为WPF按钮添加UAC盾牌图标

发布时间 2023-08-28 14:43:13作者: zhaotianff

在上一篇文章中,介绍了如何获取系统Shell的图标。在C#中调用SHGetStockIconInfo即可获取获取图标

 

定义SHGetStockIconInfo函数用到的数据结构

  1     public enum SHSTOCKICONID : uint
  2     {
  3         /// <summary>Document of a type with no associated application.</summary>
  4         SIID_DOCNOASSOC = 0,
  5         /// <summary>Document of a type with an associated application.</summary>
  6         SIID_DOCASSOC = 1,
  7         /// <summary>Generic application with no custom icon.</summary>
  8         SIID_APPLICATION = 2,
  9         /// <summary>Folder (generic, unspecified state).</summary>
 10         SIID_FOLDER = 3,
 11         /// <summary>Folder (open).</summary>
 12         SIID_FOLDEROPEN = 4,
 13         /// <summary>5.25-inch disk drive.</summary>
 14         SIID_DRIVE525 = 5,
 15         /// <summary>3.5-inch disk drive.</summary>
 16         SIID_DRIVE35 = 6,
 17         /// <summary>Removable drive.</summary>
 18         SIID_DRIVEREMOVE = 7,
 19         /// <summary>Fixed drive (hard disk).</summary>
 20         SIID_DRIVEFIXED = 8,
 21         /// <summary>Network drive (connected).</summary>
 22         SIID_DRIVENET = 9,
 23         /// <summary>Network drive (disconnected).</summary>
 24         SIID_DRIVENETDISABLED = 10,
 25         /// <summary>CD drive.</summary>
 26         SIID_DRIVECD = 11,
 27         /// <summary>RAM disk drive.</summary>
 28         SIID_DRIVERAM = 12,
 29         /// <summary>The entire network.</summary>
 30         SIID_WORLD = 13,
 31         /// <summary>A computer on the network.</summary>
 32         SIID_SERVER = 15,
 33         /// <summary>A local printer or print destination.</summary>
 34         SIID_PRINTER = 16,
 35         /// <summary>The Network virtual folder (FOLDERID_NetworkFolder/CSIDL_NETWORK).</summary>
 36         SIID_MYNETWORK = 17,
 37         /// <summary>The Search feature.</summary>
 38         SIID_FIND = 22,
 39         /// <summary>The Help and Support feature.</summary>
 40         SIID_HELP = 23,
 41         /// <summary>Overlay for a shared item.</summary>
 42         SIID_SHARE = 28,
 43         /// <summary>Overlay for a shortcut.</summary>
 44         SIID_LINK = 29,
 45         /// <summary>Overlay for items that are expected to be slow to access.</summary>
 46         SIID_SLOWFILE = 30,
 47         /// <summary>The Recycle Bin (empty).</summary>
 48         SIID_RECYCLER = 31,
 49         /// <summary>The Recycle Bin (not empty).</summary>
 50         SIID_RECYCLERFULL = 32,
 51         /// <summary>Audio CD media.</summary>
 52         SIID_MEDIACDAUDIO = 40,
 53         /// <summary>Security lock.</summary>
 54         SIID_LOCK = 47,
 55         /// <summary>A virtual folder that contains the results of a search.</summary>
 56         SIID_AUTOLIST = 49,
 57         /// <summary>A network printer.</summary>
 58         SIID_PRINTERNET = 50,
 59         /// <summary>A server shared on a network.</summary>
 60         SIID_SERVERSHARE = 51,
 61         /// <summary>A local fax printer.</summary>
 62         SIID_PRINTERFAX = 52,
 63         /// <summary>A network fax printer.</summary>
 64         SIID_PRINTERFAXNET = 53,
 65         /// <summary>A file that receives the output of a Print to file operation.</summary>
 66         SIID_PRINTERFILE = 54,
 67         /// <summary>A category that results from a Stack by command to organize the contents of a folder.</summary>
 68         SIID_STACK = 55,
 69         /// <summary>Super Video CD (SVCD) media.</summary>
 70         SIID_MEDIASVCD = 56,
 71         /// <summary>A folder that contains only subfolders as child items.</summary>
 72         SIID_STUFFEDFOLDER = 57,
 73         /// <summary>Unknown drive type.</summary>
 74         SIID_DRIVEUNKNOWN = 58,
 75         /// <summary>DVD drive.</summary>
 76         SIID_DRIVEDVD = 59,
 77         /// <summary>DVD media.</summary>
 78         SIID_MEDIADVD = 60,
 79         /// <summary>DVD-RAM media.</summary>
 80         SIID_MEDIADVDRAM = 61,
 81         /// <summary>DVD-RW media.</summary>
 82         SIID_MEDIADVDRW = 62,
 83         /// <summary>DVD-R media.</summary>
 84         SIID_MEDIADVDR = 63,
 85         /// <summary>DVD-ROM media.</summary>
 86         SIID_MEDIADVDROM = 64,
 87         /// <summary>CD+ (enhanced audio CD) media.</summary>
 88         SIID_MEDIACDAUDIOPLUS = 65,
 89         /// <summary>CD-RW media.</summary>
 90         SIID_MEDIACDRW = 66,
 91         /// <summary>CD-R media.</summary>
 92         SIID_MEDIACDR = 67,
 93         /// <summary>A writable CD in the process of being burned.</summary>
 94         SIID_MEDIACDBURN = 68,
 95         /// <summary>Blank writable CD media.</summary>
 96         SIID_MEDIABLANKCD = 69,
 97         /// <summary>CD-ROM media.</summary>
 98         SIID_MEDIACDROM = 70,
 99         /// <summary>An audio file.</summary>
100         SIID_AUDIOFILES = 71,
101         /// <summary>An image file.</summary>
102         SIID_IMAGEFILES = 72,
103         /// <summary>A video file.</summary>
104         SIID_VIDEOFILES = 73,
105         /// <summary>A mixed file.</summary>
106         SIID_MIXEDFILES = 74,
107         /// <summary>Folder back.</summary>
108         SIID_FOLDERBACK = 75,
109         /// <summary>Folder front.</summary>
110         SIID_FOLDERFRONT = 76,
111         /// <summary>Security shield. Use for UAC prompts only.</summary>
112         SIID_SHIELD = 77,
113         /// <summary>Warning.</summary>
114         SIID_WARNING = 78,
115         /// <summary>Informational.</summary>
116         SIID_INFO = 79,
117         /// <summary>Error.</summary>
118         SIID_ERROR = 80,
119         /// <summary>Key.</summary>
120         SIID_KEY = 81,
121         /// <summary>Software.</summary>
122         SIID_SOFTWARE = 82,
123         /// <summary>A UI item, such as a button, that issues a rename command.</summary>
124         SIID_RENAME = 83,
125         /// <summary>A UI item, such as a button, that issues a delete command.</summary>
126         SIID_DELETE = 84,
127         /// <summary>Audio DVD media.</summary>
128         SIID_MEDIAAUDIODVD = 85,
129         /// <summary>Movie DVD media.</summary>
130         SIID_MEDIAMOVIEDVD = 86,
131         /// <summary>Enhanced CD media.</summary>
132         SIID_MEDIAENHANCEDCD = 87,
133         /// <summary>Enhanced DVD media.</summary>
134         SIID_MEDIAENHANCEDDVD = 88,
135         /// <summary>High definition DVD media in the HD DVD format.</summary>
136         SIID_MEDIAHDDVD = 89,
137         /// <summary>High definition DVD media in the Blu-ray Disc™ format.</summary>
138         SIID_MEDIABLURAY = 90,
139         /// <summary>Video CD (VCD) media.</summary>
140         SIID_MEDIAVCD = 91,
141         /// <summary>DVD+R media.</summary>
142         SIID_MEDIADVDPLUSR = 92,
143         /// <summary>DVD+RW media.</summary>
144         SIID_MEDIADVDPLUSRW = 93,
145         /// <summary>A desktop computer.</summary>
146         SIID_DESKTOPPC = 94,
147         /// <summary>A mobile computer (laptop).</summary>
148         SIID_MOBILEPC = 95,
149         /// <summary>The User Accounts Control Panel item.</summary>
150         SIID_USERS = 96,
151         /// <summary>Smart media.</summary>
152         SIID_MEDIASMARTMEDIA = 97,
153         /// <summary>CompactFlash media.</summary>
154         SIID_MEDIACOMPACTFLASH = 98,
155         /// <summary>A cell phone.</summary>
156         SIID_DEVICECELLPHONE = 99,
157         /// <summary>A digital camera.</summary>
158         SIID_DEVICECAMERA = 100,
159         /// <summary>A digital video camera.</summary>
160         SIID_DEVICEVIDEOCAMERA = 101,
161         /// <summary>An audio player.</summary>
162         SIID_DEVICEAUDIOPLAYER = 102,
163         /// <summary>Connect to network.</summary>
164         SIID_NETWORKCONNECT = 103,
165         /// <summary>The Network and Internet Control Panel item.</summary>
166         SIID_INTERNET = 104,
167         /// <summary>A compressed file with a .zip file name extension.</summary>
168         SIID_ZIPFILE = 105,
169         /// <summary>The Additional Options Control Panel item.</summary>
170         SIID_SETTINGS = 106,
171         /// <summary>High definition DVD drive (any type - HD DVD-ROM, HD DVD-R, HD-DVD-RAM) that uses the HD DVD format.</summary>
172         /// <remarks>Windows Vista with SP1 and later.</remarks>
173         SIID_DRIVEHDDVD = 132,
174         /// <summary>High definition DVD drive (any type - BD-ROM, BD-R, BD-RE) that uses the Blu-ray Disc format.</summary>
175         /// <remarks>Windows Vista with SP1 and later.</remarks>
176         SIID_DRIVEBD = 133,
177         /// <summary>High definition DVD-ROM media in the HD DVD-ROM format.</summary>
178         /// <remarks>Windows Vista with SP1 and later.</remarks>
179         SIID_MEDIAHDDVDROM = 134,
180         /// <summary>High definition DVD-R media in the HD DVD-R format.</summary>
181         /// <remarks>Windows Vista with SP1 and later.</remarks>
182         SIID_MEDIAHDDVDR = 135,
183         /// <summary>High definition DVD-RAM media in the HD DVD-RAM format.</summary>
184         /// <remarks>Windows Vista with SP1 and later.</remarks>
185         SIID_MEDIAHDDVDRAM = 136,
186         /// <summary>High definition DVD-ROM media in the Blu-ray Disc BD-ROM format.</summary>
187         /// <remarks>Windows Vista with SP1 and later.</remarks>
188         SIID_MEDIABDROM = 137,
189         /// <summary>High definition write-once media in the Blu-ray Disc BD-R format.</summary>
190         /// <remarks>Windows Vista with SP1 and later.</remarks>
191         SIID_MEDIABDR = 138,
192         /// <summary>High definition read/write media in the Blu-ray Disc BD-RE format.</summary>
193         /// <remarks>Windows Vista with SP1 and later.</remarks>
194         SIID_MEDIABDRE = 139,
195         /// <summary>A cluster disk array.</summary>
196         /// <remarks>Windows Vista with SP1 and later.</remarks>
197         SIID_CLUSTEREDDRIVE = 140,
198         /// <summary>The highest valid value in the enumeration.</summary>
199         /// <remarks>Values over 160 are Windows 7-only icons.</remarks>
200         SIID_MAX_ICONS = 175
201     }
202 
203     [Flags]
204     public enum SHGSI : uint
205     {
206         /// <summary>The szPath and iIcon members of the SHSTOCKICONINFO structure receive the path and icon index of the requested icon, in a format suitable for passing to the ExtractIcon function. The numerical value of this flag is zero, so you always get the icon location regardless of other flags.</summary>
207         SHGSI_ICONLOCATION = 0,
208         /// <summary>The hIcon member of the SHSTOCKICONINFO structure receives a handle to the specified icon.</summary>
209         SHGSI_ICON = 0x000000100,
210         /// <summary>The iSysImageImage member of the SHSTOCKICONINFO structure receives the index of the specified icon in the system imagelist.</summary>
211         SHGSI_SYSICONINDEX = 0x000004000,
212         /// <summary>Modifies the SHGSI_ICON value by causing the function to add the link overlay to the file's icon.</summary>
213         SHGSI_LINKOVERLAY = 0x000008000,
214         /// <summary>Modifies the SHGSI_ICON value by causing the function to blend the icon with the system highlight color.</summary>
215         SHGSI_SELECTED = 0x000010000,
216         /// <summary>Modifies the SHGSI_ICON value by causing the function to retrieve the large version of the icon, as specified by the SM_CXICON and SM_CYICON system metrics.</summary>
217         SHGSI_LARGEICON = 0x000000000,
218         /// <summary>Modifies the SHGSI_ICON value by causing the function to retrieve the small version of the icon, as specified by the SM_CXSMICON and SM_CYSMICON system metrics.</summary>
219         SHGSI_SMALLICON = 0x000000001,
220         /// <summary>Modifies the SHGSI_LARGEICON or SHGSI_SMALLICON values by causing the function to retrieve the Shell-sized icons rather than the sizes specified by the system metrics.</summary>
221         SHGSI_SHELLICONSIZE = 0x000000004
222     }
223 
224     [StructLayoutAttribute(LayoutKind.Sequential, CharSet = CharSet.Unicode)]
225     public struct SHSTOCKICONINFO
226     {
227         public UInt32 cbSize;
228         public IntPtr hIcon;
229         public Int32 iSysIconIndex;
230         public Int32 iIcon;
231         [MarshalAs(UnmanagedType.ByValTStr, SizeConst = UACIcon.MAX_PATH)]
232         public string szPath;
233     }

 说明:

