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:
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