I want to use a background image for a treeview control, but I can't make it work properly. Depending on if I use BeginPaint/EndPaint or not, either it works, but the cursor flickers, either you see the image moving down for a moment when an item is expanded.

This is a fragment of the code (Nasm's syntax):

; we have a valid hBitmap, with its width and height.
; The below code is executed after creation of the TreeView control:
call GetDC, [hWndTree]
mov [hDC], eax
call CreateCompatibleDC, eax
mov [mDC], eax
call SelectObject, eax, [hBitmap]
mov [mOldObject], eax
call CreateCompatibleDC, [hDC]
mov [m2DC], eax
call CreateCompatibleBitmap, [hDC], [width], [height]
mov [hmBitmap], eax
call SelectObject, [m2DC], [hmBitmap]
mov [m2OldObject], eax
call ReleaseDC, [hWndTree], [hDC]
call SetWindowLong, [hWndTree], GWL_WNDPROC, TVProc
mov [OldTVProc], eax

And this is the subclassed TreeView procedure:

mov eax, [esp+4]
mov [hWnd], eax
mov eax, [esp+8]
mov [uMsg], eax
mov eax, [esp+12]
mov [wParam], eax
mov eax, [esp+16]
mov [lParam], eax
cmp dword [uMsg], WM_ERASEBKGND
jne .wmpaint
mov dword eax, 1
ret 16
cmp dword [uMsg], WM_PAINT
jne .default
call BeginPaint, [hWnd], ps ; ps points to a PAINTSTRUCT
; the next line is supposed to make the TV control paint itself in our
; m2DC memory context, but if using BeginPaint, it paints itself in the screen!
call CallWindowProc, [OldTVProc], [hWnd], [uMsg], [m2DC], 0
call BitBlt, [m2DC], 0, 0, [width], [height], [mDC], 0, 0, SRCAND
call GetDC, [hWnd]
mov [hDC], eax
call BitBlt, [hDC], 0, 0, [width], [height], [m2DC], 0, 0, SRCCOPY
call ReleaseDC, [hWnd], [hDC]
call EndPaint, [hWnd], ps
xor eax, eax
ret 16
call CallWindowProc, [OldTVProc], [hWnd], [uMsg], [wParam], [lParam]
ret 16

I've googled for answers, but I only found code in C++ which uses classes and interfaces and what not, and an VB one which uses a huge WM_PAINT handler to achieve the result, and I think it can't be that complicated. I found nothing searching in the forum. If anybody has a hint on this matter, I'd appreciate it.

Posted on 2003-02-27 05:35:31 by El_Choni
you cannot avoid the moving image while item expanding - because windows uses ScrollWindow for scrolling the
window content. The only way I think is to make all the items also owner draw and draw them yourself on top
of the image.

Another (but rather dirty) hack could be the usage of WM_REDRAW, you can try to disable WM_REDRAW before expanding
items and to enable after expanding and to invalidate and update the corresponding region, but this is just an idea.
Posted on 2003-02-27 06:15:09 by beaster
I tried the wm_redraw thing, but things get messed up. I'll try the invalidate, although I don't know very well how that works (what messages get called, etc.)

Thanks a lot for your help!
Posted on 2003-02-27 10:29:12 by El_Choni