В тексте заменить IDM_about на IDM_ABOUT (здесь почему-то делается автозамена)
Здесь используется кабинетная проекция и аффинные преобразования.

// cube.cpp : Defines the entry point for the application. // #include "stdafx.h" #include "cube.h" #include <cmath> #define MAX_LOADSTRING 100 // Global Variables: HINSTANCE hInst; // current instance TCHAR szTitle[MAX_LOADSTRING]; // The title bar text TCHAR szWindowClass[MAX_LOADSTRING]; // the main window class name // Forward declarations of functions included in this code module: ATOM MyRegisterClass(HINSTANCE hInstance); BOOL InitInstance(HINSTANCE, int); LRESULT CALLBACK WndProc(HWND, UINT, WPARAM, LPARAM); INT_PTR CALLBACK About(HWND, UINT, WPARAM, LPARAM); int APIENTRY _tWinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPTSTR lpCmdLine, int nCmdShow) { UNREFERENCED_PARAMETER(hPrevInstance); UNREFERENCED_PARAMETER(lpCmdLine); // TODO: Place code here. MSG msg; HACCEL hAccelTable; // Initialize global strings LoadString(hInstance, IDS_APP_TITLE, szTitle, MAX_LOADSTRING); LoadString(hInstance, IDC_CUBE, szWindowClass, MAX_LOADSTRING); MyRegisterClass(hInstance); // Perform application initialization: if (!InitInstance (hInstance, nCmdShow)) { return FALSE; } hAccelTable = LoadAccelerators(hInstance, MAKEINTRESOURCE(IDC_CUBE)); // Main message loop: while (GetMessage(&msg, NULL, 0, 0)) { if (!TranslateAccelerator(msg.hwnd, hAccelTable, &msg)) { TranslateMessage(&msg); DispatchMessage(&msg); } } return (int) msg.wParam; } ATOM MyRegisterClass(HINSTANCE hInstance) { WNDCLASSEX wcex; wcex.cbSize = sizeof(WNDCLASSEX); wcex.style = CS_HREDRAW | CS_VREDRAW; wcex.lpfnWndProc = WndProc; wcex.cbClsExtra = 0; wcex.cbWndExtra = 0; wcex.hInstance = hInstance; wcex.hIcon = LoadIcon(hInstance, MAKEINTRESOURCE(IDI_CUBE)); wcex.hCursor = LoadCursor(NULL, IDC_ARROW); wcex.hbrBackground = (HBRUSH)(COLOR_WINDOW+1); wcex.lpszMenuName = MAKEINTRESOURCE(IDC_CUBE); wcex.lpszClassName = szWindowClass; wcex.hIconSm = LoadIcon(wcex.hInstance, MAKEINTRESOURCE(IDI_SMALL)); return RegisterClassEx(&wcex); } BOOL InitInstance(HINSTANCE hInstance, int nCmdShow) { HWND hWnd; hInst = hInstance; // Store instance handle in our global variable hWnd = CreateWindow(szWindowClass, szTitle, WS_OVERLAPPEDWINDOW, CW_USEDEFAULT, 0, 320*2, 380*2, NULL, NULL, hInstance, NULL); if (!hWnd) { return FALSE; } ShowWindow(hWnd, nCmdShow); UpdateWindow(hWnd); SetTimer(hWnd,NULL,10,NULL); return TRUE; } double matrix[8][3] = { {-25,-25,-25},{25,-25,-25},{25,25,-25},{-25,25,-25}, {-25,-25, 25},{25,-25, 25},{25,25, 25},{-25,25, 25} }; POINT points[8]; POINT cube[6][4]; int a; int grani[6][4] = {{0,1,2,3},{4,5,6,7},{0,1,5,4},{3,2,6,7},{1,2,6,5},{0,3,7,4}}; void rotate_y(double alpha) { double x, alsin = sin(alpha), alcos = cos(alpha); for(int i=0;i<8;i++) { x = matrix[i][0]*alcos - matrix[i][2]*alsin; matrix[i][2] = matrix[i][0]*alsin + matrix[i][2]*alcos; matrix[i][0] = x; } } void rotate_x(double alpha) { double y, alsin = sin(alpha), alcos = cos(alpha); for(int i=0;i<8;i++) { y = matrix[i][1]*alcos - matrix[i][2]*alsin; matrix[i][2] = matrix[i][1]*alsin + matrix[i][2]*alcos; matrix[i][1] = y; } } RECT rect; double ctn = cos(atan(2.0))/2, stn = sin(atan(2.0))/2; void project() { for(int i=0;i<8;i++) { // x' = x + z*(1/2)*cos(atan(2)); // y' = y + z*(1/2)*sin(atan(2)); points[i].x = (long)floor(matrix[i][0] + matrix[i][2]*ctn)*6 + rect.right/2; points[i].y = (long)floor(matrix[i][1] + matrix[i][2]*stn)*6 + rect.bottom/2; } for(int i = 0; i < 6; i++) for(int j = 0; j < 4; j++) cube[i][j] = points[grani[i][j]]; } void show_cube(HDC hdc) { SelectObject(hdc, GetStockObject( NULL_BRUSH )); HPEN p = CreatePen(PS_DASH,2,RGB(0,150,200)); HPEN oldp = (HPEN) SelectObject(hdc,p); for(int i = 0; i < 6; i++) { Polygon(hdc,cube[i],4); } SelectObject(hdc,oldp); DeleteObject(p); DeleteObject(oldp); } void move_cube() { a++; double alpha = 0.03; if(a < 100) rotate_x(alpha); else if(a < 200) rotate_x(-alpha); else if(a < 300) rotate_y(alpha); else if(a < 400) { rotate_x(alpha); rotate_y(alpha); } else if(a < 500) { rotate_x(-alpha); rotate_y(-alpha); } else if(a < 600) { rotate_x(-alpha); rotate_y(alpha); } else if(a < 700) { rotate_x(alpha); rotate_y(-alpha); } else rotate_y(-alpha); if(a>800) a=0; } WPARAM key = 0; LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam) { int wmId, wmEvent; PAINTSTRUCT ps; HDC hdc; HDC hdcBuf; HBITMAP hbmBuf; HBITMAP hOldBmp; switch (message) { case WM_COMMAND: wmId = LOWORD(wParam); wmEvent = HIWORD(wParam); // Разобрать выбор в меню: switch (wmId) { case IDM_about: DialogBox(hInst, MAKEINTRESOURCE(IDD_ABOUTBOX), hWnd, About); break; case IDM_EXIT: DestroyWindow(hWnd); break; default: return DefWindowProc(hWnd, message, wParam, lParam); } break; case WM_PAINT: hdc = BeginPaint(hWnd, &ps); GetClientRect(hWnd, &rect); hdcBuf= CreateCompatibleDC(hdc); hbmBuf = CreateCompatibleBitmap(hdc, rect.right,rect.bottom); hOldBmp = (HBITMAP)SelectObject(hdcBuf, hbmBuf); project(); show_cube(hdcBuf); BitBlt(hdc, 0, 0, rect.right, rect.bottom, hdcBuf, 0, 0, SRCCOPY); SelectObject(hdcBuf, hOldBmp); DeleteDC(hdcBuf); DeleteObject(hbmBuf); key = 0; EndPaint(hWnd, &ps); break; case WM_TIMER: move_cube(); InvalidateRect(hWnd, NULL, FALSE); UpdateWindow(hWnd); break; case WM_ERASEBKGND: break; case WM_DESTROY: PostQuitMessage(0); break; default: return DefWindowProc(hWnd, message, wParam, lParam); } return 0; } // Message handler for about box. INT_PTR CALLBACK About(HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam) { UNREFERENCED_PARAMETER(lParam); switch (message) { case WM_INITDIALOG: return (INT_PTR)TRUE; case WM_COMMAND: if (LOWORD(wParam) == IDOK || LOWORD(wParam) == IDCANCEL) { EndDialog(hDlg, LOWORD(wParam)); return (INT_PTR)TRUE; } break; } return (INT_PTR)FALSE; }