Hi Aaron. You can prevent resizing of your hidden ColumnHeaders by
subclassing and intercepting the HDN_BEGINTRACK header notification message.
This message is sent to the header control's parent window when the user
begins dragging a divider. However, the columns can still be resized if the
user double clicks on a column separator. You can prevent this by
intercepting the HDN_DIVIDERDBLCLICK header notification message. The code
is as follows:
'Tested on a ListView with 3 ColumnHeaders
'ColumnHeader1 = FirstName
'ColumnHeader2 = LastName
'ColumnHeader3 = FullName
'===============
'Begin Module Code
Option Explicit
Public Const WM_NOTIFY = &H4E
Public Const GWL_WNDPROC = -4
Global lpPrevWndProc As Long
Global gHW As Long
Public Declare Function CallWindowProc Lib "user32" Alias _
"CallWindowProcA" (ByVal lpPrevWndFunc As Long, _
ByVal hwnd As Long, ByVal Msg As Long, _
ByVal wParam As Long, ByVal lParam As Long) As Long
Public Declare Function SetWindowLong Lib _
"user32" Alias "SetWindowLongA" _
(ByVal hwnd As Long, ByVal nIndex As Long, _
ByVal dwNewLong As Long) As Long
Public Declare Sub MoveMemory Lib _
"kernel32" Alias "RtlMoveMemory" _
(pDest As Any, pSource As Any, _
ByVal dwLength As Long)
'The NMHDR structure contains information
'about a notification message.
'The pointer to this structure is specified as
'the lParam member of the WM_NOTIFY message.
Public Type NMHDR
hwndFrom As Long ' Window handle of control sending message
idFrom As Long ' Identifier of control sending message
code As Long ' Specifies the notification code
End Type
Private Type NMHEADER
hdr As NMHDR
iItem As Long
iButton As Long
lPtrHDItem As Long ' HDITEM FAR* pItem
End Type
'Header Notifications
'HDN_BEGINDRAG Drag operation has begun
'HDN_BEGINTRACK User began dragging a divider
'HDN_DIVIDERDBLCLICK User double clicked the divider area
'HDN_ENDDRAG Drag operation has ended
'HDN_ENDTRACK User finished dragging a divider
'HDN_GETDISPINFO Item information request
'HDN_ITEMCHANGED An item has changed
'HDN_ITEMCHANGING An item is changing
'HDN_ITEMCLICK User clicked the control
'HDN_ITEMDBLCLICK User double-clicked the control
'HDN_TRACK User is dragging a divider
'NM_CUSTOMDRAW Custom draw request notification
'NM_RCLICK User clicked right mouse button in control
'NM_RELEASEDCAPTURE Control is releasing mouse capture
Public Enum HD_Notifications
HDN_FIRST = -300&
HDN_LAST = -399&
HDN_GETDISPINFO = (HDN_FIRST - 9)
HDN_BEGINDRAG = (HDN_FIRST - 10)
HDN_ENDDRAG = (HDN_FIRST - 11)
HDN_ITEMCLICK = (HDN_FIRST - 2)
HDN_ITEMDBLCLICK = (HDN_FIRST - 3)
HDN_DIVIDERDBLCLICK = (HDN_FIRST - 5)
HDN_ITEMCHANGING = (HDN_FIRST - 0)
HDN_ITEMCHANGED = (HDN_FIRST - 1)
HDN_BEGINTRACK = (HDN_FIRST - 6)
HDN_ENDTRACK = (HDN_FIRST - 7)
HDN_TRACK = (HDN_FIRST - 8)
NM_FIRST = -0& ' (0U- 0U)
NM_CUSTOMDRAW = (NM_FIRST - 12)
NM_RCLICK = (NM_FIRST - 5)
NM_RELEASEDCAPTURE = (NM_FIRST - 16)
End Enum
Public Sub Hook()
'Establish a hook to capture messages to this window
lpPrevWndProc = SetWindowLong(gHW, _
GWL_WNDPROC, _
AddressOf WindowProc)
End Sub
Public Sub Unhook()
Dim temp As Long
'Reset the message handler for this window
temp = SetWindowLong(gHW, _
GWL_WNDPROC, lpPrevWndProc)
End Sub
Function WindowProc(ByVal hwnd As Long, ByVal uMsg As Long, _
ByVal wParam As Long, ByVal lParam As Long) As Long
Dim nmh As NMHDR
Dim nmhd As NMHEADER
Select Case uMsg
Case WM_NOTIFY
' Fill the NMHDR struct from the lParam pointer.
' (for any WM_NOTIFY msg, lParam always points to a struct which is
' either the NMHDR struct, or whose 1st member is the NMHDR struct)
Call MoveMemory(nmh, ByVal lParam, Len(nmh))
'You could combine HDN_BEGINTRACK
'and HDN_DIVIDERDBLCLICK into one
'(i.e., Case HDN_BEGINTRACK, HDN_DIVIDERDBLCLICK:)
Select Case nmh.code
Case HDN_BEGINTRACK
'User began dragging a divider
Call MoveMemory(nmhd, ByVal lParam, Len(nmhd))
Debug.Print "HDN_BEGINTRACK: " & nmhd.iItem
Select Case nmhd.iItem
'Select Case ListView ColumnHeader Index
'You want to Prevent Tracking
'Note API is 0 based unlike
'ColumnHeaders Collection
'which is 1 based
Case 0
'ListView ColumnHeader Index 1
'First Name Column
'Prevent Tracking
Debug.Print "ListViewColumnHeader: " & _
(nmhd.iItem + 1) & " - Tracking Disabled"
WindowProc = 1
Exit Function
Case 1
'ListView ColumnHeader Index 2
'Last Name Column
'Prevent Tracking
Debug.Print "ListViewColumnHeader: " & _
(nmhd.iItem + 1) & " - Tracking Disabled"
WindowProc = 1
Exit Function
Case Else
'Other ColumnHeaders
'Full Name Column
'Allow Resizing
Debug.Print "ListViewColumnHeader: " & _
(nmhd.iItem + 1) & " - Tracking Enabled"
End Select
Case HDN_DIVIDERDBLCLICK
'User double clicked the divider area
Call MoveMemory(nmhd, ByVal lParam, Len(nmhd))
Debug.Print "HDN_DIVIDERDBLCLICK: " & nmhd.iItem
Select Case nmhd.iItem
'Select Case ListView ColumnHeader Index
'You want to Prevent Resizing if the User
'double clicks on a Column separator
'Note API is 0 based unlike
'ColumnHeaders Collection
'which is 1 based
Case 0
'ListView Column Index 1
'First Name Column
'Prevent Resizing if the User
'double clicks on a Column separator
Debug.Print "ListViewColumnHeader: " & _
(nmhd.iItem + 1) & " - Resizing Disabled"
WindowProc = 1
Exit Function
Case 1
'ListView ColumnHeader Index 2
'Last Name Column
'Prevent Resizing if the User
'double clicks on a Column separator
Debug.Print "ListViewColumnHeader: " & _
(nmhd.iItem + 1) & " - Resizing Disabled"
WindowProc = 1
Exit Function
Case Else
'ListView Column Index 3
'Full Name Column
'nothing
'Allow resize if user double clicks
Debug.Print "ListViewColumnHeader: " & _
(nmhd.iItem + 1) & " - Resizing Enabled"
End Select
End Select
End Select
'Pass message on to the original window message handler
WindowProc = CallWindowProc(lpPrevWndProc, hwnd, _
uMsg, wParam, lParam)
End Function
'End Module Code
'===============
'Begin Form Code
Private Sub Form_Load()
'Store handle
gHW = ListView1.hwnd
Hook
End Sub
Private Sub Form_Unload(Cancel As Integer)
'Pressing the End button or selecting End from _
the Run menu without unhooking causes _
an Invalid Page Fault and closes Microsoft Visual Basic.
'Call procedure to stop intercepting
'the messages for this window
Unhook
End Sub
'End Form Code
'===============
See the following for more info:
Header Control Notification Messages
http://msdn.microsoft.com/library/sdkdoc/shellcc/commctls/header/noti...
ns/notifications.htm
'--------
galen
Quote:
> I have a listview in Report mode with two columns that I want to hide
> because I'm combining them into a third column (First Name, Last Name,
> Full Name). I would like to hide the FirstName and LastName columns and
> only view the FullName column. I can set the column width to zero, but
> the user can still resize the colums and make them reappear.
> Thanks