WildByDesign Posted May 17 Posted May 17 I'm working on a dark mode version of Toolbars for GUIDarkTheme UDF and it's going very well. The only problem that I am trying to figure out is how to add custom icons with the _GUICtrlToolbar_AddButton function. Ideally, I would like to try adding toolbar icons created from the Segoe Fluent Icons or Segoe MDL2 Assets icon sets. This way, the icons could easily support monochrome, dark mode, etc. The _GUICtrlToolbar_AddButton makes no mention of using custom icons or adding an icon by handle or anything like that. There are, however, functions related to ImageList of these buttons: _GUICtrlToolbar_GetDisabledImageList - along with related *Set* function _GUICtrlToolbar_GetHotImageList - along with related *Set* function _GUICtrlToolbar_GetImageList - along with related *Set* function From WinAPIConstants.au3 we have: ; Standard Icon Index Constants Global Const $STD_CUT = 0 Global Const $STD_COPY = 1 Global Const $STD_PASTE = 2 Global Const $STD_UNDO = 3 Global Const $STD_REDOW = 4 Global Const $STD_DELETE = 5 Global Const $STD_FILENEW = 6 Global Const $STD_FILEOPEN = 7 Global Const $STD_FILESAVE = 8 Global Const $STD_PRINTPRE = 9 Global Const $STD_PROPERTIES = 10 Global Const $STD_HELP = 11 Global Const $STD_FIND = 12 Global Const $STD_REPLACE = 13 Global Const $STD_PRINT = 14 Would I essentially need to destroy those ImageLists and recreate the ImageLists to replace those specific Standard Icons? If Yes, that is good. That would make sense and cover the standard icons that users may already be using in their AutoIt GUI scripts that have toolbars. However, finding a way to add completely custom icons to the toolbar which are not related to those standard icons would also be important if possible. This thread is all about making toolbars (ToolbarWindow32 class) great again! The following example from @Nine should serve as a good starting point. Please note that the toolbar background fill color does not extend when the GUI is resized bigger. If anyone knows how to fix that, please let me know. Thank you. expandcollapse popup; From Nine #include <GUIConstants.au3> #include <WinAPI.au3> #include <StructureConstants.au3> #include <GuiToolbar.au3> ; Initialize System DPI awareness DllCall("user32.dll", "bool", "SetProcessDpiAwarenessContext", @AutoItX64 ? "int64" : "int", -2) Opt("MustDeclareVars", True) Global Const $tagNMTBCUSTOMDRAW = $tagNMHDR & ";dword dwDrawStage;handle hdc;" & $tagRECT & ";dword_ptr dwItemSpec;uint uItemState;lparam lItemlParam;" & _ "ptr hbrMonoDither;ptr hbrLines;ptr hpenLines;dword clrText;dword clrMark;dword clrTextHighlight;dword clrBtnFace;dword clrBtnHighlight;dword clrHighlightHotTrack;" & _ "long TextLeft;long TextTop;long TextRight;long TextBottom;int nStringBkMode;int nHLStringBkMode;int iListGap;" Global Const $TBCDRF_NOBACKGROUND = 0x400000 Global Const $TBCDRF_HILITEHOTTRACK = 0x20000 Example() Func Example() Local Enum $e_idNew = 1000, $e_idOpen, $e_idSave, $e_idHelp Local $hGUI = GUICreate("Toolbar", 600, 400, -1, -1, $WS_OVERLAPPEDWINDOW) GUISetBkColor(0x202020) Local $hToolbar = _GUICtrlToolbar_Create($hGUI) ; Set theme for toolbar. Should work on both Win10/11. ; This works well enough to not need to use WM_NOTIFY, but that gives us more control. _GUICtrlToolbar_SetWindowTheme($hToolbar, 'DarkMode') _GUICtrlToolbar_SetColorScheme($hToolbar, 0x383838, 0x383838) _GUICtrlToolbar_SetStyleTransparent($hToolbar, False) ; this can be useful, particularly without WM_NOTIFY _GUICtrlToolbar_AddBitmap($hToolbar, 1, -1, $IDB_STD_LARGE_COLOR) _GUICtrlToolbar_AddButton($hToolbar, $e_idNew, $STD_FILENEW) _GUICtrlToolbar_AddButton($hToolbar, $e_idOpen, $STD_FILEOPEN) _GUICtrlToolbar_AddButton($hToolbar, $e_idSave, $STD_FILESAVE) _GUICtrlToolbar_AddButtonSep($hToolbar, 20) _GUICtrlToolbar_AddButton($hToolbar, $e_idHelp, $STD_HELP) GUIRegisterMsg($WM_NOTIFY, WM_NOTIFY) GUISetState() Do Until GUIGetMsg() = $GUI_EVENT_CLOSE _GUICtrlToolbar_Destroy($hToolbar) EndFunc ;==>Example Func WM_NOTIFY($hWnd, $iMsg, $wParam, $lParam) Local $tTool = DllStructCreate($tagNMTBCUSTOMDRAW, $lParam) If _WinAPI_GetClassName($tTool.hWndFrom) <> "ToolbarWindow32" Or $tTool.Code <> $NM_CUSTOMDRAW Then Return $GUI_RUNDEFMSG If $tTool.dwDrawStage = $CDDS_PREPAINT Then Local $hBrush = _WinAPI_CreateSolidBrush(0x383838) Local $tRect = DllStructCreate($tagRECT, DllStructGetPtr($tTool, "left")) _WinAPI_FillRect($tTool.hdc, $tRect, $hBrush) _WinAPI_DeleteObject($hBrush) Return $CDRF_NOTIFYITEMDRAW ElseIf $tTool.dwDrawStage = $CDDS_ITEMPREPAINT And BitAND($tTool.uItemState, $CDIS_HOT) Then $tTool.clrHighlightHotTrack = BitAND($tTool.uItemState, $CDIS_SELECTED) ? 0x484848 : 0x606060 Return $TBCDRF_HILITEHOTTRACK EndIf Return $GUI_RUNDEFMSG EndFunc ;==>WM_NOTIFY
WildByDesign Posted May 17 Author Posted May 17 Now, skipping ahead of myself for a moment here, let's assume that I am able to create these custom icons to replace the standard icons index while in dark mode. The easiest way (I assume) for an already existing GUI script with toolbar (such as Helpfile toolbar examples) to benefit from this would be to add them as Local Const to override the Global Const and to retain the same value numbers: ; Standard Icon Index Constants (now in a dark mode function) Local Const $STD_CUT = 0 Local Const $STD_COPY = 1 Local Const $STD_PASTE = 2 Local Const $STD_UNDO = 3 Local Const $STD_REDOW = 4 Local Const $STD_DELETE = 5 Local Const $STD_FILENEW = 6 Local Const $STD_FILEOPEN = 7 Local Const $STD_FILESAVE = 8 Local Const $STD_PRINTPRE = 9 Local Const $STD_PROPERTIES = 10 Local Const $STD_HELP = 11 Local Const $STD_FIND = 12 Local Const $STD_REPLACE = 13 Local Const $STD_PRINT = 14
WildByDesign Posted May 17 Author Posted May 17 By the way, some of this is just gameplanning stages. Just trying to think a few steps ahead.
WildByDesign Posted May 17 Author Posted May 17 I was just testing the helpfile script from the _GUICtrlToolbar_SetImageList page and that example script does almost everything that I was hoping for. Incredible example. That example covers modifying the 3 different ImageLists related to Toolbar controls. So that shows that my initial idea is possible which is fantastic. Now it really comes down to properly creating the Bitmaps to go into those ImageLists. I personally always get confused between Bitmap, hBitmap, and HBITMAP because I have made mistakes before based on those differences.
WildByDesign Posted May 17 Author Posted May 17 (edited) Does anyone know if we can get the value (eg. $STD_FILEOPEN) of the toolbar button being drawn within the WM_NOTIFY parameters? Or from the NMCUSTOMDRAW? If yes, we may be able to avoid creating the bitmaps and messing with ImageLists and simply FillRect and DrawText the equivalent from Fluent font file by its unicode value. Edited May 17 by WildByDesign
WildByDesign Posted May 17 Author Posted May 17 I was finally able to get a custom font icon to show on the toolbar which is neat. But I think I may be in way over my head. I have no idea how to make sure that the text fits perfectly (size) or centered vertically/horizontally. I'm kind of losing this battle. My GDI+ knowledge is exactly zero. I don't even know how to make the text white. expandcollapse popup#include <GUIConstantsEx.au3> #include <GuiImageList.au3> #include <GuiToolbar.au3> #include <WinAPIGdi.au3> #include <WindowsStylesConstants.au3> #include <GDIPlus.au3> _GDIPlus_Startup() ; Initialize System DPI awareness DllCall("user32.dll", "bool", "SetProcessDpiAwarenessContext", @AutoItX64 ? "int64" : "int", -2) Example() Func Example() ; Create GUI Local $hGUI = GUICreate("Toolbar Get/Set ImageList (v" & @AutoItVersion & ")", 400, 300, -1, -1, $WS_OVERLAPPEDWINDOW) GUISetBkColor(0x202020) Local $hToolbar = _GUICtrlToolbar_Create($hGUI) _GUICtrlToolbar_SetWindowTheme($hToolbar, 'DarkMode') _GUICtrlToolbar_SetColorScheme($hToolbar, 0x383838, 0x383838) _GUICtrlToolbar_SetStyleTransparent($hToolbar, False) ; get imagelist size ;Local $hImageList = _GUICtrlToolbar_GetImageList($hToolbar) ;Local $aSize = _GUIImageList_GetIconSize($hImageList) ;Local $iW = $aSize[0] ;Local $iH = $aSize[1] Local $iW = 24 Local $iH = 24 Local $hBitmap = _GDIPlus_BitmapCreateFromScan0($iW, $iW) Local $hBmpCtxt = _GDIPlus_ImageGetGraphicsContext($hBitmap) ;get the graphics context of the bitmap _GDIPlus_GraphicsSetSmoothingMode($hBmpCtxt, $GDIP_SMOOTHINGMODE_HIGHQUALITY) _GDIPlus_GraphicsClear($hBmpCtxt, 0xFFFFFFFF) _GDIPlus_GraphicsSetTextRenderingHint($hBmpCtxt, $GDIP_TEXTRENDERINGHINTANTIALIASGRIDFIT) _GDIPlus_GraphicsDrawString($hBmpCtxt, ChrW(0xE64E), 0, 0, "Segoe MDL2 Assets", 12) $hHBMP = _GDIPlus_BitmapCreateHBITMAPFromBitmap($hBitmap) ; Create normal image list Local $hNormal = _GUIImageList_Create($iW, $iW) ;_GUIImageList_Add($hNormal, _WinAPI_CreateSolidBitmap($hGUI, 0xFF0000, $iW, $iW)) _GUIImageList_Add($hNormal, $hHBMP) _GUIImageList_Add($hNormal, $hHBMP) _GUIImageList_Add($hNormal, $hHBMP) ;_GUIImageList_Add($hNormal, _WinAPI_CreateSolidBitmap($hGUI, 0x00FF00, $iW, $iW)) ;_GUIImageList_Add($hNormal, _WinAPI_CreateSolidBitmap($hGUI, 0x0000FF, $iW, $iW)) Local $hPrevImageList = _GUICtrlToolbar_SetImageList($hToolbar, $hNormal) ; Create disabled image list Local $hDisabled = _GUIImageList_Create($iW, $iW) _GUIImageList_Add($hDisabled, _WinAPI_CreateSolidBitmap($hGUI, 0xCCCCCC, $iW, $iW)) _GUIImageList_Add($hDisabled, _WinAPI_CreateSolidBitmap($hGUI, 0xCCCCCC, $iW, $iW)) _GUIImageList_Add($hDisabled, _WinAPI_CreateSolidBitmap($hGUI, 0xCCCCCC, $iW, $iW)) _GUICtrlToolbar_SetDisabledImageList($hToolbar, $hDisabled) ; Create hot image list Local $hHot = _GUIImageList_Create($iW, $iW) _GUIImageList_Add($hHot, _WinAPI_CreateSolidBitmap($hGUI, 0x111111, $iW, $iW)) _GUIImageList_Add($hHot, _WinAPI_CreateSolidBitmap($hGUI, 0x888888, $iW, $iW)) _GUIImageList_Add($hHot, _WinAPI_CreateSolidBitmap($hGUI, 0xAAAAAA, $iW, $iW)) _GUICtrlToolbar_SetHotImageList($hToolbar, $hHot) ; Add buttons Local Enum $idRed = 1000, $idGreen, $idBlue _GUICtrlToolbar_AddButton($hToolbar, $idRed, 0) _GUICtrlToolbar_AddButton($hToolbar, $idGreen, 1) _GUICtrlToolbar_AddButton($hToolbar, $idBlue, 2) GUISetState(@SW_SHOW) ; Disable Blue button ;_GUICtrlToolbar_EnableButton($hToolbar, $idBlue, False) ; Loop until the user exits. Do Until GUIGetMsg() = $GUI_EVENT_CLOSE _GDIPlus_GraphicsDispose($hBmpCtxt) _GDIPlus_BitmapDispose($hBitmap) _GDIPlus_Shutdown() EndFunc ;==>Example
WildByDesign Posted June 6 Author Posted June 6 I finally had a bit of time to make some more progress on the custom toolbar buttons. It's nice and sharp which is good. But I don't know how to measure the font size drawn with _GDIPlus_GraphicsDrawString to ensure that it fits properly inside the box and does not get clipped. Alignment, size, etc. I'm not sure how to guarantee that part of it. Anyway, this is a standard Win32 toolbar with custom buttons: expandcollapse popup#include <GUIConstantsEx.au3> #include <GuiImageList.au3> #include <GuiToolbar.au3> #include <WinAPIGdi.au3> #include <WindowsStylesConstants.au3> #include <GDIPlus.au3> _GDIPlus_Startup() ; Initialize System DPI awareness DllCall("user32.dll", "bool", "SetProcessDpiAwarenessContext", @AutoItX64 ? "int64" : "int", -2) Example() Func Example() ; Create GUI Local $hGUI = GUICreate("Toolbar Get/Set ImageList (v" & @AutoItVersion & ")", 400, 300, -1, -1, $WS_OVERLAPPEDWINDOW) GUISetBkColor(0x202020) Local $hToolbar = _GUICtrlToolbar_Create($hGUI) _GUICtrlToolbar_SetWindowTheme($hToolbar, 'DarkMode') _GUICtrlToolbar_SetColorScheme($hToolbar, 0x383838, 0x383838) _GUICtrlToolbar_SetStyleTransparent($hToolbar, False) ; get imagelist size ;Local $hImageList = _GUICtrlToolbar_GetImageList($hToolbar) ;Local $aSize = _GUIImageList_GetIconSize($hImageList) ;Local $iW = $aSize[0] ;Local $iH = $aSize[1] Local $iW = 48 Local $iH = 48 Local $hBitmapBack = _GDIPlus_BitmapCreateFromScan0($iW, $iW) Local $hBmpCtxtBack = _GDIPlus_ImageGetGraphicsContext($hBitmapBack) ;get the graphics context of the bitmap _GDIPlus_GraphicsSetSmoothingMode($hBmpCtxtBack, $GDIP_SMOOTHINGMODE_HIGHQUALITY) _GDIPlus_GraphicsClear($hBmpCtxtBack, 0xFF383838) _GDIPlus_GraphicsSetTextRenderingHint($hBmpCtxtBack, $GDIP_TEXTRENDERINGHINTANTIALIASGRIDFIT) _GDIPlus_GraphicsDrawString($hBmpCtxtBack, ChrW(0xE64E), 0, 0, "Segoe MDL2 Assets", 24, 0, 0xFFFFFFFF) $hHBMPBack = _GDIPlus_BitmapCreateHBITMAPFromBitmap($hBitmapBack) Local $hBitmapForward = _GDIPlus_BitmapCreateFromScan0($iW, $iW) Local $hBmpCtxtForward = _GDIPlus_ImageGetGraphicsContext($hBitmapForward) ;get the graphics context of the bitmap _GDIPlus_GraphicsSetSmoothingMode($hBmpCtxtForward, $GDIP_SMOOTHINGMODE_HIGHQUALITY) _GDIPlus_GraphicsClear($hBmpCtxtForward, 0xFF383838) _GDIPlus_GraphicsSetTextRenderingHint($hBmpCtxtForward, $GDIP_TEXTRENDERINGHINTANTIALIASGRIDFIT) _GDIPlus_GraphicsDrawString($hBmpCtxtForward, ChrW(0xE64D), 0, 0, "Segoe MDL2 Assets", 24, 0, 0xFFFFFFFF) $hHBMPForward = _GDIPlus_BitmapCreateHBITMAPFromBitmap($hBitmapForward) Local $hBitmapUp = _GDIPlus_BitmapCreateFromScan0($iW, $iW) Local $hBmpCtxtUp = _GDIPlus_ImageGetGraphicsContext($hBitmapUp) ;get the graphics context of the bitmap _GDIPlus_GraphicsSetSmoothingMode($hBmpCtxtUp, $GDIP_SMOOTHINGMODE_HIGHQUALITY) _GDIPlus_GraphicsClear($hBmpCtxtUp, 0xFF383838) _GDIPlus_GraphicsSetTextRenderingHint($hBmpCtxtUp, $GDIP_TEXTRENDERINGHINTANTIALIASGRIDFIT) _GDIPlus_GraphicsDrawString($hBmpCtxtUp, ChrW(0xE64C), 0, 0, "Segoe MDL2 Assets", 24, 0, 0xFFFFFFFF) $hHBMPUp = _GDIPlus_BitmapCreateHBITMAPFromBitmap($hBitmapUp) ; Create normal image list Local $hNormal = _GUIImageList_Create($iW, $iW) ;_GUIImageList_Add($hNormal, _WinAPI_CreateSolidBitmap($hGUI, 0xFF0000, $iW, $iW)) _GUIImageList_Add($hNormal, $hHBMPBack) _GUIImageList_Add($hNormal, $hHBMPForward) _GUIImageList_Add($hNormal, $hHBMPUp) ;_GUIImageList_Add($hNormal, _WinAPI_CreateSolidBitmap($hGUI, 0x00FF00, $iW, $iW)) ;_GUIImageList_Add($hNormal, _WinAPI_CreateSolidBitmap($hGUI, 0x0000FF, $iW, $iW)) Local $hPrevImageList = _GUICtrlToolbar_SetImageList($hToolbar, $hNormal) ; Create disabled image list Local $hDisabled = _GUIImageList_Create($iW, $iW) _GUIImageList_Add($hDisabled, $hHBMPBack) _GUIImageList_Add($hDisabled, $hHBMPForward) _GUIImageList_Add($hDisabled, $hHBMPUp) ;_GUIImageList_Add($hDisabled, _WinAPI_CreateSolidBitmap($hGUI, 0xCCCCCC, $iW, $iW)) ;_GUIImageList_Add($hDisabled, _WinAPI_CreateSolidBitmap($hGUI, 0xCCCCCC, $iW, $iW)) ;_GUIImageList_Add($hDisabled, _WinAPI_CreateSolidBitmap($hGUI, 0xCCCCCC, $iW, $iW)) _GUICtrlToolbar_SetDisabledImageList($hToolbar, $hDisabled) ; Create hot image list Local $hHot = _GUIImageList_Create($iW, $iW) _GUIImageList_Add($hHot, $hHBMPBack) _GUIImageList_Add($hHot, $hHBMPForward) _GUIImageList_Add($hHot, $hHBMPUp) ;_GUIImageList_Add($hHot, _WinAPI_CreateSolidBitmap($hGUI, 0xff00ff, $iW, $iW)) ;_GUIImageList_Add($hHot, _WinAPI_CreateSolidBitmap($hGUI, 0xff0000, $iW, $iW)) ;_GUIImageList_Add($hHot, _WinAPI_CreateSolidBitmap($hGUI, 0x0000ff, $iW, $iW)) _GUICtrlToolbar_SetHotImageList($hToolbar, $hHot) ; Add buttons Local Enum $idRed = 1000, $idGreen, $idBlue _GUICtrlToolbar_AddButton($hToolbar, $idRed, 0) _GUICtrlToolbar_AddButton($hToolbar, $idGreen, 1) _GUICtrlToolbar_AddButton($hToolbar, $idBlue, 2) GUISetState(@SW_SHOW) ; Disable Blue button ;_GUICtrlToolbar_EnableButton($hToolbar, $idBlue, False) ; Loop until the user exits. Do Until GUIGetMsg() = $GUI_EVENT_CLOSE _GDIPlus_GraphicsDispose($hBmpCtxtBack) _GDIPlus_BitmapDispose($hBitmapBack) _GDIPlus_GraphicsDispose($hBmpCtxtForward) _GDIPlus_BitmapDispose($hBitmapForward) _GDIPlus_GraphicsDispose($hBmpCtxtUp) _GDIPlus_BitmapDispose($hBitmapUp) _GDIPlus_Shutdown() EndFunc ;==>Example
ahmet Posted June 7 Posted June 7 I think this should work for measuring string: $aInfo = _GDIPlus_GraphicsMeasureString($hGraphic, $sString, $hFont, $tLayout, $hFormat) $tRectMin=$aInfo[0] MsgBox(0,"Min rectangle",$tRectMin.x & ", " & $tRectMin.y & ", " & $tRectMin.width & ", " & $tRectMin.height) WildByDesign 1
argumentum Posted June 7 Posted June 7 19 hours ago, WildByDesign said: ; Initialize System DPI awareness DllCall("user32.dll", "bool", "SetProcessDpiAwarenessContext", @AutoItX64 ? "int64" : "int", -2) Example() Func Example() ; Create GUI Local $hGUI = GUICreate("Toolbar Get/Set ImageList (v" & @AutoItVersion & ")", 400, 300, -1, -1, $WS_OVERLAPPEDWINDOW) ..going to sleep soon. But looking at the code, if my scaling is 175%, that 400x300 is going to look a heck of a lot smaller. So either don't "SetProcessDpiAwarenessContext" or go the whole way. I mean, this is not the finished, ready to run GUI if all the pieces are not there, I think. 😴😪🥱 g'night WildByDesign 1 Follow the link to my code contribution ( and other things too ). FAQ - Please Read Before Posting
WildByDesign Posted June 7 Author Posted June 7 7 hours ago, ahmet said: I think this should work for measuring string: Thank you so much for this. This was really helpful using _GDIPlus_GraphicsMeasureString. Now I understand why so many people love using GDI+. 6 hours ago, argumentum said: So either don't "SetProcessDpiAwarenessContext" This is a very good point. Sorry about that. It makes sense now that the majority of examples shown on the forum are without DPI, so I should share without DPI. Unless, like you said, I go full way with the rest of the DPI measurements and sizing stuff. argumentum 1
WildByDesign Posted yesterday at 12:28 AM Author Posted yesterday at 12:28 AM Does anyone know how to make my toolbar icons transparent? I am having good success creating the custom toolbar buttons from font files. It looks good and all. But I am realizing just how limited I am with the icons not being transparent. Here is the code showing how I am creating the toolbar icons: Local $iW = 48 Local $iH = 48 Local $hBitmapBack = _GDIPlus_BitmapCreateFromScan0($iW, $iW) Local $hBmpCtxtBack = _GDIPlus_ImageGetGraphicsContext($hBitmapBack) ;get the graphics context of the bitmap _GDIPlus_GraphicsSetSmoothingMode($hBmpCtxtBack, $GDIP_SMOOTHINGMODE_HIGHQUALITY) _GDIPlus_GraphicsClear($hBmpCtxtBack, 0xFF383838) ;_GDIPlus_GraphicsSetTextRenderingHint($hBmpCtxtBack, $GDIP_TEXTRENDERINGHINTANTIALIASGRIDFIT) ;_GDIPlus_GraphicsDrawString($hBmpCtxtBack, ChrW(0xE64E), 0, 0, "Segoe MDL2 Assets", 24, 0, 0xFFFFFFFF) Local $hDC = _GDIPlus_GraphicsGetDC($hBmpCtxtBack) Local $hFont = _WinAPI_CreateFont(Round(32), 0, 0, 0, 400, False, False, False, $DEFAULT_CHARSET, _ $OUT_DEFAULT_PRECIS, $CLIP_DEFAULT_PRECIS, $DEFAULT_QUALITY, 0, 'Segoe MDL2 Assets') Local $hOldFont = _WinAPI_SelectObject($hDC, $hFont) _WinAPI_SetTextColor($hDC, _WinAPI_SwitchColor(0xFFFFFF)) _WinAPI_SetBkMode($hDC, $TRANSPARENT) Local $tRECT = _WinAPI_CreateRectEx(0, 0, $iW, $iH) Local $iTextFlags = BitOR($DT_SINGLELINE, $DT_CENTER, $DT_NOCLIP, $DT_VCENTER) _WinAPI_DrawText($hDC, ChrW(0xE72B), $tRECT, $iTextFlags) _GDIPlus_GraphicsReleaseDC($hBmpCtxtBack, $hDC) _WinAPI_SelectObject($hDC, $hOldFont) _WinAPI_DeleteObject($hFont) $hHBMPBack = _GDIPlus_BitmapCreateHBITMAPFromBitmap($hBitmapBack) Here is the current testing script: expandcollapse popup#include <GUIConstantsEx.au3> #include <GuiImageList.au3> #include <GuiToolbar.au3> #include <WinAPIGdi.au3> #include <WindowsStylesConstants.au3> #include <GDIPlus.au3> ; Initialize System DPI awareness ;DllCall("user32.dll", "bool", "SetProcessDpiAwarenessContext", @AutoItX64 ? "int64" : "int", -2) Global Const $TBCDRF_USECDCOLORS = 0x800000 Global Const $tagNMTBCUSTOMDRAW = $tagNMHDR & ";dword dwDrawStage;handle hdc;" & $tagRECT & ";dword_ptr dwItemSpec;uint uItemState;lparam lItemlParam;" & _ "ptr hbrMonoDither;ptr hbrLines;ptr hpenLines;dword clrText;dword clrMark;dword clrTextHighlight;dword clrBtnFace;dword clrBtnHighlight;dword clrHighlightHotTrack;" & _ "long TextLeft;long TextTop;long TextRight;long TextBottom;int nStringBkMode;int nHLStringBkMode;int iListGap;" _GDIPlus_Startup() Example() Func Example() ; Create GUI Local $hGUI = GUICreate("Toolbar Get/Set ImageList (v" & @AutoItVersion & ")", 400, 300, -1, -1, $WS_OVERLAPPEDWINDOW) GUISetBkColor(0x202020) Local $hToolbar = _GUICtrlToolbar_Create($hGUI) ;_GUICtrlToolbar_SetWindowTheme($hToolbar, 'DarkMode') _GUICtrlToolbar_SetColorScheme($hToolbar, 0x202020, 0x202020) _GUICtrlToolbar_SetStyleTransparent($hToolbar, False) ; get imagelist size ;Local $hImageList = _GUICtrlToolbar_GetImageList($hToolbar) ;Local $aSize = _GUIImageList_GetIconSize($hImageList) ;Local $iW = $aSize[0] ;Local $iH = $aSize[1] Local $iW = 48 Local $iH = 48 Local $hBitmapBack = _GDIPlus_BitmapCreateFromScan0($iW, $iW) Local $hBmpCtxtBack = _GDIPlus_ImageGetGraphicsContext($hBitmapBack) ;get the graphics context of the bitmap _GDIPlus_GraphicsSetSmoothingMode($hBmpCtxtBack, $GDIP_SMOOTHINGMODE_HIGHQUALITY) _GDIPlus_GraphicsClear($hBmpCtxtBack, 0xFF383838) ;_GDIPlus_GraphicsSetTextRenderingHint($hBmpCtxtBack, $GDIP_TEXTRENDERINGHINTANTIALIASGRIDFIT) ;_GDIPlus_GraphicsDrawString($hBmpCtxtBack, ChrW(0xE64E), 0, 0, "Segoe MDL2 Assets", 24, 0, 0xFFFFFFFF) Local $hDC = _GDIPlus_GraphicsGetDC($hBmpCtxtBack) Local $hFont = _WinAPI_CreateFont(Round(32), 0, 0, 0, 400, False, False, False, $DEFAULT_CHARSET, _ $OUT_DEFAULT_PRECIS, $CLIP_DEFAULT_PRECIS, $DEFAULT_QUALITY, 0, 'Segoe MDL2 Assets') Local $hOldFont = _WinAPI_SelectObject($hDC, $hFont) _WinAPI_SetTextColor($hDC, _WinAPI_SwitchColor(0xFFFFFF)) _WinAPI_SetBkMode($hDC, $TRANSPARENT) Local $tRECT = _WinAPI_CreateRectEx(0, 0, $iW, $iH) Local $iTextFlags = BitOR($DT_SINGLELINE, $DT_CENTER, $DT_NOCLIP, $DT_VCENTER) _WinAPI_DrawText($hDC, ChrW(0xE72B), $tRECT, $iTextFlags) _GDIPlus_GraphicsReleaseDC($hBmpCtxtBack, $hDC) _WinAPI_SelectObject($hDC, $hOldFont) _WinAPI_DeleteObject($hFont) $hHBMPBack = _GDIPlus_BitmapCreateHBITMAPFromBitmap($hBitmapBack) Local $hBitmapForward = _GDIPlus_BitmapCreateFromScan0($iW, $iW) Local $hBmpCtxtForward = _GDIPlus_ImageGetGraphicsContext($hBitmapForward) ;get the graphics context of the bitmap _GDIPlus_GraphicsSetSmoothingMode($hBmpCtxtForward, $GDIP_SMOOTHINGMODE_HIGHQUALITY) _GDIPlus_GraphicsClear($hBmpCtxtForward, 0xFF383838) ;_GDIPlus_GraphicsSetTextRenderingHint($hBmpCtxtForward, $GDIP_TEXTRENDERINGHINTANTIALIASGRIDFIT) ;_GDIPlus_GraphicsDrawString($hBmpCtxtForward, ChrW(0xE64D), 0, 0, "Segoe MDL2 Assets", 24, 0, 0xFFFFFFFF) Local $hDC = _GDIPlus_GraphicsGetDC($hBmpCtxtForward) Local $hFont = _WinAPI_CreateFont(Round(32), 0, 0, 0, 400, False, False, False, $DEFAULT_CHARSET, _ $OUT_DEFAULT_PRECIS, $CLIP_DEFAULT_PRECIS, $DEFAULT_QUALITY, 0, 'Segoe MDL2 Assets') Local $hOldFont = _WinAPI_SelectObject($hDC, $hFont) _WinAPI_SetTextColor($hDC, _WinAPI_SwitchColor(0xFFFFFF)) _WinAPI_SetBkMode($hDC, $TRANSPARENT) Local $tRECT = _WinAPI_CreateRectEx(0, 0, $iW, $iH) Local $iTextFlags = BitOR($DT_SINGLELINE, $DT_CENTER, $DT_NOCLIP, $DT_VCENTER) _WinAPI_DrawText($hDC, ChrW(0xE72A), $tRECT, $iTextFlags) _GDIPlus_GraphicsReleaseDC($hBmpCtxtForward, $hDC) _WinAPI_SelectObject($hDC, $hOldFont) _WinAPI_DeleteObject($hFont) $hHBMPForward = _GDIPlus_BitmapCreateHBITMAPFromBitmap($hBitmapForward) Local $hBitmapUp = _GDIPlus_BitmapCreateFromScan0($iW, $iW) Local $hBmpCtxtUp = _GDIPlus_ImageGetGraphicsContext($hBitmapUp) ;get the graphics context of the bitmap _GDIPlus_GraphicsSetSmoothingMode($hBmpCtxtUp, $GDIP_SMOOTHINGMODE_HIGHQUALITY) _GDIPlus_GraphicsClear($hBmpCtxtUp, 0xFF383838) ;_GDIPlus_GraphicsSetTextRenderingHint($hBmpCtxtUp, $GDIP_TEXTRENDERINGHINTANTIALIASGRIDFIT) ;_GDIPlus_GraphicsDrawString($hBmpCtxtUp, ChrW(0xE64C), 0, 0, "Segoe MDL2 Assets", 24, 0, 0xFFFFFFFF) Local $hDC = _GDIPlus_GraphicsGetDC($hBmpCtxtUp) Local $hFont = _WinAPI_CreateFont(Round(32), 0, 0, 0, 400, False, False, False, $DEFAULT_CHARSET, _ $OUT_DEFAULT_PRECIS, $CLIP_DEFAULT_PRECIS, $DEFAULT_QUALITY, 0, 'Segoe MDL2 Assets') Local $hOldFont = _WinAPI_SelectObject($hDC, $hFont) _WinAPI_SetTextColor($hDC, _WinAPI_SwitchColor(0xFFFFFF)) _WinAPI_SetBkMode($hDC, $TRANSPARENT) Local $tRECT = _WinAPI_CreateRectEx(0, 0, $iW, $iH) Local $iTextFlags = BitOR($DT_SINGLELINE, $DT_CENTER, $DT_NOCLIP, $DT_VCENTER) _WinAPI_DrawText($hDC, ChrW(0xE74A), $tRECT, $iTextFlags) _GDIPlus_GraphicsReleaseDC($hBmpCtxtUp, $hDC) _WinAPI_SelectObject($hDC, $hOldFont) _WinAPI_DeleteObject($hFont) $hHBMPUp = _GDIPlus_BitmapCreateHBITMAPFromBitmap($hBitmapUp) ; Create normal image list Local $hNormal = _GUIImageList_Create($iW, $iW) ;_GUIImageList_Add($hNormal, _WinAPI_CreateSolidBitmap($hGUI, 0xFF0000, $iW, $iW)) _GUIImageList_Add($hNormal, $hHBMPBack) _GUIImageList_Add($hNormal, $hHBMPForward) _GUIImageList_Add($hNormal, $hHBMPUp) ;_GUIImageList_Add($hNormal, _WinAPI_CreateSolidBitmap($hGUI, 0x00FF00, $iW, $iW)) ;_GUIImageList_Add($hNormal, _WinAPI_CreateSolidBitmap($hGUI, 0x0000FF, $iW, $iW)) Local $hPrevImageList = _GUICtrlToolbar_SetImageList($hToolbar, $hNormal) ; Create disabled image list Local $hDisabled = _GUIImageList_Create($iW, $iW) _GUIImageList_Add($hDisabled, $hHBMPBack) _GUIImageList_Add($hDisabled, $hHBMPForward) _GUIImageList_Add($hDisabled, $hHBMPUp) ;_GUIImageList_Add($hDisabled, _WinAPI_CreateSolidBitmap($hGUI, 0xCCCCCC, $iW, $iW)) ;_GUIImageList_Add($hDisabled, _WinAPI_CreateSolidBitmap($hGUI, 0xCCCCCC, $iW, $iW)) ;_GUIImageList_Add($hDisabled, _WinAPI_CreateSolidBitmap($hGUI, 0xCCCCCC, $iW, $iW)) _GUICtrlToolbar_SetDisabledImageList($hToolbar, $hDisabled) ; Create hot image list Local $hHot = _GUIImageList_Create($iW, $iW) _GUIImageList_Add($hHot, $hHBMPBack) _GUIImageList_Add($hHot, $hHBMPForward) _GUIImageList_Add($hHot, $hHBMPUp) ;_GUIImageList_Add($hHot, _WinAPI_CreateSolidBitmap($hGUI, 0xff00ff, $iW, $iW)) ;_GUIImageList_Add($hHot, _WinAPI_CreateSolidBitmap($hGUI, 0xff0000, $iW, $iW)) ;_GUIImageList_Add($hHot, _WinAPI_CreateSolidBitmap($hGUI, 0x0000ff, $iW, $iW)) _GUICtrlToolbar_SetHotImageList($hToolbar, $hHot) ; Add buttons Local Enum $idRed = 1000, $idGreen, $idBlue _GUICtrlToolbar_AddButton($hToolbar, $idRed, 0) _GUICtrlToolbar_AddButton($hToolbar, $idGreen, 1) _GUICtrlToolbar_AddButton($hToolbar, $idBlue, 2) GUIRegisterMsg($WM_NOTIFY, WM_NOTIFY) GUISetState(@SW_SHOW) ; Disable Blue button ;_GUICtrlToolbar_EnableButton($hToolbar, $idBlue, False) ; Loop until the user exits. Do Until GUIGetMsg() = $GUI_EVENT_CLOSE _GDIPlus_GraphicsDispose($hBmpCtxtBack) _GDIPlus_BitmapDispose($hBitmapBack) _GDIPlus_GraphicsDispose($hBmpCtxtForward) _GDIPlus_BitmapDispose($hBitmapForward) _GDIPlus_GraphicsDispose($hBmpCtxtUp) _GDIPlus_BitmapDispose($hBitmapUp) _GDIPlus_Shutdown() EndFunc ;==>Example Func WM_NOTIFY($hWnd, $iMsg, $wParam, $lParam) Local $tTool = DllStructCreate($tagNMTBCUSTOMDRAW, $lParam) If $tTool.Code <> $NM_CUSTOMDRAW Then Return $GUI_RUNDEFMSG Local Static $iGuiWidth = WinGetClientSize($hWnd)[0] Local Static $iToolbarWidth = _WinAPI_GetWindowWidth($tTool.hWndFrom) Local $dwDrawStage = $tTool.dwDrawStage Local $sClass = _WinAPI_GetClassName($tTool.hWndFrom) Switch $sClass Case "ToolbarWindow32" ; resize toolbar only if toolbar covers full client width If $iToolbarWidth = $iGuiWidth Then Local $aSize = WinGetClientSize($hWnd) WinMove($tTool.hWndFrom, "", 0, 0, $aSize[0]) EndIf Switch $dwDrawStage Case $CDDS_PREPAINT Local $hBrush = _WinAPI_CreateSolidBrush(0x383838) Local $tRect = DllStructCreate($tagRECT, DllStructGetPtr($tTool, "left")) _WinAPI_FillRect($tTool.hdc, $tRect, $hBrush) _WinAPI_DeleteObject($hBrush) Return $CDRF_NOTIFYITEMDRAW Case $CDDS_ITEMPREPAINT Local $iState = $tTool.uItemState If BitAND($iState, $CDIS_HOT) Then $tTool.clrText = 0xFFFFFF $tTool.clrTextHighlight = 0xFFFFFF Local $tRect = DllStructCreate($tagRECT, DllStructGetPtr($tTool, "left")) Local $hPen = _WinAPI_CreatePen($PS_SOLID, 1, 0x6B6B6B) Local $hOldPen = _WinAPI_SelectObject($tTool.hdc, $hPen) Local $hBrush = _WinAPI_CreateSolidBrush(BitAND($iState, $CDIS_SELECTED) ? 0x666666 : 0x383838) Local $hObj = _WinAPI_SelectObject($tTool.hdc, $hBrush) ;_WinAPI_InflateRect($tRect, 0, -2) _WinAPI_RoundRect($tTool.hdc, $tRect, 8, 8) _WinAPI_SelectObject($tTool.hdc, $hObj) ;_WinAPI_SelectObject($tTool.hdc, $hOldPen) _WinAPI_DeleteObject($hBrush) _WinAPI_DeleteObject($hPen) ; clear item state or else this will not work $tTool.uItemState = Null Return $TBCDRF_USECDCOLORS EndIf If BitAND($iState, $CDIS_CHECKED) Then $tTool.clrText = 0xFFFFFF $tTool.clrTextHighlight = 0xFFFFFF Local $tRect = DllStructCreate($tagRECT, DllStructGetPtr($tTool, "left")) Local $hPen = _WinAPI_CreatePen($PS_SOLID, 1, 0x6B6B6B) Local $hOldPen = _WinAPI_SelectObject($tTool.hdc, $hPen) Local $hBrush = _WinAPI_CreateSolidBrush(BitAND($iState, $CDIS_SELECTED) ? 0x666666 : 0x454545) Local $hObj = _WinAPI_SelectObject($tTool.hdc, $hBrush) ;_WinAPI_InflateRect($tRect, 0, -2) _WinAPI_RoundRect($tTool.hdc, $tRect, 8, 8) _WinAPI_SelectObject($tTool.hdc, $hObj) ;_WinAPI_SelectObject($tTool.hdc, $hOldPen) _WinAPI_DeleteObject($hBrush) _WinAPI_DeleteObject($hPen) ; clear item state or else this will not work $tTool.uItemState = Null Return $TBCDRF_USECDCOLORS EndIf If Not BitAND($iState, $CDIS_DISABLED) Then $tTool.clrText = 0xFFFFFF $tTool.clrTextHighlight = 0xFFFFFF Return $TBCDRF_USECDCOLORS EndIf EndSwitch Case Else Return $GUI_RUNDEFMSG EndSwitch Return $GUI_RUNDEFMSG EndFunc ;==>WM_NOTIFY
ahmet Posted 20 hours ago Posted 20 hours ago Take look at _GDIPlus_FontCreate. Drawing with GDIPlus allows you to draw transparent text on any background. Or do you need other functions than drawing text? For transparent images GDIPlus is better choice. I am not sure whether you can draw transparent images using GDI32. WildByDesign 1
WildByDesign Posted 20 hours ago Author Posted 20 hours ago 49 minutes ago, ahmet said: Take look at _GDIPlus_FontCreate. Drawing with GDIPlus allows you to draw transparent text on any background. Or do you need other functions than drawing text? For transparent images GDIPlus is better choice. I am not sure whether you can draw transparent images using GDI32. Thanks. I'm trying out _GDIPlus_FontCreate right now and it does seem great. It paints overtop and is transparent. I think that my problem is my initial Bitmap. This must be where I am losing transparency. If I use icon files, it works no problem because icon files already have transparency. But in this case, I am trying to create my own icon files in memory with font files. But it has to be my bitmap part that is losing the transparency. One thing I know for sure, is that the toolbar icons need the format produced by _GDIPlus_BitmapCreateHBITMAPFromBitmap in the end. I'm thinking about using _WinAPI_TransparentBlt() but don't really understand its complexity.
WildByDesign Posted 19 hours ago Author Posted 19 hours ago So it looks like if I start with an icon instead of Bitmap, I can have transparency: Local $hIcon = _WinAPI_ExtractIcon("shell32.dll", 53, True) Local $hBitmap = _GDIPlus_BitmapCreateFromHICON32($hIcon) Local $hHBitmap = _GDIPlus_BitmapCreateHBITMAPFromBitmap($hBitmap) That works and I should be able to draw on top. But I don't want the actual icon. If I could create my own blank HICON32 of a specific size, this could work. I'm trying to figure out how to do that now.
ahmet Posted 19 hours ago Posted 19 hours ago I think example _GDIPlus_HICONCreateFromBitmap has a nice, working example.
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