News:

Masm32 SDK description, downloads and other helpful links
Message to All Guests
NB: Posting URL's See here: Posted URL Change

Main Menu

maybe i catch a bug

Started by A-new, January 01, 2015, 09:32:20 PM

Previous topic - Next topic

A-new

when i use gdi32 api function,such as StretchBlt 、BitBlt
invoke StretchBlt,wParam,0,0,rect.right,rect.bottom,hdcSrc,0,0,sbmp.bmWidth,sbmp.bmHeight,SRCCOPY
then the debugger date
0012FA2C   2501084F  |hDestDC = 2501084F
0012FA30   00000000  |XDest = 0x0
0012FA34   00000000  |YDest = 0x0
0012FA38   00000123  |WidthDest = 123 (291.)
0012FA3C   000000AC  |HeightDest = AC (172.)
0012FA40   000405DE  |hSrcDC = 000405DE (window)
0012FA44   00000000  |XSrc = 0x0
0012FA48   00000000  |YSrc = 0x0
0012FA4C   2501084F  |WidthSrc = 2501084F (620824655.)
0012FA50   0012FABC  |HeightSrc = 12FABC (1243836.)
0012FA54   00CC0020  \ROP = SRCCOPY

;and the type of sbmp is BITMAP
0012FC68  0000011C ->sbmp.bmWidth
0012FC6C  00000115 ->sbmp.bmHeight
0012FC70  00000470
0012FC74  00200001
0012FC78  00000000

dedndave

i'm not sure i understand the question, but....

0012FA4C   2501084F  |WidthSrc = 2501084F (620824655.)
0012FA50   0012FABC  |HeightSrc = 12FABC (1243836.)


those are unrealistic dimensions
we can't see the rest of the code, so it's hard to say why   :P

A-new

thx ,this is just a simple project,print the bmp to the client rect
this is the code
test.asm

.386
.model flat, stdcall  ;32 bit memory model
option casemap :none  ;case sensitive

include test.inc

.code

start:
invoke GetModuleHandle,NULL
mov hInstance,eax
invoke InitCommonControls
invoke DialogBoxParam,hInstance,IDD_MAIN,NULL,addr DlgProc,NULL
invoke ExitProcess,0

;########################################################################

DlgProc proc hWin:HWND,uMsg:UINT,wParam:WPARAM,lParam:LPARAM
LOCAL hdc:HDC
LOCAL hdcSrc:HDC
LOCAL PicH:DWORD
LOCAL PicW:DWORD
LOCAL rect:RECT
LOCAL hRgn:HRGN
LOCAL hbitmap:HBITMAP
LOCAL sbmp:BITMAP
LOCAL hpaint:PAINTSTRUCT

mov eax,uMsg
.if eax==WM_INITDIALOG
invoke GetWindowLong,hWin, GWL_STYLE
or eax,WS_SIZEBOX
invoke SetWindowLong,hWin,GWL_STYLE,eax
invoke LoadBitmap,hInstance,logo
mov hbitmap,eax
invoke GetDC,hWin
mov hdc,eax
invoke CreateCompatibleDC,hdc
mov hdcSrc,eax
invoke SelectObject,hdcSrc, hbitmap
invoke ReleaseDC,hWin,hdc
invoke RtlZeroMemory,addr sbmp,sizeof sbmp
invoke GetObject,hbitmap,sizeof sbmp,addr sbmp
;initialization here
.elseif eax==WM_CTLCOLORDLG
invoke RtlZeroMemory,addr rect,sizeof rect
invoke GetClientRect,hWin,addr rect
invoke SetStretchBltMode,wParam,COLORONCOLOR
invoke StretchBlt,wParam,0,0,rect.right,rect.bottom,hdcSrc,0,0,sbmp.bmWidth,sbmp.bmHeight,SRCCOPY
invoke GetStockObject,NULL_BRUSH
.elseif eax==WM_SIZE
invoke InvalidateRect,hWin,NULL,TRUE
.elseif eax==WM_COMMAND
mov edx,wParam
movzx eax,dx
shr edx,16
.if edx==BN_CLICKED
.if eax==IDOK

.elseif eax==IDCANCEL
invoke SendMessage,hWin,WM_CLOSE,NULL,NULL
.endif
.endif
.elseif eax==WM_CLOSE
invoke DeleteDC,hdcSrc
invoke EndDialog,hWin,0
.else
mov eax,FALSE
ret
.endif
mov eax,TRUE
ret
DlgProc endp

end start



test.ini


include windows.inc
include kernel32.inc
include user32.inc
include Comctl32.inc
include shell32.inc
include gdi32.inc
includelib kernel32.lib
includelib user32.lib
includelib Comctl32.lib
includelib shell32.lib
includelib gdi32.lib
DlgProc PROTO :HWND,:UINT,:WPARAM,:LPARAM

.const

IDD_MAIN                equ 101
logo                    equ 100


;#########################################################################

.data?

hInstance dd ?

;#########################################################################


the rest file  just Resources

dedndave

after you have loaded the bitmap resource, you will have an HBITMAP object handle
you can pass that handle to GetObject to get the bitmap dimensions

i use this function for that

;***********************************************************************************************

GetBitmapSize PROC hbmpBitmap:HBITMAP,lpSize:LPVOID

;returns X and Y dimensions of a bitmap in EAX and ECX
;will optionally fill a SIZE structure with the same values
;if the lpSize pointer is NULL, no structure is filled

;------------------------------

    LOCAL   bms :BITMAP

