WildByDesign Posted 18 hours ago Posted 18 hours ago (edited) I'm playing around with using _WinAPI_FillRect and _WinAPI_DrawText on a CUSTOMDRAW ListView header. The reason why is because _WinAPI_FillRect is the only way that I can apply Windows 11 materials to the ListView header. I am having success with both _WinAPI_FillRect and _WinAPI_DrawText in my testing script. Problem: I am having zero success with getting a different header background colour when the cursor hovers over a header item. In the following case I have the code below to help determine header item state: Case $CDDS_ITEMPOSTPAINT ;... If BitAND($tInfo.ItemState, $CDIS_DEFAULT) Then ; this is not working $hBrush = _WinAPI_CreateSolidBrush(0xff00ff) ElseIf BitAND($tInfo.ItemState, $CDIS_FOCUS) Then ; this is not working $hBrush = _WinAPI_CreateSolidBrush(0xff0000) ElseIf BitAND($tInfo.ItemState, $CDIS_HOT) Then ; this is not working $hBrush = _WinAPI_CreateSolidBrush(0x0000ff) Else $hBrush = _WinAPI_CreateSolidBrush(0x000000) ; this is being used EndIf _WinAPI_FillRect($hDC, $tRECT, $hBrush) ;... I had used this with CUSTOMDRAW buttons previously with success. However, it is not working at all with header item state. If anyone has any ideas on how to achieve different header item background colour for different states, please let me know. Thank you. My current example: expandcollapse popup#include <GUIConstantsEx.au3> #include <WindowsStylesConstants.au3> #include <WinAPIShellEx.au3> #include <WinAPISysWin.au3> #include <WinAPITheme.au3> #include <WinAPIGdi.au3> #include <GuiHeader.au3> ; initiate System DPI awareness DllCall("user32.dll", "bool", "SetProcessDpiAwarenessContext", @AutoItX64 ? "int64" : "int", -2) Global $hListView, $hHeader Global $g_hSubclassProc = 0, $g_pSubclassProc = 0 Global Const $tagNMCUSTOMDRAWINFO = $tagNMHDR & ";dword DrawStage;handle hdc;" & $tagRECT & ";dword_ptr ItemSpec;uint ItemState;lparam lItemParam;" Example() Func Example() Local $hGUI = GUICreate("ListView", 300, 170) GUISetBkColor(0x202020) Local $idListview = GUICtrlCreateListView("col1|col2|col3", 10, 10, 280, 150) $hListView = GUICtrlGetHandle($idListview) GUICtrlSetBkColor(-1, 0x202020) GUICtrlSetColor(-1, 0xFFFFFF) GUICtrlCreateListViewItem("item1|item1|item1", $idListview) GUICtrlCreateListViewItem("item2|item2|item2", $idListview) GUICtrlCreateListViewItem("item3|item3|item3", $idListview) $g_hSubclassProc = DllCallbackRegister("_SubclassProc", "lresult", "hwnd;uint;wparam;lparam;uint_ptr;dword_ptr") $g_pSubclassProc = DllCallbackGetPtr($g_hSubclassProc) _WinAPI_SetWindowSubclass($hListView, $g_pSubclassProc, 0) $hHeader = _WinAPI_FindWindowEx($hListView, 0, "SysHeader32", "") _WinAPI_DwmSetWindowAttribute($hGUI, $DWMWA_USE_IMMERSIVE_DARK_MODE, True) _WinAPI_SetWindowTheme($hHeader, 'DarkMode_ItemsView') GUISetState(@SW_SHOW) ; Loop until the user exits. While 1 Switch GUIGetMsg() Case $GUI_EVENT_CLOSE ExitLoop EndSwitch WEnd _WinAPI_RemoveWindowSubclass($hListView, $g_pSubclassProc, 0) EndFunc ;==>Example Func _WinAPI_FindWindowEx($hParent, $hAfter, $sClass, $sTitle = "") 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 _SubclassProc($hWnd, $iMsg, $wParam, $lParam, $iID, $pData) #forceref $iID, $pData Local $hDC, $sClass, $iRet, $tRect Switch $iMsg Case $WM_NOTIFY Local $tNMHDR = DllStructCreate($tagNMHDR, $lParam) Local $hFrom = $tNMHDR.hWndFrom Local $iCode = $tNMHDR.Code Local $hFont = __CreateFont("Segoe UI", 9) If $iCode = $NM_CUSTOMDRAW Then Local $tNMCD = DllStructCreate($tagNMCUSTOMDRAWINFO, $lParam) Local $dwStage = $tNMCD.DrawStage $hDC = $tNMCD.hdc Switch _WinAPI_GetClassName($hFrom) Case "sysheader32" Switch $dwStage Case $CDDS_PREPAINT Return $CDRF_NOTIFYITEMDRAW Case $CDDS_ITEMPREPAINT ;_WinAPI_SetTextColor($hDC, 0xFFFFFF) Return BitOR($CDRF_NEWFONT, $CDRF_NOTIFYPOSTPAINT) Case $CDDS_ITEMPOSTPAINT ; Set header section size Local $hBrush Local $tInfo = DllStructCreate($tagNMCUSTOMDRAWINFO, $lParam) Local $tNMCustomDraw = DllStructCreate($tagNMLVCUSTOMDRAW, $lParam) Local $tRECT = DllStructCreate($tagRECT) DllStructSetData($tRECT, 1, DllStructGetData($tNMCustomDraw, 6) + 1) DllStructSetData($tRECT, 2, DllStructGetData($tNMCustomDraw, 7) + 1) DllStructSetData($tRECT, 3, DllStructGetData($tNMCustomDraw, 8) - 2) DllStructSetData($tRECT, 4, DllStructGetData($tNMCustomDraw, 9) - 2) _WinAPI_SetBkMode($hDC, $TRANSPARENT) _WinAPI_SelectObject($hDC, $hFont) _WinAPI_SetTextColor($hDC, 0xFFFFFF) Local $iCol = $tInfo.ItemSpec Local $sText = _GUICtrlHeader_GetItemText($hHeader, $iCol) If BitAND($tInfo.ItemState, $CDIS_DEFAULT) Then ; this is not working $hBrush = _WinAPI_CreateSolidBrush(0xff00ff) ElseIf BitAND($tInfo.ItemState, $CDIS_FOCUS) Then ; this is not working $hBrush = _WinAPI_CreateSolidBrush(0xff0000) ElseIf BitAND($tInfo.ItemState, $CDIS_HOT) Then ; this is not working $hBrush = _WinAPI_CreateSolidBrush(0x0000ff) Else $hBrush = _WinAPI_CreateSolidBrush(0x000000) ; this is being used EndIf _WinAPI_FillRect($hDC, $tRECT, $hBrush) _WinAPI_DrawText($hDC, $sText, $tRECT, BitOR($DT_CENTER, $DT_VCENTER, $DT_NOCLIP)) _WinAPI_DeleteObject($hBrush) _WinAPI_DeleteObject($hFont) Return $CDRF_NEWFONT EndSwitch EndSwitch EndIf EndSwitch Return _WinAPI_DefSubclassProc($hWnd, $iMsg, $wParam, $lParam) EndFunc ;==>_SubclassProc Func __CreateFont($sFontName, $nHeight = 9, $nWidth = 400) Local $stFontName = DllStructCreate("char[260]") DllStructSetData($stFontName, 1, $sFontName) Local $hDC = _WinAPI_GetDC(0) ; Get the Desktops DC Local $nPixel = _WinAPI_GetDeviceCaps($hDC, 90) $nHeight = 0 - _WinAPI_MulDiv($nHeight, $nPixel, 72) _WinAPI_ReleaseDC(0, $hDC) Local $hFont = _WinAPI_CreateFont($nHeight, 0, 0, 0, $nWidth, False, False, False, _ $DEFAULT_CHARSET, $OUT_DEFAULT_PRECIS, $CLIP_DEFAULT_PRECIS, $PROOF_QUALITY, $DEFAULT_PITCH, $sFontName) Return $hFont EndFunc ;==>__CreateFont Edited 18 hours ago by WildByDesign
MattyD Posted 7 hours ago Posted 7 hours ago 10 hours ago, WildByDesign said: _WinAPI_FillRect is the only way that I can apply Windows 11 materials to the ListView header. Do you mind expanding a bit on that, or popping up a snippet? I'm just trying to understand where you're coming from. Otherwise we can simplify things quite a bit... expandcollapse popup#include <GUIConstants.au3> #include <WindowsConstants.au3> #include <WinAPI.au3> #include <WinAPITheme.au3> Global Const $tagNMCUSTOMDRAWINFO = "struct;" & $tagNMHDR & ";dword DrawStage;handle hdc;" & _ $tagRECT & ";dword_ptr ItemSpec;uint ItemState;lparam lItemParam;endstruct" Example() Func Example() DllCall("user32.dll", "bool", "SetProcessDpiAwarenessContext", @AutoItX64 ? "int64" : "int", -2) Local $hGUI = GUICreate("ListView", 300, 170) GUISetBkColor(0x202020) Local $idListview = GUICtrlCreateListView("col1|col2|col3", 10, 10, 280, 150) Local $hListView = GUICtrlGetHandle($idListview) GUICtrlSetBkColor(-1, 0x404040) GUICtrlSetColor(-1, 0xFFFFFF) GUICtrlCreateListViewItem("item1|item1|item1", $idListview) GUICtrlCreateListViewItem("item2|item2|item2", $idListview) GUICtrlCreateListViewItem("item3|item3|item3", $idListview) Local $hSubclassProc = DllCallbackRegister("_SubclassProc", "lresult", "hwnd;uint;wparam;lparam;uint_ptr;dword_ptr") Local $pSubclassProc = DllCallbackGetPtr($hSubclassProc) _WinAPI_SetWindowSubclass($hListView, $pSubclassProc, 0) Local $hHeader = GUICtrlSendMsg($idListview, $LVM_GETHEADER, 0, 0) _WinAPI_DwmSetWindowAttribute($hGUI, $DWMWA_USE_IMMERSIVE_DARK_MODE, True) _WinAPI_SetWindowTheme($hHeader, 'DarkMode_ItemsView') GUISetState(@SW_SHOW) ; Loop until the user exits. While 1 Switch GUIGetMsg() Case $GUI_EVENT_CLOSE ExitLoop EndSwitch WEnd _WinAPI_RemoveWindowSubclass($hListView, $pSubclassProc, 0) GUIDelete($hGUI) DllCallbackFree($hSubclassProc) EndFunc ;==>Example Func _SubclassProc($hWnd, $iMsg, $wParam, $lParam, $iID, $pData) Switch $iMsg Case $WM_NOTIFY Local $tNMHDR = DllStructCreate($tagNMHDR, $lParam) If $tNMHDR.Code = $NM_CUSTOMDRAW Then Local $tNMCD = DllStructCreate($tagNMCUSTOMDRAWINFO, $lParam) Switch $tNMCD.DrawStage Case $CDDS_PREPAINT Return $CDRF_NOTIFYITEMDRAW Case $CDDS_ITEMPREPAINT _WinAPI_SetTextColor($tNMCD.hdc, 0xFFFFFF) Return $CDRF_DODEFAULT EndSwitch EndIf EndSwitch Return _WinAPI_DefSubclassProc($hWnd, $iMsg, $wParam, $lParam) EndFunc ;==>_SubclassProc
WildByDesign Posted 6 hours ago Author Posted 6 hours ago 1 hour ago, MattyD said: Do you mind expanding a bit on that, or popping up a snippet? I'm just trying to understand where you're coming from. Absolutely. I've updated my testing script and yours to include applying Acrylic to the entire GUI so that you can see what I mean. It would require Windows 11 (Build 22621+) and only works if Transparency Effects are enabled for the system. Settings app > Personalization > Colors > Transparency Effects I have seen many header subclassing examples that use _WinAPI_SetBkColor but it never works to change the header background color. I'm guessing it must have worked at some point in time with older Windows OS versions, but does not work now. Also, I'm pretty certain that _WinAPI_SetBkColor wont work to accept Windows 11 materials. It generally must be done with FillRect which I had done before with statusbar and so on. It basically works on the alpha channel of the color, so anything close to black works best. For example, anything between 0x000000 and 0x202020 shows the materials the best. My example with FillRect on the header items: expandcollapse popup#include <GUIConstantsEx.au3> #include <WindowsStylesConstants.au3> #include <WinAPIShellEx.au3> #include <WinAPISysWin.au3> #include <WinAPITheme.au3> #include <WinAPIGdi.au3> #include <GuiHeader.au3> ; initiate System DPI awareness DllCall("user32.dll", "bool", "SetProcessDpiAwarenessContext", @AutoItX64 ? "int64" : "int", -2) Global $hListView, $hHeader Global $g_hSubclassProc = 0, $g_pSubclassProc = 0 Global Const $DWMSBT_AUTO = 0 ; Default (Auto) Global Const $DWMSBT_NONE = 1 ; None Global Const $DWMSBT_MAINWINDOW = 2 ; Mica Global Const $DWMSBT_TRANSIENTWINDOW = 3 ; Acrylic Global Const $DWMSBT_TABBEDWINDOW = 4 ; Mica Alt (Tabbed) Enum $APPMODE_DEFAULT = 0, $APPMODE_ALLOWDARK, $APPMODE_FORCEDARK, $APPMODE_FORCELIGHT, $APPMODE_MAX Global Const $tagNMCUSTOMDRAWINFO = $tagNMHDR & ";dword DrawStage;handle hdc;" & $tagRECT & ";dword_ptr ItemSpec;uint ItemState;lparam lItemParam;" Example() Func Example() Local $hGUI = GUICreate("ListView", 300, 170) GUISetBkColor(0x000000) _WinAPI_SetPreferredAppMode($APPMODE_FORCEDARK) Local $idListview = GUICtrlCreateListView("col1|col2|col3", 10, 10, 280, 150) $hListView = GUICtrlGetHandle($idListview) GUICtrlSetBkColor(-1, 0x202020) GUICtrlSetColor(-1, 0xFFFFFF) GUICtrlCreateListViewItem("item1|item1|item1", $idListview) GUICtrlCreateListViewItem("item2|item2|item2", $idListview) GUICtrlCreateListViewItem("item3|item3|item3", $idListview) $g_hSubclassProc = DllCallbackRegister("_SubclassProc", "lresult", "hwnd;uint;wparam;lparam;uint_ptr;dword_ptr") $g_pSubclassProc = DllCallbackGetPtr($g_hSubclassProc) _WinAPI_SetWindowSubclass($hListView, $g_pSubclassProc, 0) $hHeader = _WinAPI_FindWindowEx($hListView, 0, "SysHeader32", "") _WinAPI_SetWindowTheme($hHeader, 'DarkMode_ItemsView') ; Apply Acrylic material (yuck, but for testing purposes!) _WinAPI_DwmSetWindowAttributeEx($hGUI, $DWMWA_USE_IMMERSIVE_DARK_MODE, True) _WinAPI_DwmSetWindowAttributeEx($hGUI, $DWMWA_SYSTEMBACKDROP_TYPE, $DWMSBT_TRANSIENTWINDOW) _WinAPI_DwmExtendFrameIntoClientArea($hGUI, _WinAPI_CreateMargins(-1, -1, -1, -1)) GUISetState(@SW_SHOW) ; Loop until the user exits. While 1 Switch GUIGetMsg() Case $GUI_EVENT_CLOSE ExitLoop EndSwitch WEnd _WinAPI_RemoveWindowSubclass($hListView, $g_pSubclassProc, 0) EndFunc ;==>Example Func _WinAPI_FindWindowEx($hParent, $hAfter, $sClass, $sTitle = "") 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 _SubclassProc($hWnd, $iMsg, $wParam, $lParam, $iID, $pData) #forceref $iID, $pData Local $hDC, $sClass, $iRet, $tRect Switch $iMsg Case $WM_NOTIFY Local $tNMHDR = DllStructCreate($tagNMHDR, $lParam) Local $hFrom = $tNMHDR.hWndFrom Local $iCode = $tNMHDR.Code Local $hFont = __CreateFont("Segoe UI", 9) If $iCode = $NM_CUSTOMDRAW Then Local $tNMCD = DllStructCreate($tagNMCUSTOMDRAWINFO, $lParam) Local $dwStage = $tNMCD.DrawStage $hDC = $tNMCD.hdc Switch _WinAPI_GetClassName($hFrom) Case "sysheader32" Switch $dwStage Case $CDDS_PREPAINT Return $CDRF_NOTIFYITEMDRAW Case $CDDS_ITEMPREPAINT ;_WinAPI_SetTextColor($hDC, 0xFFFFFF) Return BitOR($CDRF_NEWFONT, $CDRF_NOTIFYPOSTPAINT) Case $CDDS_ITEMPOSTPAINT ; Set header section size Local $hBrush Local $tInfo = DllStructCreate($tagNMCUSTOMDRAWINFO, $lParam) Local $tNMCustomDraw = DllStructCreate($tagNMLVCUSTOMDRAW, $lParam) Local $tRECT = DllStructCreate($tagRECT) DllStructSetData($tRECT, 1, DllStructGetData($tNMCustomDraw, 6)) DllStructSetData($tRECT, 2, DllStructGetData($tNMCustomDraw, 7)) DllStructSetData($tRECT, 3, DllStructGetData($tNMCustomDraw, 8) - 1) DllStructSetData($tRECT, 4, DllStructGetData($tNMCustomDraw, 9)) _WinAPI_SetBkMode($hDC, $TRANSPARENT) _WinAPI_SelectObject($hDC, $hFont) _WinAPI_SetTextColor($hDC, 0xFFFFFF) Local $iCol = $tInfo.ItemSpec Local $sText = _GUICtrlHeader_GetItemText($hHeader, $iCol) If BitAND($tInfo.ItemState, $CDIS_DEFAULT) Then ; this is not working $hBrush = _WinAPI_CreateSolidBrush(0xff00ff) ElseIf BitAND($tInfo.ItemState, $CDIS_FOCUS) Then ; this is not working $hBrush = _WinAPI_CreateSolidBrush(0xff0000) ElseIf BitAND($tInfo.ItemState, $CDIS_HOT) Then ; this is not working $hBrush = _WinAPI_CreateSolidBrush(0x0000ff) Else $hBrush = _WinAPI_CreateSolidBrush(0x000000) ; this is being used EndIf _WinAPI_FillRect($hDC, $tRECT, $hBrush) Local $tRECT = DllStructCreate($tagRECT) DllStructSetData($tRECT, 1, DllStructGetData($tNMCustomDraw, 6)) DllStructSetData($tRECT, 2, DllStructGetData($tNMCustomDraw, 7) + 2) DllStructSetData($tRECT, 3, DllStructGetData($tNMCustomDraw, 8) - 1) DllStructSetData($tRECT, 4, DllStructGetData($tNMCustomDraw, 9)) _WinAPI_DrawText($hDC, $sText, $tRECT, BitOR($DT_CENTER, $DT_VCENTER, $DT_NOCLIP)) _WinAPI_DeleteObject($hBrush) _WinAPI_DeleteObject($hFont) Return $CDRF_NEWFONT EndSwitch EndSwitch EndIf EndSwitch Return _WinAPI_DefSubclassProc($hWnd, $iMsg, $wParam, $lParam) EndFunc ;==>_SubclassProc Func __CreateFont($sFontName, $nHeight = 9, $nWidth = 400) Local $stFontName = DllStructCreate("char[260]") DllStructSetData($stFontName, 1, $sFontName) Local $hDC = _WinAPI_GetDC(0) ; Get the Desktops DC Local $nPixel = _WinAPI_GetDeviceCaps($hDC, 90) $nHeight = 0 - _WinAPI_MulDiv($nHeight, $nPixel, 72) _WinAPI_ReleaseDC(0, $hDC) Local $hFont = _WinAPI_CreateFont($nHeight, 0, 0, 0, $nWidth, False, False, False, _ $DEFAULT_CHARSET, $OUT_DEFAULT_PRECIS, $CLIP_DEFAULT_PRECIS, $PROOF_QUALITY, $DEFAULT_PITCH, $sFontName) Return $hFont EndFunc ;==>__CreateFont Func _WinAPI_SetPreferredAppMode($iPreferredAppMode) ;Windows 10 Build 18362+ Local $aResult = DllCall("UxTheme.dll", "long", 135, "long", $iPreferredAppMode) If @error Then Return SetError(1, 0, False) Return $aResult[0] EndFunc ;==>_WinAPI_SetPreferredAppMode Func _WinAPI_DwmSetWindowAttributeEx($hWnd, $iAttribute, $iData) Switch $iAttribute Case 2, 3, 4, 6, 7, 8, 10, 11, 12, 13, 14, 15, 16, $DWMWA_USE_IMMERSIVE_DARK_MODE, 33, 34, 35, 36, 37, 38, 39, 40 Case Else Return SetError(1, 0, 0) EndSwitch Local $aCall = DllCall('dwmapi.dll', 'long', 'DwmSetWindowAttribute', 'hwnd', $hWnd, 'dword', $iAttribute, _ 'dword*', $iData, 'dword', 4) If @error Then Return SetError(@error + 10, @extended, 0) If $aCall[0] Then Return SetError(10, $aCall[0], 0) Return 1 EndFunc ;==>_WinAPI_DwmSetWindowAttributeEx Your example without FillRect on header items: expandcollapse popup#include <GUIConstants.au3> #include <WindowsConstants.au3> #include <WinAPI.au3> #include <WinAPITheme.au3> Global Const $DWMSBT_AUTO = 0 ; Default (Auto) Global Const $DWMSBT_NONE = 1 ; None Global Const $DWMSBT_MAINWINDOW = 2 ; Mica Global Const $DWMSBT_TRANSIENTWINDOW = 3 ; Acrylic Global Const $DWMSBT_TABBEDWINDOW = 4 ; Mica Alt (Tabbed) Global Const $tagNMCUSTOMDRAWINFO = "struct;" & $tagNMHDR & ";dword DrawStage;handle hdc;" & _ $tagRECT & ";dword_ptr ItemSpec;uint ItemState;lparam lItemParam;endstruct" Example() Func Example() DllCall("user32.dll", "bool", "SetProcessDpiAwarenessContext", @AutoItX64 ? "int64" : "int", -2) Local $hGUI = GUICreate("ListView", 300, 170) GUISetBkColor(0x202020) Local $idListview = GUICtrlCreateListView("col1|col2|col3", 10, 10, 280, 150) Local $hListView = GUICtrlGetHandle($idListview) GUICtrlSetBkColor(-1, 0x404040) GUICtrlSetColor(-1, 0xFFFFFF) GUICtrlCreateListViewItem("item1|item1|item1", $idListview) GUICtrlCreateListViewItem("item2|item2|item2", $idListview) GUICtrlCreateListViewItem("item3|item3|item3", $idListview) Local $hSubclassProc = DllCallbackRegister("_SubclassProc", "lresult", "hwnd;uint;wparam;lparam;uint_ptr;dword_ptr") Local $pSubclassProc = DllCallbackGetPtr($hSubclassProc) _WinAPI_SetWindowSubclass($hListView, $pSubclassProc, 0) Local $hHeader = GUICtrlSendMsg($idListview, $LVM_GETHEADER, 0, 0) _WinAPI_SetWindowTheme($hHeader, 'DarkMode_ItemsView') ; Apply Acrylic material (yuck, but for testing purposes!) _WinAPI_DwmSetWindowAttributeEx($hGUI, $DWMWA_USE_IMMERSIVE_DARK_MODE, True) _WinAPI_DwmSetWindowAttributeEx($hGUI, $DWMWA_SYSTEMBACKDROP_TYPE, $DWMSBT_TRANSIENTWINDOW) _WinAPI_DwmExtendFrameIntoClientArea($hGUI, _WinAPI_CreateMargins(-1, -1, -1, -1)) GUISetState(@SW_SHOW) ; Loop until the user exits. While 1 Switch GUIGetMsg() Case $GUI_EVENT_CLOSE ExitLoop EndSwitch WEnd _WinAPI_RemoveWindowSubclass($hListView, $pSubclassProc, 0) GUIDelete($hGUI) DllCallbackFree($hSubclassProc) EndFunc ;==>Example Func _SubclassProc($hWnd, $iMsg, $wParam, $lParam, $iID, $pData) Switch $iMsg Case $WM_NOTIFY Local $tNMHDR = DllStructCreate($tagNMHDR, $lParam) If $tNMHDR.Code = $NM_CUSTOMDRAW Then Local $tNMCD = DllStructCreate($tagNMCUSTOMDRAWINFO, $lParam) Switch $tNMCD.DrawStage Case $CDDS_PREPAINT Return $CDRF_NOTIFYITEMDRAW Case $CDDS_ITEMPREPAINT _WinAPI_SetTextColor($tNMCD.hdc, 0xFFFFFF) Return $CDRF_DODEFAULT EndSwitch EndIf EndSwitch Return _WinAPI_DefSubclassProc($hWnd, $iMsg, $wParam, $lParam) EndFunc ;==>_SubclassProc Func _WinAPI_DwmSetWindowAttributeEx($hWnd, $iAttribute, $iData) Switch $iAttribute Case 2, 3, 4, 6, 7, 8, 10, 11, 12, 13, 14, 15, 16, $DWMWA_USE_IMMERSIVE_DARK_MODE, 33, 34, 35, 36, 37, 38, 39, 40 Case Else Return SetError(1, 0, 0) EndSwitch Local $aCall = DllCall('dwmapi.dll', 'long', 'DwmSetWindowAttribute', 'hwnd', $hWnd, 'dword', $iAttribute, _ 'dword*', $iData, 'dword', 4) If @error Then Return SetError(@error + 10, @extended, 0) If $aCall[0] Then Return SetError(10, $aCall[0], 0) Return 1 EndFunc ;==>_WinAPI_DwmSetWindowAttributeEx
WildByDesign Posted 6 hours ago Author Posted 6 hours ago By the way, I also tried sending a message ($HDM_GETFOCUSEDITEM) to the header in hopes to get whatever header item is under the cursor, but no luck there. I was hoping to try that to determine which brush colour to use. I am not incredibly familiar with _SendMessage though, so I may have completely botched it anyway.
WildByDesign Posted 4 hours ago Author Posted 4 hours ago I just realized that I had asked this question less than 6 months ago. 🤣 It was in the Is a ListView Header subclass with FillRect, DrawText and SetBkMode possible? thread and had some success. The end result was achieving a different brush colour on click, but not on hover unfortunately. The main difference there was doing the RectFill in $CDDS_ITEMPREPAINT, while in this current thread I'm using $CDDS_ITEMPOSTPAINT. Regardless, I am still open to any kind of improvements. Particularly if we can ever find a way to achieve a different brush colour on hover. Here is the end result from the other thread to give us another perspective: expandcollapse popup#include <APIConstants.au3> #include <ListViewConstants.au3> #include <WinAPIConstants.au3> #include <WinAPIGdi.au3> #include <WinAPIShellEx.au3> #include <WinAPISys.au3> #include <WinAPITheme.au3> #include <GuiHeader.au3> #include <GuiListView.au3> ; DPI awareness DllCall("User32.dll", "bool", "SetProcessDpiAwarenessContext" , "HWND", "DPI_AWARENESS_CONTEXT" -2) Enum $APPMODE_FORCEDARK ; Dark Mode Colors (RGB) Global Const $COLOR_BG_DARK = 0x000000 Global Const $COLOR_TEXT_LIGHT = 0xFFFFFF Global Const $COLOR_EDIT_BG = 0x1E1E1E ; Global variables for subclassing (MUST be declared before _Example()!) Global $g_hGUI = 0, $g_ListView Global $g_aControls[50][3] = [[0, 0, 0]] ; [ControlID, hWnd, OldWndProc] Global $g_iControlCount = 0 Global $g_pSubclassProc = 0 ; Structure for NM_CUSTOMDRAW notification Global Const $tagNMCUSTOMDRAW = _ $tagNMHDR & ";" & _ ; Contains NM_CUSTOMDRAW / NMHDR header among other things "dword dwDrawStage;" & _ ; Current drawing stage (CDDS_*) "handle hdc;" & _ ; Device Context Handle "long left;long top;long right;long bottom;" & _ ; Drawing rectangle "dword_ptr dwItemSpec;" & _ ; Item index or other info (depending on the control) "uint uItemState;" & _ ; State Flags (CDIS_SELECTED, CDIS_FOCUS etc.) "lparam lItemlParam" ; lParam set by the item (e.g., via LVITEM.lParam) _Example() Func _Example() #Region GUI $g_hGUI = GUICreate("ListView with Materials", 400, 400) GUISetBkColor($COLOR_BG_DARK, $g_hGUI) #EndRegion GUI #Region LIST VIEW Local $idListView = GUICtrlCreateListView("Sample|ListView", 10, 10, 380, 380, -1, BitOR($LVS_EX_DOUBLEBUFFER, $LVS_EX_FULLROWSELECT, $WS_EX_CLIENTEDGE)) _AddControlForSubclass($idListView) GUICtrlSetBkColor($idListView, $COLOR_EDIT_BG) GUICtrlSetColor($idListView, $COLOR_TEXT_LIGHT) GUICtrlSetTip(-1, '#Region LIST VIEW') GUICtrlCreateListViewItem("A|One", $idListView) GUICtrlCreateListViewItem("B|Two", $idListView) GUICtrlCreateListViewItem("C|Three", $idListView) $g_ListView = GUICtrlGetHandle($idListView) _GUICtrlListView_SetColumnWidth($idListView, 1, $LVSCW_AUTOSIZE_USEHEADER) #EndRegion LIST VIEW ; Apply Dark Mode _ApplyDarkModeToAllControls() If @OSBuild >= 22621 Then _WinAPI_DwmSetWindowAttribute_unr($g_hGUI, 38, 3) _WinAPI_DwmExtendFrameIntoClientArea($g_hGUI, _WinAPI_CreateMargins(-1, -1, -1, -1)) EndIf GUISetState(@SW_SHOW) While 1 Switch GUIGetMsg() Case $GUI_EVENT_CLOSE _CleanupSubclassing() ExitLoop EndSwitch WEnd GUIDelete() EndFunc ;==>_Example 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 _AddControlForSubclass($iCtrlID) Local $hCtrl = GUICtrlGetHandle($iCtrlID) If $hCtrl Then $g_aControls[$g_iControlCount][0] = $iCtrlID $g_aControls[$g_iControlCount][1] = $hCtrl $g_aControls[$g_iControlCount][2] = 0 ; Placeholder for OldWndProc $g_iControlCount += 1 EndIf EndFunc ;==>_AddControlForSubclass Func _ApplyDarkModeToAllControls() ; DWM Dark Mode for the main window _WinAPI_SetPreferredAppMode($APPMODE_FORCEDARK) ; Create subclass callback If Not $g_pSubclassProc Then $g_pSubclassProc = DllCallbackRegister("_SubclassProc", "lresult", "hwnd;uint;wparam;lparam;uint_ptr;dword_ptr") ; Subclass all controls Local $hCtrl, $sClass, $hEdit, $hComboLBox, $hHeader, $hUpDown For $i = 0 To $g_iControlCount - 1 $hCtrl = $g_aControls[$i][1] If $hCtrl Then $sClass = _WinAPI_GetClassName($hCtrl) ; Use SetWindowSubclass _WinAPI_SetWindowSubclass($hCtrl, DllCallbackGetPtr($g_pSubclassProc), $i, 0) ; Special themes for different control types Switch StringLower($sClass) Case "syslistview32" _WinAPI_SetWindowTheme($hCtrl, "DarkMode_Explorer", 0) ; Also make the ListView header dark $hHeader = _SendMessage($hCtrl, $LVM_GETHEADER, 0, 0) If $hHeader Then _WinAPI_SetWindowTheme($hHeader, "DarkMode_ItemsView", 0) EndIf Case Else _WinAPI_SetWindowTheme($hCtrl, "DarkMode_Explorer", 0) EndSwitch _WinAPI_AllowDarkModeForWindow($hCtrl, True) EndIf Next ; Update theme system _WinAPI_RefreshImmersiveColorPolicyState() _WinAPI_FlushMenuThemes() _WinAPI_DwmSetWindowAttribute($g_hGUI, $DWMWA_USE_IMMERSIVE_DARK_MODE, True) ; Redraw GUI _WinAPI_RedrawWindow($g_hGUI, 0, 0, $RDW_UPDATENOW) EndFunc ;==>_ApplyDarkModeToAllControls Func _CleanupSubclassing() ; Remove all subclasses If $g_pSubclassProc Then Local $hCtrl For $i = 0 To $g_iControlCount - 1 $hCtrl = $g_aControls[$i][1] If $hCtrl Then _WinAPI_RemoveWindowSubclass($hCtrl, DllCallbackGetPtr($g_pSubclassProc), $i) EndIf Next DllCallbackFree($g_pSubclassProc) $g_pSubclassProc = 0 EndIf EndFunc ;==>_CleanupSubclassing Func _SubclassProc($hWnd, $iMsg, $wParam, $lParam, $iID, $pData) Switch $iMsg Case $WM_NOTIFY Local $tNMHDR = DllStructCreate($tagNMHDR, $lParam) Local $hFrom = $tNMHDR.hWndFrom Local $iCode = $tNMHDR.Code ; --- Adjust ListView Header text color --- If $iCode = $NM_CUSTOMDRAW Then Local $tNMCUSTOMDRAW = DllStructCreate($tagNMCUSTOMDRAW, $lParam) Local $dwDrawStage = $tNMCUSTOMDRAW.dwDrawStage Local $hDC = $tNMCUSTOMDRAW.hdc Switch $dwDrawStage Case $CDDS_PREPAINT Return $CDRF_NOTIFYITEMDRAW Case $CDDS_ITEMPREPAINT $hDC = $tNMCUSTOMDRAW.hDC $iItem = $tNMCUSTOMDRAW.dwItemSpec $tRect = DllStructCreate($tagRECT, DllStructGetPtr($tNMCUSTOMDRAW, "Left")) _WinAPI_SetBkMode($hDC, 1) _WinAPI_SetTextColor($hDC, 0xFFFFFF) If BitAND($tNMCUSTOMDRAW.uItemState, $CDIS_SELECTED) Then $hBrush = _WinAPI_CreateSolidBrush(0x202020) ElseIf BitAND($tNMCUSTOMDRAW.uItemState, $CDIS_HOT) Then $hBrush = _WinAPI_CreateSolidBrush(0xff0000) ElseIf BitAND($tNMCUSTOMDRAW.uItemState, $CDIS_FOCUS) Then $hBrush = _WinAPI_CreateSolidBrush(0x0000ff) Else $hBrush = _WinAPI_CreateSolidBrush(0x000000) EndIf _WinAPI_FillRect($hDC, $tRect, $hBrush) _WinAPI_DeleteObject($hBrush) _WinAPI_InflateRect($tRect, -5, -2) _WinAPI_DrawText($hDC, _GUICtrlHeader_GetItemText($tNMCUSTOMDRAW.hWndFrom, $iItem), $tRect, $DT_LEFT) Return $CDRF_SKIPDEFAULT EndSwitch EndIf EndSwitch ; Forward standard message to DefSubclassProc Return _WinAPI_DefSubclassProc($hWnd, $iMsg, $wParam, $lParam) EndFunc ;==>_SubclassProc Func _WinAPI_FindWindowEx($hParent, $hAfter, $sClass, $sTitle = "") 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 _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 Func _WinAPI_FlushMenuThemes() Local $aResult = DllCall("UxTheme.dll", "none", 136) If @error Then Return SetError(1, 0, False) Return True EndFunc ;==>_WinAPI_FlushMenuThemes Func _WinAPI_RefreshImmersiveColorPolicyState() Local $aResult = DllCall("UxTheme.dll", "none", 104) If @error Then Return SetError(1, 0, False) Return True EndFunc ;==>_WinAPI_RefreshImmersiveColorPolicyState Func _WinAPI_SetPreferredAppMode($iPreferredAppMode) ;Windows 10 Build 18362+ Local $aResult = DllCall("UxTheme.dll", "long", 135, "long", $iPreferredAppMode) If @error Then Return SetError(1, 0, False) Return $aResult[0] EndFunc ;==>_WinAPI_SetPreferredAppMode #EndRegion DarkMode API ; #FUNCTION# ==================================================================================================================== ; Name ..........: _WinAPI_DwmSetWindowAttribute_unr ; Description ...: Dose the same as _WinAPI_DwmSetWindowAttribute; But has no Restrictions ; Syntax ........: _WinAPI_DwmSetWindowAttribute_unr($hWnd, $iAttribute, $iData) ; Parameters ....: $hWnd - a handle value. ; $iAttribute - an integer value. ; $iData - an integer value. ; Return values .: Success: 1 Failure: @error, @extended & False ; Author ........: argumentum ; Modified ......: ; Remarks .......: ; Related .......: ; Link ..........: https://www.autoitscript.com/forum/topic/211475-winapithemeex-darkmode-for-autoits-win32guis/?do=findComment&comment=1530103 ; Example .......: No ; =============================================================================================================================== Func _WinAPI_DwmSetWindowAttribute_unr($hWnd, $iAttribute, $iData) ; #include <WinAPIGdi.au3> ; unthoughtful unrestricting mod. Local $aCall = DllCall('dwmapi.dll', 'long', 'DwmSetWindowAttribute', 'hwnd', $hWnd, 'dword', $iAttribute, _ 'dword*', $iData, 'dword', 4) If @error Then Return SetError(@error, @extended, 0) If $aCall[0] Then Return SetError(10, $aCall[0], 0) Return 1 EndFunc ;==>_WinAPI_DwmSetWindowAttribute_unr
Nine Posted 4 hours ago Posted 4 hours ago That seems to be working fine : expandcollapse popup; From Nine #include <GuiConstants.au3> #include <GuiHeader.au3> #include <WinAPI.au3> #include <Misc.au3> Example() Func Example() Local $hGUI = GUICreate("Header ", 500, 300) Local $idListView = GUICtrlCreateListView("Items List|SubItems1|SubItems2", 10, 10, 480, 280) Local $hListView = GUICtrlGetHandle($idListView) Local $hHeader = GUICtrlSendMsg($idListView, $LVM_GETHEADER, 0, 0) Local $hSubClass = DllCallbackRegister(WM_NOTIFY, "lresult", "hwnd;uint;wparam;lparam;uint_ptr;dword_ptr") _WinAPI_SetWindowSubclass($hListView, DllCallbackGetPtr($hSubClass), $idListView, $hHeader) _WinAPI_SetWindowSubclass($hHeader, DllCallbackGetPtr($hSubClass), $idListView, $hHeader) GUICtrlCreateListViewItem("item1|item1|item1", $idListView) GUICtrlCreateListViewItem("item2|item2|item2", $idListView) GUICtrlCreateListViewItem("item3|item3|item3", $idListView) GUISetState() Do Until GUIGetMsg() = $GUI_EVENT_CLOSE _WinAPI_RemoveWindowSubclass($hHeader, DllCallbackGetPtr($hSubClass), $idListView) _WinAPI_RemoveWindowSubclass($hListView, DllCallbackGetPtr($hSubClass), $idListView) DllCallbackFree($hSubClass) EndFunc ;==>Example Func WM_NOTIFY($hWnd, $iMsg, $wParam, $lParam, $iID, $pData) Local Static $bHover, $tPoint Switch $iMsg Case $WM_NOTIFY Local $tCustDraw = DllStructCreate($tagNMLVCUSTOMDRAW, $lParam) If $tCustDraw.hWndFrom = $pData And $tCustDraw.Code = $NM_CUSTOMDRAW Then Local $tCustDraw = DllStructCreate($tagNMLVCUSTOMDRAW, $lParam) Switch $tCustDraw.dwDrawStage Case $CDDS_PREPAINT Return $CDRF_NOTIFYITEMDRAW Case $CDDS_ITEMPREPAINT Local $tRect = DllStructCreate($tagRECT, DllStructGetPtr($tCustDraw, "Left")) _WinAPI_SetBkMode($tCustDraw.hDC, 1) _WinAPI_SetTextColor($tCustDraw.hDC, 0xFFFFFF) Local $hBrush = _WinAPI_CreateSolidBrush($bHover And _WinAPI_PtInRect($tRect, $tPoint) ? (_IsPressed($VK_LBUTTON) ? 0xA0A0A0 : 0x505050) : 0x202020) _WinAPI_FillRect($tCustDraw.hDC, $tRect, $hBrush) _WinAPI_DeleteObject($hBrush) _WinAPI_InflateRect($tRect, -5, -2) _WinAPI_DrawText($tCustDraw.hDC, _GUICtrlHeader_GetItemText($tCustDraw.hWndFrom, $tCustDraw.dwItemSpec), $tRect, $DT_LEFT) Return $CDRF_SKIPDEFAULT EndSwitch EndIf Case $WM_MOUSEMOVE If $pData = $hWnd Then $bHover = True $tPoint = _WinAPI_GetMousePos(True, $hWnd) _WinAPI_InvalidateRect($hWnd, 0, False) _WinAPI_TrackMouseEvent($hWnd, $TME_LEAVE) EndIf Case $WM_MOUSELEAVE If $pData = $hWnd Then $bHover = False $tPoint = 0 _WinAPI_InvalidateRect($hWnd, 0, False) EndIf EndSwitch Return _WinAPI_DefSubclassProc($hWnd, $iMsg, $wParam, $lParam) EndFunc ;==>WM_NOTIFY “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
argumentum Posted 4 hours ago Posted 4 hours ago 5 minutes ago, Nine said: That seems to be working fine : if you resize the columns it all goes crazy Follow the link to my code contribution ( and other things too ). FAQ - Please Read Before Posting.
MattyD Posted 4 hours ago Posted 4 hours ago (edited) Hmm, apologies for the sidetrack, but I don't think we're quite there with the materials generally. The materials are presumably meant to be a background in and of themselves. ATM we're blending them with the backcolor of our win, so we lose the semi-transparent effect. Also, extending out that frame into the client area is affecting our controls. Ideally those should be painted on top of any window background... I've setup the left widow so you can remove the background and you can see what I mean. Obviously this approach is a non starter... if the window manager thinks the background is transparent, your mouse will click straight through it! expandcollapse popup#include <GUIConstants.au3> #include <WindowsConstants.au3> #include <WinAPI.au3> #include <WinAPITheme.au3> Global Const $DWMSBT_AUTO = 0 ; Default (Auto) Global Const $DWMSBT_NONE = 1 ; None Global Const $DWMSBT_MAINWINDOW = 2 ; Mica Global Const $DWMSBT_TRANSIENTWINDOW = 3 ; Acrylic Global Const $DWMSBT_TABBEDWINDOW = 4 ; Mica Alt (Tabbed) Example() Func Example() Local $hGUI = GUICreate("Win1", 300, 170, (@DesktopWidth-610)/2, -1, -1, BitOR($WS_EX_COMPOSITED, $WS_EX_LAYERED)) _WinAPI_SetLayeredWindowAttributes($hGUI, 0x123456, 255) Local $idRmvBkgnd = GUICtrlCreateCheckbox("Remove Bkgnd", 10, 10, 90, 25, $BS_PUSHLIKE) GUISetState() Local $hGUI2 = GUICreate("Win2", 300, 170, (@DesktopWidth+10)/2, -1, -1) Local $idExtendFrame = GUICtrlCreateCheckbox("Extend Frame", 10, 10, 90, 25, $BS_PUSHLIKE) Local $idHalfExtendFrame = GUICtrlCreateCheckbox("Patial Frame", 120, 10, 90, 25, $BS_PUSHLIKE) GUISetState() _WinAPI_DwmSetWindowAttributeEx($hGUI, $DWMWA_SYSTEMBACKDROP_TYPE, $DWMSBT_TRANSIENTWINDOW) _WinAPI_DwmSetWindowAttributeEx($hGUI2, $DWMWA_SYSTEMBACKDROP_TYPE, $DWMSBT_TRANSIENTWINDOW) While 1 Switch GUIGetMsg() Case $GUI_EVENT_CLOSE ExitLoop Case $idRmvBkgnd If GUICtrlRead($idRmvBkgnd) = $GUI_CHECKED Then _WinAPI_SetLayeredWindowAttributes($hGUI, _WinAPI_GetSysColor($COLOR_3DFACE)) Else _WinAPI_SetLayeredWindowAttributes($hGUI, 0x123456) EndIf Case $idExtendFrame If GUICtrlRead($idExtendFrame) = $GUI_CHECKED Then GUICtrlSetState($idHalfExtendFrame, $GUI_UNCHECKED) _WinAPI_DwmExtendFrameIntoClientArea($hGUI2, _WinAPI_CreateMargins(150, 85, 150, 85)) Else _WinAPI_DwmExtendFrameIntoClientArea($hGUI2, _WinAPI_CreateMargins(0, 0, 0, 0)) EndIf Case $idHalfExtendFrame If GUICtrlRead($idHalfExtendFrame) = $GUI_CHECKED Then GUICtrlSetState($idExtendFrame, $GUI_UNCHECKED) _WinAPI_DwmExtendFrameIntoClientArea($hGUI2, _WinAPI_CreateMargins(25, 25, 25, 25)) Else _WinAPI_DwmExtendFrameIntoClientArea($hGUI2, _WinAPI_CreateMargins(0, 0, 0, 0)) EndIf EndSwitch WEnd GUIDelete($hGUI) GUIDelete($hGUI2) EndFunc ;==>Example Func _WinAPI_DwmSetWindowAttributeEx($hWnd, $iAttribute, $iData) Switch $iAttribute Case 2, 3, 4, 6, 7, 8, 10, 11, 12, 13, 14, 15, 16, $DWMWA_USE_IMMERSIVE_DARK_MODE, 33, 34, 35, 36, 37, 38, 39, 40 Case Else Return SetError(1, 0, 0) EndSwitch Local $aCall = DllCall('dwmapi.dll', 'long', 'DwmSetWindowAttribute', 'hwnd', $hWnd, 'dword', $iAttribute, _ 'dword*', $iData, 'dword', 4) If @error Then Return SetError(@error + 10, @extended, 0) If $aCall[0] Then Return SetError(10, $aCall[0], 0) Return 1 EndFunc ;==>_WinAPI_DwmSetWindowAttributeEx Edited 4 hours ago by MattyD english!
Nine Posted 4 hours ago Posted 4 hours ago (edited) 42 minutes ago, argumentum said: if you resize the columns it all goes crazy Yes you are right. Need to check this. ps. subclassing the header by itself is causing Windows to react erroneously. Even with a very minimalistic subclass proc, resizing the header causes the GUI to freeze after awhile. Edited 3 hours ago by Nine “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 3 hours ago Author Posted 3 hours ago (edited) 54 minutes ago, MattyD said: The materials are presumably meant to be a background in and of themselves. ATM we're blending them with the backcolor of our win, so we lose the semi-transparent effect You are right. This “extending to client area” technique is what programs such as Mica For Everyone uses. In their case, they are doing it system-wide to work with any Win32 app. They don’t have a direct hook with individual app subclassing though, so they are limited in that sense. In our case, we have subclassing and full control since it is our GUI. So technically we could do much better with regard to materials. This extending method can be bad for the look of fonts as well since they would need alpha blending. Anyway, the proper method for applying materials to GUI and individual control windows is all done via WinRT functions. If we had that in AutoIt that would be phenomenal with regard to modern GUI functionality. But I have never been able to understand how to use the WinRT functionality in AutoIt to apply materials. If we had that, we would have much more control over material opacity, strength of effects and other fine tuning. Edited 3 hours ago by WildByDesign
Solution Nine Posted 1 hour ago Solution Posted 1 hour ago (edited) I think the issue with the header resize is solved. expandcollapse popup; From Nine #include <GuiConstants.au3> #include <GuiHeader.au3> #include <WinAPI.au3> #include <Misc.au3> Example() Func Example() Local $hGUI = GUICreate("Header ", 500, 300) Local $idListView = GUICtrlCreateListView("Items List|SubItems1|SubItems2", 10, 10, 480, 280, -1, $LVS_EX_DOUBLEBUFFER) Local $hListView = GUICtrlGetHandle($idListView) Local $hHeader = GUICtrlSendMsg($idListView, $LVM_GETHEADER, 0, 0) Local $hSubClass = DllCallbackRegister(WM_NOTIFY, "lresult", "hwnd;uint;wparam;lparam;uint_ptr;dword_ptr") _WinAPI_SetWindowSubclass($hListView, DllCallbackGetPtr($hSubClass), $hSubClass, $hHeader) _WinAPI_SetWindowSubclass($hHeader, DllCallbackGetPtr($hSubClass), 1000, $hHeader) GUICtrlCreateListViewItem("item1|item1|item1", $idListview) GUICtrlCreateListViewItem("item2|item2|item2", $idListview) GUICtrlCreateListViewItem("item3|item3|item3", $idListview) GUISetState() Do Until GUIGetMsg() = $GUI_EVENT_CLOSE _WinAPI_RemoveWindowSubclass($hHeader, DllCallbackGetPtr($hSubClass), 1000) _WinAPI_RemoveWindowSubclass($hListView, DllCallbackGetPtr($hSubClass), $hSubClass) DllCallbackFree($hSubClass) EndFunc ;==>Example Func WM_NOTIFY($hWnd, $iMsg, $wParam, $lParam, $iID, $pData) Local Static $bHover, $tPoint Switch $iMsg Case $WM_NOTIFY Local $tNMHDR = DllStructCreate($tagNMHDR, $lParam) Switch $tNMHDR.Code Case $NM_CUSTOMDRAW If $tNMHDR.hWndFrom = $pData Then Local $tCustDraw = DllStructCreate($tagNMLVCUSTOMDRAW, $lParam) Switch $tCustDraw.dwDrawStage Case $CDDS_PREPAINT Return $CDRF_NOTIFYITEMDRAW Case $CDDS_ITEMPREPAINT Local $tRect = DllStructCreate($tagRECT, DllStructGetPtr($tCustDraw, "Left")) _WinAPI_SetBkMode($tCustDraw.hDC, 1) _WinAPI_SetTextColor($tCustDraw.hDC, 0xFFFFFF) Local $hBrush = _WinAPI_CreateSolidBrush($bHover And _WinAPI_PtInRect($tRect, $tPoint) ? (_IsPressed($VK_LBUTTON) ? 0xA0A0A0 : 0x505050) : 0x202020) _WinAPI_FillRect($tCustDraw.hDC, $tRect, $hBrush) _WinAPI_DeleteObject($hBrush) _WinAPI_InflateRect($tRect, -5, -2) _WinAPI_DrawText($tCustDraw.hDC, _GUICtrlHeader_GetItemText($tCustDraw.hWndFrom, $tCustDraw.dwItemSpec), $tRect, $DT_LEFT) Return $CDRF_SKIPDEFAULT EndSwitch EndIf Case $HDN_BEGINTRACKW $bHover = False _WinAPI_RemoveWindowSubclass($pData, DllCallbackGetPtr($iID), 1000) Case $HDN_ENDTRACKW _WinAPI_SetWindowSubclass($pData, DllCallbackGetPtr($iID), 1000, $pData) EndSwitch Case $WM_MOUSEMOVE If $pData = $hWnd Then $bHover = True $tPoint = _WinAPI_GetMousePos(True, $hWnd) _WinAPI_InvalidateRect($hWnd, 0, False) _WinAPI_TrackMouseEvent($hWnd, $TME_LEAVE) EndIf Case $WM_MOUSELEAVE If $pData = $hWnd Then $bHover = False _WinAPI_InvalidateRect($hWnd, 0, False) EndIf EndSwitch Return _WinAPI_DefSubclassProc($hWnd, $iMsg, $wParam, $lParam) EndFunc ;==>WM_NOTIFY Added double buffer to avoid flickers. Edited 1 hour ago by Nine better code argumentum and WildByDesign 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 40 minutes ago Author Posted 40 minutes ago 52 minutes ago, Nine said: I think the issue with the header resize is solved. You did an absolutely incredible job with this. I feel like this was a pretty unique challenge and you nailed it. It works very well and performs great since you added the double buffering to the ListView. I am really impressed with your techniques. Thank you for always being open to interesting and unique challenges.
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