Jump to content
Sign in to follow this  
IanN1990

Breaking Main Loop when context menu is shown.

Recommended Posts

IanN1990

This code is taken from the help file to show my question

#include <GUIConstantsEx.au3>
#include <ButtonConstants.au3>

Example1()

; ****************
; * First sample *
; ****************
Func Example1()
;right click on gui to bring up context Menu.
;right click on the "ok" button to bring up a controll specific context menu.

GUICreate("My GUI Context Menu", 300, 200)

Local $contextmenu = GUICtrlCreateContextMenu()

Local $button = GUICtrlCreateButton("OK", 100, 100, 70, 20)
Local $buttoncontext = GUICtrlCreateContextMenu($button)
GUICtrlCreateMenuItem("About button", $buttoncontext)

Local $newsubmenu = GUICtrlCreateMenu("new", $contextmenu)
GUICtrlCreateMenuItem("text", $newsubmenu)

GUICtrlCreateMenuItem("Open", $contextmenu)
GUICtrlCreateMenuItem("Save", $contextmenu)
GUICtrlCreateMenuItem("", $contextmenu) ; separator

GUICtrlCreateMenuItem("Info", $contextmenu)

GUISetState()

; Run the GUI until the dialog is closed
While 1
ConsoleWrite("A") ;To Show If the script is running
Local $msg = GUIGetMsg()

If $msg = $GUI_EVENT_CLOSE Then ExitLoop
WEnd
GUIDelete()
EndFunc ;==>Example1

When no context menu is shown, the loop is happly running "shown by the army of A's" but as soon as soon as you right click "to show the context menu". It pauses until the menu disappears ?

Is there any way around this the menu can be shown and the main loop can continue ??

;AdlibRegister Only seams to take effect when the mouse is moved

;My current work around is to put the context menu in a different .au3 and have the main script run it "so it gets it own process / thread".

**Edit to enclude includes. Donno why google chrome keeps removing them

Edited by IanN1990

Share this post


Link to post
Share on other sites
JohnOne

I never knew a context menu had that effect, I would not have expected it to be script blocking

until a function resulting from a click were initiated.

But I suppose once right click, the added autoit function is in fact initiated.


AutoIt Absolute Beginners    Require a serial    Pause Script    Video Tutorials by Morthawt   ipify 

Monkey's are, like, natures humans.

Share this post


Link to post
Share on other sites
czardas

Menus normally wait for the user to select the next task. The loop get's interrupted (I guess) because the user quite often wishes to interfere with the current processing by clicking a menu item (pause, quit, resume). Perhaps this isn't true in all cases, however (if not otherwise interrupted by clicking a menu item) the current processing operation resumes after the user closes the menu. I'm sure it's possible to change the default behaviour, but why would you want to do that?

Edited by czardas

Share this post


Link to post
Share on other sites
IanN1990

Its hard to explain without posting my whole script, which is over 1,200 lines and buggy atm. So i will do my best to break it down into suedo code.

-Varaibles

-MouseHook

While 1

-Alots of different IF checks for different things like screen dimming / mouse location /

wend

MouseHook

If Right-Click

If Mouse Over Desktop = Run Context Menu

End Hook

Conext menu Code

So thats how its kinda all layed out, but i dont want my whole system script to freeze when the menu comes up, which is why atm the context menu code is in a different .au3.

I was hoping to find a way to merge it all into my main script as i dont like the idea of having lots of different .au3 scattered over the system.

Another Example of why someone might not want a broken loop.

Screen Saver

Right click to show a context menu - Loop is frozen so the screen saver animations would stop until the context menu is released.

I'm not working on this, but i thought it was a good example

Edited by IanN1990

Share this post


Link to post
Share on other sites
czardas

Yes I understand this, which is why I said not always. A video player would also be a good example. I think the trick is to spawn a new process, but I'm not sure what the best approach would be. That will depend on the type of process you wish to leave running. Although I haven't tested this, SoundPlay will play a sound file and you have the option to wait until the sound file has finished, or continue running the script during playback. I imagine these are independant processes outside of any loop. Someone with more experience will probably be able to tell you if I'm right or not.

A thought just occured to me. You could create a custom menu and poll it within the main loop. It sounds complicated to me, but it should be possible. Using a windows message command when the menu is clicked is also a possibility.

Edited by czardas

Share this post


