Jump to content

Sky Slate Blueberry Blackcurrant Watermelon Strawberry Orange Banana Apple Emerald Chocolate
Photo

per-pixel alpha blended GUI demo


  • Please log in to reply
48 replies to this topic
Sean
  • Members
  • 2462 posts
  • Last active: Feb 07 2012 04:00 AM
  • Joined: 12 Feb 2007

It's the same on Vista.

That's a pitty. I didn't think it was a bug, just an incomplete implementation...
The reason was that GdiPlus can decode (not fully though) the icon file into the Bitmap object, but cannot encode the Bitmap object into the icon file yet.
So, I supposed it would be accomplished in the next version of Windows, i.e., Vista.

PS. I modified my last post to be able to test the icon both as a file and hIcon.

Lexikos
  • Administrators
  • 9844 posts
  • AutoHotkey Foundation
  • Last active:
  • Joined: 17 Oct 2006

Do you have any particular reason using PrivateExtractIcons which seems to be abandoned by MS? Have you tried LoadImage instead?

h_icon := DllCall("LoadImage", "Uint", DllCall("GetModuleHandle", "str", "shell32.dll"), "Uint", 23, "Uint", 1, "int", 48, "int", 48, "Uint", 0)

It just occurred to me that this only works for dll files that AutoHotkey has already loaded. :(

Also, the resource ordinal is not the same as the icon index. For instance, the first icon in AutoHotkey.exe is 159.

Finally, ExtractIconEx and PrivateExtractIcons support .ico files. LoadImage does also, but only the first icon (of the specified size?)

Sean
  • Members
  • 2462 posts
  • Last active: Feb 07 2012 04:00 AM
  • Joined: 12 Feb 2007

It just occurred to me that this only works for dll files that AutoHotkey has already loaded. :(

You can use LoadLibrary instead. Or you may want to use LoadLibraryEx with the flag LOAD_LIBRARY_AS_DATAFILE. Vista seems to support more flags like LOAD_LIBRARY_AS_DATAFILE_EXCLUSIVE and LOAD_LIBRARY_AS_IMAGE_RESOURCE.

Also, the resource ordinal is not the same as the icon index. For instance, the first icon in AutoHotkey.exe is 159.

Yes, shell32.dll is special in this regard. Anyway, I don't think this is a big problem as you can easily get them using resource viewer. (EnumResource... APIs)

Finally, ExtractIconEx and PrivateExtractIcons support .ico files. LoadImage does also, but only the first icon (of the specified size?)

If size isn't enough to pick the wanted icons, may better recompile it as the .icl file, IMO.

Lexikos
  • Administrators
  • 9844 posts
  • AutoHotkey Foundation
  • Last active:
  • Joined: 17 Oct 2006

Or you may want to use LoadLibraryEx with the flag LOAD_LIBRARY_AS_DATAFILE.

Thanks for mentioning this. I wasn't aware of LoadLibraryEx or LOAD_LIBRARY_AS_DATAFILE.

I'll likely still use PrivateExtractIcons, though. Anything I could script would be larger, slower and essentially a waste of time. (My menu icons script is probably the only thing I'll ever need such a generic function for, anyway.)

tic
  • Members
  • 1934 posts
  • Last active: May 30 2018 08:13 PM
  • Joined: 22 Apr 2007
So Ive finally tried this out on my home comp (Windows 2003 - all same dlls as xp i believe in this instance) and the icon is not dragable)

Also, there are no levels of transparancy. The edges look the same as if you used transcolour, so just end abrubtly rather than having the transparencies of the image.

Thank you for any further assistance you can give. I really think this could be a big thing in ahk if you can figure out how to gte it to work (above my head! :p )

Edit:

The transparencies are all there with a png, but not an ico. it still doesnt drag though

Lexikos
  • Administrators
  • 9844 posts
  • AutoHotkey Foundation
  • Last active:
  • Joined: 17 Oct 2006
Since you mentioned png, I assume you're using Sean's script, which uses GDI+. See my previous post, and the 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.

Sean's script doesn't have the "drag" code in it, either.

philou
  • Members
  • 68 posts
  • Last active: Jan 04 2011 01:12 PM
  • Joined: 26 Jul 2006
OMG, I've hoped for something like this to be possible with AHK, especially with PNG files. It's like a dream come true. No kidding.

Now, how do I put normal controls on top of the window? I've tried to add a couple of controls, but nothing shows up.
Any idea on how to do that?

tic
  • Members
  • 1934 posts
  • Last active: May 30 2018 08:13 PM
  • Joined: 22 Apr 2007

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."


Just need the drag code in Sean's as I really like it as well!

philou
  • Members
  • 68 posts
  • Last active: Jan 04 2011 01:12 PM
  • Joined: 26 Jul 2006

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."


