unexpectedpanda Posted August 27, 2012 Share Posted August 27, 2012 (edited) Hi all,I've been doing some work on a MacBook Pro with Retina Display, and so have been toying with high DPI interfaces (~200% dpi) and ?do=embed' frameborder='0' data-embedContent> to make sure things are nice and sharp.The last barrier appears to be window icons used at the top left of the application. I've done a fair bit of searching about icons on the forums, but although there have been references here and there to blurry icons or telling AutoIt specifically what icon to use within the .ICO file, so far I haven't found a solution that's quite fit.As you can see, the desktop icon is great, so is the tray icon, but the window icon at the top left is scaled up and blurry. Native Windows apps don't seem to have this issue. Any hints of how to correct this would be very much welcome. I've uploaded some sample code here, as well as the .ico file that I'm using (374KB ZIP). It's just sample code to illustrate the point, it's not meant to be a functional GUI.You'll likely need to compile with the ?do=embed' frameborder='0' data-embedContent> to be able to see everything at properly sharp high DPI levels, rather than blurry DWM scaling ("Go" (F5) doesn't work for high DPI, you have to compile (F7)... I'm guessing I'd need access to the aut2exe code to modify that behaviour).Here's the code I'm currently using (also in the ZIP):expandcollapse popup#Region ;**** Directives created by AutoIt3Wrapper_GUI **** #AutoIt3Wrapper_Version=beta #AutoIt3Wrapper_Icon=cnet.ico #AutoIt3Wrapper_Outfile=test.exe #AutoIt3Wrapper_Res_Description=test #AutoIt3Wrapper_Res_Fileversion=0.992.0.0 #AutoIt3Wrapper_Res_requestedExecutionLevel=requireAdministrator #AutoIt3Wrapper_Res_Compatibility=Windows7 #AutoIt3Wrapper_Res_HiDpi=1 #EndRegion ;**** Directives created by AutoIt3Wrapper_GUI **** TraySetIcon(@ScriptDir & "\cnet.ico",1) #include <GUIConstantsEx.au3> #include <WindowsConstants.au3> #include <StaticConstants.au3> #include <_GetDPI.au3> Opt("GUIOnEventMode", 1) $a1 = _GetDPI() $iDPIRat = $a1[2] $FormMainGUI = GUICreate("test", 450 * $iDPIRat, 190 * $iDPIRat) GuiSetIcon(@ScriptDir & "\cnet.ico",1,$FormMainGUI) $Administratorlbl = GUICtrlCreateLabel("You MUST be signed into an administrative account before running installation",0,85 * $iDPIRat,450 * $iDPIRat,20 * $iDPIRat,$SS_CENTER) GuiCtrlSetColor($Administratorlbl,0x777777) GuiCtrlSetFont($Administratorlbl,7,400) $btnAutomated = GuiCtrlCreateButton("Prepare system and install benchmarks",25 * $iDPIRat,105 * $iDPIRat,400 * $iDPIRat,41 * $iDPIRat) $TipLabel = GUICtrlCreateLabel("Press CTRL + ALT + Q to quit the script at any time, CTRL + ALT + G to enter GOD MODE", 0,160 * $iDPIRat,450 * $iDPIRat,20 * $iDPIRat,$SS_CENTER) GuiCtrlSetColor($TipLabel,0x777777) GUICtrlSetFont($Tiplabel,7,400) GUISetState(@SW_SHOW,$FormMainGUI) GUISetOnEvent($GUI_EVENT_CLOSE,"CloseGui") Sleep(10000) ;************************************************** ;Kill the Program Func CloseGui() Exit EndFuncThanks,Unexpectedpanda Edited August 29, 2012 by unexpectedpanda Link to comment Share on other sites More sharing options...
JFX Posted August 27, 2012 Share Posted August 27, 2012 insteed GUISetIcon try this _GUISetIcon function: Link to comment Share on other sites More sharing options...
unexpectedpanda Posted August 27, 2012 Author Share Posted August 27, 2012 (edited) That seems to work well for the referenced shell32.dll, no dice for the included .ico though. Here's the code I tried below, still getting a blurry icon -- guessing I'm not referencing properly? expandcollapse popup#Region ;**** Directives created by AutoIt3Wrapper_GUI **** #AutoIt3Wrapper_Version=beta #AutoIt3Wrapper_Icon=cnet.ico #AutoIt3Wrapper_Outfile=test2.exe #AutoIt3Wrapper_Res_Description=test #AutoIt3Wrapper_Res_Fileversion=0.992.0.0 #AutoIt3Wrapper_Res_requestedExecutionLevel=requireAdministrator #AutoIt3Wrapper_Res_Compatibility=Windows7 #AutoIt3Wrapper_Res_HiDpi=1 #EndRegion ;**** Directives created by AutoIt3Wrapper_GUI **** TraySetIcon(@ScriptDir & "\cnet.ico",1) #include <GUIConstantsEx.au3> #include <WindowsConstants.au3> #include <StaticConstants.au3> #include <_GetDPI.au3> Opt("GUIOnEventMode", 1) $a1 = _GetDPI() $iDPIRat = $a1[2] $FormMainGUI = GUICreate("test", 450 * $iDPIRat, 190 * $iDPIRat) _GUISetIcon($FormMainGUI, @ScriptDir & "\cnet.ico", 1); name and not ordinal value $Administratorlbl = GUICtrlCreateLabel("You MUST be signed into an administrative account before running installation",0,85 * $iDPIRat,450 * $iDPIRat,20 * $iDPIRat,$SS_CENTER) GuiCtrlSetColor($Administratorlbl,0x777777) GuiCtrlSetFont($Administratorlbl,7,400) $btnAutomated = GuiCtrlCreateButton("Prepare system and install benchmarks",25 * $iDPIRat,105 * $iDPIRat,400 * $iDPIRat,41 * $iDPIRat) $TipLabel = GUICtrlCreateLabel("Press CTRL + ALT + Q to quit the script at any time, CTRL + ALT + G to enter GOD MODE", 0,160 * $iDPIRat,450 * $iDPIRat,20 * $iDPIRat,$SS_CENTER) GuiCtrlSetColor($TipLabel,0x777777) GUICtrlSetFont($Tiplabel,7,400) GUISetState(@SW_SHOW,$FormMainGUI) GUISetOnEvent($GUI_EVENT_CLOSE,"CloseGui") Sleep(10000) ;************************************************** ;Kill the Program Func CloseGui() Exit EndFunc ;*************************************************** ;Set high-res window icons Func _GUISetIcon($hGui, $sModule, $iName); this for loaded modules in this shape Local $a_hCall = DllCall("kernel32.dll", "hwnd", "GetModuleHandleW", "wstr", $sModule) Local $hModule = $a_hCall[0] $a_hCall = DllCall("user32.dll", "hwnd", "LoadImageW", _ "hwnd", $hModule, _ "int", $iName, _ "dword", 1, _; IMAGE_ICON "int", 32, _ "int", 32, _ "dword", 0); LR_DEFAULTCOLOR Local $hIcon = $a_hCall[0] DllCall("user32.dll", "hwnd", "SendMessageW", _ "hwnd", $hGui, _ "dword", 0x0080, _; WM_SETICON "dword", 1, _; 1 = ICON_BIG, 0 = ICON_SMALL "hwnd", $hIcon) EndFunc ;==>_GUISetIcon Edited August 27, 2012 by unexpectedpanda Link to comment Share on other sites More sharing options...
JFX Posted August 27, 2012 Share Posted August 27, 2012 Try this, it should load successfully the main icon "99" of your exe with 32x32 pixel. expandcollapse popup#Region ;**** Directives created by AutoIt3Wrapper_GUI **** #AutoIt3Wrapper_Version=beta #AutoIt3Wrapper_Icon=cnet.ico #AutoIt3Wrapper_Outfile=test2.exe #AutoIt3Wrapper_UseUpx=n #AutoIt3Wrapper_Res_Description=test #AutoIt3Wrapper_Res_Fileversion=0.992.0.0 #AutoIt3Wrapper_Res_requestedExecutionLevel=requireAdministrator #AutoIt3Wrapper_Res_Compatibility=Windows7 #EndRegion ;**** Directives created by AutoIt3Wrapper_GUI **** #AutoIt3Wrapper_Res_HiDpi=1 TraySetIcon(@ScriptDir & "\cnet.ico",1) #include <GUIConstantsEx.au3> #include <WindowsConstants.au3> #include <StaticConstants.au3> #include <_GetDPI.au3> Opt("GUIOnEventMode", 1) $a1 = _GetDPI() $iDPIRat = $a1[2] $FormMainGUI = GUICreate("test", 450 * $iDPIRat, 190 * $iDPIRat) _GUISetIcon($FormMainGUI, "", 99); name and not ordinal value $Administratorlbl = GUICtrlCreateLabel("You MUST be signed into an administrative account before running installation",0,85 * $iDPIRat,450 * $iDPIRat,20 * $iDPIRat,$SS_CENTER) GuiCtrlSetColor($Administratorlbl,0x777777) GuiCtrlSetFont($Administratorlbl,7,400) $btnAutomated = GuiCtrlCreateButton("Prepare system and install benchmarks",25 * $iDPIRat,105 * $iDPIRat,400 * $iDPIRat,41 * $iDPIRat) $TipLabel = GUICtrlCreateLabel("Press CTRL + ALT + Q to quit the script at any time, CTRL + ALT + G to enter GOD MODE", 0,160 * $iDPIRat,450 * $iDPIRat,20 * $iDPIRat,$SS_CENTER) GuiCtrlSetColor($TipLabel,0x777777) GUICtrlSetFont($Tiplabel,7,400) GUISetState(@SW_SHOW,$FormMainGUI) GUISetOnEvent($GUI_EVENT_CLOSE,"CloseGui") Sleep(10000) ;************************************************** ;Kill the Program Func CloseGui() Exit EndFunc ;*************************************************** ;Set high-res window icons Func _GUISetIcon($hGui, $sModule, $iName); this for loaded modules in this shape IF $sModule = "" Then Local $a_hCall = DllCall("kernel32.dll", "hwnd", "GetModuleHandleW", "ptr", 0) Else Local $a_hCall = DllCall("kernel32.dll", "hwnd", "GetModuleHandleW", "wstr", $sModule) EndIf Local $hModule = $a_hCall[0] $a_hCall = DllCall("user32.dll", "hwnd", "LoadImageW", _ "hwnd", $hModule, _ "int", $iName, _ "dword", 1, _; IMAGE_ICON "int", 32, _ "int", 32, _ "dword", 0); LR_DEFAULTCOLOR Local $hIcon = $a_hCall[0] DllCall("user32.dll", "hwnd", "SendMessageW", _ "hwnd", $hGui, _ "dword", 0x0080, _; WM_SETICON "dword", 1, _; 1 = ICON_BIG, 0 = ICON_SMALL "hwnd", $hIcon) EndFunc ;==>_GUISetIcon Link to comment Share on other sites More sharing options...
unexpectedpanda Posted August 27, 2012 Author Share Posted August 27, 2012 Ah wonderful, it works, thank you so much! So now it's referencing the icon with the resource name "99" in the file itself -- fancy Adding this to the source: ;Special thanks to JFX for making the high res icon code work from TranceXX Link to comment Share on other sites More sharing options...
unexpectedpanda Posted August 28, 2012 Author Share Posted August 28, 2012 New complication: I set different sized icons for different levels of DPI scaling, which now properly scales the tray and window icons. Sadly, the ALT+TAB and tray icons (which are much larger images) are now scaling incorrectly, as they're using the smaller sizes I've set for the window icon. As an interesting aside, calling MsgBox scales the icon perfectly for the taskbar (although displays nothing on ALT+TAB). Don't know if it's possible to separate the window icon from ALT-TAB and Tray? I'm afraid the DLL calling stuff is a little beyond me at this stage! Func _GUISetIcon($hGui, $sModule, $iName); this for loaded modules in this shape If $sModule = "" Then Local $a_hCall = DllCall("kernel32.dll", "hwnd", "GetModuleHandleW", "ptr", 0) Else Local $a_hCall = DllCall("kernel32.dll", "hwnd", "GetModuleHandleW", "wstr", $sModule) EndIf Local $hModule = $a_hCall[0] If $a1[1] >= 96 and $a1[1] < 120 Then $iconsize = 16 If $a1[1] >= 120 and $a1[1] < 144 Then $iconsize = 20 If $a1[1] >= 144 and $a1[1] < 192 Then $iconsize = 24 If $a1[1] >= 192 Then $iconsize = 32 $a_hCall = DllCall("user32.dll", "hwnd", "LoadImageW", _ "hwnd", $hModule, _ "int", $iName, _ "dword", 1, _; IMAGE_ICON "int", $iconsize, _ "int", $iconsize, _ "dword", 0); LR_DEFAULTCOLOR Local $hIcon = $a_hCall[0] DllCall("user32.dll", "hwnd", "SendMessageW", _ "hwnd", $hGui, _ "dword", 0x0080, _; WM_SETICON "dword", 1, _; 1 = ICON_BIG, 0 = ICON_SMALL "hwnd", $hIcon) EndFunc ;==>_GUISetIcon Link to comment Share on other sites More sharing options...
unexpectedpanda Posted August 29, 2012 Author Share Posted August 29, 2012 So this took much, much longer to figure out than I care to admit, but here's what fixed all the icons for me up to 200% DPI, with independent scaling of taskbar/ALT+TAB icons and the sysmenu icon. I'm sure you can do that DLL call in one go but I'm not yet experienced enough to figure out how to do so. expandcollapse popup;************************************************** ;Window icon resizing ;************************************************** ;Version 1.1 | Last updated 29 August 2012 ; ; Special thanks to JFX, TranceXX, ProgAndy, guinness and Yashied, ; whose separate coding efforts enabled this ; ;-------------------------------------------------- ;*************************************************** ;Set high-res window icons Func _GUISetIcon($hGui, $sModule, $iName); this for loaded modules in this shape If $sModule = "" Then Local $a_hCall = DllCall("kernel32.dll", "hwnd", "GetModuleHandleW", "ptr", 0) Else Local $a_hCall = DllCall("kernel32.dll", "hwnd", "GetModuleHandleW", "wstr", $sModule) EndIf Local $hModule = $a_hCall[0] If $a1[1] >= 96 and $a1[1] < 120 Then $iconsize = 16 $tasksize = 32 EndIf If $a1[1] >= 120 and $a1[1] < 144 Then $iconsize = 20 $tasksize = 48 EndIf If $a1[1] >= 144 and $a1[1] < 192 Then $iconsize = 24 $tasksize = 48 EndIf If $a1[1] >= 192 Then $iconsize = 32 $tasksize = 256 EndIf $a_hCall = DllCall("user32.dll", "hwnd", "LoadImageW", _ "hwnd", $hModule, _ "int", $iName, _ "dword", 1, _; IMAGE_ICON "int", $iconsize, _ ;x width "int", $iconsize, _ ;y height "dword", 0); LR_DEFAULTCOLOR Local $hIcon = $a_hCall[0] DllCall("user32.dll", "hwnd", "SendMessageW", _ "hwnd", $hGui, _ "dword", 0x0080, _; WM_SETICON "dword", 0, _; 1 = ICON_BIG, 0 = ICON_SMALL "hwnd", $hIcon) $a_hCall = DllCall("user32.dll", "hwnd", "LoadImageW", _ "hwnd", $hModule, _ "int", $iName, _ "dword", 1, _; IMAGE_ICON "int", $tasksize, _ ;x width "int", $tasksize, _ ;y height "dword", 0); LR_DEFAULTCOLOR Local $hIcon = $a_hCall[0] DllCall("user32.dll", "hwnd", "SendMessageW", _ "hwnd", $hGui, _ "dword", 0x0080, _; WM_SETICON "dword", 1, _; 1 = ICON_BIG, 0 = ICON_SMALL "hwnd", $hIcon) EndFunc ;==>_GUISetIcon Link to comment Share on other sites More sharing options...
Recommended Posts
Create an account or sign in to comment
You need to be a member in order to leave a comment
Create an account
Sign up for a new account in our community. It's easy!
Register a new accountSign in
Already have an account? Sign in here.
Sign In Now