WildByDesign Posted 22 hours ago Posted 22 hours ago This is a continuation of a script from @Nine from the Round buttons thread by @ioa747. My intention is to share this script back in that thread but the text color part is not working and therefore I did not want to pollute that thread asking for help. I'd rather get it sorted out and working 100% before sharing it there. Also, I've seen requests recently for flat, rectangle buttons and this may help for that user. I'm also likely going to use this because it's quite great. Any script from Nine is always great. So the part that is not working is changing the text color of the buttons with _WinAPI_SetTextColor. Clearly it's an area that I am not familiar with. Anyway, I put a comment line with (not working) in the areas where it is not working. If someone can help with the text color part, please, that would be fantastic. Thank you. expandcollapse popup; From Nine ; Modified by WildByDesign #include <GUIConstants.au3> #include <WindowsConstants.au3> #include <StructureConstants.au3> #include <WinAPI.au3> #include <FrameConstants.au3> #include <guibutton.au3> ; DPI awareness DllCall("User32.dll", "bool", "SetProcessDpiAwarenessContext" , "HWND", "DPI_AWARENESS_CONTEXT" -2) Global Const $tagNMCUSTOMDRAWINFO = $tagNMHDR & ";dword DrawStage;handle hdc;" & $tagRECT & ";dword_ptr ItemSpec;uint ItemState;lparam lItemParam;" Global $idButton Global $iBackColorDef = 0x404040 Global $iBackColorHot = 0x808080 Global $iBackColorSel = 0x606060 Global $iBackColorDis = 0x000000 Global $iTextColorDef = 0xFFFFFF Global $iTextColorDis = 0xA0A0A0 Example() Func Example() Local $hGUI = GUICreate("Example") GUISetBkColor(0x202020) $idButton = GUICtrlCreateButton("Test", 100, 100, 100, 30) GUICtrlSendMsg($idButton, $WM_CHANGEUISTATE, 65537, 0) GUIRegisterMsg($WM_NOTIFY, WM_NOTIFY) GUISetState() While True Switch GUIGetMsg() Case $GUI_EVENT_CLOSE ExitLoop Case $idButton ConsoleWrite("Button was pressed" & @CRLF) EndSwitch WEnd EndFunc ;==>Example Func WM_NOTIFY($hWnd, $iMsg, $wParam, $lParam) Local $hBrush Local $tInfo = DllStructCreate($tagNMCUSTOMDRAWINFO, $lParam) If $tInfo.IDFrom = $idButton And $tInfo.Code = $NM_CUSTOMDRAW And $tInfo.DrawStage = $CDDS_PREPAINT Then Local $tRECT = DllStructCreate($tagRECT, DllStructGetPtr($tInfo, "left")) If BitAND($tInfo.ItemState, $CDIS_HOT) Then ; set hot track back color $hBrush = _WinAPI_CreateSolidBrush($iBackColorHot) ; set default text color (not working) _WinAPI_SetTextColor($tInfo.hDC, $iTextColorDef) EndIf If BitAND($tInfo.ItemState, $CDIS_SELECTED) Then ; set selected back color $hBrush = _WinAPI_CreateSolidBrush($iBackColorSel) ; set default text color (not working) _WinAPI_SetTextColor($tInfo.hDC, $iTextColorDef) EndIf If BitAND($tInfo.ItemState, $CDIS_DISABLED) Then ; set disabled back color $hBrush = _WinAPI_CreateSolidBrush($iBackColorDis) ; set disabled text color (not working) _WinAPI_SetTextColor($tInfo.hDC, $iTextColorDis) EndIf If Not BitAND($tInfo.ItemState, $CDIS_HOT) And Not BitAND($tInfo.ItemState, $CDIS_SELECTED) Then $hBrush = _WinAPI_CreateSolidBrush($iBackColorDef) EndIf _WinAPI_FillRect($tInfo.hDC, $tRECT, $hBrush) _WinAPI_DeleteObject($hBrush) EndIf Return $GUI_RUNDEFMSG EndFunc ;==>WM_NOTIFY
Nine Posted 19 hours ago Posted 19 hours ago Sadly you cannot modify the font of a button with NM_CUSTOMDRAW. As per MSDN, you need to inform the parent with CDRF_NEWFONT (This occurs when dwDrawStage equals CDDS_ITEMPREPAINT). To tell that you want an item prepaint, you need to use CDRF_NOTIFYITEMDRAW (This occurs when dwDrawStage equals CDDS_PREPAINT). However the use CDRF_NOTIFYITEMDRAW does not trigger a new drawing stage with a button, as buttons don't have item... WildByDesign 1 “They did not know it was impossible, so they did it” ― Mark Twain Spoiler Block all input without UAC Save/Retrieve Images to/from Text Monitor Management (VCP commands) Tool to search in text (au3) files Date Range Picker Virtual Desktop Manager Sudoku Game 2020 Overlapped Named Pipe IPC HotString 2.0 - Hot keys with string x64 Bitwise Operations Multi-keyboards HotKeySet Recursive Array Display Fast and simple WCD IPC Multiple Folders Selector Printer Manager GIF Animation (cached) Debug Messages Monitor UDF Screen Scraping Round Corner GUI UDF Multi-Threading Made Easy Interface Object based on Tag
WildByDesign Posted 18 hours ago Author Posted 18 hours ago Thanks for confirming. I just tried to combine your NM_CUSTOMDRAW / WM_NOTIFY method with Matty's BS_OWNERDRAW / WM_DRAWITEM method. His works well for coloring the buttons and text, but lacks the ability to color the button on mouse hover. Yours does all of the button states quite well but lacks the text coloring, unfortunately. So I tried my best to combine the best of both, but it doesn't seem like it can work. I assume that WM_NOTIFY just doesn't trigger for _GUICtrl*_Create UDF functions. I used _WinAPI_GetDlgCtrlID() to obtain the control ID from the button handle but I wasn't able to get it to work properly in the end. There is so much potential with both methods but it seems that we may out of luck.
Solution Nine Posted 17 hours ago Solution Posted 17 hours ago (edited) But you could hack the NM_CUSTOMDRAW. Not so great but it is working : expandcollapse popup; From Nine #include <GUIConstants.au3> #include <WindowsConstants.au3> #include <StructureConstants.au3> #include <WinAPI.au3> #include <FrameConstants.au3> Global Const $tagNMCUSTOMDRAWINFO = $tagNMHDR & ";dword DrawStage;handle hdc;" & $tagRECT & ";dword_ptr ItemSpec;uint ItemState;lparam lItemParam;" Global $idBut Example() Func Example() Local $hGUI = GUICreate("Example") $idBut = GUICtrlCreateButton("Test", 10, 10, 100, 30) GUICtrlCreateButton("Standard", 10, 50, 100, 30) GUIRegisterMsg($WM_NOTIFY, WM_NOTIFY) GUISetState() While True Switch GUIGetMsg() Case $GUI_EVENT_CLOSE ExitLoop Case $idBut ConsoleWrite("Button was pressed" & @CRLF) EndSwitch WEnd EndFunc ;==>Example Func WM_NOTIFY($hWnd, $iMsg, $wParam, $lParam) Local $tInfo = DllStructCreate($tagNMCUSTOMDRAWINFO, $lParam) If $tInfo.IDFrom = $idBut And $tInfo.Code = $NM_CUSTOMDRAW Then Local $tRECT = DllStructCreate($tagRECT, DllStructGetPtr($tInfo, "left")) Switch $tInfo.DrawStage Case $CDDS_PREPAINT _WinAPI_DrawFrameControl($tInfo.hDC, $tRECT, $DFC_BUTTON, (BitAND($tInfo.ItemState, $CDIS_SELECTED) ? $DFCS_PUSHED : 0) + $DFCS_BUTTONPUSH) _WinAPI_InflateRect($tRECT, -3, -3) Local $hBrush = _WinAPI_CreateSolidBrush(BitAND($tInfo.ItemState, $CDIS_HOT) ? 0xCDEF : 0xAAAA) _WinAPI_FillRect($tInfo.hDC, $tRECT, $hBrush) _WinAPI_DeleteObject($hBrush) Return $CDRF_NOTIFYPOSTPAINT Case $CDDS_POSTPAINT _WinAPI_InflateRect($tRECT, -6, -6) _WinAPI_SetTextColor($tInfo.hDC, 0xFFFFFF) _WinAPI_SetBkColor($tInfo.hDC, BitAND($tInfo.ItemState, $CDIS_HOT) ? 0xCDEF : 0xAAAA) _WinAPI_DrawText($tInfo.hDC, GUICtrlRead($tInfo.IDFrom), $tRECT, BitOR($DT_CENTER, $DT_VCENTER)) EndSwitch EndIf Return $GUI_RUNDEFMSG EndFunc ;==>WM_NOTIFY Edited 16 hours ago by Nine better code WildByDesign and ioa747 2 “They did not know it was impossible, so they did it” ― Mark Twain Spoiler Block all input without UAC Save/Retrieve Images to/from Text Monitor Management (VCP commands) Tool to search in text (au3) files Date Range Picker Virtual Desktop Manager Sudoku Game 2020 Overlapped Named Pipe IPC HotString 2.0 - Hot keys with string x64 Bitwise Operations Multi-keyboards HotKeySet Recursive Array Display Fast and simple WCD IPC Multiple Folders Selector Printer Manager GIF Animation (cached) Debug Messages Monitor UDF Screen Scraping Round Corner GUI UDF Multi-Threading Made Easy Interface Object based on Tag
WildByDesign Posted 14 hours ago Author Posted 14 hours ago 3 hours ago, Nine said: But you could hack the NM_CUSTOMDRAW. Not so great but it is working : Whether it is a hack or not, it seems to do a fantastic job. Thank you so much for helping.
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