MyEarth

Listview double click header

7 posts in this topic

#1 ·  Posted (edited)

Hello,

There is an example in the Snippet can avoid sizing of a column of a listview. Work but doesn't avoid resize if used double click on the divider. Searching on the web i have found only solution like subclassing, too complex i want to avoid that. There is also something like this post:

Quote

hate to bump such an old thread, but either something was fixed over the years, or the previous poster was mistaken, but this additional WM_ block will prevent double-click resizing of columns...

at least on XP
not sure of the constants (if there's a A/W versions...) but this is something i wanted so i hope someone else does...

WM_NOTIFY(wParam, lParam, msg, hwnd)
{
   Critical
   Static HDN_BEGINTRACKA = -306, HDN_BEGINTRACKW = -326, HDN_DIVIDERDBLCLICK = -320
   Code := -(~NumGet(lParam+0, 8))-1
   Return, Code = HDN_DIVIDERDBLCLICK || Code = HDN_BEGINTRACKA || Code = HDN_BEGINTRACKW ? True : ""
}

I have try to implement that code ( original code work ) but not work in autoit, at least like i have implemented

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

$hGUI = GUICreate("ListView Fix Column Width", 400, 300)
$hListView = GUICtrlCreateListView("Column 0|Column 1|Column 2|Column 3", 2, 2, 394, 268)
GUISetState()

; Prevent resizing of a specific column (0-based)
Global $iFix_Col = 1

GUIRegisterMsg($WM_NOTIFY, "_WM_NOTIFY")

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

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_BEGINTRACK, $HDN_BEGINTRACKW, $HDN_DIVIDERDBLCLICK
            ; 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

Suggestion how to accomplish this or alternative solution to subclassing?

UPDATE: In this way work, you cant resize $iFix_Col with double click :D

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 $lParam
        Case 0x008CDD80 ; WHAT IS THIS?
            ; 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
    Return $GUI_RUNDEFMSG
EndFunc

How i can get that 0x008CDD80 in a normal way? I have get it with ConsoleWrite and that binary is for double click on this system.

Edited by MyEarth

Share this post


Link to post
Share on other sites



#2 ·  Posted (edited)

Hello. 

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

$hGUI = GUICreate("ListView Fix Column Width", 400, 300)
$hListView = GUICtrlCreateListView("Column 0|Column 1|Column 2|Column 3", 2, 2, 394, 268)
GUISetState()

; Prevent resizing of a specific column (0-based)
Global $iFix_Col = 1

GUIRegisterMsg($WM_NOTIFY, "_WM_NOTIFY")

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

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_BEGINTRACK, $HDN_BEGINTRACKW,$HDN_ITEMCHANGINGW
            ; 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

Saludos

Edited by Danyfirex

Share this post


Link to post
Share on other sites

#3 ·  Posted (edited)

Work, without doubt. But you have replaced HDN_DIVIDERDBLCLICK with -320 but our HDN_DIVIDERDBLCLICK is -305 ( $HDN_FIRST - 5 )

Why $HDN_BEGINTRACK, $HDN_BEGINTRACKW are the same value instead HDN_DIVIDERDBLCLICK not? Maybe isn't HDN_DIVIDERDBLCLICK but another variable? If yes what? I'll ask you because want to avoid any problems on other system when i'll try and i'm also curious.

UPDATE: Yes is a totally different variable:

Case $HDN_BEGINTRACK, $HDN_BEGINTRACKW, $HDN_ITEMCHANGING, $HDN_ITEMCHANGINGW

Thanks for point me in the right direction and also to that authotkeyguy.

No wait is a problem to use $HDN_ITEMCHANGING, stop to update the column...

Edited by MyEarth

Share this post


Link to post
Share on other sites

HDN_DIVIDERDBLCLICK Notifies a header control's   parent window that the user "double-clicked"  You can't prevent resize. 

Instead use HDN_ITEMCHANGING ( -320 ) that allow prevent the changes.

Return value

Returns FALSE to allow the changes, or TRUE to prevent them.

 

Saludos

Share this post


Link to post
Share on other sites

Yes i was right:

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

$hGUI = GUICreate("ListView Fix Column Width", 400, 300)
$hListView = GUICtrlCreateListView("Column 0|Column 1|Column 2|Column 3", 2, 2, 394, 268)
GUISetState()

; Prevent resizing of a specific column (0-based)
Global $iFix_Col = 1

GUIRegisterMsg($WM_NOTIFY, "_WM_NOTIFY")

_GUICtrlListView_SetColumnWidth($hListView, 1, 10) ; this not work if $HDN_ITEMCHANGING, $HDN_ITEMCHANGINGW is enabled

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

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_BEGINTRACK, $HDN_BEGINTRACKW;, $HDN_ITEMCHANGING, $HDN_ITEMCHANGINGW
            ; 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

I need some workaroud or another way.

Share this post


Link to post
Share on other sites

#6 ·  Posted (edited)

Probably you can do something like this.

 

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

Global $g__Prevent = True ;internal use Prevent or no Prevent with _GUICtrlListView_SetColumnWidthEx


$hGUI = GUICreate("ListView Fix Column Width", 400, 300)
$hListView = GUICtrlCreateListView("Column 0|Column 1|Column 2|Column 3", 2, 2, 394, 268)
GUISetState()

; Prevent resizing of a specific column (0-based)
Global $iFix_Col = 1

GUIRegisterMsg($WM_NOTIFY, "_WM_NOTIFY")

_GUICtrlListView_SetColumnWidthEx($hListView, 1, 10) ;now work
Sleep(1000)
_GUICtrlListView_SetColumnWidthEx($hListView, 1, 100) ;now work

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


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_BEGINTRACK, $HDN_BEGINTRACKW, $HDN_ITEMCHANGING, $HDN_ITEMCHANGINGW
            ; Now get column being resized
            Local $iCol = DllStructGetData($tNMHEADER, "Item")
            If $iCol = $iFix_Col And $g__Prevent Then
                ; Prevent resizing
                Return True
            Else
                ; Allow resizing
                Return False
            EndIf
    EndSwitch

EndFunc   ;==>_WM_NOTIFY


Func _GUICtrlListView_SetColumnWidthEx($hWnd, $iCol, $iWidth)
    Local $iRet = 0
    $g__Prevent = False
    If IsHWnd($hWnd) Then
        $iRet = _SendMessage($hWnd, $LVM_SETCOLUMNWIDTH, $iCol, $iWidth)
    Else
        $iRet = GUICtrlSendMsg($hWnd, $LVM_SETCOLUMNWIDTH, $iCol, $iWidth)
    EndIf
    $g__Prevent = True
    Return $iRet
EndFunc   ;==>_GUICtrlListView_SetColumnWidthEx

Saludos

Edited by Danyfirex
Rename variable

Share this post


Link to post
Share on other sites

#7 ·  Posted (edited)

MyEarth,

I would do it this way:

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

$hGUI = GUICreate("ListView Fix Column Width", 500, 500)

$cLV = GUICtrlCreateListView("Column 0|Column 1|Column 2|Column 3", 10, 10, 420, 300)
For $i = 0 To 3
    _GUICtrlListView_SetColumnWidth($cLV, $i, 100)
Next

GUISetState()

; Prevent resizing of a specific column (0-based)
Global $aFix_Col[][] = [[1, 100]]

GUIRegisterMsg($WM_NOTIFY, "_WM_NOTIFY")

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

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")
    ; Get column
    Local $iCol = DllStructGetData($tNMHEADER, "Item")
    Switch $iCode
        Case $HDN_DIVIDERDBLCLICK, $HDN_DIVIDERDBLCLICKW ; Divider double click
            For $i = 0 To UBound($aFix_Col) - 1
                If $iCol = $aFix_Col[$i][0] Then
                    _GUICtrlListView_SetColumnWidth($cLV, $iCol, $aFix_Col[$i][1])
                    ExitLoop
                EndIf
            Next
        Case $HDN_BEGINTRACK, $HDN_BEGINTRACKW ; Divider drag 
            For $i = 0 To UBound($aFix_Col) - 1
                If $iCol = $aFix_Col[$i][0] Then
                    Return True
                    ExitLoop
                EndIf
            Next
            Return False
    EndSwitch

EndFunc

You do need to know the fixed column width you require, but then is that not why you want it fixed?

M23

Edit: And thanks for showing me that the header could be resized by a double-click on the divider - I have just been modifying my GUIListViewEx UDF to prevent this using the same trick as above.

Edited by Melba23

Any of my own code posted anywhere on the forum is available for use by others without any restriction of any kind._______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

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