Link to post
Share on other sites
BrewManNH

If the context menu is blocking execution of the script, then fake it by using a pop-up window instead of a context menu, then you have total control over what happens in the back ground while this window is popped up.


If I posted any code, assume that code was written using the latest release version unless stated otherwise. Also, if it doesn't work on XP I can't help with that because I don't have access to XP, and I'm not going to.
Give a programmer the correct code and he can do his work for a day. Teach a programmer to debug and he can do his work for a lifetime - by Chirag Gude
How to ask questions the smart way!

I hereby grant any person the right to use any code I post, that I am the original author of, on the autoitscript.com forums, unless I've specifically stated otherwise in the code or the thread post. If you do use my code all I ask, as a courtesy, is to make note of where you got it from.

Back up and restore Windows user files _Array.au3 - Modified array functions that include support for 2D arrays.  -  ColorChooser - An add-on for SciTE that pops up a color dialog so you can select and paste a color code into a script.  -  Customizable Splashscreen GUI w/Progress Bar - Create a custom "splash screen" GUI with a progress bar and custom label.  -  _FileGetProperty - Retrieve the properties of a file  -  SciTE Toolbar - A toolbar demo for use with the SciTE editor  -  GUIRegisterMsg demo - Demo script to show how to use the Windows messages to interact with controls and your GUI.  -   Latin Square password generator

Share this post


Link to post
Share on other sites
IanN1990

@CZardas

I was thinking, your orginal idea of spawning a new process. Isn't that what i already have at the moment, when i have main.au3 calling context.au3 so they each have their own processes and for your edited idea. he only two ways i know of making a context menu are listed below, and both lock up the main script.

@BrewManNH What do u mean by faking it with a popup window ?

_GUICtrlMenu_TrackPopupMenu - Was the first way i learnt of making context menus, this locks up when you reach the line and only carrys on when a menu is clicked. Didn't provide enough information. So i then moved onto the following.

#NoTrayIcon
#Include "GuiMenu.au3"
local $ContextMenu = GUICreate('',0, 0, 0, 0, -2147483648, 128)
Local $tStruct=DllStructCreate("struct;long X;long Y;endstruct")
local $FileName

$hM_Module = DllCall("kernel32.dll", "hwnd", "GetModuleHandle", "ptr", 0)
DllCall("user32.dll", "hwnd", "SetWindowsHookEx", "int", 14, "ptr", DllCallbackGetPtr(DllCallbackRegister("MouseHook", "int", "int;ptr;ptr")), "hwnd", $hM_Module[0], "dword", 0)

$MainContextMenu = GUICtrlCreateContextMenu()
GUICtrlCreateMenuItem("Scan", $MainContextMenu)
GUICtrlCreateMenuItem("Copy", $MainContextMenu)
GUICtrlCreateMenuItem("Rename", $MainContextMenu)
GUICtrlCreateMenuItem("Delete", $MainContextMenu)
GUICtrlCreateMenuItem("Properties", $MainContextMenu)

AdlibRegister("MenuCheck")
GUIRegisterMsg(287, "MenuHook")
ControlClick("", "", $ContextMenu, "Right", 1, 0, 0)

While WinExists($ContextMenu)
sleep(250)
ConsoleWrite("Main Loop" & @CRLF)
WEnd

Func MenuCheck() ;Is only able to run because of mouse hook
   $MenuPosCheck = Mousegetpos()
   DllStructSetData($tStruct, 'x', $MenuPosCheck[0])
   DllStructSetData($tStruct, 'y', $MenuPosCheck[1])
   If Not(_WinAPI_GetClassName(_WinAPI_WindowFromPoint($tStruct)) = "#32768") Then
 ConsoleWrite("Mouse is no longer over Context Menu")
 GUIDelete($ContextMenu)
   EndIf
EndFunc

Func MouseHook($nCode, $wParam, $lParam)
   If $wParam = 0x207 then ControlSend("[Class:#32768]", "", "", "{Enter}")
EndFunc

Func MenuHook($hWnd, $Msg, $wParam, $lParam)
   If Not $lParam Then
 ConsoleWrite("File Clicked Is: " & $FileName & @crlf)
 GUIDelete($ContextMenu)
   Else   
   $wParam = BitAND($wParam, 0xFFFF)
   $FileName = _GUICtrlMenu_GetItemText($lParam, $wParam, False)
   ConsoleWrite("File Hovered At Mouse: " & $FileName & @CRLF)
   EndIf
