【问题标题】:Add a UAC shield to a button and retain its background image?将 UAC 屏蔽添加到按钮并保留其背景图像?
【发布时间】:2012-12-07 07:04:32
【问题描述】:

在 winforms 应用程序中使用 C# 和 .Net 4.0:是否可以将 UAC 屏蔽添加到按钮并保留按钮背景图像?怎么样?

这是我目前正在使用的,但它会删除图像......

[DllImport("user32.dll")]
public static extern int SendMessage(IntPtr hWnd, uint Msg, int wParam, int lParam);

public static void UACToButton(Button button, bool add)
{
    const Int32 BCM_SETSHIELD = 0x160C;
    if (add)
        {
        // The button must have the flat style
        button.FlatStyle = FlatStyle.System;
        if (button.Text == "")
        // and it must have text to display the shield
            button.Text = " ";
            SendMessage(button.Handle, BCM_SETSHIELD, 0, 1);        
        }
        else
            SendMessage(button.Handle, BCM_SETSHIELD, 0, 0);    
}

谢谢!

【问题讨论】:

  • 您是否试图仅在按钮上显示没有文字的盾牌?
  • 按钮没有文字。它只有一个图像,在调用方法时会被移除。
  • 从 imageres.dll 加载图标并在背景图像上自行绘制,然后在按钮上绘制图像。

标签: c# winforms uac dllimport


【解决方案1】:

正如 Elmue 所提到的,SystemIcons.Shield 是访问 UAC Shield 图标的最简单方法。这是我用来将其添加到其他图像之上的方法:

public static Image AddUACShieldToImage(Image image)
    {
        var shield = SystemIcons.Shield.ToBitmap();
        shield.MakeTransparent();

        var g = Graphics.FromImage(image);
        g.CompositingMode = CompositingMode.SourceOver;
        g.DrawImage(shield, new Rectangle(image.Width / 2, image.Height / 2, image.Width / 2, image.Height / 2));

        return image;
    }

【讨论】:

    【解决方案2】:

    也许这会有所帮助:http://blog.csharphelper.com/2011/03/03/add-uac-shields-to-buttons-menu-items-and-picture-boxes-in-c.aspx

    它采用 UAC 屏蔽并返回一个位图,该位图可以放置在任何支持位图的东西上。

    编辑: 以下是一些可以工作的粗略示例代码:

    using System;
    using System.Collections.Generic;
    using System.ComponentModel;
    using System.Data;
    using System.Drawing;
    using System.Linq;
    using System.Text;
    using System.Windows.Forms;
    using System.Runtime.InteropServices;
    
    namespace UAC_Test
    {
        public partial class Form1 : Form
        {
            public Form1()
            {
                InitializeComponent();
            }
    
            [DllImport("user32.dll")]
            public static extern int SendMessage(IntPtr hWnd, uint Msg, int wParam, int lParam);
    
            // Make the button display the UAC shield.
            public static void AddShieldToButton(Button btn)
            {
                const Int32 BCM_SETSHIELD = 0x160C;
    
                // Give the button the flat style and make it display the UAC shield.
                btn.FlatStyle = System.Windows.Forms.FlatStyle.System;
                SendMessage(btn.Handle, BCM_SETSHIELD, 0, 1);
            }
    
            // Return a bitmap containing the UAC shield.
            private static Bitmap shield_bm = null;
            public static Bitmap GetUacShieldImage()
            {
                if (shield_bm != null) return shield_bm;
    
                const int WID = 50;
                const int HGT = 50;
                const int MARGIN = 4;
    
                // Make the button. For some reason, it must
                // have text or the UAC shield won't appear.
                Button btn = new Button();
                btn.Text = " ";
                btn.Size = new Size(WID, HGT);
                AddShieldToButton(btn);
    
                // Draw the button onto a bitmap.
                Bitmap bm = new Bitmap(WID, HGT);
                btn.Refresh();
                btn.DrawToBitmap(bm, new Rectangle(0, 0, WID, HGT));
    
                // Find the part containing the shield.
                int min_x = WID, max_x = 0, min_y = HGT, max_y = 0;
    
                // Fill on the left.
                for (int y = MARGIN; y < HGT - MARGIN; y++)
                {
                    // Get the leftmost pixel's color.
                    Color target_color = bm.GetPixel(MARGIN, y);
    
                    // Fill in with this color as long as we see the target.
                    for (int x = MARGIN; x < WID - MARGIN; x++)
                    {
                        // See if this pixel is part of the shield.
                        if (bm.GetPixel(x, y).Equals(target_color))
                        {
                            // It's not part of the shield.
                            // Clear the pixel.
                            bm.SetPixel(x, y, Color.Transparent);
                        }
                        else
                        {
                            // It's part of the shield.
                            if (min_y > y) min_y = y;
                            if (min_x > x) min_x = x;
                            if (max_y < y) max_y = y;
                            if (max_x < x) max_x = x;
                        }
                    }
                }
    
                // Clip out the shield part.
                int shield_wid = max_x - min_x + 1;
                int shield_hgt = max_y - min_y + 1;
                shield_bm = new Bitmap(shield_wid, shield_hgt);
                Graphics shield_gr = Graphics.FromImage(shield_bm);
                shield_gr.DrawImage(bm, 0, 0,
                    new Rectangle(min_x, min_y, shield_wid, shield_hgt),
                    GraphicsUnit.Pixel);
    
                // Return the shield.
                return shield_bm;
            }
    
            private void Form1_Load(object sender, EventArgs e)
            {
                Graphics gfx = Graphics.FromImage(button1.BackgroundImage);
                Bitmap shield = GetUacShieldImage();
                gfx.DrawImage(shield, button1.Width / 2, button1.Height / 2);
            }
        }
    }
    

    这是在背景图像上绘制 UAC 盾牌。您可以调整按钮顶部的图像位置。它看起来不像系统 UAC 盾牌那么漂亮,但它确实在您的背景图像顶部显示了 UAC 盾牌图标。

    【讨论】:

    • 没有。它将 UAC 屏蔽作为位图并将其放在任何支持位图的东西上。获取该代码并向按钮添加背景图像,您会看到我的问题。不过还是谢谢。
    • 我已经更新了我的答案以包含一些示例代码。我一开始忘了提到你需要在背景图像上绘制 UAC 盾牌。
    • 这太复杂了!如果您的框架支持,请使用 SystemIcons.Shield,或者从 imageres.dll 加载它,或者从其他地方下载该图标并自行绘制。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2012-02-20
    • 2014-07-06
    • 2019-11-11
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多