Just need the drag code in Sean's as I really like it as well!


gah, I'm sorry, I must have missed that...

Lexikos
  • Administrators
  • 9844 posts
  • AutoHotkey Foundation
  • Last active:
  • Joined: 17 Oct 2006
Drag code:
; auto-execute section:
OnMessage(0x201, "WM_LBUTTONDOWN")
; Allow click-drag to move the window.
WM_LBUTTONDOWN() {
    if (A_Gui) {
        Gui, [color=red]+LastFound[/color]
        PostMessage, 0xA1, 2 ; WM_NCLBUTTONDOWN
    }
}
Simple to add. :)

Craziness... I put Gui, Default in previously by accident. It should have been Gui, +LastFound, but it seems to have worked anyway.

tic
  • Members
  • 1934 posts
  • Last active: May 30 2018 08:13 PM
  • Joined: 22 Apr 2007
gah!!!!

This is amazing! I think I might wet myself!

Thanks so much for going to the trouble of doing this

Sean
  • Members
  • 2462 posts
  • Last active: Feb 07 2012 04:00 AM
  • Joined: 12 Feb 2007

Just need the drag code in Sean's as I really like it as well!

The script of lexicos has the code already. You may simply copy it from there.
OK, I combined the two scripts. I hope lexicos doesn't mind.

sFile	:= "C:\alpha.png"
;hIcon	:= DllCall("LoadImage", "Uint", DllCall("GetModuleHandle", "str", "shell32.dll"), "Uint", 23, "Uint", 1, "int", 48, "int", 48, "Uint", 0x8000)

mDC_Scr	:= Gdi_CreateCompatibleDC(0)
pToken	:= Gdip_Startup()
pBitmap	:= !hIcon ? Gdip_CreateBitmapFromFile(sFile) : Gdip_CreateBitmapFromHICON(hIcon)
nWidth	:= Gdip_GetImageWidth( pBitmap)
nHeight	:= Gdip_GetImageHeight(pBitmap)
hBitmap	:= !hIcon ? Gdip_CreateHBITMAPFromBitmap(pBitmap) : Gdi_CreateDIBSection(mDC_Scr, nWidth, nHeight)
Gdip_DisposeImage(pBitmap)
Gdip_Shutdown(pToken)
oBitmap	:= Gdi_SelectObject(mDC_Scr, hBitmap)

If	hIcon
	DllCall("DrawIconEx", "Uint", mDC_Scr, "int", 0, "int", 0, "Uint", hIcon, "int", nWidth, "int", nHeight, "Uint", 0, "Uint", 0, "Uint", 1|2)

Gui, +LastFound -Caption +E0x80000
DllCall("UpdateLayeredWindow", "Uint", WinExist(), "Uint", 0, "Uint", 0, "int64P", nWidth|nHeight<<32, "Uint", mDC_Scr, "int64P", 0, "Uint", 0, "UintP", 255<<16|1<<24, "Uint", 2)
Gui, Show, Center W%nWidth% H%nHeight%
OnMessage(0x0201, "WM_LBUTTONDOWN")
OnMessage(0x0003, "WM_MOVE")

Gdi_SelectObject(mDC_Scr, oBitmap)
Gdi_DeleteObject(hBitmap)
Gdi_DeleteDC(mDC_Scr)
Return

GuiClose:
GuiEscape:
Gui, Destroy
ExitApp

WM_LBUTTONDOWN()
{
	If	A_Gui
		PostMessage, 0xA1, 2	; WM_NCLBUTTONDOWN
}

WM_MOVE(wParam, lParam, nMsg, hWnd)
{
	If	A_Gui
	&&	DllCall("UpdateLayeredWindow", "Uint", hWnd, "Uint", 0, "int64P", (lParam<<48>>48)&0xFFFFFFFF|(lParam&0xFFFF0000)<<32>>16, "Uint", 0, "Uint", 0, "Uint", 0, "Uint", 0, "Uint", 0, "Uint", 0)
	Return	0
}


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", 0, "UintP", pBits, "Uint", 0, "Uint", 0)
}

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_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
}

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
}


Lexikos
  • Administrators
  • 9844 posts
  • AutoHotkey Foundation
  • Last active:
  • Joined: 17 Oct 2006

OK, I combined the two scripts. I hope lexicos doesn't mind.

Not at all. I've added a link to it from my original post. :)

hermes as guest
  • Guests
  • Last active:
  • Joined: --
Is it possible to remove a window created through this method from the taskbar?

gui +toolwindow doesn't seem to be working as it usually would (because you've already changed the style)

Lexikos
  • Administrators
  • 9844 posts
  • AutoHotkey Foundation
  • Last active:
  • Joined: 17 Oct 2006
Gui, +ToolWindow
works fine for me...