EndFunc

The AdlibRegister only register's when the mouse is moved "though as its only used to detect when the mouse is not over the context menu that works out to my advantage in this instance.

MenuHook Procs each time a new Folder / item is highlighted and clicked. I very much do need this regesiter for the rest of the code to work, as it scans folders as you go down the tree and records as you go. Eg Documents/Work/Autoit/Script.au3 "if i was to click script.au3, its recorded the path and then executes it, much better then before when i got the name and searched the directory for it."

So do you think ethier your ideas would allow this level of functionally while letting the while loop run ? "So i can move this out of a separate .au3 and merge into the main script.

Edited by IanN1990

Share this post


Link to post
Share on other sites
czardas

I'm not familiar enough with the method you are attempting to use. I still think it should be possible, but perhaps BrewmanNH's idiea would be easier to implement. Create a child window disguised as a menu. Set a flag to True when the menu is showing. Poll the child GUI from within the loop (only) when the flag is True. If the user clicks the menu, then destroy the child GUI and set the flag to False. Alternatively you could show or hide the child GUI menu.

Edit

I just tried some standard menus and failed to override their default behaviour. So what is this process you can't interrupt? That information may help to solve this.

Edited by czardas

Share this post


Link to post
Share on other sites
IanN1990

I have edited my last post with some improved code, so its more a very much so condensed example of the full script "which is over 300 lines".

As things stand at the moment, the process i am talking about is like this. I have my Main script "which is complied into a .exe". That runs all the time, when i right click the desktop it then runs the script shown "which is complied into its own .exe". So at the same time i have the System.exe Running and ContextMenu.exe running. This way the main script can loop without getting blocked by the context menu, as it has its own process. Once the context menu has finished "ethier by the mouse leaving the Menu or a menu item being clicked, it would carry out that action and then kill itself so the process ends".

Now i want to merge the context menu script into the main script, but that means finding away around the "context menu" preventing the main loop from running.

I will admit GUIs are not my strong suite. Infact the only two GUI projects sense i joined autoit, one is this context menu and the other is a console display "

So i dont have much of an idea where to start when you say "Create a child window disguised a menu". As to me that sounds like

Make a GUI - Display a context menu then poll it, but the only two ways I know of making context menus are as shown above but both lock up the main script.

Share this post


Link to post
Share on other sites
BrewManNH

What is it that you're running that can't be blocked by the context menu? Is it really necessary for it to run non-stop if you're using the menu, what is in this context menu that isn't necessary to the rest of the script that makes it so that it can't interrupt the main script but is still useful?


If I posted any code, assume that code was written using the latest release version unless stated otherwise. Also, if it doesn't work on XP I can't help with that because I don't have access to XP, and I'm not going to.
Give a programmer the correct code and he can do his work for a day. Teach a programmer to debug and he can do his work for a lifetime - by Chirag Gude
How to ask questions the smart way!

I hereby grant any person the right to use any code I post, that I am the original author of, on the autoitscript.com forums, unless I've specifically stated otherwise in the code or the thread post. If you do use my code all I ask, as a courtesy, is to make note of where you got it from.

Back up and restore Windows user files _Array.au3 - Modified array functions that include support for 2D arrays.  -  ColorChooser - An add-on for SciTE that pops up a color dialog so you can select and paste a color code into a script.  -  Customizable Splashscreen GUI w/Progress Bar - Create a custom "splash screen" GUI with a progress bar and custom label.  -  _FileGetProperty - Retrieve the properties of a file  -  SciTE Toolbar - A toolbar demo for use with the SciTE editor  -  GUIRegisterMsg demo - Demo script to show how to use the Windows messages to interact with controls and your GUI.  -   Latin Square password generator

Share this post


Link to post
Share on other sites
IanN1990

truth be told. I might be able to get away with having the context menu in the main script even though it would block it.

So it might be able to get away with it, but it could add alot of bugs downs / make things unstable. In which case i would rather keep the two things separated.

Main reason i am looking into this, is to see if there is a way it could be done. As its nicer to keep everything in one place, rather then .au3s littered over the place and because it means total overall lines of code is reduced. "Main script has a mousehook, Context menu needs a mouse hook. If they are both in the same script, they can share the same mouse hook :D"

Edited by IanN1990

Share this post


