Sign in to follow this  
Followers 0
Zohar

[Closed] How do I check when a ContextMenu has opened?

15 posts in this topic

#1 ·  Posted (edited)

Hello

When automating another application that has a Form, some Controls, and a Context Menu,

I send a RightClick, and I need to know when the ContextMenu has opened, and to get its Handle.

How can I do that?

Thank you

Edited by Zohar

Share this post


Link to post
Share on other sites



Hello

When automating another application that has a Form, some Controls, and a Context Menu,

I send a RightClick, and I need to know when the ContextMenu has opened, and to get its Handle.

How can I do that?

Thank you

I'm completely familiar with handle getting and whatnot, but I'm pretty sure that if you try to get a handle to a nonexistent context menu, it will return 0. So you could set it up so that it will continue to try to get the handle until it isn't 0.

For those who are asking questions, look in the help file first. I'm tired of people asking stupid questions about how to do things when 10 seconds in the help file could solve their problem.[quote name='JRowe' date='24 January 2010 - 05:58 PM' timestamp='1264381100' post='766337'][quote name='beerman' date='24 January 2010 - 03:28 PM' timestamp='1264372082' post='766300']They already have a punishment system for abuse.[/quote]... and his his name is Valik.[/quote]www.minikori.com

Share this post


Link to post
Share on other sites

well,

First I need to know how to get a Handle of a ContextMenu, when the form is not mine, but a 3rd party's aplication...

How would I do that?

Share this post


Link to post
Share on other sites

how to get a Handle of a ContextMenu

See GUIMenu functions:

#include <GuiMenu.au3>

Run(@WindowsDir & "\Notepad.exe")
WinWait("[CLASS:Notepad]")

$hMainWnd = WinGetHandle("[CLASS:Notepad]")

$hMainMenu = _GUICtrlMenu_GetMenu($hMainWnd)

 

Spoiler

Using OS: Win 7 Professional, Using AutoIt Ver(s): 3.3.6.1 / 3.3.8.1

AutoIt_Rus_Community.png AutoIt Russian Community

My Work...

Spoiler

AutoIt_Icon_small.pngProjects: 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 Program

AutoIt_Icon_small.pngUDFs: 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
 
AutoIt_Icon_small.pngExamples: 
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 AutoIt_Rating.gif)

* === My topics === *

==================================================
My_Userbar.gif
==================================================

 

 

 

AutoIt is simple, subtle, elegant. © AutoIt Team

Share this post


Link to post
Share on other sites

Right,

And it seems to get a Handle,

but when I try to get the MenuItems count, it gives -1 for some reason..

I am using this on MSN Messenger.

If you go to the Tools\Options window,

then choose the "Privacy" Tab, and leave the window open,

and then run this code:

CODE

Local $hWin = WinGetHandle("Options") ;Windows Messenger Options Window

Local $hCon=ControlGetHandle("Options","","[CLASSNN:SysListView322]") ;The Right Listbox(Blocked Users)

ConsoleWrite($hCon & @CRLF)

Local $hMenu = _GUICtrlMenu_GetMenu($hCon)

ConsoleWrite($hMenu & @CRLF)

Local $iMenuItems = _GUICtrlMenu_GetItemCount($hMenu)

ConsoleWrite($iMenuItems & @CRLF)

The first ConsoleWrite, gives a handle. that means I successfully got the Listbox.

The second ConsoleWrite, gives a handle. that means I successfully got the ContextMenu. (tho is it the right menu? maybe there're more)

The last ConsoleWrite, gives me -1 :)

Share this post


Link to post
Share on other sites

This function return the menu from the bar I think not the context menu. I might be wrong though...

Share this post


Link to post
Share on other sites

what do I need to do in order to get the ContextMenu of the ListBox there?

Share this post


Link to post
Share on other sites

#8 ·  Posted (edited)

I don't remember if you should attach to the thread or attach the thread input to your thread and handle the $WM_CONTEXTMENU event message, I might be wrong though, but in theory you can send message to thread if you got a pointer to it's callback message procedure. I still need to test it though so don't count on it.

Edit1: Stupid mistake, if I'm not wrong you won't be notified for this kind of message because you can't take control over the mouse and this kind of eventuation is posted to the message queue of the thread owning the mouse input...

Edit2: The drop menu??? Do you want the context menu or the listbox's drop menu??

Edited by Authenticity

Share this post


Link to post
Share on other sites

no, not dropmenu.

It's a ListBox on a Form, that has a ContextMenu.

But I think this ContextMenu is not solely associated with this ListBox,

becoz there are 2 ListBoxes on that Form, one called "Allow List", and the other called "Block List",

and both those ListBoxes have the same ContextMenu.

You can see the form I'm talking about,

if you go in MSN Messenger(Windows Messenger) to the Tools Menu, choose Options, and choose the Privacy tab.

