Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

ListView Column

63 views
Skip to first unread message

Rob Panosh

unread,
Jan 8, 2002, 4:04:31 PM1/8/02
to
I am trying to keep the user from sizing certian ListView columns. For
example I Have the following columns

FirstName LastName Address

If the user uses the mouse and clicks in between the column headers they can
resize. I want to prevent the user from doing this on certian columns.
Does anybody know how to do this? ... or what messages to trap on the
ListView when the column header starts to resize?

Thanks,
--
Rob Panosh
Advanced Software Designs

Tom

unread,
Jan 9, 2002, 9:17:57 AM1/9/02
to
Check out the LVN_BEGINLABELEDIT and LVN_ENDLABELEDIT. I am not sure if they
will help you. From the Win32SDK, it says the notification messages are sent to
the parent window, so you might need to subclass your window and add these to
its dispatch method.

Tom Wood
Thomas Wood - Programmer
Bainbridge, Pennsylvania, USA
(717) 615-2215

Amilcar A. Camargo

unread,
Jan 9, 2002, 12:36:06 PM1/9/02
to
Hi Rob,

On Tue, 8 Jan 2002 15:04:31 -0600, "Rob Panosh"
<rob_p...@asdsoftware.com> wrote:

>I am trying to keep the user from sizing certian ListView columns. For
>example I Have the following columns

[snip]

