ReactOS  0.4.12-dev-102-g4b7f1e0
print.c
Go to the documentation of this file.
1 /*
2  * Wordpad implementation - Printing and print preview functions
3  *
4  * Copyright 2007-2008 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 <stdarg.h>
22 #include <windef.h>
23 #include <winbase.h>
24 #include <winreg.h>
25 #include <wingdi.h>
26 #include <winuser.h>
27 #include <richedit.h>
28 #include <commctrl.h>
29 #include <commdlg.h>
30 
31 #include "wordpad.h"
32 
33 typedef struct _previewinfo
34 {
35  int page;
47  float zoomratio;
48  int zoomlevel;
51 
54 
55 static RECT margins;
57 
58 extern const WCHAR wszPreviewWndClass[];
59 
60 static const WCHAR var_pagemargin[] = {'P','a','g','e','M','a','r','g','i','n',0};
61 static const WCHAR var_previewpages[] = {'P','r','e','v','i','e','w','P','a','g','e','s',0};
62 
64 {
65  static WCHAR wszPrintFilter[MAX_STRING_LEN*2+6+4+1];
66  const WCHAR files_prn[] = {'*','.','P','R','N',0};
67  const WCHAR files_all[] = {'*','.','*','\0'};
68  LPWSTR p;
70 
71  p = wszPrintFilter;
73  p += lstrlenW(p) + 1;
74  lstrcpyW(p, files_prn);
75  p += lstrlenW(p) + 1;
77  p += lstrlenW(p) + 1;
78  lstrcpyW(p, files_all);
79  p += lstrlenW(p) + 1;
80  *p = 0;
81 
82  return wszPrintFilter;
83 }
84 
86 {
87  RegSetValueExW(hKey, var_pagemargin, 0, REG_BINARY, (LPBYTE)&margins, sizeof(RECT));
88 }
89 
91 {
92  DWORD size = sizeof(RECT);
93 
94  if(!hKey || RegQueryValueExW(hKey, var_pagemargin, 0, NULL, (LPBYTE)&margins,
95  &size) != ERROR_SUCCESS || size != sizeof(RECT))
96  SetRect(&margins, 1757, 1417, 1757, 1417);
97 }
98 
100 {
102  (LPBYTE)&preview.pages_shown, sizeof(DWORD));
103 }
104 
106 {
107  DWORD size = sizeof(DWORD);
108  if(!hKey ||
110  (LPBYTE)&preview.pages_shown, &size) != ERROR_SUCCESS ||
111  size != sizeof(DWORD))
112  {
113  preview.pages_shown = 1;
114  } else {
115  if (preview.pages_shown < 1) preview.pages_shown = 1;
116  else if (preview.pages_shown > 2) preview.pages_shown = 2;
117  }
118 }
119 
120 
121 static void AddTextButton(HWND hRebarWnd, UINT string, UINT command, UINT id)
122 {
123  REBARBANDINFOW rb;
126  HWND hButton;
127 
128  LoadStringW(hInstance, string, text, MAX_STRING_LEN);
129  hButton = CreateWindowW(WC_BUTTONW, text,
130  WS_VISIBLE | WS_CHILD, 5, 5, 100, 15,
131  hRebarWnd, ULongToHandle(command), hInstance, NULL);
132 
136  rb.hwndChild = hButton;
137  rb.cyChild = rb.cyMinChild = 22;
138  rb.cx = rb.cxMinChild = 90;
139  rb.cxIdeal = 100;
140  rb.wID = id;
141 
142  SendMessageW(hRebarWnd, RB_INSERTBANDW, -1, (LPARAM)&rb);
143 }
144 
145 static HDC make_dc(void)
146 {
147  if(devNames && devMode)
148  {
149  LPDEVNAMES dn = GlobalLock(devNames);
150  LPDEVMODEW dm = GlobalLock(devMode);
151  HDC ret;
152 
153  ret = CreateDCW((LPWSTR)dn + dn->wDriverOffset,
154  (LPWSTR)dn + dn->wDeviceOffset, 0, dm);
155 
156  GlobalUnlock(dn);
157  GlobalUnlock(dm);
158 
159  return ret;
160  } else
161  {
162  return 0;
163  }
164 }
165 
166 static LONG twips_to_centmm(int twips)
167 {
168  return MulDiv(twips, CENTMM_PER_INCH, TWIPS_PER_INCH);
169 }
170 
171 static LONG centmm_to_twips(int mm)
172 {
174 }
175 
176 static LONG twips_to_pixels(int twips, int dpi)
177 {
178  return MulDiv(twips, dpi, TWIPS_PER_INCH);
179 }
180 
181 static LONG devunits_to_twips(int units, int dpi)
182 {
183  return MulDiv(units, TWIPS_PER_INCH, dpi);
184 }
185 
186 
188 {
189  RECT rc;
190  int width, height;
191 
192  if(hdc)
193  {
194  int dpiY = GetDeviceCaps(hdc, LOGPIXELSY);
195  int dpiX = GetDeviceCaps(hdc, LOGPIXELSX);
196  width = devunits_to_twips(GetDeviceCaps(hdc, PHYSICALWIDTH), dpiX);
197  height = devunits_to_twips(GetDeviceCaps(hdc, PHYSICALHEIGHT), dpiY);
198  } else
199  {
200  width = centmm_to_twips(18500);
201  height = centmm_to_twips(27000);
202  }
203 
204  SetRect(&rc, margins.left, margins.top, width - margins.right, height - margins.bottom);
205 
206  return rc;
207 }
208 
210 {
211  HWND hEditorWnd = GetDlgItem(hMainWnd, IDC_EDITOR);
212 
213  if(wordWrap == ID_WORDWRAP_MARGIN)
214  {
215  int width = 0;
216  LRESULT result;
217  HDC hdc = make_dc();
218  RECT rc = get_print_rect(hdc);
219 
220  width = rc.right - rc.left;
221  if(!hdc)
222  {
223  HDC hMaindc = GetDC(hMainWnd);
224  hdc = CreateCompatibleDC(hMaindc);
225  ReleaseDC(hMainWnd, hMaindc);
226  }
227  result = SendMessageW(hEditorWnd, EM_SETTARGETDEVICE, (WPARAM)hdc, width);
228  DeleteDC(hdc);
229  if (result)
230  return;
231  /* otherwise EM_SETTARGETDEVICE failed, so fall back on wrapping
232  * to window using the NULL DC. */
233  }
234 
235  if (wordWrap != ID_WORDWRAP_NONE) {
236  SendMessageW(hEditorWnd, EM_SETTARGETDEVICE, 0, 0);
237  } else {
238  SendMessageW(hEditorWnd, EM_SETTARGETDEVICE, 0, 1);
239  }
240 
241 }
242 
244 {
246  static WCHAR file[MAX_PATH] = {'O','U','T','P','U','T','.','P','R','N',0};
247  static const WCHAR defExt[] = {'P','R','N',0};
248  static LPWSTR file_filter;
249 
250  if(!file_filter)
251  file_filter = get_print_file_filter(hMainWnd);
252 
253  ZeroMemory(&ofn, sizeof(ofn));
254 
255  ofn.lStructSize = sizeof(ofn);
257  ofn.hwndOwner = hMainWnd;
258  ofn.lpstrFilter = file_filter;
259  ofn.lpstrFile = file;
260  ofn.nMaxFile = MAX_PATH;
261  ofn.lpstrDefExt = defExt;
262 
263  if(GetSaveFileNameW(&ofn))
264  return file;
265  else
266  return FALSE;
267 }
268 
270 {
271  int i;
272 
273  fr->chrg.cpMin = 0;
274 
275  for(i = 1; i < page; i++)
276  {
277  int bottom = fr->rc.bottom;
278  fr->chrg.cpMin = SendMessageW(hEditorWnd, EM_FORMATRANGE, FALSE, (LPARAM)fr);
279  fr->rc.bottom = bottom;
280  }
281 }
282 
284 {
285  return GetDlgItem(GetDlgItem(hMainWnd, IDC_REBAR), IDC_RULER);
286 }
287 
288 void redraw_ruler(HWND hRulerWnd)
289 {
290  RECT rc;
291 
292  GetClientRect(hRulerWnd, &rc);
293  InvalidateRect(hRulerWnd, &rc, TRUE);
294 }
295 
296 static void update_ruler(HWND hRulerWnd)
297 {
298  SendMessageW(hRulerWnd, WM_USER, 0, 0);
299  redraw_ruler(hRulerWnd);
300 }
301 
302 static void add_ruler_units(HDC hdcRuler, RECT* drawRect, BOOL NewMetrics, LONG EditLeftmost)
303 {
304  static HDC hdc;
305 
306  if(NewMetrics)
307  {
308  static HBITMAP hBitmap;
309  int i, x, y, RulerTextEnd;
310  int CmPixels;
311  int QuarterCmPixels;
312  HFONT hFont;
313  WCHAR FontName[] = {'M','S',' ','S','a','n','s',' ','S','e','r','i','f',0};
314 
315  if(hdc)
316  {
317  DeleteDC(hdc);
318  DeleteObject(hBitmap);
319  }
320 
321  hdc = CreateCompatibleDC(0);
322 
323  CmPixels = twips_to_pixels(centmm_to_twips(1000), GetDeviceCaps(hdc, LOGPIXELSX));
324  QuarterCmPixels = (int)((float)CmPixels / 4.0);
325 
326  hBitmap = CreateCompatibleBitmap(hdc, drawRect->right, drawRect->bottom);
327  SelectObject(hdc, hBitmap);
328  FillRect(hdc, drawRect, GetStockObject(WHITE_BRUSH));
329 
330  hFont = CreateFontW(10, 6, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, FontName);
331 
332  SelectObject(hdc, hFont);
333  SetBkMode(hdc, TRANSPARENT);
334  SetTextAlign(hdc, TA_CENTER);
335  y = (int)(((float)drawRect->bottom - (float)drawRect->top) / 2.0) + 1;
336  RulerTextEnd = drawRect->right - EditLeftmost + 1;
337  for(i = 1, x = EditLeftmost; x < (drawRect->right - EditLeftmost + 1); i ++)
338  {
339  WCHAR str[3];
340  WCHAR format[] = {'%','d',0};
341  int x2 = x;
342 
343  x2 += QuarterCmPixels;
344  if(x2 > RulerTextEnd)
345  break;
346 
347  MoveToEx(hdc, x2, y, NULL);
348  LineTo(hdc, x2, y+2);
349 
350  x2 += QuarterCmPixels;
351  if(x2 > RulerTextEnd)
352  break;
353 
354  MoveToEx(hdc, x2, y - 3, NULL);
355  LineTo(hdc, x2, y + 3);
356 
357  x2 += QuarterCmPixels;
358  if(x2 > RulerTextEnd)
359  break;
360 
361  MoveToEx(hdc, x2, y, NULL);
362  LineTo(hdc, x2, y+2);
363 
364  x += CmPixels;
365  if(x > RulerTextEnd)
366  break;
367 
368  wsprintfW(str, format, i);
369  TextOutW(hdc, x, 5, str, lstrlenW(str));
370  }
371  DeleteObject(hFont);
372  }
373 
374  BitBlt(hdcRuler, 0, 0, drawRect->right, drawRect->bottom, hdc, 0, 0, SRCAND);
375 }
376 
377 static void paint_ruler(HWND hWnd, LONG EditLeftmost, BOOL NewMetrics)
378 {
379  PAINTSTRUCT ps;
380  HDC hdc = BeginPaint(hWnd, &ps);
381  HDC hdcPrint = make_dc();
382  RECT printRect = get_print_rect(hdcPrint);
383  RECT drawRect;
384  HBRUSH hBrush = CreateSolidBrush(GetSysColor(COLOR_MENU));
385 
386  GetClientRect(hWnd, &drawRect);
387  FillRect(hdc, &drawRect, hBrush);
388 
389  InflateRect(&drawRect, 0, -3);
390  drawRect.left = EditLeftmost;
391  drawRect.right = twips_to_pixels(printRect.right - margins.left, GetDeviceCaps(hdc, LOGPIXELSX));
392  FillRect(hdc, &drawRect, GetStockObject(WHITE_BRUSH));
393 
394  drawRect.top--;
395  drawRect.bottom++;
396  DrawEdge(hdc, &drawRect, EDGE_SUNKEN, BF_RECT);
397 
398  drawRect.left = drawRect.right - 1;
399  drawRect.right = twips_to_pixels(printRect.right + margins.right - margins.left, GetDeviceCaps(hdc, LOGPIXELSX));
400  DrawEdge(hdc, &drawRect, EDGE_ETCHED, BF_RECT);
401 
402  drawRect.left = 0;
403  drawRect.top = 0;
404  add_ruler_units(hdc, &drawRect, NewMetrics, EditLeftmost);
405 
407  DeleteObject(hBrush);
408  DeleteDC(hdcPrint);
409  EndPaint(hWnd, &ps);
410 }
411 
413 {
414  static WNDPROC pPrevRulerProc;
415  static LONG EditLeftmost;
416  static BOOL NewMetrics;
417 
418  switch(msg)
419  {
420  case WM_USER:
421  if(wParam)
422  {
423  EditLeftmost = ((POINTL*)wParam)->x;
424  pPrevRulerProc = (WNDPROC)lParam;
425  }
426  NewMetrics = TRUE;
427  break;
428 
429  case WM_PAINT:
430  paint_ruler(hWnd, EditLeftmost, NewMetrics);
431  break;
432 
433  default:
434  return CallWindowProcW(pPrevRulerProc, hWnd, msg, wParam, lParam);
435  }
436 
437  return 0;
438 }
439 
441 {
442  FORMATRANGE fr;
443  DOCINFOW di;
445  int printedPages = 0;
446 
447  fr.hdc = pd->hDC;
448  fr.hdcTarget = pd->hDC;
449 
450  fr.rc = get_print_rect(fr.hdc);
451  SetRect(&fr.rcPage, 0, 0, fr.rc.right + margins.right, fr.rc.bottom + margins.bottom);
452 
453  ZeroMemory(&di, sizeof(di));
454  di.cbSize = sizeof(di);
456 
457  if(pd->Flags & PD_PRINTTOFILE)
458  {
460  if(!di.lpszOutput)
461  return;
462  }
463 
464  if(pd->Flags & PD_SELECTION)
465  {
466  SendMessageW(hEditorWnd, EM_EXGETSEL, 0, (LPARAM)&fr.chrg);
467  } else
468  {
469  GETTEXTLENGTHEX gt;
470  gt.flags = GTL_DEFAULT;
471  gt.codepage = 1200;
472  fr.chrg.cpMin = 0;
473  fr.chrg.cpMax = SendMessageW(hEditorWnd, EM_GETTEXTLENGTHEX, (WPARAM)&gt, 0);
474 
475  if(pd->Flags & PD_PAGENUMS)
476  char_from_pagenum(hEditorWnd, &fr, pd->nToPage);
477  }
478 
479  StartDocW(fr.hdc, &di);
480  do
481  {
482  if(StartPage(fr.hdc) <= 0)
483  break;
484 
485  fr.chrg.cpMin = SendMessageW(hEditorWnd, EM_FORMATRANGE, TRUE, (LPARAM)&fr);
486 
487  if(EndPage(fr.hdc) <= 0)
488  break;
489 
490  printedPages++;
491  if((pd->Flags & PD_PAGENUMS) && (printedPages > (pd->nToPage - pd->nFromPage)))
492  break;
493  }
494  while(fr.chrg.cpMin && fr.chrg.cpMin < fr.chrg.cpMax);
495 
496  EndDoc(fr.hdc);
497  SendMessageW(hEditorWnd, EM_FORMATRANGE, FALSE, 0);
498 }
499 
501 {
502  PAGESETUPDLGW ps;
503 
504  ZeroMemory(&ps, sizeof(ps));
505  ps.lStructSize = sizeof(ps);
506  ps.hwndOwner = hMainWnd;
508  SetRect(&ps.rtMargin, twips_to_centmm(margins.left), twips_to_centmm(margins.top),
509  twips_to_centmm(margins.right), twips_to_centmm(margins.bottom));
510  ps.hDevMode = devMode;
511  ps.hDevNames = devNames;
512 
513  if(PageSetupDlgW(&ps))
514  {
517  devMode = ps.hDevMode;
518  devNames = ps.hDevNames;
519  update_ruler(get_ruler_wnd(hMainWnd));
520  }
521 }
522 
524 {
525  PRINTDLGW pd;
526  ZeroMemory(&pd, sizeof(pd));
527 
528  ZeroMemory(&pd, sizeof(pd));
529  pd.lStructSize = sizeof(pd);
531  pd.hDevMode = devMode;
532 
533  PrintDlgW(&pd);
534 
535  devMode = pd.hDevMode;
536  devNames = pd.hDevNames;
537 }
538 
540 {
541  PRINTDLGW pd;
542 
543  ZeroMemory(&pd, sizeof(pd));
544  pd.hwndOwner = hMainWnd;
545  pd.hDC = make_dc();
546 
547  print(&pd, wszFileName);
548  DeleteDC(pd.hDC);
549 }
550 
552 {
553  PRINTDLGW pd;
554  HWND hEditorWnd = GetDlgItem(hMainWnd, IDC_EDITOR);
555  int from = 0;
556  int to = 0;
557 
558  ZeroMemory(&pd, sizeof(pd));
559  pd.lStructSize = sizeof(pd);
560  pd.hwndOwner = hMainWnd;
562  pd.nMinPage = 1;
563  pd.nMaxPage = -1;
564  pd.hDevMode = devMode;
565  pd.hDevNames = devNames;
566 
567  SendMessageW(hEditorWnd, EM_GETSEL, (WPARAM)&from, (LPARAM)&to);
568  if(from == to)
569  pd.Flags |= PD_NOSELECTION;
570 
571  if(PrintDlgW(&pd))
572  {
573  devMode = pd.hDevMode;
574  devNames = pd.hDevNames;
575  print(&pd, wszFileName);
576  update_ruler(get_ruler_wnd(hMainWnd));
577  }
578 }
579 
580 static void preview_bar_show(HWND hMainWnd, BOOL show)
581 {
582  HWND hReBar = GetDlgItem(hMainWnd, IDC_REBAR);
583  int i;
584 
585  if(show)
586  {
587  REBARBANDINFOW rb;
588  HWND hStatic;
589  UINT num_pages_string = preview.pages_shown > 1 ? STRING_PREVIEW_ONEPAGE :
591 
595  AddTextButton(hReBar, num_pages_string, ID_PREVIEW_NUMPAGES, BANDID_PREVIEW_BTN4);
599 
600  hStatic = CreateWindowW(WC_STATICW, NULL,
601  WS_VISIBLE | WS_CHILD, 0, 0, 0, 0,
602  hReBar, NULL, NULL, NULL);
603 
607  rb.hwndChild = hStatic;
608  rb.cyChild = rb.cyMinChild = 22;
609  rb.cx = rb.cxMinChild = 90;
610  rb.cxIdeal = 100;
612 
613  SendMessageW(hReBar, RB_INSERTBANDW, -1, (LPARAM)&rb);
614  } else
615  {
616  for(i = 0; i <= PREVIEW_BUTTONS; i++)
618  }
619 }
620 
621 static const int min_spacing = 10;
622 
623 static void update_preview_scrollbars(HWND hwndPreview, RECT *window)
624 {
625  SCROLLINFO sbi;
626  sbi.cbSize = sizeof(sbi);
627  sbi.fMask = SIF_PAGE|SIF_RANGE;
628  sbi.nMin = 0;
629  if (preview.zoomlevel == 0)
630  {
631  /* Hide scrollbars when zoomed out. */
632  sbi.nMax = 0;
633  sbi.nPage = window->right;
634  SetScrollInfo(hwndPreview, SB_HORZ, &sbi, TRUE);
635  sbi.nPage = window->bottom;
636  SetScrollInfo(hwndPreview, SB_VERT, &sbi, TRUE);
637  } else {
638  sbi.nMax = preview.bmScaledSize.cx * preview.pages_shown +
639  min_spacing * (preview.pages_shown + 1);
640  sbi.nPage = window->right;
641  SetScrollInfo(hwndPreview, SB_HORZ, &sbi, TRUE);
642  /* Change in the horizontal scrollbar visibility affects the
643  * client rect, so update the client rect. */
644  GetClientRect(hwndPreview, window);
645  sbi.nMax = preview.bmScaledSize.cy + min_spacing * 2;
646  sbi.nPage = window->bottom;
647  SetScrollInfo(hwndPreview, SB_VERT, &sbi, TRUE);
648  }
649 }
650 
651 static void update_preview_sizes(HWND hwndPreview, BOOL zoomLevelUpdated)
652 {
653  RECT window;
654 
655  GetClientRect(hwndPreview, &window);
656 
657  /* The zoom ratio isn't updated for partial zoom because of resizing the window. */
658  if (zoomLevelUpdated || preview.zoomlevel != 1)
659  {
660  float ratio, ratioHeight, ratioWidth;
661  if (preview.zoomlevel == 2)
662  {
663  ratio = 1.0;
664  } else {
665  ratioHeight = (window.bottom - min_spacing * 2) / (float)preview.bmSize.cy;
666 
667  ratioWidth = (float)(window.right -
668  min_spacing * (preview.pages_shown + 1)) /
669  (preview.pages_shown * preview.bmSize.cx);
670 
671  if(ratioWidth > ratioHeight)
672  ratio = ratioHeight;
673  else
674  ratio = ratioWidth;
675 
676  if (preview.zoomlevel == 1)
677  ratio += (1.0 - ratio) / 2;
678  }
679  preview.zoomratio = ratio;
680  }
681 
682  preview.bmScaledSize.cx = preview.bmSize.cx * preview.zoomratio;
683  preview.bmScaledSize.cy = preview.bmSize.cy * preview.zoomratio;
684 
685  preview.spacing.cy = max(min_spacing, (window.bottom - preview.bmScaledSize.cy) / 2);
686 
687  preview.spacing.cx = (window.right -
688  preview.bmScaledSize.cx * preview.pages_shown) /
689  (preview.pages_shown + 1);
690  if (preview.spacing.cx < min_spacing)
691  preview.spacing.cx = min_spacing;
692 
693  update_preview_scrollbars(hwndPreview, &window);
694 }
695 
696 static void draw_margin_lines(HDC hdc, int x, int y, float ratio)
697 {
698  HPEN hPen, oldPen;
699  SIZE dpi;
700  RECT page_margin = preview.rcPage;
701 
702  dpi.cx = GetDeviceCaps(hdc, LOGPIXELSX);
703  dpi.cy = GetDeviceCaps(hdc, LOGPIXELSY);
704 
705  SetRect(&page_margin, preview.rcPage.left + margins.left, preview.rcPage.top + margins.top,
706  preview.rcPage.right - margins.right, preview.rcPage.bottom - margins.bottom);
707 
708  page_margin.left = (int)((float)twips_to_pixels(page_margin.left, dpi.cx) * ratio);
709  page_margin.top = (int)((float)twips_to_pixels(page_margin.top, dpi.cy) * ratio);
710  page_margin.bottom = (int)((float)twips_to_pixels(page_margin.bottom, dpi.cy) * ratio);
711  page_margin.right = (int)((float)twips_to_pixels(page_margin.right, dpi.cx) * ratio);
712 
713  OffsetRect(&page_margin, x, y);
714 
715  hPen = CreatePen(PS_DOT, 1, RGB(0,0,0));
716  oldPen = SelectObject(hdc, hPen);
717 
718  MoveToEx(hdc, x, page_margin.top, NULL);
719  LineTo(hdc, x + preview.bmScaledSize.cx, page_margin.top);
720  MoveToEx(hdc, x, page_margin.bottom, NULL);
721  LineTo(hdc, x + preview.bmScaledSize.cx, page_margin.bottom);
722 
723  MoveToEx(hdc, page_margin.left, y, NULL);
724  LineTo(hdc, page_margin.left, y + preview.bmScaledSize.cy);
725  MoveToEx(hdc, page_margin.right, y, NULL);
726  LineTo(hdc, page_margin.right, y + preview.bmScaledSize.cy);
727 
728  SelectObject(hdc, oldPen);
729  DeleteObject(hPen);
730 }
731 
733 {
734  return preview.pageEnds[page - 1] >= preview.textlength;
735 }
736 
738 {
740  preview.page = 1;
741  preview.hdc = 0;
742  preview.hdc2 = 0;
743  preview.wszFileName = wszFileName;
744  preview.zoomratio = 0;
745  preview.zoomlevel = 0;
746  preview_bar_show(hMainWnd, TRUE);
747 
750  0, 0, 200, 10, hMainWnd, (HMENU)IDC_PREVIEW, hInstance, NULL);
751 }
752 
754 {
755  HWND hwndPreview = GetDlgItem(hMainWnd, IDC_PREVIEW);
756  preview.window.right = 0;
757  preview.window.bottom = 0;
758  preview.page = 0;
759  HeapFree(GetProcessHeap(), 0, preview.pageEnds);
760  preview.pageEnds = NULL;
761  preview.pageCapacity = 0;
762  if (preview.zoomlevel > 0)
763  preview.pages_shown = preview.saved_pages_shown;
764  if(preview.hdc) {
765  HBITMAP oldbm = GetCurrentObject(preview.hdc, OBJ_BITMAP);
766  DeleteDC(preview.hdc);
767  DeleteObject(oldbm);
768  preview.hdc = NULL;
769  }
770  if(preview.hdc2) {
771  HBITMAP oldbm = GetCurrentObject(preview.hdc2, OBJ_BITMAP);
772  DeleteDC(preview.hdc2);
773  DeleteObject(oldbm);
774  preview.hdc2 = NULL;
775  }
776 
777  preview_bar_show(hMainWnd, FALSE);
778  DestroyWindow(hwndPreview);
779 }
780 
782 {
783  return preview.page != 0;
784 }
785 
786 static void draw_preview(HWND hEditorWnd, FORMATRANGE* lpFr, RECT* paper, int page)
787 {
788  int bottom;
789 
790  if (!preview.pageEnds)
791  {
792  preview.pageCapacity = 32;
793  preview.pageEnds = HeapAlloc(GetProcessHeap(), 0,
794  sizeof(int) * preview.pageCapacity);
795  if (!preview.pageEnds) return;
796  } else if (page >= preview.pageCapacity) {
797  int *new_buffer;
798  new_buffer = HeapReAlloc(GetProcessHeap(), 0, preview.pageEnds,
799  sizeof(int) * preview.pageCapacity * 2);
800  if (!new_buffer) return;
801  preview.pageCapacity *= 2;
802  preview.pageEnds = new_buffer;
803  }
804 
805  FillRect(lpFr->hdc, paper, GetStockObject(WHITE_BRUSH));
806  if (page > 1 && is_last_preview_page(page - 1)) return;
807  lpFr->chrg.cpMin = page <= 1 ? 0 : preview.pageEnds[page-2];
808  bottom = lpFr->rc.bottom;
809  preview.pageEnds[page-1] = SendMessageW(hEditorWnd, EM_FORMATRANGE, TRUE, (LPARAM)lpFr);
810 
811  /* EM_FORMATRANGE sets fr.rc.bottom to indicate the area printed in,
812  * but we want to keep the original for drawing margins */
813  lpFr->rc.bottom = bottom;
814  SendMessageW(hEditorWnd, EM_FORMATRANGE, FALSE, 0);
815 }
816 
818 {
819  HWND hReBar = GetDlgItem(hMainWnd, IDC_REBAR);
820  EnableWindow(GetDlgItem(hReBar, ID_PREVIEW_PREVPAGE), preview.page > 1);
822  !is_last_preview_page(preview.page) &&
823  !is_last_preview_page(preview.page + preview.pages_shown - 1));
825  preview.pages_shown > 1 ||
826  (!is_last_preview_page(1) && preview.zoomlevel == 0));
827  EnableWindow(GetDlgItem(hReBar, ID_PREVIEW_ZOOMIN), preview.zoomlevel < 2);
828  EnableWindow(GetDlgItem(hReBar, ID_PREVIEW_ZOOMOUT), preview.zoomlevel > 0);
829 }
830 
831 static LRESULT print_preview(HWND hwndPreview)
832 {
833  HPEN hPen, oldPen;
834  HDC hdc;
835  HRGN back_rgn, excl_rgn;
836  RECT window, background;
837  PAINTSTRUCT ps;
838  int x, y;
839 
840  hdc = BeginPaint(hwndPreview, &ps);
841  GetClientRect(hwndPreview, &window);
842  back_rgn = CreateRectRgnIndirect(&window);
843 
844  x = preview.spacing.cx - GetScrollPos(hwndPreview, SB_HORZ);
845  y = preview.spacing.cy - GetScrollPos(hwndPreview, SB_VERT);
846 
847  /* draw page outlines */
848  hPen = CreatePen(PS_SOLID|PS_INSIDEFRAME, 2, RGB(0,0,0));
849  oldPen = SelectObject(hdc, hPen);
850  SetRect(&background, x - 2, y - 2, x + preview.bmScaledSize.cx + 2,
851  y + preview.bmScaledSize.cy + 2);
852  Rectangle(hdc, background.left, background.top,
853  background.right, background.bottom);
854  excl_rgn = CreateRectRgnIndirect(&background);
855  CombineRgn(back_rgn, back_rgn, excl_rgn, RGN_DIFF);
856  if(preview.pages_shown > 1)
857  {
858  background.left += preview.bmScaledSize.cx + preview.spacing.cx;
859  background.right += preview.bmScaledSize.cx + preview.spacing.cx;
860  Rectangle(hdc, background.left, background.top,
861  background.right, background.bottom);
862  SetRectRgn(excl_rgn, background.left, background.top,
863  background.right, background.bottom);
864  CombineRgn(back_rgn, back_rgn, excl_rgn, RGN_DIFF);
865  }
866  SelectObject(hdc, oldPen);
867  DeleteObject(hPen);
868  FillRgn(hdc, back_rgn, GetStockObject(GRAY_BRUSH));
869  DeleteObject(excl_rgn);
870  DeleteObject(back_rgn);
871 
872  StretchBlt(hdc, x, y, preview.bmScaledSize.cx, preview.bmScaledSize.cy,
873  preview.hdc, 0, 0, preview.bmSize.cx, preview.bmSize.cy, SRCCOPY);
874 
875  draw_margin_lines(hdc, x, y, preview.zoomratio);
876 
877  if(preview.pages_shown > 1)
878  {
879  if (!is_last_preview_page(preview.page)) {
880  x += preview.spacing.cx + preview.bmScaledSize.cx;
881  StretchBlt(hdc, x, y,
882  preview.bmScaledSize.cx, preview.bmScaledSize.cy,
883  preview.hdc2, 0, 0,
884  preview.bmSize.cx, preview.bmSize.cy, SRCCOPY);
885 
886  draw_margin_lines(hdc, x, y, preview.zoomratio);
887  } else {
888  InflateRect(&background, -2, -2);
889  FillRect(hdc, &background, GetStockObject(WHITE_BRUSH));
890  }
891  }
892 
893  preview.window = window;
894 
895  EndPaint(hwndPreview, &ps);
896 
897  return 0;
898 }
899 
901 {
902  HWND hStatusbar = GetDlgItem(hMainWnd, IDC_STATUSBAR);
904  WCHAR *p;
905  WCHAR wstr[MAX_STRING_LEN];
906 
907  p = wstr;
908  if (preview.pages_shown < 2 || is_last_preview_page(preview.page))
909  {
910  static const WCHAR fmt[] = {' ','%','d','\0'};
911  p += LoadStringW(hInst, STRING_PREVIEW_PAGE, wstr, MAX_STRING_LEN);
912  wsprintfW(p, fmt, preview.page);
913  } else {
914  static const WCHAR fmt[] = {' ','%','d','-','%','d','\0'};
915  p += LoadStringW(hInst, STRING_PREVIEW_PAGES, wstr, MAX_STRING_LEN);
916  wsprintfW(p, fmt, preview.page, preview.page + 1);
917  }
918  SetWindowTextW(hStatusbar, wstr);
919 }
920 
921 /* Update for page changes. */
923 {
924  RECT paper;
925  HWND hEditorWnd = GetDlgItem(hMainWnd, IDC_EDITOR);
926  HWND hwndPreview = GetDlgItem(hMainWnd, IDC_PREVIEW);
927  HBITMAP hBitmapCapture;
928  FORMATRANGE fr;
929  HDC hdc = GetDC(hwndPreview);
930 
931  fr.hdcTarget = make_dc();
932  fr.rc = fr.rcPage = preview.rcPage;
933  fr.rc.left += margins.left;
934  fr.rc.top += margins.top;
935  fr.rc.bottom -= margins.bottom;
936  fr.rc.right -= margins.right;
937 
938  fr.chrg.cpMin = 0;
939  fr.chrg.cpMax = preview.textlength;
940 
941  SetRect(&paper, 0, 0, preview.bmSize.cx, preview.bmSize.cy);
942 
943  if (!preview.hdc) {
944  preview.hdc = CreateCompatibleDC(hdc);
945  hBitmapCapture = CreateCompatibleBitmap(hdc, preview.bmSize.cx, preview.bmSize.cy);
946  SelectObject(preview.hdc, hBitmapCapture);
947  }
948 
949  fr.hdc = preview.hdc;
950  draw_preview(hEditorWnd, &fr, &paper, preview.page);
951 
952  if(preview.pages_shown > 1)
953  {
954  if (!preview.hdc2)
955  {
956  preview.hdc2 = CreateCompatibleDC(hdc);
957  hBitmapCapture = CreateCompatibleBitmap(hdc,
958  preview.bmSize.cx,
959  preview.bmSize.cy);
960  SelectObject(preview.hdc2, hBitmapCapture);
961  }
962 
963  fr.hdc = preview.hdc2;
964  draw_preview(hEditorWnd, &fr, &fr.rcPage, preview.page + 1);
965  }
966  DeleteDC(fr.hdcTarget);
967  ReleaseDC(hwndPreview, hdc);
968 
969  InvalidateRect(hwndPreview, NULL, FALSE);
970  update_preview_buttons(hMainWnd);
971  update_preview_statusbar(hMainWnd);
972 }
973 
975 {
976  HWND hReBar = GetDlgItem(hMainWnd, IDC_REBAR);
979  int nPreviewPages;
980 
981  preview.pages_shown = preview.pages_shown > 1 ? 1 : 2;
982 
983  nPreviewPages = preview.zoomlevel > 0 ? preview.saved_pages_shown :
984  preview.pages_shown;
985 
986  LoadStringW(hInst, nPreviewPages > 1 ? STRING_PREVIEW_ONEPAGE :
988  name, MAX_STRING_LEN);
989 
992  update_preview(hMainWnd);
993 }
994 
995 /* Returns the page shown that the point is in (1 or 2) or 0 if the point
996  * isn't inside either page */
998 {
999  RECT rc;
1000  rc.left = preview.spacing.cx;
1001  rc.right = rc.left + preview.bmScaledSize.cx;
1002  rc.top = preview.spacing.cy;
1003  rc.bottom = rc.top + preview.bmScaledSize.cy;
1004  if (PtInRect(&rc, pt))
1005  return 1;
1006 
1007  if (preview.pages_shown <= 1)
1008  return 0;
1009 
1010  rc.left += preview.bmScaledSize.cx + preview.spacing.cx;
1011  rc.right += preview.bmScaledSize.cx + preview.spacing.cx;
1012  if (PtInRect(&rc, pt))
1013  return is_last_preview_page(preview.page) ? 1 : 2;
1014 
1015  return 0;
1016 }
1017 
1019 {
1020  switch(msg)
1021  {
1022  case WM_CREATE:
1023  {
1024  HWND hMainWnd = GetParent(hWnd);
1025  HWND hEditorWnd = GetDlgItem(hMainWnd, IDC_EDITOR);
1026  FORMATRANGE fr;
1027  GETTEXTLENGTHEX gt = {GTL_DEFAULT, 1200};
1028  HDC hdc = GetDC(hWnd);
1029  HDC hdcTarget = make_dc();
1030 
1031  fr.rc = preview.rcPage = get_print_rect(hdcTarget);
1032  preview.rcPage.bottom += margins.bottom;
1033  preview.rcPage.right += margins.right;
1034  preview.rcPage.top = preview.rcPage.left = 0;
1035  fr.rcPage = preview.rcPage;
1036 
1037  preview.bmSize.cx = twips_to_pixels(preview.rcPage.right, GetDeviceCaps(hdc, LOGPIXELSX));
1038  preview.bmSize.cy = twips_to_pixels(preview.rcPage.bottom, GetDeviceCaps(hdc, LOGPIXELSY));
1039 
1040  preview.textlength = SendMessageW(hEditorWnd, EM_GETTEXTLENGTHEX, (WPARAM)&gt, 0);
1041 
1042  fr.hdc = CreateCompatibleDC(hdc);
1043  fr.hdcTarget = hdcTarget;
1044  fr.chrg.cpMin = 0;
1045  fr.chrg.cpMax = preview.textlength;
1046  DeleteDC(fr.hdc);
1047  DeleteDC(hdcTarget);
1048  ReleaseDC(hWnd, hdc);
1049 
1050  update_preview_sizes(hWnd, TRUE);
1051  update_preview(hMainWnd);
1052  break;
1053  }
1054 
1055  case WM_PAINT:
1056  return print_preview(hWnd);
1057 
1058  case WM_SIZE:
1059  {
1060  update_preview_sizes(hWnd, FALSE);
1061  InvalidateRect(hWnd, NULL, FALSE);
1062  break;
1063  }
1064 
1065  case WM_VSCROLL:
1066  case WM_HSCROLL:
1067  {
1068  SCROLLINFO si;
1069  RECT rc;
1070  int nBar = (msg == WM_VSCROLL) ? SB_VERT : SB_HORZ;
1071  int origPos;
1072 
1073  GetClientRect(hWnd, &rc);
1074  si.cbSize = sizeof(si);
1075  si.fMask = SIF_ALL;
1076  GetScrollInfo(hWnd, nBar, &si);
1077  origPos = si.nPos;
1078  switch(LOWORD(wParam))
1079  {
1080  case SB_TOP: /* == SB_LEFT */
1081  si.nPos = si.nMin;
1082  break;
1083  case SB_BOTTOM: /* == SB_RIGHT */
1084  si.nPos = si.nMax;
1085  break;
1086  case SB_LINEUP: /* == SB_LINELEFT */
1087  si.nPos -= si.nPage / 10;
1088  break;
1089  case SB_LINEDOWN: /* == SB_LINERIGHT */
1090  si.nPos += si.nPage / 10;
1091  break;
1092  case SB_PAGEUP: /* == SB_PAGELEFT */
1093  si.nPos -= si.nPage;
1094  break;
1095  case SB_PAGEDOWN: /* SB_PAGERIGHT */
1096  si.nPos += si.nPage;
1097  break;
1098  case SB_THUMBTRACK:
1099  si.nPos = si.nTrackPos;
1100  break;
1101  }
1102  si.fMask = SIF_POS;
1103  SetScrollInfo(hWnd, nBar, &si, TRUE);
1104  GetScrollInfo(hWnd, nBar, &si);
1105  if (si.nPos != origPos)
1106  {
1107  int amount = origPos - si.nPos;
1108  if (msg == WM_VSCROLL)
1109  ScrollWindow(hWnd, 0, amount, NULL, NULL);
1110  else
1111  ScrollWindow(hWnd, amount, 0, NULL, NULL);
1112  }
1113  return 0;
1114  }
1115 
1116  case WM_SETCURSOR:
1117  {
1118  POINT pt;
1119  RECT rc;
1120  int bHittest = 0;
1121  DWORD messagePos = GetMessagePos();
1122  pt.x = (short)LOWORD(messagePos);
1123  pt.y = (short)HIWORD(messagePos);
1124  ScreenToClient(hWnd, &pt);
1125 
1126  GetClientRect(hWnd, &rc);
1127  if (PtInRect(&rc, pt))
1128  {
1129  pt.x += GetScrollPos(hWnd, SB_HORZ);
1130  pt.y += GetScrollPos(hWnd, SB_VERT);
1131  bHittest = preview_page_hittest(pt);
1132  }
1133 
1134  if (bHittest)
1137  else
1139 
1140  return TRUE;
1141  }
1142 
1143  case WM_LBUTTONDOWN:
1144  {
1145  int page;
1146  POINT pt;
1147  pt.x = (short)LOWORD(lParam) + GetScrollPos(hWnd, SB_HORZ);
1148  pt.y = (short)HIWORD(lParam) + GetScrollPos(hWnd, SB_VERT);
1149  if ((page = preview_page_hittest(pt)) > 0)
1150  {
1151  HWND hMainWnd = GetParent(hWnd);
1152 
1153  /* Convert point from client coordinate to unzoomed page
1154  * coordinate. */
1155  pt.x -= preview.spacing.cx;
1156  if (page > 1)
1157  pt.x -= preview.bmScaledSize.cx + preview.spacing.cx;
1158  pt.y -= preview.spacing.cy;
1159  pt.x /= preview.zoomratio;
1160  pt.y /= preview.zoomratio;
1161 
1162  if (preview.zoomlevel == 0)
1163  preview.saved_pages_shown = preview.pages_shown;
1164  preview.zoomlevel = (preview.zoomlevel + 1) % 3;
1165  preview.zoomratio = 0;
1166  if (preview.zoomlevel == 0 && preview.saved_pages_shown > 1)
1167  {
1168  toggle_num_pages(hMainWnd);
1169  } else if (preview.pages_shown > 1) {
1170  if (page >= 2) preview.page++;
1171  toggle_num_pages(hMainWnd);
1172  } else {
1173  update_preview_sizes(hWnd, TRUE);
1174  InvalidateRect(hWnd, NULL, FALSE);
1175  update_preview_buttons(hMainWnd);
1176  }
1177 
1178  if (preview.zoomlevel > 0) {
1179  SCROLLINFO si;
1180  /* Convert the coordinate back to client coordinate. */
1181  pt.x *= preview.zoomratio;
1182  pt.y *= preview.zoomratio;
1183  pt.x += preview.spacing.cx;
1184  pt.y += preview.spacing.cy;
1185  /* Scroll to center view at that point on the page */
1186  si.cbSize = sizeof(si);
1187  si.fMask = SIF_PAGE;
1188  GetScrollInfo(hWnd, SB_HORZ, &si);
1189  pt.x -= si.nPage / 2;
1190  SetScrollPos(hWnd, SB_HORZ, pt.x, TRUE);
1191  GetScrollInfo(hWnd, SB_VERT, &si);
1192  pt.y -= si.nPage / 2;
1193  SetScrollPos(hWnd, SB_VERT, pt.y, TRUE);
1194  }
1195  }
1196  }
1197 
1198  default:
1199  return DefWindowProcW(hWnd, msg, wParam, lParam);
1200  }
1201 
1202  return 0;
1203 }
1204 
1206 {
1207  switch(LOWORD(wParam))
1208  {
1209  case ID_FILE_EXIT:
1210  PostMessageW(hWnd, WM_CLOSE, 0, 0);
1211  break;
1212 
1213  case ID_PREVIEW_NEXTPAGE:
1214  case ID_PREVIEW_PREVPAGE:
1215  {
1216  if(LOWORD(wParam) == ID_PREVIEW_NEXTPAGE)
1217  preview.page++;
1218  else
1219  preview.page--;
1220 
1221  update_preview(hWnd);
1222  }
1223  break;
1224 
1225  case ID_PREVIEW_NUMPAGES:
1226  toggle_num_pages(hWnd);
1227  break;
1228 
1229  case ID_PREVIEW_ZOOMIN:
1230  if (preview.zoomlevel < 2)
1231  {
1232  if (preview.zoomlevel == 0)
1233  preview.saved_pages_shown = preview.pages_shown;
1234  preview.zoomlevel++;
1235  preview.zoomratio = 0;
1236  if (preview.pages_shown > 1)
1237  {
1238  /* Forced switch to one page when zooming in. */
1239  toggle_num_pages(hWnd);
1240  } else {
1241  HWND hwndPreview = GetDlgItem(hWnd, IDC_PREVIEW);
1242  update_preview_sizes(hwndPreview, TRUE);
1243  InvalidateRect(hwndPreview, NULL, FALSE);
1244  update_preview_buttons(hWnd);
1245  }
1246  }
1247  break;
1248 
1249  case ID_PREVIEW_ZOOMOUT:
1250  if (preview.zoomlevel > 0)
1251  {
1252  HWND hwndPreview = GetDlgItem(hWnd, IDC_PREVIEW);
1253  preview.zoomlevel--;
1254  preview.zoomratio = 0;
1255  if (preview.zoomlevel == 0 && preview.saved_pages_shown > 1) {
1256  toggle_num_pages(hWnd);
1257  } else {
1258  update_preview_sizes(hwndPreview, TRUE);
1259  InvalidateRect(hwndPreview, NULL, FALSE);
1260  update_preview_buttons(hWnd);
1261  }
1262  }
1263  break;
1264 
1265  case ID_PRINT:
1266  dialog_print(hWnd, preview.wszFileName);
1267  SendMessageW(hWnd, WM_CLOSE, 0, 0);
1268  break;
1269  }
1270 
1271  return 0;
1272 }
HGDIOBJ WINAPI GetStockObject(_In_ int)
int WINAPIV wsprintfW(_Out_ LPWSTR, _In_ _Printf_format_string_ LPCWSTR,...)
static void char_from_pagenum(HWND hEditorWnd, FORMATRANGE *fr, int page)
Definition: print.c:269
void redraw_ruler(HWND hRulerWnd)
Definition: print.c:288
int WINAPI CombineRgn(_In_opt_ HRGN hrgnDest, _In_opt_ HRGN hrgnSrc1, _In_opt_ HRGN hrgnSrc2, _In_ int fnCombineMode)
#define GTL_DEFAULT
Definition: richedit.h:1054
#define ID_WORDWRAP_MARGIN
Definition: wordpad.h:112
HDC hdc2
Definition: print.c:41
#define HDC
Definition: msvc.h:22
#define CENTMM_PER_INCH
Definition: wordpad.h:25
#define SB_PAGEDOWN
Definition: winuser.h:569
struct _previewinfo * ppreviewinfo
GLint GLint GLsizei width
Definition: gl.h:1546
static void preview_bar_show(HWND hMainWnd, BOOL show)
Definition: print.c:580
DWORD Flags
Definition: commdlg.h:373
#define ULongToHandle(h)
Definition: basetsd.h:81
#define IDC_ZOOM
Definition: resource.h:16
#define SB_PAGEUP
Definition: winuser.h:568
#define max(a, b)
Definition: svc.c:63
#define LOGPIXELSX
Definition: wingdi.h:716
BOOL WINAPI InflateRect(_Inout_ LPRECT, _In_ int, _In_ int)
#define PD_NOSELECTION
Definition: commdlg.h:149
#define TRUE
Definition: types.h:120
HPEN WINAPI CreatePen(_In_ int, _In_ int, _In_ COLORREF)
HFONT WINAPI CreateFontW(_In_ int, _In_ int, _In_ int, _In_ int, _In_ int, _In_ DWORD, _In_ DWORD, _In_ DWORD, _In_ DWORD, _In_ DWORD, _In_ DWORD, _In_ DWORD, _In_ DWORD, _In_opt_ LPCWSTR)
static void draw_preview(HWND hEditorWnd, FORMATRANGE *lpFr, RECT *paper, int page)
Definition: print.c:786
LPCWSTR lpstrFilter
Definition: commdlg.h:363
int WINAPI FillRgn(_In_ HDC, _In_ HRGN, _In_ HBRUSH)
Definition: painting.c:173
#define IDC_STATUSBAR
Definition: resource.h:14
#define RBBIM_CHILD
Definition: commctrl.h:1476
#define ID_WORDWRAP_NONE
Definition: wordpad.h:110
static LONG twips_to_centmm(int twips)
Definition: print.c:166
#define SIF_RANGE
Definition: winuser.h:1221
HWND hwndOwner
Definition: commdlg.h:487
#define HBITMAP
Definition: msvc.h:28
void dialog_print(HWND hMainWnd, LPWSTR wszFileName)
Definition: print.c:551
long y
Definition: polytest.cpp:48
#define ERROR_SUCCESS
Definition: deptool.c:10
#define BANDID_PREVIEW_BTN7
Definition: wordpad.h:107
#define WM_LBUTTONDOWN
Definition: winuser.h:1752
#define PSD_INHUNDREDTHSOFMILLIMETERS
Definition: commdlg.h:175
static RECT get_print_rect(HDC hdc)
Definition: print.c:187
BOOL WINAPI OffsetRect(_Inout_ LPRECT, _In_ int, _In_ int)
#define STRING_PREVIEW_PREVPAGE
Definition: wordpad.h:220
long x
Definition: polytest.cpp:48
BOOL WINAPI Rectangle(_In_ HDC, _In_ int, _In_ int, _In_ int, _In_ int)
HDC WINAPI GetDC(_In_opt_ HWND)
HBITMAP WINAPI CreateCompatibleBitmap(_In_ HDC hdc, _In_ INT cx, _In_ INT cy)
#define SB_VERT
Definition: winuser.h:553
#define REG_BINARY
Definition: nt_native.h:1496
static HGLOBAL devMode
Definition: print.c:52
#define pt(x, y)
Definition: drawing.c:79
__wchar_t WCHAR
Definition: xmlstorage.h:180
void dialog_printsetup(HWND hMainWnd)
Definition: print.c:500
#define DWORD
Definition: msvc.h:34
#define PSD_MARGINS
Definition: commdlg.h:173
const WCHAR * text
Definition: package.c:1827
#define BANDID_PREVIEW_BTN3
Definition: wordpad.h:103
SIZE bmSize
Definition: print.c:44
#define STRING_PRINTER_FILES_PRN
Definition: wordpad.h:208
RECT rcPage
Definition: print.c:43
RECT rcPage
Definition: richedit.h:610
#define SB_HORZ
Definition: winuser.h:552
int * pageEnds
Definition: print.c:38
static DWORD wordWrap[2]
Definition: wordpad.c:66
LPWSTR lpstrFile
Definition: commdlg.h:367
#define HRGN
Definition: msvc.h:39
HRGN WINAPI CreateRectRgnIndirect(_In_ LPCRECT)
static LONG devunits_to_twips(int units, int dpi)
Definition: print.c:181
#define CALLBACK
Definition: compat.h:27
HWND hWnd
Definition: settings.c:17
LONG top
Definition: windef.h:297
#define STRING_PREVIEW_PAGE
Definition: wordpad.h:226
OPENFILENAME ofn
Definition: main.cpp:37
#define RBBIM_ID
Definition: commctrl.h:1480
HGDIOBJ WINAPI SelectObject(_In_ HDC, _In_ HGDIOBJ)
Definition: dc.c:1497
#define ZeroMemory
Definition: winbase.h:1635
BOOL WINAPI DeleteObject(_In_ HGDIOBJ)
LONG cpMax
Definition: richedit.h:501
BOOL WINAPI LineTo(_In_ HDC, _In_ int, _In_ int)
#define EM_FORMATRANGE
Definition: richedit.h:90
#define WHITE_BRUSH
Definition: wingdi.h:900
#define MAX_STRING_LEN
Definition: precomp.h:36
#define STRING_PREVIEW_PAGES
Definition: wordpad.h:227
HDC WINAPI CreateCompatibleDC(_In_opt_ HDC hdc)
int zoomlevel
Definition: print.c:48
static HWND hEditorWnd
Definition: wordpad.c:60
BOOL WINAPI SetWindowTextW(_In_ HWND, _In_opt_ LPCWSTR)
void close_preview(HWND hMainWnd)
Definition: print.c:753
#define WS_CHILD
Definition: pedump.c:617
DWORD WINAPI GetMessagePos(void)
Definition: message.c:1326
LONG left
Definition: windef.h:296
DWORD Flags
Definition: commdlg.h:491
BOOL WINAPI EndPaint(_In_ HWND, _In_ const PAINTSTRUCT *)
UINT WINAPI SetTextAlign(_In_ HDC, _In_ UINT)
Definition: text.c:749
LONG right
Definition: windef.h:298
RECT rtMargin
Definition: commdlg.h:456
#define lstrlenW
Definition: compat.h:407
BOOL WINAPI DestroyWindow(_In_ HWND)
static VOID NTAPI BitBlt(IN ULONG Left, IN ULONG Top, IN ULONG Width, IN ULONG Height, IN PUCHAR Buffer, IN ULONG BitsPerPixel, IN ULONG Delta)
Definition: vga.c:416
int WINAPI LoadStringW(_In_opt_ HINSTANCE hInstance, _In_ UINT uID, _Out_writes_to_(cchBufferMax, return+1) LPWSTR lpBuffer, _In_ int cchBufferMax)
#define CreateWindowW(a, b, c, d, e, f, g, h, i, j, k)
Definition: winuser.h:4185
#define SIF_PAGE
Definition: winuser.h:1219
DWORD WINAPI GetSysColor(_In_ int)
BOOL WINAPI StretchBlt(_In_ HDC, _In_ int, _In_ int, _In_ int, _In_ int, _In_opt_ HDC, _In_ int, _In_ int, _In_ int, _In_ int, _In_ DWORD)
WPARAM wParam
Definition: combotst.c:138
HFONT hFont
Definition: main.c:53
int WINAPI EndPage(_In_ HDC)
GLint GLint GLsizei GLsizei GLsizei GLint GLenum format
Definition: gl.h:1546
BOOL WINAPI GetSaveFileNameW(LPOPENFILENAMEW ofn)
Definition: filedlg.c:4286
HGLOBAL hDevNames
Definition: commdlg.h:452
LPCWSTR lpszOutput
Definition: wingdi.h:1662
LRESULT WINAPI DefWindowProcW(_In_ HWND, _In_ UINT, _In_ WPARAM, _In_ LPARAM)
DWORD lStructSize
Definition: commdlg.h:360
#define BANDID_PREVIEW_BTN1
Definition: wordpad.h:101
UINT_PTR WPARAM
Definition: windef.h:207
HANDLE hDevNames
Definition: commdlg.h:489
BOOL WINAPI ScrollWindow(_In_ HWND, _In_ int, _In_ int, _In_opt_ LPCRECT, _In_opt_ LPCRECT)
struct tagRECT RECT
#define EM_GETSEL
Definition: winuser.h:1958
int WINAPI StartPage(_In_ HDC)
INT INT y
Definition: msvc.h:62
#define EM_EXGETSEL
Definition: richedit.h:85
#define REBARBANDINFOW_V6_SIZE
Definition: commctrl.h:1512
#define PHYSICALHEIGHT
Definition: wingdi.h:734
BOOL WINAPI MoveToEx(_In_ HDC, _In_ int, _In_ int, _Out_opt_ LPPOINT)
#define STRING_PREVIEW_ONEPAGE
Definition: wordpad.h:222
#define RBBIM_STYLE
Definition: commctrl.h:1472
#define BF_RECT
Definition: winuser.h:462
unsigned short(__cdecl typeof(TIFFCurrentDirectory))(struct tiff *)
Definition: typeof.h:91
#define PS_SOLID
Definition: wingdi.h:584
#define RBBIM_SIZE
Definition: commctrl.h:1478
int WINAPI SetBkMode(_In_ HDC, _In_ int)
Definition: dc.c:1032
GLenum GLclampf GLint i
Definition: glfuncs.h:14
HINSTANCE hInstance
Definition: charmap.c:20
LPCWSTR lpstrDefExt
Definition: commdlg.h:376
static void AddTextButton(HWND hRebarWnd, UINT string, UINT command, UINT id)
Definition: print.c:121
#define PD_USEDEVMODECOPIESANDCOLLATE
Definition: commdlg.h:166
static BOOL is_last_preview_page(int page)
Definition: print.c:732
unsigned char * LPBYTE
Definition: typedefs.h:52
#define BANDID_PREVIEW_BUFFER
Definition: wordpad.h:108
float zoomratio
Definition: print.c:47
HDC hDC
Definition: commdlg.h:490
long LONG
Definition: pedump.c:60
static const int min_spacing
Definition: print.c:621
LONG_PTR LPARAM
Definition: windef.h:208
void registry_set_previewpages(HKEY hKey)
Definition: print.c:99
#define WM_SETCURSOR
Definition: winuser.h:1618
#define ID_FILE_EXIT
Definition: resource.h:47
HDC WINAPI BeginPaint(_In_ HWND, _Out_ LPPAINTSTRUCT)
BOOL WINAPI DrawEdge(_In_ HDC, _Inout_ LPRECT, _In_ UINT, _In_ UINT)
static void draw_margin_lines(HDC hdc, int x, int y, float ratio)
Definition: print.c:696
int textlength
Definition: print.c:39
static void add_ruler_units(HDC hdcRuler, RECT *drawRect, BOOL NewMetrics, LONG EditLeftmost)
Definition: print.c:302
int WINAPI ReleaseDC(_In_opt_ HWND, _In_ HDC)
WORD nMinPage
Definition: commdlg.h:494
DWORD lStructSize
Definition: commdlg.h:449
WORD wDeviceOffset
Definition: commdlg.h:298
#define TRANSPARENT
Definition: wingdi.h:948
#define IDC_RULER
Definition: wordpad.h:170
BOOL WINAPI PrintDlgW(LPPRINTDLGW lppd)
Definition: printdlg.c:2391
HDC hdc
Definition: msvc.h:53
const WCHAR * str
LRESULT CALLBACK ruler_proc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam)
Definition: print.c:412
UINT msg
Definition: msvc.h:92
static LPWSTR dialog_print_to_file(HWND hMainWnd)
Definition: print.c:243
smooth NULL
Definition: ftsmooth.c:416
const WCHAR wszPreviewWndClass[]
Definition: wordpad.c:56
#define COLOR_MENU
Definition: winuser.h:907
WORD wDriverOffset
Definition: commdlg.h:297
LONG cx
Definition: windef.h:324
#define PD_SELECTION
Definition: commdlg.h:147
BOOL preview_isactive(void)
Definition: print.c:781
GLint GLint bottom
Definition: glext.h:7726
#define PD_RETURNDC
Definition: commdlg.h:155
Definition: module.h:566
#define RB_INSERTBANDW
Definition: commctrl.h:1553
#define ID_PREVIEW_NUMPAGES
Definition: wordpad.h:50
#define GRAY_BRUSH
Definition: wingdi.h:896
int cbSize
Definition: wingdi.h:1660
#define RBBS_VARIABLEHEIGHT
Definition: commctrl.h:1465
#define STRING_ALL_FILES
Definition: notepad_res.h:79
DWORD lStructSize
Definition: commdlg.h:486
static HGLOBAL devNames
Definition: print.c:53
#define OFN_PATHMUSTEXIST
Definition: commdlg.h:117
static void update_preview(HWND hMainWnd)
Definition: print.c:922
#define BLACK_BRUSH
Definition: wingdi.h:894
#define BANDID_PREVIEW_BTN4
Definition: wordpad.h:104
HDC hdcTarget
Definition: richedit.h:608
static LONG centmm_to_twips(int mm)
Definition: print.c:171
BOOL WINAPI SetRectRgn(_In_ HRGN, _In_ int, _In_ int, _In_ int, _In_ int)
LONG WINAPI RegSetValueExW(_In_ HKEY hKey, _In_ LPCWSTR lpValueName, _In_ DWORD Reserved, _In_ DWORD dwType, _In_ CONST BYTE *lpData, _In_ DWORD cbData)
Definition: reg.c:4917
BOOL WINAPI PageSetupDlgW(LPPAGESETUPDLGW setupdlg)
Definition: printdlg.c:3926
static void update_ruler(HWND hRulerWnd)
Definition: print.c:296
#define dpi
Definition: sysparams.c:22
HWND hwndOwner
Definition: commdlg.h:450
#define EM_SETTARGETDEVICE
Definition: richedit.h:105
int pages_shown
Definition: print.c:36
unsigned int BOOL
Definition: ntddk_ex.h:94
GLsizeiptr size
Definition: glext.h:5919
#define GetProcessHeap()
Definition: compat.h:395
PVOID WINAPI HeapAlloc(HANDLE, DWORD, SIZE_T)
#define IDC_EDITOR
Definition: wordpad.h:156
int WINAPI StartDocW(_In_ HDC, _In_ const DOCINFOW *)
LONG WINAPI RegQueryValueExW(_In_ HKEY hkeyorg, _In_ LPCWSTR name, _In_ LPDWORD reserved, _In_ LPDWORD type, _In_ LPBYTE data, _In_ LPDWORD count)
Definition: reg.c:4134
#define STRING_PREVIEW_CLOSE
Definition: wordpad.h:225
HWND WINAPI GetDlgItem(_In_opt_ HWND, _In_ int)
int page
Definition: print.c:35
WORD nToPage
Definition: commdlg.h:493
#define SB_THUMBTRACK
Definition: winuser.h:573
#define WM_SIZE
Definition: winuser.h:1593
void registry_read_previewpages(HKEY hKey)
Definition: print.c:105
static const WCHAR var_previewpages[]
Definition: print.c:61
#define WM_CLOSE
Definition: winuser.h:1603
int WINAPI GetScrollPos(_In_ HWND, _In_ int)
#define RGB(r, g, b)
Definition: wingdi.h:2917
#define MAX_PATH
Definition: compat.h:26
const char file[]
Definition: icontest.c:11
unsigned int UINT
Definition: ndis.h:50
BOOL WINAPI InvalidateRect(_In_opt_ HWND, _In_opt_ LPCRECT, _In_ BOOL)
#define BANDID_PREVIEW_BTN5
Definition: wordpad.h:105
static LONG twips_to_pixels(int twips, int dpi)
Definition: print.c:176
unsigned long DWORD
Definition: ntddk_ex.h:95
DWORD nMaxFile
Definition: commdlg.h:368
static void paint_ruler(HWND hWnd, LONG EditLeftmost, BOOL NewMetrics)
Definition: print.c:377
SIZE spacing
Definition: print.c:46
HCURSOR WINAPI LoadCursorW(_In_opt_ HINSTANCE, _In_ LPCWSTR)
Definition: cursoricon.c:2074
#define RBBIM_CHILDSIZE
Definition: commctrl.h:1477
#define EDGE_ETCHED
Definition: winuser.h:452
#define WS_HSCROLL
Definition: pedump.c:628
#define WM_PAINT
Definition: winuser.h:1602
#define PD_PAGENUMS
Definition: commdlg.h:148
#define STRING_PREVIEW_ZOOMIN
Definition: wordpad.h:223
void init_preview(HWND hMainWnd, LPWSTR wszFileName)
Definition: print.c:737
BOOL WINAPI GetScrollInfo(_In_ HWND, _In_ int, _Inout_ LPSCROLLINFO)
void registry_read_pagemargins(HKEY hKey)
Definition: print.c:90
int ret
HWND hMainWnd
Definition: magnifier.c:33
HWND hwndOwner
Definition: commdlg.h:361
LPWSTR wszFileName
Definition: print.c:49
#define STRING_PREVIEW_NEXTPAGE
Definition: wordpad.h:219
LPVOID NTAPI GlobalLock(HGLOBAL hMem)
Definition: heapmem.c:755
LRESULT CALLBACK preview_proc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam)
Definition: print.c:1018
HGLOBAL hDevMode
Definition: commdlg.h:451
HWND WINAPI CreateWindowExW(_In_ DWORD dwExStyle, _In_opt_ LPCWSTR lpClassName, _In_opt_ LPCWSTR lpWindowName, _In_ DWORD dwStyle, _In_ int X, _In_ int Y, _In_ int nWidth, _In_ int nHeight, _In_opt_ HWND hWndParent, _In_opt_ HMENU hMenu, _In_opt_ HINSTANCE hInstance, _In_opt_ LPVOID lpParam)
CHARRANGE chrg
Definition: richedit.h:611
LPCWSTR lpszDocName
Definition: wingdi.h:1661
int WINAPI GetDeviceCaps(_In_opt_ HDC, _In_ int)
#define OFN_HIDEREADONLY
Definition: commdlg.h:107
#define STRING_PREVIEW_PRINT
Definition: wordpad.h:218
HDC hdc
Definition: print.c:40
#define STRING_PREVIEW_ZOOMOUT
Definition: wordpad.h:224
#define BANDID_PREVIEW_BTN6
Definition: wordpad.h:106
int saved_pages_shown
Definition: print.c:37
#define PD_PRINTTOFILE
Definition: commdlg.h:152
#define TWIPS_PER_INCH
Definition: wordpad.h:24
BOOL WINAPI TextOutW(_In_ HDC hdc, _In_ int x, _In_ int y, _In_reads_(c) LPCWSTR lpString, _In_ int c)
WORD nFromPage
Definition: commdlg.h:492
#define IDC_PREVIEW
Definition: wordpad.h:171
static RECT margins
Definition: print.c:55
static LPWSTR get_print_file_filter(HWND hMainWnd)
Definition: print.c:63
#define WM_USER
Definition: winuser.h:1856
HDC hdcTarget
Definition: PatBlt.c:12
HANDLE hDevMode
Definition: commdlg.h:488
GLint GLint GLsizei GLsizei height
Definition: gl.h:1546
#define PS_INSIDEFRAME
Definition: wingdi.h:591
static void toggle_num_pages(HWND hMainWnd)
Definition: print.c:974
#define SIF_POS
Definition: winuser.h:1220
BOOL WINAPI EnableWindow(_In_ HWND, _In_ BOOL)
LRESULT(CALLBACK * WNDPROC)(HWND, UINT, WPARAM, LPARAM)
Definition: winuser.h:2859
BOOL WINAPI GetClientRect(_In_ HWND, _Out_ LPRECT)
HWND WINAPI GetParent(_In_ HWND)
WORD nMaxPage
Definition: commdlg.h:495
RECT window
Definition: print.c:42
GLfloat units
Definition: glext.h:11727
#define PHYSICALWIDTH
Definition: wingdi.h:733
BOOL WINAPI SetRect(_Out_ LPRECT, _In_ int, _In_ int, _In_ int, _In_ int)
#define SB_TOP
Definition: winuser.h:578
static void print(LPPRINTDLGW pd, LPWSTR wszFileName)
Definition: print.c:440
HINSTANCE hInst
Definition: dxdiag.c:13
#define ID_PRINT
Definition: wordpad.h:39
#define PREVIEW_BUTTONS
Definition: wordpad.h:89
#define ID_PREVIEW_ZOOMOUT
Definition: wordpad.h:52
#define PD_RETURNDEFAULT
Definition: commdlg.h:157
#define lstrcpyW
Definition: compat.h:406
void target_device(HWND hMainWnd, DWORD wordWrap)
Definition: print.c:209
BOOL WINAPI DeleteDC(_In_ HDC)
static previewinfo preview
Definition: print.c:56
#define RGN_DIFF
Definition: wingdi.h:356
HCURSOR WINAPI SetCursor(_In_opt_ HCURSOR)
INT x
Definition: msvc.h:62
void print_quick(HWND hMainWnd, LPWSTR wszFileName)
Definition: print.c:539
#define STRING_PREVIEW_TWOPAGES
Definition: wordpad.h:221
#define WC_BUTTONW
Definition: commctrl.h:4588
LRESULT WINAPI SendMessageW(_In_ HWND, _In_ UINT, _In_ WPARAM, _In_ LPARAM)
#define HeapReAlloc
Definition: compat.h:393
#define OFN_OVERWRITEPROMPT
Definition: commdlg.h:116
DWORD Flags
Definition: commdlg.h:453
#define ID_PREVIEW_ZOOMIN
Definition: wordpad.h:51
#define RB_IDTOINDEX
Definition: commctrl.h:1558
#define SRCAND
Definition: wingdi.h:328
LRESULT preview_command(HWND hWnd, WPARAM wParam)
Definition: print.c:1205
#define ID_PREVIEW_NEXTPAGE
Definition: wordpad.h:48
#define SB_LINEDOWN
Definition: winuser.h:565
#define WM_HSCROLL
Definition: winuser.h:1719
HBRUSH WINAPI CreateSolidBrush(_In_ COLORREF)
#define SB_LINEUP
Definition: winuser.h:564
#define SB_BOTTOM
Definition: winuser.h:577
#define WS_VSCROLL
Definition: pedump.c:627
BOOL NTAPI GlobalUnlock(HGLOBAL hMem)
Definition: heapmem.c:1190
void get_default_printer_opts(void)
Definition: print.c:523
int pageCapacity
Definition: print.c:38
_In_ CLIPOBJ _In_ BRUSHOBJ _In_ LONG _In_ LONG _In_ LONG x2
Definition: winddi.h:3706
#define WC_STATICW
Definition: commctrl.h:4640
HDC WINAPI CreateDCW(_In_opt_ LPCWSTR pszDriver, _In_opt_ LPCWSTR pszDevice, _In_opt_ LPCWSTR psz, _In_opt_ const DEVMODEW *pdmInit)
static DWORD *static HFONT(WINAPI *pCreateFontIndirectExA)(const ENUMLOGFONTEXDVA *)
#define PS_DOT
Definition: wingdi.h:586
BOOL WINAPI PtInRect(_In_ LPCRECT, _In_ POINT)
#define IDC_ARROW
Definition: winuser.h:682
#define ID_PREVIEW_PREVPAGE
Definition: wordpad.h:49
BOOL WINAPI PostMessageW(_In_opt_ HWND, _In_ UINT, _In_ WPARAM, _In_ LPARAM)
Definition: name.c:36
#define WM_CREATE
Definition: winuser.h:1590
static int preview_page_hittest(POINT pt)
Definition: print.c:997
#define RBBS_NOGRIPPER
Definition: commctrl.h:1467
LRESULT WINAPI CallWindowProcW(_In_ WNDPROC, _In_ HWND, _In_ UINT, _In_ WPARAM, _In_ LPARAM)
#define HIWORD(l)
Definition: typedefs.h:246
#define RB_DELETEBAND
Definition: commctrl.h:1546
GLenum GLuint id
Definition: glext.h:5579
HMODULE WINAPI GetModuleHandleW(LPCWSTR lpModuleName)
Definition: loader.c:845
static void update_preview_buttons(HWND hMainWnd)
Definition: print.c:817
LONG bottom
Definition: windef.h:299
#define BANDID_PREVIEW_BTN2
Definition: wordpad.h:102
#define LOGPIXELSY
Definition: wingdi.h:717
#define EDGE_SUNKEN
Definition: winuser.h:451
static const WCHAR var_pagemargin[]
Definition: print.c:60
void registry_set_pagemargins(HKEY hKey)
Definition: print.c:85
#define TA_CENTER
Definition: wingdi.h:929
#define MAKEINTRESOURCEW(i)
Definition: winuser.h:582
static void update_preview_statusbar(HWND hMainWnd)
Definition: print.c:900
static void update_preview_scrollbars(HWND hwndPreview, RECT *window)
Definition: print.c:623
GLfloat GLfloat p
Definition: glext.h:8902
WCHAR * LPWSTR
Definition: xmlstorage.h:184
#define EM_GETTEXTLENGTHEX
Definition: richedit.h:129
BOOL WINAPI ScreenToClient(_In_ HWND, _Inout_ LPPOINT)
LONG_PTR LRESULT
Definition: windef.h:209
CardRegion * from
Definition: spigame.cpp:19
int WINAPI FillRect(HDC, LPCRECT, HBRUSH)
#define WS_VISIBLE
Definition: pedump.c:620
static HDC make_dc(void)
Definition: print.c:145
GLuint64EXT * result
Definition: glext.h:11304
static void update_preview_sizes(HWND hwndPreview, BOOL zoomLevelUpdated)
Definition: print.c:651
#define REG_DWORD
Definition: sdbapi.c:539
static LRESULT print_preview(HWND hwndPreview)
Definition: print.c:831
#define IDC_REBAR
Definition: wordpad.h:159
static const CLSID *static CLSID *static const GUID VARIANT VARIANT *static IServiceProvider DWORD *static HMENU
Definition: ordinal.c:60
LONG cy
Definition: windef.h:325
int WINAPI SetScrollPos(_In_ HWND, _In_ int, _In_ int, _In_ BOOL)
static HBITMAP hBitmap
Definition: timezone.c:34
LPARAM lParam
Definition: combotst.c:139
struct _previewinfo previewinfo
#define LOWORD(l)
Definition: pedump.c:82
SIZE bmScaledSize
Definition: print.c:45
Definition: dsound.c:943
int WINAPI SetScrollInfo(_In_ HWND, _In_ int, _In_ LPCSCROLLINFO, _In_ BOOL)
#define OBJ_BITMAP
Definition: objidl.idl:1415
#define HeapFree(x, y, z)
Definition: compat.h:394
#define MulDiv(x, y, z)
Definition: gdifloat.h:86
#define SRCCOPY
Definition: wingdi.h:331
static HWND get_ruler_wnd(HWND hMainWnd)
Definition: print.c:283
#define RBBIM_IDEALSIZE
Definition: commctrl.h:1481
HGDIOBJ WINAPI GetCurrentObject(_In_ HDC, _In_ UINT)
Definition: dc.c:439
LONG cpMin
Definition: richedit.h:500
#define WM_VSCROLL
Definition: winuser.h:1720
#define SIF_ALL
Definition: winuser.h:1218
unsigned int(__cdecl typeof(jpeg_read_scanlines))(struct jpeg_decompress_struct *
Definition: typeof.h:29
int WINAPI EndDoc(_In_ HDC)
Definition: fci.c:126