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 post
Share on other sites

In the example you linked, there is a comment in the $NM_RCLICK case.  Please read it, it tells how to disable the default processing of the right-click (hint : return 1)

Link to post
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 post
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 post
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 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
  • Recently Browsing   0 members

    No registered users viewing this page.

  • Create New...