Jump to content

Context menu problemm


UritOR
 Share

Recommended Posts

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
Link to comment
Share on other sites

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
Link to comment
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

 

Link to comment
Share on other sites

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
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...