Jump to content

Get Context menu handle from control.


Mat
 Share

Recommended Posts

Basically, I'm looking for a simple way to get any info about the context menu (Id, handle etc.) from the control. This is so I can have one function (using GUICtrlSetOnEvent) to make that controls context menu popup on primary click (edit: Using TrackPopupMenu). A switch statement would do the job, but I know that theres got to be a way.

#include <GUIMenu.au3>

Opt ("GUIOnEventMode", 1)

GUICreate ("Testing!", 400, 400)
GUISetOnEvent (-3, "_Exit")

Local $ahBtn[5], $ahMenu[5]

For $i = 0 To 4
    $ahBtn[$i] = GUICtrlCreateButton ("Button " & $i, 2, 2 + (22 * $i), 80, 20)
    GUICtrlSetOnEvent (-1, "_Clicked")
    $ahMenu[$i] = GUICtrlCreateContextMenu ($ahBtn[$i])
    For $x = 1 To 4
        GUICtrlCreateMenuItem ("Button " & $i & ", Item " & $x, $ahMenu[$i])
    Next
Next

GUISetState ()

While 1
    Sleep (1000)
WEnd

Func _Clicked ()
    Local $hMenu = 0 ; ??
    Local $aPos = ControlGetPos (@GUI_WinHandle, "", @GUI_CtrlId)
    _GUICtrlMenu_TrackPopupMenu ($hMenu, @GUI_WinHandle, $aPos[0], $aPos[1] + $aPos[3])
EndFunc ; ==> _Clicked

Func _Exit ()
    Exit
EndFunc ; ==> _Exit

Mat

(Changed code)

Edited by Mat
Link to comment
Share on other sites

You can do something like:

Func _Clicked ()
    Local $hMenu, $aPos, $iMenuItem
    
    For $i = 0 to UBound($ahBtn)-1
        If @GUI_CtrlId = $ahBtn[$i] Then
            $hMenu = GUICtrlGetHandle($ahMenu[$i][0])
            ExitLoop
        EndIf
    Next
    
    $aPos = WinGetPos(@GUI_CtrlHandle)
    $iMenuItem = _GUICtrlMenu_TrackPopupMenu ($hMenu, @GUI_WinHandle, $aPos[0], $aPos[1] + $aPos[3], 1, 1, 2)
    
    For $j = 1 To UBound($ahMenu)-1
        If $iMenuItem = $ahMenu[$i][$j] Then ExitLoop
    Next
    
    ConsoleWrite("Button: " & $i & ", MenuItem: " & $j & @CRLF)
EndFunc ; ==> _Clicked

I don't see any practical use of such code but you know... ;)

Link to comment
Share on other sites

Hi,

I'm not really sure of what your after in your overall project..

But for the _GUICtrlMenu_TrackPopupMenu() to work you'd need the handle of the Context menu you want to popup.

eg:

#include <GuiMenu.au3>
#include <GuiConstantsEx.au3>
#include <WindowsConstants.au3>

Opt ("GUIOnEventMode", 1)

Global $hGui, $ahBtn[5], $ahMenu[5]

$hGui = GUICreate ("Testing!", 400, 400)
GUISetOnEvent($GUI_EVENT_CLOSE, "Event")
For $i = 0 To 4
    $ahBtn[$i] = GUICtrlCreateButton ("Button " & $i, 2, 2 + (22 * $i), 80, 20)
    GUICtrlSetOnEvent (-1, "Event")
    $ahMenu[$i] = GUICtrlCreateContextMenu ($ahBtn[$i])
    For $x = 1 To 4
        GUICtrlCreateMenuItem ("Button " & $i & ", Item " & $x, $ahMenu[$i])
        GUICtrlSetOnEvent (-1, "Event")
    Next
Next
GUISetState(@SW_SHOW, $hGui)

While 1
    Sleep (10)
WEnd

Func Event()
    Switch @GUI_CtrlId
        Case $GUI_EVENT_CLOSE
            Exit
        Case $ahBtn[0], $ahBtn[1], $ahBtn[2], $ahBtn[3], $ahBtn[4]
            _GUICtrlMenu_TrackPopupMenu (GUICtrlGetHandle(@GUI_CtrlId + 1), $hGui)
        Case Else
            MsgBox(64, "Context Menu clicked..", "Text of context item clicked: " & @LF & GUICtrlRead(@GUI_CtrlId, 1), 3, $hGui)
    EndSwitch
