News:

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

problem sketching on mask

Started by RHL, May 04, 2012, 07:16:41 AM

Previous topic - Next topic

RHL

Hello guys  :bg
something strange is happening to me now,
I'm trying to finish a code, and it fault only one thing I do not know of because...
I am sketching a bitmap on the windows, ok, first, I make a mask to the bitmap, second, draw the mask, after, I want to draw the bitmap but this last is does not work

picture:

the last Bitblt function is not correct :/ ALL IS OK, BUT THE LAST BIBLT FUNCTION IS BAD, I DO KNOW NOT THE REASON


please, you could look at my code ( attached ) my project is short ( the bitmap is of 27kb, 4kb of project )

note:the rarest is that I have the project made on C++, this does work correct :|


ED:
the output of C++ program:



is rare!

dedndave

#1
that code looks like it should work   :red
maybe you have to use LoadImage instead of LoadBitmap

but - it is easier to use TransparentBlt   :U
you don't have to create a mask

you have to include msimg32.inc and includelib msimg32.lib



EDIT - i cleaned this one up, too

dedndave

i wanted to get the mask version working...

the problem was in the mask routine - DSTINVERT - should be SRCINVERT
but you have to keep an eye on your GDI objects
when you load or create a GDI object, you usually have to delete it when you are done
when you select one into a DC, the original should be restored

there are a number of methods for doing transparencies
another uses the MaskBlt function
you still have to create a mask, but it simplifies the WM_PAINT handler

all in all - you can't get much simpler than TransparentBlt   :U

i spent some time cleaning this one up - i didn't do that for the one in the previous post
now i am off to finish up a favour for Alex   :P


RHL

Wow! I did not know of TransparentBlt function, it is very easy! neither of MaskBlt function
:D thanks a lot mate

dedndave

i just found that one, myself
sure makes it simple, huh   :U

dedndave

found another one   :bg

GdiTransparentBlt
same as TransparentBlt, but you don't have to include msimg32.inc/lib   :P

RHL

hello :)
someone know why, i trying draw on a static controls the CPU is increment to 50%  :red
the same project added this line:



; added ( WM_CREATE message ):
invoke   CreateWindowEx,NULL,addr ClassStatic,addr ClassName, WS_CHILD or WS_VISIBLE or SS_BITMAP,30,30,100,100,hWnd,NULL,hInstance,NULL
mov      handlecontrol2,eax

ok, after, on the WM_PAINT:

         invoke   BeginPaint,handlecontrol2,addr ps
         mov      hdc10,eax
         invoke   CreateCompatibleDC,hdc10
         mov      hMem10,eax
         invoke   SelectObject,hMem10,hBit
         mov      hBmpOrg2,eax
      invoke  TransparentBlt,hdc10,0,0,dwWidth,dwHeight,hMem10,0,0,dwWidth,dwHeight,0FF00FFh
         invoke   SelectObject,hMem10,hBmpOrg2
         invoke   DeleteDC,hMem10
         invoke   EndPaint,handlecontrol2,addr ps

is the same project. just I added two lines ( to create a static control ) and change the handle in BeginPaint :/
the MSDN says: An application returns zero if it processes this message. is right... but what happen? thanks

Dave: I think the TransparentBlt function has a problem :P or well , this does not work as it should.... I will to do a example :P

qWord

The WM_PAINT-Handler should only be used for drawing the current window - it is definitely the false place for drawing controls.
The problem is, that you are not validating the requested region while handling WM_PAINT.
FPU in a trice: SmplMath
It's that simple!

RHL

hi qWord, I do not understand :P
I understand then that It only is possible with main Windows?  no child controls? :S

