News:

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

Main Menu

GDI+ gif animation

Started by six_L, January 23, 2025, 02:13:48 PM

Previous topic - Next topic

six_L

this is a demo about the GDI+ gif animation from Mikl__'s example.
1. Select a gif file in your disk, click "ApplyF" to play.
2. Use "msctls_trackbar32" and "ApplyT" to adjust speed.
3. Open the config dialogue with hotkey"ctrl+t", pasue with hotkey"ctrl+s",restore with hotkey"ctrl+a".
option casemap:none
option win64:7

include    \UASM64\include\windows.inc
include    \UASM64\include\Commctrl.inc
include    \UASM64\include\ShlObj.inc
include    \UASM64\include\gdiplus.inc

includelib \UASM64\Lib\user32.lib
includelib \UASM64\Lib\kernel32.lib
includelib \UASM64\Lib\shell32.lib
includelib \UASM64\Lib\gdi32.lib
includelib \UASM64\Lib\gdiplus.lib

TBrowseInfo struct
    hwndOwner          dq ?
    pIDLRoot           dq ?
    pszDisplayName     dq ?
    lpszTitle          dq ?
    ulFlags            dq ?
    lpfn               dq ?
    lParam             dq ?
    iImage             dq ?
TBrowseInfo ends
PItemIDList typedef ptr TBrowseInfo

    ICO_MAIN    equ 1000
    DLG_MAIN    equ 1001
    DLG_CONFIG    equ 1002
   
    IDC_HOTKEYRESTORE equ 2000
    IDC_HOTKEYPAUSE    equ 2001
    IDC_HOTKEYSETUPPARAMETERS equ 2002
   
    IDC_EDT        equ 3000
    IDC_OPENFILE    equ 3001
    IDC_APPLYF    equ 3002
    ID_VSPEED    equ 3003
    ID_SLIDER    equ 3004
    IDC_APPLYT    equ 3005

    IDC_DEFALUTSPEED equ 90

    xPROPID        equ 05100h

.data?
    hInstance    dq ?
    Main_hWnd    dq ?
    m_gdiplusToken    dd ?

    hHeap        dq ?

.data
    Guid_dimensionID \
            dd 06AEDBD6Dh
            dw 03FB5h
            dw 0418Ah
            db 083h,0A6h,07Fh,045h,022h,09Dh,0C8h,072h
    nWidth        dd 0
    nHeight        dd 0
    vdxClient    dd 0
    vdyClient    dd 0
    nFrameCount     dd 0
    pPropertyItem_buffer    dq 0
    hImage        dq 0
    Vspeed        SDWORD 90
    STOP_FLAG    BOOL FALSE
    PAUSE_FLAG    BOOL FALSE
    hThread        dq 0
    NewPosition    dq 0
    szBuf        db 260 dup(0)

.code

CenterScreen PROC USES rsi rdi hWnd:QWORD
    LOCAL wRect:RECT
    LOCAL h:DWORD
    LOCAL w:DWORD
    LOCAL x:DWORD
    LOCAL y:DWORD

    invoke    GetWindowRect,hWnd,addr wRect               
    mov     esi, wRect.bottom
    sub     esi, wRect.top
    mov    h,esi
    shr     esi, 1
    mov     edi, wRect.right
    sub     edi, wRect.left
    mov    w,edi
    shr     edi, 1
    invoke    GetSystemMetrics,SM_CYSCREEN           
    shr     rax, 1
    sub     rax, rsi
    mov    y, eax
    invoke    GetSystemMetrics,SM_CXSCREEN           
    shr     rax, 1
    sub     rax, rdi
    mov    x, eax
    invoke    MoveWindow,hWnd,x,y,w,h,TRUE                 

    ret
CenterScreen ENDP

atodq proc uses rsi rdi pString:QWORD
    ; ----------------------------------------
    ; Convert decimal string into qword value
    ; return value in rax
    ; ----------------------------------------
   
    xor    rax, rax
    mov    rsi, pString
    xor    rcx, rcx
    xor    rdx, rdx
    mov    al, [rsi]
    inc    rsi
   
    cmp    al, 2Dh   
    jne    proceed
    mov    al, [rsi]
    not    rdx
    inc    rsi
    jmp    proceed