EndFunc

Edit: As Authenticity said "I don't see any practical use of such code but you know... ;)"

Cheers

Edited by smashly
Link to comment
Share on other sites

The array was just for making the GUI easily... In the actual script that won't be such an easy option.

What smashly did was clever though... Not guaranteed to be accurate, but so long as I put the context menu creation straight after the button creation I should be ok. This is the effect I was looking for:

Opt ("GUIOnEventMode", 1)

GUICreate ("Testing!", 400, 400)
GUISetOnEvent (-3, "_Exit")

Local $ahBtn[5], $ahMenu[5]

For $i = 0 To 4
    $ahBtn[$i] = GUICtrlCreateButton ("Button " & $i, 2, 2 + (22 * $i), 80, 20)
    GUICtrlSetOnEvent (-1, "_PopupMenu")
    $ahMenu[$i] = GUICtrlCreateContextMenu ($ahBtn[$i])
    For $x = 1 To 4
        GUICtrlCreateMenuItem ("Button " & $i & ", Item " & $x, $ahMenu[$i])
    Next
Next

GUISetState ()

While 1
    Sleep (1000)
WEnd

Func _Exit ()
    Exit
EndFunc ; ==> _Exit

Func _PopupMenu()
    Local $aPos = ControlGetPos (@GUI_WinHandle, "", @GUI_CtrlId), $aWin = WinGetPos (@GUI_WinHandle)
    DllCall("User32.dll", "bool", "TrackPopupMenu", "handle", GUICtrlGetHandle (@GUI_CtrlId + 1), "uint", 0x80, "int", $aPos[0] + $aWin[0] + 6, "int", $aPos[1] + $aPos[3] + $aWin[1] + 22, "int", 0, "hwnd", @GUI_WinHandle, "ptr", 0)
EndFunc   ;==>_PopupMenu

It looks nice. Thats practical isn't it? Thanks guys.

Mat

Link to comment
Share on other sites

Hi,

Tried to run your code, but in win7 x64 I seem to have problem of getting the left click context menu to pop up.

If you want a definite control handle/id when an item is clicked then store all created controls in the arrays.

At least then you won't be guessing +1 of the control id of a button.

Also it'll make it easier to do things when a context menu item is clicked if you can locate it in the array with a loop.

Another thing that maybe could be done is prevent the right click context on a button, but still allow other right click context menus on the gui or other controls.

#include <GuiMenu.au3>
#include <GuiConstantsEx.au3>
#include <WindowsConstants.au3>
#include <WinAPI.au3>

Opt("GUIOnEventMode", 1)

Global $hGui, $aGuiContext[2], $aCtrlID[5][6]

$hGui = GUICreate("Testing!", 400, 400)
GUISetOnEvent($GUI_EVENT_CLOSE, "GuiEvent", $hGui)
$aGuiContext[0] = GUICtrlCreateContextMenu()
$aGuiContext[1] = GUICtrlCreateMenuItem("Exit", $aGuiContext[0])
GUICtrlSetOnEvent(-1, "GuiEvent")

For $i = 0 To UBound($aCtrlID, 1) - 1
    $aCtrlID[$i][0] = GUICtrlCreateButton("Button " & $i, 2, 2 + (22 * $i), 80, 20)
    GUICtrlSetOnEvent(-1, "CtrlEvent")
    $aCtrlID[$i][1] = GUICtrlCreateContextMenu($aCtrlID[$i][0])
    For $j = 2 To UBound($aCtrlID, 2) - 1
        $aCtrlID[$i][$j] = GUICtrlCreateMenuItem("Button " & $i & ", Item " & $j - 1, $aCtrlID[$i][1])
        GUICtrlSetOnEvent(-1, "CtrlEvent")
    Next
Next
GUISetState(@SW_SHOW, $hGui)

GUIRegisterMsg($WM_CONTEXTMENU, "WM_CONTEXTMENU")

