News:

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

Main Menu

StretchBlt Example

Started by zedd151, March 09, 2025, 05:27:17 PM

Previous topic - Next topic

zedd151

Quote from: NoCforMe on March 09, 2025, 07:28:03 AMHey, Zedd, maybe next you might want to try StretchBlt() to round out your GDI methods.
Okay. Here you go...  :azn:

StretchBlt example:  Another example that others might find useful...

Source code fully commented.  :tongue:
    include \masm32\include\masm32rt.inc

    DlgProc proto :dword, :dword, :dword, :dword

        cwidth        equ 390                  ; desired client area width
        cheight      equ 260                  ; desired client area height

    .data?
   
        hBmp_red      dd ?                      ; handle of bitmap loaded from resource

    .code

    start proc
    local hInstance:dword
        invoke GetModuleHandle, NULL
        mov hInstance, eax

        invoke DialogBoxParam, hInstance, 100, 0, addr DlgProc, 0  ;; create dialog box, from resource dilalog

        invoke ExitProcess, eax
    start endp

    DlgProc proc hWin:dword, uMsg:dword, wParam:dword, lParam:dword
    local hDC:dword, ps:PAINTSTRUCT, rct:RECT, hBrush:dword, hBrush_old:dword
    local mDC:dword, hBmp:dword, hBmp_old:dword, hPen:dword, hPen_old:dword
    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, eax, 100                          ; load bitmap from resource
          mov hBmp_red, eax

        .elseif uMsg == WM_PAINT
          invoke BeginPaint, hWin, addr ps
          mov hDC, eax                                          ; window client area DC

          ;; get client area rectangle
          invoke GetClientRect, hWin, addr rct                  ; client rectangle of dialog box

          invoke CreateCompatibleDC, hDC
          mov mDC, eax                                          ; memory DC

          invoke CreateCompatibleBitmap, hDC, rct.right, rct.bottom
          mov hBmp, eax                                        ; compatible bitmap handle
          invoke SelectObject, mDC, hBmp
          mov hBmp_old, eax

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

          ;; Here I change the background color of the main window
          invoke CreateSolidBrush, 00DFDFDFh                    ; color = off white
          mov hBrush, eax  ;; 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                        ; select memory bitmap object
          mov hBmp_old, eax
          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 eax, eax
        ret
    DlgProc endp

    end

The image on the left has been stretched using StretchBlt.
The image on the right is normal size using BitBlt.



:cool:
Slight change to the source code, also in the attachment.
¯\_(ツ)_/¯   :azn:

'As we don't do "requests", show us your code first.'  -  hutch—

zedd151

#1
Stretching a bitmap can also be done while using TransparentBlt.  :smiley:

    include \masm32\include\masm32rt.inc

    include \masm32\include\msimg32.inc        ; needed for TransparentBlt
    includelib \masm32\lib\msimg32.lib          ; needed for TransparentBlt
       
    DlgProc proto :dword, :dword, :dword, :dword

        cwidth        equ 390                  ; desired client area width
        cheight      equ 260                  ; desired client area height

    .data?
   
        hBmp_red      dd ?                      ; handle of bitmap loaded from resource

    .code

    start proc
    local hInstance:dword
        invoke GetModuleHandle, NULL
        mov hInstance, eax

        invoke DialogBoxParam, hInstance, 100, 0, addr DlgProc, 0  ;; create dialog box, from resource dilalog

        invoke ExitProcess, eax
    start endp

    DlgProc proc hWin:dword, uMsg:dword, wParam:dword, lParam:dword
    local hDC:dword, ps:PAINTSTRUCT, rct:RECT, hBrush:dword, hBrush_old:dword
    local mDC:dword, hBmp:dword, hBmp_old:dword, hPen:dword, hPen_old:dword
    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, eax, 100                          ; load bitmap from resource
          mov hBmp_red, eax

        .elseif uMsg == WM_PAINT
          invoke BeginPaint, hWin, addr ps
          mov hDC, eax                                          ; window client area DC
         
          ;; get client area rectangle
          invoke GetClientRect, hWin, addr rct                  ; client rectangle of dialog box

          invoke CreateCompatibleDC, hDC
          mov mDC, eax                                          ; memory DC

          invoke CreateCompatibleBitmap, hDC, rct.right, rct.bottom
          mov hBmp, eax                                        ; compatible bitmap handle
          invoke SelectObject, mDC, hBmp
          mov hBmp_old, eax

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

          ;; Here I change the background color of the main window
          invoke CreateSolidBrush, 00FFBF7Fh                    ;; a nice light blue colr
          mov hBrush, eax  ;; 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                        ; select memory bitmap object
          mov hBmp_old, eax
          invoke BitBlt, hDC, 0, 0, rct.right, rct.bottom, mDC, 0, 0, SRCCOPY
         
          ;; ###########################################################
         
          invoke SelectObject, mDC, hBmp_red                    ; select resource bitmap object
         
                                                                ; transparent blit, exclude color 00FFFFFFh
          invoke TransparentBlt, hDC,  10, 10, 240, 240, mDC, 0, 0, 120, 120, 00FFFFFFh
         
                                                                ; mormal 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 eax, eax
        ret
    DlgProc endp

    end

The image on the left has been stretched using TransparentBlt, while also making the white part of the bitmap transparent.
The image on the right is normal size using BitBlt, and represents exactly what the bitmap actually looks like.
The bitmap used here, is slightly different than the one used in the first example in that this bitmap has no borders drawn on  the actual bitmap, as the one posted above does.


Slight change to the source code, also in the attachment.
¯\_(ツ)_/¯   :azn:

'As we don't do "requests", show us your code first.'  -  hutch—