Jump to content

Disable right-click in ListView?


Go to solution Solved by pixelsearch,

Recommended Posts

I'm working on coding a GUI that includes a ListView control created using _GUICtrlListView_Create().

The ListView is used to display thumbnails of image files found in a specified folder. When a user left-clicks on a thumbnail, the thumbnail is selected and the image is displayed on another GUI window.

Since this is only a simple viewer app whose sole function is the display of the images, there is no right-click action (i.e. context menu) wanted in the app. So I want to disable the right-click functionality in the ListView. Currently, right-clicking on a thumbnail in the ListView selects it, but I don't act on the click. I only act on a left-click on a thumbnail. To avoid user confusion, I'd like to make it where right-clicking in the ListView is totally ignored and doesn't do anything at all (i.e doesn't change which thumbnail (if any) is selected).

I've got GUIRegisterMsg($WM_NOTIFY, "WM_NOTIFY") in the GUI definition, and the WM_NOTIFY function monitors all messages from the ListView. I can see where I'm getting the $NM_RCLICK message when the ListView is right-clicked, but I don't know what I need to do to prevent that right-click from triggering the default behavior (or any behavior) in the ListView.

As an example, if you run the sample script in the help topic for _GUICtrlListView_Create, it reacts to the right-click on a ListView item. What would I need to do in that script to make a right-click in the ListView do absolutely nothing?

Link to comment
Share on other sites

Link to comment
Share on other sites

I've already read that and tried it since it sounded like it would do what I wanted. But it doesn't prevent the right-click from selecting what is right-clicked on. That's the default processing I want to prevent.

Case $NM_RCLICK ; Sent by a list-view control when the user clicks an item with the right mouse button
    ;_WM_NOTIFY_DebugEvent("$NM_RCLICK", $tagNMITEMACTIVATE, $lParam, "IDFrom,,Index,SubItem,NewState,OldState,Changed,ActionX,ActionY,lParam,KeyFlags")
    Return 1 ; not to allow the default processing
    ;Return 0 ; allow the default processing


Link to comment
Share on other sites

  • Solution

@TimRude try to subclass the listview, it should intercept the right-click before it reaches it :

#include <GUIConstantsEx.au3>
#include <GuiImageList.au3>
#include <GuiListView.au3>
#include <WindowsConstants.au3>
#include <WinAPIShellEx.au3>


Global $g_hListView

; Register DLL callback that will be used as window subclass procedure
Global $g_hDll = DllCallbackRegister('_SubclassProc', 'lresult', 'hwnd;uint;wparam;lparam;uint_ptr;dword_ptr')
Global $g_pDll = DllCallbackGetPtr($g_hDll)


Func Example()
    Local $hGUI, $hImage
    $hGUI = GUICreate("ListView Create (v" & @AutoItVersion & ")", 400, 300)

    $g_hListView = _GUICtrlListView_Create($hGUI, "", 2, 2, 394, 268)

    ; Install window subclass callback
    _WinAPI_SetWindowSubclass($g_hListView, $g_pDll, 1000, 0)


    ; Load images
    $hImage = _GUIImageList_Create()
    _GUIImageList_Add($hImage, _GUICtrlListView_CreateSolidBitMap($g_hListView, 0xFF0000, 16, 16))
    _GUIImageList_Add($hImage, _GUICtrlListView_CreateSolidBitMap($g_hListView, 0x00FF00, 16, 16))
    _GUIImageList_Add($hImage, _GUICtrlListView_CreateSolidBitMap($g_hListView, 0x0000FF, 16, 16))
    _GUICtrlListView_SetImageList($g_hListView, $hImage, 1)

    ; Add columns
    _GUICtrlListView_InsertColumn($g_hListView, 0, "Column 1", 100)
    _GUICtrlListView_InsertColumn($g_hListView, 1, "Column 2", 100)
    _GUICtrlListView_InsertColumn($g_hListView, 2, "Column 3", 100)

    ; Add items
    _GUICtrlListView_AddItem($g_hListView, "Row 1: Col 1", 0)
    _GUICtrlListView_AddSubItem($g_hListView, 0, "Row 1: Col 2", 1)
    _GUICtrlListView_AddSubItem($g_hListView, 0, "Row 1: Col 3", 2)
    _GUICtrlListView_AddItem($g_hListView, "Row 2: Col 1", 1)
    _GUICtrlListView_AddSubItem($g_hListView, 1, "Row 2: Col 2", 1)
    _GUICtrlListView_AddItem($g_hListView, "Row 3: Col 1", 2)

    Until GUIGetMsg() = $GUI_EVENT_CLOSE
EndFunc   ;==>Example

Func _SubclassProc($hWnd, $iMsg, $wParam, $lParam, $iID, $pData)
    #forceref $iID, $pData
    If $iMsg = $WM_RBUTTONDOWN Then Return 0
    Return _WinAPI_DefSubclassProc($hWnd, $iMsg, $wParam, $lParam)
EndFunc   ;==>_SubclassProc

Func OnAutoItExit()
    _WinAPI_RemoveWindowSubclass($g_hListView, $g_pDll, 1000)
EndFunc   ;==>OnAutoItExit


Link to comment
Share on other sites

1 hour ago, pixelsearch said:

@TimRude try to subclass the listview, it should intercept the right-click before it reaches it

@pixelsearch That's the ticket! In my VB6 programming, I've often had to dabble in the dark art of subclassing but I didn't know how or if it was possible to do it with AutoIt. Now with your concise example I can familiarize myself with the steps involved.

Thanks for the info!

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

  • Recently Browsing   0 members

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