While 1
    Sleep(10)
WEnd

Func CtrlEvent()
    Local $iCID = @GUI_CtrlId
    For $i = 0 To UBound($aCtrlID, 1) - 1
        If $aCtrlID[$i][0] = $iCID Then
            Local $tRect = _WinAPI_GetWindowRect(GUICtrlGetHandle($aCtrlID[$i][0]))
            Return _GUICtrlMenu_TrackPopupMenu(GUICtrlGetHandle($aCtrlID[$i][1]), $hGui, DllStructGetData($tRect, "Right"), DllStructGetData($tRect, "Top"))
        EndIf
        For $j = 2 To UBound($aCtrlID, 2) - 1
            If $aCtrlID[$i][$j] = $iCID Then Return _
                    MsgBox(64, "Context Menu clicked..", "Context Menu ID: " & $aCtrlID[$i][1] & _
                    @LF & "Context Menu handle: " & GUICtrlGetHandle($aCtrlID[$i][1]) & _
                    @LF & "Context Menu $aCtrlID array index: $aCtrlID[" & $i & "][1]" & _
                    @LF & "Text of context item clicked: " & GUICtrlRead($aCtrlID[$i][$j], 1) & _
                    @LF & "$aCtrlID array index of context item clicked: $aCtrlID[" & $i & "][" & $j & "]" & _
                    @LF & "Control ID of context item clicked: " & $iCID, 20, $hGui)
        Next
    Next
EndFunc   ;==>CtrlEvent

Func GuiEvent()
    Switch @GUI_CtrlId
        Case $GUI_EVENT_CLOSE, $aGuiContext[1]
            Exit
        Case $GUI_EVENT_MINIMIZE
            ;;;
        Case $GUI_EVENT_MAXIMIZE
            ;;;
        Case $GUI_EVENT_RESTORE
            ;;;
        Case Else
            ;;;
    EndSwitch
EndFunc   ;==>GuiEvent

; Block the context menu on right click on buttons while still allowing right click context menus on anything else..
; eg; Gui or other controls right click context menus can still work.
Func WM_CONTEXTMENU($hWnd, $iMsg, $iwParam, $ilParam)
    For $i = 0 To UBound($aCtrlID, 1) - 1
        If $iwParam = GUICtrlGetHandle($aCtrlID[$i][0]) Then Return True
    Next
    Return $GUI_RUNDEFMSG
EndFunc   ;==>WM_CONTEXTMENU

Cheers

Edited by smashly
Link to comment
Share on other sites

Thanks for the win7 info, I can't see where the problem may be, except that maybe x64 allocates the id's differently or messes it up somewhere.

I think I'm going to do something clever, and use a dropdown button. It's looking good at the moment. I am going to go for a switch statement, as I think its pointless making two variables point to the same info. Do you have any info on where the script is failing on your machine?

Mat

Edit: Heres a rough idea:

Opt ("GUIOnEventMode", 1)

GUICreate ("Testing!", 400, 400)
GUISetOnEvent (-3, "_Exit")

Local $ahBtn[5], $ahMenu[5]

For $i = 0 To 4
    $ahBtn[$i] = GUICtrlCreateButton ("Button " & $i, 2, 2 + (22 * $i), 80, 20, 0x812C)
    ;GUICtrlSetOnEvent (-1, "_ButtoinClicked")
    $ahMenu[$i] = GUICtrlCreateContextMenu ($ahBtn[$i])
    For $x = 1 To 4
        GUICtrlCreateMenuItem ("Button " & $i & ", Item " & $x, $ahMenu[$i])
    Next
Next

GUIRegisterMsg (0x004E, "WM_NOTIFY")
GUISetState ()

While 1
    Sleep (1000)
WEnd

Func _Exit ()
    Exit
EndFunc ; ==> _Exit

