Nine Posted Wednesday at 05:27 PM Posted Wednesday at 05:27 PM (edited) @MattyD Sorry if we've been hijacking your thread, but in a sense it is all your fault. Making such an innovative example will certainly attract some members of the community, right ? Anyway, here my take to solve the minimize issue : expandcollapse popup#include <guiConstants.au3> #include <winapi.au3> Opt("MustDeclareVars", True) Global Const $tagMOUSEHOOKSTRUCT = "dword X;dword Y;hwnd hwnd;uint wHitTestCode;ulong_ptr dwExtraInfo;" Global $hGUI, $idBtn, $idBtn2, $hHook Example() Func Example() $hGUI = GUICreate("WM_NCHITTEST", 300, 200, -1, -1, $WS_OVERLAPPEDWINDOW) $idBtn = GUICtrlCreateButton("Button 1", 4, 4, 80, 80, $WS_CLIPSIBLINGS) $idBtn2 = GUICtrlCreateButton("Button 2", 90, 4, 80, 80, $WS_CLIPSIBLINGS) Local $idLockButtons = GUICtrlCreateCheckbox("Lock Buttons", 200, 20, 80, 20) Local $hDll = DllCallbackRegister(ButtonMoveProc, 'lresult', 'hwnd;uint;wparam;lparam;uint_ptr;dword_ptr') _WinAPI_SetWindowSubclass(GUICtrlGetHandle($idBtn), DllCallbackGetPtr($hDll), $idBtn) _WinAPI_SetWindowSubclass(GUICtrlGetHandle($idBtn2), DllCallbackGetPtr($hDll), $idBtn2) Local $hStub = DllCallbackRegister(WM_MOUSE, "LRESULT", "int;wparam;lparam") $hHook = _WinAPI_SetWindowsHookEx($WH_MOUSE, DllCallbackGetPtr($hStub), 0, _WinAPI_GetCurrentThreadId()) GUISetState() Local $iMsg While True $iMsg = GUIGetMsg() Switch $iMsg Case $GUI_EVENT_CLOSE ExitLoop Case $idLockButtons If GUICtrlRead($iMsg) = $GUI_CHECKED Then _WinAPI_RemoveWindowSubclass(GUICtrlGetHandle($idBtn), DllCallbackGetPtr($hDll), $idBtn) _WinAPI_RemoveWindowSubclass(GUICtrlGetHandle($idBtn2), DllCallbackGetPtr($hDll), $idBtn2) _WinAPI_UnhookWindowsHookEx($hHook) Else _WinAPI_SetWindowSubclass(GUICtrlGetHandle($idBtn), DllCallbackGetPtr($hDll), $idBtn, 0) _WinAPI_SetWindowSubclass(GUICtrlGetHandle($idBtn2), DllCallbackGetPtr($hDll), $idBtn2, 0) $hHook = _WinAPI_SetWindowsHookEx($WH_MOUSE, DllCallbackGetPtr($hStub), 0, _WinAPI_GetCurrentThreadId()) EndIf Case $idBtn, $idBtn2 ConsoleWrite("Click " & GUICtrlRead($iMsg) & @CRLF) EndSwitch WEnd GUIDelete() _WinAPI_RemoveWindowSubclass(GUICtrlGetHandle($idBtn), DllCallbackGetPtr($hDll), $idBtn) _WinAPI_RemoveWindowSubclass(GUICtrlGetHandle($idBtn2), DllCallbackGetPtr($hDll), $idBtn2) DllCallbackFree($hDll) _WinAPI_UnhookWindowsHookEx($hHook) DllCallbackFree($hStub) EndFunc ;==>Example Func ButtonMoveProc($hWnd, $iMsg, $wParam, $lParam, $iID, $iData) Local $aPos, $iRet, $aPoint[2], $iSrc, $iEvent, $hCursor Switch $iMsg Case $WM_NCHITTEST $aPos = WinGetPos($hWnd) $aPoint[0] = BitAND($lParam, 0xFFFF) $aPoint[1] = BitShift($lParam, 16) $iRet = $HTCAPTION If $aPoint[0] - $aPos[0] < 10 Then $iRet = $HTLEFT If $aPoint[0] - $aPos[0] > ($aPos[2] - 10) Then $iRet = $HTRIGHT If $aPoint[1] - $aPos[1] < 10 Then Switch $iRet Case $HTLEFT $iRet = $HTTOPLEFT Case $HTRIGHT $iRet = $HTTOPRIGHT Case Else $iRet = $HTTOP EndSwitch ElseIf $aPoint[1] - $aPos[1] > ($aPos[3] - 10) Then Switch $iRet Case $HTLEFT $iRet = $HTBOTTOMLEFT Case $HTRIGHT $iRet = $HTBOTTOMRIGHT Case Else $iRet = $HTBOTTOM EndSwitch EndIf Return $iRet Case $WM_SETCURSOR $iSrc = BitAND($lParam, 0xFFFF) $iEvent = BitShift($lParam, 16) If $iSrc = $HTCAPTION And $iEvent = $WM_LBUTTONDOWN Then _WinAPI_RedrawWindow($hWnd, 0, 0, $RDW_INVALIDATE + $RDW_FRAME) $hCursor = _WinAPI_LoadCursor(0, $OCR_SIZEALL) _WinAPI_SetCursor($hCursor) Return True EndIf EndSwitch Return _WinAPI_DefSubclassProc($hWnd, $iMsg, $wParam, $lParam) EndFunc ;==>ButtonMoveProc Func WM_MOUSE($iMsg, $wParam, $lParam) If $iMsg < 0 Then Return _WinAPI_CallNextHookEx($hHook, $iMsg, $wParam, $lParam) If $wParam = $WM_LBUTTONUP Then Local $tMouse = DllStructCreate($tagMOUSEHOOKSTRUCT, $lParam) If $tMouse.hwnd = GUICtrlGetHandle($idBtn) Or $tMouse.hwnd = GUICtrlGetHandle($idBtn2) Then Local $idCtrl = _WinAPI_GetDlgCtrlID($tMouse.hwnd) Local $aPos = ControlGetPos($hGUI, "", $idCtrl) GUICtrlSetPos($idCtrl, $aPos[0], $aPos[1]) EndIf EndIf Return _WinAPI_CallNextHookEx($hHook, $iMsg, $wParam, $lParam) EndFunc ;==>WM_MOUSE ps. I converted it to subclassing Edited Wednesday at 05:32 PM by Nine MattyD 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) Screen Scraping Multi-Threading Made Easy
MattyD Posted Thursday at 02:26 AM Author Posted Thursday at 02:26 AM Nah all good Its all very interesting. I might experiment some more to see if I can discover what ControlSetPos is actually doing behind the scenes . I mean calling it works a treat - but surely we shouldn't need to move everything twice.
argumentum Posted Thursday at 02:48 AM Posted Thursday at 02:48 AM (edited) ...and, making it a single function/UDF ?, so that you shift-click ( to come up with a strategy ) and make that control movable. Because writing all this for each control, what a pain. Edited Thursday at 02:49 AM by argumentum Follow the link to my code contribution ( and other things too ). FAQ - Please Read Before Posting.
ptrex Posted Thursday at 09:00 AM Posted Thursday at 09:00 AM @Nine When the windows is resized the mouse control to release the button to the new position doesn't work anymore ? Only when the window is not resized all is OK Contributions :Firewall Log Analyzer for XP - Creating COM objects without a need of DLL's - UPnP support in AU3Crystal Reports Viewer - PDFCreator in AutoIT - Duplicate File FinderSQLite3 Database functionality - USB Monitoring - Reading Excel using SQLRun Au3 as a Windows Service - File Monitor - Embedded Flash PlayerDynamic Functions - Control Panel Applets - Digital Signing Code - Excel Grid In AutoIT - Constants for Special Folders in WindowsRead data from Any Windows Edit Control - SOAP and Web Services in AutoIT - Barcode Printing Using PS - AU3 on LightTD WebserverMS LogParser SQL Engine in AutoIT - ImageMagick Image Processing - Converter @ Dec - Hex - Bin -Email Address Encoder - MSI Editor - SNMP - MIB ProtocolFinancial Functions UDF - Set ACL Permissions - Syntax HighLighter for AU3ADOR.RecordSet approach - Real OCR - HTTP Disk - PDF Reader Personal Worldclock - MS Indexing Engine - Printing ControlsGuiListView - Navigation (break the 4000 Limit barrier) - Registration Free COM DLL Distribution - Update - WinRM SMART Analysis - COM Object Browser - Excel PivotTable Object - VLC Media Player - Windows LogOnOff Gui -Extract Data from Outlook to Word & Excel - Analyze Event ID 4226 - DotNet Compiler Wrapper - Powershell_COM - New
Nine Posted Thursday at 11:09 AM Posted Thursday at 11:09 AM 8 hours ago, MattyD said: what ControlSetPos is actually doing behind the scenes Do you mean ControlMove or GUICtrlSetPos ? In any case, I tend to believe that there is an underlying bug behind all this minimize issue. 8 hours ago, MattyD said: but surely we shouldn't need to move everything twice Totally agree. “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) Screen Scraping Multi-Threading Made Easy
Nine Posted Thursday at 11:19 AM Posted Thursday at 11:19 AM 2 hours ago, ptrex said: When the windows is resized the mouse control to release the button to the new position doesn't work anymore ? Only when the window is not resized all is OK You mean with @pixelsearch base code ? It is working alright, just the flickers is quite annoying after resize. But with the snippet I provided, it makes it very tolerable. With @MattyD base code there is no is issue (no flickers) before or after resize. However, both codes have the same problem on minimize/restore, the controls get restored to their original places. But solutions was found in both cases. “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) Screen Scraping Multi-Threading Made Easy
pixelsearch Posted Thursday at 11:54 AM Posted Thursday at 11:54 AM (edited) 39 minutes ago, Nine said: However, both codes have the same problem on minimize/restore, the controls get restored to their original places. But solutions was found in both cases. So in my case (and with your help) there is no Minimize/Restore bug when using GUICtrlSetPos() instead of ControlMove Now if we refer to this post from @Melba23 this is not a bug, here is an excerpt of his post : The 2 types of commands do not have the same "prefix" as they are used differently: Any command that begins GUICtrl* is to be used on an AutoIt GUI created by the script itself - hence the use of a ControlID only to identify the control to be actioned. Commands that begin Control* can be used on any GUI - hence the requirement to define the GUI by title and text as well as providing a ControlID. So we should have in mind to always use the GUICtrl* commands when the GUI is created by our own script (my case) and everything should be fine, fingers crossed Edited Thursday at 11:57 AM by pixelsearch typo
Nine Posted Thursday at 12:12 PM Posted Thursday at 12:12 PM (edited) I understand what you are saying. But in the original code from @MattyD there is no Control* function used at all. And the minimize/restore problem is still there. I had to set position again with GUICtrlSetPos to make it work (I do not think it is normal). Edit : Here an interesting test I just made. Local $hWnd = WinGetHandle("Express") WinActivate($hWnd) Local $hCtrl = ControlGetHandle($hWnd, "", "Button6") Local $aPos = ControlGetPos($hWnd, "", $hCtrl) ControlMove($hWnd, "", $hCtrl, $aPos[0] + 50, $aPos[1]) Using an outside window (Express Burn), when I move a button and I minimize/restore the window..... well, control returns to its original place. Just like what AutoIt GUI does. Seems it is a Windows behavior not a bug like I said. ReEdit : tried with _WinAPI_SetWindowPos. Same behavior, same result. Edited Thursday at 01:27 PM 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) Screen Scraping Multi-Threading Made Easy
ioa747 Posted Thursday at 02:12 PM Posted Thursday at 02:12 PM (edited) I tried the traditional method of applying resize ... but it overflowed a little expandcollapse popup#AutoIt3Wrapper_Au3Check_Parameters=-d -w 1 -w 2 -w 3 -w 4 -w 5 -w 6 -w 7 #include <GUIConstantsEx.au3> #include <WindowsConstants.au3> #include <EditConstants.au3> #include <WinAPI.au3> Example() Func Example() Local $hGui = GUICreate("", 300, 200, -1, -1, $WS_OVERLAPPEDWINDOW) Local $idBtn1 = GUICtrlCreateButton("Button 1", 10, 40, 80, 80, $WS_CLIPSIBLINGS) Local $idBtn2 = GUICtrlCreateButton("Button 2", 100, 40, 80, 80, $WS_CLIPSIBLINGS) Local $idInput = GUICtrlCreateInput("Test 123 Text", 10, 10, 170, 20, BitOR($ES_CENTER, $WS_CLIPSIBLINGS)) Local $idLockButtons = GUICtrlCreateCheckbox("Lock Buttons", 200, 20, 80, 20, $WS_CLIPSIBLINGS) Local $bLock = False GUISetState() Local $iMsg, $aInfo While 1 $iMsg = GUIGetMsg() Switch $iMsg Case $GUI_EVENT_CLOSE Exit Case $idLockButtons $bLock = (GUICtrlRead($iMsg) = $GUI_CHECKED) ConsoleWrite("- Lock Buttons is " & _ (GUICtrlRead($iMsg) = 1 ? "Checked" : "Un-Checked") & @CRLF) Case $idBtn1 If Not $bLock Then ContinueLoop ConsoleWrite("- Button 1 is pressed" & @CRLF) Case $idBtn2 If Not $bLock Then ContinueLoop ConsoleWrite("- Button 2 is pressed" & @CRLF) Case $GUI_EVENT_PRIMARYDOWN If $bLock Then ContinueLoop $aInfo = GUIGetCursorInfo($hGui) If (Not @error) And ($aInfo[4] = $idBtn1 Or $aInfo[4] = $idBtn2 Or $aInfo[4] = $idInput) Then _Resize($hGui) EndIf EndSwitch WEnd EndFunc ;==>Example Func _Resize($hWnd, $iGrid = 5) If Not WinActive($hWnd) Then Return Local $aInfo = GUIGetCursorInfo($hWnd) Local $idControl = $aInfo[4] If $idControl = 0 Then Return If $iGrid < 1 Then $iGrid = 1 Local $iEdge = 5 Local $CtrlPos = ControlGetPos($hWnd, "", $idControl) Local $CtrlX = $CtrlPos[0] Local $CtrlY = $CtrlPos[1] Local $CtrlW = $CtrlPos[2] Local $CtrlH = $CtrlPos[3] Local $MouseX = $aInfo[0] Local $MouseY = $aInfo[1] Local $LeftEdge = Abs($MouseX - $CtrlX) < $iEdge Local $RightEdge = Abs($MouseX - ($CtrlX + $CtrlW)) < $iEdge Local $TopEdge = Abs($MouseY - $CtrlY) < $iEdge Local $BottomEdge = Abs($MouseY - ($CtrlY + $CtrlH)) < $iEdge _WinAPI_SetWindowPos(GUICtrlGetHandle($idControl), $HWND_TOP, 0, 0, 0, 0, $SWP_NOMOVE + $SWP_NOSIZE) Local $iCursorId = MouseGetCursor() Local $aInfoNew = $aInfo If $LeftEdge Or $RightEdge Or $TopEdge Or $BottomEdge Then ; ## Resizing ## Local $resizeMode = 0 If $LeftEdge Then $resizeMode += 1 If $RightEdge Then $resizeMode += 2 If $TopEdge Then $resizeMode += 4 If $BottomEdge Then $resizeMode += 8 ; Set cursor for resizing Switch $resizeMode Case 1, 2 ; Left, Right edge GUISetCursor(13, 1, $hWnd) Case 4, 8 ; Top, Bottom edge GUISetCursor(11, 1, $hWnd) Case 5, 10 ; Top-left, Bottom-right corner GUISetCursor(12, 1, $hWnd) Case 6, 9 ; Top-right, Bottom-left corner GUISetCursor(10, 1, $hWnd) EndSwitch Do $aInfo = GUIGetCursorInfo($hWnd) If $aInfoNew[0] <> $aInfo[0] Or $aInfoNew[1] <> $aInfo[1] Then $MouseX = $aInfo[0] $MouseY = $aInfo[1] Switch $resizeMode Case 1 ; Left edge $CtrlW += $CtrlX - $MouseX $CtrlX = $MouseX Case 2 ; Right edge $CtrlW = $MouseX - $CtrlX Case 4 ; Top edge $CtrlH += $CtrlY - $MouseY $CtrlY = $MouseY Case 8 ; Bottom edge $CtrlH = $MouseY - $CtrlY Case 5 ; Top-left corner $CtrlW += $CtrlX - $MouseX $CtrlX = $MouseX $CtrlH += $CtrlY - $MouseY $CtrlY = $MouseY Case 6 ; Top-right corner $CtrlW = $MouseX - $CtrlX $CtrlH += $CtrlY - $MouseY $CtrlY = $MouseY Case 9 ; Bottom-left corner $CtrlW += $CtrlX - $MouseX $CtrlX = $MouseX $CtrlH = $MouseY - $CtrlY Case 10 ; Bottom-right corner $CtrlW = $MouseX - $CtrlX $CtrlH = $MouseY - $CtrlY EndSwitch ; Snap to grid $CtrlX = Round($CtrlX / $iGrid) * $iGrid $CtrlY = Round($CtrlY / $iGrid) * $iGrid $CtrlW = Round($CtrlW / $iGrid) * $iGrid $CtrlH = Round($CtrlH / $iGrid) * $iGrid ; minimum size If $CtrlW < 15 Then $CtrlW = 15 If $CtrlH < 15 Then $CtrlH = 15 GUICtrlSetPos($idControl, $CtrlX, $CtrlY, $CtrlW, $CtrlH) EndIf Sleep(10) Until Not $aInfo[2] ElseIf $MouseX > $CtrlX + $iEdge And $MouseX < ($CtrlX + $CtrlW - $iEdge) And _ $MouseY > $CtrlY + $iEdge And $MouseY < ($CtrlY + $CtrlH - $iEdge) Then ; ## Moving ## GUISetCursor(0, 1, $hWnd) Local $OffsetX = $MouseX - $CtrlX Local $OffsetY = $MouseY - $CtrlY Do $aInfo = GUIGetCursorInfo($hWnd) If $aInfoNew[0] <> $aInfo[0] Or $aInfoNew[1] <> $aInfo[1] Then Local $NewX = Round(($aInfo[0] - $OffsetX) / $iGrid) * $iGrid Local $NewY = Round(($aInfo[1] - $OffsetY) / $iGrid) * $iGrid GUICtrlSetPos($idControl, $NewX, $NewY, $CtrlW, $CtrlH) EndIf Sleep(10) Until Not $aInfo[2] EndIf GUISetCursor($iCursorId, 0, $hWnd) EndFunc ;==>_Resize ... and since I did it, I want to share it Edit: I entered the grid parameter. Edited Thursday at 04:20 PM by ioa747 I entered the grid parameter. MattyD 1 I know that I know nothing
MattyD Posted Friday at 12:38 AM Author Posted Friday at 12:38 AM (edited) Ok so here's a test to see whats going on with GUICtrlSetPos. I tried inspecting whats being sent to the button - Bear with me... Spoiler expandcollapse popup#include <guiConstants.au3> #include <winapi.au3> #include <GUIButton.au3> Opt("MustDeclareVars", 1) Global Const $SC_MINIMIZE = 0xF020 Global Const $SC_RESTORE = 0xF120 Global $tagMSG = "hwnd hwnd;uint Message;wparam wParam;lparam lParam;dword time;" & $tagPoint & ";dword private" Global $tagNCCALCSIZE_PARAMS = "int rect1[4];int rect2[4];int rect3[4];ptr WinPos" Global $hGui = GUICreate("", 300, 200) ;~ Global $hBtn = _GUICtrlButton_Create($hGUI, "Button 1", 4, 4, 80, 80) ;~ Global $idBtn = _WinAPI_GetDlgCtrlID($hBtn) Global $idBtn = GUICtrlCreateButton("Button 1", 4, 4, 80, 80) Global $hBtn = GUICtrlGetHandle($idBtn) Global $hBtnMoveProc = DllCallbackRegister("ButtonInspect", "long", "hwnd;uint;wparam;lparam") Global $pBtnMoveProc = DllCallbackGetPtr($hBtnMoveProc) Global $pOrigBtnProc = _WinAPI_SetWindowLong($hBtn, $GWL_WNDPROC, $pBtnMoveProc) GUISetState() GUIRegisterMsg($WM_SYSCOMMAND, "WM_SYSCOMMAND") While 1 Local $iMsg = GUIGetMsg() Switch $iMsg Case $GUI_EVENT_CLOSE Exit Case $GUI_EVENT_MINIMIZE ConsoleWrite("---End Min---" & @CRLF) Case $GUI_EVENT_RESTORE ConsoleWrite("---End Restore---" & @CRLF) EndSwitch WEnd Func ButtonInspect($hWnd, $uMsg, $wParam, $lParam) Local $iRet, $aRes, $tNCCALCSIZE Switch $uMsg Case $WM_NCHITTEST $iRet = _WinAPI_DefWindowProcW($hWnd, $uMsg, $wParam, $lParam) ConsoleWrite("WM_NCHITTEST" & @CRLF) ConsoleWrite(StringFormat("\tMouse[%d, %d]", BitShift($lParam, 16), BitAND($lParam, 0xFFFF)) & @CRLF) ConsoleWrite(StringFormat("\tRET (Area)[%d]", $iRet) & @CRLF) ConsoleWrite("----Set Pos----" & @CRLF) GUICtrlSetPos($idBtn, 80, 80, 100, 100) ;~ _WinAPI_SetWindowPos($hWnd, $HWND_TOP, 80, 80, 100, 100, $SWP_FRAMECHANGED) ConsoleWrite("---End Set Pos---" & @CRLF) Return $iRet Case $WM_GETDLGCODE $iRet = _WinAPI_DefWindowProcW($hWnd, $uMsg, $wParam, $lParam) ConsoleWrite("WM_GETDLGCODE" & @CRLF) ConsoleWrite(StringFormat("\tvKey[0x%02x]", $wParam) & @CRLF) If $lParam Then Local $tMsg = DllStructCreate($tagMSG, $lParam) ConsoleWrite(StringFormat("\tMsg[0x%08x]", $tMsg.Message) & @CRLF) ConsoleWrite(StringFormat("\twParam[0x%08x]", $tMsg.wParam) & @CRLF) ConsoleWrite(StringFormat("\tlParam[0x%08x]", $tMsg.lParam) & @CRLF) ConsoleWrite(StringFormat("\tTime[0x%08x]", $tMsg.time) & @CRLF) ConsoleWrite(StringFormat("\tPoint[%d, %d]", $tMsg.X, $tMsg.Y) & @CRLF) EndIf ConsoleWrite(StringFormat("\tRET[0x%08x]", $iRet) & @CRLF) Return $iRet Case $WM_IME_SETCONTEXT $iRet = _WinAPI_DefWindowProcW($hWnd, $uMsg, $wParam, $lParam) ConsoleWrite("WM_IME_SETCONTEXT" & @CRLF) ConsoleWrite(StringFormat("\tWinActive[%d]", $wParam) & @CRLF) ConsoleWrite(StringFormat("\tOptions[0x%08x]", $lParam) & @CRLF) ConsoleWrite(StringFormat("\tRET[0x%08x]", $iRet) & @CRLF) Return $iRet Case $WM_IME_NOTIFY $iRet = _WinAPI_DefWindowProcW($hWnd, $uMsg, $wParam, $lParam) ConsoleWrite("WM_IME_NOTIFY" & @CRLF) ConsoleWrite(StringFormat("\tCommand[0x%08x]", $wParam) & @CRLF) ConsoleWrite(StringFormat("\tData[0x%08x]", $lParam) & @CRLF) ConsoleWrite(StringFormat("\tRET[0x%08x]", $iRet) & @CRLF) Return $iRet Case $WM_KILLFOCUS $iRet = _WinAPI_DefWindowProcW($hWnd, $uMsg, $wParam, $lParam) ConsoleWrite("WM_KILLFOCUS" & @CRLF) ConsoleWrite(StringFormat("\tKBFocusHWND[0x%08x]", $wParam) & @CRLF) Return $iRet Case $WM_CHILDACTIVATE $iRet = _WinAPI_DefWindowProcW($hWnd, $uMsg, $wParam, $lParam) ConsoleWrite("WM_CHILDACTIVATE" & @CRLF) Return $iRet Case $WM_SETCURSOR $iRet = _WinAPI_DefWindowProcW($hWnd, $uMsg, $wParam, $lParam) ConsoleWrite("WM_SETCURSOR" & @CRLF) ConsoleWrite(StringFormat("\tCursorHwnd[0x%08x]", $wParam) & @CRLF) ConsoleWrite(StringFormat("\tCauseMsg[0x%04x]", BitShift($lParam, 16)) & @CRLF) ConsoleWrite(StringFormat("\tHitTest[%d]", BitAND($lParam, 0xFFFF)) & @CRLF) ConsoleWrite(StringFormat("\tRET[0x%08x]", $iRet) & @CRLF) Return $iRet Case $WM_WINDOWPOSCHANGING $iRet = _WinAPI_DefWindowProcW($hWnd, $uMsg, $wParam, $lParam) ConsoleWrite("WM_WINDOWPOSCHANGING" & @CRLF) _DispWinPos($lParam) Return $iRet Case $WM_NCCALCSIZE $iRet = _WinAPI_DefWindowProcW($hWnd, $uMsg, $wParam, $lParam) Local $tNCCALCSIZE ConsoleWrite("WM_NCCALCSIZE" & @CRLF) ConsoleWrite(StringFormat("\twParam[%d]", $wParam) & @CRLF) If $wParam Then $tNCCALCSIZE = DllStructCreate($tagNCCALCSIZE_PARAMS, $lParam) ConsoleWrite(StringFormat("\tNewPos[%d %d %d %d]", $tNCCALCSIZE.rect1(1), $tNCCALCSIZE.rect1(2), $tNCCALCSIZE.rect1(3), $tNCCALCSIZE.rect1(4)) & @CRLF) ConsoleWrite(StringFormat("\tOldPos[%d %d %d %d]", $tNCCALCSIZE.rect2(1), $tNCCALCSIZE.rect2(2), $tNCCALCSIZE.rect2(3), $tNCCALCSIZE.rect2(4)) & @CRLF) ConsoleWrite(StringFormat("\tOldClientPos[%d %d %d %d]", $tNCCALCSIZE.rect3(1), $tNCCALCSIZE.rect3(2), $tNCCALCSIZE.rect3(3), $tNCCALCSIZE.rect3(4)) & @CRLF) _DispWinPos($tNCCALCSIZE.WinPos) Else $tNCCALCSIZE = DllStructCreate($tagRect, $lParam) ;proc may change rect data. ConsoleWrite(StringFormat("\tProposed[%d %d %d %d]", $tNCCALCSIZE.Left, $tNCCALCSIZE.Top, $tNCCALCSIZE.Right, $tNCCALCSIZE.Bottom) & @CRLF) EndIf ConsoleWrite(StringFormat("\tRET[0x%08x]", $iRet) & @CRLF) Return $iRet Case $WM_MOVE $iRet = _WinAPI_DefWindowProcW($hWnd, $uMsg, $wParam, $lParam) ConsoleWrite("WM_MOVE" & @CRLF) ConsoleWrite(StringFormat("\tPos[%d, %d]", BitShift($lParam, 16), BitAND($lParam, 0xFFFF)) & @CRLF) Return $iRet Case $WM_SIZE $iRet = _WinAPI_DefWindowProcW($hWnd, $uMsg, $wParam, $lParam) ConsoleWrite("WM_SIZE" & @CRLF) ConsoleWrite(StringFormat("\tType[%d]", $wParam) & @CRLF) ConsoleWrite(StringFormat("\tDims[%d, %d]", BitShift($lParam, 16), BitAND($lParam, 0xFFFF)) & @CRLF) Return $iRet Case $WM_WINDOWPOSCHANGED $iRet = _WinAPI_DefWindowProcW($hWnd, $uMsg, $wParam, $lParam) ConsoleWrite("WM_WINDOWPOSCHANGED" & @CRLF) _DispWinPos($lParam) Return $iRet Case $WM_GETOBJECT $iRet = _WinAPI_DefWindowProcW($hWnd, $uMsg, $wParam, $lParam) ConsoleWrite("WM_GETOBJECT" & @CRLF) ConsoleWrite(StringFormat("\tFlags[0x%08x]", $wParam) & @CRLF) ConsoleWrite(StringFormat("\tObjId[0x%08x]", $lParam) & @CRLF) ConsoleWrite(StringFormat("\tRET[0x%08x]", $iRet) & @CRLF) Return $iRet Case $WM_MOUSEMOVE $iRet = _WinAPI_DefWindowProcW($hWnd, $uMsg, $wParam, $lParam) ConsoleWrite("WM_MOUSEMOVE" & @CRLF) ConsoleWrite(StringFormat("\tvKey[0x%08x]", $wParam) & @CRLF) ConsoleWrite(StringFormat("\tPos[%d, %d]", BitShift($lParam, 16), BitAND($lParam, 0xFFFF)) & @CRLF) Return $iRet Case $WM_GETTEXTLENGTH $iRet = _WinAPI_DefWindowProcW($hWnd, $uMsg, $wParam, $lParam) ConsoleWrite("WM_GETTEXTLENGTH" & @CRLF) ConsoleWrite(StringFormat("\tRET[%d]", $iRet) & @CRLF) Return $iRet Case $WM_GETTEXT $iRet = _WinAPI_DefWindowProcW($hWnd, $uMsg, $wParam, $lParam) ConsoleWrite("WM_GETTEXT" & @CRLF) ConsoleWrite(StringFormat("\tLenInclNull[%d]", $wParam) & @CRLF) ConsoleWrite(StringFormat("\tpBuff[0x%08x]", $lParam) & @CRLF) ConsoleWrite(StringFormat("\tRET[%d]", $iRet) & @CRLF) Return $iRet ;;;; Below affects the painting process - need Autoit proc to handle these. Case $WM_SETFOCUS $aRes = DllCallAddress("long", $pOrigBtnProc, "hwnd", $hWnd, "uint", $uMsg, "wparam", $wParam, "lparam", $lParam) $iRet = $aRes[0] ConsoleWrite("WM_SETFOCUS" & @CRLF) ConsoleWrite(StringFormat("\tPrevWin[0x%08x]", $wParam) & @CRLF) Return $iRet Case $WM_ERASEBKGND $aRes = DllCallAddress("long", $pOrigBtnProc, "hwnd", $hWnd, "uint", $uMsg, "wparam", $wParam, "lparam", $lParam) $iRet = $aRes[0] ConsoleWrite("WM_ERASEBKGND" & @CRLF) ConsoleWrite(StringFormat("\thDC[0x%08x]", $wParam) & @CRLF) ConsoleWrite(StringFormat("\tRET[%d]", $iRet) & @CRLF) Return $iRet Case $WM_NCPAINT $aRes = DllCallAddress("long", $pOrigBtnProc, "hwnd", $hWnd, "uint", $uMsg, "wparam", $wParam, "lparam", $lParam) $iRet = $aRes[0] ConsoleWrite("WM_NCPAINT" & @CRLF) ConsoleWrite(StringFormat("\tUpdateRegion[0x%08x]", $wParam) & @CRLF) Return $iRet Case $WM_PAINT $aRes = DllCallAddress("long", $pOrigBtnProc, "hwnd", $hWnd, "uint", $uMsg, "wparam", $wParam, "lparam", $lParam) $iRet = $aRes[0] ConsoleWrite("WM_PAINT" & @CRLF) Return $iRet Case $BM_SETSTATE $aRes = DllCallAddress("long", $pOrigBtnProc, "hwnd", $hWnd, "uint", $uMsg, "wparam", $wParam, "lparam", $lParam) $iRet = $aRes[0] ConsoleWrite("BM_SETSTATE" & @CRLF) ConsoleWrite(StringFormat("\tHilighted[%d]", $wParam) & @CRLF) Return $iRet Case Else $iRet = _WinAPI_DefWindowProcW($hWnd, $uMsg, $wParam, $lParam) ;~ $aRes = DllCallAddress("long", $pOrigBtnProc, "hwnd", $hWnd, "uint", $uMsg, "wparam", $wParam, "lparam", $lParam) ;~ $iRet = $aRes[0] ConsoleWrite(StringFormat("msg: 0x%04x %-5s ret(%d) wparam( 0x%08x ) lparam( 0x%08x )", $uMsg, "(" & $uMsg & ")", $iRet, $wParam, $lParam) & @CRLF) Return $iRet EndSwitch EndFunc ;==>ButtonInspect Func _DispWinPos($pPos) Local $tPos = DllStructCreate($tagWINDOWPOS, $pPos) ConsoleWrite(StringFormat("\tInsertAfter [0x%0x8]", $tPos.InsertAfter) & @CRLF) ConsoleWrite(StringFormat("\tpos [%d %d %d %d]", $tPos.X, $tPos.Y, $tPos.CX, $tPos.CY) & @CRLF) ConsoleWrite(StringFormat("\tFlags [0x%0x8]", $tPos.InsertAfter) & @CRLF) EndFunc ;==>_DispWinPos Func WM_SYSCOMMAND($hWnd, $uMsg, $wParam, $lParam) If $wParam = $SC_MINIMIZE Then ConsoleWrite("---Start MIN---" & @CRLF) ElseIf $wParam = $SC_RESTORE Then ConsoleWrite("---Start Restore---" & @CRLF) EndIf EndFunc ;==>WM_SYSCOMMAND So run this > mouse over the control (it will jump) > then minimise > restore > esc (Exit). Next on line 58, uncomment _WinAPI_SetWindowPos & comment out GUICtrlSetPos I found the end result is near identical - except _WinAPI_SetWindowPos sends a WM_CHILDACTIVATE when moving the control (I doubt this matters) and WM_WINDOWPOSCHANGING has different coordinates after restoring. OK next uncomment 16 & 17, Comment out 19 & 20. Repeat the experiment. _WinAPI_SetWindowPos now works properly for minimize/restore (buttons now created with _GUICtrlButton_Create), and GUICtrlSetPos breaks totally. So I'm guessing Auitoit is keeping track of the controls that it creates, and is manually telling them where to go during the restore procedure. And I figure if we wanted to go deeper we could probably just wite our own restore func to test this... But I haven't got around to that just yet! Edit: Then again this seems inconsistent with what @Nine found with the external window - so maybe I'm still missing something.... Edited Friday at 05:07 AM by MattyD clarity ioa747 1
MattyD Posted Friday at 01:06 PM Author Posted Friday at 01:06 PM (edited) Here's a simpler test. This time we're defining the main gui proc. When $bBypassAutoItHdlr = False then we're letting Autoit's message handler do its thing, otherwise we're bypassing it (That's my understanding anyway!). So we can see _WinAPI_SetWindowsPos() does indeed work with a minimize/restore when $bBypassAutoItHdlr = True. So I guess the next task is to find which messages introduce the behavior. expandcollapse popup#include <guiConstants.au3> #include <winapi.au3> Opt("MustDeclareVars", 1) Global Const $SC_MINIMIZE = 0xF020 Global Const $SC_RESTORE = 0xF120 Global Const $SC_CLOSE = 0xF060 Global $hGui = GUICreate("", 300, 200, 100, 100) Global $idBtn = GUICtrlCreateButton("Button 1", 4, 4, 80, 80) Global $hBtn = GUICtrlGetHandle($idBtn) Global $hGUIProc = DllCallbackRegister("GUIProc", "long", "hwnd;uint;wparam;lparam") Global $pGUIProc = DllCallbackGetPtr($hGUIProc) Global $pOrigGUIProc = _WinAPI_SetWindowLong($hGUI, $GWL_WNDPROC, $pGUIProc) Global $bBypassAutoItHdlr = False GUISetState() _WinAPI_SetWindowPos($hBtn, $HWND_TOP, 80, 80, 100, 100, 0) ;~ GUICtrlSetPos($idBtn, 80, 80, 100, 100) While WinExists($hGUI) Sleep(10) WEnd Func guiProc($hWnd, $uMsg, $wParam, $lParam) Local $iRet, $aRes Switch $uMsg Case $WM_SYSCOMMAND Switch $wParam Case $SC_CLOSE $iRet = _WinAPI_DefWindowProcW($hWnd, $uMsg, $wParam, $lParam) GUIDelete($hGUI) Case Else If $bBypassAutoItHdlr Then $iRet = _WinAPI_DefWindowProcW($hWnd, $uMsg, $wParam, $lParam) Else $aRes = DllCallAddress("long", $pOrigGuiProc, "hwnd", $hWnd, "uint", $uMsg, "wparam", $wParam, "lparam", $lParam) $iRet = $aRes[0] EndIf EndSwitch Case $WM_DESTROY $aRes = DllCallAddress("long", $pOrigGuiProc, "hwnd", $hWnd, "uint", $uMsg, "wparam", $wParam, "lparam", $lParam) $iRet = $aRes[0] Case Else If $bBypassAutoItHdlr Then $iRet = _WinAPI_DefWindowProcW($hWnd, $uMsg, $wParam, $lParam) Else $aRes = DllCallAddress("long", $pOrigGuiProc, "hwnd", $hWnd, "uint", $uMsg, "wparam", $wParam, "lparam", $lParam) $iRet = $aRes[0] EndIf EndSwitch Return $iRet EndFunc Edited Friday at 01:22 PM by MattyD
Nine Posted Friday at 03:14 PM Posted Friday at 03:14 PM (edited) Great investigations. Seems we can force the position of the button inside $WM_WINDOWPOSCHANGING message (by setting X, Y, CX and CY). I still haven't found the elegant way to set the right position at the right time, though. Got to go for now... Edit : this is what I got best so far... expandcollapse popup#include <guiConstants.au3> #include <winapi.au3> #include <MenuConstants.au3> Opt("MustDeclareVars", True) Global $hGUI, $bRestore Example() Func Example() $hGUI = GUICreate("WM_NCHITTEST", 300, 200, -1, -1, $WS_OVERLAPPEDWINDOW) Local $idBtn = GUICtrlCreateButton("Button 1", 4, 4, 80, 80, $WS_CLIPSIBLINGS) Local $idBtn2 = GUICtrlCreateButton("Button 2", 90, 4, 80, 80, $WS_CLIPSIBLINGS) Local $idLockButtons = GUICtrlCreateCheckbox("Lock Buttons", 200, 20, 80, 20) Local $hDll = DllCallbackRegister(ButtonMoveProc, 'lresult', 'hwnd;uint;wparam;lparam;uint_ptr;dword_ptr') _WinAPI_SetWindowSubclass(GUICtrlGetHandle($idBtn), DllCallbackGetPtr($hDll), $idBtn) _WinAPI_SetWindowSubclass(GUICtrlGetHandle($idBtn2), DllCallbackGetPtr($hDll), $idBtn2) GUIRegisterMsg($WM_SYSCOMMAND, WM_SYSCOMMAND) GUISetState() Local $iMsg While True $iMsg = GUIGetMsg() Switch $iMsg Case $GUI_EVENT_CLOSE ExitLoop Case $idLockButtons If GUICtrlRead($iMsg) = $GUI_CHECKED Then _WinAPI_RemoveWindowSubclass(GUICtrlGetHandle($idBtn), DllCallbackGetPtr($hDll), $idBtn) _WinAPI_RemoveWindowSubclass(GUICtrlGetHandle($idBtn2), DllCallbackGetPtr($hDll), $idBtn2) Else _WinAPI_SetWindowSubclass(GUICtrlGetHandle($idBtn), DllCallbackGetPtr($hDll), $idBtn, 0) _WinAPI_SetWindowSubclass(GUICtrlGetHandle($idBtn2), DllCallbackGetPtr($hDll), $idBtn2, 0) EndIf Case $idBtn, $idBtn2 ConsoleWrite("Click " & GUICtrlRead($iMsg) & @CRLF) Case $GUI_EVENT_RESTORE $bRestore = False EndSwitch WEnd GUIDelete() _WinAPI_RemoveWindowSubclass(GUICtrlGetHandle($idBtn), DllCallbackGetPtr($hDll), $idBtn) _WinAPI_RemoveWindowSubclass(GUICtrlGetHandle($idBtn2), DllCallbackGetPtr($hDll), $idBtn2) DllCallbackFree($hDll) EndFunc ;==>Example Func ButtonMoveProc($hWnd, $iMsg, $wParam, $lParam, $iID, $iData) Local $tPos, $aPos, $iRet, $aPoint[2], $iSrc, $iEvent, $hCursor Switch $iMsg Case $WM_NCHITTEST $aPos = WinGetPos($hWnd) $aPoint[0] = BitAND($lParam, 0xFFFF) $aPoint[1] = BitShift($lParam, 16) $iRet = $HTCAPTION If $aPoint[0] - $aPos[0] < 10 Then $iRet = $HTLEFT If $aPoint[0] - $aPos[0] > ($aPos[2] - 10) Then $iRet = $HTRIGHT If $aPoint[1] - $aPos[1] < 10 Then Switch $iRet Case $HTLEFT $iRet = $HTTOPLEFT Case $HTRIGHT $iRet = $HTTOPRIGHT Case Else $iRet = $HTTOP EndSwitch ElseIf $aPoint[1] - $aPos[1] > ($aPos[3] - 10) Then Switch $iRet Case $HTLEFT $iRet = $HTBOTTOMLEFT Case $HTRIGHT $iRet = $HTBOTTOMRIGHT Case Else $iRet = $HTBOTTOM EndSwitch EndIf Return $iRet Case $WM_SETCURSOR $iSrc = BitAND($lParam, 0xFFFF) $iEvent = BitShift($lParam, 16) If $iSrc = $HTCAPTION And $iEvent = $WM_LBUTTONDOWN Then _WinAPI_RedrawWindow($hWnd, 0, 0, $RDW_INVALIDATE + $RDW_FRAME) $hCursor = _WinAPI_LoadCursor(0, $OCR_SIZEALL) _WinAPI_SetCursor($hCursor) Return True EndIf Case $WM_WINDOWPOSCHANGING If $bRestore Then ConsoleWrite("WM_WINDOWPOSCHANGING" & @CRLF) $tPos = DllStructCreate($tagWINDOWPOS, $lParam) $aPos = ControlGetPos($hGUI, "", $hWnd) ConsoleWrite($aPos[0] & "/" & $aPos[1] & "/" & $aPos[2] & "/" & $aPos[3] & @CRLF) $tPos.X = $aPos[0] $tPos.Y = $aPos[1] $tPos.CX = $aPos[2] $tPos.CY = $aPos[3] Return 0 EndIf EndSwitch Return _WinAPI_DefSubclassProc($hWnd, $iMsg, $wParam, $lParam) EndFunc ;==>ButtonMoveProc Func WM_SYSCOMMAND($hWnd, $uMsg, $wParam, $lParam) If $wParam = $SC_RESTORE Then ConsoleWrite("---Start Restore---" & @CRLF) $bRestore = True EndIf Return $GUI_RUNDEFMSG EndFunc ;==>WM_SYSCOMMAND Edited Friday at 05:47 PM by Nine ioa747, pixelsearch and MattyD 3 “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) Screen Scraping Multi-Threading Made Easy
MattyD Posted Friday at 11:42 PM Author Posted Friday at 11:42 PM (edited) Nice Nine, but I'll do you one better - The trigger looks to be WM_SIZE, which makes sense. I'd say we've been fighting the mechanism behind control docking. We can ignore it though by using GuiRegisterMsg and returning anything but $GUI_RUNDEFMSG. Edit: or maybe its technically better to return _WinAPI_DefWindowProcW($hWnd, $uMsg, $wParam, $lParam) I've also changed the Main GUI style so you can resize the window. If you don't register $WM_SIZE you can see autoit's "default" behavior is that the button moves when you resize the window. expandcollapse popup#AutoIt3Wrapper_UseX64=N #include <guiConstants.au3> #include <winapi.au3> Opt("MustDeclareVars", 1) Global $hGui = GUICreate("", 300, 200, 100, 100, BitOR($WS_SIZEBOX, $WS_MINIMIZEBOX)) Global $idBtn = GUICtrlCreateButton("Button 1", 4, 4, 80, 80) Global $hBtn = GUICtrlGetHandle($idBtn) Global $hBtnProc = DllCallbackRegister("btnProc", "lresult", "hwnd;uint;wparam;lparam;uint_ptr;dword_ptr") Global $pBtnProc = DllCallbackGetPtr($hBtnProc) _WinAPI_SetWindowSubclass($hBtn, $pBtnProc, $idBtn) GUIRegisterMsg($WM_SIZE, "WM_SIZE") GUISetState() Local $iMsg While 1 $iMsg = GUIGetMsg() switch $iMsg Case $GUI_EVENT_CLOSE Exit EndSwitch WEnd Func btnProc($hWnd, $uMsg, $wParam, $lParam, $uIdSubclasss, $dwRefData) local $iRet Switch $uMsg Case $WM_NCHITTEST $iRet = $HTCAPTION Case Else $iRet = _WinAPI_DefSubclassProc($hWnd, $uMsg, $wParam, $lParam) EndSwitch Return $iRet EndFunc Func WM_SIZE($hWnd, $uMsg, $wParam, $lParam) Return _WinAPI_DefWindowProcW($hWnd, $uMsg, $wParam, $lParam) EndFunc#include <guiConstants.au3> #include <winapi.au3> Opt("MustDeclareVars", 1) Global $hGui = GUICreate("", 300, 200, 100, 100, BitOR($WS_SIZEBOX, $WS_MINIMIZEBOX)) Global $idBtn = GUICtrlCreateButton("Button 1", 4, 4, 80, 80) Global $hBtn = GUICtrlGetHandle($idBtn) Global $hBtnProc = DllCallbackRegister("BtnProc", "long", "hwnd;uint;wparam;lparam") Global $pBtnProc = DllCallbackGetPtr($hBtnProc) _WinAPI_SetWindowSubclass($hBtn,$pBtnProc, $idBtn) GUIRegisterMsg($WM_SIZE, "WM_SIZE") GUISetState() Local $iMsg While 1 $iMsg = GUIGetMsg() switch $iMsg Case $GUI_EVENT_CLOSE Exit EndSwitch WEnd Func btnProc($hWnd, $uMsg, $wParam, $lParam) local $iRet Switch $uMsg Case $WM_NCHITTEST $iRet = $HTCAPTION Case Else $iRet = _WinAPI_DefSubclassProc($hWnd, $uMsg, $wParam, $lParam) EndSwitch Return $iRet EndFunc Func WM_SIZE($hWnd, $uMsg, $wParam, $lParam) Return _WinAPI_DefWindowProcW($hWnd, $uMsg, $wParam, $lParam) EndFunc Edited yesterday at 03:45 AM by MattyD
Nine Posted yesterday at 01:20 AM Posted yesterday at 01:20 AM Does not work for me : Quote !>20:19:39 AutoIt3 ended. rc:-1073740771 “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) Screen Scraping Multi-Threading Made Easy
ioa747 Posted yesterday at 01:34 AM Posted yesterday at 01:34 AM neither to me !>03:32:51 AutoIt3 ended. rc:-1073740771 I know that I know nothing
MattyD Posted yesterday at 03:22 AM Author Posted yesterday at 03:22 AM (edited) Oops it was broken for Autoit x86 - I didn't register the callback correctly when I've moved from WindowSetLong to setwindowssubclass. I've updated the example. And here's one for @argumentum if I've done things correctly Hold shift to move/resize the controls. expandcollapse popup#include <guiConstants.au3> #include <winapi.au3> #include <misc.au3> Opt("MustDeclareVars", 1) Global $hGui = GUICreate("", 300, 200, 100, 100, BitOR($WS_SIZEBOX, $WS_MINIMIZEBOX)) Global $idBtn = GUICtrlCreateButton("Button 1", 4, 4, 80, 80) Global $idBtn2 = GUICtrlCreateButton("Button 2", 90, 4, 80, 80) Global $hCursor = _WinAPI_CopyCursor(_WinAPI_LoadCursor(0, $OCR_CROSS)) Global $hBtn = GUICtrlGetHandle($idBtn) Global $hBtn2 = GUICtrlGetHandle($idBtn2) Global $hBtnProc = DllCallbackRegister("btnProc", "lresult", "hwnd;uint;wparam;lparam;uint_ptr;dword_ptr") Global $pBtnProc = DllCallbackGetPtr($hBtnProc) _WinAPI_SetWindowSubclass($hBtn, $pBtnProc, $idBtn) _WinAPI_SetWindowSubclass($hBtn2, $pBtnProc, $idBtn2) GUIRegisterMsg($WM_SIZE, "WM_SIZE") GUISetState() Local $iMsg While 1 $iMsg = GUIGetMsg() Switch $iMsg Case $GUI_EVENT_CLOSE Exit Case $idBtn, $idBtn2 ConsoleWrite(GUICtrlRead($iMsg) & @CRLF) EndSwitch WEnd Func btnProc($hWnd, $uMsg, $wParam, $lParam, $uIdSubclasss, $dwRefData) Local $iRet Switch $uMsg Case $WM_NCHITTEST Local $aPoint[2] = [BitAND($lParam, 0xFFFF), BitShift($lParam, 16)] ;Mouse coords can be negative on edge cases! If BitAND($aPoint[0], 0x8000) Then $aPoint[0] = BitOR(0xFFFF0000, $aPoint[0]) If BitAND($aPoint[1], 0x8000) Then $aPoint[1] = BitOR(0xFFFF0000, $aPoint[1]) Local $aPos = WinGetPos($hWnd), $iMar = 10 If Not _IsPressed("10") Then $iRet = _WinAPI_DefSubclassProc($hWnd, $uMsg, $wParam, $lParam) Else $iRet = $HTCAPTION If $aPoint[0] - $aPos[0] < $iMar Then $iRet = $HTLEFT If $aPoint[0] - $aPos[0] > ($aPos[2] - $iMar) Then $iRet = $HTRIGHT If $aPoint[1] - $aPos[1] < $iMar Then Switch $iRet Case $HTLEFT $iRet = $HTTOPLEFT Case $HTRIGHT $iRet = $HTTOPRIGHT Case Else $iRet = $HTTOP EndSwitch ElseIf $aPoint[1] - $aPos[1] > ($aPos[3] - $iMar) Then Switch $iRet Case $HTLEFT $iRet = $HTBOTTOMLEFT Case $HTRIGHT $iRet = $HTBOTTOMRIGHT Case Else $iRet = $HTBOTTOM EndSwitch EndIf If $aPoint[0] < 0 Then $iRet = _WinAPI_DefSubclassProc($hWnd, $uMsg, $wParam, $lParam) If $aPoint[1] < 0 Then $iRet = _WinAPI_DefSubclassProc($hWnd, $uMsg, $wParam, $lParam) _WinAPI_RedrawWindow($hWnd) EndIf Case $WM_SETCURSOR Local $iSrc = BitAND($lParam, 0xFFFF), $iEvent = BitShift($lParam, 16) If $iSrc = $HTCAPTION And $iEvent = $WM_LBUTTONDOWN Then _WinAPI_SetCursor($hCursor) $iRet = 1 Else $iRet = _WinAPI_DefSubclassProc($hWnd, $uMsg, $wParam, $lParam) EndIf Case Else $iRet = _WinAPI_DefSubclassProc($hWnd, $uMsg, $wParam, $lParam) EndSwitch Return $iRet EndFunc ;==>btnProc Func WM_SIZE($hWnd, $uMsg, $wParam, $lParam) Return _WinAPI_DefWindowProcW($hWnd, $uMsg, $wParam, $lParam) EndFunc ;==>WM_SIZE Edited yesterday at 03:52 AM by MattyD ioa747 and argumentum 2
argumentum Posted yesterday at 05:05 AM Posted yesterday at 05:05 AM 1 hour ago, MattyD said: And here's one for @argumentum Thanks. My idea/wish, is to _WinAPI_SetWindowSubclass() and _WinAPI_RemoveWindowSubclass() at will, to any control. That would make it practical to use anywhere. Follow the link to my code contribution ( and other things too ). FAQ - Please Read Before Posting.
Nine Posted yesterday at 12:59 PM Posted yesterday at 12:59 PM @MattyD Works great. Good job ! “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) Screen Scraping Multi-Threading Made Easy
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