Silly example for PlgBlt()
#define WIN32_LEAN_AND_MEAN
#include <windows.h>
#define _USE_MATH_DEFINES
#include <math.h>
static LRESULT CALLBACK WndProc(HWND, UINT, WPARAM, LPARAM);
static void RotatePoints(POINT points[], int angle, int width, int height);
static char *g_szAppName = "WTestBM";
static char *g_szFrameClass = "cWTestBM";
static HWND g_hFrame;
static HANDLE g_hInst;
HDC hDC;
HBITMAP hBM;
BITMAP bm;
POINT pts[3];
int angle;
UINT_PTR nIdEvent;
int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance,
LPSTR lpCmdLine, int nCmdShow)
{
WNDCLASSEX wcx;
MSG msg;
wcx.cbSize = sizeof(WNDCLASSEX);
wcx.style = CS_HREDRAW | CS_VREDRAW | CS_OWNDC;
wcx.lpfnWndProc = (WNDPROC) WndProc;
wcx.cbClsExtra = 0;
wcx.cbWndExtra = 0;
wcx.hInstance = hInstance;
wcx.hIcon = LoadIcon(NULL, IDI_APPLICATION);
wcx.hCursor = LoadCursor(NULL, IDC_ARROW);
wcx.hbrBackground= (HBRUSH)COLOR_APPWORKSPACE+1;
wcx.lpszMenuName = NULL;
wcx.lpszClassName= g_szFrameClass;
wcx.hIconSm = 0;
if (!RegisterClassEx(&wcx))
return 0;
g_hInst = hInstance;
g_hFrame = CreateWindowEx(0, g_szFrameClass, g_szAppName,
WS_OVERLAPPEDWINDOW,
CW_USEDEFAULT, CW_USEDEFAULT,
300, 320,
NULL, NULL, g_hInst, NULL);
if(!g_hFrame) return 0;
ShowWindow(g_hFrame, nCmdShow);
UpdateWindow(g_hFrame);
while(GetMessage(&msg, NULL, 0, 0))
{
TranslateMessage(&msg);
DispatchMessage(&msg);
}
return (int) msg.wParam;
}
static LRESULT CALLBACK WndProc(HWND hWnd, UINT wMsg, WPARAM wParam, LPARAM lParam)
{
switch (wMsg)
{
case WM_TIMER:
{
HBITMAP hbmOld;
RotatePoints(pts, angle, bm.bmWidth, bm.bmHeight);
HDC hdcMem = CreateCompatibleDC(hDC);
hbmOld = SelectObject(hdcMem, hBM);
PlgBlt(hDC, pts, hdcMem, 0, 0, bm.bmWidth, bm.bmHeight, NULL, 0, 0);
DeleteDC(hdcMem);
angle += 6;
return 0;
}
case WM_CREATE:
{
hBM = (HBITMAP)LoadImage(GetModuleHandle(NULL), "WTestBM.bmp", IMAGE_BITMAP, 0, 0, LR_LOADFROMFILE);
GetObject(hBM, sizeof(bm), &bm);
nIdEvent = SetTimer(hWnd, 2, 100, NULL);
hDC = GetDC(hWnd);
return 0;
}
case WM_DESTROY:
KillTimer(hWnd, nIdEvent);
DeleteObject(hBM);
PostQuitMessage(0);
return (0);
}
return DefWindowProc(hWnd, wMsg, wParam, lParam);
}
static void RotatePoints(POINT points[], int angle, int width, int height)
{ // https://www.powerbasic.com/support/pbforums/showthread.php?t=46549
double dsin, dcos;
long cx, cy, ofs;
cx = width / 2;
cy = height / 2;
ofs = sqrt(width * width + height * height) / 2 - max(cx, cy);
dsin = sin(angle * M_PI/180); //sin(2 * M_PI * angle / 360);
dcos = cos(angle * M_PI/180); // cos(2 * M_PI * angle / 360);
// UL, UR, LL corners of source image
points[0].x = ofs + cx + (int)(-cx * dcos) - (-cy * dsin);
points[0].y = ofs + cy + (int)(-cx * dsin) + (-cy * dcos);
points[1].x = ofs + cx + (int)(cx * dcos) - (-cy * dsin);
points[1].y = ofs + cy + (int)(cx * dsin) + (-cy * dcos);
points[2].x = ofs + cx + (int)(-cx * dcos) - (cy * dsin);
points[2].y = ofs + cy + (int)(-cx * dsin) + (cy * dcos);
}