Func WM_NOTIFY($hWnd, $msgId, $wParam, $lParam)
    $tNMHDR = DllStructCreate("hwnd hWndFrom;uint_ptr IDFrom;INT Code", $lParam)
    $hWndFrom = HWnd(DllStructGetData($tNMHDR, "hWndFrom"))
    $iIDFrom = DllStructGetData($tNMHDR, "IDFrom")
    $iCode = DllStructGetData($tNMHDR, "Code")

    If $iCode <> -1248 Then Return "GUI_RUNDEFMSG"
    Local $aPos = ControlGetPos ($hWnd, "", $iIDFrom), $aWin = WinGetPos ($hWnd)
    DllCall("User32.dll", "bool", "TrackPopupMenu", "handle", GUICtrlGetHandle ($iIDFrom + 1), "uint", 0x80, "int", $aPos[0] + $aWin[0] + 6, "int", $aPos[1] + $aPos[3] + $aWin[1] + 22, "int", 0, "hwnd", $hWndFrom, "ptr", 0)
EndFunc ; ==> WM_NOTIFY
Edited by Mat
Link to comment
Share on other sites

Hi,

the failure comes from the DllCall("User32.dll", "bool", "TrackPopupMenu","handle",.....).

Returns @error 2 unknown "return type" if I use AutoIt v3.3.0.0, but works ok if I use AutoIt Beta 3.3.1.7

Both beta and public release I'm running under x64 autoit in win 7 x64

Works ok under both beta and public release autoit using DllCall("User32.dll", "int", "TrackPopupMenu","hwnd",..,..,......)

Edit: Helps if I update from 3.3.0.0 to 3.3.2.0 public release

(actually needed to dl 3.3.2.0 public release from the beta link on the dl page as the public release link is still 3.3.0.0)

But in your latest code snippet your WM_NOTIFY function is not filtered properly, so as soon as I run your script the menu pops up without intervention.

Same if I click on the gui the popup menu disappears, but as soon as I mouse over a button (not clicking) then the menu pops up again.

While the popup is still showing, mosusing over another button doesn't show a new popup, clicking does.

Maybe it was meant to be that way?

To get anything to work I need to change the -1248 to -1247 before I can even get WM_NOTIFY function to trip off the DLLCall..

For me the $icode is never -1248, so WM_NOTIFY function always returns "GUI_RUNDEFMSG"

I get -1247, -1249 or -12 while checking the $iCode before the line;

If $iCode <> -1248 Then Return "GUI_RUNDEFMSG"

Cheers

Edited by smashly
Link to comment
Share on other sites

; Notifications
Global Const $BCN_FIRST = -1250
Global Const $BCN_DROPDOWN = ($BCN_FIRST + 0x0002)
Global Const $BCN_HOTITEMCHANGE = ($BCN_FIRST + 0x0001)

-1248 = -1250 + 0x0002 = -1250 + 2 = -1248

Thats how I reached that number, also: looking at the numbers for the notifications (for buttons) -1247 is impossible. After a lot of digging... -1247 is the notification that the mouse is over the button (or possibly just the dropdown part). I am getting -1248 as expected when thew dropdown arrow is clicked. Clicking the button normally should not drop down the box, you have to click on the arrow to the right. -1249 is "HOTITEMCHANGE", which I am yet to work out...

I recognize the dll problem you were having, I used to get it too.

Mat

Link to comment
Share on other sites

More info:

Constants.au3 ==> $GWL_ID ==> -12

Constants.au3 ==> $TRAY_EVENT_MOUSEOUT ==> -12

GUIConstantsEx.au3 ==> $GUI_EVENT_RESIZED ==> -12

WindowsConstants.au3 ==> $NM_CUSTOMDRAW ==> -12

I'm presuming the -12 you are seeing is the last, as its the only notification. -1247 does not return any results. I thought it could have been -12, 47 put together, but 47 returns garbage. I've been using this to get the values:

#include <AVIConstants.au3>
#include <BorderConstants.au3>
#include <ButtonConstants.au3>
#include <ColorConstants.au3>
#include <ComboConstants.au3>
#include <Constants.au3>
#include <DateTimeConstants.au3>
#include <DirConstants.au3>
#include <EditConstants.au3>
#include <FileConstants.au3>
#include <FontConstants.au3>
#include <FrameConstants.au3>
#include <GDIPlusConstants.au3>
#include <GUIConstants.au3>
#include <GUIConstantsEx.au3>
#include <HeaderConstants.au3>
#include <ImageListConstants.au3>
#include <IPAddressConstants.au3>
#include <ListBoxConstants.au3>
#include <ListViewConstants.au3>
#include <MemoryConstants.au3>
#include <MenuConstants.au3>
#include <ProcessConstants.au3>
#include <ProgressConstants.au3>
#include <RebarConstants.au3>
#include <RichEditConstants.au3>
#include <ScrollBarConstants.au3>
#include <SecurityConstants.au3>
#include <SliderConstants.au3>
#include <StaticConstants.au3>
#include <StatusBarConstants.au3>
#include <StructureConstants.au3>
#include <TabConstants.au3>
#include <ToolbarConstants.au3>
#include <ToolTipConstants.au3>
#include <TreeViewConstants.au3>
#include <UpDownConstants.au3>
#include <WindowsConstants.au3>

$vTarget = -12

$sDir = StringTrimRight (@AutoItExe, 11) & "include\"

$hSearch = FileFindFirstFile ($sDir & "*Constants*.au3")

Local $sRet = ""
While 1
    $sFile = FileFindNextFile ($hSearch)
    If @error Then ExitLoop

    $sData = FileRead ($sDir & $sFile)
    $aLines = StringSplit (StringReplace (StringReplace ($sData, @CRLF, @CR), @LF, @CR), @CR)
    For $i = 1 To $aLines[0]
        $aLines[$i] = StringStripWS ($aLines[$i], 3)
        If StringLeft ($aLines[$i], 1) = ";" Then ContinueLoop
        $aSplit = StringSplit ($aLines[$i], "=")
        If $aSplit[0] <> 2 Then ContinueLoop
        $aSplit[2] = Execute ($aSplit[2])
        If $aSplit[2] = $vTarget Then ConsoleWrite ($sFile & " ==> " & StringTrimLeft ($aSplit[1], StringLen ("Global Const ")) & " ==> " & $aSplit[2] & @CRLF)
    Next
WEnd

Its surprisingly quick. I think the only problem is that the dropdown part of the button is not showing, but "if it works on vista, it'll work on win7". Make sure you are clicking on the dropdown arrow and not the button.

Edit:

This is my console:

