Jump to content

Listview Disable Column Headers + Mouse cursor


Terenz
 Share

Recommended Posts

Hi all. From this script of Melba:

http://www.autoitscript.com/wiki/Snippets_(_GUI_)#Disable_Specific_Column_Headers

You can disable specific column header. There is only a little problem, the mouse cursor is always changing

2ngr2vo.png

I think there is a EVENT when the mouse is over a column or when you try to change the column width with the mouse but i dont' have found it

Thanks for the help

Nothing is so strong as gentleness. Nothing is so gentle as real strength

 

Link to comment
Share on other sites

  • Moderators

Terenz,

I found that method of disabling single headers in another language and converted it to AutoIt code. I seem to remember that in the original article it was mentioned that there was no simple way to prevent the change to the mouse cursor and that it would involve all sorts of complicated stuff without giving any details of what exactly was required. That was why I did not do it myself. Good luck in your search! :D

M23

Public_Domain.png.2d871819fcb9957cf44f4514551a2935.png Any of my own code posted anywhere on the forum is available for use by others without any restriction of any kind

Open spoiler to see my UDFs:

Spoiler

ArrayMultiColSort ---- Sort arrays on multiple columns
ChooseFileFolder ---- Single and multiple selections from specified path treeview listing
Date_Time_Convert -- Easily convert date/time formats, including the language used
ExtMsgBox --------- A highly customisable replacement for MsgBox
GUIExtender -------- Extend and retract multiple sections within a GUI
GUIFrame ---------- Subdivide GUIs into many adjustable frames
GUIListViewEx ------- Insert, delete, move, drag, sort, edit and colour ListView items
GUITreeViewEx ------ Check/clear parent and child checkboxes in a TreeView
Marquee ----------- Scrolling tickertape GUIs
NoFocusLines ------- Remove the dotted focus lines from buttons, sliders, radios and checkboxes
Notify ------------- Small notifications on the edge of the display
Scrollbars ----------Automatically sized scrollbars with a single command
StringSize ---------- Automatically size controls to fit text
Toast -------------- Small GUIs which pop out of the notification area

 

Link to comment
Share on other sites

I have found a possible solution ( in C++ )

http://www.mikaellinusson.com/tech/2013/09/04/how-to-disable-resizing-in-a-listview-win32-c/

I have try but probably i'm missing something, don't know c++

P.S. I have just noticed you miss to "catch" the double click on the header for automatic resizing, also if is disable it moves :D

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

; The 0-based column to be disabled
Global $iFix_Col, $hHeader

_Main()

Func _Main()
    Local Const $hGUI = GUICreate("ListView Fix Column Width", 400, 300)

    Local Const $hListView = GUICtrlCreateListView("Column 0|Column 1|Column 2|Column 3", 2, 2, 394, 268)
    $hHeader = _GUICtrlHeader_Create($hGUI)
    GUISetState(@SW_SHOWNORMAL)

    ; Prevent resizing of column 1
    $iFix_Col = 1

    GUIRegisterMsg($WM_NOTIFY, "_WM_NOTIFY")

    ; Loop until user exits
    Do
    Until GUIGetMsg() = $GUI_EVENT_CLOSE
EndFunc   ;==>_Main

Func _WM_NOTIFY($hWnd, $iMsg, $wParam, $lParam)
    #forceref $hWnd, $iMsg, $wParam
    ; Get details of message
    Local Const $tNMHEADER = DllStructCreate($tagNMHEADER, $lParam)
    Local $tNMHDR = DllStructCreate($tagNMHDR, $lParam)
    Local $hWndFrom = DllStructGetData($tNMHDR, "hWndFrom")
    Local Const $iCode = DllStructGetData($tNMHEADER, "Code")
    Switch $hWndFrom
        Case $hHeader
            Switch $iCode
                Case $WM_SETCURSOR
                    Return True
            EndSwitch
    EndSwitch
    Switch $iCode
        Case $HDN_BEGINTRACKW
            ; Now get column being resized
            Local $iCol = DllStructGetData($tNMHEADER, "Item")
            If $iCol = $iFix_Col Then
                ; Prevent resizing
                Return True
            Else
                ; Allow resizing
                Return False
            EndIf
    EndSwitch
EndFunc   ;==>_WM_NOTIFY
Edited by Terenz