that's the form, and those are the 2 ListBoxes.

RightClicking on each ListBox, gives the same ContextMenu.

I would really like to get a Handle for this ContextMenu.

and I am getting a handle..

but when I output the MenuItems count in it, I get -1.

so it means something in my code above, is wrong..

Share this post


Link to post
Share on other sites

I attached an Image of that window.

2 ListBoxes,

and a ContextMenu.

post-45260-1232793142_thumb.jpg

Share this post


Link to post
Share on other sites

Excuse me if I'm deviating the subject but what is the purpose of this code section? to modify the listbox's content or to modify the context menu?

Share this post


Link to post
Share on other sites

The purpose of the whole script, is to Clean the ListBox on the Right(Blocked Users).

This list tends to grow over time:

when you delete a person in messenger, it is moved to that Blocked list.

After that user deletes you too, you are able to delete him from the block list.

(If he hasn't deleted you on his side too, then the context menu will show the "Delete" menuitem disabled).

All I want, is to make a simple script that will go over the whole list(ListBox) on the right,

and for every item there:

- RightClick it

- If the "Delete" MenuItem is Enabled, then Delete the user, and pop up a message box, saying that a user was deleted.

(if it's "Delete" menuitem is disabled, then do nothing, and continue to next item in the list box).

This whole script is very simple,

except the fact of catching the ContextMenu that is being opened.

I donno what's wrong with my code, that it outputs -1.. instead of outputting 3, like it should.

CODE

Local $hWin = WinGetHandle("Options") ;Windows Messenger Options Window

Local $hCon=ControlGetHandle("Options","","[CLASSNN:SysListView322]") ;The Right Listbox(Blocked Users)

ConsoleWrite($hCon & @CRLF)

Local $hMenu = _GUICtrlMenu_GetMenu($hCon)

ConsoleWrite($hMenu & @CRLF)

Local $iMenuItems = _GUICtrlMenu_GetItemCount($hMenu)

ConsoleWrite($iMenuItems & @CRLF)

maybe the $hMenu that I am getting is a handle that is not pointing to the right menu..

then how would I get the handle to the correct menu?

Share this post


Link to post
Share on other sites

BTW

a very similar problem to this one, which I haven't solved too,

Is when automating IE:

let's say I open IE,

Navigate to a certain URL which contains a Login page with 2 TextBoxes: Username and Password,

then I focus on the Username TextBox there,

and simulate pressing the {Down} key.

This causes IE to pop up a small listbox containing the stored Usernames(and passwords) for this website.

And I would really like to get a handle to this listbox that pops up,

so I can specifically choose a Username from there.

right now, what I'm doing to workaround this, is Send("{Down}{Down}{Down}") to get to the 3rd username, for example.

but the disadvantage with this workaround, is that If tomorrow a new username&password is stored for this site, the order of the items might change,

and Send("{Down}{Down}{Down}") will not get to the right position in the list..

Share this post


Link to post
Share on other sites

#14 ·  Posted (edited)

Let me first try to explain a non-simple but possible way for the SysListView32 thing and I'll then try to read your IE issue :)

What you should try is to make a small procedure called upon, say, mouse click that use WinGetHandle for the parent window then if you got a valid handle use EnumChildWindows API with this handle (use DllCallbackRegister first, then use DllCallbackGetPtr for the EnumChildWindows func) then for each child window get it's class name using GetClassName API and it's window text using GetWindowText and preform some check to see if there is a match.

At last, send a message to this control like $LVM_DELETEALLITEMS and nothing should remain there I believe, but probably your problem isn't resolved yet because I think if the program keeps this information on a registry key or server it'll just make some esthetical action, nothing really useful...

Edited by Authenticity

Share this post


Link to post
Share on other sites

Let me first try to explain a non-simple but possible way for the SysListView32 thing and I'll then try to read your IE issue :)

What you should try is to make a small procedure called upon, say, mouse click that use WinGetHandle for the parent window then if you got a valid handle use EnumChildWindows API with this handle (use DllCallbackRegister first, then use DllCallbackGetPtr for the EnumChildWindows func) then for each child window get it's class name using GetClassName API and it's window text using GetWindowText and preform some check to see if there is a match.

At last, send a message to this control like $LVM_DELETEALLITEMS and nothing should remain there I believe, but probably your problem isn't resolved yet because I think if the program keeps this information on a registry key or server it'll just make some esthetical action, nothing really useful...

But there's no SysListView32 here:)

In the Messenger example, there's a ListBox that pops up a ContextMenu.

In the IE Login Page example, there's a TextBox that pops up a ListBox.

in both cases, a control pops up a floating control for letting the user choose an option.

and this "floating" control is what I am trying to catch.

so I can then interact with it.

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  
Followers 0