>"C:\Program Files\AutoIt3\SciTE\AutoIt3Wrapper\AutoIt3Wrapper.exe" /run /prod /ErrorStdOut /in "C:\Users\new user\Documents\AutoIt\test.au3" /autoit3dir "C:\Program Files\AutoIt3" /UserParams    
+>13:17:00 Starting AutoIt3Wrapper v.2.0.0.7    Environment(Language:0409  Keyboard:00000809  OS:WIN_VISTA/  CPU:X64 OS:X86)
>Running AU3Check (1.54.19.0)  from:C:\Program Files\AutoIt3
+>13:17:00 AU3Check ended.rc:0
>Running:(3.3.2.0):C:\Program Files\AutoIt3\autoit3.exe "C:\Users\new user\Documents\AutoIt\test.au3"    
Writing Constants ini
$TRAY_EVENT_MOUSEOUT or $GUI_EVENT_RESIZED or $NM_CUSTOMDRAW
Inrecognized Id: -1247
$TRAY_EVENT_MOUSEOUT or $GUI_EVENT_RESIZED or $NM_CUSTOMDRAW
$TRAY_EVENT_MOUSEOUT or $GUI_EVENT_RESIZED or $NM_CUSTOMDRAW
Inrecognized Id: -1247
$TRAY_EVENT_MOUSEOUT or $GUI_EVENT_RESIZED or $NM_CUSTOMDRAW
$TRAY_EVENT_MOUSEOUT or $GUI_EVENT_RESIZED or $NM_CUSTOMDRAW
Inrecognized Id: -1247
$TRAY_EVENT_MOUSEOUT or $GUI_EVENT_RESIZED or $NM_CUSTOMDRAW
$TRAY_EVENT_MOUSEOUT or $GUI_EVENT_RESIZED or $NM_CUSTOMDRAW
Inrecognized Id: -1247
$TRAY_EVENT_MOUSEOUT or $GUI_EVENT_RESIZED or $NM_CUSTOMDRAW
$TRAY_EVENT_MOUSEOUT or $GUI_EVENT_RESIZED or $NM_CUSTOMDRAW
Inrecognized Id: -1247
$TRAY_EVENT_MOUSEOUT or $GUI_EVENT_RESIZED or $NM_CUSTOMDRAW
$TRAY_EVENT_MOUSEOUT or $GUI_EVENT_RESIZED or $NM_CUSTOMDRAW
Inrecognized Id: -1247
$TRAY_EVENT_MOUSEOUT or $GUI_EVENT_RESIZED or $NM_CUSTOMDRAW
$TRAY_EVENT_MOUSEOUT or $GUI_EVENT_RESIZED or $NM_CUSTOMDRAW
Inrecognized Id: -1247
$TRAY_EVENT_MOUSEOUT or $GUI_EVENT_RESIZED or $NM_CUSTOMDRAW
$TRAY_EVENT_MOUSEOUT or $GUI_EVENT_RESIZED or $NM_CUSTOMDRAW
Inrecognized Id: -1247
$TRAY_EVENT_MOUSEOUT or $GUI_EVENT_RESIZED or $NM_CUSTOMDRAW
$TRAY_EVENT_MOUSEOUT or $GUI_EVENT_RESIZED or $NM_CUSTOMDRAW
Inrecognized Id: -1247
$TRAY_EVENT_MOUSEOUT or $GUI_EVENT_RESIZED or $NM_CUSTOMDRAW
$TRAY_EVENT_MOUSEOUT or $GUI_EVENT_RESIZED or $NM_CUSTOMDRAW
Inrecognized Id: -1247
$TRAY_EVENT_MOUSEOUT or $GUI_EVENT_RESIZED or $NM_CUSTOMDRAW
$TRAY_EVENT_MOUSEOUT or $GUI_EVENT_RESIZED or $NM_CUSTOMDRAW
Inrecognized Id: -1247
$TRAY_EVENT_MOUSEOUT or $GUI_EVENT_RESIZED or $NM_CUSTOMDRAW
$BCN_HOTITEMCHANGE
$TRAY_EVENT_MOUSEOUT or $GUI_EVENT_RESIZED or $NM_CUSTOMDRAW
Inrecognized Id: -1247
$TRAY_EVENT_MOUSEOUT or $GUI_EVENT_RESIZED or $NM_CUSTOMDRAW
$TRAY_EVENT_MOUSEOUT or $GUI_EVENT_RESIZED or $NM_CUSTOMDRAW
Inrecognized Id: -1247
$TRAY_EVENT_MOUSEOUT or $GUI_EVENT_RESIZED or $NM_CUSTOMDRAW
$BCN_HOTITEMCHANGE
$TRAY_EVENT_MOUSEOUT or $GUI_EVENT_RESIZED or $NM_CUSTOMDRAW
Inrecognized Id: -1247
$TRAY_EVENT_MOUSEOUT or $GUI_EVENT_RESIZED or $NM_CUSTOMDRAW
$BCN_HOTITEMCHANGE
$TRAY_EVENT_MOUSEOUT or $GUI_EVENT_RESIZED or $NM_CUSTOMDRAW
Inrecognized Id: -1247
$TRAY_EVENT_MOUSEOUT or $GUI_EVENT_RESIZED or $NM_CUSTOMDRAW
$BCN_HOTITEMCHANGE
$TRAY_EVENT_MOUSEOUT or $GUI_EVENT_RESIZED or $NM_CUSTOMDRAW
Inrecognized Id: -1247
$TRAY_EVENT_MOUSEOUT or $GUI_EVENT_RESIZED or $NM_CUSTOMDRAW
$TRAY_EVENT_MOUSEOUT or $GUI_EVENT_RESIZED or $NM_CUSTOMDRAW
Inrecognized Id: -1247
$TRAY_EVENT_MOUSEOUT or $GUI_EVENT_RESIZED or $NM_CUSTOMDRAW
$BCN_HOTITEMCHANGE
$TRAY_EVENT_MOUSEOUT or $GUI_EVENT_RESIZED or $NM_CUSTOMDRAW
Inrecognized Id: -1247
$TRAY_EVENT_MOUSEOUT or $GUI_EVENT_RESIZED or $NM_CUSTOMDRAW
Inrecognized Id: -1247
$BCN_DROPDOWN
$TRAY_EVENT_MOUSEOUT or $GUI_EVENT_RESIZED or $NM_CUSTOMDRAW
Inrecognized Id: -1247
$TRAY_EVENT_MOUSEOUT or $GUI_EVENT_RESIZED or $NM_CUSTOMDRAW
$TRAY_EVENT_MOUSEOUT or $GUI_EVENT_RESIZED or $NM_CUSTOMDRAW
Inrecognized Id: -1247
$TRAY_EVENT_MOUSEOUT or $GUI_EVENT_RESIZED or $NM_CUSTOMDRAW
+>13:17:12 AutoIT3.exe ended.rc:0
+>13:17:13 AutoIt3Wrapper Finished
>Exit code: 0    Time: 12.780

