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 WCHAR szAppName
[5] = {'V','i','e','w',0};
28 static WCHAR szTitle
[MAX_PATH
];
29 static WCHAR szFileTitle
[MAX_PATH
];
32 static HENHMETAFILE enhmf
;
33 static int deltax
= 0, deltay
= 0;
34 static int width
= 0, height
= 0;
35 static BOOL isAldus
, isEnhanced
;
49 #define APMHEADER_KEY 0x9AC6CDD7l
52 static BOOL
FileOpen(HWND hWnd
, WCHAR
*fn
, int fnsz
)
54 WCHAR filter
[120], metafileFilter
[100];
55 static const WCHAR filterW
[] = {'%','s','%','c','*','.','w','m','f',';','*','.','e','m','f','%','c',0};
56 OPENFILENAMEW ofn
= { sizeof(OPENFILENAMEW
),
57 0, 0, NULL
, NULL
, 0, 0, NULL
,
58 fnsz
, NULL
, 0, NULL
, NULL
,
59 OFN_SHOWHELP
, 0, 0, NULL
, 0, NULL
};
61 LoadStringW( hInst
, IDS_OPEN_META_STRING
, metafileFilter
, ARRAY_SIZE(metafileFilter
) );
62 swprintf( filter
, ARRAY_SIZE(filter
), filterW
, metafileFilter
, 0, 0 );
64 ofn
.lpstrFilter
= filter
;
70 return GetOpenFileNameW(&ofn
);
73 static BOOL
FileIsEnhanced( LPCWSTR szFileName
)
79 handle
= CreateFileW( szFileName
, GENERIC_READ
, FILE_SHARE_READ
| FILE_SHARE_WRITE
,
80 NULL
, OPEN_EXISTING
, FILE_ATTRIBUTE_NORMAL
, 0 );
81 if (handle
== INVALID_HANDLE_VALUE
)
84 if (!ReadFile( handle
, &enh
, sizeof(ENHMETAHEADER
), &size
, NULL
) || size
!= sizeof(ENHMETAHEADER
) )
86 CloseHandle( handle
);
89 CloseHandle( handle
);
92 return (enh
.dSignature
== ENHMETA_SIGNATURE
);
95 static BOOL
FileIsPlaceable( LPCWSTR szFileName
)
101 handle
= CreateFileW( szFileName
, GENERIC_READ
, FILE_SHARE_READ
| FILE_SHARE_WRITE
,
102 NULL
, OPEN_EXISTING
, FILE_ATTRIBUTE_NORMAL
, 0 );
103 if (handle
== INVALID_HANDLE_VALUE
)
106 if (!ReadFile( handle
, &apmh
, sizeof(APMFILEHEADER
), &size
, NULL
) || size
!= sizeof(APMFILEHEADER
))
108 CloseHandle( handle
);
111 CloseHandle( handle
);
113 /* Is it placeable? */
114 return (apmh
.key
== APMHEADER_KEY
);
117 static HMETAFILE
GetPlaceableMetaFile( LPCWSTR szFileName
)
121 APMFILEHEADER APMHeader
;
129 handle
= CreateFileW( szFileName
, GENERIC_READ
, FILE_SHARE_READ
| FILE_SHARE_WRITE
,
130 NULL
, OPEN_EXISTING
, FILE_ATTRIBUTE_NORMAL
, 0 );
131 if (handle
== INVALID_HANDLE_VALUE
)
134 if (!ReadFile( handle
, &APMHeader
, sizeof(APMFILEHEADER
), &size
, NULL
) || size
!= sizeof(APMFILEHEADER
))
136 CloseHandle( handle
);
140 p
= (WORD
*) &APMHeader
;
144 if (checksum
!= APMHeader
.checksum
) {
146 sprintf(msg
, "Computed checksum %04x != stored checksum %04x\n",
147 checksum
, APMHeader
.checksum
);
148 MessageBoxA(hMainWnd
, msg
, "Checksum failed", MB_OK
);
149 CloseHandle( handle
);
153 if (!ReadFile( handle
, &mfHeader
, sizeof(METAHEADER
), &size
, NULL
) || size
!= sizeof(METAHEADER
))
155 CloseHandle( handle
);
159 if (!(lpData
= GlobalAlloc(GPTR
, (mfHeader
.mtSize
* 2L))))
161 CloseHandle( handle
);
165 SetFilePointer( handle
, sizeof(APMFILEHEADER
), NULL
, FILE_BEGIN
);
166 if (!ReadFile(handle
, lpData
, mfHeader
.mtSize
* 2, &size
, NULL
) || size
!= mfHeader
.mtSize
* 2)
169 CloseHandle( handle
);
172 CloseHandle( handle
);
174 if (!(hmf
= SetMetaFileBitsEx(mfHeader
.mtSize
*2, lpData
))) {
180 width
= APMHeader
.bbox
.Right
- APMHeader
.bbox
.Left
;
181 height
= APMHeader
.bbox
.Bottom
- APMHeader
.bbox
.Top
;
183 /* printf("Ok! width %d height %d inch %d\n", width, height, APMHeader.inch); */
184 hdc
= GetDC(hMainWnd
);
185 width
= width
* GetDeviceCaps(hdc
, LOGPIXELSX
)/APMHeader
.inch
;
186 height
= height
* GetDeviceCaps(hdc
,LOGPIXELSY
)/APMHeader
.inch
;
187 ReleaseDC(hMainWnd
, hdc
);
195 static void DoOpenFile(LPCWSTR filename
)
197 if (!filename
) return;
199 isAldus
= FileIsPlaceable(filename
);
201 hmf
= GetPlaceableMetaFile(filename
);
204 isEnhanced
= FileIsEnhanced(filename
);
206 enhmf
= GetEnhMetaFileW(filename
);
208 hmf
= GetMetaFileW(filename
);
209 GetClientRect(hMainWnd
, &r
);
210 width
= r
.right
- r
.left
;
211 height
= r
.bottom
- r
.top
;
213 InvalidateRect( hMainWnd
, NULL
, TRUE
);
216 static void UpdateWindowCaption(void)
218 WCHAR szCaption
[MAX_PATH
];
219 WCHAR szView
[MAX_PATH
];
220 static const WCHAR hyphenW
[] = { ' ','-',' ',0 };
222 LoadStringW(hInst
, IDS_DESCRIPTION
, szView
, ARRAY_SIZE(szView
));
224 if (szFileTitle
[0] != '\0')
226 lstrcpyW(szCaption
, szFileTitle
);
227 LoadStringW(hInst
, IDS_DESCRIPTION
, szView
, ARRAY_SIZE(szView
));
228 lstrcatW(szCaption
, hyphenW
);
229 lstrcatW(szCaption
, szView
);
232 lstrcpyW(szCaption
, szView
);
234 SetWindowTextW(hMainWnd
, szCaption
);
237 static LRESULT CALLBACK
WndProc(HWND hwnd
, UINT uMessage
, WPARAM wparam
, LPARAM lparam
)
244 BeginPaint(hwnd
, &ps
);
245 SetMapMode(ps
.hdc
, MM_ANISOTROPIC
);
246 /* Set the window extent to a sane value in case the metafile doesn't */
247 SetWindowExtEx(ps
.hdc
, width
, height
, NULL
);
248 SetViewportExtEx(ps
.hdc
, width
, height
, NULL
);
249 SetViewportOrgEx(ps
.hdc
, deltax
, deltay
, NULL
);
250 if (isEnhanced
&& enhmf
)
253 GetClientRect(hwnd
, &r
);
254 PlayEnhMetaFile(ps
.hdc
, enhmf
, &r
);
257 PlayMetaFile(ps
.hdc
, hmf
);
262 case WM_COMMAND
: /* message: command from application menu */
263 switch (LOWORD(wparam
))
267 WCHAR filename
[MAX_PATH
];
268 if (FileOpen(hwnd
, filename
, ARRAY_SIZE(filename
)))
271 GetFileTitleW(filename
, szFileTitle
, ARRAY_SIZE(szFileTitle
));
272 DoOpenFile(filename
);
273 UpdateWindowCaption();
278 case IDM_SET_EXT_TO_WIN
:
281 GetClientRect(hwnd
, &r
);
282 width
= r
.right
- r
.left
;
283 height
= r
.bottom
- r
.top
;
285 InvalidateRect( hwnd
, NULL
, TRUE
);
292 InvalidateRect( hwnd
, NULL
, TRUE
);
296 InvalidateRect( hwnd
, NULL
, TRUE
);
300 InvalidateRect( hwnd
, NULL
, TRUE
);
304 InvalidateRect( hwnd
, NULL
, TRUE
);
312 return DefWindowProcW(hwnd
, uMessage
, wparam
, lparam
);
316 case WM_DESTROY
: /* message: window being destroyed */
320 default: /* Passes it on if unprocessed */
321 return DefWindowProcW(hwnd
, uMessage
, wparam
, lparam
);
326 static BOOL
InitApplication(HINSTANCE hInstance
)
330 /* Load the application description strings */
331 LoadStringW(hInstance
, IDS_DESCRIPTION
, szTitle
, ARRAY_SIZE(szTitle
));
333 /* Fill in window class structure with parameters that describe the
336 wc
.cbSize
= sizeof(WNDCLASSEXW
);
337 wc
.style
= CS_HREDRAW
| CS_VREDRAW
; /* Class style(s) */
338 wc
.lpfnWndProc
= WndProc
; /* Window Procedure */
339 wc
.cbClsExtra
= 0; /* No per-class extra data */
340 wc
.cbWndExtra
= 0; /* No per-window extra data */
341 wc
.hInstance
= hInstance
; /* Owner of this class */
344 wc
.hCursor
= LoadCursorW(NULL
, (LPWSTR
)IDC_ARROW
);
345 wc
.hbrBackground
= (HBRUSH
)(COLOR_WINDOW
+ 1); /* Default color */
346 wc
.lpszMenuName
= szAppName
; /* Menu name from .rc */
347 wc
.lpszClassName
= szAppName
; /* Name to register as */
349 if (!RegisterClassExW(&wc
)) return FALSE
;
351 /* Call module specific initialization functions here */
356 static BOOL
InitInstance(HINSTANCE hInstance
, int nCmdShow
)
358 /* Save the instance handle in a global variable for later use */
361 /* Create main window */
362 hMainWnd
= CreateWindowW(szAppName
, /* See RegisterClass() call */
363 szTitle
, /* window title */
364 WS_OVERLAPPEDWINDOW
, /* Window style */
365 CW_USEDEFAULT
, 0, /* positioning */
366 CW_USEDEFAULT
, 0, /* size */
367 NULL
, /* Overlapped has no parent */
368 NULL
, /* Use the window class menu */
375 /* Call module specific instance initialization functions here */
377 /* show the window, and paint it for the first time */
378 ShowWindow(hMainWnd
, nCmdShow
);
379 UpdateWindow(hMainWnd
);
384 static void HandleCommandLine(LPWSTR cmdline
)
386 /* skip white space */
387 while (*cmdline
== ' ') cmdline
++;
391 /* file name is passed on the command line */
392 if (cmdline
[0] == '"')
395 cmdline
[lstrlenW(cmdline
) - 1] = 0;
398 GetFileTitleW(cmdline
, szFileTitle
, ARRAY_SIZE(szFileTitle
));
400 UpdateWindowCaption();
404 int APIENTRY
wWinMain(HINSTANCE hInstance
, HINSTANCE hPrevInstance
, LPWSTR lpCmdLine
, int nCmdShow
)
408 /* Other instances of app running? */
411 /* stuff to be done once */
412 if (!InitApplication(hInstance
))
414 return FALSE
; /* exit */
418 /* stuff to be done every time */
419 if (!InitInstance(hInstance
, nCmdShow
))
424 HandleCommandLine(lpCmdLine
);
427 /* Acquire and dispatch messages until a WM_QUIT message is received */
428 while (GetMessageW(&msg
, NULL
, 0, 0))
430 TranslateMessage(&msg
);
431 DispatchMessageW(&msg
);