SHSTOCKICONID这里实际只需要定义SIID_SHIELD这一个值就行了,我这里全部贴出来了,以后需要用到的时候可以直接到这里复制了。

 

定义UACIcon的类,在这个类里封装获取UAC图标的方法

 1 public class UACIcon
 2     {
 3         public const int MAX_PATH = 260;
 4 
 5         [DllImport("Shell32.dll", SetLastError = false)]
 6         public static extern Int32 SHGetStockIconInfo(SHSTOCKICONID siid, SHGSI uFlags, ref SHSTOCKICONINFO psii);
 7 
 8         [DllImport("user32.dll", SetLastError = true)]
 9         static extern bool DestroyIcon(IntPtr hIcon);
10 
11         public static BitmapSource GetUACIcon()
12         {
13             BitmapSource shieldSource = null;
14 
15             SHSTOCKICONINFO sii = new SHSTOCKICONINFO();
16             sii.cbSize = (UInt32)Marshal.SizeOf(typeof(SHSTOCKICONINFO));
17 
18             Marshal.ThrowExceptionForHR(SHGetStockIconInfo(SHSTOCKICONID.SIID_SHIELD,
19                 SHGSI.SHGSI_ICON | SHGSI.SHGSI_LARGEICON,
20                 ref sii));
21 
22             shieldSource = System.Windows.Interop.Imaging.CreateBitmapSourceFromHIcon(
23                 sii.hIcon,
24                 Int32Rect.Empty,
25                 BitmapSizeOptions.FromEmptyOptions());
26 
27             DestroyIcon(sii.hIcon);
28             return shieldSource;
29         }
30     }