When running this script:

If Not FileExists (@ScriptDir & "\Constants.ini") Then _WriteFile()

Opt ("GUIOnEventMode", 1)

GUICreate ("Testing!", 400, 400)
GUISetOnEvent (-3, "_Exit")

Local $ahBtn[5], $ahMenu[5]

For $i = 0 To 4
    $ahBtn[$i] = GUICtrlCreateButton ("Button " & $i, 2, 2 + (22 * $i), 80, 20, 0x812C)
    ;GUICtrlSetOnEvent (-1, "_Buttonclicked")
    $ahMenu[$i] = GUICtrlCreateContextMenu ($ahBtn[$i])
    For $x = 1 To 4
        GUICtrlCreateMenuItem ("Button " & $i & ", Item " & $x, $ahMenu[$i])
    Next
Next

GUIRegisterMsg (0x004E, "WM_NOTIFY")
GUISetState ()

While 1
    Sleep (1000)
WEnd

Func _Exit ()
    Exit
EndFunc ; ==> _Exit

Func WM_NOTIFY($hWnd, $msgId, $wParam, $lParam)
    $tNMHDR = DllStructCreate("hwnd hWndFrom;uint_ptr IDFrom;INT Code", $lParam)
    $hWndFrom = HWnd(DllStructGetData($tNMHDR, "hWndFrom"))
    $iIDFrom = DllStructGetData($tNMHDR, "IDFrom")
    $iCode = DllStructGetData($tNMHDR, "Code")

    ConsoleWrite (_GetCode ($iCode) & @CRLF)
    If $iCode <> -1248 Then Return "GUI_RUNDEFMSG"
    Local $aPos = ControlGetPos ($hWnd, "", $iIDFrom), $aWin = WinGetPos ($hWnd)
    DllCall("User32.dll", "bool", "TrackPopupMenu", "handle", GUICtrlGetHandle ($iIDFrom + 1), "uint", 0x80, "int", $aPos[0] + $aWin[0] + 6, "int", $aPos[1] + $aPos[3] + $aWin[1] + 22, "int", 0, "hwnd", $hWndFrom, "ptr", 0)
EndFunc ; ==> WM_NOTIFY

Func _GetCode ($iCode)
    Local $a = IniReadSection (@ScriptDir & "\Constants.ini", $iCode), $sRet = ""
    If @error Then Return "Inrecognized Id: " & $iCode
    For $i = 1 To $a[0][0]
        $sRet &= $a[$i][1] & " or "
    Next
    Return StringTrimRight ($sRet, 4)
EndFunc