;------------------------------

    xor     eax,eax
    mov     bms.bmWidth,eax
    mov     bms.bmHeight,eax
    INVOKE  GetObject,hbmpBitmap,sizeof BITMAP,addr bms
    mov     edx,lpSize
    mov     ecx,bms.bmWidth
    mov     eax,bms.bmHeight
    .if edx
        mov     [edx]._SIZE.x,ecx
        mov     [edx]._SIZE.y,eax
    .endif
    ret

GetBitmapSize ENDP

;***********************************************************************************************


to use it, you would place a PROTOtype near the beginning of the program (usually, just after the INCLUDE's)
GetBitmapSize PROTO :HBITMAP,:LPVOID

then, to use the routine.....
        INVOKE  GetBitmapSize,hBmp,NULL
;EAX = Y dimension
;ECX = X dimension


as a side note:
opening a ".const" section is not required for EQUates

dedndave

optionally, if you want to use a global _SIZE structure...
        .DATA?

BmpSize _SIZE <>

        .CODE

        INVOKE  GetBitmapSize,hBmp,offset BmpSize
;EAX = BmpSize.y = Y dimension
;ECX = BmpSize.x = X dimension

A-new

thx your help,my poor english,now i really know why my code do not work normal
Just because a local variable
LOCAL sbmp:BITMAP
if define this variable as a global variable
.data?
sbmp BITMAP<>

my code will work well,but the real problem appeared,Why won't show my bitmap in the client area and if I use C language to write the same code can display bitmap




dedndave

well, in the WM_INITDIALOG code, i see where you select the bitmap into a compatible DC
however, i don't see the code for WM_PAINT - i don't see where it is ever copied into the dialog hDC
also - i don't see the resource file
it might help if you would ZIP and attach the complete project

that having been said, i rarely use a dialog window when painting or drawing
i might use a dialog if it just has controls (buttons, edit boxes, icons, text, etc)

but, when i want to draw/paint, i generally use a regular window with WndProc and a message loop
so - i have little experience with painting in a dialog
i guess it could work, though - lol

dedndave

ohhh - now i see the code in WM_CTLCOLORDLG   :biggrin:

never saw that before - lol
that message is generally used for a solid color
i don't think painting it will work

If an application processes this message, it must return a handle to a brush.
The system uses the brush to paint the background of the dialog box.


what you can imply from that is that after the WM_CTLCOLORDLG message returns to the system,
the HBRUSH returned in EAX is used to paint the dialog background
so, whatever you painted gets covered up
maybe that's not how it works
you said you have a working C version   :redface:

ok - you use a NULL brush - hmmm interesting approach

dedndave

tomorrow, i'll make a RC file and play with it a bit

i see a couple little things....
you should save and restore the orginal HBITMAP selection in the memory DC
(when SelectObject returns, save EAX - then, in WM_CLOSE, select that back into the DC before deleting it)

no need to zero the RECT structure before GetClientRect

dedndave

#9
ok - got my curiosity up, so i had to play with it tonight   :lol:

i made the following changes:

1) created RC file

2) global hdcSrc variable and sbmp structure

3) include file path's and masm32rt.inc
i don't use KetilO's RadAsm, so we need paths to make things work
also - i used \masm32\include\masm32rt.inc to handle the preface (.386, model, option, inc's and lib's)
you can have a look inside that file to see what it does

4) DlgProc return values
i modified the way DlgProc handles return values
generally, a dialog proc should return 0 - there are a few exceptions
one exception to this rule is WM_CTLCOLORxxx
it must return an HBRUSH
you can look at the code and see what i added and commented out

5) added hbrNull global variable
got the stock NULL_BRUSH in WM_INITDIALOG and stored it
then, return the global in EAX for WM_CTLCOLORDLG

6) added code to save and restore the original memory DC HBITMAP, as previously mentioned

you only need to download Test.zip
test.png.zip is the picture you see...

EDIT: attachment updated (Test2.zip)
corrected DialogProc return values
added manifest

A-new

Thank you very much,I'm just start learning assembly,from your answer I understand the difference between global and local variables,and how to return a value in the assembly
Thank you again for give directions
I don't have enough permissions to upload attachments,Today I also modified successfully, will no longer show oneself up
In fact,it's my stupid bug
thx man

dedndave

well - i never saw your RC file
but, DialogBoxParam creates a modal dialog

http://msdn.microsoft.com/en-us/library/windows/desktop/ms645465%28v=vs.85%29.aspx

that page links you to DialogProc...

http://msdn.microsoft.com/en-us/library/windows/desktop/ms645469%28v=vs.85%29.aspx

as you can see, i got the return value incorrect   :lol:
so - you want to read that page and modify your program accorfdingly
i am not used to using dialog boxes   :P
i almost always use CreateWindowEx

the important thing is to allow each message type to return values seperately   :t

A-new

thx again,in fact rc file is not  so important,

today i read your code again found that  our code is similar, just the function GetStockObject's position is different,

Through your answer and I learned a lot of things,thank you very much




dedndave

i modified the attachment, above

corrected DialogProc return values
added manifest

A-new

What is the use for add manifest ,it looks no difference ,now I still have a problem .elseif eax==WM_CTLCOLORDLG
invoke GetClientRect,hWin,addr rect
invoke SetStretchBltMode,wParam,COLORONCOLOR
invoke StretchBlt,wParam,0,0,rect.right,rect.bottom,hdcSrc,0,0,sbmp.bmWidth,sbmp.bmHeight,SRCCOPY
mov eax,hBitmapBrush
ret ;if not add ret,the picture does not show

and radasm progect  thx bro