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

how to word wrap in CListCtrl?

786 views
Skip to first unread message

A. Ng

unread,
Jul 9, 2003, 10:02:47 AM7/9/03
to
Hi,

I have an application that sets up a grid using CListCtrl.
Now I am trying to fit a line of characters into one of the cells.
Because the length of the line may vary, I need to have word wrap for the
cell.
However, I cannot find references anywhere to do this.
Any ideas or advices are absolutely appreciated.

Andy


Yan K. Avlasov

unread,
Jul 9, 2003, 2:23:08 PM7/9/03
to
I don't think you can do it without handling NM_CUSTOMDRAW and draw item
text manually. In report mode all items should have the same height, so you
have to decide beforehand how many lines of text per listview item you want
and choose the appropriate item height. Setting item height is a bit
tricky... One way to do it is to create empty imagelist of desired height
and select it into your list control.

Yan


"A. Ng" <a...@peerdirect.com> wrote in message
news:e3HvHLiR...@tk2msftngp13.phx.gbl...

A. Ng

unread,
Jul 9, 2003, 4:45:38 PM7/9/03
to
Yan,

Thanks for the suggestion. I checked MSDN on NM_CUSTOMDRAW but it did not
provide any details
at all. Wonder if any one have some pseudo/sample code for me to look at?
BTW, I am kind of new to MFC, so I really appreciate the help here.

Andy

"Yan K. Avlasov" <_yan_avlasov_@_azimuth.net_> wrote in message
news:%23hcTnck...@tk2msftngp13.phx.gbl...

Joseph M. Newcomer

unread,
Jul 9, 2003, 4:24:41 PM7/9/03
to
There are two issues here: getting the text to display on multiple lines, and getting the
text to word wrap. You will probably have to go to an owner-draw style to display
multiline text; I don't think this ability is built in. I've never had to do it, so I
can't tell.

The other issue is how to actually split the input into words and fit them into the area
you have provided. The usual algorithms require doing GetTextExtent, searching for break
characters, etc.

I tend to solve this problem in a very lazy fashion.

I keep an ordinary CEdit control, invisible, around. Typically, I create it during the
PreSubclassWindow operation. It has no horizontal scrolling, is a multiline listbox, and
has vertical scrolling. I set its font to be the font of the dialog, or to be more
precise, to the font of the control (CListBox) that I am dealing with.