Nothing is so strong as gentleness. Nothing is so gentle as real strength

 

Link to comment
Share on other sites

  • Moderators

Terenz ,

Good find. :thumbsup:

That does not look too difficult to implement - it is a simple subclassing of the ListView header. I will take a look later today and see what I can come up with - but perhaps you can try yourself and see if you can beat me to a solution. ;)

M23

Public_Domain.png.2d871819fcb9957cf44f4514551a2935.png Any of my own code posted anywhere on the forum is available for use by others without any restriction of any kind

Open spoiler to see my UDFs:

Spoiler

ArrayMultiColSort ---- Sort arrays on multiple columns
ChooseFileFolder ---- Single and multiple selections from specified path treeview listing
Date_Time_Convert -- Easily convert date/time formats, including the language used
ExtMsgBox --------- A highly customisable replacement for MsgBox
GUIExtender -------- Extend and retract multiple sections within a GUI
GUIFrame ---------- Subdivide GUIs into many adjustable frames
GUIListViewEx ------- Insert, delete, move, drag, sort, edit and colour ListView items
GUITreeViewEx ------ Check/clear parent and child checkboxes in a TreeView
Marquee ----------- Scrolling tickertape GUIs
NoFocusLines ------- Remove the dotted focus lines from buttons, sliders, radios and checkboxes
Notify ------------- Small notifications on the edge of the display
Scrollbars ----------Automatically sized scrollbars with a single command
StringSize ---------- Automatically size controls to fit text
Toast -------------- Small GUIs which pop out of the notification area

 

Link to comment
Share on other sites

Thanks. Sure i'm trying right now, the main goal is to make everething in the same WM_NOTIFY without register another message, if is possible

Edited by Terenz

Nothing is so strong as gentleness. Nothing is so gentle as real strength

 

Link to comment
Share on other sites

  • Moderators

Terenz,

It is a bit more complicated than that. :D