@@:
    sub    al, 30h
    lea    rcx, [rcx+4*rcx]
    lea    rcx, [rax+2*rcx]
    mov    al, [rsi]
    inc    rsi
proceed:
    or    al, al
    jne    @B
    lea    rax, [rdx+rcx]
    xor    rax, rdx
    ret

atodq endp

xSelectFile proc USES rbx hWin:QWORD,pTitle:QWORD,pOutBuf:QWORD
    LOCAL xInfo:TBrowseInfo
   
    invoke    RtlZeroMemory,ADDR xInfo,sizeof TBrowseInfo
 
    lea    rax, xInfo
    mov    rcx, CStr("SelectFile")
    mov    (TBrowseInfo PTR [rax]).pszDisplayName, rcx
    mov    rcx,pTitle
    mov    (TBrowseInfo PTR [rax]).lpszTitle, rcx
    mov    rcx,hWin
    mov    (TBrowseInfo PTR [rax]).hwndOwner, rcx
    mov    (TBrowseInfo PTR [rax]).ulFlags, BIF_RETURNONLYFSDIRS or BIF_BROWSEINCLUDEFILES
 
    invoke    SHBrowseForFolder, addr xInfo
    cmp    rax, 0
    je    @Exit
    mov    rbx,rax
 
    invoke    SHGetPathFromIDList,rax,pOutBuf
    invoke    GlobalFree,rbx
@Exit:
    ret
xSelectFile endp

InitGgdiplus proc
    local @gdis:GdiplusStartupInput
   
    mov    @gdis.GdiplusVersion,1
    mov    @gdis.DebugEventCallback,0
    mov    @gdis.SuppressBackgroundThread,0
    mov    @gdis.SuppressExternalCodecs,0
    invoke    GdiplusStartup,addr m_gdiplusToken,addr @gdis,NULL
    ret

InitGgdiplus endp

WorkerThread proc hWnd:HWND
    LOCAL hDC:HDC
    LOCAL graphics:QWORD
    LOCAL FrameIndex:DWORD

    .while STOP_FLAG == FALSE
        invoke    GetDC, hWnd
        mov    hDC, rax
        invoke    GdipCreateFromHDC,hDC,addr graphics
       
        invoke    GdipDrawImageRectI,graphics,hImage,0,0,nWidth,nHeight
        ;Selects the frame in this Image object specified by a dimension and an index.
        invoke    GdipImageSelectActiveFrame,hImage,addr Guid_dimensionID,FrameIndex
       
        .if PAUSE_FLAG == FALSE
            inc    FrameIndex
            mov    eax,nFrameCount
            sub    eax,FrameIndex
            jnz    @f
            mov    FrameIndex,eax
        .endif
@@:   
        invoke    GdipDeleteGraphics,graphics
        invoke    ReleaseDC,hWnd, hDC
        invoke    Sleep,Vspeed
    .endw
       
    ret

WorkerThread endp

RestartThread proc
   
    mov    STOP_FLAG,TRUE
    invoke    WaitForSingleObject,hThread,INFINITE
    invoke    CloseHandle,hThread
    mov    STOP_FLAG,FALSE
    invoke    CreateThread,NULL,NULL,offset WorkerThread,Main_hWnd,NULL,NULL
    mov    hThread,rax
    ret

RestartThread endp

