RE: Drawing text over a list view's client area (like Outlook Express)
Tech-Archive recommends: Repair Windows Errors & Optimize Windows Performance
"Danny" wrote:
> Hello,
>
> I would like to call DrawText(... "No items in this view"...) on my list
> view so that the user will see that message instead of a lot of white when
> there are no items in the control.
>
> I subclassed the list view, and for each WM_PAINT I let the listview first
> paint itself, and then I paint the text right over it. It works fine, except
> that while resizing my listview, I get ugly trailing "echos" of previous text
> that I drew on the window (these artifacts disappear by themselves shortly
> after resizing stops). What am I doing wrong?
>
> I tried enveloping my own drawing with BeginPaint/EndPaint, I tried painting
> to the DC obtained through BeginPaint instead of getting my own with GetDC, I
> even tried calculating the rect where the last call to DrawText painted and
> then invalidating it, but all to no avail. I cannot use list view custom draw
> because all my code has to be applicable to non-listview windows (I plan to
> do similar drawing onto my own custom controls and want to reuse this code
> later).
>
> Code:
>
> ListView_SubclassWndProc()
> {
> if (msg == WM_PAINT)
> {
> LRESULT res = CallWindowProc(OriginalListViewProc);
> ListView_OnPaint();
> return res;
> }
> }
>
> BOOL ListView_OnPaint()
> {
>
> HDC hDC = GetDC(hwndListView);
> if (hDC == NULL)
> return FALSE;
>
> if (DrawText(hDC, "My Text", -1, Bounds, DT_SINGLELINE | DT_CENTER |
> DT_END_ELLIPSIS | DT_NOCLIP | DT_VCENTER) == 0)
> return FALSE;
>
> if ((BOOL)ReleaseDC(hwndListView, hDC) == FALSE)
> return FALSE;
>
> return TRUE;
> }
>
Instead, check to see if the list has items (LVM_GETITEMCOUNT) and if it
does, call the original WndProc for it. If not, (and only then) call your
function to do the drawing, using BeginPaint/EndPaint as normal.
There's a caveat. You should also handle WM_SIZE, because when the window is
resized larger, *only part of the client* is invalidated, so you'll want to
invalidate the whole window if the list is empty, allowing you to draw in the
centre again. If you don't, you'll get similar display artefacts. I've done
this (albeit using WTL and MFC for separate applications) and it works fine.
In your drawing, you may want to use ExtTextOut with ETO_OPAQUE, since that
can do a fill rectangle and paint in one call.
Hope this helps
Steve S
.
Relevant Pages
- Re: OpenGL problem
... drawing in the window of Y program. ... X program, and I am trying to set the device context, that the drawing will ... The HDC can't be shared between two different processes. ... (microsoft.public.win32.programmer.mmedia) - Re: Problem with Double Buffering (win32+GDI)
... The thread calls this drawing function 30 times per second. ... creation of app window. ... HDC hdc; ... whatever you draw into it, it just shows a black background. ... (microsoft.public.win32.programmer.ui) - Re: Transferring formatted Text between forms by the API Function SendMessage
... > How do I get the hdc? ... RTFBoxes do have window handles. ... done what is to be done the device context handle has to be released by use ... The device context holds the properties and drawing objects of the drawing ... (microsoft.public.vb.winapi) - Drawing desktop background
... drawing the background and which ones for drawing the icons/text. ... I need to be able to transfer a hDC across processes and I ... simply inserting a window behind the desktop and modifying the desktop ... redirecting WM_ERASEBKGND calls from the desktop to my window WndProc ... (microsoft.public.win32.programmer.gdi) - Re: Projectile OpenGL Problem
... Commas in declaration lists are tasteless. ... Why is it called szAppName when it is the name of a window class? ... hWnd = CreateWindow( ... HDC hDC; ... (microsoft.public.vc.mfc) |
|