Bug 2988: slovak translation for downloader by kario@szm.sk
[reactos.git] / reactos / base / applications / wordpad / print.c
1 /*
2 * Wordpad implementation - Printing and print preview functions
3 *
4 * Copyright 2007 by Alexander N. Sørnes <alex@thehandofagony.com>
5 *
6 * This library is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU Lesser General Public
8 * License as published by the Free Software Foundation; either
9 * version 2.1 of the License, or (at your option) any later version.
10 *
11 * This library is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 * Lesser General Public License for more details.
15 *
16 * You should have received a copy of the GNU Lesser General Public
17 * License along with this library; if not, write to the Free Software
18 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
19 */
20
21 #include <windows.h>
22 #include <richedit.h>
23 #include <commctrl.h>
24
25 #include "wordpad.h"
26
27 typedef struct _previewinfo
28 {
29 int page;
30 int pages;
31 HDC hdc;
32 HDC hdcSized;
33 RECT window;
34 LPWSTR wszFileName;
35 } previewinfo, *ppreviewinfo;
36
37 static HGLOBAL devMode;
38 static HGLOBAL devNames;
39
40 static RECT margins;
41 static previewinfo preview;
42
43 static const WCHAR var_pagemargin[] = {'P','a','g','e','M','a','r','g','i','n',0};
44
45 static LPWSTR get_print_file_filter(HWND hMainWnd)
46 {
47 static WCHAR wszPrintFilter[MAX_STRING_LEN*2+6+4+1];
48 const WCHAR files_prn[] = {'*','.','P','R','N',0};
49 const WCHAR files_all[] = {'*','.','*','\0'};
50 LPWSTR p;
51 HINSTANCE hInstance = (HINSTANCE)GetWindowLongPtr(hMainWnd, GWLP_HINSTANCE);
52
53 p = wszPrintFilter;
54 LoadStringW(hInstance, STRING_PRINTER_FILES_PRN, p, MAX_STRING_LEN);
55 p += lstrlenW(p) + 1;
56 lstrcpyW(p, files_prn);
57 p += lstrlenW(p) + 1;
58 LoadStringW(hInstance, STRING_ALL_FILES, p, MAX_STRING_LEN);
59 p += lstrlenW(p) + 1;
60 lstrcpyW(p, files_all);
61 p += lstrlenW(p) + 1;
62 *p = 0;
63
64 return wszPrintFilter;
65 }
66
67 void registry_set_pagemargins(HKEY hKey)
68 {
69 RegSetValueExW(hKey, var_pagemargin, 0, REG_BINARY, (LPBYTE)&margins, sizeof(RECT));
70 }
71
72 void registry_read_pagemargins(HKEY hKey)
73 {
74 DWORD size = sizeof(RECT);
75
76 if(!hKey || RegQueryValueExW(hKey, var_pagemargin, 0, NULL, (LPBYTE)&margins,
77 &size) != ERROR_SUCCESS || size != sizeof(RECT))
78 {
79 margins.top = 1417;
80 margins.bottom = 1417;
81 margins.left = 1757;
82 margins.right = 1757;
83 }
84 }
85
86 static void AddTextButton(HWND hRebarWnd, int string, int command, int id)
87 {
88 REBARBANDINFOW rb;
89 HINSTANCE hInstance = (HINSTANCE)GetWindowLongPtr(hRebarWnd, GWLP_HINSTANCE);
90 WCHAR text[MAX_STRING_LEN];
91 HWND hButton;
92
93 LoadStringW(hInstance, string, text, MAX_STRING_LEN);
94 hButton = CreateWindowW(WC_BUTTONW, text,
95 WS_VISIBLE | WS_CHILD, 5, 5, 100, 15,
96 hRebarWnd, (HMENU)command, hInstance, NULL);
97
98 rb.cbSize = sizeof(rb);
99 rb.fMask = RBBIM_SIZE | RBBIM_CHILDSIZE | RBBIM_STYLE | RBBIM_CHILD | RBBIM_IDEALSIZE | RBBIM_ID;
100 rb.fStyle = RBBS_NOGRIPPER | RBBS_VARIABLEHEIGHT;
101 rb.hwndChild = hButton;
102 rb.cyChild = rb.cyMinChild = 22;
103 rb.cx = rb.cxMinChild = 90;
104 rb.cxIdeal = 100;
105 rb.wID = id;
106
107 SendMessageW(hRebarWnd, RB_INSERTBAND, -1, (LPARAM)&rb);
108 }
109
110 static HDC make_dc(void)
111 {
112 if(devNames && devMode)
113 {
114 LPDEVNAMES dn = GlobalLock(devNames);
115 LPDEVMODEW dm = GlobalLock(devMode);
116 HDC ret;
117
118 ret = CreateDCW((LPWSTR)dn + dn->wDriverOffset,
119 (LPWSTR)dn + dn->wDeviceOffset, 0, dm);
120
121 GlobalUnlock(dn);
122 GlobalUnlock(dm);
123
124 return ret;
125 } else
126 {
127 return 0;
128 }
129 }
130
131 static LONG twips_to_centmm(int twips)
132 {
133 return MulDiv(twips, 1000, 567);
134 }
135
136 LONG centmm_to_twips(int mm)
137 {
138 return MulDiv(mm, 567, 1000);
139 }
140
141 static LONG twips_to_pixels(int twips, int dpi)
142 {
143 float ret = ((float)twips / ((float)567 * 2.54)) * (float)dpi;
144 return (LONG)ret;
145 }
146
147 static LONG devunits_to_twips(int units, int dpi)
148 {
149 float ret = ((float)units / (float)dpi) * (float)567 * 2.54;
150 return (LONG)ret;
151 }
152
153
154 static RECT get_print_rect(HDC hdc)
155 {
156 RECT rc;
157 int width, height;
158
159 if(hdc)
160 {
161 int dpiY = GetDeviceCaps(hdc, LOGPIXELSY);
162 int dpiX = GetDeviceCaps(hdc, LOGPIXELSX);
163 width = devunits_to_twips(GetDeviceCaps(hdc, PHYSICALWIDTH), dpiX);
164 height = devunits_to_twips(GetDeviceCaps(hdc, PHYSICALHEIGHT), dpiY);
165 } else
166 {
167 width = centmm_to_twips(18500);
168 height = centmm_to_twips(27000);
169 }
170
171 rc.left = margins.left;
172 rc.right = width - margins.right;
173 rc.top = margins.top;
174 rc.bottom = height - margins.bottom;
175
176 return rc;
177 }
178
179 void target_device(HWND hMainWnd, DWORD wordWrap)
180 {
181 HWND hEditorWnd = GetDlgItem(hMainWnd, IDC_EDITOR);
182 HDC hdc = make_dc();
183 int width = 0;
184
185 if(wordWrap == ID_WORDWRAP_MARGIN)
186 {
187 RECT rc = get_print_rect(hdc);
188 width = rc.right;
189 }
190
191 if(!hdc)
192 {
193 HDC hMaindc = GetDC(hMainWnd);
194 hdc = CreateCompatibleDC(hMaindc);
195 ReleaseDC(hMainWnd, hMaindc);
196 }
197
198 SendMessageW(hEditorWnd, EM_SETTARGETDEVICE, (WPARAM)hdc, width);
199
200 DeleteDC(hdc);
201 }
202
203 static LPWSTR dialog_print_to_file(HWND hMainWnd)
204 {
205 OPENFILENAMEW ofn;
206 static WCHAR file[MAX_PATH] = {'O','U','T','P','U','T','.','P','R','N',0};
207 static const WCHAR defExt[] = {'P','R','N',0};
208 static LPWSTR file_filter;
209
210 if(!file_filter)
211 file_filter = get_print_file_filter(hMainWnd);
212
213 ZeroMemory(&ofn, sizeof(ofn));
214
215 ofn.lStructSize = sizeof(ofn);
216 ofn.Flags = OFN_PATHMUSTEXIST | OFN_HIDEREADONLY | OFN_OVERWRITEPROMPT;
217 ofn.hwndOwner = hMainWnd;
218 ofn.lpstrFilter = file_filter;
219 ofn.lpstrFile = (LPWSTR)file;
220 ofn.nMaxFile = MAX_PATH;
221 ofn.lpstrDefExt = (LPWSTR)defExt;
222
223 if(GetSaveFileNameW(&ofn))
224 return (LPWSTR)file;
225 else
226 return FALSE;
227 }
228
229 static int get_num_pages(HWND hEditorWnd, FORMATRANGE fr)
230 {
231 int page = 0;
232
233 do
234 {
235 page++;
236 fr.chrg.cpMin = SendMessageW(hEditorWnd, EM_FORMATRANGE, TRUE,
237 (LPARAM)&fr);
238 }
239 while(fr.chrg.cpMin && fr.chrg.cpMin < fr.chrg.cpMax);
240
241 return page;
242 }
243
244 static void char_from_pagenum(HWND hEditorWnd, FORMATRANGE *fr, int page)
245 {
246 int i;
247
248 for(i = 1; i <= page; i++)
249 {
250 if(i == page)
251 break;
252
253 fr->chrg.cpMin = SendMessageW(hEditorWnd, EM_FORMATRANGE, TRUE, (LPARAM)fr);
254 }
255 }
256
257 static void print(LPPRINTDLGW pd, LPWSTR wszFileName)
258 {
259 FORMATRANGE fr;
260 DOCINFOW di;
261 HWND hEditorWnd = GetDlgItem(pd->hwndOwner, IDC_EDITOR);
262 int printedPages = 0;
263
264 fr.hdc = pd->hDC;
265 fr.hdcTarget = pd->hDC;
266
267 fr.rc = get_print_rect(fr.hdc);
268 fr.rcPage.left = 0;
269 fr.rcPage.right = fr.rc.right + margins.right;
270 fr.rcPage.top = 0;
271 fr.rcPage.bottom = fr.rc.bottom + margins.bottom;
272
273 ZeroMemory(&di, sizeof(di));
274 di.cbSize = sizeof(di);
275 di.lpszDocName = wszFileName;
276
277 if(pd->Flags & PD_PRINTTOFILE)
278 {
279 di.lpszOutput = dialog_print_to_file(pd->hwndOwner);
280 if(!di.lpszOutput)
281 return;
282 }
283
284 if(pd->Flags & PD_SELECTION)
285 {
286 SendMessageW(hEditorWnd, EM_EXGETSEL, 0, (LPARAM)&fr.chrg);
287 } else
288 {
289 GETTEXTLENGTHEX gt;
290 gt.flags = GTL_DEFAULT;
291 gt.codepage = 1200;
292 fr.chrg.cpMin = 0;
293 fr.chrg.cpMax = SendMessageW(hEditorWnd, EM_GETTEXTLENGTHEX, (WPARAM)&gt, 0);
294
295 if(pd->Flags & PD_PAGENUMS)
296 char_from_pagenum(hEditorWnd, &fr, pd->nToPage);
297 }
298
299 StartDocW(fr.hdc, &di);
300 do
301 {
302 if(StartPage(fr.hdc) <= 0)
303 break;
304
305 fr.chrg.cpMin = SendMessageW(hEditorWnd, EM_FORMATRANGE, TRUE, (LPARAM)&fr);
306
307 if(EndPage(fr.hdc) <= 0)
308 break;
309
310 printedPages++;
311 if((pd->Flags & PD_PAGENUMS) && (printedPages > (pd->nToPage - pd->nFromPage)))
312 break;
313 }
314 while(fr.chrg.cpMin && fr.chrg.cpMin < fr.chrg.cpMax);
315
316 EndDoc(fr.hdc);
317 SendMessageW(hEditorWnd, EM_FORMATRANGE, FALSE, 0);
318 }
319
320 void dialog_printsetup(HWND hMainWnd)
321 {
322 PAGESETUPDLGW ps;
323
324 ZeroMemory(&ps, sizeof(ps));
325 ps.lStructSize = sizeof(ps);
326 ps.hwndOwner = hMainWnd;
327 ps.Flags = PSD_INHUNDREDTHSOFMILLIMETERS | PSD_MARGINS;
328 ps.rtMargin.left = twips_to_centmm(margins.left);
329 ps.rtMargin.right = twips_to_centmm(margins.right);
330 ps.rtMargin.top = twips_to_centmm(margins.top);
331 ps.rtMargin.bottom = twips_to_centmm(margins.bottom);
332 ps.hDevMode = devMode;
333 ps.hDevNames = devNames;
334
335 if(PageSetupDlgW(&ps))
336 {
337 margins.left = centmm_to_twips(ps.rtMargin.left);
338 margins.right = centmm_to_twips(ps.rtMargin.right);
339 margins.top = centmm_to_twips(ps.rtMargin.top);
340 margins.bottom = centmm_to_twips(ps.rtMargin.bottom);
341 devMode = ps.hDevMode;
342 devNames = ps.hDevNames;
343 }
344 }
345
346 void get_default_printer_opts(void)
347 {
348 PRINTDLGW pd;
349 ZeroMemory(&pd, sizeof(pd));
350
351 ZeroMemory(&pd, sizeof(pd));
352 pd.lStructSize = sizeof(pd);
353 pd.Flags = PD_RETURNDC | PD_RETURNDEFAULT;
354 pd.hDevMode = devMode;
355
356 PrintDlgW(&pd);
357
358 devMode = pd.hDevMode;
359 devNames = pd.hDevNames;
360 }
361
362 void print_quick(LPWSTR wszFileName)
363 {
364 PRINTDLGW pd;
365
366 ZeroMemory(&pd, sizeof(pd));
367 pd.hDC = make_dc();
368
369 print(&pd, wszFileName);
370 }
371
372 void dialog_print(HWND hMainWnd, LPWSTR wszFileName)
373 {
374 PRINTDLGW pd;
375 HWND hEditorWnd = GetDlgItem(hMainWnd, IDC_EDITOR);
376 int from = 0;
377 int to = 0;
378
379 ZeroMemory(&pd, sizeof(pd));
380 pd.lStructSize = sizeof(pd);
381 pd.hwndOwner = hMainWnd;
382 pd.Flags = PD_RETURNDC | PD_USEDEVMODECOPIESANDCOLLATE;
383 pd.nMinPage = 1;
384 pd.nMaxPage = -1;
385 pd.hDevMode = devMode;
386 pd.hDevNames = devNames;
387
388 SendMessageW(hEditorWnd, EM_GETSEL, (WPARAM)&from, (LPARAM)&to);
389 if(from == to)
390 pd.Flags |= PD_NOSELECTION;
391
392 if(PrintDlgW(&pd))
393 {
394 devMode = pd.hDevMode;
395 devNames = pd.hDevNames;
396 print(&pd, wszFileName);
397 }
398 }
399
400 static void preview_bar_show(HWND hMainWnd, BOOL show)
401 {
402 HWND hReBar = GetDlgItem(hMainWnd, IDC_REBAR);
403 int i;
404
405 if(show)
406 {
407 REBARBANDINFOW rb;
408 HWND hStatic;
409
410 AddTextButton(hReBar, STRING_PREVIEW_PRINT, ID_PRINT, BANDID_PREVIEW_BTN1);
411 AddTextButton(hReBar, STRING_PREVIEW_NEXTPAGE, ID_PREVIEW_NEXTPAGE, BANDID_PREVIEW_BTN2);
412 AddTextButton(hReBar, STRING_PREVIEW_PREVPAGE, ID_PREVIEW_PREVPAGE, BANDID_PREVIEW_BTN3);
413 AddTextButton(hReBar, STRING_PREVIEW_CLOSE, ID_FILE_EXIT, BANDID_PREVIEW_BTN4);
414
415 hStatic = CreateWindowW(WC_STATICW, NULL,
416 WS_VISIBLE | WS_CHILD, 0, 0, 0, 0,
417 hReBar, NULL, NULL, NULL);
418
419 rb.cbSize = sizeof(rb);
420 rb.fMask = RBBIM_SIZE | RBBIM_CHILDSIZE | RBBIM_STYLE | RBBIM_CHILD | RBBIM_IDEALSIZE | RBBIM_ID;
421 rb.fStyle = RBBS_NOGRIPPER | RBBS_VARIABLEHEIGHT;
422 rb.hwndChild = hStatic;
423 rb.cyChild = rb.cyMinChild = 22;
424 rb.cx = rb.cxMinChild = 90;
425 rb.cxIdeal = 100;
426 rb.wID = BANDID_PREVIEW_BUFFER;
427
428 SendMessageW(hReBar, RB_INSERTBAND, -1, (LPARAM)&rb);
429 } else
430 {
431 for(i = 0; i <= PREVIEW_BUTTONS; i++)
432 SendMessageW(hReBar, RB_DELETEBAND, SendMessageW(hReBar, RB_IDTOINDEX, BANDID_PREVIEW_BTN1+i, 0), 0);
433 }
434 }
435
436 void init_preview(HWND hMainWnd, LPWSTR wszFileName)
437 {
438 preview.page = 1;
439 preview.hdc = 0;
440 preview.wszFileName = wszFileName;
441 preview_bar_show(hMainWnd, TRUE);
442 }
443
444 void close_preview(HWND hMainWnd)
445 {
446 preview.window.right = 0;
447 preview.window.bottom = 0;
448 preview.page = 0;
449 preview.pages = 0;
450
451 preview_bar_show(hMainWnd, FALSE);
452 }
453
454 BOOL preview_isactive(void)
455 {
456 return preview.page != 0;
457 }
458
459 LRESULT print_preview(HWND hMainWnd)
460 {
461 FORMATRANGE fr;
462 GETTEXTLENGTHEX gt;
463 HDC hdc;
464 RECT window, background;
465 HBITMAP hBitmapCapture, hBitmapScaled;
466 int bmWidth, bmHeight, bmNewWidth, bmNewHeight;
467 float ratioWidth, ratioHeight, ratio;
468 int xOffset, yOffset;
469 int barheight;
470 HWND hReBar = GetDlgItem(hMainWnd, IDC_REBAR);
471 PAINTSTRUCT ps;
472
473 hdc = BeginPaint(hMainWnd, &ps);
474 GetClientRect(hMainWnd, &window);
475
476 fr.hdcTarget = make_dc();
477 fr.rc = get_print_rect(fr.hdcTarget);
478 fr.rcPage.left = 0;
479 fr.rcPage.top = 0;
480 fr.rcPage.bottom = fr.rc.bottom + margins.bottom;
481 fr.rcPage.right = fr.rc.right + margins.right;
482
483 bmWidth = twips_to_pixels(fr.rcPage.right, GetDeviceCaps(hdc, LOGPIXELSX));
484 bmHeight = twips_to_pixels(fr.rcPage.bottom, GetDeviceCaps(hdc, LOGPIXELSY));
485
486 hBitmapCapture = CreateCompatibleBitmap(hdc, bmWidth, bmHeight);
487
488 if(!preview.hdc)
489 {
490 RECT paper;
491 HWND hEditorWnd = GetDlgItem(hMainWnd, IDC_EDITOR);
492
493 preview.hdc = CreateCompatibleDC(hdc);
494 fr.hdc = preview.hdc;
495 gt.flags = GTL_DEFAULT;
496 gt.codepage = 1200;
497 fr.chrg.cpMin = 0;
498 fr.chrg.cpMax = SendMessageW(hEditorWnd, EM_GETTEXTLENGTHEX, (WPARAM)&gt, 0);
499
500 paper.left = 0;
501 paper.right = bmWidth;
502 paper.top = 0;
503 paper.bottom = bmHeight;
504
505 if(!preview.pages)
506 preview.pages = get_num_pages(hEditorWnd, fr);
507
508 SelectObject(preview.hdc, hBitmapCapture);
509
510 char_from_pagenum(hEditorWnd, &fr, preview.page);
511
512 FillRect(preview.hdc, &paper, GetStockObject(WHITE_BRUSH));
513 SendMessageW(hEditorWnd, EM_FORMATRANGE, TRUE, (LPARAM)&fr);
514 SendMessageW(hEditorWnd, EM_FORMATRANGE, FALSE, 0);
515
516 EnableWindow(GetDlgItem(hReBar, ID_PREVIEW_PREVPAGE), preview.page > 1);
517 EnableWindow(GetDlgItem(hReBar, ID_PREVIEW_NEXTPAGE), preview.page < preview.pages);
518 }
519
520 barheight = SendMessageW(hReBar, RB_GETBARHEIGHT, 0, 0);
521 ratioWidth = ((float)window.right - 20.0) / (float)bmHeight;
522 ratioHeight = ((float)window.bottom - 20.0 - (float)barheight) / (float)bmHeight;
523
524 if(ratioWidth > ratioHeight)
525 ratio = ratioHeight;
526 else
527 ratio = ratioWidth;
528
529 bmNewWidth = (int)((float)bmWidth * ratio);
530 bmNewHeight = (int)((float)bmHeight * ratio);
531 hBitmapScaled = CreateCompatibleBitmap(hdc, bmNewWidth, bmNewHeight);
532
533 xOffset = ((window.right - bmNewWidth) / 2);
534 yOffset = ((window.bottom - bmNewHeight + barheight) / 2);
535
536 if(window.right != preview.window.right || window.bottom != preview.window.bottom)
537 {
538 HPEN hPen;
539 int TopMargin = (int)((float)twips_to_pixels(fr.rc.top, GetDeviceCaps(hdc, LOGPIXELSX)) * ratio);
540 int BottomMargin = (int)((float)twips_to_pixels(fr.rc.bottom, GetDeviceCaps(hdc, LOGPIXELSX)) * ratio);
541 int LeftMargin = (int)((float)twips_to_pixels(fr.rc.left, GetDeviceCaps(hdc, LOGPIXELSY)) * ratio);
542 int RightMargin = (int)((float)twips_to_pixels(fr.rc.right, GetDeviceCaps(hdc, LOGPIXELSY)) * ratio);
543
544 DeleteDC(preview.hdcSized);
545 preview.hdcSized = CreateCompatibleDC(hdc);
546 SelectObject(preview.hdcSized, hBitmapScaled);
547
548 StretchBlt(preview.hdcSized, 0, 0, bmNewWidth, bmNewHeight, preview.hdc, 0, 0, bmWidth, bmHeight, SRCCOPY);
549
550 /* Draw margin lines */
551 hPen = CreatePen(PS_DOT, 1, RGB(0,0,0));
552 SelectObject(preview.hdcSized, hPen);
553
554 MoveToEx(preview.hdcSized, 0, TopMargin, NULL);
555 LineTo(preview.hdcSized, bmNewWidth, TopMargin);
556 MoveToEx(preview.hdcSized, 0, BottomMargin, NULL);
557 LineTo(preview.hdcSized, bmNewWidth, BottomMargin);
558
559 MoveToEx(preview.hdcSized, LeftMargin, 0, NULL);
560 LineTo(preview.hdcSized, LeftMargin, bmNewHeight);
561 MoveToEx(preview.hdcSized, RightMargin, 0, NULL);
562 LineTo(preview.hdcSized, RightMargin, bmNewHeight);
563 }
564
565 window.top = barheight;
566 FillRect(hdc, &window, GetStockObject(GRAY_BRUSH));
567
568 SelectObject(hdc, hBitmapScaled);
569
570 background.left = xOffset - 2;
571 background.right = xOffset + bmNewWidth + 2;
572 background.top = yOffset - 2;
573 background.bottom = yOffset + bmNewHeight + 2;
574
575 FillRect(hdc, &background, GetStockObject(BLACK_BRUSH));
576
577 BitBlt(hdc, xOffset, yOffset, bmNewWidth, bmNewHeight, preview.hdcSized, 0, 0, SRCCOPY);
578
579 DeleteDC(fr.hdcTarget);
580 preview.window = window;
581
582 EndPaint(hMainWnd, &ps);
583
584 return 0;
585 }
586
587 LRESULT preview_command(HWND hWnd, WPARAM wParam, LPARAM lParam)
588 {
589 switch(LOWORD(wParam))
590 {
591 case ID_FILE_EXIT:
592 PostMessageW(hWnd, WM_CLOSE, 0, 0);
593 break;
594
595 case ID_PREVIEW_NEXTPAGE:
596 case ID_PREVIEW_PREVPAGE:
597 {
598 HWND hReBar = GetDlgItem(hWnd, IDC_REBAR);
599 RECT rc;
600
601 if(LOWORD(wParam) == ID_PREVIEW_NEXTPAGE)
602 preview.page++;
603 else
604 preview.page--;
605
606 preview.hdc = 0;
607 preview.window.right = 0;
608
609 GetClientRect(hWnd, &rc);
610 rc.top += SendMessageW(hReBar, RB_GETBARHEIGHT, 0, 0);
611 InvalidateRect(hWnd, &rc, TRUE);
612 }
613 break;
614
615 case ID_PRINT:
616 dialog_print(hWnd, preview.wszFileName);
617 SendMessageW(hWnd, WM_CLOSE, 0, 0);
618 break;
619 }
620
621 return 0;
622 }