MDCT Posted June 23, 2009 Share Posted June 23, 2009 Hello, Now I have question regarding context-menu. I have tried to search the forum, but could find the solution. Basically, I want to create a context-menu that disappears when the mouse is not on the context-menu. Is it possible? Below is a simple context-menu example. To show the context-menu, run the script and hold left-mouse-button for a few seconds. expandcollapse popup#include <Constants.au3> #include <MenuConstants.au3> #include <Misc.au3> #include <WindowsConstants.au3> ;Mainloop While 1 if _IsPressed("01") Then for $x=1 to 10 if not _IsPressed("01") then ExitLoop Sleep(50) Next if _IsPressed("01") then showPopup() EndIf WEnd Func showPopup() $hDlg = GUICreate("", 1, 1, 0, 0, $WS_POPUP, $WS_EX_TOOLWINDOW); Create our temporary GUI $cDummy = GUICtrlCreateDummy(); Create a dummy control to hang a context menu on $hContextMenu = GUICtrlCreateContextMenu($cDummy); Create the context menu $exit=GUICtrlCreateMenuItem("Exit",$hContextMenu) GUISetState(@SW_SHOW,$hDlg) $rect = MouseGetPos() $nResult = _GUICtrlMenu_TrackPopupMenu(GUICtrlGetHandle($hContextMenu), $hDlg, $rect[0]-27, $rect[1]-12, 1, 1, 2) If $nResult = $exit Then exit GUIDelete($hDlg) EndFunc Func _GUICtrlMenu_TrackPopupMenu($hMenu, $hWnd, $iX = -1, $iY = -1, $iAlignX = 1, $iAlignY = 1, $iNotify = 0, $iButtons = 0) Local $iFlags, $aResult If $iX = -1 Then $iX = _WinAPI_GetMousePosX() If $iY = -1 Then $iY = _WinAPI_GetMousePosY() Switch $iAlignX Case 1 $iFlags = BitOR($iFlags, $TPM_LEFTALIGN) Case 2 $iFlags = BitOR($iFlags, $TPM_RIGHTALIGN) Case Else $iFlags = BitOR($iFlags, $TPM_CENTERALIGN) EndSwitch Switch $iAlignY Case 1 $iFlags = BitOR($iFlags, $TPM_TOPALIGN) Case 2 $iFlags = BitOR($iFlags, $TPM_VCENTERALIGN) Case Else $iFlags = BitOR($iFlags, $TPM_BOTTOMALIGN) EndSwitch If BitAND($iNotify, 1) <> 0 Then $iFlags = BitOR($iFlags, $TPM_NONOTIFY) If BitAND($iNotify, 2) <> 0 Then $iFlags = BitOR($iFlags, $TPM_RETURNCMD) Switch $iButtons Case 1 $iFlags = BitOR($iFlags, $TPM_RIGHTBUTTON) Case Else $iFlags = BitOR($iFlags, $TPM_LEFTBUTTON) EndSwitch $aResult = DllCall("User32.dll", "int", "TrackPopupMenu", "hwnd", $hMenu, "int", $iFlags, "int", $iX, "int", $iY, "int", 0, "hwnd", $hWnd, "hwnd", 0) Return $aResult[0] EndFunc ;==>_GUICtrlMenu_TrackPopupMenu By the time it goes to "_GUICtrlMenu_TrackPopupMenu", the script is paused. I did try using Adlib, if I did not made mistake on the code, Adlib also won't work. Any idea on how to make the context-menu disappear on mouse-leave? Thank you. Link to comment Share on other sites More sharing options...
MrCreatoR Posted June 23, 2009 Share Posted June 23, 2009 I am not sure that this can work with seperate menu, but here is a gui main menu example: #include <Constants.au3> #include <MenuConstants.au3> #include <Misc.au3> #include <WindowsConstants.au3> ; GUIRegisterMsg($WM_MENUSELECT, "MENU_HANDLER") $hDlg = GUICreate("", 200, 120, 0, 0); Create our temporary GUI $nDummy = GUICtrlCreateLabel("", 0, -100) $hContextMenu = GUICtrlCreateMenu("Menu"); Create the context menu $exit = GUICtrlCreateMenuItem("Exit", $hContextMenu) GUISetState(@SW_SHOW, $hDlg) While GUIGetMsg() <> -3 WEnd Func MENU_HANDLER($hWndGUI, $MsgID, $wParam, $lParam) Local $iItemID = BitAND($wParam, 0xFFFF) If GUICtrlRead($iItemID) = "" Then ControlClick($hWndGUI, "", $nDummy) Return "GUI_RUNDEFMSG" EndFunc Spoiler Using OS: Win 7 Professional, Using AutoIt Ver(s): 3.3.6.1 / 3.3.8.1 AutoIt Russian Community My Work... Spoiler Projects: ATT - Application Translate Tool {new}| BlockIt - Block files & folders {new}| SIP - Selected Image Preview {new}| SISCABMAN - SciTE Abbreviations Manager {new}| AutoIt Path Switcher | AutoIt Menu for Opera! | YouTube Download Center! | Desktop Icons Restorator | Math Tasks | KeyBoard & Mouse Cleaner | CaptureIt - Capture Images Utility | CheckFileSize ProgramUDFs: OnAutoItErrorRegister - Handle AutoIt critical errors {new}| AutoIt Syntax Highlight {new}| Opera Library! | Winamp Library | GetFolderToMenu | Custom_InputBox()! | _FileRun UDF | _CheckInput() UDF | _GUIInputSetOnlyNumbers() UDF | _FileGetValidName() UDF | _GUICtrlCreateRadioCBox UDF | _GuiCreateGrid() | _PathSplitByRegExp() | _GUICtrlListView_MoveItems - UDF | GUICtrlSetOnHover_UDF! | _ControlTab UDF! | _MouseSetOnEvent() UDF! | _ProcessListEx - UDF | GUICtrl_SetResizing - UDF! | Mod. for _IniString UDFs | _StringStripChars UDF | _ColorIsDarkShade UDF | _ColorConvertValue UDF | _GUICtrlTab_CoverBackground | CUI_App_UDF | _IncludeScripts UDF | _AutoIt3ExecuteCode | _DragList UDF | Mod. for _ListView_Progress | _ListView_SysLink | _GenerateRandomNumbers | _BlockInputEx | _IsPressedEx | OnAutoItExit Handler | _GUICtrlCreateTFLabel UDF | WinControlSetEvent UDF | Mod. for _DirGetSizeEx UDF Examples: ScreenSaver Demo - Matrix included | Gui Drag Without pause the script | _WinAttach()! | Turn Off/On Monitor | ComboBox Handler Example | Mod. for "Thinking Box" | Cool "About" Box | TasksBar Imitation Demo Like the Projects/UDFs/Examples? Please rate the topic (up-right corner of the post header: Rating ) * === My topics === * ================================================== ================================================== AutoIt is simple, subtle, elegant. © AutoIt Team Link to comment Share on other sites More sharing options...
MDCT Posted June 23, 2009 Author Share Posted June 23, 2009 Thanks, it's a nice idea, but I cannot seem to make this method to work without using the GUI. Is GUICtrlCreateDummy() the only way to create GUI-less contextmenu? Link to comment Share on other sites More sharing options...
ResNullius Posted June 23, 2009 Share Posted June 23, 2009 (edited) Don't know if this will help, but Holger made a function to show a script's TrayMenu at the current mouse position. so it sort of emulates a context menuhttp://www.autoitscript.com/forum/index.ph...st&p=202661Edit: Actually, that might help with simulating a GUI-less context menu, but the biggest problem with menus (context and tray) is that the execution of the script is paused when the menus are visible. That means no looping to check for active window changes or the like. Hmmm... Edited June 23, 2009 by ResNullius Link to comment Share on other sites More sharing options...
MDCT Posted June 23, 2009 Author Share Posted June 23, 2009 (edited) Thanks for trying to help, ResNullius. Just like you said, when "Func ShowTrayMenu()" is executed, it shows the tray and then pauses the script. I think it can be done by using 2 scripts. One script is to create the menu, the other is to detect mouse by getting window classname that's on the mouse position. But it's not a pretty solution. EDIT: Well, even it's not a pretty solution, I did it anyway. Here's the first script that needs to be compiled and run as exe (because scite cannot execute 2 scripts). expandcollapse popup#include <WinAPI.au3> global const $TITLE_SENDER = '#Sender' global const $TITLE_RECEIVER = '#Reseiver' global const $WM_COPYDATA = 0x004A global $sMsg, $Dummy, $Flag = 0 ;_Receiver() GUICreate($TITLE_RECEIVER) GUIRegisterMsg($WM_COPYDATA, '_WM_COPYDATA') While 1 Sleep(50) if $Flag = 1 then $X=MouseGetPos() $hPoint = DllCall("User32.dll", "hwnd", "WindowFromPoint", "int", $X[0], "int", $X[1]) tooltip(_WinAPI_GetClassName($hPoint[0]),0,0) While _WinAPI_GetClassName($hPoint[0]) <> "#32768" $X=MouseGetPos() $hPoint = DllCall("User32.dll", "hwnd", "WindowFromPoint", "int", $X[0], "int", $X[1]) Sleep(16) WEnd While _WinAPI_GetClassName($hPoint[0]) = "#32768" $X=MouseGetPos() $hPoint = DllCall("User32.dll", "hwnd", "WindowFromPoint", "int", $X[0], "int", $X[1]) Sleep(16) WEnd if _WinAPI_GetClassName($hPoint[0]) <> "#32768" then msgbox(0,0,"Out") $Flag = 0 endif Sleep(50) WEnd func _WM_COPYDATA($hWnd, $msgID, $wParam, $lParam) local $tCOPYDATA = DllStructCreate('dword;dword;ptr', $lParam) local $tMsg = DllStructCreate('char[' & DllStructGetData($tCOPYDATA, 2) & ']', DllStructGetData($tCOPYDATA, 3)) $sMsg = DllStructGetData($tMsg, 1) ; For Sender GUICtrlSendToDummy($Dummy) ; For Receiver $Flag = 1 return 0 endfunc; _WM_COPYDATA Here is the one that can be executed by using Scite. And don't forget to hold left-mouse-button to show the contextmenu. expandcollapse popup#include <Constants.au3> #include <MenuConstants.au3> #include <Misc.au3> #include <WindowsConstants.au3> global const $TITLE_SENDER = '#Sender' global const $TITLE_RECEIVER = '#Reseiver' ;global const $WM_COPYDATA = 0x004A global $sMsg, $Dummy, $Flag = 0 ;Mainloop While 1 Sleep(16) if _IsPressed("01") Then for $x=1 to 10 if not _IsPressed("01") then ExitLoop Sleep(50) Next if _IsPressed("01") then _SendData(WinGetHandle($TITLE_RECEIVER), "1") showPopup() EndIf EndIf Sleep(16) WEnd Func showPopup() $hDlg = GUICreate("", 1, 1, 0, 0, $WS_POPUP, $WS_EX_TOOLWINDOW); Create our temporary GUI $cDummy = GUICtrlCreateDummy(); Create a dummy control to hang a context menu on $hContextMenu = GUICtrlCreateContextMenu($cDummy); Create the context menu $exit=GUICtrlCreateMenuItem("Exit",$hContextMenu) GUISetState(@SW_SHOW,$hDlg) $rect = MouseGetPos() $nResult = _GUICtrlMenu_TrackPopupMenu(GUICtrlGetHandle($hContextMenu), $hDlg, $rect[0]-27, $rect[1]-12, 1, 1, 2) If $nResult = $exit Then exit GUIDelete($hDlg) EndFunc Func _GUICtrlMenu_TrackPopupMenu($hMenu, $hWnd, $iX = -1, $iY = -1, $iAlignX = 1, $iAlignY = 1, $iNotify = 0, $iButtons = 0) Local $iFlags, $aResult If $iX = -1 Then $iX = _WinAPI_GetMousePosX() If $iY = -1 Then $iY = _WinAPI_GetMousePosY() Switch $iAlignX Case 1 $iFlags = BitOR($iFlags, $TPM_LEFTALIGN) Case 2 $iFlags = BitOR($iFlags, $TPM_RIGHTALIGN) Case Else $iFlags = BitOR($iFlags, $TPM_CENTERALIGN) EndSwitch Switch $iAlignY Case 1 $iFlags = BitOR($iFlags, $TPM_TOPALIGN) Case 2 $iFlags = BitOR($iFlags, $TPM_VCENTERALIGN) Case Else $iFlags = BitOR($iFlags, $TPM_BOTTOMALIGN) EndSwitch If BitAND($iNotify, 1) <> 0 Then $iFlags = BitOR($iFlags, $TPM_NONOTIFY) If BitAND($iNotify, 2) <> 0 Then $iFlags = BitOR($iFlags, $TPM_RETURNCMD) Switch $iButtons Case 1 $iFlags = BitOR($iFlags, $TPM_RIGHTBUTTON) Case Else $iFlags = BitOR($iFlags, $TPM_LEFTBUTTON) EndSwitch $aResult = DllCall("User32.dll", "int", "TrackPopupMenu", "hwnd", $hMenu, "int", $iFlags, "int", $iX, "int", $iY, "int", 0, "hwnd", $hWnd, "hwnd", 0) Return $aResult[0] EndFunc ;==>_GUICtrlMenu_TrackPopupMenu func _SendData($hWnd, $sData) local $tCOPYDATA, $tMsg $tMsg = DllStructCreate('char[' & StringLen($sData) + 1 & ']') DllStructSetData($tMsg, 1, $sData) $tCOPYDATA = DllStructCreate('dword;dword;ptr') DllStructSetData($tCOPYDATA, 2, StringLen($sData) + 1) DllStructSetData($tCOPYDATA, 3, DllStructGetPtr($tMsg)) $Ret = DllCall('user32.dll', 'lparam', 'SendMessage', 'hwnd', $hWnd, 'int', $WM_COPYDATA, 'wparam', 0, 'lparam', DllStructGetPtr($tCOPYDATA)) if (@error) or ($Ret[0] = -1) then return 0 endif return 1 endfunc; _SendData Basically, the second script will send message to the first script after it creates context-menu. the first script will detect the window class on mouse over. Anyone has other idea? Edited June 23, 2009 by MDCT Link to comment Share on other sites More sharing options...
MrCreatoR Posted June 23, 2009 Share Posted June 23, 2009 (edited) Try this: expandcollapse popup#include <Constants.au3> #include <WindowsConstants.au3> #include <WinAPI.au3> #include <GUIMenu.au3> #include <Misc.au3> #include <Timers.au3> ; Global $hUser32Dll = DllOpen("User32.dll") Global $iHideMenuDelay = 10 While 1 If _IsPressed("01", $hUser32Dll) Then For $x = 1 To 10 If Not _IsPressed("01", $hUser32Dll) Then ExitLoop Sleep(50) Next If _IsPressed("01", $hUser32Dll) Then _ShowPopupMenu_Proc() Else Sleep(100) EndIf WEnd Func _ShowPopupMenu_Proc() Local $hDlg, $cDummy, $nContextMenu, $hContextMenu, $nHide_MItem, $nExit_MItem, $hTimer, $aMousePos, $nResult $hDlg = GUICreate("", 1, 1, 0, 0, $WS_POPUP, $WS_EX_TOOLWINDOW); Create our temporary GUI $cDummy = GUICtrlCreateDummy(); Create a dummy control to hang a context menu on $nContextMenu = GUICtrlCreateContextMenu($cDummy); Create the context menu $hContextMenu = GUICtrlGetHandle($nContextMenu) $nHide_MItem = GUICtrlCreateMenuItem("Hide", $nContextMenu) $nShowMsg_MItem = GUICtrlCreateMenuItem("Show some message", $nContextMenu) GUICtrlCreateMenuItem("", $nContextMenu) $nExit_MItem = GUICtrlCreateMenuItem("Exit", $nContextMenu) GUISetState(@SW_SHOW, $hDlg) $hTimer = _Timer_SetTimer($hDlg, $iHideMenuDelay, "_CheckHoverMenu_Proc") $aMousePos = MouseGetPos() $nResult = _GUICtrlMenu_TrackPopupMenu($hContextMenu, $hDlg, $aMousePos[0] - 27, $aMousePos[1] - 12, 1, 1, 2) _Timer_KillTimer($hDlg, $hTimer) Switch $nResult Case $nShowMsg_MItem MsgBox(64, 'Title', 'My Message') Case $nHide_MItem ;hm... it's already hidden :D Case $nExit_MItem DllClose($hUser32Dll) Exit EndSwitch GUIDelete($hDlg) EndFunc Func _CheckHoverMenu_Proc($hWnd, $Msg, $iIDTimer, $dwTime) Local $stPoint = DllStructCreate("int X;int Y") Local $aMousePos = MouseGetPos() DllStructSetData($stPoint, "X", $aMousePos[0]) DllStructSetData($stPoint, "Y", $aMousePos[1]) Local $hWndFromPoint = _WinAPI_WindowFromPoint($stPoint) If _WinAPI_GetClassName($hWndFromPoint) <> "#32768" Then Send("{ESC}") EndFunc Edited June 23, 2009 by MrCreatoR Spoiler Using OS: Win 7 Professional, Using AutoIt Ver(s): 3.3.6.1 / 3.3.8.1 AutoIt Russian Community My Work... Spoiler Projects: ATT - Application Translate Tool {new}| BlockIt - Block files & folders {new}| SIP - Selected Image Preview {new}| SISCABMAN - SciTE Abbreviations Manager {new}| AutoIt Path Switcher | AutoIt Menu for Opera! | YouTube Download Center! | Desktop Icons Restorator | Math Tasks | KeyBoard & Mouse Cleaner | CaptureIt - Capture Images Utility | CheckFileSize ProgramUDFs: OnAutoItErrorRegister - Handle AutoIt critical errors {new}| AutoIt Syntax Highlight {new}| Opera Library! | Winamp Library | GetFolderToMenu | Custom_InputBox()! | _FileRun UDF | _CheckInput() UDF | _GUIInputSetOnlyNumbers() UDF | _FileGetValidName() UDF | _GUICtrlCreateRadioCBox UDF | _GuiCreateGrid() | _PathSplitByRegExp() | _GUICtrlListView_MoveItems - UDF | GUICtrlSetOnHover_UDF! | _ControlTab UDF! | _MouseSetOnEvent() UDF! | _ProcessListEx - UDF | GUICtrl_SetResizing - UDF! | Mod. for _IniString UDFs | _StringStripChars UDF | _ColorIsDarkShade UDF | _ColorConvertValue UDF | _GUICtrlTab_CoverBackground | CUI_App_UDF | _IncludeScripts UDF | _AutoIt3ExecuteCode | _DragList UDF | Mod. for _ListView_Progress | _ListView_SysLink | _GenerateRandomNumbers | _BlockInputEx | _IsPressedEx | OnAutoItExit Handler | _GUICtrlCreateTFLabel UDF | WinControlSetEvent UDF | Mod. for _DirGetSizeEx UDF Examples: ScreenSaver Demo - Matrix included | Gui Drag Without pause the script | _WinAttach()! | Turn Off/On Monitor | ComboBox Handler Example | Mod. for "Thinking Box" | Cool "About" Box | TasksBar Imitation Demo Like the Projects/UDFs/Examples? Please rate the topic (up-right corner of the post header: Rating ) * === My topics === * ================================================== ================================================== AutoIt is simple, subtle, elegant. © AutoIt Team Link to comment Share on other sites More sharing options...
MDCT Posted June 23, 2009 Author Share Posted June 23, 2009 (edited) Try this:This is brilliant, MrCreatoR. It works very nice and efficient, just what I wanted. Thank you again for your help.EDIT:I don't understand about $iHideMenuDelay, it doesn't seem to affect the context-menu. Whatever it is, I'm happy with the function. Thanks. Edited June 23, 2009 by MDCT Link to comment Share on other sites More sharing options...
MrCreatoR Posted June 23, 2009 Share Posted June 23, 2009 I don't understand about $iHideMenuDelay, it doesn't seem to affect the context-menuIt affects on the time that needed before next function call (to check the menu hovering). In other words - It's a delay before menu will dissapear Spoiler Using OS: Win 7 Professional, Using AutoIt Ver(s): 3.3.6.1 / 3.3.8.1 AutoIt Russian Community My Work... Spoiler Projects: ATT - Application Translate Tool {new}| BlockIt - Block files & folders {new}| SIP - Selected Image Preview {new}| SISCABMAN - SciTE Abbreviations Manager {new}| AutoIt Path Switcher | AutoIt Menu for Opera! | YouTube Download Center! | Desktop Icons Restorator | Math Tasks | KeyBoard & Mouse Cleaner | CaptureIt - Capture Images Utility | CheckFileSize ProgramUDFs: OnAutoItErrorRegister - Handle AutoIt critical errors {new}| AutoIt Syntax Highlight {new}| Opera Library! | Winamp Library | GetFolderToMenu | Custom_InputBox()! | _FileRun UDF | _CheckInput() UDF | _GUIInputSetOnlyNumbers() UDF | _FileGetValidName() UDF | _GUICtrlCreateRadioCBox UDF | _GuiCreateGrid() | _PathSplitByRegExp() | _GUICtrlListView_MoveItems - UDF | GUICtrlSetOnHover_UDF! | _ControlTab UDF! | _MouseSetOnEvent() UDF! | _ProcessListEx - UDF | GUICtrl_SetResizing - UDF! | Mod. for _IniString UDFs | _StringStripChars UDF | _ColorIsDarkShade UDF | _ColorConvertValue UDF | _GUICtrlTab_CoverBackground | CUI_App_UDF | _IncludeScripts UDF | _AutoIt3ExecuteCode | _DragList UDF | Mod. for _ListView_Progress | _ListView_SysLink | _GenerateRandomNumbers | _BlockInputEx | _IsPressedEx | OnAutoItExit Handler | _GUICtrlCreateTFLabel UDF | WinControlSetEvent UDF | Mod. for _DirGetSizeEx UDF Examples: ScreenSaver Demo - Matrix included | Gui Drag Without pause the script | _WinAttach()! | Turn Off/On Monitor | ComboBox Handler Example | Mod. for "Thinking Box" | Cool "About" Box | TasksBar Imitation Demo Like the Projects/UDFs/Examples? Please rate the topic (up-right corner of the post header: Rating ) * === My topics === * ================================================== ================================================== AutoIt is simple, subtle, elegant. © AutoIt Team Link to comment Share on other sites More sharing options...
MDCT Posted June 24, 2009 Author Share Posted June 24, 2009 It affects on the time that needed before next function call (to check the menu hovering). In other words - It's a delay before menu will dissapear Okay, got that. I tried it between 10 and 100, no wonder it doesn't show any difference.Thanks a lot, man. 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