I have ported my 32 bit gdi examples to 64 bit.
I had to make a couple of changes for these to work as expected in 64 bit. Originally I used the PAINTSTRUCT RECT for some of the API calls in WM_PAINT, which worked fine in the original 32 bit versions. But also in the 32 bit code, I used GetClientRect for other API calls. That also worked fine in 32 bit. But not so, for 64 bit. I now use the RECT structure filled in by GetClientRect for everything in WM_PAINT, I even modified the 32 bit versions to do the same. Now code-wise, no difference between the two flavors of each program except for obvious dword/qword and registers, etc. :rolleyes:
- polygon_64 ; example of creating a filled polygon
- stretchblt_64 ; example of using StretchBlt to stretch a bitmap
- transparentblt_64 ; example of using TransparentBlt to exclude a single color when drawing a bitmap
- transparentblt_stretch_64 ; same as above, but also stretches the bitmap as well
code for stretchblt_64
include \masm64\include64\masm64rt.inc
cwidth equ 390 ; desired client area width
cheight equ 260 ; desired client area height
.data?
hBmp_red dq ? ; handle of bitmap loaded from resource
.code
start proc
local hInstance:qword
invoke GetModuleHandle, NULL
mov hInstance, rax
invoke DialogBoxParam, hInstance, 100, 0, addr DlgProc, 0 ;; create dialog box, from resource dilalog
invoke ExitProcess, rax
start endp
DlgProc proc hWin:qword, uMsg:qword, wParam:qword, lParam:qword
local hDC:qword, ps:PAINTSTRUCT, rct:RECT, hBrush:qword, hBrush_old:qword
local mDC:qword, hBmp:qword, hBmp_old:qword, hPen:qword, hPen_old:qword
local x:dword, y:dword, wwid:dword, whgt:dword, cwid:dword, chgt:dword
.if uMsg == WM_INITDIALOG
;; resizing Client Area to exact dimensions, specified by cwidth and cheight
invoke GetWindowRect, hWin, addr rct ;; get window current dimensions.
mov eax, rct.right ;; obtain current window width by subtracting left boundary
sub eax, rct.left ;; from the right boundary
mov wwid, eax ;; store current window width
mov eax, rct.bottom ;; obtain current window height by subtracting top boundary
sub eax, rct.top ;; from the bottom boundary
mov whgt, eax ;; store current window height
invoke GetClientRect, hWin, addr rct ;; get client area current dimensions.
mov eax, rct.right ;; obtain current client width by subtracting left boundary
sub eax, rct.left ;; from the right boundary
mov cwid, eax ;; store current client area width
mov eax, rct.bottom ;; obtain current client height by subtracting top boundary
sub eax, rct.top ;; from the bottom boundary
mov chgt, eax ;; store client area height
;; calculate the difference between desired client area width and current client area width
mov eax, cwidth
sub eax, cwid
;; adjust the window width according to the difference calculated above
add wwid, eax
;; calculate the difference between desired client area height and current client area height
mov eax, cheight
sub eax, chgt
;; adjust the window height according to the difference calculated height
add whgt, eax
;; center the main window
;; obtain client area of the desktop, not including the task bar
invoke SystemParametersInfoA, SPI_GETWORKAREA, 0, addr rct, 0
;; center window width
mov eax, rct.right
sub eax, wwid
sar eax, 1
mov x, eax
;; center window height
mov eax, rct.bottom
sub eax, whgt
sar eax, 1
mov y, eax
;; implement the centering of the resized main window
invoke MoveWindow, hWin, x, y, wwid, whgt, TRUE
invoke GetModuleHandle, 0
invoke LoadBitmap, rax, 100 ; load bitmap from resource
mov hBmp_red, rax
.elseif uMsg == WM_PAINT
invoke BeginPaint, hWin, addr ps
mov hDC, rax ; window client area DC
;; get client area rectangle
invoke GetClientRect, hWin, addr rct ; client rectangle of dialog box
invoke CreateCompatibleDC, hDC
mov mDC, rax ; memory DC
invoke CreateCompatibleBitmap, hDC, rct.right, rct.bottom
mov hBmp, rax ; compatible bitmap handle
;; ###########################################################
invoke SelectObject, mDC, hBmp ; select memory bitmap object
mov hBmp_old, rax
;; Here I change the background color of the main window
invoke CreateSolidBrush, 00DFDFDFh ; color = off white
mov hBrush, rax ;; save the brush handle
;; fill the client area rectangle with chosen color
invoke FillRect, mDC, addr rct, hBrush ; fill rectangle in memory DC
;; delete the brush, as it is no longer needed
invoke DeleteObject, hBrush
invoke SelectObject, mDC, hBmp
mov hBmp_old, rax
invoke BitBlt, hDC, 0, 0, rct.right, rct.bottom, mDC, 0, 0, SRCCOPY
;; ###########################################################
invoke SelectObject, mDC, hBmp_red ; select resource bitmap object
; stretch blit resource bitmap
invoke StretchBlt, hDC, 10, 10, 240, 240, mDC, 0, 0, 120, 120, SRCCOPY
; normal bit blit resource bitmap
invoke BitBlt, hDC, 260, 10, 120, 120, mDC, 0, 0, SRCCOPY
;; ###########################################################
invoke SelectObject, mDC, hBmp_old
invoke DeleteObject, hBmp ; delete DC bitmap object
invoke DeleteDC, mDC ; delete memory DC
invoke EndPaint, hWin, addr ps
.elseif uMsg == WM_CLOSE
invoke DeleteObject, hBmp_red ; delete resource bitmap object
invoke EndDialog, hWin, 0 ; clode dialog box
.endif
xor rax, rax
ret
DlgProc endp
end
(https://i.postimg.cc/G21H5Kdd/untitled.png)
all examples listed above are included in the attached zip file. :smiley: