autoit3 - trigger context menu to open on button click/press - autoit

I am working on a project, in which I decided I should have history of previously searched stuff (since it's an app with which you can search stuff), so I have been thinking that I could just create the context menu or regular menu, that I could somehow force to activate on a button click or by using accelerators.
Now, I haven't been able to figure out how to make that work.
First I tried the GuiCtrlSetState() function, which didn't seem to work (I tried show and focus), then I tried accelerators and they didn't do anything.
So I'm wondering is there any way I can make the context menu or regular menu pop up on button press/click or key press (with accelerators)?
So what I'm basically trying to do is some sort of a pop-up, you click on a button or press a key to trigger the context menu or regular menu to open.
I know I could be old school and use a new GUI or just a combo box for the history or anything but I kinda want this, if there's any way to do so.
Any help, or an alternative way of doing the same thing appreciated.
Here's the testing code in which I was trying to make the test button trigger and activate the context menu, and I have tried the same with the regular
menu: 
#NoTrayIcon
#include <GUIConstantsEx.au3>
GUICreate("test123")
$but = guictrlcreatebutton("test", -1, -1, -1)
$xt = GUICtrlCreateContextMenu("test context menu")
GUICtrlCreateMenuItem("test1", $xt)
GUICtrlCreateMenuItem("test2", $xt)
GUISetState(#SW_MAXIMIZE)
While 1
$msg = GUIGetMsg()
If $msg = $but Then
GUICtrlSetState($xt, $GUI_FOCUS)
EndIf
Sleep(5)
WEnd

If you check the help file under GUICtrlCreateContextMenu:
; right click on gui to bring up context Menu.
; right click on the "ok" button to bring up a controll specific context menu.
#include <ButtonConstants.au3>
#include <GUIConstantsEx.au3>
#include <MsgBoxConstants.au3>
Example()
Func Example()
GUICreate("My GUI Context Menu", 300, 200)
Local $idContextmenu = GUICtrlCreateContextMenu()
Local $idNewsubmenu = GUICtrlCreateMenu("new", $idContextmenu)
Local $idNewsubmenuText = GUICtrlCreateMenuItem("text", $idNewsubmenu)
Local $idButton = GUICtrlCreateButton("OK", 100, 100, 70, 20)
Local $idButtoncontext = GUICtrlCreateContextMenu($idButton)
Local $idMenuAbout = GUICtrlCreateMenuItem("About button", $idButtoncontext)
Local $idMenuOpen = GUICtrlCreateMenuItem("Open", $idContextmenu)
Local $idMenuSave = GUICtrlCreateMenuItem("Save", $idContextmenu)
GUICtrlCreateMenuItem("", $idContextmenu) ; separator
Local $idMenuInfo = GUICtrlCreateMenuItem("Info", $idContextmenu)
GUISetState(#SW_SHOW)
; Loop until the user exits.
While 1
Switch GUIGetMsg()
Case $GUI_EVENT_CLOSE
ExitLoop
Case $idButton
MsgBox($MB_SYSTEMMODAL, "Button Clicked", 'OK')
Case $idMenuAbout
MsgBox($MB_SYSTEMMODAL, "Menu Selected", 'About')
Case $idMenuOpen
MsgBox($MB_SYSTEMMODAL, "Menu Selected", 'Open')
Case $idMenuSave
MsgBox($MB_SYSTEMMODAL, "Menu Selected", 'Save')
Case $idMenuInfo
MsgBox($MB_SYSTEMMODAL, "Menu Selected", 'Info')
Case $idNewsubmenuText
MsgBox($MB_SYSTEMMODAL, "SubMenu Selected", 'Text')
EndSwitch
WEnd
GUIDelete()
EndFunc ;==>Example

Related

How to open the browser in collapsed form?

The code:
Local $iPID=ShellExecute("C:\Program Files\Mozilla Firefox\firefox.exe", "","","", #SW_MINIMIZE);
How to open the browser in collapsed form?
; Optional debugging feature.
Opt('TrayIconDebug', True)
; Run Firefox if not running.
If Not ProcessExists('firefox.exe') Then
ShellExecute('"C:\Program Files\Mozilla Firefox\firefox.exe"')
EndIf
; Wait for a window to match the class.
WinWait('[CLASS:MozillaWindowClass]')
$hFirefox = 0
$iAbort = 5
Do
Sleep(1000)
; Get all class windows into an array.
$aWList = WinList('[CLASS:MozillaWindowClass]')
For $i1 = 1 To UBound($aWList) -1
; Get the visible window from the window handle.
If BitAND(WinGetState($aWList[$i1][1]), 2) Then
$hFirefox = $aWList[$i1][1]
_WinState($aWList[$i1][1], $aWList[$i1][0], True)
ExitLoop 2
Else
_WinState($aWList[$i1][1], $aWList[$i1][0], False)
EndIf
Next
$iAbort -= 1
Until Not WinExists('[CLASS:MozillaWindowClass]') Or $iAbort = 0
; Minimize the visible window.
If WinSetState($hFirefox, '', #SW_MINIMIZE) Then
ConsoleWrite('A Firefox window has been minimized.' & #CRLF)
EndIf
Exit
Func _WinState($hWinHandle, $sWinTitle, $bWinVisible = False)
; Debug output for visible state of a window.
Local $sWinVisible = $bWinVisible ? 'True' : 'False'
ConsoleWrite(StringFormat('Handle: %s Visible: %-5s Title: %s', $hWinHandle, $sWinVisible, $sWinTitle) & #CRLF)
EndFunc
Even if you set a Firefox shortcut to minimize and use it
to start Firefox, Firefox may not minimize at startup.
This is why the show flag of #SW_MINIMIZE for the
ShellExecute function may not work.
A -tray argument exists though I cannot get it to work as
mentioned in Command Line Options.
To minimize at startup, the code provided may help.
It will find the 1st window that is visible of the class
MozillaWindowClass, and will attempt to minimize it.
The variable $hFirefox may contain the handle of the
visible Firefox window which can be used after the Do
loop has complete.
Some code is optional, i.e. _WinState() is used to output
debug information to console to know if the the window search
for the visible window is working OK.

If statement not working AutoIT

I am having trouble with the code I am writing. I have a table which lists staff member details. I am trying to have an email address copy to the clipboard when you select a record and right click. I have the following code:
#include <GUIConstantsEx.au3>
#include <mssql.au3>
#include <MsgBoxConstants.au3>
#include <Array.au3>
#include <WindowsConstants.au3>
#include <AutoItConstants.au3>
global $title = "E-Mail address lookup"
global $name = InputBox($title,"Please type the name of the person you wish to find")
global $sqlCon = _MSSQL_Con("server", "username", "password", "directory-plus")
global $result = _MSSQL_GetRecord($sqlCon, "autoit_view","*", "WHERE cn LIKE '%" & StringStripWS($name,3) & "%'")
if StringLen(StringStripWS($name,3)) < 1 then
MsgBox(0, $title, "Name cannot be empty")
Else
Global $rset = UBound($result) - 1
Global $ControlID = GUICreate($title, 500, 150)
Global $idListview = GUICtrlCreateListView("Deparment|E-Mail Address|Name|Telephone Number", 10, 10, 480, 150)
for $count = 1 to $rset step 1
GUICtrlCreateListViewItem($result[$count][0] & "|" & $result[$count][2] & "|" & $result[$count][1] & "|" & $result[$count][2], $idListview)
if MouseClick($MOUSE_CLICK_RIGHT)==1 Then
ClipPut($result[$count][2])
EndIf
Next
GUISetState(#SW_SHOW)
GUISetState()
While 1
Global $Msg = GUIGetMsg()
Switch $Msg
Case -3, $ControlID
Exit
EndSwitch
WEnd
EndIf
I would have thought my IF statement within the for loop would do the trick but, when I run my code, it just copies whatever is in email address column in the last row when in fact I want it to copy the email address when you right click on a particular row but I'm not sure how to do it.
Your code has two major problems. The first is that MouseClick() doesn't check for the mouse button being pressed, but instead sends a mouse button click. Since sending a mouse button click is going to succeed, MouseClick($MOUSE_CLICK_RIGHT)==1 will evaluate to true. For each list view item you create, you are putting the email address on the clipboard.
The second problem is that the if statement is in the wrong place. It's executed just after you create each list view item.
Instead, change your While statement as follows
While 1
Global $Msg = GUIGetMsg()
Switch $Msg
Case -3, $ControlID
Exit
case $GUI_EVENT_SECONDARYDOWN
$selecteditem=StringSplit(GUICtrlRead(GUICtrlRead($idListview)),"|")
if #error=0 and $selecteditem[0]>1 Then
ClipPut($selecteditem[2])
EndIf
EndSwitch
WEnd

AutoIT WinWaitActive doesn't uderstands that window is active

I want to get pixel color from a game and react.
So I have this sript:
#include <Color.au3>
Local $pause = False;
$WinName = "Game" ; Let's say there is a game with this name =)
$hwnd = WinGetHandle($WinName) ; Checked handle with powershell and Au3Info, handle is correct
local $res
Opt("PixelCoordMode", 2);
HotKeySet("{F10}", "exitNow");
HotKeySet("{F11}", "Pause");
While 1
;WinWaitActive($hwnd) ; The script stops here if it is uncommented no matter if window is active or not
if ( $pause ) Then
$res = GetPos();
ConsoleWrite ( StringFormat ("Result color: %s %s", $res[0], $res[1] ) )
Sleep (1000)
EndIf
WEnd
Func exitNow()
Exit
EndFunc
Func Pause()
$pause = Not $pause
EndFunc
Func GetPos()
local $var = Hex(PixelGetColor(5, 5, $hwnd)) ; Only works in windowed mode, FullScreen return some random colors like 00FFFFFF or 00AAAAAA
$var = StringTrimLeft($var,2) ; Removing first 2 numbers they r always 00
local $var1 = Hex(PixelGetColor(15, 5, $hwnd)) ; Only works in windowed mode, FullScreen return some random colors like 00FFFFFF or 00AAAAAA
$var1 = StringTrimLeft($var1,2) ; Removing first 2 numbers they r always 00
local $result[2] = [ $var, $var1 ]
return $result
EndFunc
Main script should before window is active and only then should try to GetPixelColor but that never happens, no matter what I do, i've tried WindowActivate still no result.
a) - What am I doing wrong ? Or may be there is another way to check if window is currently active ?
So at the moment I start script disabled, and when I activate window manually I press F11 to enable.
b) - PixelGetColor only works if game is running in Windowed mode, if it's a fullscreen mode result is unpredictable. Is there a way to make PixelGetColor work in fullscreen.
I've tried to run game x32, x64, DX9 and DX11 in different combinations Fullscreen result is just wrong.
ADDED:
Now While looks like this and that works :)
Thanks to Xenobeologist!!!
While 1
$hwnd = WinGetHandle('[Active]');
If ( $pause ) Then
If WinGetTitle($hwnd) <> $WinName Then
Pause()
ContinueLoop
EndIf
$res = GetPos();
ConsoleWrite ( StringFormat ("Result color: %s %s", $res[0], $res[1] ) )
Sleep (1000)
Else
If WinGetTitle($hwnd) = $WinName Then
Pause()
ContinueLoop
EndIf
EndIf
WEnd
a) is now solved
b) is still not solved. One more thing, topic of this question doesn't say anything bout this question, should add info bout this into the topic or it's better to start a new thread? a) was my main question, it would be prefect to solve b) as well but I can live without it. As far as I understood it's much more complicated. What do you think?
ADDED2:
As far as I understand problem b) can be solved by using more complex code. Here http://www.autohotkey.com/board/topic/63664-solved-imagesearch-failure-wdirectx-fullscreen-gamewin7/ was discussed pretty same problem. It's AHK and ImageSearch function, but im pretty sure that the reason I get wrong colours in fullscreen is the same. I don't want to complicate code that much and PrintScreen is too slow so I'll use windowed mode and wont be bothering with b).
Does this help?
#include <MsgBoxConstants.au3>
$handle = WinGetHandle('[Active]')
ConsoleWrite('!Title : ' & WinGetTitle($handle) & #CRLF)
ConsoleWrite('!Process : ' & WinGetProcess($handle) & #CRLF)
ConsoleWrite('!Text : ' & WinGetText($handle) & #CRLF)
Sleep(Random(10, 3000, 1))
If WinActive($handle) Then MsgBox($MB_SYSTEMMODAL, "", "WinActive" & #CRLF & "Scite ")

Autoit: Creating a Function?

I have a GUI that records the list of all the chm in a folder. When 'RUN' button is clicked, it will open the first chm in the list until so on. Then I have created a function that should expand the tree.
My problem is my function, it works until MsgBox() and stops there. When I ran my program there is no error indicated.
#include <GuiConstantsEx.au3>
#include <GuiListBox.au3>
#include <GuiTreeView.au3>
#include <File.au3>
#include <Array.au3>
;GUI
$guiTitle = "Automation"
GUICreate($guiTitle, 250, 430)
Global $hWnd = ControlGetHandle("[CLASS:HH Parent;TITLE:AutoIt Help]", "", "[CLASS:SysTreeView32; INSTANCE:1]")
Global $hChild = _GUICtrlTreeView_GetFirstChild($hWnd, 0)
Local $source = InputBox("Source Folder","Please enter the source folder","")
;InputBox
If #error = 1 Then
Exit
EndIf
If #error = 4 Then
Exit
;GUI_List
Else
$add = GUICtrlCreateButton("Show", 10, 53, 230, 20)
$picList = GUICtrlCreateList("", 10, 78, 230, 300)
$run = GUICtrlCreateButton("Run", 170, 385, 70, 30)
GUISetState(#SW_SHOW)
While 1
$msg = GUIGetMsg()
Switch $msg
;add
Case $add
Global $FileList = _FileListToArray($source, "*.chm")
If #error = 1 Then
MsgBox(0, "", "No Files Found.")
Exit
EndIf
If #error = 4 Then
MsgBox(0, "", "No Files Found.")
Exit
EndIf
For $i = 1 To $FileList[0] ;List_IFIX Pictures
GUICtrlSetData($picList, $FileList[$i])
Next
;run
Case $run
If _GUICtrlListBox_GetCount($picList) = 0 Then
MsgBox(0, "", "No Files Found.")
Else
For $i = 1 To $FileList[0]
If Not WinExists("AutoIT Help]") Then
ShellExecute($source & "\" & $FileList[1])
_Expand($hWnd, $hChild)
EndIf
Next
EndIf
;exit
Case $GUI_EVENT_CLOSE
ExitLoop
EndSwitch
WEnd
EndIf
And here is my function:
Func _Expand($hWnd, $hChild)
WinWaitActive("AutoIT Help")
MsgBox(0,"","Expand")
While 1
$hChild = _GUICtrlTreeView_GetNextChild($hWnd, $hChild)
If _GUICtrlTreeView_GetText($hWnd, $hChild) = "Tutorials" Then ExitLoop
WEnd
_GUICtrlTreeView_Expand(ControlGetHandle("[CLASS:HH Parent;TITLE:AutoIt Help]","", "[CLASS:SysTreeView32; INSTANCE:1]"),$hchild, True)
EndFunc
Lots of problems with the code.
Check your titles! In two cases you have got the window title spelt incorrectly in your example. AutoIt is spelt with a lowercase t, and window title matching is case sensitive unless you set an option otherwise.
If "Tutorials" is not found then you will loop forever. You should add a check after _GUICtrlTreeView_GetNextChild to see if you've reached the end of the treeview.
But the real problem with your code is that you are setting $hWnd and $hChild at the beginning of the code, before you run the process that creates the window. As a result, the window is not found, and so $hWnd will always be NULL when you call _Expand.
This sort of question is not encouraged on stackoverflow. We like questions which will be useful to other people in the future rather than help with specific code. Before asking questions like this in the future, please try and debug the problem yourself. You could add ConsoleWrite statements through the code showing variable values, which would have shown you that $hWnd didn't have a handle value when you enter expand, from there it is obvious.

Autoit dead loop problem

In SSMS (SQL Server Management Studio), you have to middle-click the tab or press Ctrl+F4 to close the current editor tab. I want to use Autoit to make a shortcut Ctrl+w do the same thing. But I have problem with it. The following is the code. What I thought is, when the user press Ctrl+w, check if the user is in SSMS, if so, send Ctrl+F4 to close the current tab, if not, send Ctrl+w to let it go as normal. But the point is, if you send Ctrl+w, it will be captured again by Autoit, so dead loop occurs. I can't find a way to solve this problem. Anyone can help me with it?
Thanks.
HotKeySet("^w", "close_ssms_editor")
While 1
Sleep(200)
WEnd
; using Ctrl + w to close
; * editors in SSMS
; * editors in SSMS through Royal TS
Func close_ssms_editor()
$window_class_name = get_window_class_name(WinGetHandle(""))
If $window_class_name = "wndclass_desked_gsk" or $window_class_name = "WindowsForms10.Window.8.app.0.218f99c" Then
Send("^{F4}")
Else
Send("^w")
EndIf
EndFunc
Func get_window_class_name($nCtrl)
If Not IsHWnd($nCtrl) then $nCtrl = HWnd($nCtrl)
Local $struct = DllStructCreate("char[128]"),$classname = 0
$ret = DllCall("user32.dll","int","GetClassName","hwnd",$nCtrl,"ptr",DllStructGetPtr($struct),"int",DllStructGetSize($struct))
If IsArray($ret) Then
$classname = DllStructGetData($struct,1)
While (StringIsDigit(StringRight($classname,1)))
$classname = StringTrimRight($classname,1)
WEnd
EndIf
$struct =0
Return $classname
EndFunc
I found the solution.
; using Ctrl + w to close
; * editor in SSMS
; * editor in SSMS through Royal TS
Func close_ssms_editor()
$window_class_name = get_window_class_name(WinGetHandle(""))
If $window_class_name = "wndclass_desked_gsk" or $window_class_name = "WindowsForms10.Window.8.app.0.218f99c" Then
Send("^{F4}")
Else
HotKeySet("^w")
Send("^w")
HotKeySet("^w", "close_ssms_editor")
EndIf
EndFunc

Resources