2 * Copyright 1998 Douglas Ridgway
4 * This library is free software; you can redistribute it and/or
5 * modify it under the terms of the GNU Lesser General Public
6 * License as published by the Free Software Foundation; either
7 * version 2.1 of the License, or (at your option) any later version.
9 * This library is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12 * Lesser General Public License for more details.
14 * You should have received a copy of the GNU Lesser General Public
15 * License along with this library; if not, write to the Free Software
16 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
25 static HINSTANCE hInst
;
27 static char szAppName
[5] = "View";
28 static char szTitle
[80];
31 static HENHMETAFILE enhmf
;
32 static int deltax
= 0, deltay
= 0;
33 static int width
= 0, height
= 0;
34 static BOOL isAldus
, isEnhanced
;
48 #define APMHEADER_KEY 0x9AC6CDD7l
51 static BOOL
FileOpen(HWND hWnd
, char *fn
, int fnsz
)
53 OPENFILENAME ofn
= { sizeof(OPENFILENAME
),
54 0, 0, NULL
, NULL
, 0, 0, NULL
,
55 fnsz
, NULL
, 0, NULL
, NULL
,
56 OFN_SHOWHELP
, 0, 0, NULL
, 0, NULL
};
57 ofn
.lpstrFilter
= "Metafiles\0*.wmf;*.emf\0";
63 return GetOpenFileName(&ofn
);
66 static BOOL
FileIsEnhanced( LPCSTR szFileName
)
71 if( (hInFile
= _lopen( szFileName
, OF_READ
) ) == HFILE_ERROR
)
74 if( _lread( hInFile
, &enh
, sizeof(ENHMETAHEADER
) ) != sizeof(ENHMETAHEADER
) )
82 return (enh
.dSignature
== ENHMETA_SIGNATURE
);
85 static BOOL
FileIsPlaceable( LPCSTR szFileName
)
90 if( (hInFile
= _lopen( szFileName
, OF_READ
) ) == HFILE_ERROR
)
93 if( _lread( hInFile
, &apmh
, sizeof(APMFILEHEADER
) )
94 != sizeof(APMFILEHEADER
) )
101 /* Is it placeable? */
102 return (apmh
.key
== APMHEADER_KEY
);
105 static HMETAFILE
GetPlaceableMetaFile( LPCSTR szFileName
)
109 APMFILEHEADER APMHeader
;
116 if( (fh
= _lopen( szFileName
, OF_READ
) ) == HFILE_ERROR
) return 0;
118 if (!_lread(fh
, &APMHeader
, sizeof(APMFILEHEADER
))) return 0;
119 _llseek(fh
, sizeof(APMFILEHEADER
), 0);
121 p
= (WORD
*) &APMHeader
;
125 if (checksum
!= APMHeader
.checksum
) {
127 sprintf(msg
, "Computed checksum %04x != stored checksum %04x\n",
128 checksum
, APMHeader
.checksum
);
129 MessageBox(hMainWnd
, msg
, "Checksum failed", MB_OK
);
133 if (!_lread(fh
, &mfHeader
, sizeof(METAHEADER
))) return 0;
135 if (!(lpData
= GlobalAlloc(GPTR
, (mfHeader
.mtSize
* 2L)))) return 0;
137 _llseek(fh
, sizeof(APMFILEHEADER
), 0);
138 if (!_lread(fh
, lpData
, (UINT
)(mfHeader
.mtSize
* 2L)))
146 if (!(hmf
= SetMetaFileBitsEx(mfHeader
.mtSize
*2, lpData
)))
150 width
= APMHeader
.bbox
.Right
- APMHeader
.bbox
.Left
;
151 height
= APMHeader
.bbox
.Bottom
- APMHeader
.bbox
.Top
;
153 /* printf("Ok! width %d height %d inch %d\n", width, height, APMHeader.inch); */
154 hdc
= GetDC(hMainWnd
);
155 width
= width
* GetDeviceCaps(hdc
, LOGPIXELSX
)/APMHeader
.inch
;
156 height
= height
* GetDeviceCaps(hdc
,LOGPIXELSY
)/APMHeader
.inch
;
157 ReleaseDC(hMainWnd
, hdc
);
164 static void DoOpenFile(LPCSTR filename
)
166 if (!filename
) return;
168 isAldus
= FileIsPlaceable(filename
);
170 hmf
= GetPlaceableMetaFile(filename
);
173 isEnhanced
= FileIsEnhanced(filename
);
175 enhmf
= GetEnhMetaFile(filename
);
177 hmf
= GetMetaFile(filename
);
178 GetClientRect(hMainWnd
, &r
);
179 width
= r
.right
- r
.left
;
180 height
= r
.bottom
- r
.top
;
182 InvalidateRect( hMainWnd
, NULL
, TRUE
);
185 static LRESULT CALLBACK
WndProc(HWND hwnd
, UINT uMessage
, WPARAM wparam
, LPARAM lparam
)
192 BeginPaint(hwnd
, &ps
);
193 SetMapMode(ps
.hdc
, MM_ANISOTROPIC
);
194 /* Set the window extent to a sane value in case the metafile doesn't */
195 SetWindowExtEx(ps
.hdc
, width
, height
, NULL
);
196 SetViewportExtEx(ps
.hdc
, width
, height
, NULL
);
197 SetViewportOrgEx(ps
.hdc
, deltax
, deltay
, NULL
);
198 if (isEnhanced
&& enhmf
)
201 GetClientRect(hwnd
, &r
);
202 PlayEnhMetaFile(ps
.hdc
, enhmf
, &r
);
205 PlayMetaFile(ps
.hdc
, hmf
);
210 case WM_COMMAND
: /* message: command from application menu */
211 switch (GET_WM_COMMAND_ID(wparam
,lparam
))
215 char filename
[MAX_PATH
];
216 if (FileOpen(hwnd
, filename
, sizeof(filename
)))
217 DoOpenFile(filename
);
221 case IDM_SET_EXT_TO_WIN
:
224 GetClientRect(hwnd
, &r
);
225 width
= r
.right
- r
.left
;
226 height
= r
.bottom
- r
.top
;
228 InvalidateRect( hwnd
, NULL
, TRUE
);
235 InvalidateRect( hwnd
, NULL
, TRUE
);
239 InvalidateRect( hwnd
, NULL
, TRUE
);
243 InvalidateRect( hwnd
, NULL
, TRUE
);
247 InvalidateRect( hwnd
, NULL
, TRUE
);
255 return DefWindowProc(hwnd
, uMessage
, wparam
, lparam
);
259 case WM_DESTROY
: /* message: window being destroyed */
263 default: /* Passes it on if unprocessed */
264 return DefWindowProc(hwnd
, uMessage
, wparam
, lparam
);
269 static BOOL
InitApplication(HINSTANCE hInstance
)
273 /* Load the application description strings */
274 LoadString(hInstance
, IDS_DESCRIPTION
, szTitle
, sizeof(szTitle
));
276 /* Fill in window class structure with parameters that describe the
279 wc
.cbSize
= sizeof(WNDCLASSEX
);
280 wc
.style
= CS_HREDRAW
| CS_VREDRAW
; /* Class style(s) */
281 wc
.lpfnWndProc
= WndProc
; /* Window Procedure */
282 wc
.cbClsExtra
= 0; /* No per-class extra data */
283 wc
.cbWndExtra
= 0; /* No per-window extra data */
284 wc
.hInstance
= hInstance
; /* Owner of this class */
287 wc
.hCursor
= LoadCursor(NULL
, IDC_ARROW
); /* Cursor */
288 wc
.hbrBackground
= (HBRUSH
)(COLOR_WINDOW
+ 1); /* Default color */
289 wc
.lpszMenuName
= szAppName
; /* Menu name from .rc */
290 wc
.lpszClassName
= szAppName
; /* Name to register as */
292 /* Register the window class and return FALSE if unsuccessful */
294 if (!RegisterClassEx(&wc
))
296 if (!RegisterClass((LPWNDCLASS
)&wc
.style
))
300 /* Call module specific initialization functions here */
305 static BOOL
InitInstance(HINSTANCE hInstance
, int nCmdShow
)
307 /* Save the instance handle in a global variable for later use */
310 /* Create main window */
311 hMainWnd
= CreateWindow(szAppName
, /* See RegisterClass() call */
312 szTitle
, /* window title */
313 WS_OVERLAPPEDWINDOW
, /* Window style */
314 CW_USEDEFAULT
, 0, /* positioning */
315 CW_USEDEFAULT
, 0, /* size */
316 NULL
, /* Overlapped has no parent */
317 NULL
, /* Use the window class menu */
324 /* Call module specific instance initialization functions here */
326 /* show the window, and paint it for the first time */
327 ShowWindow(hMainWnd
, nCmdShow
);
328 UpdateWindow(hMainWnd
);
333 static void HandleCommandLine(LPSTR cmdline
)
337 /* skip white space */
338 while (*cmdline
== ' ') cmdline
++;
340 /* skip executable name */
341 delimiter
= (*cmdline
== '"' ? '"' : ' ');
343 if (*cmdline
== delimiter
) cmdline
++;
344 while (*cmdline
&& *cmdline
!= delimiter
) cmdline
++;
345 if (*cmdline
== delimiter
) cmdline
++;
349 /* file name is passed on the command line */
350 if (cmdline
[0] == '"')
353 cmdline
[lstrlen(cmdline
) - 1] = 0;
359 int APIENTRY
WinMain(HINSTANCE hInstance
,
360 HINSTANCE hPrevInstance
,
367 /* Other instances of app running? */
370 /* stuff to be done once */
371 if (!InitApplication(hInstance
))
373 return FALSE
; /* exit */
377 /* stuff to be done every time */
378 if (!InitInstance(hInstance
, nCmdShow
))
383 HandleCommandLine(GetCommandLine());
385 hAccelTable
= LoadAccelerators(hInstance
, szAppName
);
388 /* Acquire and dispatch messages until a WM_QUIT message is received */
389 while (GetMessage(&msg
, NULL
, 0, 0))
391 /* Add other Translation functions (for modeless dialogs
392 and/or MDI windows) here. */
394 if (!TranslateAccelerator(msg
.hwnd
, hAccelTable
, &msg
))
396 TranslateMessage(&msg
);
397 DispatchMessage(&msg
);
401 /* Add module specific instance free/delete functions here */
403 /* Returns the value from PostQuitMessage */