Hello all, lately I am learning about creating controls, modify, and wanted to know how I can set a background image
for a dialog control, as this picture, for example this is done in VB:
(http://farm7.static.flickr.com/6050/5912147904_db5e313dd5.jpg)
I want set a imagen of background interchanged, I mean that I Will can change for various images in runtime, it is possible?
thank you very much people :bg
You use a STATIC control with the bitmap style and use STM_SETIMAGE message to load an image from your resource section. In most OS versions the image needs to be a BMP file. You set the STATIC control to the size of the dialog/Window and place other controls over it. This technique is not successful if you are directly drawing on the client area of the dialog/Window. Note that you may have to create the STATIC control before the other controls on the dialog so that the other controls overwrite the image where they are placed.
hutch, thanks but I not see nothing option of bitmap style:
(http://img96.imageshack.us/img96/6058/20654628.png)
:(
this is a dialog with radasm
Hi RHL,
If you want to set the background image in a dialog its best to handle the WM_PAINT message and draw the client area yourself.
Static control style is "SS_BITMAP". I do not use RadAsm but from memory using Ketil's resource editor, it is called something else, a picture control or similar.
Here's a snippet for handling WM_PAINT, it uses GDI+ so that you can use a number of different image formats, pretty much does exactly what you want:
DATA SECTION
hInstance HANDLE ?
GDIPlusToken ULONG_PTR 0
gdipsi GdiplusStartupInput <1,0,0,0>
pPic1 PTR 0
CODE SECTION
invoke GetModuleHandle, 0
mov [hInstance],eax
invoke GdiplusStartup,offset GDIPlusToken,offset gdipsi,NULL
invoke DialogBoxParam,[hInstance],1000,0,ADDR DlgProc,0
invoke GdipDisposeImage,[pPic1]
invoke GdiplusShutdown,[GDIPlusToken]
invoke ExitProcess,0
DlgProc FRAME hwnd,uMsg,wParam,lParam
uses edi,ebx,esi
LOCAL rect:RECT
LOCAL pGraphics:%PTR
LOCAL ps:PAINTSTRUCT
cmp D[uMsg],WM_INITDIALOG
jne >.WM_PAINT
invoke GdipLoadImageFromFile,L"SOMEIMAGE.JPG",offset pPic1
jmp >>.EXIT
.WM_PAINT
cmp D[uMsg],WM_PAINT
jne >>.WM_CLOSE
invoke BeginPaint,[hwnd],offset ps
invoke GetClientRect,[hwnd],offset rect
invoke GdipCreateFromHWND, [hwnd], offset pGraphics
invoke GdipSetPixelOffsetMode,[pGraphics],PixelOffsetModeHighQuality
invoke GdipSetInterpolationMode,[pGraphics],InterpolationModeHighQualityBicubic
invoke GdipDrawImageRectI,[pGraphics],[pPic1],0,0,[rect.right], [rect.bottom]
invoke GdipDeleteGraphics, [pGraphics]
invoke EndPaint,[hwnd],offset ps
mov eax, TRUE
ret
.WM_CLOSE
cmp D[uMsg],WM_CLOSE
jne >.DEFPROC
INVOKE EndDialog,[hwnd],0
.DEFPROC
mov eax,FALSE
ret
.EXIT
mov eax, TRUE
ret
ENDF
Shape control in radasm - little black square over white square icon - set xStyle to WS_CHILD + WS_VISIBLE + SS_BITMAP. Then in WM_INITDIALOG call SendMessage with STM_SETIMAGE to set the bitmap. Or use a png file (store as raw data resource) and use PngLib to create a bmp to use with STM_SETIMAGE.
If re-using and recalling to set a different image at runtime see my other post about handling STM_SETIMAGE to prevent memory leak: http://www.masm32.com/board/index.php?topic=17270.0
The problem with the static control idea is that it works great as long as you don't have to resize the window, if you do you have to resize the control as well slowing everything down. Its better just to paint your background directly. If you only plan on using bitmaps the following will do the same as the GDI+ example:
DATA SECTION
hInstance HANDLE ?
hBmp HANDLE ?
cxDib DD ?
cyDib DD ?
CODE SECTION
START:
invoke GetModuleHandle, 0
mov [hInstance],eax
invoke DialogBoxParam,[hInstance],1000,0,ADDR DlgProc,0
invoke ExitProcess,0
DlgProc FRAME hwnd,uMsg,wParam,lParam
uses edi,ebx,esi
LOCAL bmp:BITMAP
LOCAL membmp:%HANDLE
LOCAL rect:RECT
LOCAL ps:PAINTSTRUCT
LOCAL hDC:%HANDLE
LOCAL mdc1:%HANDLE
LOCAL mdc2:%HANDLE
cmp D[uMsg],WM_INITDIALOG
jne >.WM_PAINT
invoke LoadImage,[hInstance],"SomeImage.bmp",IMAGE_BITMAP,0,0,LR_LOADFROMFILE
mov [hBmp],eax
invoke GetObject,eax,SIZEOF BITMAP,offset bmp
mov eax,[bmp.bmWidth]
mov [cxDib],eax
mov eax,[bmp.bmHeight]
mov [cyDib],eax
jmp >>.EXIT
.WM_PAINT
cmp D[uMsg],WM_PAINT
jne >>.WM_CLOSE
invoke BeginPaint,[hwnd],addr ps
invoke CreateCompatibleDC,[ps.hdc]
mov [mdc1],eax
invoke CreateCompatibleDC,[ps.hdc]
mov [mdc2],eax
invoke GetClientRect,[hwnd],offset rect
invoke CreateCompatibleBitmap,[ps.hdc],[rect.right],[rect.bottom]
mov [membmp],eax
invoke SetStretchBltMode,[mdc1],COLORONCOLOR
invoke SelectObject,[mdc1],[membmp]
mov [membmp],eax
invoke SelectObject,[mdc2],[hBmp]
mov [hBmp],eax
invoke StretchBlt,[mdc1],0,0,[rect.right],[rect.bottom],[mdc2],0,0,[cxDib],[cyDib],SRCCOPY
invoke GetDC,[hwnd]
mov [hDC],eax
invoke BitBlt,[hDC],0,0,[rect.right],[rect.bottom],[mdc1],0,0,SRCCOPY
invoke ReleaseDC,[hwnd],[hDC]
invoke SelectObject,[mdc1],[membmp]
invoke DeleteObject,eax
invoke SelectObject,[mdc2],[hBmp]
mov [hBmp],eax
invoke DeleteDC,[mdc1]
invoke DeleteDC,[mdc2]
invoke EndPaint,[hwnd],addr ps
mov eax, TRUE
ret
.WM_CLOSE
cmp D[uMsg],WM_CLOSE
jne >.DEFPROC
INVOKE EndDialog,[hwnd],0
.DEFPROC
mov eax,FALSE
ret
.EXIT
mov eax, TRUE
ret
ENDF
I am very grateful to you
This sizes the dialog window, instead of the bitmap.
;==============================================================================
include \masm32\include\masm32rt.inc
;==============================================================================
.data
hBmp0 dd 0
hBmp1 dd 0
hBrush0 dd 0
hBrush1 dd 0
bmpWidth0 dd 0
bmpHeight0 dd 0
bmpWidth1 dd 0
bmpHeight1 dd 0
currentImage dd 0
bitmap BITMAP <>
path0 db "\masm32\examples\exampl01\showdib\apollo11.bmp",0
path1 db "\masm32\examples\exampl01\showdib\printer.bmp",0
.code
;==============================================================================
;---------------------------------------------------------------------
; This procedure sizes the specified window so the client area is the
; specified width and height and returns whatever MoveWindow returns.
; Unlike AdjustWindowRect and AdjustWindowRectEx, this procedure can
; handle the WS_OVERLAPPED style.
;---------------------------------------------------------------------
SetClientSize proc uses ebx hwnd:HWND, pixelWidth:DWORD, pixelHeight:DWORD
LOCAL rcc:RECT, rcw:RECT
invoke GetClientRect, hwnd, ADDR rcc
invoke GetWindowRect, hwnd, ADDR rcw
mov ecx, rcw.right
sub ecx, rcw.left ; ecx = window width - 1
mov eax, pixelWidth
dec eax ; eax = pixelWidth - 1
mov ebx, rcc.right ; ebx = client width - 1
sub ebx, eax ; ebx = difference
sub ecx, ebx ; adjust width
mov edx, rcw.bottom
sub edx, rcw.top ; edx = window height - 1
mov eax, pixelHeight
dec eax ; eax = pixelHeight - 1
mov ebx, rcc.bottom ; ebx = client height - 1
sub ebx, eax ; ebx = difference
sub edx, ebx ; adjust height
invoke MoveWindow, hwnd, rcw.left, rcw.top, ecx, edx, TRUE
ret
SetClientSize endp
;==============================================================================
DlgProc proc uses ebx hwndDlg:dword, uMsg:dword, wParam:dword, lParam:dword
SWITCH uMsg
CASE WM_INITDIALOG
invoke LoadImage, 0, ADDR path0, IMAGE_BITMAP, 0, 0, LR_LOADFROMFILE
mov hBmp0, eax
invoke LoadImage, 0, ADDR path1, IMAGE_BITMAP, 0, 0, LR_LOADFROMFILE
mov hBmp1, eax
invoke CreatePatternBrush, hBmp0
mov hBrush0, eax
invoke CreatePatternBrush, hBmp1
mov hBrush1, eax
invoke GetObject, hBmp0, SIZEOF BITMAP, ADDR bitmap
push bitmap.bmWidth
pop bmpWidth0
push bitmap.bmHeight
pop bmpHeight0
invoke GetObject, hBmp1, SIZEOF BITMAP, ADDR bitmap
push bitmap.bmWidth
pop bmpWidth1
push bitmap.bmHeight
pop bmpHeight1
;printf("%d\t%d\n", bmpWidth0, bmpHeight0)
;printf("%d\t%d\n", bmpWidth1, bmpHeight1)
invoke SetClientSize, hwndDlg, bmpWidth0, bmpHeight0
CASE WM_CTLCOLORDLG
SWITCH currentImage
CASE 0
return hBrush0
CASE 1
return hBrush1
ENDSW
CASE WM_COMMAND
SWITCH wParam
CASE 1001
SWITCH currentImage
CASE 0
mov currentImage, 1
invoke SetClientSize, hwndDlg, bmpWidth1, bmpHeight1
CASE 1
mov currentImage, 0
invoke SetClientSize, hwndDlg, bmpWidth0, bmpHeight0
ENDSW
invoke InvalidateRect, hwndDlg, NULL, TRUE
CASE IDCANCEL
invoke DeleteObject, hBrush0
invoke DeleteObject, hBrush1
invoke DeleteObject, hBmp0
invoke DeleteObject, hBmp1
invoke EndDialog, hwndDlg, 0
ENDSW
CASE WM_CLOSE
invoke DeleteObject, hBrush0
invoke DeleteObject, hBrush1
invoke DeleteObject, hBmp0
invoke DeleteObject, hBmp1
invoke EndDialog, hwndDlg, 0
ENDSW
xor eax, eax
ret
DlgProc endp
;==============================================================================
start:
;==============================================================================
Dialog "Test", "MS Sans Serif",10, \
WS_OVERLAPPED or WS_SYSMENU or DS_CENTER, \
1,0,0,120,100,1024
DlgButton "Next",WS_TABSTOP,5,5,20,10,1001
invoke GetModuleHandle, NULL
CallModalDialog eax,0,DlgProc,NULL
exit
;==============================================================================
end start