UritOR

Context menu problemm

10 posts in this topic

#1 ·  Posted (edited)

Hi, I'm looking for a help, maybe some one can help=)

When I create a  contextmenu for some control I want it to pop up immediately but "State of a "contextmenu" control cannot be changed."

I work in OnEvent mode.  When I create few graphic controls in a GUI (and store them in the array(1 dimension)), I also create a context menu for each one(and store all these in different array(1 dimension)). All I want to be done is  that right mouse click will open a context menu of a control (picture .bmp), with 1 menu item "Delete", and when clicked it should be deleted from gui and from array. 

What I've done works partly for me. When I right click on some control It shows me a contextmenu with 1 menu item "Delete". but depending on the mouse cursor coordinates, the context menu sometimes "overlaps" the other neighbor picture control , so I have an ability to move a lil bit mouse cursor (out of borders of the control i clicked on ) and click "delete".

If at the time of the "Click" the cursor was above another control so the another control will be deleted. if the cursor was above empty space nothing will happen.

 

Anyone can help?

 

Thanx 

#include <GUIConstantsEx.au3>
#include <WinAPI.au3>
#include <WindowsConstants.au3>
#include <ColorConstants.au3>

Opt("GUIOnEventMode", 1) ; Change to OnEvent mode
Opt("GUICloseOnESC", 0) ; prevents ESC to exit script
HotKeySet("^n", "AddNewControl")

$guiWidth = _WinAPI_GetSystemMetrics(0)
$guiHeight = @DesktopHeight -  _WinAPI_GetSystemMetrics(15)

Local $GUI = GUICreate("", 100,100,0,0,$WS_POPUP)
WinSetState($GUI, "", @SW_MAXIMIZE)
GUISetBkColor($COLOR_WHITE)
    GUISetOnEvent($GUI_EVENT_CLOSE, "_Exit")
;---------------------------------------------------
Local $contextMenu = GUICtrlCreateContextMenu()
    Local $addControl = GUICtrlCreateMenuItem("AddControl", $contextMenu)
        GUICtrlsetOnEvent($addControl, "AddNewControl")
;---------------------------------------------------
Local $fileTopMenu = GUICtrlCreateMenu("File")
    Local $fileAddControl = GUICtrlCreateMenuItem("AddControl               Ctrl+n", $fileTopMenu)
        GUICtrlSetOnEvent($fileAddControl, "AddNewControl")
    Local $fileExitItem = GUICtrlCreateMenuItem("Exit                              Alt+F4", $fileTopMenu)
        GUICtrlSetOnEvent($fileExitItem, "_Exit")
;----------------------------------------------------

GUISetState(@SW_SHOW, $GUI)

local $total=0
Dim $rect[4], $idRectContext[4], $idRectMenu[4]
local $width, $height,$maxInRow,$maxInCol, $gapX, $gapY, $maxRect

    $maxInRow = 4
    $maxInCol = 4
    $maxRect = $maxInRow * $maxInCol

    Dim $rect[$maxRect]
    Dim $idRectContext = $rect
    Dim $idRectMenu = $rect

    $width = Int(0.95*($GuiWidth / $maxInRow))
    $gapX =  Int(($GuiWidth - ($width*$maxInRow)) / (1+$maxInRow))

    $height = Int((0.95*$GuiHeight / $maxInCol))
    $gapY = Int(($GuiHeight - ($height*$maxInCol)) / (1+$maxInCol))

While 1
    Sleep(500) ;reduce CPU usage
WEnd

Func _Exit()
    GUIDelete()
    Exit
EndFunc

Func AddNewControl()
;------- prevents to create more controls before finsh with current ---------
    HotKeySet ("^n")
    GUICtrlSetState($addControl, $GUI_DISABLE)
    GUICtrlSetState($fileAddControl, $GUI_DISABLE)
;----------------------------------------------------------------------------
;---------------  checks and limit the maximum controls creation ------------
    If     $total = UBound($rect) Then
        MsgBox($MB_SYSTEMMODAL, "Warning", "You reached the maximum controls number.")
        HotKeySet ("^n", "AddNewControl")
        GUICtrlSetState($addControl, $GUI_ENABLE)
        GUICtrlSetState($fileAddControl, $GUI_ENABLE)
        Return
    Endif
;-----------------------------------------------------------------------------
; ------------------- adding new control to a first empty space in a grid ----------
    For $i=0 to (UBound($rect)-1)
        if $rect[$i] = 0 Then
            $rect[$i] = GUICtrlCreatePic(@ScriptDir & "\picture.bmp", CalculateX($i),CalculateY($i), $width, $height)
                if $rect[$i] = 0 then
                    MsgBox(0,"Error", "There is no picture in a folder.")
                    ExitLoop
                endif
            $idRectContext[$i] = GUICtrlCreateContextMenu($rect[$i])
            $idRectMenu[$i] = GUICtrlCreateMenuItem("Delete", $idRectContext[$i])
            GUICtrlSetOnEvent($idRectMenu[$i], "Delete")
            ExitLoop
        EndIf
    Next
    $total+=1
 ; ----------------------------------------------------
