Fog Creek Software
Discussion Board




EM_DISPLAYBAND (Technical question)

I am seeking help in determing how to go about using the Rich Edit Window message EM_DISPLAYBAND.  The documentation for this message confuses me. 

(Technical stuff follows.)

I use the EM_FORMATRANGE message to measure and render the contents of my rich edit window.  MSDN documentation leads me to believe that the EM_DISPLAYBAND message is just as well suited to the task of rendering as the EM_FORMATRANGE message.  In fact it says that the EM_DISPLAYBAND message is normally called after the EM_FORMATRANGE message.

I am confused as to how to use EM_DISPLAYBAND because I don't understand when to use it.  If EM_FORMATRANGE can render the contents of the control why would you use EM_DISPLAYBAND to do the same thing.

The only thing I can derive from the documentation is that EM_DISPLAYBAND displays a portion of the text in a rectangle?  But how does it determine which device context to use?  And Can I repeatedly call EM_DISPLAYBAND to "band" text, instead of repeated calls to EM_FORMATRANGE?

The messages are confusing and the documentation does not help.

I would think EM_FORMATRANGE should only format or measure a range of text and not be able to render it.

EM_DISPLAYBAND should actually render or display the text.

At any rate, I know this is very technical and not something that most people are familiar with, but I thought I would try and post it here to see if anyone can point me to a (Microsoft specific? ) message board or newsgroup that would help me answer the question or perhaps someone can explain it here.

Googling for EM_DISPLAYBAND does not turn up anything useful.  The samples on MSDN are written to repeatedly call the EM_FORMATRANGE message to "band" text.  They do not use EM_DISPLAYBAND.  My own attempts at writing a sample program to use EM_DISPLAYBAND are thwarted by the confusing documentation.

Dave B.
Monday, December 22, 2003

In the old days people had dot matrix printers that could only print one band of text at a time. Naive programs, when printing to dot matrix printers, simply re-rendered the entire page again and again for each line of text and only kept the rectangle that the printer was working on.

I would guess that this is a holdover from that.

Joel Spolsky
Monday, December 22, 2003

The documentation seems to say that

the ideal method is to band or divide the text to be printed into small chunks. Each chunk is first formatted and then rendered to the Printer DC. This is achieved by sending an EM_FORMATRANGE with wParam set to 0 immediately followed by EM_DISPLAYBAND.

Alternatively. you could either use EM_FORMATRANGE with wParam set to True and do away with EM_DISPLAYBAND.

Admittedly, there is an apparent redundancy over there, which could be because of the reason Joel pointed out.

Sathyaish Chakravarthy
Monday, December 22, 2003

Thanks for the replies Joel and Sathyaish.

I did find one piece of MFC sample code in MSDN 2001 that I still find confusing.  It's under "DisplayBand" in the Index.

==========================

// The pointer to my rich edit control.
extern CRichEditCtrl* pmyRichEditCtrl;
// A pointer to a printer DC.
extern CDC* pMyPrinterDC;

FORMATRANGE fr;

// Get the page width and height from the printer.
long lPageWidth = ::MulDiv(pMyPrinterDC->GetDeviceCaps(PHYSICALWIDTH),
    1440, pMyPrinterDC->GetDeviceCaps(LOGPIXELSX));
long lPageHeight = ::MulDiv(pMyPrinterDC->GetDeviceCaps(PHYSICALHEIGHT),
    1440, pMyPrinterDC->GetDeviceCaps(LOGPIXELSY));
CRect rcPage(0, 0, lPageWidth, lPageHeight);

// Format the text and render it to the printer.
fr.hdc = pMyPrinterDC->m_hDC;
fr.hdcTarget = pMyPrinterDC->m_hDC;
fr.rc = rcPage;
fr.rcPage = rcPage;
fr.chrg.cpMin = 0;
fr.chrg.cpMax = -1;
pmyRichEditCtrl->FormatRange(&fr, TRUE);

// Update the display with the new formatting.
RECT rcClient;
pmyRichEditCtrl->GetClientRect(&rcClient);
pmyRichEditCtrl->DisplayBand(&rcClient);

=========================

If I'm reading this code correctly DisplayBand is being used to display the contents of the rich edit window to a display device even though these contents were previously rendered to a printers device context.

Specifically the client rectangle of the rich edit window itself appears to be the destination of the DisplayBand call.  What I don't understand is that both device contexts in the previously defined FORMATRANGE structure point to the printer not the display.  Thus leading me to question DisplayBand.

I guess it's just a matter of my curiosity and my wondering whether or not the EM_DISPLAYBAND method is better than the dual calls to EM_FORMATRANGE. 

I hate not being able to fully understand something because I always think there is a better way of doing said thing that I do not realize and am not utilizing because of my misunderstanding. 

i.e. What am I missing by not using EM_DISPLAYBAND?  Why is the EM_DISPLAYBAND documentation not clear?  Why can you not set the output device context of EM_DISPLAYBAND?  Does it always output to the "Display"?  or does it output to the device you previously set in the FORMATRANGE structure?  So many unanswered questions, but I guess all that matters is that it works in some form or another.

Dave B.
Monday, December 22, 2003

You probably don't have to think about this unless you want to be able to print the contents of your rich text control, in which case you need to manually handle EM_DISPLAYBANDS sent to you during printing. When you handle these you can implement them in terms of the display code already provided by the control, and that's what that sample code shows you how to do.

Joel Spolsky
Monday, December 22, 2003

>If I'm reading this code correctly DisplayBand is being used to display the contents of the rich edit window to a display device even though these contents were previously rendered to a printers device context.

I am no authority on this, but I think your confusion stems from the fact that you assume the DisplayBand in the example above prints to the WindowDC of the RTF control rather than the PrinterDC which in my opinion is not true. The DisplayBand does not specify a DC and hence it only follows the rendering of the band on the DC specified by the previous call to FormatRange. It is only equivalant to setting the wParam in the FormatRange to a nonzero value. I hope that also answers your question about why you cannot set a DC on DisplayBand.


>Does it always output to the "Display"? 

No


>or does it output to the device you previously set in the FORMATRANGE structure? 

Yes.

Sathyaish Chakravarthy
Monday, December 22, 2003

*  Recent Topics

*  Fog Creek Home