When it comes time to draw (and I've done this with CListBox, not CListCtrl), I resize
this invisible edit control to the width of the area I have to draw in. This sets the
"column width". I then do a SetWindowText to put the text in the edit control. The CEdit
does all the grotty details of figuring out how to break the line up. Forcing word wrap by
splitting the word if the word is too long to fit on even a single line. All that stuff. I
then iterate through all the lines of the edit control, extracting the string that is each
line, and do a simple TextOut on that. Assuming you know the x, y, and width of the area
you need to write text into,

TCHAR buffer[SOME_MAX_SIZE];

int lineheight = dc.GetTextExtent(CString(_T("X")).cy;

c_Format.SetWindowPos(NULL, 0, 0, width, lineheight, SWP_NOMOVE | SWP_NOZORDER);

for(int i = 0; i < c_Format.GetLineCount(); i++)
{ /* retrieve and display */
c_Format.GetLine(i, buffer, sizeof(buffer) / sizeof(TCHAR));
TextOut(x, y, s);
y += lineheight;
} /* retrieve and display */

beats trying to write your own line-wrap code!
joe

Joseph M. Newcomer [MVP]
email: newc...@flounder.com
Web: http://www.flounder.com
MVP Tips: http://www.flounder.com/mvp_tips.htm

CheckAbdoul

unread,
Jul 9, 2003, 5:19:48 PM7/9/03
to
See if the following link helps you

http://www.codeproject.com/listctrl/lvcustomdraw.asp

--
Cheers
Check Abdoul [ VC++ MVP ]
-----------------------------------

"A. Ng" <a...@peerdirect.com> wrote in message
news:e3HvHLiR...@tk2msftngp13.phx.gbl...

Yan K. Avlasov

unread,
Jul 9, 2003, 5:35:01 PM7/9/03
to
Handling NM_CUSTOMDRAW in your case will be quite tedious... It is better
that you derive your own class from CListCtrl. In your class handle
NM_CUSTOMDRAW message (you can specify the handler in the messages section
of class properties (assuming you go with the VC++ .NET). This is how your
handler may look like (this is just to get you going, it will not handle
drawing images, different item states and control focus):


void CMyListCtrl::OnNMCustomdraw(NMHDR *pNMHDR, LRESULT *pResult)
{
LPNMLVCUSTOMDRAW pNMCD = reinterpret_cast<LPNMLVCUSTOMDRAW>(pNMHDR);
*pResult = 0;
switch(pNMCD->nmcd.dwDrawStage)
{
case CDDS_PREPAINT :
*pResult = CDRF_NOTIFYITEMDRAW;
break;

case CDDS_ITEMPREPAINT:
*pResult = CDRF_NOTIFYSUBITEMDRAW;
break;

case CDDS_SUBITEM | CDDS_ITEMPREPAINT:
*pResult = CDRF_SKIPDEFAULT;
{
CRect rc;
CDC* pDC = CDC::FromHandle( pNMCD->nmcd.hdc );
CString itemText = GetItemText( pNMCD->nmcd.dwItemSpec,
pNMCD->iSubItem );
GetSubItemRect( pNMCD->nmcd.dwItemSpec, pNMCD->iSubItem,
LVIR_BOUNDS, rc );
pDC->FillSolidRect( rc, GetSysColor( COLOR_WINDOW ) );
GetSubItemRect( pNMCD->nmcd.dwItemSpec, pNMCD->iSubItem,
LVIR_LABEL, rc );
pDC->DrawText( itemText, rc, DT_LEFT|DT_WORDBREAK );
}
break;
}
}

"A. Ng" <a...@peerdirect.com> wrote in message

news:OoTcRsl...@TK2MSFTNGP10.phx.gbl...

Jus...@boohoo.gone

unread,
Jul 9, 2003, 11:22:29 PM7/9/03
to
On Wed, 09 Jul 2003 16:24:41 -0400, Joseph M. Newcomer
<newc...@flounder.com> wrote:

>I tend to solve this problem in a very lazy fashion.

All good programmers do. (That's a bad "joke," not flamebait! )

>I keep an ordinary CEdit control, invisible, around.

[Good advice snipped]

I've taken a slightly different approach. I create the edit control
and use it for all the data entry. I make it appears as though it's
part of whatever background control I need it to.

I move the edit to whatever location that will have the focus and the
user types into it. I determine what the location and extents are
( x, y, cx,cy coords ) and call MoveWindow(...), like so:

myEdit.MoveWindow( x,y,cx,cy ).

When I want it hidden I call MoveWindow() Like this:

myEdit.MoveWindow( -1000,-1000,10,10 );
(Arguments are just examples assuming MM_TEXT.)

Thus taking it out of the viewable DC. You can also just toggle
ShowWindow( SW_HIDE ) and ShowWindow( SW_SHOW ). I've
informally timed this and I see no difference in performance.

When the user moves focus away from that location, you get the text
out of the edit and put it ( paint it, or whatever ) into the
appropriate area.

The net effect is that it looks like it's part of your background
control. On occasion I disable other controls to accommodate this
behavior.

[War Story Alert!]
I once created an irregular spreadsheet (grid) with nothing but *one*
old style edit window and a lot of paint. IOW, it looked just like a
modern spreadsheet, but the rows determined the size of the cells not
the columns. I literally painted everything on the screen except where
the current cell was. That was the edit control that I just
"MoveWindow'ed" around. The customer loved it.

"Ah, the good old, bad old days."


-----= Posted via Newsfeeds.Com, Uncensored Usenet News =-----
http://www.newsfeeds.com - The #1 Newsgroup Service in the World!
-----== Over 80,000 Newsgroups - 16 Different Servers! =-----

A. Ng

unread,
Jul 10, 2003, 10:24:54 AM7/10/03
to
Thanks for all the help. Am going to follow all of your advices.
Though it does not seem trivial, but it seems doable :)

Andy

"A. Ng" <a...@peerdirect.com> wrote in message
news:e3HvHLiR...@tk2msftngp13.phx.gbl...

José Lamas Ríos

unread,
Jul 10, 2003, 1:35:12 PM7/10/03
to
"Joseph M. Newcomer" <newc...@flounder.com> wrote in message
news:1rtogvou7qs3e5tdm...@4ax.com...

What about simply using DrawText() with DT_WORDBREAK?


--
jlr


Jus...@boohoo.gone

unread,
Jul 11, 2003, 12:36:40 AM7/11/03
to
On Thu, 10 Jul 2003 14:35:12 -0300, "José Lamas Ríos"
<j...@artech.com.uy> wrote:

>What about simply using DrawText() with DT_WORDBREAK?

How does one type into DrawText() ? ... Suddenly you're writting a lot
of code.

My watch is three hours fast, and I can't fix it. So I'm going to
move to New York. - sw

José Lamas Ríos

unread,
Jul 11, 2003, 8:07:58 AM7/11/03
to
<Jus...@BooHoo.gone> wrote in message
news:3f0e3e6c...@news.dakotacom.net...

> On Thu, 10 Jul 2003 14:35:12 -0300, "José Lamas Ríos"
> <j...@artech.com.uy> wrote:
>
> >What about simply using DrawText() with DT_WORDBREAK?
>
> How does one type into DrawText() ?

You don't. The issue at hand was about displaying text with word wrap.

> ... Suddenly you're writting a lot
> of code.

Huh?


--
jlr


0 new messages