Jeff Schwab
10/22/2008 7:41:00 PM
Mosfet wrote:
> Hi,
>
> I am currently writing a graphical control(a list control) that can
> display a picture followed by some text and to do so I first calculate
> an item height and then I really draw.
> I was wondering if it would be a good idea to merge the two
> methods(calculating and drawing) knowing that when calculating we
> actually simulate a drawing.
> Basically my control is called the first time to calculate the height of
> an Item (MeasureItem) and then to draw (DrawItem).
> I was thinking of something like that :
>
> // Method to handle OwnerDraw
> void MeasureItem( LPMEASUREITEMSTRUCT lpMeasureItemStruct )
> {
> DrawItem(lpDIS, TRUE);
> }
> void DrawItem(LPDRAWITEMSTRUCT lpDIS)
> {
> DrawItem(lpDIS, FALSE);
> }
>
>
> // custom method that calulate or really draw
> void DrawItem(LPDRAWITEMSTRUCT lpDIS, BOOL bOnlyCalculate)
> {
>
> }
>
>
> Now you need to know that the difference between drawing text or
> calculating its height relies on an flag (DT_CALCRECT) passed to a
> function DrawText:
>
> DrawText(hDC,lpString, nCount, &Rect, uFormat)
>
> if uFormat & DT_CALCRECT we calculate otherwise it means we draw.
>
> So I was wondering if it would be possible to write a template that
> could take a pointer to DrawText function and that would add DT_CALCRECT
> to the argument when calculating :
>
> DrawTextFunc<false>(....) would mean we call function to calculate
> DrawTextFunc<true>(....) would mean we really draw
>
> About drawing bitmap we could do something similar
>
> DrawBitmap<false>() would mean we don't display bitmap - so should call
> an empty function
> DrawBitmap<true>() really draw the bitmap
>
>
> Could someone tell me how to write something like my DrawTextFunc and
> DrawBitmap ?
>
You have a nice idea, but rather than parameterizing the function with a
boolean value, consider parameterizing with a "policy" type that
translates DrawBitmap's actions into either drawing or calculation. For
example, something like:
/* Accumulates height of drawing operations. */
struct MeasuringContext {
// ...
void verticalLine(Point const& base, std::size_t length) {
updateMaxHeight(base, length);
}
};
/* Forwards drawing operations to graphical device. */
struct DrawingContext {
// ...
void verticalLine(Point const& base, std::size_t length) {
drawVerticalLine(base, length);
}
};
template<typename Context>
void DrawBitmap(Context context) {
// ...
context.verticalLine(base, length);
// ...
}