Leaked source code of windows server 2003
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

640 lines
20 KiB

  1. /***************************************************************************
  2. PROGRAM: mfdcod32
  3. PURPOSE: view and decode Windows Metafiles and Enhanced Metafiles.
  4. FUNCTIONS:
  5. WinMain() - calls initialization function, processes message loop
  6. InitApplication() - initializes window data and registers window
  7. InitInstance() - saves instance handle and creates main window
  8. MainWndProc() - processes messages
  9. WaitCursor() - loads hourglass cursor/restores original cursor
  10. HISTORY: 1/16/91 - wrote it - Dennis Crain
  11. 5/20/93 - ported to win32 (NT) - Dennis Crain
  12. 7/1/93 - added enhanced metafile functionality - denniscr
  13. ***************************************************************************/
  14. #define MAIN
  15. #include <windows.h>
  16. #include <windowsx.h>
  17. #include "mfdcod32.h"
  18. int iDestDC;
  19. /**********************************************************************
  20. FUNCTION : WinMain
  21. PARAMETERS : HANDLE
  22. HANDLE
  23. LPSTR
  24. int
  25. PURPOSE : calls initialization function, processes message loop
  26. CALLS : WINDOWS
  27. GetMessage
  28. TranslateMessage
  29. DispatchMessage
  30. APP
  31. InitApplication
  32. RETURNS : int
  33. COMMENTS : Windows recognizes this function by name as the initial entry
  34. point for the program. This function calls the application
  35. initialization routine, if no other instance of the program is
  36. running, and always calls the instance initialization routine.
  37. It then executes a message retrieval and dispatch loop that is
  38. the top-level control structure for the remainder of execution.
  39. The loop is terminated when a WM_QUIT message is received, at
  40. which time this function exits the application instance by
  41. returning the value passed by PostQuitMessage().
  42. If this function must abort before entering the message loop,
  43. it returns the conventional value NULL.
  44. HISTORY : 1/16/91 - created - denniscr
  45. ***********************************************************************/
  46. int APIENTRY WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow)
  47. {
  48. MSG msg;
  49. if (!hPrevInstance)
  50. if (!InitApplication(hInstance))
  51. return (FALSE);
  52. //
  53. //Perform initializations that apply to a specific instance
  54. //
  55. if (!InitInstance(hInstance, nCmdShow))
  56. return (FALSE);
  57. //
  58. //Acquire and dispatch messages until a WM_QUIT message is received.
  59. //
  60. while (GetMessage(&msg, NULL, 0, 0))
  61. {
  62. TranslateMessage(&msg);
  63. DispatchMessage(&msg);
  64. }
  65. return ((int) msg.wParam);
  66. UNREFERENCED_PARAMETER( lpCmdLine );
  67. }
  68. /**********************************************************************
  69. FUNCTION : InitApplication
  70. PARAMETERS : HANDLE hInstance
  71. PURPOSE : Initializes window data and registers window class
  72. CALLS : WINDOWS
  73. RegisterClass
  74. MESSAGES : none
  75. RETURNS : BOOL
  76. COMMENTS : This function is called at initialization time only if no
  77. other instances of the application are running. This function
  78. performs initialization tasks that can be done once for any
  79. number of running instances.
  80. In this case, we initialize a window class by filling out a
  81. data structure of type WNDCLASS and calling the Windows
  82. RegisterClass() function. Since all instances of this
  83. application use the same window class, we only need to do this
  84. when the first instance is initialized.
  85. HISTORY : 1/16/91 - created - modified from SDK sample app GENERIC
  86. ***********************************************************************/
  87. BOOL InitApplication(hInstance)
  88. HINSTANCE hInstance; // current instance
  89. {
  90. WNDCLASS wc;
  91. bInPaint = FALSE;
  92. //
  93. //Fill in window class structure with parameters that describe the
  94. //main window.
  95. //
  96. wc.style = 0; //Class style(s)
  97. wc.lpfnWndProc = MainWndProc; //Function to retrieve messages for
  98. //windows of this class
  99. wc.cbClsExtra = 0; //No per-class extra data
  100. wc.cbWndExtra = 0; //No per-window extra data
  101. wc.hInstance = hInstance; //Application that owns the class
  102. wc.hIcon = LoadIcon(hInstance, "WMFICON");
  103. wc.hCursor = LoadCursor(NULL, IDC_ARROW);
  104. wc.hbrBackground = (HBRUSH) (COLOR_BTNSHADOW + 1);
  105. wc.lpszMenuName = "MetaMenu"; //Name of menu resource in .RC file
  106. wc.lpszClassName = "MetaWndClass"; //Name used in call to CreateWindow
  107. //
  108. //Register the window class and return success/failure code
  109. //
  110. return (RegisterClass(&wc));
  111. }
  112. /**********************************************************************
  113. FUNCTION : InitInstance
  114. PARAMETERS : HANDLE hInstance - Current instance identifier
  115. int nCmdShow - Param for first ShowWindow() call
  116. PURPOSE : Saves instance handle and creates main window
  117. CALLS : WINDOWS
  118. CreateWindow
  119. ShowWindow
  120. UpdateWindow
  121. MESSAGES : none
  122. RETURNS : BOOL
  123. COMMENTS : This function is called at initialization time for every
  124. instance of this application. This function performs
  125. initialization tasks that cannot be shared by multiple
  126. instances.
  127. In this case, we save the instance handle in a static variable
  128. and create and display the main program window.
  129. HISTORY :
  130. ***********************************************************************/
  131. BOOL InitInstance(hInstance, nCmdShow)
  132. HINSTANCE hInstance; // Current instance identifier.
  133. int nCmdShow; // Param for first ShowWindow() call.
  134. {
  135. HWND hWnd; // Main window handle.
  136. HDC hDC ; // Main DC handle
  137. // Save the instance handle in static variable, which will be used in
  138. // many subsequence calls from this application to Windows.
  139. hInst = hInstance;
  140. // Create a main window for this application instance.
  141. hWnd = CreateWindow(
  142. "MetaWndClass", // See RegisterClass() call.
  143. APPNAME, // Text for window title bar.
  144. WS_OVERLAPPEDWINDOW, // Window style.
  145. CW_USEDEFAULT, // Default horizontal position.
  146. CW_USEDEFAULT, // Default vertical position.
  147. CW_USEDEFAULT, // Default width.
  148. CW_USEDEFAULT, // Default height.
  149. NULL, // Overlapped windows have no parent.
  150. NULL, // Use the window class menu.
  151. hInstance, // This instance owns this window.
  152. NULL // Pointer not needed.
  153. );
  154. //
  155. // If window could not be created, return "failure"
  156. //
  157. if (!hWnd)
  158. return (FALSE);
  159. hWndMain = hWnd;
  160. //
  161. // Make the window visible; update its client area; and return "success"
  162. //
  163. ShowWindow(hWnd, nCmdShow); // Show the window
  164. UpdateWindow(hWnd); // Sends WM_PAINT message
  165. return (TRUE); // Returns the value from PostQuitMessage
  166. }
  167. BOOL bConvertToGdiPlus = FALSE;
  168. BOOL bUseGdiPlusToPlay = FALSE;
  169. /**********************************************************************
  170. FUNCTION : MainWndProc
  171. PARAMETERS : HWND hWnd - window handle
  172. unsigned message - type of message
  173. WORD wParam - additional information
  174. LONG lParam - additional information
  175. PURPOSE : Processes messages
  176. CALLS :
  177. MESSAGES : WM_CREATE
  178. WM_COMMAND
  179. wParams
  180. - IDM_EXIT
  181. - IDM_ABOUT
  182. - IDM_OPEN
  183. - IDM_PRINT
  184. - IDM_PRINTDLG
  185. - IDM_LIST
  186. - IDM_CLEAR
  187. - IDM_ENUM
  188. - IDM_ENUMRANGE
  189. - IDM_ALLREC
  190. - IDM_DESTDISPLAY
  191. - IDM_DESTMETA
  192. - IDM_HEADER
  193. - IDM_CLIPHDR
  194. - IDM_PLACEABLEHDR
  195. WM_DESTROY
  196. RETURNS : long
  197. COMMENTS :
  198. HISTORY : 1/16/91 - created - drc
  199. ***********************************************************************/
  200. LRESULT CALLBACK MainWndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
  201. {
  202. RECT rect;
  203. INT_PTR iFOpenRet;
  204. char TempOpenName[128];
  205. INT_PTR iDlgRet;
  206. BOOL releaseDC = FALSE;
  207. switch (message)
  208. {
  209. case WM_CREATE:
  210. //
  211. // init the state of the menu items
  212. //
  213. CheckMenuItem(GetMenu(hWnd), IDM_DESTDISPLAY, MF_CHECKED);
  214. break;
  215. case WM_COMMAND:
  216. //
  217. // message: command from application menu
  218. //
  219. switch (LOWORD(wParam))
  220. {
  221. case IDM_EXIT: // file exit menu option
  222. PostQuitMessage(0);
  223. break;
  224. case IDM_ABOUT: // about box
  225. DialogBox(hInst, // current instance
  226. "AboutBox", // resource to use
  227. hWnd, // parent handle
  228. About); // About() instance address
  229. break;
  230. case IDM_OPEN: // select a metafile to open
  231. // save the name of previously opened file
  232. if (lstrlen((LPSTR)OpenName) != 0)
  233. lstrcpy((LPSTR)TempOpenName, (LPSTR)OpenName);
  234. //
  235. // initialize file info flags
  236. //
  237. if (!bMetaFileOpen) {
  238. bBadFile = FALSE;
  239. bValidFile = FALSE;
  240. }
  241. //
  242. // clear the client area
  243. //
  244. GetClientRect(hWnd, (LPRECT)&rect);
  245. InvalidateRect(hWnd, (LPRECT)&rect, TRUE);
  246. //
  247. // call file open dlg
  248. //
  249. iFOpenRet = OpenFileDialog((LPSTR)OpenName);
  250. //
  251. // if a file was selected
  252. //
  253. if (iFOpenRet)
  254. {
  255. //
  256. // if file contains a valid metafile and it was rendered
  257. //
  258. if (!ProcessFile(hWnd, (LPSTR)OpenName))
  259. lstrcpy((LPSTR)OpenName, (LPSTR)TempOpenName);
  260. }
  261. else
  262. lstrcpy((LPSTR)OpenName, (LPSTR)TempOpenName);
  263. break;
  264. case IDM_SAVEAS:
  265. {
  266. int iSaveRet;
  267. LPSTR lpszFilter;
  268. //
  269. //get a name of a file to copy the metafile to
  270. //
  271. lpszFilter = (bEnhMeta) ? gszSaveWMFFilter : gszSaveEMFFilter;
  272. iSaveRet = SaveFileDialog((LPSTR)SaveName, lpszFilter);
  273. //
  274. //if the file selected is this metafile then warn user
  275. //
  276. if (!lstrcmp((LPSTR)OpenName, (LPSTR)SaveName))
  277. MessageBox(hWnd, (LPSTR)"Cannot overwrite the opened metafile!",
  278. (LPSTR)"Copy Metafile", MB_OK | MB_ICONEXCLAMATION);
  279. else
  280. //
  281. //the user didn't hit the cancel button
  282. //
  283. if (iSaveRet)
  284. {
  285. HDC hrefDC;
  286. WaitCursor(TRUE);
  287. if (!bEnhMeta)
  288. ConvertWMFtoEMF(hMF, (LPSTR)SaveName);
  289. else
  290. {
  291. // Try to get a printer DC by default
  292. //hrefDC = GetPrinterDC(FALSE);
  293. hrefDC = NULL;
  294. if (hrefDC == NULL)
  295. {
  296. releaseDC = TRUE;
  297. hrefDC = GetDC(NULL);
  298. }
  299. ConvertEMFtoWMF(hrefDC, hemf, (LPSTR)SaveName);
  300. if (releaseDC)
  301. {
  302. ReleaseDC(hWnd, hrefDC);
  303. }
  304. else
  305. {
  306. DeleteDC(hrefDC);
  307. }
  308. }
  309. }
  310. }
  311. break;
  312. case IDM_PRINT: // play the metafile to a printer DC
  313. PrintWMF(FALSE);
  314. break;
  315. case IDM_PRINTDLG:
  316. PrintWMF(TRUE);
  317. break;
  318. case IDM_LIST: // list box containing all records of metafile
  319. WaitCursor(TRUE);
  320. DialogBox(hInst, // current instance
  321. "LISTRECS", // resource to use
  322. hWnd, // parent handle
  323. ListDlgProc); // About() instance address
  324. WaitCursor(FALSE);
  325. break;
  326. case IDM_CLEAR: // clear the client area
  327. GetClientRect(hWnd, (LPRECT)&rect);
  328. InvalidateRect(hWnd, (LPRECT)&rect, TRUE);
  329. break;
  330. case IDM_ENUM: // play - step - all menu option
  331. // set flags appropriately before playing to destination
  332. bEnumRange = FALSE;
  333. bPlayItAll = FALSE;
  334. PlayMetaFileToDest(hWnd, iDestDC);
  335. break;
  336. case IDM_ENUMRANGE: // play - step - range menu option
  337. //
  338. // odd logic here...this just forces evaluation of the
  339. // enumeration range in MetaEnumProc. We are not "playing
  340. // it all"
  341. //
  342. bPlayItAll = TRUE;
  343. iDlgRet = DialogBox(hInst,"ENUMRANGE",hWnd,EnumRangeDlgProc);
  344. //
  345. // if cancel button not pressed, play to destination
  346. //
  347. if (iDlgRet != IDCANCEL)
  348. PlayMetaFileToDest(hWnd, iDestDC);
  349. break;
  350. case IDM_ALLREC: // play - all menu option
  351. //
  352. // set flag appropriately and play to destination
  353. //
  354. bEnumRange = FALSE;
  355. bPlayItAll = TRUE;
  356. bPlayRec = TRUE;
  357. PlayMetaFileToDest(hWnd, iDestDC);
  358. break;
  359. case IDM_DESTDISPLAY: // play - destination - display menu option
  360. CheckMenuItem(GetMenu(hWnd), IDM_DESTDISPLAY, MF_CHECKED);
  361. CheckMenuItem(GetMenu(hWnd), IDM_DESTMETA, MF_UNCHECKED);
  362. CheckMenuItem(GetMenu(hWnd), IDM_DESTDIB, MF_UNCHECKED);
  363. CheckMenuItem(GetMenu(hWnd), IDM_DESTPRN, MF_UNCHECKED);
  364. //
  365. // set destination flag to display
  366. //
  367. iDestDC = DESTDISPLAY;
  368. break;
  369. case IDM_DESTMETA: // play - destination - metafile menu option
  370. CheckMenuItem(GetMenu(hWnd), IDM_DESTDISPLAY, MF_UNCHECKED);
  371. CheckMenuItem(GetMenu(hWnd), IDM_DESTMETA, MF_CHECKED);
  372. CheckMenuItem(GetMenu(hWnd), IDM_DESTDIB, MF_UNCHECKED);
  373. CheckMenuItem(GetMenu(hWnd), IDM_DESTPRN, MF_UNCHECKED);
  374. // set destination flag to metafile
  375. iDestDC = DESTMETA;
  376. break;
  377. case IDM_DESTDIB:
  378. CheckMenuItem(GetMenu(hWnd), IDM_DESTDISPLAY, MF_UNCHECKED);
  379. CheckMenuItem(GetMenu(hWnd), IDM_DESTMETA, MF_UNCHECKED);
  380. CheckMenuItem(GetMenu(hWnd), IDM_DESTDIB, MF_CHECKED);
  381. CheckMenuItem(GetMenu(hWnd), IDM_DESTPRN, MF_UNCHECKED);
  382. iDestDC = DESTDIB;
  383. break;
  384. case IDM_DESTPRN:
  385. CheckMenuItem(GetMenu(hWnd), IDM_DESTDISPLAY, MF_UNCHECKED);
  386. CheckMenuItem(GetMenu(hWnd), IDM_DESTMETA, MF_UNCHECKED);
  387. CheckMenuItem(GetMenu(hWnd), IDM_DESTDIB, MF_UNCHECKED);
  388. CheckMenuItem(GetMenu(hWnd), IDM_DESTPRN, MF_CHECKED);
  389. iDestDC = DESTPRN;
  390. break;
  391. case IDM_ENHHEADER:
  392. if (bValidFile)
  393. DialogBox(hInst,"ENHMETAHEADER",hWnd,EnhMetaHeaderDlgProc);
  394. break;
  395. case IDM_HEADER: // display the common metafile header
  396. if (bValidFile)
  397. DialogBox(hInst,"HEADER",hWnd,HeaderDlgProc);
  398. break;
  399. case IDM_CLIPHDR: // display the metafilepict of a clipboard file
  400. if (bValidFile)
  401. DialogBox(hInst, "CLIPHDR", hWnd, ClpHeaderDlgProc);
  402. break;
  403. case IDM_PLACEABLEHDR: // display the placeable metafile header
  404. if (bValidFile)
  405. DialogBox(hInst,"PLACEABLEHDR",hWnd, PlaceableHeaderDlgProc);
  406. break;
  407. case IDM_GDIPLUS_CONVERT:
  408. //
  409. // clear the client area
  410. //
  411. GetClientRect(hWnd, (LPRECT)&rect);
  412. InvalidateRect(hWnd, (LPRECT)&rect, TRUE);
  413. if (!bConvertToGdiPlus)
  414. {
  415. bConvertToGdiPlus = TRUE;
  416. CheckMenuItem(GetMenu(hWnd), IDM_GDIPLUS_CONVERT, MF_CHECKED);
  417. goto NoGdipPlay;
  418. }
  419. else
  420. {
  421. NoGdipConvert:
  422. bConvertToGdiPlus = FALSE;
  423. CheckMenuItem(GetMenu(hWnd), IDM_GDIPLUS_CONVERT, MF_UNCHECKED);
  424. }
  425. break;
  426. // use (or not) GDI+ to play the metafile
  427. case IDM_GDIPLUS_PLAY:
  428. //
  429. // clear the client area
  430. //
  431. GetClientRect(hWnd, (LPRECT)&rect);
  432. InvalidateRect(hWnd, (LPRECT)&rect, TRUE);
  433. if (!bUseGdiPlusToPlay)
  434. {
  435. bUseGdiPlusToPlay = TRUE;
  436. CheckMenuItem(GetMenu(hWnd), IDM_GDIPLUS_PLAY, MF_CHECKED);
  437. goto NoGdipConvert;
  438. }
  439. else
  440. {
  441. NoGdipPlay:
  442. bUseGdiPlusToPlay = FALSE;
  443. CheckMenuItem(GetMenu(hWnd), IDM_GDIPLUS_PLAY, MF_UNCHECKED);
  444. }
  445. break;
  446. default: // let Windows process it
  447. return (DefWindowProc(hWnd, message, wParam, lParam));
  448. }
  449. break;
  450. case WM_DESTROY: // message: window being destroyed
  451. //
  452. //if memory for metafile pict is around nuke it
  453. //
  454. if (lpMFP != NULL || lpOldMFP != NULL)
  455. {
  456. GlobalUnlock(hMFP);
  457. GlobalFree(hMFP);
  458. }
  459. //
  460. //if the memory for placeable and clipboard wmf bits is around
  461. //free it
  462. //
  463. if (lpMFBits != NULL)
  464. GlobalFreePtr(lpMFBits);
  465. //
  466. //if the memory for the emf header, desc string and palette
  467. //is still around then nuke it
  468. //
  469. if (EmfPtr.lpEMFHdr)
  470. GlobalFreePtr(EmfPtr.lpEMFHdr);
  471. if (EmfPtr.lpDescStr)
  472. GlobalFreePtr(EmfPtr.lpDescStr);
  473. if (EmfPtr.lpPal)
  474. GlobalFreePtr(EmfPtr.lpPal);
  475. PostQuitMessage(0);
  476. break;
  477. default: // passes it on if unproccessed
  478. return (DefWindowProc(hWnd, message, wParam, lParam));
  479. }
  480. return ((LRESULT)0);
  481. }
  482. /**********************************************************************
  483. FUNCTION : WaitCursor
  484. PARAMETERS : BOOL bWait - TRUE for the hour glass cursor
  485. FALSE to return to the previous cursor
  486. PURPOSE : toggle the mouse cursor to the hourglass and back
  487. CALLS : WINDOWS
  488. LoadCursor
  489. SetCursor
  490. MESSAGES : none
  491. RETURNS : void
  492. COMMENTS :
  493. HISTORY : 1/16/91 - created - drc
  494. ***********************************************************************/
  495. void WaitCursor(bWait)
  496. BOOL bWait;
  497. {
  498. HCURSOR hCursor;
  499. static HCURSOR hOldCursor;
  500. //
  501. // if hourglass cursor is to be used
  502. //
  503. if (bWait)
  504. {
  505. hCursor = LoadCursor(NULL, IDC_WAIT);
  506. hOldCursor = SetCursor(hCursor);
  507. }
  508. else
  509. SetCursor(hOldCursor);
  510. }