From MSDN, HDN_BEGINTRACK notification message is sent to your
listview when the user begins to resize a column. If you code a
dispatch for your listview and return TRUE, resizing is prevented (I
haven't tested it).

HTH,

Amilcar A. Camargo F.
Sand, S. A.
Guatemala, C. A.

Rob Panosh

unread,
Jan 9, 2002, 4:11:48 PM1/9/02
to
Amilcar,

I am not an expert on trapping these kind of messages. Here is a start of
my dispatch on my Split window that owns the listview. Could you ( or
somebody else lurking ) give me a little help?

METHOD Dispatch(oEvent) CLASS FormQueryResults_STD // this is a splitwindow.
//
//s
//
// REP: 12.21.2001 - Created.

// Note: My listview is in the first pane.

DO CASE

CASE oEvent:Message == WM_NOTIFY
// I am assuming this is where I trap the HDN_BEGINTRACK message.
// Some help would be appreciated.


ENDCASE


RETURN SUPER:Dispatch(oEvent)


Thanks,
Rob Panosh


"Amilcar A. Camargo" <acam...@acfsoft.com> wrote in message
news:3c3c7afe...@News.cis.dfn.de...

Marc

unread,
Jan 9, 2002, 4:21:18 PM1/9/02
to
Rob,

Search message to/from me around 6 months ago.

You're going to have to get a handle to the header control used by the
ListView. Search CodeGuru or some other such programmer sites.

Then you can intercept messages to the header.
Here are a few methods from my browser class and my Header control
class that I use to handle this issue with Classmate's browser control.
IIRC, the header control's owner-draw stuff was for other issues.

HTH,

-Marc-

//
class FpHeaderControl inherit cHeaderControl
//
~"ONLYEARLY+"
protect nCurrentCol as longint
protect lAllowItemResize as logic

declare access ColumnNo
declare assign ColumnNo
declare method GoOwnerDraw
declare method DisableItemResize
~"ONLYEARLY-"
//
//
access ColumnNo as longint pascal class FpHeaderControl
//
~"ONLYEARLY+"
return self:nCurrentCol
~"ONLYEARLY-"
//
//
assign ColumnNo(nCol as longint) as longint pascal class FpHeaderControl
//
~"ONLYEARLY+"
self:nCurrentCol := nCol
return nCol
~"ONLYEARLY-"
//
//
method Init(oParent,xID,oOrigin,oSize,cClassName,nStyle,nExtStyle) class FpHeaderControl
// Initialize and subclass

//default nStyle to _or(WS_CHILD,HDS_BUTTONS,HDS_HORZ,)

super:Init(oParent,xID,oOrigin,oSize,cClassName,nStyle,nExtStyle)
self:Subclass()

self:lAllowItemResize := true
self:nCurrentCol := -1

return self
//
//
method _ProcessNotifyMsg(oEvent as cControlNotifyEvent) as longint pascal class FpHeaderControl
//
~"ONLYEARLY+"
if oEvent:NotifyCode == HDN_BEGINTRACK
if .not. self:lAllowItemResize
return 1L // Don't do it
endif
endif
return super:_ProcessNotifyMsg(oEvent)

~"ONLYEARLY-"
//
//
method OnSetCursor(oEvent as cEvent) as longint pascal class FpHeaderControl
// Prevent Cursor change if .not. lAllowItemResize
~"ONLYEARLY+"
// Intercept Divider Drag
if .not. self:lAllowItemResize
return 1
endif
return super:OnSetCursor(oEvent)
~"ONLYEARLY-"
//
//
method OnMouseButtonDown(oEvent as cMouseEvent) as longint pascal class FpHeaderControl
// Prevent sensitivity to Divider Click when .not. lAllowItemResize
local nHitTestCodes as dword
local nItemIndex as longint
local oBB as cBoundingBox
local nX as longint
local nPos as dword
~"ONLYEARLY+"
if .not. self:lAllowItemResize

nItemIndex := self:HitTest( oEvent:Position, @nHitTestCodes )

if _and(nHitTestCodes, HHT_ONDIVIDER) == HHT_ONDIVIDER

// Is the divider click inside THIS item?
oBB := self:GetItemBoundingBox(nItemIndex)

if .not. oBB:PointInside(oEvent:Position)

// Must be in the NEXT!
oBB := self:GetItemBoundingBox(nItemIndex + 1)
endif

// Send a dummy click to the selected item
// Make sure the position is well centered within the item
nX := oBB:Left + ( (oBB:Right - oBB:Left) / 2 )
nPos := MakeLong(word(_cast, nX), word(_cast, oEvent:Position:Y))

self:SendMessage( WM_LBUTTONDOWN, MK_LBUTTON, longint(_cast, nPos) )
return 0
endif
endif
return super:OnMouseButtonDown(oEvent)
~"ONLYEARLY-"
//
//
method DisableItemResize() as void pascal class FpHeaderControl
// Disable Resizing of items via divider dragging
~"ONLYEARLY+"
self:lAllowItemResize := false
return
~"ONLYEARLY-"
//
//
method GoOwnerDraw() as void pascal class FpHeaderControl
// Convert all Header items to ownerdraw
local nItemIndex as longint
local oHdrItem as cHeaderControlItem
~"ONLYEARLY+"
for nItemIndex := 0 upto (self:ItemCount - 1)
oHdrItem := self:GetItem(nItemIndex)
oHdrItem:Alignment := HDF_OWNERDRAW
self:SetItemAttributes( oHdrItem, nItemIndex)
next

return
~"ONLYEARLY-"
//
//
method OnOwnerDraw_DrawItem(oEvent as cEvent) as longint pascal class FpHeaderControl
// custom draw for multi-line Header items
local sDI as _WINDRAWITEMSTRUCT
local oHdrItem as cHeaderControlItem
local pText as psz
local sDrawRect is _WINRECT
~"ONLYEARLY+"
// Get the DrawItem structure
sDI := ptr(_cast, oEvent:lParam)

// Get the individual Header Item info.
oHdrItem := self:GetItem( longint(_cast, sDi.ItemId) )

// Draw the header text
pText := StringAlloc( oHdrItem:Caption )

// Adjust the rectangle so we start text a bit further down
CopyRect(@sDrawRect, @sDi.rcItem)
sDrawRect.Top += 1

DrawText(sDI.hDC, pText, longint(_cast, sLen(oHdrItem:Caption)), @sDrawRect, DT_CENTER)

MemFree(pText)

return Longint(_cast, TRUE)
~"ONLYEARLY-"
//
//
///////////////////////////////////////////////////////////////////
//
method Init(oParent,xID,oOrigin,oSize,nStyle,nExtStyle) class FpDataBrowser

.. Excerpt sample: replace the default header control with my own
// Replace the cHeaderControl with FpHeaderControl
self:oHdr:EndWindow()
self:oHdr := NULL_OBJECT

self:oHdr := FpHeaderControl{self}
self:oHdr:_AutoAlign(NULL_OBJECT)
self:oHdr:Show(SW_NORMAL)
.. Other init
//
//
method DisableColResize() as void pascal class FpDataBrowser
// Disable Resizing of columns via Header item divider dragging
local oHeader as FpHeaderControl
~"ONLYEARLY+"
self:lEnableColResize := false
oHeader := self:oHdr
oHeader:DisableItemResize()
return
~"ONLYEARLY-"
//
//
method OnHeaderControlItemClick(oEvent as cHeaderControlItemClickEvent) as longint pascal class FpDataBrowser
// Process Mouse Clicks on the Header Control. DividerDoubleClick == AutoSize.

local nItem as longint

~"ONLYEARLY+"

if !self:EditEnd(false)
return 0
endif

// See if Parent:OnDataBrowserColumnClick() wants to handle this.
if logic(_cast, self:_FireEvent(DBE_COLUMNCLICK, oEvent))

nItem := oEvent:ItemIndex
if nItem >= 0 .and. nItem <= self:nLastColumn

do case
// Single Click to header.
case oEvent:Click

// Sort by the column
// Do not handle here. Handle in subclass.
// self:SortOnColumn(nItem)
// self:Refresh()

// Double Click on Divider.
case oEvent:DividerDoubleClick

if self:lEnableColResize
// Automatically size the column
self:AutoSizeColumn(nItem)

self:Repaint()
self:_ExtEditSetColOptControlPos()
endif

endcase

endif
endif

return 0
~"ONLYEARLY-"

//

Amilcar A. Camargo

unread,
Jan 9, 2002, 10:02:29 PM1/9/02
to
Rob,

On Wed, 9 Jan 2002 15:11:48 -0600, "Rob Panosh"
<rob_p...@asdsoftware.com> wrote:

>Amilcar,
>
>I am not an expert on trapping these kind of messages.

I'm not either... :-)

> Here is a start of
>my dispatch on my Split window that owns the listview. Could you ( or
>somebody else lurking ) give me a little help?
>
>METHOD Dispatch(oEvent) CLASS FormQueryResults_STD // this is a splitwindow.

My best bet is that you have to catch it up in your ListView subclass.
The header control is a child of your ListView. The following code
should get you started. It's from the top of my mind so you have to
double check it:

[Begin Sample]
METHOD Dispatch( oEv ) CLASS MyListView
LOCAL pNM AS _winNMHEADER

DO CASE

// Notify
CASE oEv:Message == WM_NOTIFY

pNM := PTR( _CAST, oEv:lParam )

// If resizing my column
IF pNM.hdr._code == HDN_BEGINTRACK

// If its on my column (zero based)
IF pNM.iItem == 2 // Third column
RETURN 1L // No allow
ENDIF

ENDIF

ENDCASE

RETURN SUPER:Dispatch( oEv )

[End Sample]

Rob Panosh

unread,
Jan 10, 2002, 8:16:02 AM1/10/02
to
Amilcar,

I put the following code on my list view and you can see I have a tone
within the HDN_BEGINTRACK and it never go off. Looks like the message is
never passed. Any Ideas?

Rob

METHOD Dispatch(oEvent) CLASS FormQueryResultsLV_STD
LOCAL pNM AS _winNMHEADER


//
//s
//
// REP: 12.21.2001 - Created.


DO CASE

CASE oEvent:Message == WM_NOTIFY

pNM := PTR( _CAST, oEvent:lParam )

// If resizing my column
IF pNM.hdr._code == HDN_BEGINTRACK

Tone(1800,1)


// If its on my column (zero based)
IF pNM.iItem == 2 // Third column
RETURN 1L // No allow
ENDIF

ENDIF


CASE oEvent:Message == WM_MOUSEWHEEL

IF HiWord( oEvent:wParam ) = 65416 // scrollind down ... if scrolling up
it will = 120
SendMessage(SELF:Owner:Handle(0), (WM_USER+99), UNITINCREMENT, 0 )
ENDIF

ENDCASE


RETURN SUPER:Dispatch(oEvent)

"Amilcar A. Camargo" <acam...@acfsoft.com> wrote in message

news:3c3d00b...@News.cis.dfn.de...

Stephane Hebert

unread,
Jan 10, 2002, 11:29:35 AM1/10/02
to
Rob,

Maybe your system is "tone deaf" ?
You could always use MessageBeep(), remember ? <g>


--
============================
Stéphane Hébert
ste...@audiocontrole.com
============================


"Rob Panosh" <rob_p...@asdsoftware.com> a écrit dans le message news:
3c3d...@nntp01.splitrock.net...


> Amilcar,
>
> I put the following code on my list view and you can see I have a tone
> within the HDN_BEGINTRACK and it never go off. Looks like the message is
> never passed. Any Ideas?
>
> Rob
>
> METHOD Dispatch(oEvent) CLASS FormQueryResultsLV_STD
> LOCAL pNM AS _winNMHEADER
> //

> file://s

Rob Panosh

unread,
Jan 10, 2002, 11:54:03 AM1/10/02
to
No it is not Tone deaf.

"Stephane Hebert" <sgtp...@bootcamp.com> wrote in message
news:Fgj%7.10785$p04.3...@news20.bellglobal.com...

Amilcar A. Camargo

unread,
Jan 10, 2002, 3:56:06 PM1/10/02
to
Rob,

On Thu, 10 Jan 2002 07:16:02 -0600, "Rob Panosh"
<rob_p...@asdsoftware.com> wrote:

>Amilcar,
>


>I put the following code on my list view and you can see I have a tone
>within the HDN_BEGINTRACK and it never go off. Looks like the message is
>never passed. Any Ideas?

[snip]

Let me put some time appart to test it and see if I can come with
something usefull.

Regards,

Rob Panosh

unread,
Jan 10, 2002, 4:06:29 PM1/10/02
to
Thanks I appreciate that.

"Amilcar A. Camargo" <acam...@acfsoft.com> wrote in message

news:3c3dfac7...@News.cis.dfn.de...

Amilcar A. Camargo

unread,
Jan 10, 2002, 9:04:29 PM1/10/02
to
Rob,

On Thu, 10 Jan 2002 20:56:06 GMT, acam...@acfsoft.com (Amilcar A.
Camargo) wrote:

>Let me put some time appart to test it and see if I can come with
>something usefull.

After some testing, even if I catch the TRACKING messages the ListView
column gets resized. Below is a copy of a message sometime ago, BTW a
response to Stephane from Paolo Cherubini:

[Begin Copy]

From: "Paolo Cherubini" <pa...@ats.it>
Date: Mon, 24 Sep 2001 18:19:46 +0200

Hello,

Try the following code.
It simply restore the original width of an item in the header of a
listview after a drag.

Ciao Paolo
------------------------------
METHOD Dispatch(oE) CLASS MyWindow

STATIC lStart:=FALSE AS LOGIC , ;
nItem :=0 AS INT , ;
nLung :=0 AS INT

LOCAL sNotifica AS _winHD_NOTIFY, ;
sColonna IS _WINHDITEM

&& Select the notify messages
IF oE:Message=WM_NOTIFY

&& Fill the structure with the notify informations
sNotifica:=PTR(_CAST, oE:lParam)

&& The user is dragging a divider in the header control
IF sNotifica.hdr._code=HDN_TRACK

IF !lStart

&& Do remeber next call the dragging already started
lStart:=TRUE

&& Ask the header control about the width of the
&& current item at this moment
sColonna.Mask:=HDI_WIDTH

SendMessage(sNotifica.hdr.hwndFrom , ;
HDM_GETITEM , ;
DWORD(_CAST, sNotifica.iItem), ;
LONGINT(_CAST, @sColonna))

&& Store the item width
nLung:=sColonna.cxy

&& Store the item number
nItem:=sNotifica.iItem

ENDIF

// The item changed
ELSEIF sNotifica.hdr._code==HDN_ITEMCHANGED

&& lStart true in here means the user finished doing the drag
IF lStart

SUPER:Dispatch(oE)

lStart:=FALSE

&& Restore the original width of the item
sColonna.Mask := HDI_WIDTH
sColonna.cxy := nLung

SendMessage(sNotifica.hdr.hwndFrom, ;
HDM_SETITEM , ;
DWORD(_CAST, nItem) , ;
LONGINT(_CAST, @sColonna))

RETURN 0L

ENDIF

ENDIF

ENDIF

RETURN SUPER:Dispatch(oE)

[End Copy]

HTH,

Karl-Heinz Rauscher

unread,
Jan 11, 2002, 2:29:26 AM1/11/02
to
Rob,

i trap HDN_ITEMCHANGING and check for HDI_WIDTH. The advantage is that a
user keyboard input like [strg][alt][+] is recognized also. The columns to
prevent from resizing are stored in a array that you must fill
via the Preventresizing assign.

sample:

oDCListView1:Preventresizing := { #COLUMN1 , #COLUMN4 }

regards
Karl-Heinz

----------------------------------

STRUCT _winHDITEM

MEMBER mask AS DWORD
MEMBER cxy AS INT
MEMBER pszText AS PSZ
MEMBER hbm AS PTR
MEMBER cchTextMax AS INT
MEMBER fmt AS INT
MEMBER lParam AS LONG
MEMBER iImage AS INT
MEMBER iOrder AS INT


STRUCT _winNMHEADER
MEMBER hdr IS _WINNMHDR
MEMBER iItem AS INT
MEMBER iButton AS INT
MEMBER pitem AS _WINHDITEM


DEFINE HDN_ITEMCHANGING := (HDN_FIRST-20) // Error: only the
HDN_ITEMCHANGINGW DEFINE works ....


CLASS NewListView INHERIT ListView

PROTECT _aPreventResize := {} AS ARRAY

METHOD Dispatch ( oEvent ) CLASS MyListView
LOCAL struNotify AS _winNMHDR
LOCAL struMHeader AS _winNMHEADER
LOCAL oColumn AS ListViewColumn
LOCAL nColumn AS LONG
LOCAL symColumn AS SYMBOL


DO CASE
CASE oEvent:message == WM_NOTIFY

struNotify := PTR ( _CAST , oEvent:lParam )


IF struNotify._code == HDN_ITEMCHANGING

struMHeader := PTR ( _CAST , oEvent:lParam )

IF _and ( struMHeader.pItem.mask , HDI_WIDTH ) == HDI_WIDTH

nColumn := struMHeader.iItem + 1

IF ( oColumn := SELF:__GetColumnFromIndex(nColumn) ) != NULL_OBJECT

symColumn := oColumn:namesym

IF AScan ( SELF:PreventResize , { | a | a == symColumn } ) > 0

RETURN SELF:eventReturnvalue := 1L

ENDIF

ENDIF

ENDIF


ENDIF

ENDCASE

RETURN SUPER:Dispatch ( oEvent )


METHOD INIT( oOwner , nID, oPoint, oDimension, kStyle ) CLASS NewListView

SUPER:INIT ( oOwner , nID, oPoint, oDimension, kStyle )


ACCESS PreventResize () CLASS NewListView

RETURN _aPreventResize

ASSIGN PreventResize ( aColumns ) CLASS NewListView

RETURN _aPreventResize := aColumns

Rob Panosh

unread,
Jan 11, 2002, 8:10:52 AM1/11/02
to
Amilcar,

I have tried this code. The problem I am having is message HDN_TRACK is NOT
being passed to the Dispatch on my splitwindow.

Rob

"Amilcar A. Camargo" <acam...@acfsoft.com> wrote in message

news:3c3e46dd...@News.cis.dfn.de...

Rob Panosh

unread,
Jan 11, 2002, 8:29:17 AM1/11/02
to
Karl,

Works Perfect .... Thank you! Do you have code to keep the cursor from
changing to a split bar? I want to keep the arrow on these columns.

Rob

"Karl-Heinz Rauscher" <khrau...@compuserve.com> wrote in message
news:a1m4c7$rm4cj$1...@ID-61886.news.dfncis.de...

Amilcar A. Camargo

unread,
Jan 11, 2002, 1:04:29 PM1/11/02
to
Rob,

On Fri, 11 Jan 2002 07:10:52 -0600, "Rob Panosh"
<rob_p...@asdsoftware.com> wrote:

>Amilcar,
>
>I have tried this code. The problem I am having is message HDN_TRACK is NOT
>being passed to the Dispatch on my splitwindow.

Subclass the listview and trap them in the ListView Dispatch().

Regards,

0 new messages