I have got the ListView header subclassed and prevented the cursor from changing, but the GUI then becomes unresponsive: :(

#include <GuiConstantsEx.au3>
#include <WindowsConstants.au3>
#include <GuiListView.au3>
#include <HeaderConstants.au3>
#include <WinAPI.au3>

; The 0-based column to be disabled
Global $iFix_Col
Global $hOld_WndProc
; Get new WndProc hamdle and pointer
Global $hNew_WndProc = DllCallbackRegister("_New_LVHdr_Proc", "lresult", "hwnd;uint;wparam;lparam")
Global $pNew_WndProc = DllCallbackGetPtr($hNew_WndProc)
; To save old WndProc handle
Global $hOld_WndProc

_Main()

Func _Main()
    Local Const $hGUI = GUICreate("ListView Fix Column Width", 400, 300)
    
    Local Const $cListView = GUICtrlCreateListView("Column 0|Column 1|Column 2|Column 3", 10, 10, 380, 220)
    GUICtrlCreateListViewItem("0|1|2|3", $cListView)

    Global $hLVHdr = _GUICtrlListView_GetHeader($cListView)
    
    $cButton = GUICtrlCreateButton("Test", 10, 250, 80, 30)

    GUISetState()

    ; Prevent resizing of column 1
    $iFix_Col = 1

    ; Prevent drag resize
    GUIRegisterMsg($WM_NOTIFY, "_WM_NOTIFY")

    ; SubClass LV Header
    $hOld_WndProc = _WinAPI_SetWindowLong($hLVHdr, $GWL_WNDPROC, $pNew_WndProc)
    ConsoleWrite("Old proc: 0x" & Hex($hOld_WndProc, 8) & @CRLF)

    ; Loop until user exits
    While 1
        Switch GUIGetMsg()
            Case $GUI_EVENT_CLOSE
                Exit
            Case $cButton
                ConsoleWrite("Pressed" & @CRLF)
        EndSwitch
    WEnd

    GUIDelete($hGUI)
EndFunc   ;==>_Main

Func _WM_NOTIFY($hWnd, $iMsg, $wParam, $lParam)

    ; Get details of message
    Local $tNMHEADER = DllStructCreate($tagNMHEADER, $lParam)
    ; Look for header resize code
    $iCode = DllStructGetData($tNMHEADER, "Code")
    Switch $iCode
        Case $HDN_BEGINTRACKW
            ; Now get column being resized
            Local $iCol = DllStructGetData($tNMHEADER, "Item")
            If $iCol = $iFix_Col Then
                ; Prevent resizing
                Return True
            Else
                ; Allow resizing
                Return False
            EndIf
    EndSwitch

EndFunc

Func _New_LVHdr_Proc($hWnd, $iMsg, $wParam, $lParam)

    Switch $iMsg
        Case $WM_SETCURSOR
            Return TRUE
    EndSwitch

    ; Now call previous WndProc and complete the chain
    Return _WinAPI_CallWindowProc($hOld_WndProc, $hWnd, $iMsg, $wParam, $lParam)

EndFunc   ;==>_No_LVHdr_Resize
It also blocks the cursor change for all columns. Anyone got any bright ideas? :huh:

M23

Public_Domain.png.2d871819fcb9957cf44f4514551a2935.png Any of my own code posted anywhere on the forum is available for use by others without any restriction of any kind

Open spoiler to see my UDFs:

Spoiler

ArrayMultiColSort ---- Sort arrays on multiple columns
ChooseFileFolder ---- Single and multiple selections from specified path treeview listing
Date_Time_Convert -- Easily convert date/time formats, including the language used
ExtMsgBox --------- A highly customisable replacement for MsgBox
GUIExtender -------- Extend and retract multiple sections within a GUI
GUIFrame ---------- Subdivide GUIs into many adjustable frames
GUIListViewEx ------- Insert, delete, move, drag, sort, edit and colour ListView items
GUITreeViewEx ------ Check/clear parent and child checkboxes in a TreeView
Marquee ----------- Scrolling tickertape GUIs
NoFocusLines ------- Remove the dotted focus lines from buttons, sliders, radios and checkboxes
Notify ------------- Small notifications on the edge of the display
Scrollbars ----------Automatically sized scrollbars with a single command
StringSize ---------- Automatically size controls to fit text
Toast -------------- Small GUIs which pop out of the notification area

 

Link to comment
Share on other sites

Melba,

Do you know an autoit issue with the subclassing where the internal code seems to be stuck in an infinite loop so that you can't do anything?

I'm saying this because it's the same thing in your script.

Edit: Resize a column and you'll see what's going on.

Edited by FireFox
Link to comment
Share on other sites

  • Moderators

FireFox,

No, it is a new problem to me - I can see what is happening, but I have no idea why. Whenever I have subclassed controls before it has worked without problem - see my NoFocusLines & GUIFrame UDFs for examples. So I am at a loss as to why it is happening this time. :wacko:

M23

Public_Domain.png.2d871819fcb9957cf44f4514551a2935.png Any of my own code posted anywhere on the forum is available for use by others without any restriction of any kind

Open spoiler to see my UDFs:

Spoiler

ArrayMultiColSort ---- Sort arrays on multiple columns
ChooseFileFolder ---- Single and multiple selections from specified path treeview listing
Date_Time_Convert -- Easily convert date/time formats, including the language used
ExtMsgBox --------- A highly customisable replacement for MsgBox
GUIExtender -------- Extend and retract multiple sections within a GUI
GUIFrame ---------- Subdivide GUIs into many adjustable frames
GUIListViewEx ------- Insert, delete, move, drag, sort, edit and colour ListView items
GUITreeViewEx ------ Check/clear parent and child checkboxes in a TreeView
Marquee ----------- Scrolling tickertape GUIs
NoFocusLines ------- Remove the dotted focus lines from buttons, sliders, radios and checkboxes
Notify ------------- Small notifications on the edge of the display
Scrollbars ----------Automatically sized scrollbars with a single command
StringSize ---------- Automatically size controls to fit text
Toast -------------- Small GUIs which pop out of the notification area

 

Link to comment
Share on other sites

Have you got any issues with the quoted examples ? I can't reproduce the bug.

If you want we can talk by PM. I have this issue with a script so I dropped it...

I'm willing to open a ticket if nothing is found to prevent it.

Edited by FireFox
Link to comment
Share on other sites

  • Moderators

FireFox,

I suggest opening a thread in Dev Chat to attract the attention of the cognoscenti. Post your failing example and I will add mine. Both of the UDFs I mentioned above still work so there is no obvious problem with subclassing itself in AutoIt - it must be something in these particular cases. :wacko:

M23

Public_Domain.png.2d871819fcb9957cf44f4514551a2935.png Any of my own code posted anywhere on the forum is available for use by others without any restriction of any kind

Open spoiler to see my UDFs:

Spoiler

ArrayMultiColSort ---- Sort arrays on multiple columns
ChooseFileFolder ---- Single and multiple selections from specified path treeview listing
Date_Time_Convert -- Easily convert date/time formats, including the language used
ExtMsgBox --------- A highly customisable replacement for MsgBox
GUIExtender -------- Extend and retract multiple sections within a GUI
GUIFrame ---------- Subdivide GUIs into many adjustable frames
GUIListViewEx ------- Insert, delete, move, drag, sort, edit and colour ListView items
GUITreeViewEx ------ Check/clear parent and child checkboxes in a TreeView
Marquee ----------- Scrolling tickertape GUIs
NoFocusLines ------- Remove the dotted focus lines from buttons, sliders, radios and checkboxes
Notify ------------- Small notifications on the edge of the display
Scrollbars ----------Automatically sized scrollbars with a single command
StringSize ---------- Automatically size controls to fit text
Toast -------------- Small GUIs which pop out of the notification area

 

Link to comment
Share on other sites

Alright :)

