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