; --------- returns the ability to create more controls---------
    HotKeySet ("^n", "AddNewControl")
    GUICtrlSetState($addControl, $GUI_ENABLE)
    GUICtrlSetState($fileAddControl, $GUI_ENABLE)
;---------------------------------------------------------------
EndFunc

Func CalculateX($controlOrder)
    $orderInRow = Int( MOD ($controlOrder,$maxInRow ) )
    return (Int(MOD($controlOrder,$maxInRow))*$width)+($gapX*$orderInRow)+$gapX
EndFunc

Func CalculateY($controlOrder)
    $orderInCol = Int($controlOrder/$maxInRow)
    return $gapY+$orderInCol*($gapY+$height)
EndFunc

Func Delete()
    $aCInfo = GUIGetCursorInfo($GUI)
    $i=-1
    Do
        $i+=1
    Until $rect[$i] = $aCInfo[4]
    $rect[$i]=0
    $total -=1
    GUICtrlDelete($aCInfo[4])
EndFunc

 

Edited by UritOR

Share this post


Link to post
Share on other sites



Anyone? Please,

I still can not solve it

Share this post


Link to post
Share on other sites

#3 ·  Posted (edited)

* snip *

Edited by rcmaehl

My UDFs are generally for me. If they aren't updated for a while, it means I'm not using them myself. As soon as I start using them again, they'll get updated.

MY PROJECTS


Active: IRC UDF, WindowEx UDF
Discontinued: GithubBubbleSort UDF

Share this post


Link to post
Share on other sites

Nope, didn't help, also in a help file its written   "State of a "contextmenu" control cannot be changed."

Thanx rcmaehl.

Anyone have others ideas?

Share this post


Link to post
Share on other sites

#5 ·  Posted (edited)

Instead of using coordinates you might use @GUI_CtrlId, something like this - *untested,  it's for the concept*  :)

Func Delete()
   For $i = UBound($rect)-1 to 0 step -1
        If @GUI_CtrlId = $idRectMenu[$i] Then
             GUICtrlDelete($rect[$i])
             GUICtrlDelete($idRectMenu[$i])
             _ArrayDelete($rect[$i])
             _ArrayDelete($idRectMenu[$i])
             Exitloop
        EndIf
   Next
EndFunc

Edit
Why not use a single 2D array instead of two 1D arrays ?

Edited by mikell

Share this post


Link to post
Share on other sites

mikell,

Thank you so much! =)

@GUI_CtrlId -  thats what I need 

------------------------------    Solved         ---------------------------

Share this post


Link to post
Share on other sites

Another suggestion, even though it's solved *blush*

#include <WinAPI.au3>
#include <WindowsConstants.au3>
#include <Array.au3>

Opt("GuiOnEventMode", 1)

$hWnd = GUICreate("", 700, 320)
GUISetOnEvent(-3, "_MyExit", $hWnd)
GUISetState(@SW_SHOW, $hWnd)

Dim $aArray[1]

$aArray[0] = GUICtrlCreateLabel("", 105, 5, 100, 100)
GUICtrlSetBkColor(-1, 0xFF0000)

#Region
    Global $hCtrl = 0
    $dummy = GUICtrlCreateDummy( )
    $dummyContextMenu = GUICtrlCreateContextMenu($dummy)
    GUICtrlCreateMenuItem("Delete", $dummyContextMenu)
    GUICtrlSetOnEvent(-1, "Delete")
;~  GUIRegisterMsg(0x0205, "WM_RBUTTONUP");$WM_RBUTTONUP
    GUIRegisterMsg($WM_CONTEXTMENU, "WM_CONTEXTMENU")
#EndRegion

While 1
    Sleep(10)
WEnd

Func _MyExit()
    Exit
EndFunc

Func Delete()
    GUICtrlDelete(_WinAPI_GetDlgCtrlID($hCtrl))
EndFunc

Func WM_CONTEXTMENU($hWnd, $iMsg, $wParam, $lParam)
    ConsoleWrite("WM_CONTEXTMENU"&@CRLF& _
    @TAB&"wParam: "&$wParam&@CRLF& _
    @TAB&@TAB&"ControlID: "&_WinAPI_GetDlgCtrlID($wParam)&@CRLF)
