Leaderboard
Popular Content
Showing content with the highest reputation on 12/06/2025 in Posts
-
Need help synchronizing MDI (WS_EX_MDICHILD) window with Child Window (WS_CHILD)
ioa747 and one other reacted to WildByDesign for a topic
@pixelsearch That is some seriously incredible work! That real-time resize synchronization is a beautiful thing. Thank you for figuring that out. I don't think I realized how necessary that really was. I have a fix for this as well as a few other things. You also mentioned a script hang at times when reordering columns. I haven't experienced that yet but I'll see if there is something I can do about the timing of it. This is nice. I didn't realize that could be used to measure individual controls. I was using the following: Local $aRect = _GUICtrlHeader_GetItemRect($g_hHeader, 0) $sHeaderHeight = $aRect[3] But yours is less code so that seems better. There were some flickering issues with the horizontal scrolling as well as the resizing of header items. Also the issue with the scrollbars turning gray. I have solved all of those issues and made all of those silky smooth. It took me 2-3 hours to really figure it out. And I may have lost my marbles a few times. But in the end, it is silky smooth. I added a call to _changeExStyles() in function _resizeHeaderItems() and function _resizeLVCols() Func _changeExStyles() ; remove WS_EX_COMPOSITED from GUI __WinAPI_Set_Window_Style($g_hGUI, $WS_EX_COMPOSITED, False, True) ; add LVS_EX_DOUBLEBUFFER to ListView _GUICtrlListView_SetExtendedListViewStyle($g_hListview, BitOR($LVS_EX_FULLROWSELECT, $LVS_EX_DOUBLEBUFFER)) ; set adlib to reset those values AdlibRegister("_resetExStylesAdlib", 3000) EndFunc Func _resetExStylesAdlib() ; add WS_EX_COMPOSITED to GUI __WinAPI_Set_Window_Style($g_hGUI, $WS_EX_COMPOSITED, True, True) ; remove LVS_EX_DOUBLEBUFFER from ListView _GUICtrlListView_SetExtendedListViewStyle($g_hListview, $LVS_EX_FULLROWSELECT) ; unregister adlib AdlibUnRegister("_resetExStylesAdlib") EndFunc The idea is that the extended styles for the GUI and ListView are changed temporarily (3 seconds by Adlib) before being reset back to default. This way, all of the problems are solved with header and ListView when accessing them. Then reset back to default so that any resizing or separator movement in the main GUI will still be smooth. Silky smooth script in full: #include <GUIConstantsEx.au3> #include <GuiListView.au3> #include <StructureConstants.au3> #include <WinAPISysWin.au3> #include <WindowsConstants.au3> #include <WinAPISys.au3> ; DPI DllCall("User32.dll", "bool", "SetProcessDpiAwarenessContext" , "HWND", "DPI_AWARENESS_CONTEXT" -2) Opt("MustDeclareVars", 1) ;0=no, 1=require pre-declaration Global $g_hGUI, $g_hChild, $g_hHeader, $g_hListview, $g_bHeaderEndDrag Example() Func Example() $g_hGUI = GUICreate("Example", 400, 400, -1, -1, $WS_OVERLAPPEDWINDOW, $WS_EX_COMPOSITED) GUISetBkColor(0x202020) GUISetState(@SW_SHOW, $g_hGUI) $g_hChild = GUICreate("ChildWindow", 320, 320, 40, 40, $WS_CHILD, -1, $g_hGUI) GUISetBkColor(0x606060) $g_hHeader = _GUICtrlHeader_Create($g_hChild) Local $iHeaderHeight = _WinAPI_GetWindowHeight($g_hHeader) For $i = 0 To 3 _GUICtrlHeader_AddItem($g_hHeader, "Column" & $i, 100) Next Local $idListview = GUICtrlCreateListView("col0|col1|col2|col3", 0, $iHeaderHeight, 320, 320 - $iHeaderHeight, _ BitOR($GUI_SS_DEFAULT_LISTVIEW, $LVS_NOCOLUMNHEADER), $LVS_EX_FULLROWSELECT) $g_hListview = GUICtrlGetHandle($idListview) _GUICtrlListView_BeginUpdate($idListview) For $i = 1 To 30 GUICtrlCreateListViewItem("item" & $i & "-0|item" & $i & "-1|item" & $i & "-2|item" & $i & "-3", $idListview) Next _GUICtrlListView_EndUpdate($idListview) ; resize listview columns to match header widths _resizeLVCols() GUISetState(@SW_SHOW, $g_hChild) ; get rid of dotted rectangle in listview, when an item got the focus GUICtrlSendMsg($idListview, $WM_CHANGEUISTATE, 65537, 0) GUIRegisterMsg($WM_NOTIFY, WM_NOTIFY) While 1 Switch GUIGetMsg() Case $GUI_EVENT_CLOSE ExitLoop EndSwitch If $g_bHeaderEndDrag Then $g_bHeaderEndDrag = False _reorderLVCols() EndIf WEnd _GUICtrlHeader_Destroy($g_hHeader) GUIDelete($g_hChild) GUIDelete($g_hGUI) EndFunc ;==>Example Func _changeExStyles() ; remove WS_EX_COMPOSITED from GUI __WinAPI_Set_Window_Style($g_hGUI, $WS_EX_COMPOSITED, False, True) ; add LVS_EX_DOUBLEBUFFER to ListView _GUICtrlListView_SetExtendedListViewStyle($g_hListview, BitOR($LVS_EX_FULLROWSELECT, $LVS_EX_DOUBLEBUFFER)) ; set adlib to reset those values AdlibRegister("_resetExStylesAdlib", 3000) EndFunc Func _resetExStylesAdlib() ; add WS_EX_COMPOSITED to GUI __WinAPI_Set_Window_Style($g_hGUI, $WS_EX_COMPOSITED, True, True) ; remove LVS_EX_DOUBLEBUFFER from ListView _GUICtrlListView_SetExtendedListViewStyle($g_hListview, $LVS_EX_FULLROWSELECT) ; unregister adlib AdlibUnRegister("_resetExStylesAdlib") EndFunc ;============================================== Func _resizeHeaderItems() ; temporarily change extended styles for GUI and ListView _changeExStyles() Local $aRect For $iCol = 0 To _GUICtrlListView_GetColumnCount($g_hListView) - 1 If $iCol Then $aRect = _GUICtrlListView_GetSubItemRect($g_hListView, 0, $iCol) Else $aRect = _GUICtrlListView_GetItemRect($g_hListView, 0, 2) ; 2 = bounding rectangle of the item text EndIf _GUICtrlHeader_SetItemWidth( $g_hHeader, $iCol, $aRect[2] - (($aRect[0] > 0) ? $aRect[0] : 0) ) Next EndFunc ;==>_resizeHeaderItems ;============================================== Func _resizeLVCols() ; temporarily change extended styles for GUI and ListView _changeExStyles() Local $aRect For $iCol = 0 To _GUICtrlListView_GetColumnCount($g_hListView) - 1 $aRect = _GUICtrlHeader_GetItemRect($g_hHeader, $iCol) _GUICtrlListView_SetColumnWidth($g_hListview, $iCol, $aRect[2] - (($aRect[0] > 0) ? $aRect[0] : 0) ) Next EndFunc ;==>_resizeLVCols ;============================================== Func _reorderLVCols() ; remove LVS_NOCOLUMNHEADER from listview __WinAPI_Set_Window_Style($g_hListView, $LVS_NOCOLUMNHEADER, False, False) ; reorder listview columns order to match header items order Local $aOrder = _GUICtrlHeader_GetOrderArray($g_hHeader) _GUICtrlListView_SetColumnOrderArray($g_hListview, $aOrder) ; add LVS_NOCOLUMNHEADER back to listview __WinAPI_Set_Window_Style($g_hListView, $LVS_NOCOLUMNHEADER, True, False) _resizeHeaderItems() ; avoid a bad behavior if header item on the left is dropped elsewhere when horizontal scrollbar had been moved. EndFunc ;==>_reorderLVCols ;============================================== Func __WinAPI_Set_Window_Style($hWnd, $i_Style, $b_Add, $b_exStyle = False) ; compacted code (from Kafu's original) If Not IsHWnd($hWnd) Then $hWnd = GUICtrlGetHandle($hWnd) Local $iIndex = $b_exStyle ? $GWL_EXSTYLE : $GWL_STYLE ; $iIndex as named by msdn & help file Local $i_Style_Old = _WinAPI_GetWindowLong($hWnd, $iIndex) If $b_Add Then If BitAND($i_Style_Old, $i_Style) Then Return ; style already applied _WinAPI_SetWindowLong($hWnd, $iIndex, BitOR($i_Style_Old, $i_Style)) Else ; remove If Not BitAND($i_Style_Old, $i_Style) Then Return ; style not set _WinAPI_SetWindowLong($hWnd, $iIndex, BitXOR($i_Style_Old, $i_Style)) EndIf Local $iRet = _WinAPI_SetWindowPos($hWnd, $HWND_TOP, 0, 0, 0, 0, BitOR($SWP_FRAMECHANGED, $SWP_NOACTIVATE, $SWP_NOMOVE, $SWP_NOSIZE, $SWP_NOZORDER)) ; +++ If Not $iRet Then MsgBox($MB_TOPMOST, "_WinAPI_SetWindowPos", "Error = " & _WinAPI_GetLastError() & " Message = " & _WinAPI_GetLastErrorMessage()) EndFunc ;==>__WinAPI_Set_Window_Style ;============================================== Func WM_NOTIFY($hWnd, $iMsg, $wParam, $lParam) #forceref $hWnd, $iMsg, $wParam Local $tNMHDR = DllStructCreate($tagNMHDR, $lParam) Local $hWndFrom = HWnd(DllStructGetData($tNMHDR, "hWndFrom")) Local $iCode = DllStructGetData($tNMHDR, "Code") Switch $hWndFrom Case $g_hHeader Switch $iCode Case $HDN_TRACK, $HDN_TRACKW Local $tNMHEADER = DllStructCreate($tagNMHEADER, $lParam) Local $iHeaderItem = $tNMHEADER.Item Local $tHDITEM = DllStructCreate($tagHDITEM, $tNMHEADER.pItem) Local $iHeaderItemWidth = $tHDITEM.XY _GUICtrlHeader_SetItemWidth($g_hHeader, $iHeaderItem, $iHeaderItemWidth) _resizeLVCols() Return False ; to continue tracking the divider Case $HDN_ENDDRAG $g_bHeaderEndDrag = True Return False ; to allow the control to automatically place and reorder the item EndSwitch Case $g_hListView Switch $iCode Case $LVN_ENDSCROLL Local Static $tagNMLVSCROLL = $tagNMHDR & ";int dx;int dy" Local $tNMLVSCROLL = DllStructCreate($tagNMLVSCROLL, $lParam) If $tNMLVSCROLL.dy = 0 Then ; ListView horizontal scrolling _resizeHeaderItems() EndIf EndSwitch EndSwitch Return $GUI_RUNDEFMSG EndFunc ;==>WM_NOTIFY2 points -
Need help synchronizing MDI (WS_EX_MDICHILD) window with Child Window (WS_CHILD)
ioa747 and one other reacted to pixelsearch for a topic
Hey everybody @WildByDesign I hadn't time to test your scripts yet (glad argumentum and ioa747 are helping you for the tests) because I really wanted to improve 2 functionalities of the "detached" header control, which are : 1) Dragging the divider between 2 header items to enlarge a column : I wanted the listview columns to be enlarged at same time (as in a native listview) which wasn't the case in our preceding scripts. To do this I used the $HDN_TRACK notification + $tagNMHEADER + $tagHDITEM to finally reach $tHDITEM.XY which indicated in real time what was the width of the header item being enlarged. This value varies constantly during the tracking. Without this, I wouldn't have made it at all ! 2) Dragging and dropping a header item elsewhere : Notification $HDN_ENDDRAG was used here, with a global variable $g_bHeaderEndDrag, no adlib/timer at all. Glad you found the 3-way steps "remove LVS_NOCOLUMNHEADER from listview" => reorder LV columns => "add LVS_NOCOLUMNHEADER back to listview". But I don't know how secure is this 3-way because, from time to time, the script hangs on my computer, exactly at the time when a header item is dropped elsewhere to reorder columns. Also, if someone knows why both LV scrollbars aren't redrawn correctly after a header item is dropped elsewhere, please indicate your solution. Actually, clicking at the blank place where they are supposed to appear make them immediately visible, that's strange, maybe some window to refresh after the reorder part ? 3) LV horizontal scrolling : no change from the precedent script : $LVN_ENDSCROLL notification is used to check the horizontal scrolling in real-time and have LV columns scroll horizontally while the horizontal scrollbar is moved, thanks to $tNMLVSCROLL.dy ! The scrolling may be a bit different from a "native" LV but it works and that's the good part, especially we didn't install a ListView subclass callback to handle messages related to both Scrollbars controls. I used _WinAPI_GetWindowHeight($g_hHeader) in the script and it seems to work : the LV is placed immediately under the header after you use its value in your LV vertical coords. Ok here is the code, time to rest a bit (a lot !) after these efforts. Have a great evening everybody #include <GUIConstantsEx.au3> #include <GuiListView.au3> #include <StructureConstants.au3> #include <WinAPISysWin.au3> #include <WindowsConstants.au3> ; DPI DllCall("User32.dll", "bool", "SetProcessDpiAwarenessContext" , "HWND", "DPI_AWARENESS_CONTEXT" -2) Opt("MustDeclareVars", 1) ;0=no, 1=require pre-declaration Global $g_hGUI, $g_hChild, $g_hHeader, $g_hListview, $g_bHeaderEndDrag Example() Func Example() $g_hGUI = GUICreate("Example", 400, 400, -1, -1, $WS_OVERLAPPEDWINDOW, $WS_EX_COMPOSITED) GUISetBkColor(0x202020) GUISetState(@SW_SHOW, $g_hGUI) $g_hChild = GUICreate("ChildWindow", 320, 320, 40, 40, $WS_CHILD, -1, $g_hGUI) GUISetBkColor(0x606060) $g_hHeader = _GUICtrlHeader_Create($g_hChild) Local $iHeaderHeight = _WinAPI_GetWindowHeight($g_hHeader) For $i = 0 To 3 _GUICtrlHeader_AddItem($g_hHeader, "Column" & $i, 100) Next Local $idListview = GUICtrlCreateListView("col0|col1|col2|col3", 0, $iHeaderHeight, 320, 320 - $iHeaderHeight, _ BitOR($GUI_SS_DEFAULT_LISTVIEW, $LVS_NOCOLUMNHEADER), BitOR($LVS_EX_DOUBLEBUFFER, $LVS_EX_FULLROWSELECT)) $g_hListview = GUICtrlGetHandle($idListview) _GUICtrlListView_BeginUpdate($idListview) For $i = 1 To 30 GUICtrlCreateListViewItem("item" & $i & "-0|item" & $i & "-1|item" & $i & "-2|item" & $i & "-3", $idListview) Next _GUICtrlListView_EndUpdate($idListview) ; resize listview columns to match header widths _resizeLVCols() GUISetState(@SW_SHOW, $g_hChild) ; get rid of dotted rectangle in listview, when an item got the focus GUICtrlSendMsg($idListview, $WM_CHANGEUISTATE, 65537, 0) GUIRegisterMsg($WM_NOTIFY, WM_NOTIFY) While 1 Switch GUIGetMsg() Case $GUI_EVENT_CLOSE ExitLoop EndSwitch If $g_bHeaderEndDrag Then $g_bHeaderEndDrag = False _reorderLVCols() EndIf WEnd _GUICtrlHeader_Destroy($g_hHeader) GUIDelete($g_hChild) GUIDelete($g_hGUI) EndFunc ;==>Example ;============================================== Func _resizeHeaderItems() Local $aRect For $iCol = 0 To _GUICtrlListView_GetColumnCount($g_hListView) - 1 If $iCol Then $aRect = _GUICtrlListView_GetSubItemRect($g_hListView, 0, $iCol) Else $aRect = _GUICtrlListView_GetItemRect($g_hListView, 0, 2) ; 2 = bounding rectangle of the item text EndIf _GUICtrlHeader_SetItemWidth( $g_hHeader, $iCol, $aRect[2] - (($aRect[0] > 0) ? $aRect[0] : 0) ) Next EndFunc ;==>_resizeHeaderItems ;============================================== Func _resizeLVCols() Local $aRect For $iCol = 0 To _GUICtrlListView_GetColumnCount($g_hListView) - 1 $aRect = _GUICtrlHeader_GetItemRect($g_hHeader, $iCol) _GUICtrlListView_SetColumnWidth($g_hListview, $iCol, $aRect[2] - (($aRect[0] > 0) ? $aRect[0] : 0) ) Next EndFunc ;==>_resizeLVCols ;============================================== Func _reorderLVCols() ; remove LVS_NOCOLUMNHEADER from listview __WinAPI_Set_Window_Style($g_hListView, $LVS_NOCOLUMNHEADER, False, False) ; reorder listview columns order to match header items order Local $aOrder = _GUICtrlHeader_GetOrderArray($g_hHeader) _GUICtrlListView_SetColumnOrderArray($g_hListview, $aOrder) ; add LVS_NOCOLUMNHEADER back to listview __WinAPI_Set_Window_Style($g_hListView, $LVS_NOCOLUMNHEADER, True, False) _resizeHeaderItems() ; avoid a bad behavior if header item on the left is dropped elsewhere when horizontal scrollbar had been moved. EndFunc ;==>_reorderLVCols ;============================================== Func __WinAPI_Set_Window_Style($hWnd, $i_Style, $b_Add, $b_exStyle = False) ; compacted code (from Kafu's original) If Not IsHWnd($hWnd) Then $hWnd = GUICtrlGetHandle($hWnd) Local $iIndex = $b_exStyle ? $GWL_EXSTYLE : $GWL_STYLE ; $iIndex as named by msdn & help file Local $i_Style_Old = _WinAPI_GetWindowLong($hWnd, $iIndex) If $b_Add Then If BitAND($i_Style_Old, $i_Style) Then Return ; style already applied _WinAPI_SetWindowLong($hWnd, $iIndex, BitOR($i_Style_Old, $i_Style)) Else ; remove If Not BitAND($i_Style_Old, $i_Style) Then Return ; style not set _WinAPI_SetWindowLong($hWnd, $iIndex, BitXOR($i_Style_Old, $i_Style)) EndIf Local $iRet = _WinAPI_SetWindowPos($hWnd, $HWND_TOP, 0, 0, 0, 0, BitOR($SWP_FRAMECHANGED, $SWP_NOACTIVATE, $SWP_NOMOVE, $SWP_NOSIZE, $SWP_NOZORDER)) ; +++ If Not $iRet Then MsgBox($MB_TOPMOST, "_WinAPI_SetWindowPos", "Error = " & _WinAPI_GetLastError() & " Message = " & _WinAPI_GetLastErrorMessage()) EndFunc ;==>__WinAPI_Set_Window_Style ;============================================== Func WM_NOTIFY($hWnd, $iMsg, $wParam, $lParam) #forceref $hWnd, $iMsg, $wParam Local $tNMHDR = DllStructCreate($tagNMHDR, $lParam) Local $hWndFrom = HWnd(DllStructGetData($tNMHDR, "hWndFrom")) Local $iCode = DllStructGetData($tNMHDR, "Code") Switch $hWndFrom Case $g_hHeader Switch $iCode Case $HDN_TRACK, $HDN_TRACKW Local $tNMHEADER = DllStructCreate($tagNMHEADER, $lParam) Local $iHeaderItem = $tNMHEADER.Item Local $tHDITEM = DllStructCreate($tagHDITEM, $tNMHEADER.pItem) Local $iHeaderItemWidth = $tHDITEM.XY _GUICtrlHeader_SetItemWidth($g_hHeader, $iHeaderItem, $iHeaderItemWidth) _resizeLVCols() Return False ; to continue tracking the divider Case $HDN_ENDDRAG $g_bHeaderEndDrag = True Return False ; to allow the control to automatically place and reorder the item EndSwitch Case $g_hListView Switch $iCode Case $LVN_ENDSCROLL Local Static $tagNMLVSCROLL = $tagNMHDR & ";int dx;int dy" Local $tNMLVSCROLL = DllStructCreate($tagNMLVSCROLL, $lParam) If $tNMLVSCROLL.dy = 0 Then ; ListView horizontal scrolling _resizeHeaderItems() EndIf EndSwitch EndSwitch Return $GUI_RUNDEFMSG EndFunc ;==>WM_NOTIFY2 points -
Need help synchronizing MDI (WS_EX_MDICHILD) window with Child Window (WS_CHILD)
WildByDesign reacted to ioa747 for a topic
for changing the size of the window I put this, but for GUIFrame_ I couldn't find where to put it While True Local $iMsg = GUIGetMsg() Switch $iMsg Case -3 ;$GUI_EVENT_CLOSE __TreeListExplorer_Shutdown() Exit Case -12 ;$GUI_EVENT_RESIZED Local $aClientSize = WinGetClientSize($hChildLV) ConsoleWrite("SetWindowPos=" & _WinAPI_SetWindowPos($g_hHeader, 0, 0, 0, $aClientSize[0], 25, BitOR($SWP_NOZORDER, $SWP_NOACTIVATE)) & @CRLF) EndSwitch WEnd1 point -
Guiscape -- A new GUI builder project!
ioa747 reacted to argumentum for a topic
...to be or not to be... ...to theme or not to theme.., that is a good question. I believe that in your project, theme-ing each control will not be possible. Don't worry about themes but do use proper windows coloring if you need to color something: #include <GUIConstantsEx.au3> #include <StaticConstants.au3> #include <WindowsConstants.au3> #include <WinAPISysWin.au3> #Region ### START Koda GUI section ### Form= $Form1 = GUICreate("Form1", 400, 100) GUICtrlCreateLabel("Label just as is, will be seen", 10, 10, 380, 17, -1, $WS_EX_STATICEDGE) GUICtrlCreateLabel("Label with COLOR_HIGHLIGHT will be seen as it should", 10, 40, 380, 17, -1, $WS_EX_STATICEDGE) GUICtrlSetColor(-1, _WinAPI_SwitchColor(_WinAPI_GetSysColor($COLOR_HIGHLIGHT))) GUISetState(@SW_SHOW) #EndRegion ### END Koda GUI section ### While 1 Switch GUIGetMsg() Case $GUI_EVENT_CLOSE GUIDelete() Exit EndSwitch WEnd Therefore, if we respect default coloring, everything should be visible by default. Then give users the ability to use custom colors. But by default, default theme colors should be sufficient.1 point