News:

Masm32 SDK description, downloads and other helpful links
Message to All Guests

Main Menu

FillRect returns failure - "The handle is invalid."

Started by raleep, July 08, 2012, 10:56:08 AM

Previous topic - Next topic

raleep

Here is the relevant code:


reset:
invoke CreateSolidBrush,0ff0000h
invoke FillRect,hdc,lprect,eax
or eax,eax
  jz germs


hdc is the handle to the device context returned by BeginPaint in the windows procedure and used successfully in many places in the program.
lprect is a pointer to the structure returned by GetClientRect in winmain defined specifically as follows:

rect   LABEL   DWORD
r_lft     DD   ?   ;00
r_top   DD   ?   ;04
r_rgt    DD   ?   ;08
r_bot   DD   ?   ;0C

lprect   DD   rect

germs is a routine that gets, formats and displays the last error message.

I initially used the handle obtained in the initialization of the windows class structure, but thought I could eliminate that as an issue by using a fresh brush here.

Any idea what I am doing wrong?

Thanks,  Robert

[Later]
It also fails with 0ff0001 as the third parameter.

MichaelW

I'm guessing here at what the problem is, and that it's related to "used successfully in many places in the program".

;==============================================================================
; Build as a console app.
;==============================================================================
    include \masm32\include\masm32rt.inc
;==============================================================================
    .data
    .code
;==============================================================================

DlgProc proc uses ebx hwndDlg:HWND, uMsg:UINT, wParam:WPARAM, lParam:LPARAM

    LOCAL ps:PAINTSTRUCT, rc:RECT, hdc:HDC

    SWITCH uMsg

        CASE WM_PAINT

            invoke BeginPaint, hwndDlg, ADDR ps
            mov hdc, eax
            ;invoke FillRect, hdc, ADDR ps.rcPaint, COLOR_HOTLIGHT+1
            invoke CreateSolidBrush, 0ff00ffh
            invoke FillRect, hdc, ADDR ps.rcPaint, eax
            .IF eax == 0
                printf("%s\n",LastError$())
            .ENDIF
            invoke EndPaint, hwndDlg, ADDR ps

            ;-----------------------------------------------
            ; The HDC returned by BeginPaint is apparently
            ; invalid after EndPaint executes.
            ;-----------------------------------------------

            invoke GetClientRect, hwndDlg, ADDR rc
            invoke FillRect, hdc, ADDR rc, COLOR_HOTLIGHT+1
            .IF eax == 0
                printf("After EndPaint: %s\n",LastError$())
            .ENDIF

        CASE WM_COMMAND

            SWITCH wParam
                CASE IDCANCEL
                    invoke EndDialog, hwndDlg, 0
            ENDSW

        CASE WM_CLOSE

            invoke EndDialog, hwndDlg, 0

    ENDSW

    return 0

DlgProc endp

;==============================================================================
start:
;==============================================================================

    Dialog "Test", "MS Sans Serif",10, \
           WS_OVERLAPPED or WS_SYSMENU or DS_CENTER, \
           0,0,0,200,150,1024
    CallModalDialog 0,0,DlgProc,0
    exit

;==============================================================================
end start
Well Microsoft, here's another nice mess you've gotten us into.

qWord

raleep,
your code has a handle leak -> DeleteObject().
MREAL macros - when you need floating point arithmetic while assembling!

MichaelW

I found documentation to support my findings here.

"EndPaint releases the display device context that BeginPaint retrieved."
Well Microsoft, here's another nice mess you've gotten us into.

raleep

Quote from: MichaelW on July 08, 2012, 09:01:34 PM
I found documentation to support my findings here.

"EndPaint releases the display device context that BeginPaint retrieved."

Sure enough, all the "many places" where hdc is "used successfully" are in the display module bracketed by BeginPaint and EndPaint, whereas this attempted use is outside any such brackets.


Thank you, Robert

raleep

Quote from: qWord on July 08, 2012, 06:29:01 PM
raleep,
your code has a handle leak -> DeleteObject().
Thank you qWord for reminding of the need to delete the object.  That was not the main problem here.  Now that it works I've gone back to using the brush handle obtained in the initialization of the windows class structure, which persists as long as the program is running.