News:

MASM32 SDK Description, downloads and other helpful links
MASM32.com New Forum Link
masmforum WebSite

Paint Solid Background

Started by raleeper, April 23, 2007, 02:08:03 AM

Previous topic - Next topic

raleeper

1.  I am new to the MASM Forum and new to windows programming.  I am somewhat experienced at MASM [5.1] programming.  I have a dos program that i'm trying to rewrite for or convert to windows.  I think I have a fair idea how to procede, but I'm stuck at an early stage - how to paint the entire client area a solid color.

I realize I could [probably] fill the entire area with text, using spaces for the blank areas at the bottom and after the last non-blank character on a line.  An early version of my dos program worked that way.  But if possible, I want to do it in windows the way I decided was more efficient for dos.

2.  Using Iczelion's tutorials and further info from the SDK I got a program that created a window with a text string (Times New Roman, white on blue) at the top left, but the remainder of the window is white (or one of the very limited number of other choices settable in the window class).  The closest I can come is wc.hbrBackground,COLOR_BACKGROUND+1, which is light, slate-blue.  I want deep pure blue (rgb 0,0,255).

The next thing I tried was:
   in WindProc, after    invoke BeginPaint,hWnd, ADDR ps

   invoke CreateSolidBrush,0FF0000h
   invoke SelectObject,hdc,eax

That didn't work so I tried

   invoke SetDCBrushColor,hdc,0FF0000h

Both of these "work" in the sense of not returning an error, but except for the text string the window is unrelentingly white/slate-blue/black/gray.  I've tried 0 through 14 and COLOR_WINDOW+1 (6 - white),COLOR_HIGHLIGHT+1 (slate blue) and COLOR_BACKGROUND+1 (2 - slate blue) and am pretty sure I'm not going to find pure blue.

   invoke CreateSolidBrush,00FF0000h
   mov   [hbrsh], eax
   invoke FillRect,hdc,rect,hbrsh

also doesn't seem to work.

3.  This post is already too long, so I haven't included the full source.  It looks to me as if either windows wont do what I want or I'm missing something simple.  Any help will be greatly appreciated.

Ratch

rasleeper,

     When filling out the WNDCLASS structure for RegisterClass, do a INVOKE CreateSolidBrush,RGB(0,0,255).  Then copy the result  (EAX) into the hbrBackground field of the WNDCLASS structure.  That's it!  Ratch

raleeper

   invoke CreateSolidBrush,RGB(0,0,255)
lfw.asm(63) : error A2136: too many arguments to INVOKE
lfw.asm(63) : error A2148: invalid symbol type in expression : RGB
lfw.asm(63) : error A2114: INVOKE argument type mismatch : argument : 1

   invoke CreateSolidBrush,00FF0000h
        mov wc.hbrBackground,eax

no error, but screen remains slate blue.

raleeper

I should add that I've redefined RGB as:

RGB macro red,green,blue
mov   eax, red + green shl 8 + blue shl 16
ENDM

Ratch

raleeper,

     Instead of a MACRO, RGB should be a MACRO FUNCTION as follows.

RGB MACRO RED:REQ,GREEN:REQ,BLUE:REQ
EXITM <(BLUE SHL 16)+(GREEN SHL 8)+RED>
ENDM


     Are you sure that you are using the "blue background class" for your INVOKE CreateWindow?  Or maybe you are overwriting wc.hbrBackground somewhere.  You should post a stripped down version of your code so we can look at it.  Best to send it via a ZIP file.  Ratch

MichaelW

Or you could eliminate the RGB macro as the source of the problem by setting the hbrBackground member to the value returned by:

invoke GetStockObject, BLACK_BRUSH

(or WHITE_BRUSH, etc )


eschew obfuscation

Ratch

MichaelW,

     He has already done that be directly coding the blue color into CreateSolidBrush without using his RGB MACRO.  Ratch

jckl

This works for me just fine.


    invoke CreateSolidBrush,0FF0000h
    mov   wc.hbrBackground,eax