上面的代码中包含了从句柄创建WPF ImageSource的代码,如果对这一块不了解的话,可以参考

https://learn.microsoft.com/en-us/dotnet/api/system.windows.interop.imaging.createbitmapsourcefromhicon?view=windowsdesktop-7.0

 

界面XAML如下:

 1   <Grid>
 2         <Button Width="74" Height="28">
 3             <Button.Content>
 4                 <Grid>
 5                     <Grid.ColumnDefinitions>
 6                         <ColumnDefinition Width="32"/>
 7                         <ColumnDefinition/>
 8                     </Grid.ColumnDefinitions>
 9 
10                     <Image Stretch="Uniform" x:Name="img_Icon" Width="18" Height="18" HorizontalAlignment="Right"/>
11                     <Label Content="确认" Grid.Column="1" HorizontalAlignment="Left"/>
12                 </Grid>
13             </Button.Content>
14         </Button>
15     </Grid>

 

加载图标

1   public partial class MainWindow : Window
2     {
3         public MainWindow()
4         {
5             InitializeComponent();
6 
7             this.img_Icon.Source = UACIcon.GetUACIcon();
8         }
9     }

 

运行效果:

 

示例代码

 

参考资料:

https://www.cnblogs.com/zhaotianff/p/17662167.html  获取系统图标

https://pinvoke.net/default.aspx/shell32/SHGetStockIconInfo.html   SHGetStockIconInfo函数P/Invoke签名