Now back to the thread, the best corresponding code I've found is -12 for the NOTIFY message (I didn't find the constant associated with it), but the structure does not return the hovered item...

I would get the mouse position to find the column hovered and then change the cursor or not.

Br, FireFox.

Link to comment
Share on other sites

I can't make so much for help you guys. This script prevent the resizing AND the double click on the column, nothing about the cursor

#include <GUIConstants.au3>
#include <WindowsConstants.au3>
#include <StructureConstants.au3>
#include <HeaderConstants.au3>

Global $iFix_Col = 1
Global Const $HDN_ITEMCHANGINGA = $HDN_FIRST - 0

$hGUI = GUICreate("Test", 420, 240)
$iListView = GUICtrlCreateListView("Column1|Column2", 20, 20, 380, 200)
GUICtrlCreateListViewItem("Item 1|SubItem 1", $iListView)
GUICtrlCreateListViewItem("Item 2|SubItem 2", $iListView)

GUIRegisterMsg($WM_NOTIFY, "_WM_NOTIFY")

GUISetState(@SW_SHOW)

While 1
    $nMsg = GUIGetMsg()
    Switch $nMsg
        Case $GUI_EVENT_CLOSE
            Exit
    EndSwitch
WEnd

Func _WM_NOTIFY($hWndGUI, $MsgID, $wParam, $lParam)
    Local Const $tNMHEADER = DllStructCreate($tagNMHEADER, $lParam)
    Local Const $TagNMHDR = DllStructCreate("int;int;int", $lParam)
    Local Const $iEvent = DllStructGetData($TagNMHDR, 3)
    Switch $iEvent
        Case $HDN_ITEMCHANGINGA, $HDN_ITEMCHANGINGW
            Local $iCol = DllStructGetData($tNMHEADER, "Item")
            If $iCol = $iFix_Col Then Return True
    EndSwitch
    Return $GUI_RUNDEFMSG
EndFunc   ;==>WM_NOTIFY

If can be useful:

http://msdn.microsoft.com/en-us/library/windows/desktop/bb775238(v=vs.85).aspx

Edited by Terenz

Nothing is so strong as gentleness. Nothing is so gentle as real strength

 

Link to comment
Share on other sites

This work also for the mouse cursor:

Original post:

#include <GUIConstantsEx.au3>
#include <Constants.au3>
#include <WindowsConstants.au3>
#include <GuiListView.au3>

Global $iFix_Col = 1
Global $hListView, $hHeader
Global $wProcOld, $wProcNew
Global Const $HDN_ITEMCHANGINGA = $HDN_FIRST - 0

Local $iExWindowStyle = BitOR($WS_EX_DLGMODALFRAME, $WS_EX_CLIENTEDGE)
Local $iExListViewStyle = BitOR($LVS_EX_FULLROWSELECT, $LVS_EX_SUBITEMIMAGES, $LVS_EX_GRIDLINES, $LVS_EX_CHECKBOXES, $LVS_EX_DOUBLEBUFFER)

