#define _USE_MATH_DEFINES #include <math.h> #include <windows.h> #pragma comment(linker, "/subsystem:windows") double sin_deg(double deg) { return sin(deg*M_PI/180.0); } double cos_deg(double deg) { return cos(deg*M_PI/180.0); } void RotateAndDown(double deg, HWND hWnd) { XFORM xForm1={0}; XFORM xForm2={0}; XFORM xForm3={0}; HDC hDC = GetDC(hWnd); SetGraphicsMode(hDC, GM_ADVANCED); SetMapMode(hDC, MM_LOENGLISH); int deg_rot = (int)deg; //旋转矩阵 xForm1.eM11 = (FLOAT) cos_deg(deg_rot); xForm1.eM12 = (FLOAT) sin_deg(deg_rot); xForm1.eM21 = (FLOAT) (0-sin_deg(deg_rot)); xForm1.eM22 = (FLOAT) cos_deg(deg_rot); xForm1.eDx = (FLOAT) 0.0; xForm1.eDy = (FLOAT) 0.0; //平移矩阵 xForm2.eM11 = (FLOAT) 1; xForm2.eM12 = (FLOAT) 0; xForm2.eM21 = (FLOAT) 0; xForm2.eM22 = (FLOAT) 1; xForm2.eDx = (FLOAT) 0.0; xForm2.eDy = (FLOAT) (0-deg); //数学理论:矩阵的线性变换是支持乘法原理的。 //关键:将旋转矩阵与平移矩阵相乘,从而得到一个新的矩阵,它能同时执行旋转和平移变换。 CombineTransform(&xForm3, &xForm1, &xForm2); SetWorldTransform(hDC, &xForm3); RECT rect={0}; GetClientRect(hWnd, (LPRECT) &rect); DPtoLP(hDC, (LPPOINT) &rect, 2); SelectObject(hDC, CreatePen(PS_SOLID, 10, RGB(0,255,0))); Rectangle(hDC, rect.right/2-100, rect.bottom/2-100, rect.right/2+100, rect.bottom/2+100); SelectObject(hDC, CreatePen(PS_SOLID, 5, RGB(255,0,0))); Rectangle(hDC, rect.right/2-1, rect.bottom/2-1, rect.right/2, rect.bottom/2); ReleaseDC(hWnd, hDC); } DWORD WINAPI DrawThread(LPVOID lpParameter) { static int n=0; HWND hwnd = (HWND)lpParameter; InvalidateRect(hwnd, NULL, TRUE); for ( n=0; n<=360; n+=5 ) { if ( n != 360 ) InvalidateRect(hwnd, NULL, TRUE); Sleep(10); RotateAndDown(n, hwnd); Sleep(10); } return 0; } LRESULT CALLBACK WndProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam) { switch (message) { case WM_CREATE: CreateThread(NULL, 0, DrawThread, (LPVOID)hwnd, 0, NULL); break; case WM_LBUTTONUP: CreateThread(NULL, 0, DrawThread, (LPVOID)hwnd, 0, NULL); break; case WM_RBUTTONUP: InvalidateRect(hwnd, NULL, TRUE); break; case WM_CLOSE: break; case WM_DESTROY: PostQuitMessage(0); break; } return DefWindowProc(hwnd, message, wParam, lParam); } int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nShowCmd) { WNDCLASS wndclass={0}; wndclass.cbClsExtra = 0; wndclass.cbWndExtra = 0; wndclass.hbrBackground = (HBRUSH)GetStockObject(WHITE_BRUSH); wndclass.hCursor = LoadCursor(NULL,IDC_ARROW); wndclass.hIcon = LoadIcon(NULL,IDI_APPLICATION); wndclass.hInstance = hInstance; wndclass.lpfnWndProc = WndProc; wndclass.lpszClassName = "L"; wndclass.lpszMenuName = NULL; wndclass.style = CS_HREDRAW | CS_VREDRAW; if ( !RegisterClass(&wndclass) ) { MessageBox(NULL, "窗口注册失败!", "信息", 0); return 0; } HWND hwnd = CreateWindow( "L", "旋转下落", WS_OVERLAPPEDWINDOW, CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, NULL, NULL, hInstance, NULL); if ( hwnd == NULL ) { MessageBox(NULL, "窗口创建失败!", "信息", 0); return 0; } ShowWindow(hwnd, nShowCmd); UpdateWindow(hwnd); MSG msg={0}; while ( GetMessage(&msg, NULL, 0, 0) ) { TranslateMessage(&msg); DispatchMessage(&msg); } if ( !UnregisterClass(wndclass.lpszClassName, hInstance) ) { MessageBox(NULL,"窗口注销失败!","信息",0); } return msg.wParam; }