InitGifFileParameters proc plFile:QWORD
    LOCAL xw:DWORD
    LOCAL xh:DWORD
    LOCAL ptDiff:POINT
    LOCAL rctWnd:RECT
    LOCAL rctClient:RECT
    LOCAL @Wfile[1024]:BYTE
    LOCAL count:DWORD
    LOCAL pDimensionIDs:QWORD
    LOCAL xSize:DWORD
   
    invoke    RtlZeroMemory,addr @Wfile,sizeof @Wfile
    invoke    MultiByteToWideChar,CP_ACP,0,plFile,-1,addr @Wfile,1024
    invoke    GdipDisposeImage,hImage
    invoke    GdipLoadImageFromFile,addr @Wfile,addr hImage
    ;Gets the number of frame dimensions in this Image object.
    invoke    GdipImageGetFrameDimensionsCount,hImage,addr count
    xor    rcx,rcx
    mov    ecx,count
    test    ecx,ecx
    jz    @f
    shl    rcx,4
    mov    rax,rcx
    invoke    HeapAlloc,hHeap,HEAP_ZERO_MEMORY,rax
    mov    pDimensionIDs,rax
    ;Gets the identifiers for the frame dimensions of this Image object.
    invoke    GdipImageGetFrameDimensionsList,hImage,rax,count
    ;Gets the number of frames in a specified dimension of this Image object.
    invoke    GdipImageGetFrameCount,hImage,pDimensionIDs,addr nFrameCount
    ;Gets the size, in bytes, of a specified property item of this Image object.
    invoke    GdipGetPropertyItemSize,hImage,xPROPID,addr xSize

    xor    rcx,rcx
    mov    ecx,xSize
    shl    ecx,2
    mov    rax,rcx
    invoke    HeapAlloc,hHeap,HEAP_ZERO_MEMORY,rax
    mov    pPropertyItem_buffer,rax
    ;Gets a specified property item (piece of metadata) from this Image object.
    invoke    GdipGetPropertyItem,hImage,xPROPID,xSize,rax
    invoke    HeapFree,hHeap,HEAP_ZERO_MEMORY,pDimensionIDs
@@:
    invoke    GdipGetImageWidth,hImage,addr nWidth
    invoke    GdipGetImageHeight,hImage,addr nHeight
   
    invoke    GetClientRect,Main_hWnd,addr rctClient
    invoke    GetWindowRect,Main_hWnd,addr rctWnd
    mov    eax,rctWnd.right
    sub    eax,rctWnd.left
    sub    eax,rctClient.right
    mov    ptDiff.x,eax
    mov    eax,rctWnd.bottom
    sub    eax,rctWnd.top
    sub    eax,rctClient.bottom
    mov    ptDiff.y,eax
    mov    ecx,nHeight
    add    ecx,ptDiff.y
    mov    xh,ecx    ;nHeight
    mov    ecx,nWidth
    add    ecx,ptDiff.x
    mov    xw,ecx   
    invoke    MoveWindow,Main_hWnd,500,300,xw,xh,1

    ret

InitGifFileParameters endp