Link to post
Share on other sites
JohnOne

I think it's been established that having a context menu in your script will block it.

So you can keep it how it is with two processes, or you can imagine a gui which

emulates, what your context menu does, bearing in mind that your script will still

be blocked while any functions triggered by your fake context menu are carried out.

You can explain your script in million words, but I think we get the idea, it gets blocked.

I'd stick to two processes if one needs not to be blocked, I don't see the big deal.

Your main script starts the other, the other shuts down if your main does not exist.

If you want to take it further then store the second as a resource and execute it from

memory (overkill)


AutoIt Absolute Beginners    Require a serial    Pause Script    Video Tutorials by Morthawt   ipify 

Monkey's are, like, natures humans.

Share this post


Link to post
Share on other sites
czardas

Perhaps you could make things easier by redesigning the main script to exclude any processes which must not be blocked. So the screen dimmer should have it's own process and will never be affected by the menu Tools > Run > Screen > Auto > Something (Run external script).

Edited by czardas

Share this post


Link to post
Share on other sites
BrewManNH

None of the things you're doing while the script is running seems to have any need to be monitored while the menu is open, after all a context menu is designed to take you away from the things you're doing in the windows and focuses on the menu to allow you to click on an entry. If you right click on a Windows Explorer listing, you can't then go to another folder while the menu is open. As soon as you do, that menu closes and you have to right click again. If you're moving the mouse around to do other things while the context menu is open, you're using it wrong. If there are processes in the background that need to monitor where your mouse is and alter something while the context menu is open, you're doing something wrong in how you're executing the processes.


If I posted any code, assume that code was written using the latest release version unless stated otherwise. Also, if it doesn't work on XP I can't help with that because I don't have access to XP, and I'm not going to.
Give a programmer the correct code and he can do his work for a day. Teach a programmer to debug and he can do his work for a lifetime - by Chirag Gude
How to ask questions the smart way!

I hereby grant any person the right to use any code I post, that I am the original author of, on the autoitscript.com forums, unless I've specifically stated otherwise in the code or the thread post. If you do use my code all I ask, as a courtesy, is to make note of where you got it from.

Back up and restore Windows user files _Array.au3 - Modified array functions that include support for 2D arrays.  -  ColorChooser - An add-on for SciTE that pops up a color dialog so you can select and paste a color code into a script.  -  Customizable Splashscreen GUI w/Progress Bar - Create a custom "splash screen" GUI with a progress bar and custom label.  -  _FileGetProperty - Retrieve the properties of a file  -  SciTE Toolbar - A toolbar demo for use with the SciTE editor  -  GUIRegisterMsg demo - Demo script to show how to use the Windows messages to interact with controls and your GUI.  -   Latin Square password generator

Share this post


Link to post
Share on other sites
IanN1990

Alot of fair comments, and from the sounds of it. i would be best just leaving things how they are. Having the main script calling the context menu script, keeping things separate so they can run independent of each other.

Share this post


Link to post
Share on other sites
AoRaToS

I came across the same issue while working on the LAN Messenger I've made. While a context menu is open the messages someone sends you don't come through and open a window, however once the context menu closes the messages that were sent while it was open come through so I decided I can live with it, it's not a big deal :)

I would say the GUI way is easy to do and will keep your script cleaner than having 2 separate scripts however it's your choice at the end of the day!


s!mpL3 LAN Messenger

Current version 2.9.8.8 [30/09/2015]

Download Here

s!mpL3

Share this post


Link to post
Share on other sites
LarsJ

A little late but the solution is simple. Just remove the modeless style of the context menu.

Include GuiMenu.au3 in the code in the first post

and replace this line:

Local $contextmenu = GUICtrlCreateContextMenu()

with these three lines:

Local $contextmenu = GUICtrlCreateContextMenu()

Local $hCM = GUICtrlGetHandle( $contextmenu )

_GUICtrlMenu_SetMenuStyle($hCM, BitXOR(_GUICtrlMenu_GetMenuStyle($hCM), $MNS_MODELESS))

The A's will keep printing when you activate the context menu.

  • Like 1

Share this post


Link to post
Share on other sites
IanN1990

Very Cleaver Idea LarsJ, it works nicely :)

Share this post


Link to post
Share on other sites

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 account

Sign in

Already have an account? Sign in here.

Sign In Now
Sign in to follow this  

×