GUICreate("ListView", 300, 200, -1, -1)

$hListView = GUICtrlCreateListView("Column1|Col2|Col3", 10, 10, 280, 180, -1, $iExWindowStyle)
_GUICtrlListView_SetExtendedListViewStyle($hListView, $iExListViewStyle)
$hHeader = HWnd(_GUICtrlListView_GetHeader($hListView))

GUICtrlCreateListViewItem("item2|col22|col23", $hListView)
GUICtrlCreateListViewItem("item1|col12|col13", $hListView)
GUICtrlCreateListViewItem("item3|col32|col33", $hListView)

$wProcNew = DllCallbackRegister("_HeaderWindowProc", "ptr", "hwnd;uint;wparam;lparam")
$wProcOld = _WinAPI_SetWindowLong($hHeader, $GWL_WNDPROC, DllCallbackGetPtr($wProcNew))
GUISetState()

_GUICtrlListView_RegisterSortCallBack($hListView, False)
GUIRegisterMsg($WM_NOTIFY, "_WM_NOTIFY")

While 1
    Switch GUIGetMsg()
        Case $GUI_EVENT_CLOSE
            ExitLoop
    EndSwitch
WEnd

_GUICtrlListView_UnRegisterSortCallBack($hListView)
GUIRegisterMsg($WM_NOTIFY, "")

; required on exit if subclassing
If $wProcOld Then
    _WinAPI_SetWindowLong($hHeader, $GWL_WNDPROC, $wProcOld)
EndIf
; Delete callback function
If $wProcNew Then DllCallbackFree($wProcNew)
Exit

Func _WM_NOTIFY($hWnd, $iMsg, $iwParam, $ilParam)
    #forceref $hWnd, $iMsg, $iwParam
    Local $hWndFrom, $iCode, $tNMHDR, $tNMHEADER, $hWndListView
    $hWndListView = $hListView
    If Not IsHWnd($hListView) Then $hWndListView = GUICtrlGetHandle($hListView)
    $tNMHDR = DllStructCreate($tagNMHDR, $ilParam)
    $hWndFrom = HWnd(DllStructGetData($tNMHDR, "hWndFrom"))
    $iCode = DllStructGetData($tNMHDR, "Code")
    $tNMHEADER = DllStructCreate($tagNMHEADER, $ilParam)
    Switch $hWndFrom
        Case $hHeader
            Switch $iCode
                Case $HDN_ITEMCHANGINGA, $HDN_ITEMCHANGINGW
                    Return True
            EndSwitch
        Case $hWndListView
            Switch $iCode
                Case $LVN_COLUMNCLICK ; A column was clicked
                    Local $tInfo = DllStructCreate($tagNMLISTVIEW, $ilParam)

                    ; Kick off the sort callback
                    _GUICtrlListView_SortItems($hWndFrom, DllStructGetData($tInfo, "SubItem"))
                    ; No return value
            EndSwitch
    EndSwitch
    Return $__LISTVIEWCONSTANT_GUI_RUNDEFMSG
EndFunc   ;==>_WM_NOTIFY

; subclass function
Func _HeaderWindowProc($hWnd, $iMsg, $wParam, $lParam)
    #forceref $hWnd, $iMsg, $wParam, $lParam
    Switch $hWnd
        Case $hHeader
            Switch $iMsg
                Case $WM_SETCURSOR;, $WM_LBUTTONDOWN
                    Return False
            EndSwitch
    EndSwitch
    Return _WinAPI_CallWindowProc($wProcOld, $hWnd, $iMsg, $wParam, $lParam)
EndFunc   ;==>_HeaderWindowProc

It disable the cursor for all the column, no way to disable only for the first also using a $flag

Nothing is so strong as gentleness. Nothing is so gentle as real strength

 

Link to comment
Share on other sites

Is pratically the same, i didn't notice.

An easy way, is possible to set an event on hover on the column header ( like find the area occupied by the header with GetWindowRect and if mouse is in that area = hover ) and if disabled ( just check the flag ) then use guisetcursor with the arrow?

Or guisetcursor will be overrided by the listview?

Edited by Terenz

Nothing is so strong as gentleness. Nothing is so gentle as real strength

 

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