ConfigDlg proc hWnd:QWORD,uMsg:DWORD,wParam:QWORD,lParam:QWORD
   
    mov    eax,uMsg
    .if    eax ==    WM_INITDIALOG
                invoke    SendDlgItemMessage,hWnd,ID_SLIDER,TBM_SETRANGEMIN,FALSE,0
                invoke    SendDlgItemMessage,hWnd,ID_SLIDER,TBM_SETRANGEMAX,FALSE,100
                invoke    SendDlgItemMessage,hWnd,ID_SLIDER,TBM_SETTICFREQ,2,0
    .elseif eax == WM_COMMAND
         mov    rcx,wParam
        .if    cx == IDC_APPLYF
            invoke    RtlZeroMemory,addr szBuf,sizeof szBuf
            invoke  GetDlgItemText,hWnd,IDC_EDT,ADDR szBuf,sizeof szBuf
            .if rax
                invoke  InitGifFileParameters,ADDR szBuf
                invoke    CenterScreen,Main_hWnd
                invoke    RestartThread
            .else
                invoke    MessageBox, 0,CStr("Need GifFile"), CStr("Error:GetDlgItemText"), MB_OK or MB_ICONINFORMATION
            .endif
        .elseif cx == IDC_APPLYT
            invoke    RtlZeroMemory,addr szBuf,sizeof szBuf
            invoke  GetDlgItemText,hWnd,ID_VSPEED,ADDR szBuf,sizeof szBuf
            .if rax
                invoke  atodq,ADDR szBuf
                mov    rcx,2000
                mul    rcx
                mov    rcx,100   
                div    rcx        ;(0-100%)*2000
                mov    Vspeed,eax
            .else
                mov    Vspeed,IDC_DEFALUTSPEED
            .endif
        .elseif cx == IDC_OPENFILE
            invoke    RtlZeroMemory,addr szBuf,sizeof szBuf
            invoke    xSelectFile,hWnd,CStr("Select Your File"),addr szBuf
            invoke    SetDlgItemText,hWnd,IDC_EDT,addr szBuf
        .endif
       
    .elseif eax == WM_HSCROLL
                mov rax,wParam
                .if ax == TB_THUMBPOSITION ; Same as SB_THUMBPOSITION
            mov    rax,wParam
            shr    eax,16
            xor    rcx,rcx
            mov    cx,ax
            mov    NewPosition,rcx
            invoke    SendDlgItemMessage,hWnd,ID_SLIDER,TBM_SETPOS,TRUE,NewPosition
           
            invoke    RtlZeroMemory,addr szBuf,sizeof szBuf
            invoke    wsprintf,addr szBuf,CStr("%d"),NewPosition
            invoke    SendDlgItemMessage, hWnd,ID_VSPEED, WM_SETTEXT, FALSE, addr szBuf
               .elseif ax == TB_THUMBTRACK ; Same as SB_THUMBTRACK
            mov    rax,wParam
            shr    eax,16
            xor    rcx,rcx
            mov    cx,ax
            mov    NewPosition,rcx
            invoke    SendDlgItemMessage,hWnd,ID_SLIDER,TBM_SETPOS,TRUE,NewPosition
           
            invoke    RtlZeroMemory,addr szBuf,sizeof szBuf
            invoke    wsprintf,addr szBuf,CStr("%d"),NewPosition
            invoke    SendDlgItemMessage, hWnd,ID_VSPEED, WM_SETTEXT, FALSE, addr szBuf
                .endif

    .elseif    eax == WM_CLOSE
        invoke    EndDialog,hWnd,NULL
    .else
        mov    rax,FALSE
        ret
    .endif
    mov    rax,TRUE
    ret

ConfigDlg endp

MainDlgProc proc hWnd:QWORD,uMsg:DWORD,wParam:QWORD,lParam:QWORD
   
    mov    eax,uMsg
    .if    eax ==    WM_CREATE
        mov    rax,hWnd
        mov    Main_hWnd,rax

        invoke    RegisterHotKey, hWnd, IDC_HOTKEYPAUSE, MOD_CONTROL,"S"
                invoke    RegisterHotKey, hWnd, IDC_HOTKEYRESTORE, MOD_CONTROL,"A"
                invoke    RegisterHotKey, hWnd, IDC_HOTKEYSETUPPARAMETERS, MOD_CONTROL,"T"
       
        invoke    CreateDialogParam,hInstance,DLG_CONFIG,hWnd,offset ConfigDlg,NULL
        invoke    CloseHandle,rax
    .elseif    eax ==    WM_HOTKEY
        mov    rax, wParam
        .if    rax == IDC_HOTKEYPAUSE
            mov    PAUSE_FLAG,TRUE
        .elseif rax == IDC_HOTKEYRESTORE
            mov    PAUSE_FLAG,FALSE
        .elseif rax == IDC_HOTKEYSETUPPARAMETERS
            invoke    CreateDialogParam,hInstance,DLG_CONFIG,hWnd,offset ConfigDlg,NULL
            invoke    CloseHandle,rax
        .endif

    .elseif    eax ==    WM_SIZE
        mov    rax,lParam
        xor    rcx,rcx
        mov    cx,ax
        mov    vdxClient,ecx
        shr    rax,16
        xor    rcx,rcx
        mov    cx,ax
        mov    vdyClient,ecx
    .elseif    eax ==    WM_CLOSE
        mov    STOP_FLAG,TRUE
        invoke    GdipDisposeImage,hImage
        invoke    HeapFree,hHeap,HEAP_ZERO_MEMORY,pPropertyItem_buffer
        invoke    DestroyWindow,hWnd
        invoke    PostQuitMessage,NULL
    .else
        invoke    DefWindowProc,hWnd,uMsg,wParam,lParam
        ret
    .endif
    xor    rax,rax
    ret