;~  ConsoleWrite("hWnd: "&$hWnd&@CRLF)
;~  ConsoleWrite("wParam: "&$wParam&@TAB&"ControlID: "&_WinAPI_GetDlgCtrlID($wParam)&@CRLF)

    $hCtrl = $wParam
    If Not ( _ArraySearch($aArray, _WinAPI_GetDlgCtrlID($wParam)) = -1 ) Then ShowMenu($hWnd, $dummyContextMenu)

EndFunc

; Show a menu in a given GUI window which belongs to a given GUI ctrl
Func ShowMenu($hWnd, $nContextID)
    Local $hMenu = GUICtrlGetHandle($nContextID)

    $arPos = MouseGetPos()

    Local $x = $arPos[0]
    Local $y = $arPos[1]

    DllCall("user32.dll", "int", "TrackPopupMenuEx", "hwnd", $hMenu, "int", 0, "int", $x, "int", $y, "hwnd", $hWnd, "ptr", 0)
EndFunc

 

Share this post


Link to post
Share on other sites

genius257,

Yeah works, but in my eyes looks more complex. =) 

How we gonna accomplish it with few controls. Create many dummy ?

Share this post


Link to post
Share on other sites

#9 ·  Posted (edited)

33 minutes ago, UritOR said:

How we gonna accomplish it with few controls. Create many dummy ?

No :) Any control you wish to add to the dummy context menu, you simply add to the array:

$aArray

Edit:

I've implemented an example where left click adds a new label where you click

#include <WinAPI.au3>
#include <WindowsConstants.au3>
#include <Array.au3>

Opt("GuiOnEventMode", 1)

$hWnd = GUICreate("", 700, 320)
GUISetOnEvent(-3, "_MyExit", $hWnd)
GUISetState(@SW_SHOW, $hWnd)

Dim $aArray[1]

$aArray[0] = GUICtrlCreateLabel("", 105, 5, 100, 100)
GUICtrlSetBkColor(-1, 0xFF0000)

#Region
    Global $hCtrl = 0
    $dummy = GUICtrlCreateDummy( )
    $dummyContextMenu = GUICtrlCreateContextMenu($dummy)
    GUICtrlCreateMenuItem("Delete", $dummyContextMenu)
    GUICtrlSetOnEvent(-1, "Delete")
    GUIRegisterMsg($WM_LBUTTONDOWN, "WM_LBUTTONDOWN")
    GUIRegisterMsg($WM_CONTEXTMENU, "WM_CONTEXTMENU")
#EndRegion

While 1
    Sleep(10)
WEnd

Func _MyExit()
    Exit
EndFunc

Func Delete()
    GUICtrlDelete(_WinAPI_GetDlgCtrlID($hCtrl))
EndFunc

Func WM_LBUTTONDOWN($hWnd, $iMsg, $wParam, $lParam)
    ConsoleWrite("WM_LBUTTONDOWN"&@CRLF)
    $x = _WinAPI_LoWord($lParam)
    $y = _WinAPI_HiWord($lParam)

    Local $ctrl = GUICtrlCreateLabel("", _WinAPI_LoWord($lParam), _WinAPI_HiWord($lParam), 100, 100)
    GUICtrlSetBkColor($ctrl, 0xFF0000)
    ReDim $aArray[UBound($aArray, 1)+1]
    $aArray[UBound($aArray, 1)-1] = $ctrl
EndFunc

Func WM_CONTEXTMENU($hWnd, $iMsg, $wParam, $lParam)
    ConsoleWrite("WM_CONTEXTMENU"&@CRLF& _
    @TAB&"wParam: "&$wParam&@CRLF& _
    @TAB&@TAB&"ControlID: "&_WinAPI_GetDlgCtrlID($wParam)&@CRLF)
;~  ConsoleWrite("hWnd: "&$hWnd&@CRLF)
;~  ConsoleWrite("wParam: "&$wParam&@TAB&"ControlID: "&_WinAPI_GetDlgCtrlID($wParam)&@CRLF)

    $hCtrl = $wParam
    If Not ( _ArraySearch($aArray, _WinAPI_GetDlgCtrlID($wParam)) = -1 ) Then ShowMenu($hWnd, $dummyContextMenu)

EndFunc

; Show a menu in a given GUI window which belongs to a given GUI ctrl
Func ShowMenu($hWnd, $nContextID)
    Local $hMenu = GUICtrlGetHandle($nContextID)

    $arPos = MouseGetPos()

    Local $x = $arPos[0]
    Local $y = $arPos[1]

    DllCall("user32.dll", "int", "TrackPopupMenuEx", "hwnd", $hMenu, "int", 0, "int", $x, "int", $y, "hwnd", $hWnd, "ptr", 0)
EndFunc

 

Edited by genius257

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