This is a pure SDK example (only 12 kb) to show you how to use the PlgBlt API to perform image rotation.

You can post your comments there

Source code:

Code:
'+--------------------------------------------------------------------------+
'|                                                                          |
'|                                PlgBlt                                    |
'|                                                                          |
'|             SDK example showing how to use the PlgBlt API                |
'|                       to perform image rotation.                         |
'|                                                                          |
'+--------------------------------------------------------------------------+
'|                                                                          |
'|                         Author Patrice TERRIER                           |
'|                            copyright(c) 2009                             |
'|                           www.zapsolution.com                            |
'|                        [email protected]                          |
'|                                                                          |
'+--------------------------------------------------------------------------+
'|                  Project started on : 05-28-2009 (MM-DD-YYYY)            |
'|                        Last revised : 05-08-2009 (MM-DD-YYYY)            |
'+--------------------------------------------------------------------------+

#COMPILE EXE "PlgBlt.exe"

'-----------------------------------------------------------------
' Equates:
'-----------------------------------------------------------------
%WINAPI                                         = 1
%TRUE                                           = 1
%FALSE                                          = 0
%NULL                                           = 0
%ANSI_VAR_FONT                                  = 12
%SW_RESTORE                                     = 9
%WM_CREATE                                      = &H1
%WM_DESTROY                                     = &H2
%WM_PAINT                                       = &HF
%WM_CLOSE                                       = &H10
%WM_COMMAND                                     = &H111
%WM_TIMER                                       = &H113
%WS_OVERLAPPED                                  = &H0
%WS_CHILD                                       = &H40000000
%WS_VISIBLE                                     = &H10000000
%WS_CLIPSIBLINGS                                = &H04000000
%WS_CLIPCHILDREN                                = &H02000000
%WS_CAPTION                                     = &H00C00000  ' WS_BORDER OR WS_DLGFRAME
%WS_SYSMENU                                     = &H00080000
%WS_THICKFRAME                                  = &H00040000
%WS_TABSTOP                                     = &H00010000
%WS_MINIMIZEBOX                                 = &H00020000
%WS_MAXIMIZEBOX                                 = &H00010000
%WS_OVERLAPPEDWINDOW                            = %WS_OVERLAPPED OR %WS_CAPTION OR %WS_SYSMENU OR %WS_THICKFRAME OR %WS_MINIMIZEBOX OR %WS_MAXIMIZEBOX
%WS_EX_WINDOWEDGE                               = &H00000100
%WS_EX_APPWINDOW                                = &H00040000
%CS_VREDRAW                                     = &H1
%CS_HREDRAW                                     = &H2
%PM_REMOVE                                      = &H0001
%SM_CXSCREEN                                    = 0
%SM_CYSCREEN                                    = 1
%IDC_ARROW                                      = 32512&
%LR_LOADFROMFILE                                = &H0010

%TIMER_DELAY = 0  '// Timer delay (animation speed)

'-----------------------------------------------------------------
' TYPE and UNION structures:
'-----------------------------------------------------------------
TYPE RECT
    nLeft AS LONG
    nTop AS LONG
    nRight AS LONG
    nBottom AS LONG
END TYPE

TYPE POINTAPI
    x AS LONG
    y AS LONG
END TYPE

TYPE tagMSG
    hwnd AS DWORD
    message AS DWORD
    wParam AS LONG
    lParam AS LONG
    time AS DWORD
    pt AS POINTAPI
END TYPE

TYPE WNDCLASSEX
    cbSize AS DWORD
    style AS DWORD
    lpfnWndProc AS LONG
    cbClsExtra AS LONG
    cbWndExtra AS LONG
    hInstance AS DWORD
    hIcon AS DWORD
    hCursor AS DWORD
    hbrBackground AS DWORD
    lpszMenuName AS ASCIIZ PTR
    lpszClassName AS ASCIIZ PTR
    hIconSm AS DWORD
END TYPE

TYPE PAINTSTRUCT
    hDC AS DWORD
    fErase AS LONG
    rcPaint AS RECT
    fRestore AS LONG
    fIncUpdate AS LONG
    rgbReserved(0 TO 31) AS BYTE
END TYPE

