|
|
1.1 ! root 1: ! 2: /******************************************************************************\ ! 3: * This is a part of the Microsoft Source Code Samples. ! 4: * Copyright (C) 1993 Microsoft Corporation. ! 5: * All rights reserved. ! 6: * This source code is only intended as a supplement to ! 7: * Microsoft Development Tools and/or WinHelp documentation. ! 8: * See these sources for detailed information regarding the ! 9: * Microsoft samples programs. ! 10: \******************************************************************************/ ! 11: ! 12: /********************************************************************\ ! 13: * world.c -- Sample program demonstrating scaling and translating * ! 14: * an image from a metafile with World Coordinate * ! 15: * Transforms. * ! 16: * * ! 17: * Comments: * ! 18: * * ! 19: * The application loads the specified metafile. The user can * ! 20: * scale the image through a menu option and translate it via * ! 21: * the scrollbars and arrow keys. * ! 22: * * ! 23: * Functions: * ! 24: * * ! 25: * WinMain() - Initializes Application * ! 26: * MainWndProc() - Processes Application Messages * ! 27: * ScaleDlgProc() - Processes "Scale Image" Dialog Box Messages * ! 28: * AboutDlgProc() - Processes "About" Dialog Box Messages * ! 29: * OpenMetaFile() - Gets Metafile name and opens the Metafile * ! 30: * SetUnityXform() - Helper routine which sets the unity transform * ! 31: * * ! 32: * * ! 33: \********************************************************************/ ! 34: ! 35: ! 36: /********************* Header Files *********************/ ! 37: ! 38: #include <windows.h> ! 39: #include <memory.h> ! 40: #include <stdlib.h> ! 41: #include "world.h" ! 42: ! 43: ! 44: /********************** Defines *************************/ ! 45: ! 46: #define VSCROLLMAX 50 ! 47: #define HSCROLLMAX 50 ! 48: #define VERTSCALE VSCROLLMAX/3 ! 49: #define HORZSCALE HSCROLLMAX/3 ! 50: ! 51: #define LINEINC 1 ! 52: #define PAGEINC 4 ! 53: ! 54: #define FIRSTSTRING 0 ! 55: #define LASTSTRING 10 ! 56: #define MAXINPUT 10 ! 57: ! 58: /********************* Prototypes ***********************/ ! 59: ! 60: LRESULT CALLBACK MainWndProc( HWND, UINT, WPARAM, LPARAM ); ! 61: LRESULT CALLBACK AboutDlgProc( HWND, UINT, WPARAM, LPARAM ); ! 62: LRESULT CALLBACK ScaleDlgProc( HWND, UINT, WPARAM, LPARAM ); ! 63: BOOL OpenMetafile( HWND ); ! 64: void SetUnityXform( VOID ); ! 65: ! 66: /******************* Global Variables ********************/ ! 67: ! 68: HANDLE ghInstance; ! 69: ! 70: HENHMETAFILE hEMF; /* Handle of metafile opened */ ! 71: XFORM xForm; /* Transform to apply in SetWorldTransform() */ ! 72: BOOL bFileOpen; /* Logs if a metafile has been opened or not */ ! 73: BOOL bFileJustOpen; /* Used to re-initialize "Scale Image" values */ ! 74: ! 75: /* Used for putting up File Open common dialog */ ! 76: ! 77: OPENFILENAME OpenFileName; ! 78: CHAR szFile[MAX_PATH]; ! 79: CHAR szFileTitle[MAX_PATH]; ! 80: CHAR szFilter[] = "Metafile (*.EMF)\0*.emf\0All Files (*.*)\0*.*\0"; ! 81: ! 82: ! 83: /********************************************************************\ ! 84: * Function: int APIENTRY WinMain(HINSTANCE, HINSTANCE, LPSTR, int) * ! 85: * * ! 86: * Purpose: Initializes Application * ! 87: * * ! 88: * Comments: Standard template * ! 89: * * ! 90: * * ! 91: \********************************************************************/ ! 92: ! 93: ! 94: int APIENTRY WinMain( HINSTANCE hInstance, ! 95: HINSTANCE hPrevInstance, ! 96: LPSTR lpszCmdLine, ! 97: int nCmdShow ) ! 98: { ! 99: WNDCLASS wc; ! 100: MSG msg; ! 101: HWND hWnd; ! 102: ! 103: if( !hPrevInstance ) { ! 104: wc.lpszClassName = "WorldClass"; ! 105: wc.lpfnWndProc = MainWndProc; ! 106: wc.style = CS_OWNDC | CS_VREDRAW | CS_HREDRAW; ! 107: wc.hInstance = hInstance; ! 108: wc.hIcon = LoadIcon( hInstance, "WorldIcon" ); ! 109: wc.hCursor = LoadCursor( NULL, IDC_ARROW ); ! 110: wc.hbrBackground = (HBRUSH)( COLOR_WINDOW+1 ); ! 111: wc.lpszMenuName = "WorldMenu"; ! 112: wc.cbClsExtra = 0; ! 113: wc.cbWndExtra = 0; ! 114: ! 115: RegisterClass( &wc ); ! 116: } ! 117: ! 118: ghInstance = hInstance; ! 119: ! 120: hWnd = CreateWindow( "WorldClass", ! 121: "World Coordinate Transforms", ! 122: WS_OVERLAPPEDWINDOW|WS_HSCROLL|WS_VSCROLL, ! 123: 0, ! 124: 0, ! 125: CW_USEDEFAULT, ! 126: CW_USEDEFAULT, ! 127: NULL, ! 128: NULL, ! 129: hInstance, ! 130: NULL ! 131: ); ! 132: ! 133: ShowWindow( hWnd, nCmdShow ); ! 134: ! 135: while( GetMessage( &msg, NULL, 0, 0 ) ) { ! 136: TranslateMessage( &msg ); ! 137: DispatchMessage( &msg ); ! 138: } ! 139: ! 140: return msg.wParam; ! 141: } ! 142: ! 143: ! 144: /********************************************************************\ ! 145: * Function: LRESULT CALLBACK MainWndProc(HWND, UINT, WPARAM, LPARAM) * ! 146: * * ! 147: * Purpose: Processes Application Messages * ! 148: * * ! 149: * Comments: The following messages are processed * ! 150: * * ! 151: * WM_CREATE * ! 152: * WM_HSCROLL * ! 153: * WM_VSCROLL * ! 154: * WM_KEYDOWN * ! 155: * WM_PAINT * ! 156: * WM_COMMAND * ! 157: * WM_DESTROY * ! 158: * * ! 159: * * ! 160: \********************************************************************/ ! 161: ! 162: ! 163: LRESULT CALLBACK MainWndProc( HWND hWnd, UINT msg, WPARAM wParam, ! 164: LPARAM lParam ) ! 165: { ! 166: static int nVscrollPos, nHscrollPos; ! 167: int nVscrollInc, nHscrollInc; ! 168: RECT rect; ! 169: PAINTSTRUCT ps; ! 170: HDC hDC; ! 171: ! 172: switch( msg ) { ! 173: ! 174: /**************************************************************\ ! 175: * WM_CREATE: The scrollbar range is set. Global variables * ! 176: * are initialized. The new API SetGraphicsMode() must * ! 177: * be called before SetWorldCoordinates() can be called * ! 178: * in the WM_PAINT case. * ! 179: \**************************************************************/ ! 180: ! 181: case WM_CREATE: ! 182: ! 183: SetScrollRange( hWnd, SB_HORZ, 0, HSCROLLMAX, FALSE ); ! 184: SetScrollRange( hWnd, SB_VERT, 0, VSCROLLMAX, FALSE ); ! 185: ! 186: bFileOpen = FALSE; ! 187: bFileJustOpen = FALSE; ! 188: ! 189: hDC = GetDC( hWnd ); ! 190: SetGraphicsMode( hDC, GM_ADVANCED ); ! 191: ReleaseDC( hWnd, hDC ); ! 192: ! 193: break; ! 194: ! 195: /**************************************************************\ ! 196: * WM_HSCROLL: Standard template, except that instead of * ! 197: * calling ScrollWindow(), the transform is updated. * ! 198: \**************************************************************/ ! 199: ! 200: case WM_HSCROLL: ! 201: switch( wParam ) { ! 202: case SB_LINEUP: ! 203: nHscrollInc = -LINEINC; ! 204: break; ! 205: case SB_LINEDOWN: ! 206: nHscrollInc = LINEINC; ! 207: break; ! 208: case SB_PAGEUP: ! 209: nHscrollInc = -PAGEINC; ! 210: break; ! 211: case SB_PAGEDOWN: ! 212: nHscrollInc = PAGEINC; ! 213: break; ! 214: case SB_THUMBPOSITION: ! 215: nHscrollInc = HIWORD(wParam) - nHscrollPos; ! 216: break; ! 217: default: ! 218: nHscrollInc = 0; ! 219: } ! 220: if(nHscrollInc=max(-nHscrollPos,min(nHscrollInc,HSCROLLMAX- ! 221: nHscrollPos))) { ! 222: nHscrollPos += nHscrollInc; ! 223: SetScrollPos( hWnd, SB_HORZ, nHscrollPos, TRUE ); ! 224: ! 225: xForm.eDx += (FLOAT) (nHscrollInc * HORZSCALE); ! 226: InvalidateRect( hWnd, NULL, TRUE ); ! 227: } ! 228: return 0; ! 229: ! 230: /**************************************************************\ ! 231: * WM_VSCROLL: Standard template, except that instead of * ! 232: * calling ScrollWindow(), the transform is updated.* * ! 233: \**************************************************************/ ! 234: ! 235: case WM_VSCROLL: ! 236: switch( wParam ) { ! 237: case SB_TOP: ! 238: nVscrollInc = -nVscrollPos; ! 239: break; ! 240: case SB_BOTTOM: ! 241: nVscrollInc = VSCROLLMAX - nVscrollPos; ! 242: break; ! 243: case SB_LINEUP: ! 244: nVscrollInc = -LINEINC; ! 245: break; ! 246: case SB_LINEDOWN: ! 247: nVscrollInc = LINEINC; ! 248: break; ! 249: case SB_PAGEUP: ! 250: nVscrollInc = -PAGEINC; ! 251: break; ! 252: case SB_PAGEDOWN: ! 253: nVscrollInc = PAGEINC; ! 254: break; ! 255: case SB_THUMBTRACK: ! 256: nVscrollInc = HIWORD(wParam) - nVscrollPos; ! 257: break; ! 258: default: ! 259: nVscrollInc = 0; ! 260: } ! 261: if(nVscrollInc=max(-nVscrollPos,min(nVscrollInc,VSCROLLMAX- ! 262: nVscrollPos))) { ! 263: nVscrollPos += nVscrollInc; ! 264: SetScrollPos( hWnd, SB_VERT, nVscrollPos, TRUE ); ! 265: ! 266: xForm.eDy += (FLOAT) (nVscrollInc * VERTSCALE); ! 267: InvalidateRect( hWnd, NULL, TRUE ); ! 268: } ! 269: return 0; ! 270: ! 271: /**************************************************************\ ! 272: * WM_KEYDOWN: Standard template * ! 273: \**************************************************************/ ! 274: ! 275: case WM_KEYDOWN: ! 276: switch( wParam ) { ! 277: case VK_UP: ! 278: SendMessage( hWnd, WM_VSCROLL, SB_LINEUP, 0L ); ! 279: break; ! 280: case VK_DOWN: ! 281: SendMessage( hWnd, WM_VSCROLL, SB_LINEDOWN, 0L ); ! 282: break; ! 283: case VK_LEFT: ! 284: SendMessage( hWnd, WM_HSCROLL, SB_LINEUP, 0L ); ! 285: break; ! 286: case VK_RIGHT: ! 287: SendMessage( hWnd, WM_HSCROLL, SB_LINEDOWN, 0L ); ! 288: break; ! 289: case VK_PRIOR: ! 290: SendMessage( hWnd, WM_VSCROLL, SB_PAGEUP, 0L ); ! 291: break; ! 292: case VK_NEXT: ! 293: SendMessage( hWnd, WM_VSCROLL, SB_PAGEDOWN, 0L ); ! 294: break; ! 295: } ! 296: return 0; ! 297: ! 298: /**************************************************************\ ! 299: * WM_PAINT: If a Metafile has been opened, the transform * ! 300: * is applied using SetWorldTransform() and the Metafile * ! 301: * is displayed using PlayEnhMetaFile(). * ! 302: \**************************************************************/ ! 303: ! 304: case WM_PAINT: ! 305: hDC = BeginPaint( hWnd, &ps ); ! 306: ! 307: if( bFileOpen ) { ! 308: GetClientRect( hWnd, &rect ); ! 309: SetWorldTransform( hDC, &xForm ); ! 310: PlayEnhMetaFile( hDC, hEMF, &rect ); ! 311: } ! 312: ! 313: EndPaint( hWnd, &ps ); ! 314: break; ! 315: ! 316: /**************************************************************\ ! 317: * WM_COMMAND: If Metafile.Open is selected, OpenMetafile * ! 318: * and InvalidateRect() are called and the thumb * ! 319: * position is centered. If Metafile.Exit is selected, * ! 320: * a WM_CLOSE message is sent. If Scale is chosen, then * ! 321: * the "Scale Image" dialog is displayed; if the user * ! 322: * choses OK, then InvalidateRect() is called. If * ! 323: * Help.About is chosen, then the "About" dialog box is * ! 324: * displayed. * ! 325: \**************************************************************/ ! 326: ! 327: case WM_COMMAND: ! 328: switch( wParam ) { ! 329: case IDM_OPEN: ! 330: if( OpenMetafile( hWnd ) ) { ! 331: SetWindowText( hWnd, OpenFileName.lpstrFile ); ! 332: SetUnityXform( ); ! 333: nHscrollPos = HSCROLLMAX/2; ! 334: nVscrollPos = VSCROLLMAX/2; ! 335: SetScrollPos( hWnd, SB_HORZ, nHscrollPos, TRUE ); ! 336: SetScrollPos( hWnd, SB_VERT, nVscrollPos, TRUE ); ! 337: ! 338: InvalidateRect( hWnd, NULL, TRUE ); ! 339: } ! 340: break; ! 341: case IDM_EXIT: ! 342: SendMessage( hWnd, WM_CLOSE, 0, 0 ); ! 343: break; ! 344: case IDM_SCALE: ! 345: if( DialogBox( ghInstance, "ScaleDlg", hWnd, ! 346: (DLGPROC) ScaleDlgProc ) ) ! 347: InvalidateRect( hWnd, NULL, TRUE ); ! 348: break; ! 349: case IDM_ABOUT: ! 350: DialogBox( ghInstance, "AboutDlg", hWnd, (DLGPROC) ! 351: AboutDlgProc ); ! 352: break; ! 353: } ! 354: break; ! 355: ! 356: /**************************************************************\ ! 357: * WM_DESTROY: PostQuitMessage() is called * ! 358: \**************************************************************/ ! 359: ! 360: case WM_DESTROY: ! 361: PostQuitMessage( 0 ); ! 362: break; ! 363: ! 364: /**************************************************************\ ! 365: * Let the default window proc handle all other messages * ! 366: \**************************************************************/ ! 367: ! 368: default: ! 369: return( DefWindowProc( hWnd, msg, wParam, lParam )); ! 370: } ! 371: ! 372: return 0; ! 373: } ! 374: ! 375: ! 376: /********************************************************************\ ! 377: * Function: LRESULT CALLBACK ScaleDlgProc(HWND, UINT, WPARAM, LPARAM)* ! 378: * * ! 379: * Purpose: Processes "Scale Image" Dialog Box Messages. * ! 380: * * ! 381: * Comments: The following messages are processed: * ! 382: * * ! 383: * WM_INITDIALOG * ! 384: * WM_COMMAND * ! 385: * * ! 386: \********************************************************************/ ! 387: ! 388: ! 389: LRESULT CALLBACK ScaleDlgProc( HWND hDlg, UINT uMsg, WPARAM wParam, LPARAM lParam ) ! 390: { ! 391: char buffer[MAXINPUT]; ! 392: static char HorzInputBuf[MAXINPUT]; ! 393: static char VertInputBuf[MAXINPUT]; ! 394: int index; ! 395: ! 396: switch( uMsg ) { ! 397: ! 398: /**************************************************************\ ! 399: * WM_INITDIALOG: Strings representing the possible scale * ! 400: * factors are loaded into the comboboxes. The current * ! 401: * selection is indicated. * ! 402: \**************************************************************/ ! 403: ! 404: case WM_INITDIALOG: ! 405: for( index=FIRSTSTRING; index <= LASTSTRING; index++ ) { ! 406: LoadString( GetModuleHandle(NULL), index, buffer, MAXINPUT); ! 407: SendDlgItemMessage( hDlg, IDC_HORZ, CB_ADDSTRING, 0, ! 408: (LPARAM)buffer ); ! 409: SendDlgItemMessage( hDlg, IDC_VERT, CB_ADDSTRING, 0, ! 410: (LPARAM)buffer ); ! 411: } ! 412: ! 413: if( bFileJustOpen || !bFileOpen ) { ! 414: lstrcpy( HorzInputBuf, " 1.0" ); ! 415: lstrcpy( VertInputBuf, " 1.0" ); ! 416: bFileJustOpen = FALSE; ! 417: } ! 418: ! 419: SendDlgItemMessage( hDlg, IDC_HORZ, CB_SELECTSTRING, 0, ! 420: (LPARAM)HorzInputBuf ); ! 421: SendDlgItemMessage( hDlg, IDC_VERT, CB_SELECTSTRING, 0, ! 422: (LPARAM)VertInputBuf ); ! 423: return TRUE; ! 424: ! 425: /**************************************************************\ ! 426: * WM_COMMAND: If the OK button is selected, the current * ! 427: * horizontal and vertical scaling factors are obtained * ! 428: * from the ComboBox and the transform is updated. If * ! 429: * the CANCEL button is selected, EndDialog() is called. * ! 430: \**************************************************************/ ! 431: ! 432: case WM_COMMAND: ! 433: switch( wParam ) { ! 434: case IDOK: ! 435: index = SendDlgItemMessage( hDlg, IDC_HORZ, CB_GETCURSEL, ! 436: 0, 0 ); ! 437: LoadString( GetModuleHandle(NULL), index, HorzInputBuf, ! 438: MAXINPUT ); ! 439: xForm.eM11 = (FLOAT) atof( HorzInputBuf ); ! 440: ! 441: index = SendDlgItemMessage( hDlg, IDC_VERT, CB_GETCURSEL, ! 442: 0, 0 ); ! 443: LoadString( GetModuleHandle(NULL), index, VertInputBuf, ! 444: MAXINPUT ); ! 445: xForm.eM22 = (FLOAT) atof( VertInputBuf ); ! 446: ! 447: EndDialog( hDlg, TRUE ); ! 448: return TRUE; ! 449: case IDCANCEL: ! 450: EndDialog( hDlg, FALSE ); ! 451: return TRUE; ! 452: } ! 453: break; ! 454: } ! 455: ! 456: return FALSE; ! 457: } ! 458: ! 459: ! 460: /********************************************************************\ ! 461: * Function: LRESULT CALLBACK AboutDlgProc(HWND, UINT, WPARAM, LPARAM)* ! 462: * * ! 463: * Purpose: Processes "About" Dialog Box Messages * ! 464: * * ! 465: * Comments: The Dialog Box is displayed when the user selects * ! 466: * Help.About. * ! 467: * * ! 468: \********************************************************************/ ! 469: ! 470: ! 471: LRESULT CALLBACK AboutDlgProc( HWND hDlg, UINT uMsg, WPARAM wParam, LPARAM lParam ) ! 472: { ! 473: switch( uMsg ) { ! 474: case WM_INITDIALOG: ! 475: return TRUE; ! 476: case WM_COMMAND: ! 477: switch( wParam ) { ! 478: case IDOK: ! 479: EndDialog( hDlg, TRUE ); ! 480: return TRUE; ! 481: } ! 482: break; ! 483: } ! 484: ! 485: return FALSE; ! 486: } ! 487: ! 488: ! 489: /********************************************************************\ ! 490: * Function: BOOL OpenMetafile( HWND ) * ! 491: * * ! 492: * Purpose: Gets Metafile name and opens the Metafile * ! 493: * * ! 494: * Comments: Uses the Common Dialog GetOpenFileName() to prompt user * ! 495: * for the name of the Metafile to be opened. If the name * ! 496: * is successfully retrieved, GetEnhMetaFile() is used to * ! 497: * open the Metafile. * ! 498: * * ! 499: \********************************************************************/ ! 500: ! 501: ! 502: BOOL OpenMetafile( HWND hWnd ) ! 503: { ! 504: szFile[0] = '\0'; ! 505: szFileTitle[0] = '\0'; ! 506: memset( (LPVOID) &OpenFileName, 0, sizeof( OPENFILENAME )); ! 507: ! 508: OpenFileName.lStructSize = sizeof( OPENFILENAME ); ! 509: OpenFileName.hwndOwner = hWnd; ! 510: OpenFileName.lpstrFilter = szFilter; ! 511: OpenFileName.lpstrCustomFilter = (LPSTR) NULL; ! 512: OpenFileName.nMaxCustFilter = 0L; ! 513: OpenFileName.nFilterIndex = 1L; ! 514: OpenFileName.lpstrFile = szFile; ! 515: OpenFileName.nMaxFile = sizeof( szFile ); ! 516: OpenFileName.lpstrFileTitle = szFileTitle; ! 517: OpenFileName.nMaxFileTitle = sizeof( szFileTitle ); ! 518: OpenFileName.lpstrInitialDir = NULL; ! 519: OpenFileName.lpstrTitle = "Open Metafile"; ! 520: OpenFileName.Flags = OFN_PATHMUSTEXIST | OFN_FILEMUSTEXIST; ! 521: OpenFileName.nFileOffset = 0; ! 522: OpenFileName.nFileExtension = 0; ! 523: OpenFileName.lpstrDefExt = "*.EMF"; ! 524: ! 525: if( !GetOpenFileName( &OpenFileName ) ) ! 526: return FALSE; ! 527: ! 528: hEMF = GetEnhMetaFile( OpenFileName.lpstrFile ); ! 529: bFileOpen = TRUE; ! 530: bFileJustOpen = TRUE; ! 531: ! 532: return TRUE; ! 533: } ! 534: ! 535: ! 536: /********************************************************************\ ! 537: * Function: void SetUnityXform( VOID ) * ! 538: * * ! 539: * Purpose: Helper routine which sets the unity transform * ! 540: * * ! 541: * Comments: These fields have the following use in this application: * ! 542: * * ! 543: * eM11: Horizontal Scaling Factor * ! 544: * eM12: Not Used * ! 545: * eM21: Not Used * ! 546: * eM22: Vertical Scaling Factor * ! 547: * eDx: Horizontal Translation * ! 548: * eDy: Vertical Translation * ! 549: * * ! 550: \********************************************************************/ ! 551: ! 552: ! 553: void SetUnityXform( ) ! 554: { ! 555: xForm.eM11 = (FLOAT) 1.0; ! 556: xForm.eM12 = (FLOAT) 0.0; ! 557: xForm.eM21 = (FLOAT) 0.0; ! 558: xForm.eM22 = (FLOAT) 1.0; ! 559: xForm.eDx = (FLOAT) 0.0; ! 560: xForm.eDy = (FLOAT) 0.0; ! 561: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.