MainDlgProc endp

_WinMain proc
    LOCAL    @stWndClass:WNDCLASSEX
    LOCAL    @stMsg:MSG
    LOCAL    hWnd:HANDLE

    invoke    RtlZeroMemory,addr @stWndClass,sizeof @stWndClass
    invoke    LoadIcon,hInstance,ICO_MAIN
    mov    @stWndClass.hIcon,rax
    mov    @stWndClass.hIconSm,rax
    invoke    LoadCursor,0,IDC_ARROW
    mov    @stWndClass.hCursor,rax
    mov    rax,hInstance
    mov    @stWndClass.hInstance,rax
    mov    @stWndClass.cbSize,sizeof WNDCLASSEX
    mov    @stWndClass.style,CS_HREDRAW or CS_VREDRAW
    lea    rax,MainDlgProc
    mov    @stWndClass.lpfnWndProc,rax
    mov    @stWndClass.hbrBackground,COLOR_WINDOW + 1
    mov    rax,CStr("GdiTourClass")
    mov    @stWndClass.lpszClassName,rax
    invoke    RegisterClassEx,addr @stWndClass
    invoke    CreateWindowEx,WS_EX_CLIENTEDGE,CStr("GdiTourClass"),CStr("GDI+ gif animation"),\
        WS_OVERLAPPEDWINDOW,400,200,400,300,NULL,NULL,hInstance,NULL
    mov    hWnd,rax
    invoke    ShowWindow,hWnd,SW_SHOWNORMAL
    invoke    UpdateWindow,hWnd
    .while    TRUE
        invoke    GetMessage,addr @stMsg,NULL,0,0
        .break    .if rax    == 0
        invoke    TranslateMessage,addr @stMsg
        invoke    DispatchMessage,addr @stMsg
    .endw
    ret

_WinMain endp

WinMainCRTStartup Proc
    invoke    InitGgdiplus
    invoke    GetModuleHandle,NULL
    mov    hInstance,rax
    invoke    GetProcessHeap
    mov    hHeap, rax
    invoke    _WinMain
    invoke    GdiplusShutdown,m_gdiplusToken
    invoke    ExitProcess,NULL
    ret
WinMainCRTStartup Endp


end
#include <\UASM64\include\resource.h>

#define    ICO_MAIN        1000
#define    IDC_CONFIG        1002

#define    IDC_EDT            3000
#define    IDC_OPENFILE    3001
#define    IDC_APPLYF        3002
#define    ID_VSPEED        3003
#define    ID_SLIDER        3004
#define    IDC_APPLYT        3005

ICO_MAIN    ICON        "Amain.ico"

IDC_CONFIG DIALOGEX 1,1,230,75
STYLE 0xD0C80000 | DS_CENTER | WS_MINIMIZEBOX | WS_CHILD | WS_VISIBLE | WS_SYSMENU
FONT 8,"Consolas"
CAPTION "Setup Gif Parameters"
BEGIN
    LTEXT "Gif File:",-1,2,8,50,14,ES_LEFT
    EDITTEXT IDC_EDT,40,6,172,14,ES_LEFT | ES_AUTOHSCROLL | WS_BORDER,WS_EX_CLIENTEDGE
    PUSHBUTTON "...",IDC_OPENFILE,213,6,15,12,0
    PUSHBUTTON "ApplyF",IDC_APPLYF,92,55,30,14,0

    LTEXT "Speed:", -1, 8, 32, 24, 14
    CONTROL "Slider",ID_SLIDER,"msctls_trackbar32",TBS_AUTOTICKS | 0x50000000,33,27,175,24
    EDITTEXT ID_VSPEED,210,32,18,12,ES_READONLY | ES_CENTER | ES_NUMBER | WS_BORDER,WS_EX_CLIENTEDGE
   
    PUSHBUTTON "ApplyT",IDC_APPLYT,127,55,30,14,0

END

if you can't immediately build exe and wanna to know "What is it? What does it do?". the post has bin attachment.
Say you, Say me, Say the codes together for ever.