' Bitmap Header Definition
TYPE BITMAP
  bmType AS LONG
  bmWidth AS LONG
  bmHeight AS LONG
  bmWidthBytes AS LONG
  bmPlanes AS WORD
  bmBitsPixel AS WORD
  bmBits AS BYTE PTR
END TYPE

'-----------------------------------------------------------------
' Declared Functions:
'-----------------------------------------------------------------
DECLARE FUNCTION AdjustWindowRectEx LIB "USER32.DLL" ALIAS "AdjustWindowRectEx" (lpRect AS RECT, BYVAL dsStyle AS LONG, BYVAL bMenu AS LONG, BYVAL dwEsStyle AS DWORD) AS LONG
DECLARE FUNCTION CreateWindowEx LIB "USER32.DLL" ALIAS "CreateWindowExA" (BYVAL dwExStyle AS DWORD, lpClassName AS ASCIIZ, lpWindowName AS ASCIIZ, BYVAL dwStyle AS DWORD, BYVAL x AS LONG, BYVAL y AS LONG, _
    BYVAL nWidth AS LONG, BYVAL nHeight AS LONG, BYVAL hWndParent AS DWORD, BYVAL hMenu AS DWORD, BYVAL hInstance AS DWORD, lpParam AS ANY) AS DWORD
DECLARE FUNCTION DefWindowProc LIB "USER32.DLL" ALIAS "DefWindowProcA" (BYVAL hWnd AS DWORD, BYVAL uMsg AS DWORD, BYVAL wParam AS DWORD, BYVAL lParam AS LONG) AS LONG
DECLARE FUNCTION DispatchMessage LIB "USER32.DLL" ALIAS "DispatchMessageA" (lpMsg AS tagMSG) AS LONG
DECLARE FUNCTION GetClassInfoEx LIB "USER32.DLL" ALIAS "GetClassInfoExA" (BYVAL hInst AS DWORD, lpszClass AS ASCIIZ, lpWndClass AS WNDCLASSEX) AS LONG
DECLARE FUNCTION GetClientRect LIB "USER32.DLL" ALIAS "GetClientRect" (BYVAL hwnd AS DWORD, lpRect AS RECT) AS LONG
DECLARE FUNCTION GetMessage LIB "USER32.DLL" ALIAS "GetMessageA" (lpMsg AS tagMSG, BYVAL hWnd AS DWORD, BYVAL uMsgFilterMin AS DWORD, BYVAL uMsgFilterMax AS DWORD) AS LONG
DECLARE FUNCTION GetStockObject LIB "GDI32.DLL" ALIAS "GetStockObject" (BYVAL nIndex AS LONG) AS DWORD
DECLARE FUNCTION GetSystemMetrics LIB "USER32.DLL" ALIAS "GetSystemMetrics" (BYVAL nIndex AS LONG) AS LONG
DECLARE FUNCTION IsDialogMessage LIB "USER32.DLL" ALIAS "IsDialogMessageA" (BYVAL hDlg AS DWORD, lpMsg AS tagMSG) AS LONG
DECLARE FUNCTION LoadCursor LIB "USER32.DLL" ALIAS "LoadCursorA" (BYVAL hInstance AS DWORD, lpCursorName AS ASCIIZ) AS DWORD
DECLARE FUNCTION LoadIcon LIB "USER32.DLL" ALIAS "LoadIconA" (BYVAL hInstance AS DWORD, lpIconName AS ASCIIZ) AS DWORD
DECLARE FUNCTION PeekMessage LIB "USER32.DLL" ALIAS "PeekMessageA" (lpMsg AS tagMSG, BYVAL hWnd AS DWORD, BYVAL dwMsgFilterMin AS DWORD, BYVAL dwMsgFilterMax AS DWORD, BYVAL dwRemoveMsg AS DWORD) AS LONG
DECLARE FUNCTION RegisterClassEx LIB "USER32.DLL" ALIAS "RegisterClassExA" (pcWndClassEx AS WNDCLASSEX) AS WORD
DECLARE FUNCTION SetForegroundWindow LIB "USER32.DLL" ALIAS "SetForegroundWindow" (BYVAL hWnd AS DWORD) AS LONG
DECLARE FUNCTION SetRect LIB "USER32.DLL" ALIAS "SetRect" (lpRect AS RECT, BYVAL X1 AS LONG, BYVAL Y1 AS LONG, BYVAL X2 AS LONG, BYVAL Y2 AS LONG) AS LONG
DECLARE FUNCTION ShowWindow LIB "USER32.DLL" ALIAS "ShowWindow" (BYVAL hWnd AS DWORD, BYVAL nCmdShow AS LONG) AS LONG
DECLARE FUNCTION TranslateMessage LIB "USER32.DLL" ALIAS "TranslateMessage" (lpMsg AS tagMSG) AS LONG
DECLARE FUNCTION GetDC LIB "USER32.DLL" ALIAS "GetDC" (BYVAL hWnd AS DWORD) AS DWORD
DECLARE FUNCTION CreateCompatibleDC LIB "GDI32.DLL" ALIAS "CreateCompatibleDC" (BYVAL hdc AS DWORD) AS DWORD
DECLARE FUNCTION SelectObject LIB "GDI32.DLL" ALIAS "SelectObject" (BYVAL hdc AS DWORD, BYVAL hObject AS DWORD) AS DWORD
DECLARE FUNCTION DeleteDC LIB "GDI32.DLL" ALIAS "DeleteDC" (BYVAL hdc AS DWORD) AS LONG
DECLARE FUNCTION ReleaseDC LIB "USER32.DLL" ALIAS "ReleaseDC" (BYVAL hWnd AS DWORD, BYVAL hDC AS DWORD) AS LONG
DECLARE FUNCTION SetTimer LIB "USER32.DLL" ALIAS "SetTimer" (BYVAL hWnd AS DWORD, BYVAL nIDEvent AS LONG, BYVAL uElapse AS DWORD, BYVAL lpTimerFunc AS LONG) AS LONG
DECLARE FUNCTION KillTimer LIB "USER32.DLL" ALIAS "KillTimer" (BYVAL hWnd AS DWORD, BYVAL nIDEvent AS LONG) AS LONG
DECLARE FUNCTION DeleteObject LIB "GDI32.DLL" ALIAS "DeleteObject" (BYVAL hObject AS DWORD) AS LONG
DECLARE FUNCTION PlgBlt LIB "GDI32.DLL" ALIAS "PlgBlt" (BYVAL hdcDest AS DWORD, lpPoint AS POINTAPI, BYVAL hdcSrc AS DWORD, BYVAL nXSrc AS LONG, BYVAL nYSrc AS LONG, BYVAL nWidth AS LONG, BYVAL nHeight AS LONG, BYVAL hbmMask AS DWORD, _
                 BYVAL xMask AS LONG, BYVAL yMask AS LONG) AS LONG
