4ggr35510n Posted September 19, 2010 Share Posted September 19, 2010 (edited) Greetings! Using GuiRegisterMsg I've registered two functions, as in this simple example below. And almost immediately I've encounter two major, nasty issues: - This MSG doesn't work when clicked on Gui Element (such as one of labels) - It is not capable to recieve wm_lbuttonup from outside the window, even if lbuttondown happend inside window :/ Could you give me some hints and ideas, how should I done it properly, to a) get msg even in clicked on gui element, get msg from 'outside' the window (if the window is still active!) or at least some way to recognize when and at which position mouse is leaving my gui window? I'll really appreciate your help! BR, 4gr $hGUI = GUICreate("Menu", 400, 300) $label = GUICtrlCreateLabel('', 1, 1, 390, 20) $label2 = GUICtrlCreateLabel('',1, 100, 390, 20) GUISetState() ; Register message handlers GUIRegisterMsg(0x0201, 'L_down') GUIRegisterMsg(0x0202, 'L_up') ; Loop until user exits Do Until GUIGetMsg() = -3 Func L_down($hWnd, $iMsg, $iwParam, $ilParam) GUICtrlSetData($label, Dec(StringMid($ilParam, 3, 4)) & ' ' & Dec(StringMid($ilParam, 7, 4))) ConsoleWrite('KLIK' & @CRLF) EndFunc Func L_up($hWnd, $iMsg, $iwParam, $ilParam) GUICtrlSetData($label2, Dec(StringMid($ilParam, 3, 4)) & ' ' & Dec(StringMid($ilParam, 7, 4))) EndFunc Edited November 16, 2010 by 4ggr35510n Link to comment Share on other sites More sharing options...
AdmiralAlkex Posted September 19, 2010 Share Posted September 19, 2010 You need something likehttp://www.autoitscript.com/forum/index.php?showtopic=81761 .Some of my scripts: ShiftER, Codec-Control, Resolution switcher for HTC ShiftSome of my UDFs: SDL UDF, SetDefaultDllDirectories, Converting GDI+ Bitmap/Image to SDL Surface Link to comment Share on other sites More sharing options...
4ggr35510n Posted September 20, 2010 Author Share Posted September 20, 2010 (edited) Thank you for answer, AdmiralAlkex!Very nice script and really useful... But on my (very poor) PC it's taking up to 50% of CPU :[I've found THIS cool script that receives only mouse events from inside the gui, which solves my first problem :]Yet neither of those two are able to get WM_MOUSELEAVE message code... MSDN says that to receive 'mouseleave' you have to make prior call to TrackMouseEvent. I've searched on forum, but there was only one topic about it, which doesn't help me at all I'm not as advanced to crack it by myself... Could you please help me with this? :] Edited September 20, 2010 by 4ggr35510n Link to comment Share on other sites More sharing options...
AdmiralAlkex Posted September 20, 2010 Share Posted September 20, 2010 Ehhhmmm If I may ask, why do you need to know when the left button is released outside the window anyway? .Some of my scripts: ShiftER, Codec-Control, Resolution switcher for HTC ShiftSome of my UDFs: SDL UDF, SetDefaultDllDirectories, Converting GDI+ Bitmap/Image to SDL Surface Link to comment Share on other sites More sharing options...
4ggr35510n Posted September 21, 2010 Author Share Posted September 21, 2010 (edited) Not released, not necessarily. I just need to know when the mouse leaves gui... Eh, I don't know how to explain... Run this examples, please:#include <winapi.au3> $gui_handle = GUICreate('abba', 700, 400) Global $pic_X = 600/2 Global $pic_Y = 300/2 Global $mouse_X, $mouse_Y Global $pic_handle = GUICtrlCreatePic('', $pic_X, $pic_Y, 1, 1) $bitmap = _WinApi_CreateSolidBitmap($gui_handle, 0xFF00FF, 100, 100) GUICtrlSendMsg($pic_handle, 0x0172, 0, $bitmap) GUISetState() ; Register message handlers GUIRegisterMsg(0x0201, 'Down') GUIRegisterMsg(0x0202, 'Up') ; Loop until user exits Do Until GUIGetMsg() = -3 Func Down($hWnd, $iMsg, $iwParam, $ilParam) $mouse_Y = BitShift($iLParam, 16) $mouse_X = BitAND($iLParam, 0xFFFF) EndFunc Func Up($hWnd, $iMsg, $iwParam, $ilParam) $pic_Y -= BitShift($iLParam, 16) - $mouse_Y $pic_X -= BitAND($iLParam, 0xFFFF) - $mouse_X GUICtrlSetPos($pic_handle, $pic_X, $pic_y) EndFuncBasically, the idea is to move image while moving mouse holding LBM. In spoiler below, there is a version with dynamic moving, using MouseMove, not LButtonDown and Up messages. Run this please, because I will rather go with this option:expandcollapse popup#include <winapi.au3> $gui_handle = GUICreate('Dynamic Moving Pic With Mouse', 700, 400) Global $pic_X = 300 Global $pic_Y = 150 Global $mouse_X, $mouse_Y, $do_move = 0 Global $pic_handle = GUICtrlCreatePic('', $pic_X, $pic_Y, 1, 1) $bitmap = _WinApi_CreateSolidBitmap($gui_handle, 0xFF00FF, 100, 100) GUICtrlSendMsg($pic_handle, 0x0172, 0, $bitmap) GUISetState() ; Register message handlers GUIRegisterMsg(0x0200, 'Move') ; Loop until user exits Do Until GUIGetMsg() = -3 Func Move($hWnd, $iMsg, $iwParam, $ilParam) $mouse_Y_temp = BitShift($iLParam, 16) $mouse_X_temp = BitAND($iLParam, 0xFFFF) If BitAnd($iwParam, 0x1) Then If $mouse_Y_temp <> $mouse_X OR $mouse_X_temp <> $mouse_X Then $pic_Y += $mouse_y_temp - $mouse_Y $pic_X += $mouse_X_temp - $mouse_X $mouse_X = $mouse_X_temp $mouse_Y = $mouse_Y_temp GUICtrlSetPos($pic_handle, $pic_X, $pic_y) EndIf Else $mouse_X = $mouse_X_temp $mouse_Y = $mouse_Y_temp EndIf EndFuncYet I don't know how to do 2 things: - get msg when mouse is leaving gui or when MouseUp is done outside (its needed only in first case, because mouse move stops automatically on leaving)-Get windows mouse messages even if clicked on gui element? (need this anyway for both and this issue is killing me. how to get msg when clicking on gui element, in some simple way, without overloading CPU? )@EDIT:I've found a way how to bypass 'not getting msg from gui-element' issue. Pasted in spoiler below, creating second window and adding 'movement speed' option. Yet I would like not using this solution in final code, so if someone could give me advice, how to get msg from element, I would be uncommonly thankful, able to create just one, neat and clean window :] expandcollapse popup#include <winapi.au3> $gui_handle = GUICreate('MAPA', 700, 400) Global $pic_X = 300 Global $pic_Y = 150 Global $mouse_X, $mouse_Y, $do_move = 0 Global $pic_handle = GUICtrlCreatePic('', $pic_X, $pic_Y, 1, 1) $bitmap = _WinApi_CreateSolidBitmap($gui_handle, 0xFF00FF, 100, 100) GUICtrlSendMsg($pic_handle, 0x0172, 0, $bitmap) GUISetState() Global $_SPEED = 3 $gui_control = GuiCreate('MapControl', 100, 100, 100, 100, Default, 0x00000080) $p = GUICtrlCreateButton('+',0,0, 20) $m = GUICtrlCreateButton('-',20,0, 20) $label = GUICtrlCreateLabel($_SPEED, 40,0, 30,12) GUIRegisterMsg(0x0200, 'Move') GUISetState() While True Switch GUIGetMsg() Case $p $_SPEED += 1 GUICtrlSetData($label, $_SPEED) Case $m $_SPEED -= 1 GUICtrlSetData($label, $_SPEED) Case -3 Exit EndSwitch WEnd Func Move($hWnd, $iMsg, $iwParam, $ilParam) If $hWnd = $gui_control Then $mouse_Y_temp = BitShift($iLParam, 16) $mouse_X_temp = BitAND($iLParam, 0xFFFF) If BitAnd($iwParam, 0x1) Then If $mouse_Y_temp <> $mouse_X OR $mouse_X_temp <> $mouse_X Then $pic_Y += ($mouse_y_temp - $mouse_Y) * $_SPEED $pic_X += ($mouse_X_temp - $mouse_X) * $_SPEED $mouse_X = $mouse_X_temp $mouse_Y = $mouse_Y_temp GUICtrlSetPos($pic_handle, $pic_X, $pic_y) EndIf Else $mouse_X = $mouse_X_temp $mouse_Y = $mouse_Y_temp EndIf EndIf EndFunc Edited September 21, 2010 by 4ggr35510n Link to comment Share on other sites More sharing options...
AdmiralAlkex Posted September 21, 2010 Share Posted September 21, 2010 -Get windows mouse messages even if clicked on gui element? I thought that would be easy, just set a new window proc with SetWindowLong and read the necessary message. expandcollapse popup#Include <WinAPI.au3> #include <Constants.au3> ;For $GWL_WNDPROC #include <WindowsConstants.au3> ;For $WM_MOUSEMOVE $gui_handle = GUICreate('Dynamic Moving Pic With Mouse', 700, 400) Global Const $MK_LBUTTON = 0x0001 $button = GUICtrlCreateButton("Click me!", 100, 100, 50, 30) ;To prove that messages still work Global $pic_X = 300 Global $pic_Y = 150 Global $mouse_X, $mouse_Y ConsoleWrite(3 & @CRLF) Global $pic_handle = GUICtrlCreatePic('', $pic_X, $pic_Y, 1, 1) $hPic = GUICtrlGetHandle($pic_handle) $bitmap = _WinApi_CreateSolidBitmap($gui_handle, 0xFF00FF, 100, 100) GUICtrlSendMsg($pic_handle, 0x0172, 0, $bitmap) ConsoleWrite(4 & @CRLF) GUISetState() ConsoleWrite(1 & @CRLF) ;~ $wProcNew = DllCallbackRegister("_MyWindowProc", "ptr", "hwnd;uint;long;ptr") ;~ $wProcOld = _WinAPI_SetWindowLong($gui_handle, $GWL_WNDPROC, DllCallbackGetPtr($wProcNew)) ;Hijack the AutoIt message pump ConsoleWrite(2 & @CRLF) ; Loop until user exits While 1 Switch GUIGetMsg() Case -3 _WinAPI_SetWindowLong($gui_handle, $GWL_WNDPROC, $wProcOld) ;Maybe isn't necessary here, but better safe than sorry :P Exit Case $button MsgBox(0, "Some title", "Some text") EndSwitch WEnd Func _MyWindowProc($hWnd, $uiMsg, $wParam, $lParam) Static $mouse_X = "", $mouse_Y = "" If $uiMsg = $WM_MOUSEMOVE Then If $wParam = $MK_LBUTTON Then ;If left button is down $iPosX = BitAND($lParam, 0xFFFF) ; Low Word $iPosY = BitShift($lParam, 16) ; Hi Word $pic_X += $mouse_X -$iPosX $pic_Y += $mouse_Y -$iPosY If $pic_X < 0 Then $pic_X = 0 If $pic_Y < 0 Then $pic_Y = 0 If $pic_X > 600 Then $pic_X = 600 If $pic_Y > 300 Then $pic_Y = 300 ;~ ControlMove($gui_handle, "", $hPic, $pic_X, $pic_y) $mouse_X = $iPosX $mouse_Y = $iPosY EndIf EndIf ;pass the unhandled messages to default WindowProc Return _WinAPI_CallWindowProc($wProcOld, $hWnd, $uiMsg, $wParam, $lParam) EndFunc ;==>_MyWindowProc That was an epic failure, I'm just dead-locking AutoIt. Someone else must help you with this, I'm beaten .Some of my scripts: ShiftER, Codec-Control, Resolution switcher for HTC ShiftSome of my UDFs: SDL UDF, SetDefaultDllDirectories, Converting GDI+ Bitmap/Image to SDL Surface Link to comment Share on other sites More sharing options...
4ggr35510n Posted September 21, 2010 Author Share Posted September 21, 2010 (edited) I've tried to get something from ur code, but its totally not my level :| MSDN isn't too supportive too...Maybe someone nice could help me with this Anyway,Thank you very much for your help! I owe you! Edited September 21, 2010 by 4ggr35510n Link to comment Share on other sites More sharing options...
seandisanti Posted September 21, 2010 Share Posted September 21, 2010 maybe i'm not understanding, wouldn't be the first time, but why can't you use MouseGetPos() and WinGetPos() to tell if he mouse has moved beyond the gui? Link to comment Share on other sites More sharing options...
4ggr35510n Posted September 24, 2010 Author Share Posted September 24, 2010 (Mouse/Win)GetPos() is a CPU-killer in that case...No one can help with getting Windows Messages from gui element? Link to comment Share on other sites More sharing options...
Moderators Melba23 Posted September 24, 2010 Moderators Share Posted September 24, 2010 4ggr35510n, Basically, the idea is to move image while moving mouse holding LBM.Perhaps you cannot do it using the messages you have been using. Does this help at all - it does seem to do what you want and does not kill my CPU: expandcollapse popup#include <GUIConstantsEx.au3> #include <WindowsConstants.au3> #include <WinAPI.au3> Global Const $SC_DRAGMOVE = 0xF012 ; Create main GUI $hGUI = GUICreate("Test", 500, 500) GUISetState() ; Get system values for the GUI borders Global $iBorder = _WinAPI_GetSystemMetrics(8) ; Border width Global $iBar = _WinAPI_GetSystemMetrics(4) ; Title bar height Global $aMain_Pos = WinGetPos($hGUI) ; Create the child GUI $hGUI_Child = GUICreate("Child", 100, 100, 100, 100, $WS_POPUP, $WS_EX_MDICHILD, $hGUI) $hPic = GUICtrlCreatePic("", 0, 0, 1, 1) $hBitMap = _WinApi_CreateSolidBitmap($hGUI_Child, 0xFF00FF, 100, 100) GUICtrlSendMsg($hPic, 0x0172, 0, $hBitMap) GUISetState(@SW_SHOW, $hGUI_Child) ; Look for the child moving GUIRegisterMsg($WM_WINDOWPOSCHANGING, "WM_WINDOWPOSCHANGING") While 1 ; Use the advanced parameter to distinguish between GUIs $aMsg = GUIGetMsg(1) Switch $aMsg[1] Case $hGUI Switch $aMsg[0] Case $GUI_EVENT_CLOSE Exit EndSwitch Case $hGUI_Child Switch $aMsg[0] ; If the mouse is down on the child Case $GUI_EVENT_PRIMARYDOWN ; Tell the GUI to drag _SendMessage($hGUI_Child, $WM_SYSCOMMAND, $SC_DRAGMOVE, 0) EndSwitch EndSwitch WEnd ; Handler for the child moving Func WM_WINDOWPOSCHANGING($hWnd, $Msg, $wParam, $lParam) ; If it the child sending the message If $hWnd = $hGUI_Child Then ; Get main GUI position and calculate current min and max positions for child $aMain_Pos = WinGetPos($hGUI) Local $iY_Min = $aMain_Pos[1] + $iBorder + $iBar Local $iY_Max = $aMain_Pos[1] + $iBorder + $iBar + 400 Local $iX_Min = $aMain_Pos[0] + $iBorder Local $iX_Max = $aMain_Pos[0] + $iBorder + 400 ; Get current child position Local $stWinPos = DllStructCreate("uint;uint;int;int;int;int;uint", $lParam) Local $iLeft = DllStructGetData($stWinPos, 3) Local $iTop = DllStructGetData($stWinPos, 4) Local $iWidth = DllStructGetData($stWinPos, 5) Local $iHeight = DllStructGetData($stWinPos, 6) ; Adjust as necessary to remain within the limits we set If $iLeft < $iX_Min Then DllStructSetData($stWinPos, 3, $iX_Min) If $iLeft > $iX_Max Then DllStructSetData($stWinPos, 3, $iX_Max) If $iTop < $iY_Min Then DllStructSetData($stWinPos, 4, $iY_Min) If $iTop > $iY_Max Then DllStructSetData($stWinPos, 4, $iY_Max) EndIf EndFunc I hope that you find it useful - even if it uses a very different technique to move the image. M23  Any of my own code posted anywhere on the forum is available for use by others without any restriction of any kind Open spoiler to see my UDFs: Spoiler ArrayMultiColSort ---- Sort arrays on multiple columnsChooseFileFolder ---- Single and multiple selections from specified path treeview listingDate_Time_Convert -- Easily convert date/time formats, including the language usedExtMsgBox --------- A highly customisable replacement for MsgBoxGUIExtender -------- Extend and retract multiple sections within a GUIGUIFrame ---------- Subdivide GUIs into many adjustable framesGUIListViewEx ------- Insert, delete, move, drag, sort, edit and colour ListView itemsGUITreeViewEx ------ Check/clear parent and child checkboxes in a TreeViewMarquee ----------- Scrolling tickertape GUIsNoFocusLines ------- Remove the dotted focus lines from buttons, sliders, radios and checkboxesNotify ------------- Small notifications on the edge of the displayScrollbars ----------Automatically sized scrollbars with a single commandStringSize ---------- Automatically size controls to fit textToast -------------- Small GUIs which pop out of the notification area  Link to comment Share on other sites More sharing options...
4ggr35510n Posted November 16, 2010 Author Share Posted November 16, 2010 Something like solved:expandcollapse popupOnAutoItExitRegister('OnAutoitExit') Global Const $tagPOINT = "int X;int Y" Global Const $MSLLHOOKSTRUCT = $tagPOINT & ";dword mouseData;dword flags;dword time;ulong_ptr dwExtraInfo" Global $hKey_Proc = DllCallbackRegister("MouseProc", "int", "int;ptr;ptr") Global $hM_Module = DllCall("kernel32.dll", "hwnd", "GetModuleHandle", "ptr", 0) Global $hM_Hook, $ptX = 0, $ptY = 0 Global $labX = 150, $labY = 150 Global $hGUI = GUICreate('Test', 75/100 * @DesktopWidth, 75/100 * @DesktopHeight) Global $label = GUICtrlCreateLabel('MOVE ME!', $labX, $labY, 300, 300, BitOR(0x0200, 0x01) ) GUICtrlSetBkColor(-1, 0xFF00FF) GUICtrlSetFont(-1, 22, 1200) GUIRegisterMsg(0x0006, 'MouseHook_Manage') ; WM_ACTIVATE GUISetState() Do Until GuiGetMsg() = -3 Func MouseProc($nCode, $wParam, $lParam) Local $info, $x, $y Switch $wParam Case 0x0201 $info = DllStructCreate($MSLLHOOKSTRUCT, $lParam) $ptX = DllStructGetData($info, 1) $ptY = DllStructGetData($info, 2) ConsoleWrite($ptX & ' ' & $ptY & @CRLF) Case 0x0202 ;ConsoleWrite($labX & ' ' & $labY & @CRLF) $info = DllStructCreate($MSLLHOOKSTRUCT, $lParam) $x = DllStructGetData($info, 1) $y = DllStructGetData($info, 2) ConsoleWrite($x & ' ' & $y & @CRLF) $difx = $x - $ptX $dify = $y - $ptY $labX += $difx $labY += $dify ConsoleWrite($difx & ' ' & $dify & @CRLF) ControlMove($hGUI, '', $label, $labX, $labY) EndSwitch EndFunc Func MouseHook_Manage($hWND, $some_shit, $wActiveState) If $hGUI = $hWND Then Switch StringRight($wActiveState, 1) Case 0 DllCall("user32.dll", "int", "UnhookWindowsHookEx", "hwnd", $hM_Hook[0]) $hM_Hook[0] = 0 Case 1 $hM_Hook = DllCall("user32.dll", "hwnd", "SetWindowsHookEx", "int", 14, "ptr", DllCallbackGetPtr($hKey_Proc), "hwnd", $hM_Module[0], "dword", 0) Case 2 $hM_Hook = DllCall("user32.dll", "hwnd", "SetWindowsHookEx", "int", 14, "ptr", DllCallbackGetPtr($hKey_Proc), "hwnd", $hM_Module[0], "dword", 0) EndSwitch EndIf EndFunc Func OnAutoItExit() DllCall("user32.dll", "int", "UnhookWindowsHookEx", "hwnd", $hM_Hook[0]) $hM_Hook[0] = 0 DllCallbackFree($hKey_Proc) $hKey_Proc = 0 EndFuncNo child-window, you can move label/picture by clicking on it... Quite works. But:If anyone has an idea how to cut off the MouseHook_Menage function (detecting gui window [dis]activated; since I can't make $WH_MOUSE work properly ) - I'll appreciate your thoughts in this topic: Thank very much every one for help! PS Moving control only on WM_LBUTTONUP message is intended (slow, old and ugly CPU). You can easily change script to move every time it receives WM_MOUSEMOVE message... If you want to continue such a useless thing ;] Link to comment Share on other sites More sharing options...
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