/*------------------------------------------ NTXFORM.C -- Windows NT Matrix Tranforms (c) Charles Petzold, 1993 ------------------------------------------*/ #include #include #include #include "ntxform.h" #define TWO_PI (2 * 3.14159) long APIENTRY WndProc (HWND, UINT, WPARAM, LPARAM) ; BOOL APIENTRY MatrixBox (HWND, UINT, WPARAM, LPARAM) ; BOOL APIENTRY AngleBox (HWND, UINT, WPARAM, LPARAM) ; HANDLE hInst ; int PASCAL WinMain (HANDLE hInstance, HANDLE hPrevInstance, LPSTR lpszCmdLine, int nCmdShow) { static char szAppName[] = "NtXform" ; HWND hwnd ; MSG msg ; WNDCLASS wndclass ; hInst = hInstance ; wndclass.style = CS_HREDRAW | CS_VREDRAW ; wndclass.lpfnWndProc = WndProc ; wndclass.cbClsExtra = 0 ; wndclass.cbWndExtra = 0 ; wndclass.hInstance = hInstance ; wndclass.hIcon = LoadIcon (NULL, IDI_APPLICATION) ; wndclass.hCursor = LoadCursor (NULL, IDC_ARROW) ; wndclass.hbrBackground = GetStockObject (WHITE_BRUSH) ; wndclass.lpszMenuName = szAppName ; wndclass.lpszClassName = szAppName ; RegisterClass (&wndclass) ; hwnd = CreateWindow (szAppName, "Matrix Transforms", WS_OVERLAPPEDWINDOW, CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, NULL, NULL, hInstance, NULL) ; ShowWindow (hwnd, nCmdShow) ; UpdateWindow (hwnd) ; while (GetMessage (&msg, NULL, 0, 0)) { TranslateMessage (&msg) ; DispatchMessage (&msg) ; } return msg.wParam ; } long APIENTRY WndProc (HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam) { static int cxClient, cyClient ; static LOGFONT logfont ; static XFORM xform = { (FLOAT) 1.0, (FLOAT) 0.0, (FLOAT) 0.0, (FLOAT) 1.0, (FLOAT) 0.0, (FLOAT) 0.0 } ; HDC hdc ; PAINTSTRUCT ps ; switch (message) { case WM_CREATE: // initialize LOGFONT structure logfont.lfHeight = -1440 ; strcpy (logfont.lfFaceName, "Times New Roman") ; return 0 ; case WM_SIZE: cxClient = LOWORD (lParam) ; cyClient = HIWORD (lParam) ; return 0 ; case WM_COMMAND: switch (wParam) { case IDM_SELECT: if (DialogBoxParam (hInst, "MatrixBox", hwnd, MatrixBox, (LPARAM) &xform)) InvalidateRect (hwnd, NULL, TRUE) ; break ; } return 0 ; case WM_PAINT: hdc = BeginPaint (hwnd, &ps) ; // Draw horizontal and vertical lines MoveToEx (hdc, 0, cyClient / 2, NULL) ; LineTo (hdc, cxClient, cyClient / 2) ; MoveToEx (hdc, cxClient / 2, 0, NULL) ; LineTo (hdc, cxClient / 2, cyClient) ; // Set window/viewport transform SetMapMode (hdc, MM_TWIPS) ; SetViewportOrgEx (hdc, cxClient / 2, cyClient / 2, NULL) ; // Set font and alignment SelectObject (hdc, CreateFontIndirect (&logfont)) ; SetTextAlign (hdc, TA_BASELINE | TA_LEFT) ; SetBkMode (hdc, TRANSPARENT) ; // Set world transform SetGraphicsMode (hdc, GM_ADVANCED) ; SetWorldTransform (hdc, &xform) ; // Display text TextOut (hdc, 0, 0, "Hello!", 6) ; // Clean up DeleteObject (SelectObject (hdc, GetStockObject (SYSTEM_FONT))); EndPaint (hwnd, &ps) ; return 0 ; case WM_DESTROY: PostQuitMessage (0) ; return 0 ; } return DefWindowProc (hwnd, message, wParam, lParam) ; } BOOL SetDlgItemFloat (HWND hwnd, int idControl, FLOAT eValue) { char szBuffer [32] ; sprintf (szBuffer, "%f", eValue) ; return SetDlgItemText (hwnd, idControl, szBuffer) ; } FLOAT GetDlgItemFloat (HWND hwnd, int idControl) { char szBuffer [32] ; GetDlgItemText (hwnd, idControl, szBuffer, 32) ; return (FLOAT) atof (szBuffer) ; } BOOL APIENTRY MatrixBox (HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam) { static PXFORM pxform ; switch (message) { case WM_INITDIALOG: pxform = (PXFORM) lParam ; SetDlgItemFloat (hwnd, IDD_EM11, pxform->eM11) ; SetDlgItemFloat (hwnd, IDD_EM12, pxform->eM12) ; SetDlgItemFloat (hwnd, IDD_EM21, pxform->eM21) ; SetDlgItemFloat (hwnd, IDD_EM22, pxform->eM22) ; SetDlgItemFloat (hwnd, IDD_EDX , pxform->eDx ) ; SetDlgItemFloat (hwnd, IDD_EDY , pxform->eDy ) ; return TRUE ; case WM_COMMAND: switch (wParam) { case IDD_ANGLE: if (DialogBoxParam (hInst, "AngleBox", hwnd, AngleBox, (LPARAM) pxform)) { SetDlgItemFloat (hwnd, IDD_EM11, pxform->eM11) ; SetDlgItemFloat (hwnd, IDD_EM12, pxform->eM12) ; SetDlgItemFloat (hwnd, IDD_EM21, pxform->eM21) ; SetDlgItemFloat (hwnd, IDD_EM22, pxform->eM22) ; } return TRUE ; case IDOK: pxform->eM11 = GetDlgItemFloat (hwnd, IDD_EM11) ; pxform->eM12 = GetDlgItemFloat (hwnd, IDD_EM12) ; pxform->eM21 = GetDlgItemFloat (hwnd, IDD_EM21) ; pxform->eM22 = GetDlgItemFloat (hwnd, IDD_EM22) ; pxform->eDx = GetDlgItemFloat (hwnd, IDD_EDX ) ; pxform->eDy = GetDlgItemFloat (hwnd, IDD_EDY ) ; EndDialog (hwnd, TRUE) ; return TRUE ; case IDCANCEL: EndDialog (hwnd, FALSE) ; return TRUE ; } break ; } return FALSE ; } BOOL APIENTRY AngleBox (HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam) { static FLOAT eAngle = (FLOAT) 0.0, eScale = (FLOAT) 1.0 ; static PXFORM pxform ; switch (message) { case WM_INITDIALOG: pxform = (PXFORM) lParam ; SetDlgItemFloat (hwnd, IDD_ANGLE, eAngle) ; SetDlgItemFloat (hwnd, IDD_SCALE, eScale) ; return TRUE ; case WM_COMMAND: switch (wParam) { case IDOK: eAngle = GetDlgItemFloat (hwnd, IDD_ANGLE) ; eScale = GetDlgItemFloat (hwnd, IDD_SCALE) ; pxform->eM11 = (FLOAT) (eScale * cos (TWO_PI * eAngle / 360)) ; pxform->eM12 = (FLOAT) (eScale * sin (TWO_PI * eAngle / 360)) ; pxform->eM21 = -pxform->eM12 ; pxform->eM22 = pxform->eM11 ; EndDialog (hwnd, TRUE) ; return TRUE ; case IDCANCEL: EndDialog (hwnd, FALSE) ; return TRUE ; } break ; } return FALSE ; }