DECLARE FUNCTION BeginPaint LIB "USER32.DLL" ALIAS "BeginPaint" (BYVAL hWnd AS DWORD, lpPaint AS PAINTSTRUCT) AS LONG
DECLARE FUNCTION EndPaint LIB "USER32.DLL" ALIAS "EndPaint" (BYVAL hWnd AS DWORD, lpPaint AS PAINTSTRUCT) AS LONG
DECLARE SUB InitCommonControls LIB "COMCTL32.DLL" ALIAS "InitCommonControls" ()
DECLARE SUB PostQuitMessage LIB "USER32.DLL" ALIAS "PostQuitMessage" (BYVAL nExitCode AS LONG)
DECLARE FUNCTION LoadImage LIB "USER32.DLL" ALIAS "LoadImageA" (BYVAL hInst AS DWORD, lpsz AS ASCIIZ, BYVAL uType AS DWORD, BYVAL cxDesired AS LONG, BYVAL cyDesired AS LONG, BYVAL fuLoad AS DWORD) AS DWORD
DECLARE FUNCTION GetObject LIB "GDI32.DLL" ALIAS "GetObjectA" (BYVAL hObject AS DWORD, BYVAL nCount AS LONG, lpObject AS ANY) AS LONG

DECLARE FUNCTION zTrace LIB "zTrace.DLL" ALIAS "zTrace" (zMessage AS ASCIIZ) AS LONG