why the W32 API does not want me? lol :(

qWord

Quote from: RHL on May 05, 2012, 10:53:23 PM
hi qWord, I do not understand :P
I understand then that It only is possible with main Windows?  no child controls? :S
probably I do not understand your question: You have create a subclass for the control and your shown handler is inside this subclass? If so, it is ok.
FPU in a trice: SmplMath
It's that simple!

RHL

qWord:
for example this code, the CPU is incremented to 50%:

       

include \MASM32\INCLUDE\masm32rt.inc
include \masm32\include\msimg32.inc                         
includelib \masm32\lib\msimg32.lib                       

WinMain proto :DWORD,:DWORD,:DWORD,:DWORD

MAINBITMAP equ 500   ; BITMAP

.data
    ClassName db "MainWinClass",0
    AppName  db "Main Window",0
    ClassStatic db "Static",0
    ClassButt db "Button",0
    NameStatic1 db "Mydraw1",0
NameStatic2 db "Mydraw2",0

.data?
   hInstance HINSTANCE ?
   CommandLine LPSTR ?
   hstatic1 dd ?
   hstatic2 dd ?
   hbutton dd ?
   hBit dd ?
   dwWidth dd ?
   dwHeight dd ?
   
   handlecontrol2 dd ?
   
   
   
.code
start:
invoke GetModuleHandle, NULL
mov    hInstance,eax
invoke GetCommandLine
mov    CommandLine,eax
invoke WinMain, hInstance,NULL,CommandLine, SW_SHOWDEFAULT
invoke ExitProcess,eax
WinMain proc hInst:HINSTANCE,hPrevInst:HINSTANCE,CmdLine:LPSTR,CmdShow:DWORD
LOCAL wc:WNDCLASSEX
LOCAL msg:MSG
LOCAL hwnd:HWND

mov   wc.cbSize,SIZEOF WNDCLASSEX
mov   wc.style, CS_HREDRAW or CS_VREDRAW
mov   wc.lpfnWndProc, OFFSET WndProc
mov   wc.cbClsExtra,NULL
mov   wc.cbWndExtra,NULL
push  hInstance
pop   wc.hInstance
mov   wc.hbrBackground,COLOR_BTNFACE+1
mov   wc.lpszMenuName,NULL
mov   wc.lpszClassName,OFFSET ClassName

invoke LoadIcon,NULL,IDI_APPLICATION
mov   wc.hIcon,eax
mov   wc.hIconSm,eax

invoke LoadCursor,NULL,IDC_ARROW
mov   wc.hCursor,eax

invoke RegisterClassEx, addr wc

INVOKE CreateWindowEx,WS_EX_CLIENTEDGE,ADDR ClassName,ADDR AppName,\
           WS_OVERLAPPEDWINDOW,CW_USEDEFAULT,CW_USEDEFAULT,100h,100h,NULL,NULL,hInst,NULL
mov   hwnd,eax
invoke ShowWindow, hwnd,SW_SHOWNORMAL
invoke UpdateWindow, hwnd

.WHILE TRUE
invoke GetMessage, ADDR msg,NULL,0,0
.BREAK .IF (!eax)
invoke TranslateMessage, ADDR msg
invoke DispatchMessage, ADDR msg
.ENDW
mov     eax,msg.wParam
ret
WinMain endp

WndProc proc hWnd:HWND, uMsg:UINT, wParam:WPARAM, lParam:LPARAM
    LOCAL   hBmpOrg2:DWORD
LOCAL Bm:BITMAP
LOCAL ps:PAINTSTRUCT
LOCAL hdc10:HDC
LOCAL hMem10:HDC

.IF uMsg==WM_DESTROY
                invoke  DeleteObject,hBit                       ;added by Dave
invoke PostQuitMessage,NULL
.ELSEIF uMsg==WM_CREATE
invoke CreateWindowEx,NULL,addr ClassButt,addr AppName, WS_CHILD or WS_VISIBLE,60,48,80,40,hWnd,NULL,hInstance,NULL
mov hbutton,eax
invoke CreateWindowEx,NULL,addr ClassStatic,addr ClassName, WS_CHILD or WS_VISIBLE or SS_BITMAP,30,30,100,100,hWnd,NULL,hInstance,NULL
mov handlecontrol2,eax
invoke LoadBitmap,hInstance,MAINBITMAP
mov hBit,eax
    invoke GetObject,hBit,sizeof Bm,addr Bm        ;added by Dave
                push    Bm.bmWidth                              ;added by Dave
                pop     dwWidth                                 ;added by Dave
                push    Bm.bmHeight                             ;added by Dave
                pop     dwHeight                                ;added by Dave
.elseif uMsg==WM_PAINT
    invoke BeginPaint,handlecontrol2,addr ps
    mov hdc10,eax
    invoke CreateCompatibleDC,hdc10
    mov hMem10,eax
    invoke SelectObject,hMem10,hBit
    mov hBmpOrg2,eax
invoke  TransparentBlt,hdc10,0,0,dwWidth,dwHeight,hMem10,0,0,dwWidth,dwHeight,0FF00FFh
    invoke SelectObject,hMem10,hBmpOrg2
    invoke DeleteDC,hMem10
    invoke EndPaint,handlecontrol2,addr ps
.ELSE
invoke DefWindowProc,hWnd,uMsg,wParam,lParam
ret
.ENDIF
xor eax,eax
ret
WndProc endp
end start



why? :( all is ok, but the CPU...  :@ this is happening to me many times lol

MichaelW

If in the calls to BeginPaint and EndPaint I substitute hWnd for handlecontrol2, then the CPU usage drops to 0 (when I'm not dragging the window) and the window looks and and appears to work the same as it did. Why are you passing handlecontrol2 in the WM_PAINT handler for the main window?

If you are trying to draw in a static control from the window procedure for the main window, why not use an SS_OWNERDRAW static control?
eschew obfuscation

RHL

Quote from: MichaelW on May 06, 2012, 08:56:40 AM
If in the calls to BeginPaint and EndPaint I substitute hWnd for handlecontrol2, then the CPU usage drops to 0 (when I'm not dragging the window) and the window looks and and appears to work the same as it did. Why are you passing handlecontrol2 in the WM_PAINT handler for the main window?

If you are trying to draw in a static control from the window procedure for the main window, why not use an SS_OWNERDRAW static control?

thanks u MichaelW for your reply, yeah i want to draw in a static control :P
I tried with SS_OWNERDRAW:
invoke CreateWindowEx,NULL,addr ClassStatic,addr ClassName, WS_CHILD or WS_VISIBLE or SS_OWNERDRAW ,30,30,100,100,hWnd,NULL,hInstance,NULL

right?
I tried with several ways for example, in the WM_PAINT message,I used the DefWindowProc:

invoke DefWindowProc,hWnd,uMsg,wParam,lParam
ret


and the CPU is normal  :eek
but in the MSDN documentation, it says: the return must be zero, is rare



qWord

when a static control has the SS_OWNERDRAW-style, the parent window will receive the WM_DRAWITEM-message -> this is the place to draw to the static control.
The WM_PAINT-handler is only responsible for the current Window, which is identified by the procedure paremater hWnd!
FPU in a trice: SmplMath
It's that simple!

MichaelW

An example, based on a MASM32 in-memory dialog:

;==============================================================================
    include \masm32\include\masm32rt.inc
    include \masm32\include\msimg32.inc
    includelib \masm32\lib\msimg32.lib
;==============================================================================

IDC_STC equ 1001

;==============================================================================
    .data
      hInstance HANDLE  0
      hBmp      HBITMAP 0
    .code
;==============================================================================

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

    LOCAL hdcMem:HDC, bmp:BITMAP

    SWITCH uMsg

        CASE WM_INITDIALOG

            invoke LoadImage, 0, chr$("mydraws.bmp"), IMAGE_BITMAP,
                              0, 0, LR_LOADFROMFILE
            mov hBmp, eax

        CASE WM_DRAWITEM

            mov edi, lParam

            ASSUME edi:PTR DRAWITEMSTRUCT

            SWITCH [edi].itemAction

                CASE ODA_DRAWENTIRE

                    invoke CreateCompatibleDC, [edi].hdc
                    mov hdcMem, eax
                    push eax

                    invoke SelectObject, hdcMem, hBmp
                    push eax

                    invoke GetObject, hBmp, SIZEOF bmp, ADDR bmp

                    ;--------------------------------------------------
                    ; The ASSUME for EDI and the crowded layout of the
                    ; TransparentBlt invoke were necessary to avoid  a
                    ; "error A2039: line too long".
                    ;--------------------------------------------------

                    invoke TransparentBlt,[edi].hdc,[edi].rcItem.left,
                                      [edi].rcItem.top,[edi].rcItem.right,
                                      [edi].rcItem.bottom,hdcMem,0,0,
                                      bmp.bmWidth,bmp.bmHeight,0FF00FFh

                    ;-------------------------------------------------------
                    ; This was used to verify that the pixel size of the
                    ; static control, which is specified in Dialog Template
                    ; Units in the dialog template, is close to the size of
                    ; the bitmap (192x48). Note that TransparentBlt works
                    ; much like StretchBlt, in that it will stretch the
                    ; bitmap to fit, as necessary. You must build this
                    ; source as a console app to see the printf output.
                    ;-------------------------------------------------------

                    ;printf("%d\n", [edi].rcItem.top)
                    ;printf("%d\n", [edi].rcItem.left)
                    ;printf("%d\n", [edi].rcItem.right)
                    ;printf("%d\n", [edi].rcItem.bottom)

                    pop eax
                    invoke SelectObject, hdcMem, eax

                    pop eax
                    invoke DeleteDC,eax

            ENDSW

            ASSUME edi:NOTHING

            return TRUE

        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:
;==============================================================================

    invoke GetModuleHandle, NULL
    mov   hInstance, eax

    Dialog "Test", \
           "MS Sans Serif",10, \
           WS_OVERLAPPED or WS_SYSMENU or DS_CENTER, \
           1,0,0,100,75,1024

    DlgStatic 0,SS_OWNERDRAW or WS_BORDER,10,10,77,20,IDC_STC

    CallModalDialog hInstance,0,DlgProc,NULL

    exit
;==============================================================================
end start
eschew obfuscation