Are you sure that you are going for that color or are you looking for more like 0800000h

raleeper

Ratch, jckl and MichaelW

Thanks for your help - I have it working.  Ratch showed me what I needed to do and jckl assured me it should work (this was critical, since it wasn't working for me until I cleared out some junk from my code).

ramguru

Alternatively you can use this code to paint background:

invoke BeginPaint, hWnd, ADDR ps
invoke SetBkColor, ps.hdc, colorRGB
invoke ExtTextOut, ps.hdc, 0, 0, ETO_OPAQUE, ADDR ps.rcPaint, 0, 0, 0
invoke EndPaint, hWnd, ADDR ps

BTW your application will flicker, because you're going to paint twice: clear window, and then draw something, that's bad practice, unless you're double-buffering

Grincheux

WmPaint PROC USES EBX EDI ESI,__hWnd:HWND
LOCAL _Ps:PAINTSTRUCT
LOCAL _rc:RECT
LOCAL _hBmpMem:HBITMAP
LOCAL _hBmpMemOld:HBITMAP
LOCAL _hBrush_Blue:HBRUSH
LOCAL _dwX:DWord
LOCAL _dwY:DWord
LOCAL _dwStringLength:DWord
LOCAL _szString[256]:Byte
LOCAL _lpRc:Ptr RECT

; ======== EBX = HWND ============
; ======== ESI = HDC ==============
; ======== EDI = HDCMEM ===========

lea eax,_Ps
mov ebx,__hWnd

lea edx,_rc

push eax          ; These 2 PUSH are for EndPaint
push ebx          ; Like this I have only One "LEA EAX,_Ps"

mov _lpRc,edx   ; Only one "LEA EAX,_rc" pointer store into stack

mov DWord Ptr _szString,"EYB"
mov _dwStringLength,3

INVOKE BeginPaint,ebx,eax

test eax,eax
jz @Exit

mov edi,eax                 ; _hDC into EDI

INVOKE CreateCompatibleDC,eax

test eax,eax
jz @Exit

mov esi,eax               ; _hDCMem into ESI

INVOKE GetClientRect,ebx,_lpRc

INVOKE CreateCompatibleBitmap,edi,_rc.right,_rc.bottom

test eax,eax
jz @Error_1

mov _hBmpMem,eax

INVOKE SelectObject,esi,_hBmpMem

test eax,eax
jz @Error_2

mov _hBmpMemOld,eax

INVOKE SetBkMode,esi,TRANSPARENT
INVOKE CreateSolidBrush,00ff0000h

test eax,eax
jz @Error_3

mov _hBrush_Blue,eax

INVOKE FillRect,esi,_lpRc,_hBrush_Blue
INVOKE DeleteObject_hBrush_Blue
INVOKE TextOut,esi,500,300,ADDR _szString,_dwStringLength
INVOKE SetStretchBltMode,edi,HALFTONE
INVOKE BitBlt,edi,0,0,_rc.right,_rc.bottom,esi,0,0,SRCCOPY

@Error_3 :

INVOKE SelectObject,esi,_hBmpMemOld

@Error_2 :

INVOKE DeleteObject,_hBitmap

@Error_1 :

INVOKE DeleteDC,esi

@Exit :

call EndPaint

ret
WmPaint   ENDP

WindowProc PROC...

...

.IF eax == WM_ERASEBCKGND
    mov eax,TRUE
    jmp @Exit

...

@Exit :

ret

WindowProc ENDP

This code enables you do draw without any flash. I used the WM_ERASEBCKGND to don't have to paint the window background because it is made into the WmPaint proc.

That's all
Kenavo

Grincheux
_____________________________________________________
http://www.phrio.biz

zooba

Be careful using transparent background on text when you're not erasing the background each time - if the font is antialised (or is using ClearType) you'll get strange artifacts as the blurring accumulates. Simplest solution is to use an opaque background or copy the original background over the text before redrawing it (like you'd have to if the text changed).

Cheers,

Zooba :U