MACRO Pi = 3.141592653589793##
MACRO HalfPI = 1.5707963267948965##
MACRO DegreesToRadians(Deg) = Deg * 0.0174532925199432957##

FUNCTION WinMain (BYVAL hInstance     AS LONG, _
                  BYVAL hPrevInstance AS LONG, _
                  BYVAL lpCmdLine     AS ASCIIZ PTR, _
                  BYVAL iCmdShow      AS LONG) AS LONG

    LOCAL rc          AS RECT
    LOCAL Msg         AS tagMsg
    LOCAL wc          AS WndClassEx
    LOCAL zClass      AS ASCIIZ * 80
    LOCAL IsInitialized, x, y AS LONG, dwExStyle, dwStyle, hMain  AS DWORD
'
    zClass = "ZPLGBLT"
'
    IsInitialized = GetClassInfoEx(hInstance, zClass, wc)
    IF IsInitialized&   = 0 THEN
       wc.cbSize        = SIZEOF(wc)
       wc.style         = %CS_HREDRAW OR %CS_VREDRAW
       wc.lpfnWndProc   = CODEPTR(WndProc)
       wc.cbClsExtra    = 0
       wc.cbWndExtra    = 0
       wc.hInstance     = hInstance
       wc.hIcon         = LoadIcon(wc.hInstance, "PROGRAM")
       wc.hCursor       = LoadCursor(%NULL, BYVAL %IDC_ARROW)
       wc.hbrBackground = %NULL ' GetStockObject(%BLACK_BRUSH)
       wc.lpszMenuName  = %NULL
       wc.lpszClassName = VARPTR(zClass)
       wc.hIconSm       = wc.hIcon
       IF RegisterClassEx(wc) THEN IsInitialized = %TRUE
    END IF
'
    IF IsInitialized THEN
'
      CALL InitCommonControls()
'
     ' Window Extended Style
       dwExStyle = %WS_EX_APPWINDOW OR %WS_EX_WINDOWEDGE
     ' Windows Style
       dwStyle = %WS_OVERLAPPEDWINDOW
'
       CALL SetRect(rc, 0, 0, 410, 400)
       CALL AdjustWindowRectEx(rc, dwStyle, %FALSE, dwExStyle)  ' Adjust Window To True Requested Size
'
       x = MAX&((GetSystemMetrics(%SM_CXSCREEN) - rc.nRight - rc.nLeft) \ 2, 0)
       y = MAX&((GetSystemMetrics(%SM_CYSCREEN) - rc.nBottom - rc.nTop) \ 2, 0)
'
     ' Create The Window
       MyTitle$ = "PlgBlt"
       hMain = CreateWindowEx(dwExStyle, _            ' Extended Style For The Window
                             zClass, _                ' Class Name
                             (MyTitle$), _            ' Window Title
                             dwStyle OR _             ' Defined Window Style
                             %WS_CLIPSIBLINGS OR _    ' Required Window Style
                             %WS_CLIPCHILDREN, _      ' Required Window Style
                             x, y, _                  ' Window Position
                             rc.nRight - rc.nLeft, _  ' Calculate Window Width
                             rc.nBottom - rc.nTop, _  ' Calculate Window Height
                             %NULL, _                 ' No Parent Window
                             %NULL, _                 ' No Menu
                             wc.hInstance, _          ' Instance
                             BYVAL %NULL)             ' Dont Pass Anything To WM_CREATE
'
       IF hMain THEN
'
        ' Show the main window
          CALL ShowWindow(hMain, iCmdShow)
          CALL SetForegroundWindow(hMain)                  ' Slightly Higher Priority

          CALL SetTimer(hMain, 1, %TIMER_DELAY, %NULL)

          WHILE GetMessage(Msg, %NULL, 0, 0)
              IF IsDialogMessage(hMain, Msg) = %FALSE THEN
                 CALL TranslateMessage(msg)                ' Translate The Message
                 CALL DispatchMessage(msg)                 ' Dispatch The Message
              END IF
          WEND

          CALL KillTimer(hMain, 1)

          FUNCTION = msg.wParam
       END IF

    END IF

END FUNCTION

