|
|
/***************************************************************************
PROGRAM: mfdcod32
PURPOSE: view and decode Windows Metafiles and Enhanced Metafiles.
FUNCTIONS:
WinMain() - calls initialization function, processes message loop InitApplication() - initializes window data and registers window InitInstance() - saves instance handle and creates main window MainWndProc() - processes messages WaitCursor() - loads hourglass cursor/restores original cursor
HISTORY: 1/16/91 - wrote it - Dennis Crain 5/20/93 - ported to win32 (NT) - Dennis Crain 7/1/93 - added enhanced metafile functionality - denniscr
***************************************************************************/
#define MAIN
#include <windows.h>
#include <windowsx.h>
#include "mfdcod32.h"
int iDestDC;
/**********************************************************************
FUNCTION : WinMain
PARAMETERS : HANDLE HANDLE LPSTR int
PURPOSE : calls initialization function, processes message loop
CALLS : WINDOWS GetMessage TranslateMessage DispatchMessage
APP InitApplication
RETURNS : int
COMMENTS : Windows recognizes this function by name as the initial entry point for the program. This function calls the application initialization routine, if no other instance of the program is running, and always calls the instance initialization routine. It then executes a message retrieval and dispatch loop that is the top-level control structure for the remainder of execution. The loop is terminated when a WM_QUIT message is received, at which time this function exits the application instance by returning the value passed by PostQuitMessage().
If this function must abort before entering the message loop, it returns the conventional value NULL.
HISTORY : 1/16/91 - created - denniscr
***********************************************************************/
int APIENTRY WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow) { MSG msg;
if (!hPrevInstance) if (!InitApplication(hInstance)) return (FALSE); //
//Perform initializations that apply to a specific instance
//
if (!InitInstance(hInstance, nCmdShow)) return (FALSE); //
//Acquire and dispatch messages until a WM_QUIT message is received.
//
while (GetMessage(&msg, NULL, 0, 0)) { TranslateMessage(&msg); DispatchMessage(&msg); } return ((int) msg.wParam);
UNREFERENCED_PARAMETER( lpCmdLine ); }
/**********************************************************************
FUNCTION : InitApplication
PARAMETERS : HANDLE hInstance
PURPOSE : Initializes window data and registers window class
CALLS : WINDOWS RegisterClass
MESSAGES : none
RETURNS : BOOL
COMMENTS : This function is called at initialization time only if no other instances of the application are running. This function performs initialization tasks that can be done once for any number of running instances.
In this case, we initialize a window class by filling out a data structure of type WNDCLASS and calling the Windows RegisterClass() function. Since all instances of this application use the same window class, we only need to do this when the first instance is initialized.
HISTORY : 1/16/91 - created - modified from SDK sample app GENERIC
***********************************************************************/
BOOL InitApplication(hInstance) HINSTANCE hInstance; // current instance
{ WNDCLASS wc;
bInPaint = FALSE; //
//Fill in window class structure with parameters that describe the
//main window.
//
wc.style = 0; //Class style(s)
wc.lpfnWndProc = MainWndProc; //Function to retrieve messages for
//windows of this class
wc.cbClsExtra = 0; //No per-class extra data
wc.cbWndExtra = 0; //No per-window extra data
wc.hInstance = hInstance; //Application that owns the class
wc.hIcon = LoadIcon(hInstance, "WMFICON"); wc.hCursor = LoadCursor(NULL, IDC_ARROW); wc.hbrBackground = (HBRUSH) (COLOR_BTNSHADOW + 1); wc.lpszMenuName = "MetaMenu"; //Name of menu resource in .RC file
wc.lpszClassName = "MetaWndClass"; //Name used in call to CreateWindow
//
//Register the window class and return success/failure code
//
return (RegisterClass(&wc));
}
/**********************************************************************
FUNCTION : InitInstance
PARAMETERS : HANDLE hInstance - Current instance identifier int nCmdShow - Param for first ShowWindow() call
PURPOSE : Saves instance handle and creates main window
CALLS : WINDOWS CreateWindow ShowWindow UpdateWindow
MESSAGES : none
RETURNS : BOOL
COMMENTS : This function is called at initialization time for every instance of this application. This function performs initialization tasks that cannot be shared by multiple instances.
In this case, we save the instance handle in a static variable and create and display the main program window.
HISTORY :
***********************************************************************/
BOOL InitInstance(hInstance, nCmdShow) HINSTANCE hInstance; // Current instance identifier.
int nCmdShow; // Param for first ShowWindow() call.
{ HWND hWnd; // Main window handle.
HDC hDC ; // Main DC handle
// Save the instance handle in static variable, which will be used in
// many subsequence calls from this application to Windows.
hInst = hInstance;
// Create a main window for this application instance.
hWnd = CreateWindow( "MetaWndClass", // See RegisterClass() call.
APPNAME, // Text for window title bar.
WS_OVERLAPPEDWINDOW, // Window style.
CW_USEDEFAULT, // Default horizontal position.
CW_USEDEFAULT, // Default vertical position.
CW_USEDEFAULT, // Default width.
CW_USEDEFAULT, // Default height.
NULL, // Overlapped windows have no parent.
NULL, // Use the window class menu.
hInstance, // This instance owns this window.
NULL // Pointer not needed.
); //
// If window could not be created, return "failure"
//
if (!hWnd) return (FALSE);
hWndMain = hWnd;
//
// Make the window visible; update its client area; and return "success"
//
ShowWindow(hWnd, nCmdShow); // Show the window
UpdateWindow(hWnd); // Sends WM_PAINT message
return (TRUE); // Returns the value from PostQuitMessage
}
BOOL bConvertToGdiPlus = FALSE; BOOL bUseGdiPlusToPlay = FALSE;
/**********************************************************************
FUNCTION : MainWndProc
PARAMETERS : HWND hWnd - window handle unsigned message - type of message WORD wParam - additional information LONG lParam - additional information
PURPOSE : Processes messages
CALLS :
MESSAGES : WM_CREATE
WM_COMMAND
wParams - IDM_EXIT - IDM_ABOUT - IDM_OPEN - IDM_PRINT - IDM_PRINTDLG - IDM_LIST - IDM_CLEAR - IDM_ENUM - IDM_ENUMRANGE - IDM_ALLREC - IDM_DESTDISPLAY - IDM_DESTMETA - IDM_HEADER - IDM_CLIPHDR - IDM_PLACEABLEHDR
WM_DESTROY
RETURNS : long
COMMENTS :
HISTORY : 1/16/91 - created - drc
***********************************************************************/
LRESULT CALLBACK MainWndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam) { RECT rect; INT_PTR iFOpenRet; char TempOpenName[128]; INT_PTR iDlgRet; BOOL releaseDC = FALSE;
switch (message) { case WM_CREATE: //
// init the state of the menu items
//
CheckMenuItem(GetMenu(hWnd), IDM_DESTDISPLAY, MF_CHECKED); break;
case WM_COMMAND: //
// message: command from application menu
//
switch (LOWORD(wParam)) {
case IDM_EXIT: // file exit menu option
PostQuitMessage(0); break;
case IDM_ABOUT: // about box
DialogBox(hInst, // current instance
"AboutBox", // resource to use
hWnd, // parent handle
About); // About() instance address
break;
case IDM_OPEN: // select a metafile to open
// save the name of previously opened file
if (lstrlen((LPSTR)OpenName) != 0) lstrcpy((LPSTR)TempOpenName, (LPSTR)OpenName); //
// initialize file info flags
//
if (!bMetaFileOpen) { bBadFile = FALSE; bValidFile = FALSE; } //
// clear the client area
//
GetClientRect(hWnd, (LPRECT)&rect); InvalidateRect(hWnd, (LPRECT)&rect, TRUE); //
// call file open dlg
//
iFOpenRet = OpenFileDialog((LPSTR)OpenName); //
// if a file was selected
//
if (iFOpenRet) { //
// if file contains a valid metafile and it was rendered
//
if (!ProcessFile(hWnd, (LPSTR)OpenName)) lstrcpy((LPSTR)OpenName, (LPSTR)TempOpenName); } else lstrcpy((LPSTR)OpenName, (LPSTR)TempOpenName); break;
case IDM_SAVEAS: { int iSaveRet; LPSTR lpszFilter; //
//get a name of a file to copy the metafile to
//
lpszFilter = (bEnhMeta) ? gszSaveWMFFilter : gszSaveEMFFilter;
iSaveRet = SaveFileDialog((LPSTR)SaveName, lpszFilter); //
//if the file selected is this metafile then warn user
//
if (!lstrcmp((LPSTR)OpenName, (LPSTR)SaveName)) MessageBox(hWnd, (LPSTR)"Cannot overwrite the opened metafile!", (LPSTR)"Copy Metafile", MB_OK | MB_ICONEXCLAMATION);
else //
//the user didn't hit the cancel button
//
if (iSaveRet) { HDC hrefDC;
WaitCursor(TRUE); if (!bEnhMeta) ConvertWMFtoEMF(hMF, (LPSTR)SaveName); else { // Try to get a printer DC by default
//hrefDC = GetPrinterDC(FALSE);
hrefDC = NULL; if (hrefDC == NULL) { releaseDC = TRUE; hrefDC = GetDC(NULL); } ConvertEMFtoWMF(hrefDC, hemf, (LPSTR)SaveName); if (releaseDC) { ReleaseDC(hWnd, hrefDC); } else { DeleteDC(hrefDC); } } } } break;
case IDM_PRINT: // play the metafile to a printer DC
PrintWMF(FALSE); break; case IDM_PRINTDLG: PrintWMF(TRUE); break;
case IDM_LIST: // list box containing all records of metafile
WaitCursor(TRUE); DialogBox(hInst, // current instance
"LISTRECS", // resource to use
hWnd, // parent handle
ListDlgProc); // About() instance address
WaitCursor(FALSE); break;
case IDM_CLEAR: // clear the client area
GetClientRect(hWnd, (LPRECT)&rect); InvalidateRect(hWnd, (LPRECT)&rect, TRUE); break;
case IDM_ENUM: // play - step - all menu option
// set flags appropriately before playing to destination
bEnumRange = FALSE; bPlayItAll = FALSE; PlayMetaFileToDest(hWnd, iDestDC); break;
case IDM_ENUMRANGE: // play - step - range menu option
//
// odd logic here...this just forces evaluation of the
// enumeration range in MetaEnumProc. We are not "playing
// it all"
//
bPlayItAll = TRUE;
iDlgRet = DialogBox(hInst,"ENUMRANGE",hWnd,EnumRangeDlgProc); //
// if cancel button not pressed, play to destination
//
if (iDlgRet != IDCANCEL) PlayMetaFileToDest(hWnd, iDestDC); break;
case IDM_ALLREC: // play - all menu option
//
// set flag appropriately and play to destination
//
bEnumRange = FALSE; bPlayItAll = TRUE; bPlayRec = TRUE; PlayMetaFileToDest(hWnd, iDestDC); break;
case IDM_DESTDISPLAY: // play - destination - display menu option
CheckMenuItem(GetMenu(hWnd), IDM_DESTDISPLAY, MF_CHECKED); CheckMenuItem(GetMenu(hWnd), IDM_DESTMETA, MF_UNCHECKED); CheckMenuItem(GetMenu(hWnd), IDM_DESTDIB, MF_UNCHECKED); CheckMenuItem(GetMenu(hWnd), IDM_DESTPRN, MF_UNCHECKED);
//
// set destination flag to display
//
iDestDC = DESTDISPLAY; break;
case IDM_DESTMETA: // play - destination - metafile menu option
CheckMenuItem(GetMenu(hWnd), IDM_DESTDISPLAY, MF_UNCHECKED); CheckMenuItem(GetMenu(hWnd), IDM_DESTMETA, MF_CHECKED); CheckMenuItem(GetMenu(hWnd), IDM_DESTDIB, MF_UNCHECKED); CheckMenuItem(GetMenu(hWnd), IDM_DESTPRN, MF_UNCHECKED);
// set destination flag to metafile
iDestDC = DESTMETA; break;
case IDM_DESTDIB: CheckMenuItem(GetMenu(hWnd), IDM_DESTDISPLAY, MF_UNCHECKED); CheckMenuItem(GetMenu(hWnd), IDM_DESTMETA, MF_UNCHECKED); CheckMenuItem(GetMenu(hWnd), IDM_DESTDIB, MF_CHECKED); CheckMenuItem(GetMenu(hWnd), IDM_DESTPRN, MF_UNCHECKED);
iDestDC = DESTDIB; break;
case IDM_DESTPRN: CheckMenuItem(GetMenu(hWnd), IDM_DESTDISPLAY, MF_UNCHECKED); CheckMenuItem(GetMenu(hWnd), IDM_DESTMETA, MF_UNCHECKED); CheckMenuItem(GetMenu(hWnd), IDM_DESTDIB, MF_UNCHECKED); CheckMenuItem(GetMenu(hWnd), IDM_DESTPRN, MF_CHECKED);
iDestDC = DESTPRN; break;
case IDM_ENHHEADER: if (bValidFile) DialogBox(hInst,"ENHMETAHEADER",hWnd,EnhMetaHeaderDlgProc); break;
case IDM_HEADER: // display the common metafile header
if (bValidFile) DialogBox(hInst,"HEADER",hWnd,HeaderDlgProc); break;
case IDM_CLIPHDR: // display the metafilepict of a clipboard file
if (bValidFile) DialogBox(hInst, "CLIPHDR", hWnd, ClpHeaderDlgProc); break;
case IDM_PLACEABLEHDR: // display the placeable metafile header
if (bValidFile) DialogBox(hInst,"PLACEABLEHDR",hWnd, PlaceableHeaderDlgProc); break;
case IDM_GDIPLUS_CONVERT: //
// clear the client area
//
GetClientRect(hWnd, (LPRECT)&rect); InvalidateRect(hWnd, (LPRECT)&rect, TRUE);
if (!bConvertToGdiPlus) { bConvertToGdiPlus = TRUE; CheckMenuItem(GetMenu(hWnd), IDM_GDIPLUS_CONVERT, MF_CHECKED); goto NoGdipPlay; } else { NoGdipConvert: bConvertToGdiPlus = FALSE; CheckMenuItem(GetMenu(hWnd), IDM_GDIPLUS_CONVERT, MF_UNCHECKED); } break;
// use (or not) GDI+ to play the metafile
case IDM_GDIPLUS_PLAY: //
// clear the client area
//
GetClientRect(hWnd, (LPRECT)&rect); InvalidateRect(hWnd, (LPRECT)&rect, TRUE);
if (!bUseGdiPlusToPlay) { bUseGdiPlusToPlay = TRUE; CheckMenuItem(GetMenu(hWnd), IDM_GDIPLUS_PLAY, MF_CHECKED); goto NoGdipConvert; } else { NoGdipPlay: bUseGdiPlusToPlay = FALSE; CheckMenuItem(GetMenu(hWnd), IDM_GDIPLUS_PLAY, MF_UNCHECKED); } break;
default: // let Windows process it
return (DefWindowProc(hWnd, message, wParam, lParam)); } break;
case WM_DESTROY: // message: window being destroyed
//
//if memory for metafile pict is around nuke it
//
if (lpMFP != NULL || lpOldMFP != NULL) { GlobalUnlock(hMFP); GlobalFree(hMFP); } //
//if the memory for placeable and clipboard wmf bits is around
//free it
//
if (lpMFBits != NULL) GlobalFreePtr(lpMFBits); //
//if the memory for the emf header, desc string and palette
//is still around then nuke it
//
if (EmfPtr.lpEMFHdr) GlobalFreePtr(EmfPtr.lpEMFHdr); if (EmfPtr.lpDescStr) GlobalFreePtr(EmfPtr.lpDescStr); if (EmfPtr.lpPal) GlobalFreePtr(EmfPtr.lpPal);
PostQuitMessage(0); break;
default: // passes it on if unproccessed
return (DefWindowProc(hWnd, message, wParam, lParam)); } return ((LRESULT)0); }
/**********************************************************************
FUNCTION : WaitCursor
PARAMETERS : BOOL bWait - TRUE for the hour glass cursor FALSE to return to the previous cursor
PURPOSE : toggle the mouse cursor to the hourglass and back
CALLS : WINDOWS LoadCursor SetCursor
MESSAGES : none
RETURNS : void
COMMENTS :
HISTORY : 1/16/91 - created - drc
***********************************************************************/
void WaitCursor(bWait) BOOL bWait; { HCURSOR hCursor; static HCURSOR hOldCursor; //
// if hourglass cursor is to be used
//
if (bWait) { hCursor = LoadCursor(NULL, IDC_WAIT); hOldCursor = SetCursor(hCursor); } else SetCursor(hOldCursor);
}
|