Func _WriteFile ()
    ConsoleWrite ("Writing Constants ini" & @CRLF)
    $sData = "#include <AVIConstants.au3>" & @CRLF & _
    "#include <BorderConstants.au3>" & @CRLF & _
    "#include <ButtonConstants.au3>" & @CRLF & _
    "#include <ColorConstants.au3>" & @CRLF & _
    "#include <ComboConstants.au3>" & @CRLF & _
    "#include <Constants.au3>" & @CRLF & _
    "#include <DateTimeConstants.au3>" & @CRLF & _
    "#include <DirConstants.au3>" & @CRLF & _
    "#include <EditConstants.au3>" & @CRLF & _
    "#include <FileConstants.au3>" & @CRLF & _
    "#include <FontConstants.au3>" & @CRLF & _
    "#include <FrameConstants.au3>" & @CRLF & _
    "#include <GDIPlusConstants.au3>" & @CRLF & _
    "#include <GUIConstants.au3>" & @CRLF & _
    "#include <GUIConstantsEx.au3>" & @CRLF & _
    "#include <HeaderConstants.au3>" & @CRLF & _
    "#include <ImageListConstants.au3>" & @CRLF & _
    "#include <IPAddressConstants.au3>" & @CRLF & _
    "#include <ListBoxConstants.au3>" & @CRLF & _
    "#include <ListViewConstants.au3>" & @CRLF & _
    "#include <MemoryConstants.au3>" & @CRLF & _
    "#include <MenuConstants.au3>" & @CRLF & _
    "#include <ProcessConstants.au3>" & @CRLF & _
    "#include <ProgressConstants.au3>" & @CRLF & _
    "#include <RebarConstants.au3>" & @CRLF & _
    "#include <RichEditConstants.au3>" & @CRLF & _
    "#include <ScrollBarConstants.au3>" & @CRLF & _
    "#include <SecurityConstants.au3>" & @CRLF & _
    "#include <SliderConstants.au3>" & @CRLF & _
    "#include <StaticConstants.au3>" & @CRLF & _
    "#include <StatusBarConstants.au3>" & @CRLF & _
    "#include <StructureConstants.au3>" & @CRLF & _
    "#include <TabConstants.au3>" & @CRLF & _
    "#include <ToolbarConstants.au3>" & @CRLF & _
    "#include <ToolTipConstants.au3>" & @CRLF & _
    "#include <TreeViewConstants.au3>" & @CRLF & _
    "#include <UpDownConstants.au3>" & @CRLF & _
    "#include <WindowsConstants.au3>" & @CRLF & _
    "$vTarget = -12" & @CRLF & _
    "FileDelete (@ScriptDir & ""\Constants.ini"")" & @CRLF & _
    "$sDir = StringTrimRight (@AutoItExe, 11) & ""include\""" & @CRLF & _
    "$hSearch = FileFindFirstFile ($sDir & ""*Constants*.au3"")" & @CRLF & _
    "Local $sRet = """"" & @CRLF & _
    "While 1" & @CRLF & _
    "   $sFile = FileFindNextFile ($hSearch)" & @CRLF & _
    "   If @error Then ExitLoop" & @CRLF & _
    "   $sData = FileRead ($sDir & $sFile)" & @CRLF & _
    "   $aLines = StringSplit (StringReplace (StringReplace ($sData, @CRLF, @CR), @LF, @CR), @CR)" & @CRLF & _
    "   For $i = 1 To $aLines[0]" & @CRLF & _
    "       $aLines[$i] = StringStripWS ($aLines[$i], 3)" & @CRLF & _
    "       If StringLeft ($aLines[$i], 1) = "";"" Then ContinueLoop" & @CRLF & _
    "       $aSplit = StringSplit ($aLines[$i], ""="")" & @CRLF & _
    "       If $aSplit[0] <> 2 Then ContinueLoop" & @CRLF & _
    "       $aSplit[2] = Execute ($aSplit[2])" & @CRLF & _
    "       IniWrite (@ScriptDir & ""\Constants.ini"", StringStripWS ($aSplit[2], 3), $sFile, StringStripWS (StringTrimLeft ($aSplit[1], StringLen (""Global Const "")), 3))" & @CRLF & _
    "   Next" & @CRLF & _
    "WEnd"
    Local $sFile = @ScriptDir & "\tempscript.au3"
    Local $hFile = FileOpen ($sFile, 2)
    FileWrite ($hFile, $sData)
    FileFlush ($hFile)
    RunWait ("""" & @AutoItExe & """ /AutoIt3ExecuteScript """ & $sFile & """")
    FileDelete ($sFile)
EndFunc ; ==> _WriteFile

It will take a few secs to start the first time, as it writes a big ini file with all the constants indexed by value.

Mat

Edited by Mat
Link to comment
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
 Share

  • Recently Browsing   0 members

    • No registered users viewing this page.
×
×
  • Create New...