FUNCTION RenderRotation(BYVAL hWnd AS LONG, BYVAL X AS LONG, BYVAL Y AS LONG, BYVAL hBitmap AS LONG, ByVal inAngle As LONG) As Long
    LOCAL K, SrceDC, DestDC AS Long
    DIM PlgPts(0 To 4) AS PointAPI

    STATIC HalfWidth, HalfHeight, PicWidth, PicHeight AS LONG
    DIM sCos1(360) AS STATIC SINGLE
    DIM sSin1(360) AS STATIC SINGLE
    DIM sCos2(360) AS STATIC SINGLE
    DIM sSin2(360) AS STATIC SINGLE

    IF HalfWidth = 0 THEN
       LOCAL AngleRad AS SINGLE
       LOCAL bm AS BITMAP
       CALL GetObject(hBitmap, SIZEOF(bm), bm)
       PicWidth = bm.bmWidth: PicHeight = bm.bmHeight

       ' Get half picture size and angle in radians
       HalfWidth = PicWidth \ 2:  HalfHeight = PicHeight \ 2
       FOR K = 0 TO 360
           AngleRad = DegreesToRadians(K)
           sCos1(K) = Cos(AngleRad) * HalfWidth
           sSin1(K) = Sin(AngleRad) * HalfWidth
           sCos2(K) = Cos(AngleRad + HalfPi) * HalfHeight
           sSin2(K) = Sin(AngleRad + HalfPi) * HalfHeight
       NEXT
    END IF

    ' Create temporary DC and select input picture into it
    DestDC = GetDC(hWnd) 
    SrceDC = CreateCompatibleDC(DestDC)
    CALL SelectObject(SrceDC, hBitmap)

    PlgPts(0).X = sCos1(inAngle)
    PlgPts(0).Y = sSin1(inAngle)
    PlgPts(1).X = sCos2(inAngle)
    PlgPts(1).Y = sSin2(inAngle)

    ' Project parallelogram points for rotated area
    PlgPts(2).X = HalfWidth  + X - PlgPts(0).X - PlgPts(1).X
    PlgPts(2).Y = HalfHeight + Y - PlgPts(0).Y - PlgPts(1).Y
    PlgPts(3).X = HalfWidth  + X - PlgPts(1).X + PlgPts(0).X
    PlgPts(3).Y = HalfHeight + Y - PlgPts(1).Y + PlgPts(0).Y
    PlgPts(4).X = HalfWidth  + X - PlgPts(0).X + PlgPts(1).X
    PlgPts(4).Y = HalfHeight + Y - PlgPts(0).Y + PlgPts(1).Y

    ' Draw rotated image
    FUNCTION = PlgBlt(DestDC, PlgPts(2), SrceDC, 0, 0, PicWidth, PicHeight, 0&, 0, 0)

    CALL DeleteDC(SrceDC)
    CALL ReleaseDC(hWnd, DestDC)

END FUNCTION

FUNCTION WndProc(BYVAL hWnd AS LONG, BYVAL Msg AS LONG, BYVAL wParam AS LONG, BYVAL lParam AS LONG) AS LONG
    LOCAL ps AS PAINTSTRUCT
    LOCAL rc AS RECT
    STATIC nAngle, hBitmap AS LONG

    SELECT CASE LONG Msg

    CASE %WM_CREATE
         hBitmap = LoadImage(0, (EXE.Path$ + "cube.bmp"), 0, 0, 0, %LR_LOADFROMFILE)

    CASE %WM_COMMAND
         SELECT CASE LONG LOWRD(wParam)

         END SELECT
    CASE %WM_TIMER
         nAngle = (nAngle + 4) MOD 360
         CALL RenderRotation(hWnd, 60, 100, hBitmap, nAngle)

    CASE %WM_PAINT
         BeginPaint(hWnd, ps)
         CALL EndPaint(hWnd, ps)
         FUNCTION = 0: EXIT FUNCTION
    CASE %WM_CLOSE

    CASE %WM_DESTROY
         CALL DeleteObject(hBitmap)
         CALL PostQuitMessage(0)
         FUNCTION = 0: EXIT FUNCTION
    END SELECT

    FUNCTION = DefWindowProc(hWnd, Msg, wParam, lParam)

END FUNCTION
Attached Files