 |
AutoHotkey Community Let's help each other out
|
| View previous topic :: View next topic |
| Author |
Message |
Lexikos
Joined: 17 Oct 2006 Posts: 2605 Location: Australia, Qld
|
Posted: Tue Oct 16, 2007 12:42 pm Post subject: per-pixel alpha blended GUI demo |
|
|
| tic wrote: | | Should really start a new topic, but do you have any idea of how to have an image with transparencies put onto an invisible gui? So the png for example would appear to be its own gui. | So I'm starting a new topic.
For anyone with programming experience, this demonstration is based on one of these articles/demos:
Per Pixel Alpha Blend (C++)
Per Pixel Alpha Blend in C#
(I forget which one.)
A while ago I wrote a test script to demonstrate how to do this from AutoHotkey. It got rather messy, as I tried various things with it. (Various text effects with GDI; messy because GDI doesn't really support alpha-blending.) Here's a cleaned up version - a magnifying glass (just an icon, lol) that can be dragged around the screen:
| Quote: |  |
[Edit: see Sean's post with added PNG support via GDI+]
| Code: | ; REQUIRES WINDOWS 2000 OR LATER
#NoEnv
Gui, -Caption +E0x80000 ; WS_EX_LAYERED
; Prevents later Gui,Show calls from auto-sizing the GUI.
; Center/default positioning doesn't work unless we explicitly
; size the GUI. :-/ (It will be resized to the size of the icon later.)
Gui, Show, W1 H1 Hide
Gui, +LastFound
if !(h_icon := ExtractIcon("shell32.dll", 23, 48))
ExitApp
GetIconSize(h_icon, width, height)
; Create a device context compatible with the screen.
if (hdcDest := DllCall("CreateCompatibleDC", "UInt", 0))
{
; Create a 32-bit bitmap to draw the icon onto.
if (h_bm := CreateDIBSection(width, height, 32, hdcDest, pBits))
{
; Select the new bitmap into the device context.
if (bmOld := GDI_SelectObject(hdcDest, h_bm))
{
; Draw the icon onto the window.
DllCall("DrawIconEx"
, "UInt", hdcDest ; hdc (destination device context)
, "Int" , x+1 ; xLeft
, "Int" , 0 ; yTop
, "UInt", h_icon
, "UInt", width
, "UInt", height
, "UInt", 0 ; istepIfAniCur
, "UInt", 0 ; hbrFlickerFreeDraw = NULL (draw directly into buffer)
, "UInt", 3) ; diFlags = DI_NORMAL
; BLENDFUNCTION bf
VarSetCapacity(bf, 4, 0)
;NumPut(0, bf, 0, "UChar") ; BlendOp := AC_SRC_OVER
;NumPut(0, bf, 1, "UChar") ; BlendFlags - must be zero
NumPut(255, bf, 2, "UChar") ; SourceConstantAlpha := 255
NumPut(1, bf, 3, "UChar") ; AlphaFormat := AC_SRC_ALHPA
VarSetCapacity(size, 8, 0)
NumPut(width, size, 0)
NumPut(height, size, 4)
hwnd := WinExist()
DllCall("UpdateLayeredWindow"
, "uint", hwnd
, "uint", 0 ; hdcDst
, "uint", 0 ; pptDst (pointer to new position, or NULL if not changing)
, "uint", &size ; psize (pointer to new size, or NULL if not changing)
, "uint", hdcDest ; hdcSrc (defines the layered window)
, "uint", &ptSrc ; pptSrc (pointer to location of the layer in the DC)
, "uint", 0 ; crKey (not used if !(dwFlags&ULW_COLROKEY))
, "uint", &bf ; pblend
, "uint", 2) ; dwFlags := ULW_ALPHA (use pblend, not crKey)
; Reselect previous object (as per MSDN recommendation.)
GDI_SelectObject(hdcDest, bmOld)
}
; we no longer need the bitmap! (Windows has created a copy for the layered window)
DllCall("DeleteObject", "uint", h_bm)
}
; Done using the device context.
DllCall("DeleteDC", "UInt", hdcDest)
}
OnMessage(0x201, "WM_LBUTTONDOWN")
Gui, Show
return
GuiClose:
GuiEscape:
ExitApp
; Allow click-drag to move the window.
WM_LBUTTONDOWN() {
if (A_Gui) {
Gui, +LastFound
PostMessage, 0xA1, 2 ; WM_NCLBUTTONDOWN
}
}
GDI_SelectObject(hdc, hgdiobj) {
return DllCall("SelectObject", "uint", hdc, "uint", hgdiobj)
}
GDI_DeleteObject(hObject) {
return DllCall("DeleteObject", "uint", hObject)
}
GetIconSize(h_icon, ByRef width, ByRef height)
{
VarSetCapacity(ii, 20, 0)
if (DllCall("GetIconInfo", "UInt", h_icon, "UInt", &ii))
{
hbmColor := NumGet(ii, 16)
hbmMask := NumGet(ii, 12)
ret := GetBitmapSize(hbmColor, width, height)
DllCall("DeleteObject", "UInt", hbmColor)
DllCall("DeleteObject", "UInt", hbmMask)
return ret
}
return false
}
GetBitmapSize(h_bitmap, ByRef width, ByRef height, ByRef bpp="")
{
VarSetCapacity(bm, 24, 0) ; BITMAP
if (!DllCall("GetObject", "UInt", h_bitmap, "Int", 24, "UInt", &bm))
return false
width := NumGet(bm, 4, "int")
height := NumGet(bm, 8, "int")
bpp := NumGet(bm,18, "ushort")
return true
}
CreateDIBSection(w, h, bpp, hDC=0, ByRef ppvBits=0)
{
hdcUsed := hDC ? hDC : DllCall("GetDC", "UInt", 0)
if (hdcUsed)
{
VarSetCapacity(bi, 40, 0) ; BITMAPINFO(HEADER)
NumPut(40, bi, 0) ; biSize
NumPut(1, bi, 12, "UShort") ; biPlanes
NumPut(0, bi, 16) ; biCompression = BI_RGB (none)
NumPut(w, bi, 4) ; biWidth
NumPut(h, bi, 8) ; biHeight
NumPut(bpp,bi, 14, "UShort") ; biBitCount
hbmp := DllCall("CreateDIBSection"
, "UInt" , hDC
, "UInt" , &bi ; defines format, attributes, etc.
, "UInt" , 0 ; iUsage = DIB_RGB_COLORS
, "UInt*", ppvBits ; gets a pointer to the bitmap data
, "UInt" , 0
, "UInt" , 0)
if (hdcUsed != hDC)
DllCall("ReleaseDC", "UInt", 0, "UInt", hdcUsed)
return hbmp
}
return 0
}
ExtractIcon(Filename, IconNumber, IconSize=0)
{
return DllCall("LoadImage"
,"uint",DllCall("GetModuleHandle","str","shell32.dll")
,"uint",IconNumber,"uint",1,"int",IconSize,"int",IconSize,"uint",0)
}
| It should work on Vista and XP; I'm not sure if the icon exists on earlier versions of Windows. The icon can easily be changed, anyway, by changing this line: | Code: | | if !(h_icon := ExtractIcon("shell32.dll", 23, 48)) | Icon 23 on Vista and XP is a magnifying glass. The "48" on the end is to specify the 48x48 icon.
The process is "basically":
- Create the GUI/window with the WS_EX_LAYERED extended style (+E0x80000).
- Create a GDI device context. (Knowing how to use this is more important than knowing what it is.)
- Create a 32-bit device independent bitmap.
- Select the bitmap into the device context.
- Using the device context, draw the icon onto the bitmap.
- Call UpdateLayeredWindow() to update the size and content of the window, using the device context.
If you already have a bitmap (i.e. loaded from a PNG file), you can skip steps 3 and 5. To load PNG files, see Image conversions and capturing with GDI+.
It is important to note that layered windows cannot have controls. At least, they won't be visible. To have similar functionality, you'd either have to use two windows/GUIs (one layered + one with controls) or draw your own "controls."
Edit: Updated ExtractIcon() to use LoadImage (thanks to Sean.)
Edit: Fixed WM_LBUTTONDOWN() to use Gui,+LastFound instead of Gui,Default (oops.)
Edit: Fixed handle leak in CreateDIBSection (minor since it didn't apply to the example.)
Last edited by Lexikos on Thu Feb 28, 2008 7:42 am; edited 4 times in total |
|
| Back to top |
|
 |
tic
Joined: 22 Apr 2007 Posts: 1365
|
Posted: Tue Oct 16, 2007 1:28 pm Post subject: |
|
|
This is very cool Lexikos. A probelm that I couldnt possibly understand yet until I delve further into your code is that on win2000, it shows the image, but it can only be moved around the area it was originally created (so is bounded by itself when it was 1st created). Hopefully you understand that, but its a little hard to describe.....
So I run the ahk, and the icon appears. I hover over it and it starts moving, but the edges of it are cut off outside where it was 1st drawn.
My plan is to make an objectdock clone, and then improve upon it. (may take a while ) |
|
| Back to top |
|
 |
Lexikos
Joined: 17 Oct 2006 Posts: 2605 Location: Australia, Qld
|
Posted: Tue Oct 16, 2007 2:28 pm Post subject: |
|
|
I think I understand what you mean. Perhaps the window's position needs to be updated using UpdateLayeredWindow. Try adding this to the auto-execute section of the script: | Code: | | OnMessage(0x3, "WM_MOVE") | and this elsewhere: | Code: | WM_MOVE(wParam, lParam, msg, hwnd) {
if (A_Gui) {
VarSetCapacity(p,8), NumPut(lParam,p)
NumPut(NumGet(p,2,"short"),p,4,"int") ; Y
NumPut(NumGet(p,0,"short"),p,0,"int") ; X
DllCall("UpdateLayeredWindow","uint",hwnd,"uint",0,"uint",&p
,"uint",0,"uint",0,"uint",0,"uint",0,"uint",0,"uint",0)
}
} | The third parameter of UpdateLayeredWindow is pptDst: | Quote: | | Pointer to a POINT structure that specifies the new screen position of the layered window. If the current position is not changing, pptDst can be NULL. |
Moving the window with UpdateLayeredWindow doesn't seem to trigger WM_MOVE. Even if it did, | Quote: | | If a message arrives while its function is still running due to a previous arrival of the same message, the function will not be called again |
|
|
| Back to top |
|
 |
Sean
Joined: 12 Feb 2007 Posts: 1359
|
Posted: Wed Oct 17, 2007 4:51 am Post subject: |
|
|
I was wondering why no one was interested in it...
Here is the code for PNG files.
| Code: | sFile := "C:\test.png" ; Specify a real PNG file.
Gui, +LastFound -Caption +E0x80000
hGui := WinExist()
pToken := Gdip_Startup()
pImage := Gdip_LoadImageFromFile(sFile)
nW := Gdip_GetImageWidth(pImage)
nH := Gdip_GetImageHeight(pImage)
mDC := Gdi_CreateCompatibleDC(0)
mBM := Gdi_CreateDIBSection(mDC, nW, nH, 32)
oBM := Gdi_SelectObject(mDC, mBM)
Gdip_DrawImageRectI(pGraphics:=Gdip_CreateFromHDC(mDC), pImage, 0, 0, nW, nH)
DllCall("UpdateLayeredWindow", "Uint", hGui, "Uint", 0, "Uint", 0, "int64P", nW|nH<<32, "Uint", mDC, "int64P", 0, "Uint", 0, "intP", 0xFF<<16|1<<24, "Uint", 2)
GDI_SelectObject(mDC, oBM)
Gdi_DeleteObject(mBM)
Gdi_DeleteDC(mDC)
Gdip_DeleteGraphics(pGraphics)
Gdip_DisposeImage(pImage)
Gdip_Shutdown(pToken)
Gui, Show, Center W%nW% H%nH%
Return
GuiClose:
GuiEscape:
ExitApp
Gdi_CreateCompatibleDC(hDC = 0)
{
Return DllCall("gdi32\CreateCompatibleDC", "Uint", hDC)
}
Gdi_CreateDIBSection(hDC, nW, nH, bpp = 32, ByRef pBits = "")
{
NumPut(VarSetCapacity(bi, 40, 0), bi)
NumPut(nW, bi, 4)
NumPut(nH, bi, 8)
NumPut(bpp, NumPut(1, bi, 12, "UShort"), 0, "Ushort")
Return DllCall("gdi32\CreateDIBSection", "Uint", hDC, "Uint", &bi, "Uint", DIB_RGB_COLORS:=0, "UintP", pBits, "Uint", 0, "Uint", 0)
}
Gdi_SelectObject(hDC, hGdiObj)
{
Return DllCall("gdi32\SelectObject", "Uint", hDC, "Uint", hGdiObj)
}
Gdi_DeleteObject(hGdiObj)
{
Return DllCall("gdi32\DeleteObject", "Uint", hGdiObj)
}
Gdi_DeleteDC(hDC)
{
Return DllCall("gdi32\DeleteDC", "Uint", hDC)
}
Gdip_Startup()
{
If Not DllCall("GetModuleHandle", "str", "gdiplus")
DllCall("LoadLibrary" , "str", "gdiplus")
VarSetCapacity(si, 16, 0), si := Chr(1)
DllCall("gdiplus\GdiplusStartup", "UintP", pToken, "Uint", &si, "Uint", 0)
Return pToken
}
Gdip_Shutdown(pToken)
{
DllCall("gdiplus\GdiplusShutdown", "Uint", pToken)
If hModule := DllCall("GetModuleHandle", "str", "gdiplus")
DllCall("FreeLibrary" , "Uint", hModule)
Return 0
}
Gdip_CreateFromHDC(hDC)
{
DllCall("gdiplus\GdipCreateFromHDC", "Uint", hDC, "UintP", pGraphics)
Return pGraphics
}
Gdip_DeleteGraphics(pGraphics)
{
Return DllCall("gdiplus\GdipDeleteGraphics", "Uint", pGraphics)
}
Gdip_LoadImageFromFile(sFile)
{
VarSetCapacity(wFile, 1023)
DllCall("kernel32\MultiByteToWideChar", "Uint", 0, "Uint", 0, "Uint", &sFile, "int", -1, "Uint", &wFile, "int", 512)
DllCall("gdiplus\GdipLoadImageFromFile", "Uint", &wFile, "UintP", pImage)
Return pImage
}
Gdip_DisposeImage(pImage)
{
Return DllCall("gdiplus\GdipDisposeImage", "Uint", pImage)
}
Gdip_GetImageWidth(pImage)
{
DllCall("gdiplus\GdipGetImageWidth", "Uint", pImage, "UintP", nW)
Return nW
}
Gdip_GetImageHeight(pImage)
{
DllCall("gdiplus\GdipGetImageHeight", "Uint", pImage, "UintP", nH)
Return nH
}
Gdip_DrawImageRectI(pGraphics, pImage, nL, nT, nW, nH)
{
Return DllCall("gdiplus\GdipDrawImageRectI", "Uint", pGraphics, "Uint", pImage, "int", nL, "int", nT, "int", nW, "int", nH)
}
|
|
|
| Back to top |
|
 |
Sean
Joined: 12 Feb 2007 Posts: 1359
|
Posted: Wed Oct 17, 2007 6:16 am Post subject: Re: per-pixel alpha blended GUI demo |
|
|
| lexikos wrote: | | Code: | | h_icon := ExtractIcon("shell32.dll", 23, 48) |
|
Do you have any particular reason using PrivateExtractIcons which seems to be abandoned by MS? Have you tried LoadImage instead?
| Code: | | h_icon := DllCall("LoadImage", "Uint", DllCall("GetModuleHandle", "str", "shell32.dll"), "Uint", 23, "Uint", 1, "int", 48, "int", 48, "Uint", 0) |
|
|
| Back to top |
|
 |
Lexikos
Joined: 17 Oct 2006 Posts: 2605 Location: Australia, Qld
|
Posted: Wed Oct 17, 2007 7:12 am Post subject: |
|
|
AutoHotkey uses LoadImage for icon files and ExtractIcon for executables. Since ExtractIcon is limited to 16x16 or 32x32, I had assumed that LoadImage did not support loading icons from executables...
Thanks for the tip.
Now I wonder why Chris used ExtractIcon() at all... |
|
| Back to top |
|
 |
ManaUser
Joined: 24 May 2007 Posts: 904
|
Posted: Wed Oct 17, 2007 8:10 am Post subject: |
|
|
| Hmm, it didn't work for me. I'm running XP, and I got a draggable magnifying glass, but it wasn't transparent at all. |
|
| Back to top |
|
 |
Lexikos
Joined: 17 Oct 2006 Posts: 2605 Location: Australia, Qld
|
Posted: Wed Oct 17, 2007 10:03 am Post subject: |
|
|
Hmm. Works fine for me on two different XP machines.
It doesn't work (on any version of Windows, afaik) if the display depth is set to anything other than 32-bit. I think this is because the icon has no alpha channel. The solution is to manually calculate the alpha data for the bitmap (after drawing the icon onto it) or (I think) use GDI+ (which properly supports alpha blending) to draw the icon.
Since you said the icon was draggable, I assume you are already running at 32-bit. The icon is not drag-able at 16-bit (because pixels with alpha=0 are transparent to the mouse.) I think the magnifying glass is still visible because GDI uses pre-multiplied alpha. |
|
| Back to top |
|
 |
SoggyDog
Joined: 02 May 2006 Posts: 225 Location: Greeley, CO
|
Posted: Thu Oct 18, 2007 2:50 pm Post subject: |
|
|
| ManaUser wrote: | | Hmm, it didn't work for me. I'm running XP, and I got a draggable magnifying glass, but it wasn't transparent at all. |
Same here; Draggable, but not transparant.
This is my computer at work; Haven't tried at home.
1024x768 32-bit 60 Hertz
MOBILITY RADEON AGP (0x4C59)
Internal DAC(350MHz)
16 MB
Microsoft Windows XP
Professional
Version 2002
Service Pack 2
Intel(R) Pentium(R) III
Mobile CPU 866MHz
863 MHz, 1.00 GB of RAM _________________
SoggyDog
Download AutoHotKey Wallpaper
Does 'Fuzzy Logic' tickle? |
|
| Back to top |
|
 |
Sean
Joined: 12 Feb 2007 Posts: 1359
|
Posted: Thu Oct 18, 2007 4:44 pm Post subject: |
|
|
I think the transparent magnifying glass icon is Vista only. The one in XP isn't transparent. You may test the per-pixel alpha-blending with the PNG file here:
http://en.wikipedia.org/wiki/Portable_Network_Graphics
You may convert this .png to .ico, then could test also transparent icon for per-pixel alpha blending. |
|
| Back to top |
|
 |
ManaUser
Joined: 24 May 2007 Posts: 904
|
Posted: Thu Oct 18, 2007 9:59 pm Post subject: |
|
|
| Ah, yes. The PNG one is works. |
|
| Back to top |
|
 |
Lexikos
Joined: 17 Oct 2006 Posts: 2605 Location: Australia, Qld
|
Posted: Thu Oct 18, 2007 11:23 pm Post subject: |
|
|
Actually, it has slight transparency around the edges to make it look smooth. I can see how one might think it has no transparency. When you said "wasn't transparent at all", I imagined a completely opaque box.
Btw, you can also adjust the overall transparency level by changing this line:
| Code: | | NumPut(255, bf, 2, "UChar") ; SourceConstantAlpha := 255 |
|
|
| Back to top |
|
 |
ManaUser
Joined: 24 May 2007 Posts: 904
|
Posted: Fri Oct 19, 2007 12:27 am Post subject: |
|
|
| lexikos wrote: | | Actually, it has slight transparency around the edges to make it look smooth. I can see how one might think it has no transparency. |
Right again. Sorry. I was expecting the lens to be transparent like in your example. |
|
| Back to top |
|
 |
Sean
Joined: 12 Feb 2007 Posts: 1359
|
Posted: Fri Oct 19, 2007 1:25 am Post subject: |
|
|
| lexikos wrote: | | Actually, it has slight transparency around the edges to make it look smooth. |
As a matter of fact, it doesn't work with GdiPlus in XP while it does work with DrawIconEx. I suppose it's because GdiPlus in XP doesn't fully support Icon yet. I'm wondering if the GdiPlus in Vista improves the support for Icon.
| Code: | ;sFile := "C:\mag.ico" ; Specify the real path of the Icon.
;hIcon := DllCall("LoadImage", "Uint", 0, "Uint", &sFile, "Uint", 1, "int", 48, "int", 48, "Uint", 0x10)
hIcon := DllCall("LoadImage", "Uint", DllCall("GetModuleHandle", "str", "shell32.dll"), "Uint", 23, "Uint", 1, "int", 48, "int", 48, "Uint", 0)
pToken := Gdip_Startup()
pBitmap := hIcon ? Gdip_CreateBitmapFromHICON(hIcon) : Gdip_CreateBitmapFromFile(sFile)
hBitmap := Gdip_CreateHBITMAPFromBitmap(pBitmap)
nW := Gdip_GetImageWidth( pBitmap)
nH := Gdip_GetImageHeight(pBitmap)
Gdip_DisposeImage(pBitmap)
Gdip_Shutdown(pToken)
DllCall("DestroyIcon", "Uint", hIcon)
mDC := Gdi_CreateCompatibleDC(0)
oBitmap := Gdi_SelectObject(mDC, hBitmap)
Gui, +LastFound -Caption +E0x80000
DllCall("UpdateLayeredWindow", "Uint", WinExist(), "Uint", 0, "Uint", 0, "int64P", nW|nH<<32, "Uint", mDC, "int64P", 0, "Uint", 0, "UintP", 255<<16|1<<24, "Uint", 2)
Gui, Show, Center W%nW% H%nH%
Gdi_SelectObject(mDC, oBitmap)
Gdi_DeleteObject(hBitmap)
Gdi_DeleteDC(mDC)
Return
GuiClose:
GuiEscape:
ExitApp
Gdi_CreateCompatibleDC(hDC = 0)
{
Return DllCall("gdi32\CreateCompatibleDC", "Uint", hDC)
}
Gdi_SelectObject(hDC, hGdiObj)
{
Return DllCall("gdi32\SelectObject", "Uint", hDC, "Uint", hGdiObj)
}
Gdi_DeleteObject(hGdiObj)
{
Return DllCall("gdi32\DeleteObject", "Uint", hGdiObj)
}
Gdi_DeleteDC(hDC)
{
Return DllCall("gdi32\DeleteDC", "Uint", hDC)
}
Gdip_Startup()
{
If Not DllCall("GetModuleHandle", "str", "gdiplus")
DllCall("LoadLibrary" , "str", "gdiplus")
VarSetCapacity(si, 16, 0), si := Chr(1)
DllCall("gdiplus\GdiplusStartup", "UintP", pToken, "Uint", &si, "Uint", 0)
Return pToken
}
Gdip_Shutdown(pToken)
{
DllCall("gdiplus\GdiplusShutdown", "Uint", pToken)
If hModule := DllCall("GetModuleHandle", "str", "gdiplus")
DllCall("FreeLibrary" , "Uint", hModule)
Return 0
}
Gdip_CreateBitmapFromFile(sFile)
{
VarSetCapacity(wFile, 1023)
DllCall("kernel32\MultiByteToWideChar", "Uint", 0, "Uint", 0, "Uint", &sFile, "int", -1, "Uint", &wFile, "int", 512)
DllCall("gdiplus\GdipCreateBitmapFromFile", "Uint", &wFile, "UintP", pBitmap)
Return pBitmap
}
Gdip_CreateBitmapFromHICON(hIcon)
{
DllCall("gdiplus\GdipCreateBitmapFromHICON", "Uint", hIcon, "UintP", pBitmap)
Return pBitmap
}
Gdip_CreateHBITMAPFromBitmap(pBitmap, ARGB = 0)
{
DllCall("gdiplus\GdipCreateHBITMAPFromBitmap", "Uint", pBitmap, "UintP", hBitmap, "Uint", ARGB)
Return hBitmap
}
Gdip_DisposeImage(pImage)
{
Return DllCall("gdiplus\GdipDisposeImage", "Uint", pImage)
}
Gdip_GetImageWidth(pImage)
{
DllCall("gdiplus\GdipGetImageWidth", "Uint", pImage, "UintP", nW)
Return nW
}
Gdip_GetImageHeight(pImage)
{
DllCall("gdiplus\GdipGetImageHeight", "Uint", pImage, "UintP", nH)
Return nH
}
|
Last edited by Sean on Fri Oct 19, 2007 5:58 am; edited 1 time in total |
|
| Back to top |
|
 |
Lexikos
Joined: 17 Oct 2006 Posts: 2605 Location: Australia, Qld
|
Posted: Fri Oct 19, 2007 2:55 am Post subject: |
|
|
| Sean wrote: | | I'm wondering if the GdiPlus in Vista improves the support for Icon. | It's the same on Vista. Bitmap.FromHicon() / CreateBitmapFromHICON() loses the alpha channel. Icon.FromHandle() + Graphics.DrawIcon() should work, but they don't have unmanaged GDI+ equivalents.
Here's what I've discovered via .NET Reflector:
Icon.FromHandle()
The Icon class seems to be a wrapper around a GDI icon. FromHandle() simply copies the handle to the Icon's private handle variable.
Graphics.DrawIcon()
If the Graphics object was created from an Image object, it does this: | Code: | | this.DrawImage(icon.ToBitmap(), targetRect); | If the icon is 32-bit, Icon.ToBitmap() creates a 32-bit bitmap and copies the icon data to it. This seems similar to what this guy does to work around the FromHicon issue. | Quote: | There appears to be a bug in GDI+ with regard to getting the bitmap
image of any icon which results in an image being use that is not the
correct pixel format. This seems to occur with any GDI+ function that
internally has to a convert an image to a bitmap. The solution below
addresses the issue by using GetIconInfo, creating a bitmap which will
contain the correct bits but wrong format, then copy the bitmap bits
to a new bitmap with the correctly format. |
If the Graphics object was not created from an Image object, it (indirectly) calls (the native Win32 function) DrawIconEx().  |
|
| Back to top |
|
 |
|
|
You can post new topics in this forum You can reply to topics in this forum
|
Powered by phpBB © 2001, 2005 phpBB Group
|