2 * Wordpad implementation - Printing and print preview functions
4 * Copyright 2007-2008 by Alexander N. Sørnes <alex@thehandofagony.com>
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.
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.
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
27 typedef struct _previewinfo
37 } previewinfo
, *ppreviewinfo
;
39 static HGLOBAL devMode
;
40 static HGLOBAL devNames
;
43 static previewinfo preview
;
45 static const WCHAR var_pagemargin
[] = {'P','a','g','e','M','a','r','g','i','n',0};
47 static LPWSTR
get_print_file_filter(HWND hMainWnd
)
49 static WCHAR wszPrintFilter
[MAX_STRING_LEN
*2+6+4+1];
50 const WCHAR files_prn
[] = {'*','.','P','R','N',0};
51 const WCHAR files_all
[] = {'*','.','*','\0'};
53 HINSTANCE hInstance
= GetModuleHandleW(0);
56 LoadStringW(hInstance
, STRING_PRINTER_FILES_PRN
, p
, MAX_STRING_LEN
);
58 lstrcpyW(p
, files_prn
);
60 LoadStringW(hInstance
, STRING_ALL_FILES
, p
, MAX_STRING_LEN
);
62 lstrcpyW(p
, files_all
);
66 return wszPrintFilter
;
69 void registry_set_pagemargins(HKEY hKey
)
71 RegSetValueExW(hKey
, var_pagemargin
, 0, REG_BINARY
, (LPBYTE
)&margins
, sizeof(RECT
));
74 void registry_read_pagemargins(HKEY hKey
)
76 DWORD size
= sizeof(RECT
);
78 if(!hKey
|| RegQueryValueExW(hKey
, var_pagemargin
, 0, NULL
, (LPBYTE
)&margins
,
79 &size
) != ERROR_SUCCESS
|| size
!= sizeof(RECT
))
82 margins
.bottom
= 1417;
88 static void AddTextButton(HWND hRebarWnd
, UINT string
, UINT command
, UINT id
)
91 HINSTANCE hInstance
= GetModuleHandleW(0);
92 WCHAR text
[MAX_STRING_LEN
];
95 LoadStringW(hInstance
, string
, text
, MAX_STRING_LEN
);
96 hButton
= CreateWindowW(WC_BUTTONW
, text
,
97 WS_VISIBLE
| WS_CHILD
, 5, 5, 100, 15,
98 hRebarWnd
, ULongToHandle(command
), hInstance
, NULL
);
100 rb
.cbSize
= REBARBANDINFOW_V6_SIZE
;
101 rb
.fMask
= RBBIM_SIZE
| RBBIM_CHILDSIZE
| RBBIM_STYLE
| RBBIM_CHILD
| RBBIM_IDEALSIZE
| RBBIM_ID
;
102 rb
.fStyle
= RBBS_NOGRIPPER
| RBBS_VARIABLEHEIGHT
;
103 rb
.hwndChild
= hButton
;
104 rb
.cyChild
= rb
.cyMinChild
= 22;
105 rb
.cx
= rb
.cxMinChild
= 90;
109 SendMessageW(hRebarWnd
, RB_INSERTBAND
, -1, (LPARAM
)&rb
);
112 static HDC
make_dc(void)
114 if(devNames
&& devMode
)
116 LPDEVNAMES dn
= GlobalLock(devNames
);
117 LPDEVMODEW dm
= GlobalLock(devMode
);
120 ret
= CreateDCW((LPWSTR
)dn
+ dn
->wDriverOffset
,
121 (LPWSTR
)dn
+ dn
->wDeviceOffset
, 0, dm
);
133 static LONG
twips_to_centmm(int twips
)
135 return MulDiv(twips
, CENTMM_PER_INCH
, TWIPS_PER_INCH
);
138 static LONG
centmm_to_twips(int mm
)
140 return MulDiv(mm
, TWIPS_PER_INCH
, CENTMM_PER_INCH
);
143 static LONG
twips_to_pixels(int twips
, int dpi
)
145 return MulDiv(twips
, dpi
, TWIPS_PER_INCH
);
148 static LONG
devunits_to_twips(int units
, int dpi
)
150 return MulDiv(units
, TWIPS_PER_INCH
, dpi
);
154 static RECT
get_print_rect(HDC hdc
)
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
);
167 width
= centmm_to_twips(18500);
168 height
= centmm_to_twips(27000);
171 rc
.left
= margins
.left
;
172 rc
.right
= width
- margins
.right
;
173 rc
.top
= margins
.top
;
174 rc
.bottom
= height
- margins
.bottom
;
179 void target_device(HWND hMainWnd
, DWORD wordWrap
)
181 HWND hEditorWnd
= GetDlgItem(hMainWnd
, IDC_EDITOR
);
183 if(wordWrap
== ID_WORDWRAP_MARGIN
)
188 RECT rc
= get_print_rect(hdc
);
190 width
= rc
.right
- rc
.left
;
193 HDC hMaindc
= GetDC(hMainWnd
);
194 hdc
= CreateCompatibleDC(hMaindc
);
195 ReleaseDC(hMainWnd
, hMaindc
);
197 result
= SendMessageW(hEditorWnd
, EM_SETTARGETDEVICE
, (WPARAM
)hdc
, width
);
201 /* otherwise EM_SETTARGETDEVICE failed, so fall back on wrapping
202 * to window using the NULL DC. */
205 if (wordWrap
!= ID_WORDWRAP_NONE
) {
206 SendMessageW(hEditorWnd
, EM_SETTARGETDEVICE
, 0, 0);
208 SendMessageW(hEditorWnd
, EM_SETTARGETDEVICE
, 0, 1);
213 static LPWSTR
dialog_print_to_file(HWND hMainWnd
)
216 static WCHAR file
[MAX_PATH
] = {'O','U','T','P','U','T','.','P','R','N',0};
217 static const WCHAR defExt
[] = {'P','R','N',0};
218 static LPWSTR file_filter
;
221 file_filter
= get_print_file_filter(hMainWnd
);
223 ZeroMemory(&ofn
, sizeof(ofn
));
225 ofn
.lStructSize
= sizeof(ofn
);
226 ofn
.Flags
= OFN_PATHMUSTEXIST
| OFN_HIDEREADONLY
| OFN_OVERWRITEPROMPT
;
227 ofn
.hwndOwner
= hMainWnd
;
228 ofn
.lpstrFilter
= file_filter
;
229 ofn
.lpstrFile
= file
;
230 ofn
.nMaxFile
= MAX_PATH
;
231 ofn
.lpstrDefExt
= defExt
;
233 if(GetSaveFileNameW(&ofn
))
239 static int get_num_pages(HWND hEditorWnd
, FORMATRANGE fr
)
246 int bottom
= fr
.rc
.bottom
;
248 fr
.chrg
.cpMin
= SendMessageW(hEditorWnd
, EM_FORMATRANGE
, FALSE
,
250 fr
.rc
.bottom
= bottom
;
252 while(fr
.chrg
.cpMin
&& fr
.chrg
.cpMin
< fr
.chrg
.cpMax
);
257 static void char_from_pagenum(HWND hEditorWnd
, FORMATRANGE
*fr
, int page
)
263 for(i
= 1; i
< page
; i
++)
265 int bottom
= fr
->rc
.bottom
;
266 fr
->chrg
.cpMin
= SendMessageW(hEditorWnd
, EM_FORMATRANGE
, FALSE
, (LPARAM
)fr
);
267 fr
->rc
.bottom
= bottom
;
271 static HWND
get_ruler_wnd(HWND hMainWnd
)
273 return GetDlgItem(GetDlgItem(hMainWnd
, IDC_REBAR
), IDC_RULER
);
276 void redraw_ruler(HWND hRulerWnd
)
280 GetClientRect(hRulerWnd
, &rc
);
281 InvalidateRect(hRulerWnd
, &rc
, TRUE
);
284 static void update_ruler(HWND hRulerWnd
)
286 SendMessageW(hRulerWnd
, WM_USER
, 0, 0);
287 redraw_ruler(hRulerWnd
);
290 static void print(LPPRINTDLGW pd
, LPWSTR wszFileName
)
294 HWND hEditorWnd
= GetDlgItem(pd
->hwndOwner
, IDC_EDITOR
);
295 int printedPages
= 0;
298 fr
.hdcTarget
= pd
->hDC
;
300 fr
.rc
= get_print_rect(fr
.hdc
);
302 fr
.rcPage
.right
= fr
.rc
.right
+ margins
.right
;
304 fr
.rcPage
.bottom
= fr
.rc
.bottom
+ margins
.bottom
;
306 ZeroMemory(&di
, sizeof(di
));
307 di
.cbSize
= sizeof(di
);
308 di
.lpszDocName
= wszFileName
;
310 if(pd
->Flags
& PD_PRINTTOFILE
)
312 di
.lpszOutput
= dialog_print_to_file(pd
->hwndOwner
);
317 if(pd
->Flags
& PD_SELECTION
)
319 SendMessageW(hEditorWnd
, EM_EXGETSEL
, 0, (LPARAM
)&fr
.chrg
);
323 gt
.flags
= GTL_DEFAULT
;
326 fr
.chrg
.cpMax
= SendMessageW(hEditorWnd
, EM_GETTEXTLENGTHEX
, (WPARAM
)>
, 0);
328 if(pd
->Flags
& PD_PAGENUMS
)
329 char_from_pagenum(hEditorWnd
, &fr
, pd
->nToPage
);
332 StartDocW(fr
.hdc
, &di
);
335 int bottom
= fr
.rc
.bottom
;
336 if(StartPage(fr
.hdc
) <= 0)
339 fr
.chrg
.cpMin
= SendMessageW(hEditorWnd
, EM_FORMATRANGE
, TRUE
, (LPARAM
)&fr
);
341 if(EndPage(fr
.hdc
) <= 0)
343 bottom
= fr
.rc
.bottom
;
346 if((pd
->Flags
& PD_PAGENUMS
) && (printedPages
> (pd
->nToPage
- pd
->nFromPage
)))
349 while(fr
.chrg
.cpMin
&& fr
.chrg
.cpMin
< fr
.chrg
.cpMax
);
352 SendMessageW(hEditorWnd
, EM_FORMATRANGE
, FALSE
, 0);
355 void dialog_printsetup(HWND hMainWnd
)
359 ZeroMemory(&ps
, sizeof(ps
));
360 ps
.lStructSize
= sizeof(ps
);
361 ps
.hwndOwner
= hMainWnd
;
362 ps
.Flags
= PSD_INHUNDREDTHSOFMILLIMETERS
| PSD_MARGINS
;
363 ps
.rtMargin
.left
= twips_to_centmm(margins
.left
);
364 ps
.rtMargin
.right
= twips_to_centmm(margins
.right
);
365 ps
.rtMargin
.top
= twips_to_centmm(margins
.top
);
366 ps
.rtMargin
.bottom
= twips_to_centmm(margins
.bottom
);
367 ps
.hDevMode
= devMode
;
368 ps
.hDevNames
= devNames
;
370 if(PageSetupDlgW(&ps
))
372 margins
.left
= centmm_to_twips(ps
.rtMargin
.left
);
373 margins
.right
= centmm_to_twips(ps
.rtMargin
.right
);
374 margins
.top
= centmm_to_twips(ps
.rtMargin
.top
);
375 margins
.bottom
= centmm_to_twips(ps
.rtMargin
.bottom
);
376 devMode
= ps
.hDevMode
;
377 devNames
= ps
.hDevNames
;
378 update_ruler(get_ruler_wnd(hMainWnd
));
382 void get_default_printer_opts(void)
385 ZeroMemory(&pd
, sizeof(pd
));
387 ZeroMemory(&pd
, sizeof(pd
));
388 pd
.lStructSize
= sizeof(pd
);
389 pd
.Flags
= PD_RETURNDC
| PD_RETURNDEFAULT
;
390 pd
.hDevMode
= devMode
;
394 devMode
= pd
.hDevMode
;
395 devNames
= pd
.hDevNames
;
398 void print_quick(LPWSTR wszFileName
)
402 ZeroMemory(&pd
, sizeof(pd
));
405 print(&pd
, wszFileName
);
408 void dialog_print(HWND hMainWnd
, LPWSTR wszFileName
)
411 HWND hEditorWnd
= GetDlgItem(hMainWnd
, IDC_EDITOR
);
415 ZeroMemory(&pd
, sizeof(pd
));
416 pd
.lStructSize
= sizeof(pd
);
417 pd
.hwndOwner
= hMainWnd
;
418 pd
.Flags
= PD_RETURNDC
| PD_USEDEVMODECOPIESANDCOLLATE
;
421 pd
.hDevMode
= devMode
;
422 pd
.hDevNames
= devNames
;
424 SendMessageW(hEditorWnd
, EM_GETSEL
, (WPARAM
)&from
, (LPARAM
)&to
);
426 pd
.Flags
|= PD_NOSELECTION
;
430 devMode
= pd
.hDevMode
;
431 devNames
= pd
.hDevNames
;
432 print(&pd
, wszFileName
);
433 update_ruler(get_ruler_wnd(hMainWnd
));
437 static void preview_bar_show(HWND hMainWnd
, BOOL show
)
439 HWND hReBar
= GetDlgItem(hMainWnd
, IDC_REBAR
);
447 AddTextButton(hReBar
, STRING_PREVIEW_PRINT
, ID_PRINT
, BANDID_PREVIEW_BTN1
);
448 AddTextButton(hReBar
, STRING_PREVIEW_NEXTPAGE
, ID_PREVIEW_NEXTPAGE
, BANDID_PREVIEW_BTN2
);
449 AddTextButton(hReBar
, STRING_PREVIEW_PREVPAGE
, ID_PREVIEW_PREVPAGE
, BANDID_PREVIEW_BTN3
);
450 AddTextButton(hReBar
, STRING_PREVIEW_TWOPAGES
, ID_PREVIEW_NUMPAGES
, BANDID_PREVIEW_BTN4
);
451 AddTextButton(hReBar
, STRING_PREVIEW_CLOSE
, ID_FILE_EXIT
, BANDID_PREVIEW_BTN5
);
453 hStatic
= CreateWindowW(WC_STATICW
, NULL
,
454 WS_VISIBLE
| WS_CHILD
, 0, 0, 0, 0,
455 hReBar
, NULL
, NULL
, NULL
);
457 rb
.cbSize
= REBARBANDINFOW_V6_SIZE
;
458 rb
.fMask
= RBBIM_SIZE
| RBBIM_CHILDSIZE
| RBBIM_STYLE
| RBBIM_CHILD
| RBBIM_IDEALSIZE
| RBBIM_ID
;
459 rb
.fStyle
= RBBS_NOGRIPPER
| RBBS_VARIABLEHEIGHT
;
460 rb
.hwndChild
= hStatic
;
461 rb
.cyChild
= rb
.cyMinChild
= 22;
462 rb
.cx
= rb
.cxMinChild
= 90;
464 rb
.wID
= BANDID_PREVIEW_BUFFER
;
466 SendMessageW(hReBar
, RB_INSERTBAND
, -1, (LPARAM
)&rb
);
469 for(i
= 0; i
<= PREVIEW_BUTTONS
; i
++)
470 SendMessageW(hReBar
, RB_DELETEBAND
, SendMessageW(hReBar
, RB_IDTOINDEX
, BANDID_PREVIEW_BTN1
+i
, 0), 0);
474 void init_preview(HWND hMainWnd
, LPWSTR wszFileName
)
479 preview
.wszFileName
= wszFileName
;
480 preview_bar_show(hMainWnd
, TRUE
);
483 void close_preview(HWND hMainWnd
)
485 preview
.window
.right
= 0;
486 preview
.window
.bottom
= 0;
490 preview_bar_show(hMainWnd
, FALSE
);
493 BOOL
preview_isactive(void)
495 return preview
.page
!= 0;
498 static void add_ruler_units(HDC hdcRuler
, RECT
* drawRect
, BOOL NewMetrics
, LONG EditLeftmost
)
504 static HBITMAP hBitmap
;
505 int i
, x
, y
, RulerTextEnd
;
509 WCHAR FontName
[] = {'M','S',' ','S','a','n','s',' ','S','e','r','i','f',0};
514 DeleteObject(hBitmap
);
517 hdc
= CreateCompatibleDC(0);
519 CmPixels
= twips_to_pixels(centmm_to_twips(1000), GetDeviceCaps(hdc
, LOGPIXELSX
));
520 QuarterCmPixels
= (int)((float)CmPixels
/ 4.0);
522 hBitmap
= CreateCompatibleBitmap(hdc
, drawRect
->right
, drawRect
->bottom
);
523 SelectObject(hdc
, hBitmap
);
524 FillRect(hdc
, drawRect
, GetStockObject(WHITE_BRUSH
));
526 hFont
= CreateFontW(10, 6, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, FontName
);
528 SelectObject(hdc
, hFont
);
529 SetBkMode(hdc
, TRANSPARENT
);
530 SetTextAlign(hdc
, TA_CENTER
);
531 y
= (int)(((float)drawRect
->bottom
- (float)drawRect
->top
) / 2.0) + 1;
532 RulerTextEnd
= drawRect
->right
- EditLeftmost
+ 1;
533 for(i
= 1, x
= EditLeftmost
; x
< (drawRect
->right
- EditLeftmost
+ 1); i
++)
536 WCHAR format
[] = {'%','d',0};
539 x2
+= QuarterCmPixels
;
540 if(x2
> RulerTextEnd
)
543 MoveToEx(hdc
, x2
, y
, NULL
);
544 LineTo(hdc
, x2
, y
+2);
546 x2
+= QuarterCmPixels
;
547 if(x2
> RulerTextEnd
)
550 MoveToEx(hdc
, x2
, y
- 3, NULL
);
551 LineTo(hdc
, x2
, y
+ 3);
553 x2
+= QuarterCmPixels
;
554 if(x2
> RulerTextEnd
)
557 MoveToEx(hdc
, x2
, y
, NULL
);
558 LineTo(hdc
, x2
, y
+2);
564 wsprintfW(str
, format
, i
);
565 TextOutW(hdc
, x
, 5, str
, lstrlenW(str
));
570 BitBlt(hdcRuler
, 0, 0, drawRect
->right
, drawRect
->bottom
, hdc
, 0, 0, SRCAND
);
573 static void paint_ruler(HWND hWnd
, LONG EditLeftmost
, BOOL NewMetrics
)
576 HDC hdc
= BeginPaint(hWnd
, &ps
);
577 HDC hdcPrint
= make_dc();
578 RECT printRect
= get_print_rect(hdcPrint
);
580 HBRUSH hBrush
= CreateSolidBrush(GetSysColor(COLOR_MENU
));
582 GetClientRect(hWnd
, &drawRect
);
583 FillRect(hdc
, &drawRect
, hBrush
);
586 drawRect
.bottom
-= 3;
587 drawRect
.left
= EditLeftmost
;
588 drawRect
.right
= twips_to_pixels(printRect
.right
- margins
.left
, GetDeviceCaps(hdc
, LOGPIXELSX
));
589 FillRect(hdc
, &drawRect
, GetStockObject(WHITE_BRUSH
));
593 DrawEdge(hdc
, &drawRect
, EDGE_SUNKEN
, BF_RECT
);
595 drawRect
.left
= drawRect
.right
- 1;
596 drawRect
.right
= twips_to_pixels(printRect
.right
+ margins
.right
- margins
.left
, GetDeviceCaps(hdc
, LOGPIXELSX
));
597 DrawEdge(hdc
, &drawRect
, EDGE_ETCHED
, BF_RECT
);
601 add_ruler_units(hdc
, &drawRect
, NewMetrics
, EditLeftmost
);
603 SelectObject(hdc
, GetStockObject(BLACK_BRUSH
));
604 DeleteObject(hBrush
);
609 LRESULT CALLBACK
ruler_proc(HWND hWnd
, UINT msg
, WPARAM wParam
, LPARAM lParam
)
611 static WNDPROC pPrevRulerProc
;
612 static LONG EditLeftmost
;
613 static BOOL NewMetrics
;
620 EditLeftmost
= ((POINTL
*)wParam
)->x
;
621 pPrevRulerProc
= (WNDPROC
)lParam
;
627 paint_ruler(hWnd
, EditLeftmost
, NewMetrics
);
631 return CallWindowProcW(pPrevRulerProc
, hWnd
, msg
, wParam
, lParam
);
637 static void draw_preview_page(HDC hdc
, HDC
* hdcSized
, FORMATRANGE
* lpFr
, float ratio
, int bmNewWidth
, int bmNewHeight
, int bmWidth
, int bmHeight
)
639 HBITMAP hBitmapScaled
= CreateCompatibleBitmap(hdc
, bmNewWidth
, bmNewHeight
);
641 int TopMargin
= (int)((float)twips_to_pixels(lpFr
->rc
.top
, GetDeviceCaps(hdc
, LOGPIXELSX
)) * ratio
);
642 int BottomMargin
= (int)((float)twips_to_pixels(lpFr
->rc
.bottom
, GetDeviceCaps(hdc
, LOGPIXELSX
)) * ratio
);
643 int LeftMargin
= (int)((float)twips_to_pixels(lpFr
->rc
.left
, GetDeviceCaps(hdc
, LOGPIXELSY
)) * ratio
);
644 int RightMargin
= (int)((float)twips_to_pixels(lpFr
->rc
.right
, GetDeviceCaps(hdc
, LOGPIXELSY
)) * ratio
);
648 *hdcSized
= CreateCompatibleDC(hdc
);
649 SelectObject(*hdcSized
, hBitmapScaled
);
651 StretchBlt(*hdcSized
, 0, 0, bmNewWidth
, bmNewHeight
, hdc
, 0, 0, bmWidth
, bmHeight
, SRCCOPY
);
653 /* Draw margin lines */
654 hPen
= CreatePen(PS_DOT
, 1, RGB(0,0,0));
655 SelectObject(*hdcSized
, hPen
);
657 MoveToEx(*hdcSized
, 0, TopMargin
, NULL
);
658 LineTo(*hdcSized
, bmNewWidth
, TopMargin
);
659 MoveToEx(*hdcSized
, 0, BottomMargin
, NULL
);
660 LineTo(*hdcSized
, bmNewWidth
, BottomMargin
);
662 MoveToEx(*hdcSized
, LeftMargin
, 0, NULL
);
663 LineTo(*hdcSized
, LeftMargin
, bmNewHeight
);
664 MoveToEx(*hdcSized
, RightMargin
, 0, NULL
);
665 LineTo(*hdcSized
, RightMargin
, bmNewHeight
);
669 static void draw_preview(HWND hEditorWnd
, FORMATRANGE
* lpFr
, int bmWidth
, int bmHeight
, RECT
* paper
, int page
)
671 HBITMAP hBitmapCapture
= CreateCompatibleBitmap(lpFr
->hdc
, bmWidth
, bmHeight
);
673 char_from_pagenum(hEditorWnd
, lpFr
, page
);
674 SelectObject(lpFr
->hdc
, hBitmapCapture
);
675 FillRect(lpFr
->hdc
, paper
, GetStockObject(WHITE_BRUSH
));
676 SendMessageW(hEditorWnd
, EM_FORMATRANGE
, TRUE
, (LPARAM
)lpFr
);
677 /* EM_FORMATRANGE sets fr.rc to indicate the area printed in, but we want to
678 keep the original for drawing margins */
679 lpFr
->rc
= get_print_rect(lpFr
->hdcTarget
);
680 SendMessageW(hEditorWnd
, EM_FORMATRANGE
, FALSE
, 0);
683 LRESULT
print_preview(HWND hMainWnd
)
688 RECT window
, background
;
689 int bmWidth
, bmHeight
, bmNewWidth
, bmNewHeight
;
690 float ratioWidth
, ratioHeight
, ratio
;
691 int xOffset
, yOffset
;
693 float spacing
= 20.0;
694 HWND hReBar
= GetDlgItem(hMainWnd
, IDC_REBAR
);
697 hdc
= BeginPaint(hMainWnd
, &ps
);
698 GetClientRect(hMainWnd
, &window
);
700 fr
.hdcTarget
= make_dc();
701 fr
.rc
= get_print_rect(fr
.hdcTarget
);
704 fr
.rcPage
.bottom
= fr
.rc
.bottom
+ margins
.bottom
;
705 fr
.rcPage
.right
= fr
.rc
.right
+ margins
.right
;
707 bmWidth
= twips_to_pixels(fr
.rcPage
.right
, GetDeviceCaps(hdc
, LOGPIXELSX
));
708 bmHeight
= twips_to_pixels(fr
.rcPage
.bottom
, GetDeviceCaps(hdc
, LOGPIXELSY
));
713 HWND hEditorWnd
= GetDlgItem(hMainWnd
, IDC_EDITOR
);
715 preview
.hdc
= CreateCompatibleDC(hdc
);
719 if(preview
.hdc2
!= (HDC
)-1)
720 DeleteDC(preview
.hdc2
);
721 preview
.hdc2
= CreateCompatibleDC(hdc
);
724 fr
.hdc
= preview
.hdc
;
725 gt
.flags
= GTL_DEFAULT
;
728 fr
.chrg
.cpMax
= SendMessageW(hEditorWnd
, EM_GETTEXTLENGTHEX
, (WPARAM
)>
, 0);
731 paper
.right
= bmWidth
;
733 paper
.bottom
= bmHeight
;
736 preview
.pages
= get_num_pages(hEditorWnd
, fr
);
738 fr
.hdc
= preview
.hdc
;
739 draw_preview(hEditorWnd
, &fr
, bmWidth
, bmHeight
, &paper
, preview
.page
);
743 fr
.hdc
= preview
.hdc2
;
744 draw_preview(hEditorWnd
, &fr
, bmWidth
, bmHeight
, &paper
, preview
.page
+ 1);
747 EnableWindow(GetDlgItem(hReBar
, ID_PREVIEW_PREVPAGE
), preview
.page
> 1);
748 EnableWindow(GetDlgItem(hReBar
, ID_PREVIEW_NEXTPAGE
), preview
.hdc2
?
749 (preview
.page
+ 1) < preview
.pages
:
750 preview
.page
< preview
.pages
);
751 EnableWindow(GetDlgItem(hReBar
, ID_PREVIEW_NUMPAGES
), preview
.pages
> 1);
754 barheight
= SendMessageW(hReBar
, RB_GETBARHEIGHT
, 0, 0);
755 ratioHeight
= ((float)window
.bottom
- spacing
- (float)barheight
) / (float)bmHeight
;
758 ratioWidth
= ((float)window
.right
/ 2.0 - spacing
* 2.0) / (float)bmWidth
;
760 ratioWidth
= ((float)window
.right
- spacing
* 3.0) / (float)bmWidth
;
762 if(ratioWidth
> ratioHeight
)
767 bmNewWidth
= (int)((float)bmWidth
* ratio
);
768 bmNewHeight
= (int)((float)bmHeight
* ratio
);
770 yOffset
= ((window
.bottom
- bmNewHeight
+ barheight
) / 2);
773 xOffset
= (window
.right
- bmNewWidth
) / 2;
775 xOffset
= (window
.right
- bmNewWidth
* 2) / 2;
777 window
.top
= barheight
;
778 FillRect(hdc
, &window
, GetStockObject(GRAY_BRUSH
));
780 background
.left
= xOffset
- 2;
781 background
.right
= xOffset
+ bmNewWidth
+ 2;
782 background
.top
= yOffset
- 2;
783 background
.bottom
= yOffset
+ bmNewHeight
+ 2;
785 FillRect(hdc
, &background
, GetStockObject(BLACK_BRUSH
));
787 if(window
.right
!= preview
.window
.right
|| window
.bottom
!= preview
.window
.bottom
)
789 draw_preview_page(preview
.hdc
, &preview
.hdcSized
, &fr
, ratio
, bmNewWidth
, bmNewHeight
, bmWidth
, bmHeight
);
793 background
.left
+= bmNewWidth
+ spacing
;
794 background
.right
+= bmNewWidth
+ spacing
;
796 FillRect(hdc
, &background
, GetStockObject(BLACK_BRUSH
));
798 draw_preview_page(preview
.hdc2
, &preview
.hdcSized2
, &fr
, ratio
, bmNewWidth
, bmNewHeight
, bmWidth
, bmHeight
);
802 BitBlt(hdc
, xOffset
, yOffset
, bmNewWidth
, bmNewHeight
, preview
.hdcSized
, 0, 0, SRCCOPY
);
806 BitBlt(hdc
, xOffset
+ bmNewWidth
+ spacing
, yOffset
, bmNewWidth
, bmNewHeight
, preview
.hdcSized2
, 0, 0, SRCCOPY
);
809 DeleteDC(fr
.hdcTarget
);
810 preview
.window
= window
;
812 EndPaint(hMainWnd
, &ps
);
817 static void update_preview(HWND hWnd
)
821 DeleteDC(preview
.hdc
);
824 preview
.window
.right
= 0;
826 GetClientRect(hWnd
, &rc
);
827 rc
.top
+= SendMessageW(GetDlgItem(hWnd
, IDC_REBAR
), RB_GETBARHEIGHT
, 0, 0);
828 InvalidateRect(hWnd
, &rc
, TRUE
);
831 LRESULT
preview_command(HWND hWnd
, WPARAM wParam
)
833 switch(LOWORD(wParam
))
836 PostMessageW(hWnd
, WM_CLOSE
, 0, 0);
839 case ID_PREVIEW_NEXTPAGE
:
840 case ID_PREVIEW_PREVPAGE
:
842 if(LOWORD(wParam
) == ID_PREVIEW_NEXTPAGE
)
847 update_preview(hWnd
);
851 case ID_PREVIEW_NUMPAGES
:
853 HWND hReBar
= GetDlgItem(hWnd
, IDC_REBAR
);
854 WCHAR name
[MAX_STRING_LEN
];
855 HINSTANCE hInst
= GetModuleHandleW(0);
859 DeleteDC(preview
.hdc2
);
863 if(preview
.page
== preview
.pages
)
865 preview
.hdc2
= (HDC
)-1;
868 LoadStringW(hInst
, preview
.hdc2
? STRING_PREVIEW_ONEPAGE
: STRING_PREVIEW_TWOPAGES
,
869 name
, MAX_STRING_LEN
);
871 SetWindowTextW(GetDlgItem(hReBar
, ID_PREVIEW_NUMPAGES
), name
);
872 update_preview(hWnd
);
877 dialog_print(hWnd
, preview
.wszFileName
);
878 SendMessageW(hWnd
, WM_CLOSE
, 0, 0);