Jump to content
Sign in to follow this  

contextmenu while WM_NOTIFY :(

Recommended Posts


Simple to ask but not easy to do for me !

Instead a msgbox with coordonnate when right click on a line, is someone can make to be appaear a contextmenu with first value of the line (or anything else) ?

like in windows rightclick >new >folder...

#include <ListViewConstants.au3>
#include <GUIConstantsEx.au3>
#include <WindowsConstants.au3>
#include <GUIListView.au3>

$gui = GUICreate('test')
; === $LVS_EX_FULLROWSELECT required to identify subitem
$hListView = GUICtrlCreateListView('Spalte1|Spalte2', 10, 10, 300, 200, -1, BitOR($LVS_EX_TRACKSELECT,$LVS_EX_FULLROWSELECT))
_GUICtrlListView_SetColumnWidth($hListView, 0, 146)
_GUICtrlListView_SetColumnWidth($hListView, 1, $LVSCW_AUTOSIZE_USEHEADER)
For $i = 1 To 10
    GUICtrlCreateListViewItem('row ' & $i & ' col 1|row ' & $i & ' col 2', $hListView)
    $msg = GUIGetMsg()
Until $msg = $GUI_EVENT_CLOSE

Func _RightClick($Info)
    MsgBox(0, 'read row-index ' & $Info[3] & ', col-index ' & $Info[4] , _GUICtrlListView_GetItemText($Info[1], $Info[3], $Info[4]) )

Func WM_NOTIFY($hWnd, $iMsg, $iwParam, $ilParam)
    Local $hWndFrom, $iIDFrom, $iCode, $tNMHDR, $hWndListView
    $hWndListView = $hListView
    If Not IsHWnd($hListView) Then $hWndListView = GUICtrlGetHandle($hListView)

    $tNMHDR = DllStructCreate($tagNMHDR, $ilParam)
    $hWndFrom = HWnd(DllStructGetData($tNMHDR, "hWndFrom"))
    $iIDFrom = DllStructGetData($tNMHDR, "IDFrom")
    $iCode = DllStructGetData($tNMHDR, "Code")
    Switch $hWndFrom
        Case $hWndListView
            Switch $iCode
                Case $NM_RCLICK ; Sent by a list-view control when the user clicks an item with the right mouse button
                    Local $tInfo = DllStructCreate($tagNMITEMACTIVATE, $ilParam)
                    Local $aInfo[5] = [$hWndFrom, _
                                        $iIDFrom, _
                                        $iCode, _
                                        DllStructGetData($tInfo, "Index"), _
                                        DllStructGetData($tInfo, "SubItem")]
EndFunc   ;==>WM_NOTIFY

Share this post

Link to post
Share on other sites

like this :mellow:

great job !

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

Opt('MustDeclareVars', 1)

Global $hLv, $hLVCM

Local $hGui, $msg, $cLv, $cLVCM, $cMenu1, $a, $b, $c
$hGui = GUICreate('ListView ContextMenu', 410, 300, -1, -1)
$cLv = GUICtrlCreateListView('List of Items', 5, 5, 400, 290)
$hLv = GUICtrlGetHandle($cLv) ;get listview handle from control ID
_GUICtrlListView_SetExtendedListViewStyle($cLv, BitOR($LVS_EX_GRIDLINES, $LVS_EX_FULLROWSELECT))
_GUICtrlListView_SetColumnWidth($cLv, 0, 396)

For $i = 1 To 150
    GUICtrlCreateListViewItem('ITEM ' & $i, $cLv)

;Create a dummy parent for the listview contextmenu menu so it will not popup on right click
;unless shown with _GUICtrlMenu_TrackPopupMenu()
$cMenu1 = GUICtrlCreateDummy()
$cLVCM = GUICtrlCreateContextMenu($cMenu1)
$hLVCM = GUICtrlGetHandle(-1)
$a = GUICtrlCreateMenuItem('LV Menu Item 1', $cLVCM)
$b = GUICtrlCreateMenuItem('LV Menu Item 2', $cLVCM)
$c = GUICtrlCreateMenuItem('LV Menu Item 3', $cLVCM)


While 1
    $msg = GUIGetMsg()
    Switch $msg
        Case 0
        Case $a
            ConsoleWrite("+ LV Menu Item 1" & @CRLF)
        Case $b
            ConsoleWrite("- LV Menu Item 2" & @CRLF)
        Case $c
            ConsoleWrite("> LV Menu Item 3" & @CRLF)
        Case -3

Func _WM_CONTEXTMENU($hWnd, $iMsg, $wParam, $lParam)
    #forceref $hWnd, $iMsg, $wParam, $lParam
    Switch $wParam
        Case $hLv ;bypass other contextmenus
            ;If $lParam = -1 Then Return $GUI_RUNDEFMSG ;option: ignore menu appkey/Shift-F10
            Local $iRet, $iX, $iY, $aSel, $aPos, $iIdx, $tpoint, $fSysMenu = False
            If $lParam = -1 Then ;Keyboard: Menu Appkey/Shift-F10
                ;get last selected item (if one or more selected by keyboard))
                $aSel = _GUICtrlListView_GetSelectedIndices($wParam, True)
                If @error Or UBound($aSel) <= 1 Then Return $GUI_RUNDEFMSG
                If $aSel[$aSel[0]] = -1 Then Return $GUI_RUNDEFMSG
                $iIdx = $aSel[$aSel[0]]
                $aPos = _GUICtrlListView_GetItemPosition($wParam, $iIdx)
                $tpoint = DllStructCreate("int X;int Y")
                DllStructSetData($tpoint, "X", $aPos[0])
                DllStructSetData($tpoint, "Y", $aPos[1])
                _WinAPI_ClientToScreen($wParam, $tPoint)
                $iX = DllStructGetData($tpoint, "X")
                $iY = DllStructGetData($tpoint, "Y")
                $fSysMenu = True
            Else ;mouse right click on listview item
                $iX = BitAND($lParam, 0x0000FFFF)
                $iY = BitShift($lParam, 16)
                ;convert Screen to Client coordinates
                $tpoint = DllStructCreate("int X;int Y")
                DllStructSetData($tpoint, "X", $iX)
                DllStructSetData($tpoint, "Y", $iY)
                _WinAPI_ScreenToClient($wParam, $tpoint)
                Local $iYPos1 = DllStructGetData($tPoint, "Y")

                ;WM_NOTIFY NM_RCLICK notification is not sent for right clicks on header,
                ;so when using WM_CONTEXTMENU only, we have to check before hit test if click is on header
                ;by checking if Y position is less than the header height
                Local $tRect = DllStructCreate($tagRECT)
                Local $hHeader = _SendMessage($wParam, $LVM_GETHEADER, 0, 0, 0, "wparam", "lparam", "hwnd")
                $iRet = _SendMessage($hHeader, $HDM_GETITEMRECT, 0, DllStructGetPtr($tRect), 0, "wparam", "ptr")
                If @error Or $iRet < 0 Then Return $GUI_RUNDEFMSG
                Local $iYPos2 = DllStructGetData($tRect, "Bottom")-1
                If $iYPos2 <0 Then Return $GUI_RUNDEFMSG
                If $iYPos1 <= $iYPos2 Then Return $GUI_RUNDEFMSG

                ;Do ListView HitTest
                Local $tTest = DllStructCreate($tagLVHITTESTINFO)
                DllStructSetData($tTest, "X", DllStructGetData($tPoint, "X"))
                DllStructSetData($tTest, "Y", $iYPos1)
                $iRet = _SendMessage($wParam, $LVM_HITTEST, 0, DllStructGetPtr($tTest))
                If @error Or $iRet = -1 Then Return $GUI_RUNDEFMSG ; -1 = not on lv item, otherwise returns index
                Switch DllStructGetData($tTest, "Flags")
                    Case $LVHT_ONITEMICON, $LVHT_ONITEMLABEL, $LVHT_ONITEM ;hit was on item icon or 1st column item or subitem
                        $fSysMenu = True

            If $iX >= 0 And $iY >= 0 Then
                ;pop the listview contextmenu
                If $fSysMenu = True And _GUICtrlMenu_IsMenu($hLVCM) = 1 Then
                    _GUICtrlMenu_TrackPopupMenu($hLVCM, $hWnd, $iX, $iY, 1, 1, 1)
                    Return True

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  

  • Recently Browsing   0 members

    No registered users viewing this page.

  • Create New...