WildByDesign Posted March 13 Posted March 13 11 minutes ago, UEZ said: Another white line seems to occur at 200% above the menus I believe I have seen this before, although I do not think it is related to the infamous white line at the bottom that all win32-darkmode apps have had to handle. I don't have 200% DPI monitor to test. However, I have a feeling some adjustments may be needed for 200% and above to the _WM_MEASUREITEM() function. Specifically: $t.itemHeight = $iTextHeight + 0.5 You could try different changes there to see if it covers up that top white area. This is just a guess without being able to test at 200% myself.
WildByDesign Posted Tuesday at 12:56 PM Posted Tuesday at 12:56 PM (edited) I really like the customdraw code for the slider/trackbar control. I do have a suggestion to help improve the usability of it. I find that I don't always click on it properly because it gives no indication of whether the cursor is over the thumb or not. In Case $TBCD_THUMB, if possible, I would suggest adding a slightly different color for when the cursor is over the thumb. I don't know exactly how to do it. But I do know that the Case $TBCD_THUMB gets hit up anytime the cursor goes over the thumb specifically. EDIT: All of the trackbar states can be found here although I do not know what their values are. EDIT2: Also, if you don't want to draw the thumb, you can get it from the theme resources: Local $tRECT = _WinAPI_CreateRectEx(0, 0, 15, 24) ; based on my 125% scaling _WinAPI_SetBkMode($hDC, $TRANSPARENT) Local $hTheme = _WinAPI_OpenThemeData($hForm, 'TrackBar') ;Local $tSIZE = __WinAPI_GetThemePartSize($hTheme, $TKP_THUMBBOTTOM, 0, Null, Null, $TS_TRUE) ; need to get tRECT here _WinAPI_DrawThemeBackground($hTheme, 4, 0, $hDC, $tRECT) ; active ;_WinAPI_DrawThemeBackground($hTheme, 4, 3, $hDC, $tRECT) ; hover? Edited Tuesday at 01:33 PM by WildByDesign
UEZ Posted Tuesday at 10:02 PM Author Posted Tuesday at 10:02 PM (edited) This should do the trick: expandcollapse popup... Func _WM_NOTIFY($hWnd, $iMsg, $wParam, $lParam) ... ; --- Slider (msctls_trackbar32) custom drawing --- If $iCode = $NM_CUSTOMDRAW And StringLower(_WinAPI_GetClassName($hWndFrom)) = "msctls_trackbar32" Then Local $tNMCD = DllStructCreate($tagNMCUSTOMDRAW, $lParam) Local $dwStage = $tNMCD.dwDrawStage Local $hDC = $tNMCD.hdc Local $dwItemSpec = $tNMCD.dwItemSpec Switch $dwStage Case $CDDS_PREPAINT $tNMCD.ItemState = BitXOR($tNMCD.ItemState, $CDIS_FOCUS) Return $CDRF_NOTIFYSUBITEMDRAW Case 0x00010001 ;BitOR($CDDS_SUBITEM, $CDDS_ITEMPREPAINT) Switch $dwItemSpec Case $TBCD_THUMB Local $iL = $tNMCD.left Local $iT = $tNMCD.top Local $iR = $tNMCD.right - 1 Local $iB = $tNMCD.bottom Local $iMid = ($iL + $iR) / 2 Local $iSplit = $iB - ($iR - $iL) / 2 ; Hover check via cursor position Local $tPt = DllStructCreate($tagPOINT) DllCall("user32.dll", "bool", "GetCursorPos", "struct*", $tPt) DllCall("user32.dll", "bool", "ScreenToClient", "hwnd", $hWndFrom, "struct*", $tPt) Local $bHot = ($tPt.X >= $iL And $tPt.X <= $iR And $tPt.Y >= $iT And $tPt.Y <= $iB) Local $tPoints = DllStructCreate("int p[10]") $tPoints.p((1)) = $iL $tPoints.p((2)) = $iT $tPoints.p((3)) = $iR $tPoints.p((4)) = $iT $tPoints.p((5)) = $iR $tPoints.p((6)) = $iSplit $tPoints.p((7)) = $iMid $tPoints.p((8)) = $iB $tPoints.p((9)) = $iL $tPoints.p((10)) = $iSplit Local $hBrush = _WinAPI_CreateSolidBrush(_ColorToCOLORREF($bHot ? $COLOR_TAB_ACCENT_LIGHT : $COLOR_TAB_ACCENT)) Local $hPen = _WinAPI_CreatePen(0, 1, _ColorToCOLORREF($COLOR_CONTROL_BG)) Local $hOldBrush = _WinAPI_SelectObject($hDC, $hBrush) Local $hOldPen = _WinAPI_SelectObject($hDC, $hPen) DllCall("gdi32.dll", "bool", "Polygon", "handle", $hDC, "struct*", $tPoints, "int", 5) _WinAPI_SelectObject($hDC, $hOldBrush) _WinAPI_SelectObject($hDC, $hOldPen) _WinAPI_DeleteObject($hBrush) _WinAPI_DeleteObject($hPen) Return $CDRF_SKIPDEFAULT Case $TBCD_CHANNEL Local $hBrush = _WinAPI_CreateSolidBrush(_ColorToCOLORREF($COLOR_MENU_SELECT)) Local $tRECT2 = DllStructCreate($tagRECT) $tRECT2.Left = $tNMCD.left $tRECT2.Top = $tNMCD.top $tRECT2.Right = $tNMCD.right $tRECT2.Bottom = $tNMCD.bottom _WinAPI_FillRect($hDC, $tRECT2, $hBrush) _WinAPI_DeleteObject($hBrush) Return $CDRF_SKIPDEFAULT Case Else Return $CDRF_DODEFAULT ; channel + ticks drawn by Windows EndSwitch EndSwitch EndIf ... Edited Tuesday at 10:03 PM by UEZ WildByDesign 1 Please don't send me any personal message and ask for support! I will not reply! Selection of finest graphical examples at Codepen.io The own fart smells best! ✌Her 'sikim hıyar' diyene bir avuç tuz alıp koşma!¯\_(ツ)_/¯ ٩(●̮̮̃•̃)۶ ٩(-̮̮̃-̃)۶ૐ
WildByDesign Posted Tuesday at 10:14 PM Posted Tuesday at 10:14 PM (edited) 2 hours ago, UEZ said: This should do the trick: This works wonderfully. Thank you. EDIT: After further testing, there appears to be one bug with this. If you have the cursor on the thumb and move the cursor off to the left, right or above the thumb, the color restores properly 100% of the time. Perfect. However, if you have the cursor on the thumb and move the cursor straight down off of the thumb, the color only restores properly approx. 50% of the time. It gets stuck with the hot color in that case. EDIT2: This seems to fix the issue 100%: (adding - 1) Local $bHot = ($tPt.X >= $iL And $tPt.X <= $iR And $tPt.Y >= $iT And $tPt.Y <= $iB - 1) Edited Wednesday at 12:16 AM by WildByDesign UEZ 1
WildByDesign Posted Thursday at 11:51 AM Posted Thursday at 11:51 AM (edited) I have a usability idea to improve the menu. Generally, all programs in Windows with a menubar will have the menubar item text go dim when it is not the foreground window (similar to the titlebar text). This is something that we are lacking and even ModernMenuRaw UDF did not do. Try something like this within your _WM_DRAWITEM and adjust to how you prefer: _WinAPI_SetBkMode($hDC, $TRANSPARENT) ; ... If _WinAPI_GetForegroundWindow() <> $g_hGUI Then $clrText = _WinAPI_ColorAdjustLuma($clrText, -30) ; ... _WinAPI_SetTextColor($hDC, $clrText) I find that it works quite well. I'm not sure what the text color should be exactly, but that can be adjusted to however you think is best. Edited Thursday at 11:54 AM by WildByDesign UEZ 1
UEZ Posted Thursday at 02:58 PM Author Posted Thursday at 02:58 PM 2 hours ago, WildByDesign said: I have a usability idea to improve the menu. Generally, all programs in Windows with a menubar will have the menubar item text go dim when it is not the foreground window (similar to the titlebar text). This is something that we are lacking and even ModernMenuRaw UDF did not do. Try something like this within your _WM_DRAWITEM and adjust to how you prefer: _WinAPI_SetBkMode($hDC, $TRANSPARENT) ; ... If _WinAPI_GetForegroundWindow() <> $g_hGUI Then $clrText = _WinAPI_ColorAdjustLuma($clrText, -30) ; ... _WinAPI_SetTextColor($hDC, $clrText) I find that it works quite well. I'm not sure what the text color should be exactly, but that can be adjusted to however you think is best. Nice idea - added to DPI code. I've a MsgBox in the example when you select About in the menus which is not in dark mode. I created a MsgBoxEx to make also the Windows MsgBox dark. One issue is when you added timer to the MsgBoxEx and drag it around when counter reaches 0 and the MsgBox is closed it will cause a crash -> 0xC000041D It is more or less this code: expandcollapse popup;Coded by UEZ build 2026-03-19 beta #AutoIt3Wrapper_Run_Au3Stripper=y #Au3Stripper_Parameters=/so #Au3Stripper_Ignore_Funcs=_TimerProc #include <ButtonConstants.au3> #include <Timers.au3> #include <WinAPIConstants.au3> #include <WinAPIGdi.au3> #include <WinAPIProc.au3> #include <WinAPISys.au3> #include <WinAPISysWin.au3> #include <WinAPITheme.au3> #include <WindowsConstants.au3> Global Const $BS_PUSHBUTTON = 0x000000 Global Const $COLOR_BG_DARK = 0x202020 Global Const $COLOR_TEXT_LIGHT = 0xF0F0F0 Global Const $COLOR_HOTTRACK_MENU = 0x3A3A3A Const $HCBT_CREATEWND = 3, $HCBT_DESTROYWND = 4, $HCBT_ACTIVATE = 5, $g_iFlagDefault = BitOR($MB_TOPMOST, $MB_ICONINFORMATION) Global $g_hMsgBoxHook, $g_hSubMsgBox, $g_idTImer, $g_sBtn1_Txt = "Close", $g_sBtn2_Txt, $g_sBtn3_Txt Global $g_Timeout = 0, $g_hMsgBoxOldProc, $g_hMsgBoxBrush, $g_hMsgBoxBtn = 0, $g_bMsgBoxClosing = False Global $g_hMsgBoxSubProc = DllCallbackRegister("_MsgBoxProc", "lresult", "hwnd;uint;wparam;lparam") Func _WinAPI_SetDlgItemText($hDlg, $nIDDlgItem, $lpString) ;https://learn.microsoft.com/en-us/windows/win32/api/winuser/nf-winuser-setdlgitemtextw Local $aRet = DllCall("user32.dll", "int", "SetDlgItemText", "hwnd", $hDlg, "int", $nIDDlgItem, "str", $lpString) If @error Then Return SetError(@error, @extended, 0) Return $aRet[0] EndFunc ;==>_WinAPI_SetDlgItemText Func _WinAPI_FindWindowEx($hParent, $sClass, $sTitle = "", $hAfter = 0) Local $ret = DllCall("user32.dll", "hwnd", "FindWindowExW", "hwnd", $hParent, "hwnd", $hAfter, "wstr", $sClass, "wstr", $sTitle) If @error Or Not IsArray($ret) Then Return 0 Return $ret[0] EndFunc ;==>_WinAPI_FindWindowEx Func _ColorToCOLORREF($iColor) ;RGB to BGR Local $iR = BitAND(BitShift($iColor, 16), 0xFF) Local $iG = BitAND(BitShift($iColor, 8), 0xFF) Local $iB = BitAND($iColor, 0xFF) Return BitOR(BitShift($iB, -16), BitShift($iG, -8), $iR) EndFunc ;==>_ColorToCOLORREF Func _MsgBoxProc($hWnd, $iMsg, $wParam, $lParam) If Not $g_hMsgBoxOldProc Then Return _WinAPI_DefWindowProc($hWnd, $iMsg, $wParam, $lParam) Switch $iMsg Case $WM_CTLCOLORSTATIC, $WM_CTLCOLORDLG, $WM_CTLCOLORBTN _WinAPI_SetTextColor($wParam, _ColorToCOLORREF($COLOR_TEXT_LIGHT)) _WinAPI_SetBkColor($wParam, _ColorToCOLORREF($COLOR_BG_DARK)) Return $g_hMsgBoxBrush Case $WM_ERASEBKGND ; Paint entire dialog background including button area Local $tRECT = _WinAPI_GetClientRect($hWnd) _WinAPI_FillRect($wParam, $tRECT, $g_hMsgBoxBrush) Return 1 Case $WM_PAINT Local $iRet = _WinAPI_CallWindowProc($g_hMsgBoxOldProc, $hWnd, $iMsg, $wParam, $lParam) Local $hDC = _WinAPI_GetDC($hWnd) Local $tRECT = _WinAPI_GetClientRect($hWnd), $tRECT2 $tRECT.top = $tRECT.bottom - 42 Local $hBrushFooter = _WinAPI_CreateSolidBrush(_ColorToCOLORREF($COLOR_HOTTRACK_MENU)) _WinAPI_FillRect($hDC, $tRECT, $hBrushFooter) _WinAPI_ReleaseDC($hWnd, $hDC) _WinAPI_DeleteObject($hBrushFooter) Return $iRet Case $WM_CLOSE If $g_idTImer Then _Timer_KillTimer($hWnd, $g_idTImer) $g_idTImer = 0 EndIf Case $WM_DESTROY If $g_idTImer Then _Timer_KillTimer($hWnd, $g_idTImer) $g_idTImer = 0 EndIf _WinAPI_SetWindowLong($hWnd, $GWL_WNDPROC, $g_hMsgBoxOldProc) _WinAPI_DeleteObject($g_hMsgBoxBrush) $g_hMsgBoxBrush = 0 EndSwitch Return _WinAPI_CallWindowProc($g_hMsgBoxOldProc, $hWnd, $iMsg, $wParam, $lParam) EndFunc Func _TimerProc($hWnd, $iMsg, $wParam, $lParam) If $g_bMsgBoxClosing Then Return If $g_Timeout <= 1 Then $g_bMsgBoxClosing = True _Timer_KillTimer($hWnd, $g_idTImer) _WinAPI_PostMessage($hWnd, $WM_CLOSE, 0, 0) Else $g_Timeout -= 1 _WinAPI_SetDlgItemText($hWnd, $IDOK + 1, $g_sBtn1_Txt & " [" & $g_Timeout & "]") EndIf EndFunc Func _CBTHookProc($nCode, $wParam, $lParam) If $nCode < 0 Then Return _WinAPI_CallNextHookEx($g_hMsgBoxHook, $nCode, $wParam, $lParam) Local Const $hHWND = HWnd($wParam) Switch $nCode Case $HCBT_ACTIVATE If _WinAPI_GetClassName($hHWND) = "#32770" Then If $g_Timeout Then $g_idTImer = _Timer_SetTimer($hHWND, 1000, "_TimerProc") _WinAPI_SetDlgItemText($wParam, $IDOK, $g_Timeout ? $g_sBtn1_Txt & " [" & $g_Timeout & "]" : $g_sBtn1_Txt) ; Title bar dark _WinAPI_DwmSetWindowAttribute($hHWND, $DWMWA_USE_IMMERSIVE_DARK_MODE, True) ; Dark theme current button $g_hMsgBoxBtn = _WinAPI_GetDlgItem($hHWND, $IDOK) _WinAPI_SetWindowTheme($g_hMsgBoxBtn, "DarkMode_Explorer", 0) _WinAPI_AllowDarkModeForWindow($g_hMsgBoxBtn, True) ; Dark theme for static controls (text + icon) Local $hStatic = _WinAPI_FindWindowEx($hHWND, "Static") $g_hStaticMsgBox = $hStatic While $hStatic _WinAPI_AllowDarkModeForWindow($hStatic, True) $hStatic = _WinAPI_FindWindowEx($hHWND, "Static", "", $hStatic) WEnd $g_hMsgBoxBrush = _WinAPI_CreateSolidBrush(_ColorToCOLORREF($COLOR_BG_DARK)) $g_hMsgBoxOldProc = _WinAPI_SetWindowLong($hHWND, $GWL_WNDPROC, DllCallbackGetPtr($g_hMsgBoxSubProc)) _WinAPI_RedrawWindow($hHWND, 0, 0, BitOR($RDW_INVALIDATE, $RDW_UPDATENOW, $RDW_ALLCHILDREN)) EndIf Case $HCBT_DESTROYWND If _WinAPI_GetClassName($hHWND) = "#32770" Then _Timer_KillTimer($hHWND, $g_idTImer) EndSwitch Return _WinAPI_CallNextHookEx($g_hMsgBoxHook, $nCode, $wParam, $lParam) EndFunc ;==>_CBTHookProc Func MsgBoxEx($sText, $sTitle = Default, $iTimeout = 0, $iFlag = Default, $sBtn_Txt = Default, $hParentHWND = "") If $sBtn_Txt <> Default Then $g_sBtn1_Txt = $sBtn_Txt If $iFlag = Default Then $iFlag = $g_iFlagDefault $g_Timeout = $iTimeout Local $hMsgProc = DllCallbackRegister("_CBTHookProc", "int", "uint;wparam;lparam") Local Const $hThreadID = _WinAPI_GetCurrentThreadId() $g_hMsgBoxHook = _WinAPI_SetWindowsHookEx($WH_CBT, DllCallbackGetPtr($hMsgProc), Null, $hThreadID) If $sTitle = Default Then $sTitle = "Information" Local Const $iReturn = MsgBox($iFlag, $sTitle, $sText, $iTimeout, $hParentHWND) If $g_hMsgBoxHook Then _WinAPI_UnhookWindowsHookEx($g_hMsgBoxHook) DllCallbackFree($hMsgProc) Return $iReturn EndFunc ;==>MsgBoxEx Func _WinAPI_AllowDarkModeForWindow($hWND, $bAllow = True) Local $aResult = DllCall("UxTheme.dll", "bool", 133, "hwnd", $hWND, "bool", $bAllow) If @error Then Return SetError(1, 0, False) Return ($aResult[0] <> 0) EndFunc ;==>_WinAPI_AllowDarkModeForWindow ConsoleWrite(MsgBoxEx("This is a test", "Information", 5) & @CRLF) Any idea how to prevend it? WildByDesign 1 Please don't send me any personal message and ask for support! I will not reply! Selection of finest graphical examples at Codepen.io The own fart smells best! ✌Her 'sikim hıyar' diyene bir avuç tuz alıp koşma!¯\_(ツ)_/¯ ٩(●̮̮̃•̃)۶ ٩(-̮̮̃-̃)۶ૐ
WildByDesign Posted Thursday at 03:52 PM Posted Thursday at 03:52 PM 50 minutes ago, UEZ said: One issue is when you added timer to the MsgBoxEx and drag it around when counter reaches 0 and the MsgBox is closed it will cause a crash -> 0xC000041D I personally have always wished for a proper dark mode MsgBox, so this is quite exciting. 51 minutes ago, UEZ said: Any idea how to prevend it? I don’t know what is the root cause of this crash. I know that @MattyD has been doing similar work recently on additional dialogs. Sorry to tag you in here Matty, but do you have any idea as to the source of this crash?
WildByDesign Posted Thursday at 08:51 PM Posted Thursday at 08:51 PM 5 hours ago, UEZ said: One issue is when you added timer to the MsgBoxEx and drag it around when counter reaches 0 and the MsgBox is closed it will cause a crash -> 0xC000041D I notice a crash when the MsgBox loses focus and regains focus as well. For example, open the About msgbox. Click on the taskbar and back on the About msgbox and it crashes.
MattyD Posted Thursday at 09:42 PM Posted Thursday at 09:42 PM I think the main issue is that we're using $HCBT_ACTIVATE as the trigger to install everything, but it can fire several times during the life of the dialog. When we get a HCBT_ACTIVATE, we stash a ptr to the original proc ($g_hMsgBoxOldProc) and use this to do the donkey work within _MsgBoxProc. But if HCBT_ACTIVATE fires a second time, g_hMsgBoxOldProc becomes a ptr to our MsgBoxProc . So that causes the func to recurse into itself until it everything falls apart.
UEZ Posted Thursday at 10:06 PM Author Posted Thursday at 10:06 PM (edited) Thanks for the hint @MattyD - it fixed the focus crash. This seems to work - please test: expandcollapse popup;Coded by UEZ build 2026-03-19 beta #AutoIt3Wrapper_Run_Au3Stripper=y #Au3Stripper_Parameters=/so #Au3Stripper_Ignore_Funcs=_TimerProc #include <ButtonConstants.au3> #include <Timers.au3> #include <WinAPIConstants.au3> #include <WinAPIGdi.au3> #include <WinAPIProc.au3> #include <WinAPISys.au3> #include <WinAPISysWin.au3> #include <WinAPITheme.au3> #include <WindowsConstants.au3> Global Const $BS_PUSHBUTTON = 0x000000 Global Const $COLOR_BG_DARK = 0x202020 Global Const $COLOR_TEXT_LIGHT = 0xF0F0F0 Global Const $COLOR_HOTTRACK_MENU = 0x3A3A3A Global Const $COLOR_TITLE_DARK = 0x181818 Const $HCBT_CREATEWND = 3, $HCBT_DESTROYWND = 4, $HCBT_ACTIVATE = 5, $g_iFlagDefault = BitOR($MB_TOPMOST, $MB_ICONINFORMATION) Global $g_hMsgBoxHook, $g_hSubMsgBox, $g_idTImer, $g_sBtn1_Txt = "Close", $g_sBtn2_Txt, $g_sBtn3_Txt Global $g_Timeout = 0, $g_hMsgBoxOldProc, $g_hMsgBoxBrush, $g_hMsgBoxBtn = 0, $g_bMsgBoxClosing = False, $g_bNCLButtonDown = False, $g_bMsgBoxInitialized = False Global $g_hMsgBoxSubProc = DllCallbackRegister("_MsgBoxProc", "lresult", "hwnd;uint;wparam;lparam") Func _WinAPI_SetDlgItemText($hDlg, $nIDDlgItem, $lpString) ;https://learn.microsoft.com/en-us/windows/win32/api/winuser/nf-winuser-setdlgitemtextw Local $aRet = DllCall("user32.dll", "int", "SetDlgItemText", "hwnd", $hDlg, "int", $nIDDlgItem, "str", $lpString) If @error Then Return SetError(@error, @extended, 0) Return $aRet[0] EndFunc ;==>_WinAPI_SetDlgItemText Func _WinAPI_FindWindowEx($hParent, $sClass, $sTitle = "", $hAfter = 0) Local $ret = DllCall("user32.dll", "hwnd", "FindWindowExW", "hwnd", $hParent, "hwnd", $hAfter, "wstr", $sClass, "wstr", $sTitle) If @error Or Not IsArray($ret) Then Return 0 Return $ret[0] EndFunc ;==>_WinAPI_FindWindowEx Func _ColorToCOLORREF($iColor) ;RGB to BGR Local $iR = BitAND(BitShift($iColor, 16), 0xFF) Local $iG = BitAND(BitShift($iColor, 8), 0xFF) Local $iB = BitAND($iColor, 0xFF) Return BitOR(BitShift($iB, -16), BitShift($iG, -8), $iR) EndFunc ;==>_ColorToCOLORREF Func _MsgBoxProc($hWnd, $iMsg, $wParam, $lParam) If Not $g_hMsgBoxOldProc Then Return _WinAPI_DefWindowProc($hWnd, $iMsg, $wParam, $lParam) If $g_Timeout < 0 Or Not _WinAPI_IsWindow($hWnd) Then Return _WinAPI_DefWindowProc($hWnd, $iMsg, $wParam, $lParam) Switch $iMsg Case $WM_CTLCOLORSTATIC, $WM_CTLCOLORDLG, $WM_CTLCOLORBTN If Not $g_hMsgBoxBrush Then Return _WinAPI_CallWindowProc($g_hMsgBoxOldProc, $hWnd, $iMsg, $wParam, $lParam) _WinAPI_SetTextColor($wParam, _ColorToCOLORREF($COLOR_TEXT_LIGHT)) _WinAPI_SetBkColor($wParam, _ColorToCOLORREF($COLOR_BG_DARK)) Return $g_hMsgBoxBrush Case $WM_ERASEBKGND If Not $g_hMsgBoxBrush Then Return _WinAPI_CallWindowProc($g_hMsgBoxOldProc, $hWnd, $iMsg, $wParam, $lParam) Local $tRECT = _WinAPI_GetClientRect($hWnd) _WinAPI_FillRect($wParam, $tRECT, $g_hMsgBoxBrush) Return 1 Case $WM_PAINT Local $iRet = _WinAPI_CallWindowProc($g_hMsgBoxOldProc, $hWnd, $iMsg, $wParam, $lParam) Local $hDC = _WinAPI_GetDC($hWnd) Local $tRECT = _WinAPI_GetClientRect($hWnd) If $g_hMsgBoxBtn Then Local $tBtnRect = _WinAPI_GetWindowRect($g_hMsgBoxBtn) Local $tPoint = DllStructCreate($tagPOINT) $tPoint.x = $tBtnRect.left $tPoint.y = $tBtnRect.top _WinAPI_ScreenToClient($hWnd, $tPoint) $tRECT.top = $tPoint.y - 10 EndIf Local $hBrushFooter = _WinAPI_CreateSolidBrush(_ColorToCOLORREF($COLOR_HOTTRACK_MENU)) _WinAPI_FillRect($hDC, $tRECT, $hBrushFooter) _WinAPI_ReleaseDC($hWnd, $hDC) _WinAPI_DeleteObject($hBrushFooter) Return $iRet Case $WM_COMMAND If $g_bNCLButtonDown And (BitAND($wParam, 0xFFFF) = $IDOK) Then $g_bMsgBoxClosing = True Return 0 EndIf Return _WinAPI_CallWindowProc($g_hMsgBoxOldProc, $hWnd, $iMsg, $wParam, $lParam) Case $WM_NCLBUTTONDOWN $g_bNCLButtonDown = True Local $iRet = _WinAPI_CallWindowProc($g_hMsgBoxOldProc, $hWnd, $iMsg, $wParam, $lParam) $g_bNCLButtonDown = False If $g_bMsgBoxClosing Then _WinAPI_PostMessage($hWnd, $WM_COMMAND, $IDOK + 1, 0) EndIf Return $iRet Case $WM_CLOSE If $g_idTImer Then _Timer_KillTimer($hWnd, $g_idTImer) $g_idTImer = 0 EndIf Case $WM_NCDESTROY _WinAPI_SetWindowLong($hWnd, $GWL_WNDPROC, $g_hMsgBoxOldProc) Local $hBrush = $g_hMsgBoxBrush $g_hMsgBoxBrush = 0 If $hBrush Then _WinAPI_DeleteObject($hBrush) EndIf Case $WM_DESTROY If $g_idTImer Then _Timer_KillTimer($hWnd, $g_idTImer) $g_idTImer = 0 EndIf Return _WinAPI_CallWindowProc($g_hMsgBoxOldProc, $hWnd, $iMsg, $wParam, $lParam) EndSwitch Return _WinAPI_CallWindowProc($g_hMsgBoxOldProc, $hWnd, $iMsg, $wParam, $lParam) EndFunc Func _TimerProc($hWnd, $iMsg, $wParam, $lParam) If Not _WinAPI_IsWindow($hWnd) Or $g_bMsgBoxClosing Then Return If $g_Timeout <= 1 Then $g_bMsgBoxClosing = True _Timer_KillTimer($hWnd, $g_idTImer) $g_idTImer = 0 If Not $g_bNCLButtonDown Then _WinAPI_PostMessage($hWnd, $WM_COMMAND, $IDOK + 1, 0) Return EndIf $g_Timeout -= 1 _WinAPI_SetDlgItemText($hWnd, $IDOK + 1, $g_sBtn1_Txt & " [" & $g_Timeout & "]") EndFunc Func _CBTHookProc($nCode, $wParam, $lParam) If $nCode < 0 Then Return _WinAPI_CallNextHookEx($g_hMsgBoxHook, $nCode, $wParam, $lParam) Local Const $hHWND = HWnd($wParam) Switch $nCode Case $HCBT_ACTIVATE If _WinAPI_GetClassName($hHWND) = "#32770" Then If $g_bMsgBoxInitialized Then Return _WinAPI_CallNextHookEx($g_hMsgBoxHook, $nCode, $wParam, $lParam) $g_bMsgBoxInitialized = True If $g_Timeout Then $g_idTImer = _Timer_SetTimer($hHWND, 1000, "_TimerProc") _WinAPI_SetDlgItemText($wParam, $IDOK, $g_Timeout ? $g_sBtn1_Txt & " [" & $g_Timeout & "]" : $g_sBtn1_Txt) ; Title bar dark _WinAPI_DwmSetWindowAttribute($hHWND, $DWMWA_USE_IMMERSIVE_DARK_MODE, True) ; Dark title + caption colors _WinAPI_DwmSetWindowAttribute($hHWND, 20, True) ; immersive dark ; optional: remove bright border _WinAPI_DwmSetWindowAttribute($hHWND, $DWMWA_BORDER_COLOR, _ColorToCOLORREF(0x303030)) ; caption color _WinAPI_DwmSetWindowAttribute($hHWND, $DWMWA_CAPTION_COLOR, _ColorToCOLORREF($COLOR_TITLE_DARK)) ; caption text _WinAPI_DwmSetWindowAttribute($hHWND, $DWMWA_TEXT_COLOR, _ColorToCOLORREF($COLOR_TEXT_LIGHT)) Local $i, $iStyle For $i = 0 To 7 $hBtn = _WinAPI_GetDlgItem($hHWND, $i) If $hBtn Then $g_hMsgBoxBtn = $hBtn _WinAPI_SetWindowTheme($hBtn, "DarkMode_Explorer", 0) _WinAPI_AllowDarkModeForWindow($hBtn, True) EndIf Next ; Dark theme for static controls (text + icon) Local $hStatic = _WinAPI_FindWindowEx($hHWND, "Static") While $hStatic _WinAPI_AllowDarkModeForWindow($hStatic, True) $hStatic = _WinAPI_FindWindowEx($hHWND, "Static", "", $hStatic) WEnd $g_hMsgBoxBrush = _WinAPI_CreateSolidBrush(_ColorToCOLORREF($COLOR_BG_DARK)) $g_hMsgBoxOldProc = _WinAPI_SetWindowLong($hHWND, $GWL_WNDPROC, DllCallbackGetPtr($g_hMsgBoxSubProc)) _WinAPI_RedrawWindow($hHWND, 0, 0, BitOR($RDW_INVALIDATE, $RDW_UPDATENOW, $RDW_ALLCHILDREN)) EndIf Case $HCBT_DESTROYWND If _WinAPI_GetClassName($hHWND) = "#32770" Then $g_bMsgBoxInitialized = False _Timer_KillTimer($hHWND, $g_idTImer) EndIf EndSwitch Return _WinAPI_CallNextHookEx($g_hMsgBoxHook, $nCode, $wParam, $lParam) EndFunc ;==>_CBTHookProc Func MsgBoxEx($sText, $sTitle = Default, $iTimeout = 0, $iFlag = Default, $sBtn_Txt = Default, $hParentHWND = "") $g_hMsgBoxBtn = 0 $g_bMsgBoxClosing = False $g_bNCLButtonDown = False $g_bMsgBoxInitialized = False If $sBtn_Txt <> Default Then $g_sBtn1_Txt = $sBtn_Txt If $iFlag = Default Then $iFlag = $g_iFlagDefault $g_Timeout = $iTimeout Local $hMsgProc = DllCallbackRegister("_CBTHookProc", "int", "uint;wparam;lparam") Local Const $hThreadID = _WinAPI_GetCurrentThreadId() $g_hMsgBoxHook = _WinAPI_SetWindowsHookEx($WH_CBT, DllCallbackGetPtr($hMsgProc), Null, $hThreadID) If $sTitle = Default Then $sTitle = "Information" Local Const $iReturn = MsgBox($iFlag, $sTitle, $sText, 0, $hParentHWND) If $g_hMsgBoxHook Then _WinAPI_UnhookWindowsHookEx($g_hMsgBoxHook) DllCallbackFree($hMsgProc) Return $iReturn EndFunc ;==>MsgBoxEx Func _WinAPI_AllowDarkModeForWindow($hWND, $bAllow = True) Local $aResult = DllCall("UxTheme.dll", "bool", 133, "hwnd", $hWND, "bool", $bAllow) If @error Then Return SetError(1, 0, False) Return ($aResult[0] <> 0) EndFunc ;==>_WinAPI_AllowDarkModeForWindow ConsoleWrite(MsgBoxEx("This is a test", "Information", 5) & @CRLF) Edited Thursday at 10:15 PM by UEZ Please don't send me any personal message and ask for support! I will not reply! Selection of finest graphical examples at Codepen.io The own fart smells best! ✌Her 'sikim hıyar' diyene bir avuç tuz alıp koşma!¯\_(ツ)_/¯ ٩(●̮̮̃•̃)۶ ٩(-̮̮̃-̃)۶ૐ
WildByDesign Posted Thursday at 10:13 PM Posted Thursday at 10:13 PM 6 minutes ago, UEZ said: This seems to work - please test: All good now.
WildByDesign Posted yesterday at 12:36 PM Posted yesterday at 12:36 PM I really like the technique that you use to paint the darker rectangle around the Edit and ListBox controls to cover up the brighter border. However, I feel like it takes away some of the "depth" of the control and could make the user have a harder time to know which edit/listbox control is active. Suggestion: When the specific Edit/ListBox control is active, paint the background slightly brighter. My thought would be to use your existing _WM_CTLCOLOR() function. If we can determine if the Edit/ListBox control has focus (keyboard), change the color of the brush that is returned from that function. This might be the best option since it would work for both Win10 and Win11 users. I just don't know how to determine if that specific control has the focus. Possibly the control handle can be compared with _WinAPI_GetFocus() but I have not tried. Alternative: DarkMode_DarkTheme works perfectly now for Edit controls. Not perfect for ListBox though. But Edit controls are perfect and would not need any additional rectangle painted around them. The only downside is that it would only works for Windows 11 24H2/25H2 with latest updates.
MattyD Posted yesterday at 03:01 PM Posted yesterday at 03:01 PM I had a bit more of a play with that msgbox stuff today and I landed on something like this. It's not meant to be a replacement by any means, it's probably more a scratch pad for my own benefit. But I figure someone might wish to pick though it. expandcollapse popup#AutoIt3Wrapper_UseX64=N #include <ButtonConstants.au3> #include <Timers.au3> #include <WinAPI.au3> #include <WinAPITheme.au3> #include <WindowsConstants.au3> #include <WinAPIGdi.au3> ;Store COLOR_* as coloref (consistancy with _WinAPI_GetSysColor()) Global Const $COLOR_BG_DARK = _WinAPI_SwitchColor(0x202020) Global Const $COLOR_TEXT_LIGHT = _WinAPI_SwitchColor(0xF0F0F0) Global Const $COLOR_HOTTRACK_MENU = _WinAPI_SwitchColor(0x3A3A3A) Global Const $COLOR_TITLE_DARK = _WinAPI_SwitchColor(0x181818) Global Const $HCBT_MOVESIZE = 0 Global Const $HCBT_MINMAX = 1 Global Const $HCBT_QS = 2 Global Const $HCBT_CREATEWND = 3 Global Const $HCBT_DESTROYWND = 4 Global Const $HCBT_ACTIVATE = 5 Global Const $HCBT_CLICKSKIPPED = 6 Global Const $HCBT_KEYSKIPPED = 7 Global Const $HCBT_SYSCOMMAND = 8 Global Const $HCBT_SETFOCUS = 9 Global $g_hMsgBoxHook, $g_idTImer, $g_sBtn1_Txt = "Close" Global $g_UseDarkMode Global $g_Timeout = 0, $g_hMsgBoxOldProc, $g_hMsgBoxBrush, $g_hMsgBoxBtn = 0, $g_bMsgBoxClosing = False, $g_bNCLButtonDown = False, $g_bMsgBoxInitialized = False Global $g_hMsgBoxSubProc = DllCallbackRegister("_MsgBoxProc", "lresult", "hwnd;uint;wparam;lparam;uint_ptr;dword_ptr") Global $g_pMsgBoxSubProc = DllCallbackGetPtr($g_hMsgBoxSubProc) Global Enum $PAM_Default, $PAM_AllowDark, $PAM_ForceDark, $PAM_ForceLight, $PAM_Max ;From testing, using $PAM_AllowDark will cause _WinAPI_ShouldAppsUseDarkMode() to follow the actual darkmode setting. ;Otherwise you can force _WinAPI_ShouldAppsUseDarkMode to return either way with $PAM_ForceDark & $PAM_ForceLight. _WinAPI_SetPreferredAppMode($PAM_ForceDark) ConsoleWrite(MsgBoxEx("This is a test", "Information", 5) & @CRLF) Func _WinAPI_SetDlgItemText($hDlg, $nIDDlgItem, $lpString) ;https://learn.microsoft.com/en-us/windows/win32/api/winuser/nf-winuser-setdlgitemtextw Local $aRet = DllCall("user32.dll", "int", "SetDlgItemText", "hwnd", $hDlg, "int", $nIDDlgItem, "str", $lpString) If @error Then Return SetError(@error, @extended, 0) Return $aRet[0] EndFunc ;==>_WinAPI_SetDlgItemText Func _MsgBoxProc($hWnd, $iMsg, $wParam, $lParam, $iSubClsID, $pData) Local Static $hBkColorBrush, $hFooterBrush, $hTimer Switch $iMsg Case $WM_NCCREATE If $g_UseDarkMode Then _WinAPI_DwmSetWindowAttribute($hWnd, $DWMWA_USE_IMMERSIVE_DARK_MODE, True) Case $WM_INITDIALOG $hBkColorBrush = _WinAPI_CreateSolidBrush($COLOR_BG_DARK) $hFooterBrush = _WinAPI_CreateSolidBrush($COLOR_HOTTRACK_MENU) _WinAPI_SetDlgItemText($hWnd, $IDOK, StringFormat("%s [%d]", $g_sBtn1_Txt, $g_Timeout)) If $g_Timeout Then $hTimer = _Timer_SetTimer($hWnd, 1000, "_TimerProc") Case $WM_CTLCOLORSTATIC, $WM_CTLCOLORDLG If $g_UseDarkMode Then _WinAPI_SetTextColor($wParam, $COLOR_TEXT_LIGHT) _WinAPI_SetBkColor($wParam, $COLOR_BG_DARK) Return $hBkColorBrush EndIf Case $WM_CTLCOLORBTN If $g_UseDarkMode Then Return $hBkColorBrush Case $WM_PAINT If $g_UseDarkMode Then Local $tPS = DllStructCreate($tagPAINTSTRUCT) Local $hDC = _WinAPI_BeginPaint($hWnd, $tPS) Local $tPaintRect = DllStructCreate($tagRECT, DllStructGetPtr($tPS, "rPaint")) $tPaintRect.Top = ($tPaintRect.Bottom - 42) _WinAPI_FillRect($hDC, $tPaintRect, $hFooterBrush) _WinAPI_EndPaint($hWnd, $tPS) Return True EndIf Case $WM_COMMAND Local $iNotifCode = _WinAPI_HiWord($wParam) Local $iItemId = _WinAPI_LoWord($wParam) If (Not $lParam) Or ($iNotifCode = $BN_CLICKED) Then Return _Dialog_EndDialog($hWnd, $iItemId) EndIf Case $WM_DESTROY _Timer_KillTimer($hWnd, $hTimer) _WinAPI_RemoveWindowSubclass($hWnd, $g_pMsgBoxSubProc, $iSubClsID) _WinAPI_SetActiveWindow(_WinAPI_GetParent($hWnd)) _WinAPI_DeleteObject($hBkColorBrush) _WinAPI_DeleteObject($hFooterBrush) EndSwitch Return _WinAPI_DefSubclassProc($hWnd, $iMsg, $wParam, $lParam) EndFunc Func _TimerProc($hWnd, $iMsg, $wParam, $lParam) If Not _WinAPI_IsWindow($hWnd) Then Return If $g_Timeout <= 1 Then _WinAPI_PostMessage($hWnd, $WM_COMMAND, $IDOK + 1, 0) $g_Timeout -= 1 _WinAPI_SetDlgItemText($hWnd, $IDOK + 1, StringFormat("%s [%d]", $g_sBtn1_Txt, $g_Timeout)) EndFunc Func _CBTHookProc($nCode, $wParam, $lParam) Local Const $hWnd = HWnd($wParam) If $nCode < 0 Then Return _WinAPI_CallNextHookEx($g_hMsgBoxHook, $nCode, $wParam, $lParam) Switch $nCode Case $HCBT_CREATEWND Switch _WinAPI_GetClassName($hWnd) Case "#32770" _WinAPI_SetWindowSubclass($hWnd, $g_pMsgBoxSubProc, 1000) Case "Button" If $g_UseDarkMode Then _WinAPI_SetWindowTheme($hWnd, "DarkMode_Explorer") EndSwitch EndSwitch Return _WinAPI_CallNextHookEx($g_hMsgBoxHook, $nCode, $wParam, $lParam) EndFunc ;==>_CBTHookProc Func MsgBoxEx($sText, $sTitle = Default, $iTimeout = 0, $iFlag = Default, $sBtn_Txt = Default, $hParentHWND = "") $g_UseDarkMode = _WinAPI_ShouldAppsUseDarkMode() $g_bMsgBoxInitialized = False If $sBtn_Txt <> Default Then $g_sBtn1_Txt = $sBtn_Txt If $iFlag = Default Then $iFlag = BitOR($MB_TOPMOST, $MB_ICONINFORMATION) $g_Timeout = $iTimeout Local $hMsgProc = DllCallbackRegister("_CBTHookProc", "int", "uint;wparam;lparam") Local Const $hThreadID = _WinAPI_GetCurrentThreadId() $g_hMsgBoxHook = _WinAPI_SetWindowsHookEx($WH_CBT, DllCallbackGetPtr($hMsgProc), Null, $hThreadID) If $sTitle = Default Then $sTitle = "Information" Local Const $iReturn = MsgBox($iFlag, $sTitle, $sText, 0, $hParentHWND) If $g_hMsgBoxHook Then _WinAPI_UnhookWindowsHookEx($g_hMsgBoxHook) DllCallbackFree($hMsgProc) Return $iReturn EndFunc ;==>MsgBoxEx Func _Dialog_EndDialog($hWnd, $iReturn) Local $aCall = DllCall("User32.dll", "bool", "EndDialog", "hwnd", $hWnd, "int_ptr", $iReturn) If @error Then Return SetError(@error, @extended, False) Return $aCall[0] EndFunc Func _WinAPI_ShouldAppsUseDarkMode() Local $aResult = DllCall("UxTheme.dll", "bool", 132) If @error Then Return SetError(1, 0, False) Return $aResult[0] EndFunc ;==>_WinAPI_AllowDarkModeForWindow Func _WinAPI_SetPreferredAppMode($iMode) Local $aResult = DllCall("UxTheme.dll", "ptr", 135, "int", $iMode) If @error Then Return SetError(1, 0, False) Return $aResult[0] EndFunc WildByDesign, argumentum and UEZ 2 1
UEZ Posted 23 hours ago Author Posted 23 hours ago 3 hours ago, WildByDesign said: I really like the technique that you use to paint the darker rectangle around the Edit and ListBox controls to cover up the brighter border. However, I feel like it takes away some of the "depth" of the control and could make the user have a harder time to know which edit/listbox control is active. Suggestion: When the specific Edit/ListBox control is active, paint the background slightly brighter. My thought would be to use your existing _WM_CTLCOLOR() function. If we can determine if the Edit/ListBox control has focus (keyboard), change the color of the brush that is returned from that function. This might be the best option since it would work for both Win10 and Win11 users. I just don't know how to determine if that specific control has the focus. Possibly the control handle can be compared with _WinAPI_GetFocus() but I have not tried. Alternative: DarkMode_DarkTheme works perfectly now for Edit controls. Not perfect for ListBox though. But Edit controls are perfect and would not need any additional rectangle painted around them. The only downside is that it would only works for Windows 11 24H2/25H2 with latest updates. I did some modifications -> It gets more and more complicated and I'm loosing the overview of all stuff.... 51 minutes ago, MattyD said: I had a bit more of a play with that msgbox stuff today and I landed on something like this. It's not meant to be a replacement by any means, it's probably more a scratch pad for my own benefit. But I figure someone might wish to pick though it. expandcollapse popup#AutoIt3Wrapper_UseX64=N #include <ButtonConstants.au3> #include <Timers.au3> #include <WinAPI.au3> #include <WinAPITheme.au3> #include <WindowsConstants.au3> #include <WinAPIGdi.au3> ;Store COLOR_* as coloref (consistancy with _WinAPI_GetSysColor()) Global Const $COLOR_BG_DARK = _WinAPI_SwitchColor(0x202020) Global Const $COLOR_TEXT_LIGHT = _WinAPI_SwitchColor(0xF0F0F0) Global Const $COLOR_HOTTRACK_MENU = _WinAPI_SwitchColor(0x3A3A3A) Global Const $COLOR_TITLE_DARK = _WinAPI_SwitchColor(0x181818) Global Const $HCBT_MOVESIZE = 0 Global Const $HCBT_MINMAX = 1 Global Const $HCBT_QS = 2 Global Const $HCBT_CREATEWND = 3 Global Const $HCBT_DESTROYWND = 4 Global Const $HCBT_ACTIVATE = 5 Global Const $HCBT_CLICKSKIPPED = 6 Global Const $HCBT_KEYSKIPPED = 7 Global Const $HCBT_SYSCOMMAND = 8 Global Const $HCBT_SETFOCUS = 9 Global $g_hMsgBoxHook, $g_idTImer, $g_sBtn1_Txt = "Close" Global $g_UseDarkMode Global $g_Timeout = 0, $g_hMsgBoxOldProc, $g_hMsgBoxBrush, $g_hMsgBoxBtn = 0, $g_bMsgBoxClosing = False, $g_bNCLButtonDown = False, $g_bMsgBoxInitialized = False Global $g_hMsgBoxSubProc = DllCallbackRegister("_MsgBoxProc", "lresult", "hwnd;uint;wparam;lparam;uint_ptr;dword_ptr") Global $g_pMsgBoxSubProc = DllCallbackGetPtr($g_hMsgBoxSubProc) Global Enum $PAM_Default, $PAM_AllowDark, $PAM_ForceDark, $PAM_ForceLight, $PAM_Max ;From testing, using $PAM_AllowDark will cause _WinAPI_ShouldAppsUseDarkMode() to follow the actual darkmode setting. ;Otherwise you can force _WinAPI_ShouldAppsUseDarkMode to return either way with $PAM_ForceDark & $PAM_ForceLight. _WinAPI_SetPreferredAppMode($PAM_ForceDark) ConsoleWrite(MsgBoxEx("This is a test", "Information", 5) & @CRLF) Func _WinAPI_SetDlgItemText($hDlg, $nIDDlgItem, $lpString) ;https://learn.microsoft.com/en-us/windows/win32/api/winuser/nf-winuser-setdlgitemtextw Local $aRet = DllCall("user32.dll", "int", "SetDlgItemText", "hwnd", $hDlg, "int", $nIDDlgItem, "str", $lpString) If @error Then Return SetError(@error, @extended, 0) Return $aRet[0] EndFunc ;==>_WinAPI_SetDlgItemText Func _MsgBoxProc($hWnd, $iMsg, $wParam, $lParam, $iSubClsID, $pData) Local Static $hBkColorBrush, $hFooterBrush, $hTimer Switch $iMsg Case $WM_NCCREATE If $g_UseDarkMode Then _WinAPI_DwmSetWindowAttribute($hWnd, $DWMWA_USE_IMMERSIVE_DARK_MODE, True) Case $WM_INITDIALOG $hBkColorBrush = _WinAPI_CreateSolidBrush($COLOR_BG_DARK) $hFooterBrush = _WinAPI_CreateSolidBrush($COLOR_HOTTRACK_MENU) _WinAPI_SetDlgItemText($hWnd, $IDOK, StringFormat("%s [%d]", $g_sBtn1_Txt, $g_Timeout)) If $g_Timeout Then $hTimer = _Timer_SetTimer($hWnd, 1000, "_TimerProc") Case $WM_CTLCOLORSTATIC, $WM_CTLCOLORDLG If $g_UseDarkMode Then _WinAPI_SetTextColor($wParam, $COLOR_TEXT_LIGHT) _WinAPI_SetBkColor($wParam, $COLOR_BG_DARK) Return $hBkColorBrush EndIf Case $WM_CTLCOLORBTN If $g_UseDarkMode Then Return $hBkColorBrush Case $WM_PAINT If $g_UseDarkMode Then Local $tPS = DllStructCreate($tagPAINTSTRUCT) Local $hDC = _WinAPI_BeginPaint($hWnd, $tPS) Local $tPaintRect = DllStructCreate($tagRECT, DllStructGetPtr($tPS, "rPaint")) $tPaintRect.Top = ($tPaintRect.Bottom - 42) _WinAPI_FillRect($hDC, $tPaintRect, $hFooterBrush) _WinAPI_EndPaint($hWnd, $tPS) Return True EndIf Case $WM_COMMAND Local $iNotifCode = _WinAPI_HiWord($wParam) Local $iItemId = _WinAPI_LoWord($wParam) If (Not $lParam) Or ($iNotifCode = $BN_CLICKED) Then Return _Dialog_EndDialog($hWnd, $iItemId) EndIf Case $WM_DESTROY _Timer_KillTimer($hWnd, $hTimer) _WinAPI_RemoveWindowSubclass($hWnd, $g_pMsgBoxSubProc, $iSubClsID) _WinAPI_SetActiveWindow(_WinAPI_GetParent($hWnd)) _WinAPI_DeleteObject($hBkColorBrush) _WinAPI_DeleteObject($hFooterBrush) EndSwitch Return _WinAPI_DefSubclassProc($hWnd, $iMsg, $wParam, $lParam) EndFunc Func _TimerProc($hWnd, $iMsg, $wParam, $lParam) If Not _WinAPI_IsWindow($hWnd) Then Return If $g_Timeout <= 1 Then _WinAPI_PostMessage($hWnd, $WM_COMMAND, $IDOK + 1, 0) $g_Timeout -= 1 _WinAPI_SetDlgItemText($hWnd, $IDOK + 1, StringFormat("%s [%d]", $g_sBtn1_Txt, $g_Timeout)) EndFunc Func _CBTHookProc($nCode, $wParam, $lParam) Local Const $hWnd = HWnd($wParam) If $nCode < 0 Then Return _WinAPI_CallNextHookEx($g_hMsgBoxHook, $nCode, $wParam, $lParam) Switch $nCode Case $HCBT_CREATEWND Switch _WinAPI_GetClassName($hWnd) Case "#32770" _WinAPI_SetWindowSubclass($hWnd, $g_pMsgBoxSubProc, 1000) Case "Button" If $g_UseDarkMode Then _WinAPI_SetWindowTheme($hWnd, "DarkMode_Explorer") EndSwitch EndSwitch Return _WinAPI_CallNextHookEx($g_hMsgBoxHook, $nCode, $wParam, $lParam) EndFunc ;==>_CBTHookProc Func MsgBoxEx($sText, $sTitle = Default, $iTimeout = 0, $iFlag = Default, $sBtn_Txt = Default, $hParentHWND = "") $g_UseDarkMode = _WinAPI_ShouldAppsUseDarkMode() $g_bMsgBoxInitialized = False If $sBtn_Txt <> Default Then $g_sBtn1_Txt = $sBtn_Txt If $iFlag = Default Then $iFlag = BitOR($MB_TOPMOST, $MB_ICONINFORMATION) $g_Timeout = $iTimeout Local $hMsgProc = DllCallbackRegister("_CBTHookProc", "int", "uint;wparam;lparam") Local Const $hThreadID = _WinAPI_GetCurrentThreadId() $g_hMsgBoxHook = _WinAPI_SetWindowsHookEx($WH_CBT, DllCallbackGetPtr($hMsgProc), Null, $hThreadID) If $sTitle = Default Then $sTitle = "Information" Local Const $iReturn = MsgBox($iFlag, $sTitle, $sText, 0, $hParentHWND) If $g_hMsgBoxHook Then _WinAPI_UnhookWindowsHookEx($g_hMsgBoxHook) DllCallbackFree($hMsgProc) Return $iReturn EndFunc ;==>MsgBoxEx Func _Dialog_EndDialog($hWnd, $iReturn) Local $aCall = DllCall("User32.dll", "bool", "EndDialog", "hwnd", $hWnd, "int_ptr", $iReturn) If @error Then Return SetError(@error, @extended, False) Return $aCall[0] EndFunc Func _WinAPI_ShouldAppsUseDarkMode() Local $aResult = DllCall("UxTheme.dll", "bool", 132) If @error Then Return SetError(1, 0, False) Return $aResult[0] EndFunc ;==>_WinAPI_AllowDarkModeForWindow Func _WinAPI_SetPreferredAppMode($iMode) Local $aResult = DllCall("UxTheme.dll", "ptr", 135, "int", $iMode) If @error Then Return SetError(1, 0, False) Return $aResult[0] EndFunc Very good - seems to be more stable and the behaviour is same as MsgBox() - thanks. WildByDesign, MattyD and ioa747 3 Please don't send me any personal message and ask for support! I will not reply! Selection of finest graphical examples at Codepen.io The own fart smells best! ✌Her 'sikim hıyar' diyene bir avuç tuz alıp koşma!¯\_(ツ)_/¯ ٩(●̮̮̃•̃)۶ ٩(-̮̮̃-̃)۶ૐ
WildByDesign Posted 21 hours ago Posted 21 hours ago 2 hours ago, UEZ said: I did some modifications -> Excellent job with the Edit/ListBox control borders. It is a subtle yet perfect design that you did. 👍
WildByDesign Posted 2 hours ago Posted 2 hours ago (edited) 21 hours ago, MattyD said: I had a bit more of a play with that msgbox stuff today and I landed on something like this. It's not meant to be a replacement by any means, it's probably more a scratch pad for my own benefit. But I figure someone might wish to pick though it. Hey Matty. So this MsgBoxEx from you is quite incredible. I have extended it by allowing application of Win11 materials (Mica, Tabbed, Acrylic, etc.) and DPI scaling for certain measurements where it was needed (eg. footer height painting). The fact that your MsgBoxEx follows standard MsgBox return values and everything I feel like you've got something special here. I do not want to take away from the current thread/topic. Would you be willing to open a new topic for your MsgBoxEx script? I feel like it has such value that it deserves it. But also, I have some questions, suggestions and possibly some code to share back to improve it. And I feel like if it has its own topic, it would be easy for you to update/modify that first post to always have the latest. By the way, thank you for all of the incredible things that you share with the community. This is yet another gem. Edited 2 hours ago by WildByDesign
MattyD Posted 45 minutes ago Posted 45 minutes ago Thank you, and of course credit where it's due to UEZ. Sounds like you've been busy , feel free to start up another thread and I'll pop by.
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