Home | Info | Community | Development | myReactOS | Contact Us
ReactOS Development > Doxygenprint.c
Go to the documentation of this file.
00001 /* 00002 * Wordpad implementation - Printing and print preview functions 00003 * 00004 * Copyright 2007-2008 by Alexander N. Sørnes <alex@thehandofagony.com> 00005 * 00006 * This library is free software; you can redistribute it and/or 00007 * modify it under the terms of the GNU Lesser General Public 00008 * License as published by the Free Software Foundation; either 00009 * version 2.1 of the License, or (at your option) any later version. 00010 * 00011 * This library is distributed in the hope that it will be useful, 00012 * but WITHOUT ANY WARRANTY; without even the implied warranty of 00013 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 00014 * Lesser General Public License for more details. 00015 * 00016 * You should have received a copy of the GNU Lesser General Public 00017 * License along with this library; if not, write to the Free Software 00018 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA 00019 */ 00020 00021 #include <windows.h> 00022 #include <richedit.h> 00023 #include <commctrl.h> 00024 00025 #include "wordpad.h" 00026 00027 typedef struct _previewinfo 00028 { 00029 int page; 00030 int pages_shown; 00031 int saved_pages_shown; 00032 int *pageEnds, pageCapacity; 00033 int textlength; 00034 HDC hdc; 00035 HDC hdc2; 00036 RECT window; 00037 RECT rcPage; 00038 SIZE bmSize; 00039 SIZE bmScaledSize; 00040 SIZE spacing; 00041 float zoomratio; 00042 int zoomlevel; 00043 LPWSTR wszFileName; 00044 } previewinfo, *ppreviewinfo; 00045 00046 static HGLOBAL devMode; 00047 static HGLOBAL devNames; 00048 00049 static RECT margins; 00050 static previewinfo preview; 00051 00052 extern const WCHAR wszPreviewWndClass[]; 00053 00054 static const WCHAR var_pagemargin[] = {'P','a','g','e','M','a','r','g','i','n',0}; 00055 static const WCHAR var_previewpages[] = {'P','r','e','v','i','e','w','P','a','g','e','s',0}; 00056 00057 static LPWSTR get_print_file_filter(HWND hMainWnd) 00058 { 00059 static WCHAR wszPrintFilter[MAX_STRING_LEN*2+6+4+1]; 00060 const WCHAR files_prn[] = {'*','.','P','R','N',0}; 00061 const WCHAR files_all[] = {'*','.','*','\0'}; 00062 LPWSTR p; 00063 HINSTANCE hInstance = GetModuleHandleW(0); 00064 00065 p = wszPrintFilter; 00066 LoadStringW(hInstance, STRING_PRINTER_FILES_PRN, p, MAX_STRING_LEN); 00067 p += lstrlenW(p) + 1; 00068 lstrcpyW(p, files_prn); 00069 p += lstrlenW(p) + 1; 00070 LoadStringW(hInstance, STRING_ALL_FILES, p, MAX_STRING_LEN); 00071 p += lstrlenW(p) + 1; 00072 lstrcpyW(p, files_all); 00073 p += lstrlenW(p) + 1; 00074 *p = 0; 00075 00076 return wszPrintFilter; 00077 } 00078 00079 void registry_set_pagemargins(HKEY hKey) 00080 { 00081 RegSetValueExW(hKey, var_pagemargin, 0, REG_BINARY, (LPBYTE)&margins, sizeof(RECT)); 00082 } 00083 00084 void registry_read_pagemargins(HKEY hKey) 00085 { 00086 DWORD size = sizeof(RECT); 00087 00088 if(!hKey || RegQueryValueExW(hKey, var_pagemargin, 0, NULL, (LPBYTE)&margins, 00089 &size) != ERROR_SUCCESS || size != sizeof(RECT)) 00090 { 00091 margins.top = 1417; 00092 margins.bottom = 1417; 00093 margins.left = 1757; 00094 margins.right = 1757; 00095 } 00096 } 00097 00098 void registry_set_previewpages(HKEY hKey) 00099 { 00100 RegSetValueExW(hKey, var_previewpages, 0, REG_DWORD, 00101 (LPBYTE)&preview.pages_shown, sizeof(DWORD)); 00102 } 00103 00104 void registry_read_previewpages(HKEY hKey) 00105 { 00106 DWORD size = sizeof(DWORD); 00107 if(!hKey || 00108 RegQueryValueExW(hKey, var_previewpages, 0, NULL, 00109 (LPBYTE)&preview.pages_shown, &size) != ERROR_SUCCESS || 00110 size != sizeof(DWORD)) 00111 { 00112 preview.pages_shown = 1; 00113 } else { 00114 if (preview.pages_shown < 1) preview.pages_shown = 1; 00115 else if (preview.pages_shown > 2) preview.pages_shown = 2; 00116 } 00117 } 00118 00119 00120 static void AddTextButton(HWND hRebarWnd, UINT string, UINT command, UINT id) 00121 { 00122 REBARBANDINFOW rb; 00123 HINSTANCE hInstance = GetModuleHandleW(0); 00124 WCHAR text[MAX_STRING_LEN]; 00125 HWND hButton; 00126 00127 LoadStringW(hInstance, string, text, MAX_STRING_LEN); 00128 hButton = CreateWindowW(WC_BUTTONW, text, 00129 WS_VISIBLE | WS_CHILD, 5, 5, 100, 15, 00130 hRebarWnd, ULongToHandle(command), hInstance, NULL); 00131 00132 rb.cbSize = REBARBANDINFOW_V6_SIZE; 00133 rb.fMask = RBBIM_SIZE | RBBIM_CHILDSIZE | RBBIM_STYLE | RBBIM_CHILD | RBBIM_IDEALSIZE | RBBIM_ID; 00134 rb.fStyle = RBBS_NOGRIPPER | RBBS_VARIABLEHEIGHT; 00135 rb.hwndChild = hButton; 00136 rb.cyChild = rb.cyMinChild = 22; 00137 rb.cx = rb.cxMinChild = 90; 00138 rb.cxIdeal = 100; 00139 rb.wID = id; 00140 00141 SendMessageW(hRebarWnd, RB_INSERTBAND, -1, (LPARAM)&rb); 00142 } 00143 00144 static HDC make_dc(void) 00145 { 00146 if(devNames && devMode) 00147 { 00148 LPDEVNAMES dn = GlobalLock(devNames); 00149 LPDEVMODEW dm = GlobalLock(devMode); 00150 HDC ret; 00151 00152 ret = CreateDCW((LPWSTR)dn + dn->wDriverOffset, 00153 (LPWSTR)dn + dn->wDeviceOffset, 0, dm); 00154 00155 GlobalUnlock(dn); 00156 GlobalUnlock(dm); 00157 00158 return ret; 00159 } else 00160 { 00161 return 0; 00162 } 00163 } 00164 00165 static LONG twips_to_centmm(int twips) 00166 { 00167 return MulDiv(twips, CENTMM_PER_INCH, TWIPS_PER_INCH); 00168 } 00169 00170 static LONG centmm_to_twips(int mm) 00171 { 00172 return MulDiv(mm, TWIPS_PER_INCH, CENTMM_PER_INCH); 00173 } 00174 00175 static LONG twips_to_pixels(int twips, int dpi) 00176 { 00177 return MulDiv(twips, dpi, TWIPS_PER_INCH); 00178 } 00179 00180 static LONG devunits_to_twips(int units, int dpi) 00181 { 00182 return MulDiv(units, TWIPS_PER_INCH, dpi); 00183 } 00184 00185 00186 static RECT get_print_rect(HDC hdc) 00187 { 00188 RECT rc; 00189 int width, height; 00190 00191 if(hdc) 00192 { 00193 int dpiY = GetDeviceCaps(hdc, LOGPIXELSY); 00194 int dpiX = GetDeviceCaps(hdc, LOGPIXELSX); 00195 width = devunits_to_twips(GetDeviceCaps(hdc, PHYSICALWIDTH), dpiX); 00196 height = devunits_to_twips(GetDeviceCaps(hdc, PHYSICALHEIGHT), dpiY); 00197 } else 00198 { 00199 width = centmm_to_twips(18500); 00200 height = centmm_to_twips(27000); 00201 } 00202 00203 rc.left = margins.left; 00204 rc.right = width - margins.right; 00205 rc.top = margins.top; 00206 rc.bottom = height - margins.bottom; 00207 00208 return rc; 00209 } 00210 00211 void target_device(HWND hMainWnd, DWORD wordWrap) 00212 { 00213 HWND hEditorWnd = GetDlgItem(hMainWnd, IDC_EDITOR); 00214 00215 if(wordWrap == ID_WORDWRAP_MARGIN) 00216 { 00217 int width = 0; 00218 LRESULT result; 00219 HDC hdc = make_dc(); 00220 RECT rc = get_print_rect(hdc); 00221 00222 width = rc.right - rc.left; 00223 if(!hdc) 00224 { 00225 HDC hMaindc = GetDC(hMainWnd); 00226 hdc = CreateCompatibleDC(hMaindc); 00227 ReleaseDC(hMainWnd, hMaindc); 00228 } 00229 result = SendMessageW(hEditorWnd, EM_SETTARGETDEVICE, (WPARAM)hdc, width); 00230 DeleteDC(hdc); 00231 if (result) 00232 return; 00233 /* otherwise EM_SETTARGETDEVICE failed, so fall back on wrapping 00234 * to window using the NULL DC. */ 00235 } 00236 00237 if (wordWrap != ID_WORDWRAP_NONE) { 00238 SendMessageW(hEditorWnd, EM_SETTARGETDEVICE, 0, 0); 00239 } else { 00240 SendMessageW(hEditorWnd, EM_SETTARGETDEVICE, 0, 1); 00241 } 00242 00243 } 00244 00245 static LPWSTR dialog_print_to_file(HWND hMainWnd) 00246 { 00247 OPENFILENAMEW ofn; 00248 static WCHAR file[MAX_PATH] = {'O','U','T','P','U','T','.','P','R','N',0}; 00249 static const WCHAR defExt[] = {'P','R','N',0}; 00250 static LPWSTR file_filter; 00251 00252 if(!file_filter) 00253 file_filter = get_print_file_filter(hMainWnd); 00254 00255 ZeroMemory(&ofn, sizeof(ofn)); 00256 00257 ofn.lStructSize = sizeof(ofn); 00258 ofn.Flags = OFN_PATHMUSTEXIST | OFN_HIDEREADONLY | OFN_OVERWRITEPROMPT; 00259 ofn.hwndOwner = hMainWnd; 00260 ofn.lpstrFilter = file_filter; 00261 ofn.lpstrFile = file; 00262 ofn.nMaxFile = MAX_PATH; 00263 ofn.lpstrDefExt = defExt; 00264 00265 if(GetSaveFileNameW(&ofn)) 00266 return file; 00267 else 00268 return FALSE; 00269 } 00270 00271 static void char_from_pagenum(HWND hEditorWnd, FORMATRANGE *fr, int page) 00272 { 00273 int i; 00274 00275 fr->chrg.cpMin = 0; 00276 00277 for(i = 1; i < page; i++) 00278 { 00279 int bottom = fr->rc.bottom; 00280 fr->chrg.cpMin = SendMessageW(hEditorWnd, EM_FORMATRANGE, FALSE, (LPARAM)fr); 00281 fr->rc.bottom = bottom; 00282 } 00283 } 00284 00285 static HWND get_ruler_wnd(HWND hMainWnd) 00286 { 00287 return GetDlgItem(GetDlgItem(hMainWnd, IDC_REBAR), IDC_RULER); 00288 } 00289 00290 void redraw_ruler(HWND hRulerWnd) 00291 { 00292 RECT rc; 00293 00294 GetClientRect(hRulerWnd, &rc); 00295 InvalidateRect(hRulerWnd, &rc, TRUE); 00296 } 00297 00298 static void update_ruler(HWND hRulerWnd) 00299 { 00300 SendMessageW(hRulerWnd, WM_USER, 0, 0); 00301 redraw_ruler(hRulerWnd); 00302 } 00303 00304 static void add_ruler_units(HDC hdcRuler, RECT* drawRect, BOOL NewMetrics, LONG EditLeftmost) 00305 { 00306 static HDC hdc; 00307 00308 if(NewMetrics) 00309 { 00310 static HBITMAP hBitmap; 00311 int i, x, y, RulerTextEnd; 00312 int CmPixels; 00313 int QuarterCmPixels; 00314 HFONT hFont; 00315 WCHAR FontName[] = {'M','S',' ','S','a','n','s',' ','S','e','r','i','f',0}; 00316 00317 if(hdc) 00318 { 00319 DeleteDC(hdc); 00320 DeleteObject(hBitmap); 00321 } 00322 00323 hdc = CreateCompatibleDC(0); 00324 00325 CmPixels = twips_to_pixels(centmm_to_twips(1000), GetDeviceCaps(hdc, LOGPIXELSX)); 00326 QuarterCmPixels = (int)((float)CmPixels / 4.0); 00327 00328 hBitmap = CreateCompatibleBitmap(hdc, drawRect->right, drawRect->bottom); 00329 SelectObject(hdc, hBitmap); 00330 FillRect(hdc, drawRect, GetStockObject(WHITE_BRUSH)); 00331 00332 hFont = CreateFontW(10, 6, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, FontName); 00333 00334 SelectObject(hdc, hFont); 00335 SetBkMode(hdc, TRANSPARENT); 00336 SetTextAlign(hdc, TA_CENTER); 00337 y = (int)(((float)drawRect->bottom - (float)drawRect->top) / 2.0) + 1; 00338 RulerTextEnd = drawRect->right - EditLeftmost + 1; 00339 for(i = 1, x = EditLeftmost; x < (drawRect->right - EditLeftmost + 1); i ++) 00340 { 00341 WCHAR str[3]; 00342 WCHAR format[] = {'%','d',0}; 00343 int x2 = x; 00344 00345 x2 += QuarterCmPixels; 00346 if(x2 > RulerTextEnd) 00347 break; 00348 00349 MoveToEx(hdc, x2, y, NULL); 00350 LineTo(hdc, x2, y+2); 00351 00352 x2 += QuarterCmPixels; 00353 if(x2 > RulerTextEnd) 00354 break; 00355 00356 MoveToEx(hdc, x2, y - 3, NULL); 00357 LineTo(hdc, x2, y + 3); 00358 00359 x2 += QuarterCmPixels; 00360 if(x2 > RulerTextEnd) 00361 break; 00362 00363 MoveToEx(hdc, x2, y, NULL); 00364 LineTo(hdc, x2, y+2); 00365 00366 x += CmPixels; 00367 if(x > RulerTextEnd) 00368 break; 00369 00370 wsprintfW(str, format, i); 00371 TextOutW(hdc, x, 5, str, lstrlenW(str)); 00372 } 00373 DeleteObject(hFont); 00374 } 00375 00376 BitBlt(hdcRuler, 0, 0, drawRect->right, drawRect->bottom, hdc, 0, 0, SRCAND); 00377 } 00378 00379 static void paint_ruler(HWND hWnd, LONG EditLeftmost, BOOL NewMetrics) 00380 { 00381 PAINTSTRUCT ps; 00382 HDC hdc = BeginPaint(hWnd, &ps); 00383 HDC hdcPrint = make_dc(); 00384 RECT printRect = get_print_rect(hdcPrint); 00385 RECT drawRect; 00386 HBRUSH hBrush = CreateSolidBrush(GetSysColor(COLOR_MENU)); 00387 00388 GetClientRect(hWnd, &drawRect); 00389 FillRect(hdc, &drawRect, hBrush); 00390 00391 drawRect.top += 3; 00392 drawRect.bottom -= 3; 00393 drawRect.left = EditLeftmost; 00394 drawRect.right = twips_to_pixels(printRect.right - margins.left, GetDeviceCaps(hdc, LOGPIXELSX)); 00395 FillRect(hdc, &drawRect, GetStockObject(WHITE_BRUSH)); 00396 00397 drawRect.top--; 00398 drawRect.bottom++; 00399 DrawEdge(hdc, &drawRect, EDGE_SUNKEN, BF_RECT); 00400 00401 drawRect.left = drawRect.right - 1; 00402 drawRect.right = twips_to_pixels(printRect.right + margins.right - margins.left, GetDeviceCaps(hdc, LOGPIXELSX)); 00403 DrawEdge(hdc, &drawRect, EDGE_ETCHED, BF_RECT); 00404 00405 drawRect.left = 0; 00406 drawRect.top = 0; 00407 add_ruler_units(hdc, &drawRect, NewMetrics, EditLeftmost); 00408 00409 SelectObject(hdc, GetStockObject(BLACK_BRUSH)); 00410 DeleteObject(hBrush); 00411 DeleteDC(hdcPrint); 00412 EndPaint(hWnd, &ps); 00413 } 00414 00415 LRESULT CALLBACK ruler_proc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam) 00416 { 00417 static WNDPROC pPrevRulerProc; 00418 static LONG EditLeftmost; 00419 static BOOL NewMetrics; 00420 00421 switch(msg) 00422 { 00423 case WM_USER: 00424 if(wParam) 00425 { 00426 EditLeftmost = ((POINTL*)wParam)->x; 00427 pPrevRulerProc = (WNDPROC)lParam; 00428 } 00429 NewMetrics = TRUE; 00430 break; 00431 00432 case WM_PAINT: 00433 paint_ruler(hWnd, EditLeftmost, NewMetrics); 00434 break; 00435 00436 default: 00437 return CallWindowProcW(pPrevRulerProc, hWnd, msg, wParam, lParam); 00438 } 00439 00440 return 0; 00441 } 00442 00443 static void print(LPPRINTDLGW pd, LPWSTR wszFileName) 00444 { 00445 FORMATRANGE fr; 00446 DOCINFOW di; 00447 HWND hEditorWnd = GetDlgItem(pd->hwndOwner, IDC_EDITOR); 00448 int printedPages = 0; 00449 00450 fr.hdc = pd->hDC; 00451 fr.hdcTarget = pd->hDC; 00452 00453 fr.rc = get_print_rect(fr.hdc); 00454 fr.rcPage.left = 0; 00455 fr.rcPage.right = fr.rc.right + margins.right; 00456 fr.rcPage.top = 0; 00457 fr.rcPage.bottom = fr.rc.bottom + margins.bottom; 00458 00459 ZeroMemory(&di, sizeof(di)); 00460 di.cbSize = sizeof(di); 00461 di.lpszDocName = wszFileName; 00462 00463 if(pd->Flags & PD_PRINTTOFILE) 00464 { 00465 di.lpszOutput = dialog_print_to_file(pd->hwndOwner); 00466 if(!di.lpszOutput) 00467 return; 00468 } 00469 00470 if(pd->Flags & PD_SELECTION) 00471 { 00472 SendMessageW(hEditorWnd, EM_EXGETSEL, 0, (LPARAM)&fr.chrg); 00473 } else 00474 { 00475 GETTEXTLENGTHEX gt; 00476 gt.flags = GTL_DEFAULT; 00477 gt.codepage = 1200; 00478 fr.chrg.cpMin = 0; 00479 fr.chrg.cpMax = SendMessageW(hEditorWnd, EM_GETTEXTLENGTHEX, (WPARAM)>, 0); 00480 00481 if(pd->Flags & PD_PAGENUMS) 00482 char_from_pagenum(hEditorWnd, &fr, pd->nToPage); 00483 } 00484 00485 StartDocW(fr.hdc, &di); 00486 do 00487 { 00488 if(StartPage(fr.hdc) <= 0) 00489 break; 00490 00491 fr.chrg.cpMin = SendMessageW(hEditorWnd, EM_FORMATRANGE, TRUE, (LPARAM)&fr); 00492 00493 if(EndPage(fr.hdc) <= 0) 00494 break; 00495 00496 printedPages++; 00497 if((pd->Flags & PD_PAGENUMS) && (printedPages > (pd->nToPage - pd->nFromPage))) 00498 break; 00499 } 00500 while(fr.chrg.cpMin && fr.chrg.cpMin < fr.chrg.cpMax); 00501 00502 EndDoc(fr.hdc); 00503 SendMessageW(hEditorWnd, EM_FORMATRANGE, FALSE, 0); 00504 } 00505 00506 void dialog_printsetup(HWND hMainWnd) 00507 { 00508 PAGESETUPDLGW ps; 00509 00510 ZeroMemory(&ps, sizeof(ps)); 00511 ps.lStructSize = sizeof(ps); 00512 ps.hwndOwner = hMainWnd; 00513 ps.Flags = PSD_INHUNDREDTHSOFMILLIMETERS | PSD_MARGINS; 00514 ps.rtMargin.left = twips_to_centmm(margins.left); 00515 ps.rtMargin.right = twips_to_centmm(margins.right); 00516 ps.rtMargin.top = twips_to_centmm(margins.top); 00517 ps.rtMargin.bottom = twips_to_centmm(margins.bottom); 00518 ps.hDevMode = devMode; 00519 ps.hDevNames = devNames; 00520 00521 if(PageSetupDlgW(&ps)) 00522 { 00523 margins.left = centmm_to_twips(ps.rtMargin.left); 00524 margins.right = centmm_to_twips(ps.rtMargin.right); 00525 margins.top = centmm_to_twips(ps.rtMargin.top); 00526 margins.bottom = centmm_to_twips(ps.rtMargin.bottom); 00527 devMode = ps.hDevMode; 00528 devNames = ps.hDevNames; 00529 update_ruler(get_ruler_wnd(hMainWnd)); 00530 } 00531 } 00532 00533 void get_default_printer_opts(void) 00534 { 00535 PRINTDLGW pd; 00536 ZeroMemory(&pd, sizeof(pd)); 00537 00538 ZeroMemory(&pd, sizeof(pd)); 00539 pd.lStructSize = sizeof(pd); 00540 pd.Flags = PD_RETURNDC | PD_RETURNDEFAULT; 00541 pd.hDevMode = devMode; 00542 00543 PrintDlgW(&pd); 00544 00545 devMode = pd.hDevMode; 00546 devNames = pd.hDevNames; 00547 } 00548 00549 void print_quick(HWND hMainWnd, LPWSTR wszFileName) 00550 { 00551 PRINTDLGW pd; 00552 00553 ZeroMemory(&pd, sizeof(pd)); 00554 pd.hwndOwner = hMainWnd; 00555 pd.hDC = make_dc(); 00556 00557 print(&pd, wszFileName); 00558 DeleteDC(pd.hDC); 00559 } 00560 00561 void dialog_print(HWND hMainWnd, LPWSTR wszFileName) 00562 { 00563 PRINTDLGW pd; 00564 HWND hEditorWnd = GetDlgItem(hMainWnd, IDC_EDITOR); 00565 int from = 0; 00566 int to = 0; 00567 00568 ZeroMemory(&pd, sizeof(pd)); 00569 pd.lStructSize = sizeof(pd); 00570 pd.hwndOwner = hMainWnd; 00571 pd.Flags = PD_RETURNDC | PD_USEDEVMODECOPIESANDCOLLATE; 00572 pd.nMinPage = 1; 00573 pd.nMaxPage = -1; 00574 pd.hDevMode = devMode; 00575 pd.hDevNames = devNames; 00576 00577 SendMessageW(hEditorWnd, EM_GETSEL, (WPARAM)&from, (LPARAM)&to); 00578 if(from == to) 00579 pd.Flags |= PD_NOSELECTION; 00580 00581 if(PrintDlgW(&pd)) 00582 { 00583 devMode = pd.hDevMode; 00584 devNames = pd.hDevNames; 00585 print(&pd, wszFileName); 00586 update_ruler(get_ruler_wnd(hMainWnd)); 00587 } 00588 } 00589 00590 static void preview_bar_show(HWND hMainWnd, BOOL show) 00591 { 00592 HWND hReBar = GetDlgItem(hMainWnd, IDC_REBAR); 00593 int i; 00594 00595 if(show) 00596 { 00597 REBARBANDINFOW rb; 00598 HWND hStatic; 00599 UINT num_pages_string = preview.pages_shown > 1 ? STRING_PREVIEW_ONEPAGE : 00600 STRING_PREVIEW_TWOPAGES; 00601 00602 AddTextButton(hReBar, STRING_PREVIEW_PRINT, ID_PRINT, BANDID_PREVIEW_BTN1); 00603 AddTextButton(hReBar, STRING_PREVIEW_NEXTPAGE, ID_PREVIEW_NEXTPAGE, BANDID_PREVIEW_BTN2); 00604 AddTextButton(hReBar, STRING_PREVIEW_PREVPAGE, ID_PREVIEW_PREVPAGE, BANDID_PREVIEW_BTN3); 00605 AddTextButton(hReBar, num_pages_string, ID_PREVIEW_NUMPAGES, BANDID_PREVIEW_BTN4); 00606 AddTextButton(hReBar, STRING_PREVIEW_ZOOMIN, ID_PREVIEW_ZOOMIN, BANDID_PREVIEW_BTN5); 00607 AddTextButton(hReBar, STRING_PREVIEW_ZOOMOUT, ID_PREVIEW_ZOOMOUT, BANDID_PREVIEW_BTN6); 00608 AddTextButton(hReBar, STRING_PREVIEW_CLOSE, ID_FILE_EXIT, BANDID_PREVIEW_BTN7); 00609 00610 hStatic = CreateWindowW(WC_STATICW, NULL, 00611 WS_VISIBLE | WS_CHILD, 0, 0, 0, 0, 00612 hReBar, NULL, NULL, NULL); 00613 00614 rb.cbSize = REBARBANDINFOW_V6_SIZE; 00615 rb.fMask = RBBIM_SIZE | RBBIM_CHILDSIZE | RBBIM_STYLE | RBBIM_CHILD | RBBIM_IDEALSIZE | RBBIM_ID; 00616 rb.fStyle = RBBS_NOGRIPPER | RBBS_VARIABLEHEIGHT; 00617 rb.hwndChild = hStatic; 00618 rb.cyChild = rb.cyMinChild = 22; 00619 rb.cx = rb.cxMinChild = 90; 00620 rb.cxIdeal = 100; 00621 rb.wID = BANDID_PREVIEW_BUFFER; 00622 00623 SendMessageW(hReBar, RB_INSERTBAND, -1, (LPARAM)&rb); 00624 } else 00625 { 00626 for(i = 0; i <= PREVIEW_BUTTONS; i++) 00627 SendMessageW(hReBar, RB_DELETEBAND, SendMessageW(hReBar, RB_IDTOINDEX, BANDID_PREVIEW_BTN1+i, 0), 0); 00628 } 00629 } 00630 00631 static const int min_spacing = 10; 00632 00633 static void update_preview_scrollbars(HWND hwndPreview, RECT *window) 00634 { 00635 SCROLLINFO sbi; 00636 sbi.cbSize = sizeof(sbi); 00637 sbi.fMask = SIF_PAGE|SIF_RANGE; 00638 sbi.nMin = 0; 00639 if (preview.zoomlevel == 0) 00640 { 00641 /* Hide scrollbars when zoomed out. */ 00642 sbi.nMax = 0; 00643 sbi.nPage = window->right; 00644 SetScrollInfo(hwndPreview, SB_HORZ, &sbi, TRUE); 00645 sbi.nPage = window->bottom; 00646 SetScrollInfo(hwndPreview, SB_VERT, &sbi, TRUE); 00647 } else { 00648 sbi.nMax = preview.bmScaledSize.cx * preview.pages_shown + 00649 min_spacing * (preview.pages_shown + 1); 00650 sbi.nPage = window->right; 00651 SetScrollInfo(hwndPreview, SB_HORZ, &sbi, TRUE); 00652 /* Change in the horizontal scrollbar visibility affects the 00653 * client rect, so update the client rect. */ 00654 GetClientRect(hwndPreview, window); 00655 sbi.nMax = preview.bmScaledSize.cy + min_spacing * 2; 00656 sbi.nPage = window->bottom; 00657 SetScrollInfo(hwndPreview, SB_VERT, &sbi, TRUE); 00658 } 00659 } 00660 00661 static void update_preview_sizes(HWND hwndPreview, BOOL zoomLevelUpdated) 00662 { 00663 RECT window; 00664 00665 GetClientRect(hwndPreview, &window); 00666 00667 /* The zoom ratio isn't updated for partial zoom because of resizing the window. */ 00668 if (zoomLevelUpdated || preview.zoomlevel != 1) 00669 { 00670 float ratio, ratioHeight, ratioWidth; 00671 if (preview.zoomlevel == 2) 00672 { 00673 ratio = 1.0; 00674 } else { 00675 ratioHeight = (window.bottom - min_spacing * 2) / (float)preview.bmSize.cy; 00676 00677 ratioWidth = (float)(window.right - 00678 min_spacing * (preview.pages_shown + 1)) / 00679 (preview.pages_shown * preview.bmSize.cx); 00680 00681 if(ratioWidth > ratioHeight) 00682 ratio = ratioHeight; 00683 else 00684 ratio = ratioWidth; 00685 00686 if (preview.zoomlevel == 1) 00687 ratio += (1.0 - ratio) / 2; 00688 } 00689 preview.zoomratio = ratio; 00690 } 00691 00692 preview.bmScaledSize.cx = preview.bmSize.cx * preview.zoomratio; 00693 preview.bmScaledSize.cy = preview.bmSize.cy * preview.zoomratio; 00694 00695 preview.spacing.cy = max(min_spacing, (window.bottom - preview.bmScaledSize.cy) / 2); 00696 00697 preview.spacing.cx = (window.right - 00698 preview.bmScaledSize.cx * preview.pages_shown) / 00699 (preview.pages_shown + 1); 00700 if (preview.spacing.cx < min_spacing) 00701 preview.spacing.cx = min_spacing; 00702 00703 update_preview_scrollbars(hwndPreview, &window); 00704 } 00705 00706 static void draw_margin_lines(HDC hdc, int x, int y, float ratio) 00707 { 00708 HPEN hPen, oldPen; 00709 SIZE dpi; 00710 RECT page_margin = preview.rcPage; 00711 00712 dpi.cx = GetDeviceCaps(hdc, LOGPIXELSX); 00713 dpi.cy = GetDeviceCaps(hdc, LOGPIXELSY); 00714 00715 page_margin.left = preview.rcPage.left + margins.left; 00716 page_margin.top = preview.rcPage.top + margins.top; 00717 page_margin.bottom = preview.rcPage.bottom - margins.bottom; 00718 page_margin.right = preview.rcPage.right - margins.right; 00719 00720 page_margin.left = (int)((float)twips_to_pixels(page_margin.left, dpi.cx) * ratio); 00721 page_margin.top = (int)((float)twips_to_pixels(page_margin.top, dpi.cy) * ratio); 00722 page_margin.bottom = (int)((float)twips_to_pixels(page_margin.bottom, dpi.cy) * ratio); 00723 page_margin.right = (int)((float)twips_to_pixels(page_margin.right, dpi.cx) * ratio); 00724 00725 page_margin.left += x; 00726 page_margin.top += y; 00727 page_margin.bottom += y; 00728 page_margin.right += x; 00729 00730 hPen = CreatePen(PS_DOT, 1, RGB(0,0,0)); 00731 oldPen = SelectObject(hdc, hPen); 00732 00733 MoveToEx(hdc, x, page_margin.top, NULL); 00734 LineTo(hdc, x + preview.bmScaledSize.cx, page_margin.top); 00735 MoveToEx(hdc, x, page_margin.bottom, NULL); 00736 LineTo(hdc, x + preview.bmScaledSize.cx, page_margin.bottom); 00737 00738 MoveToEx(hdc, page_margin.left, y, NULL); 00739 LineTo(hdc, page_margin.left, y + preview.bmScaledSize.cy); 00740 MoveToEx(hdc, page_margin.right, y, NULL); 00741 LineTo(hdc, page_margin.right, y + preview.bmScaledSize.cy); 00742 00743 SelectObject(hdc, oldPen); 00744 DeleteObject(hPen); 00745 } 00746 00747 static BOOL is_last_preview_page(int page) 00748 { 00749 return preview.pageEnds[page - 1] >= preview.textlength; 00750 } 00751 00752 void init_preview(HWND hMainWnd, LPWSTR wszFileName) 00753 { 00754 HINSTANCE hInstance = GetModuleHandleW(0); 00755 preview.page = 1; 00756 preview.hdc = 0; 00757 preview.hdc2 = 0; 00758 preview.wszFileName = wszFileName; 00759 preview.zoomratio = 0; 00760 preview.zoomlevel = 0; 00761 preview_bar_show(hMainWnd, TRUE); 00762 00763 CreateWindowExW(0, wszPreviewWndClass, NULL, 00764 WS_VISIBLE | WS_CHILD | WS_VSCROLL | WS_HSCROLL, 00765 0, 0, 200, 10, hMainWnd, (HMENU)IDC_PREVIEW, hInstance, NULL); 00766 } 00767 00768 void close_preview(HWND hMainWnd) 00769 { 00770 HWND hwndPreview = GetDlgItem(hMainWnd, IDC_PREVIEW); 00771 preview.window.right = 0; 00772 preview.window.bottom = 0; 00773 preview.page = 0; 00774 HeapFree(GetProcessHeap(), 0, preview.pageEnds); 00775 preview.pageEnds = NULL; 00776 preview.pageCapacity = 0; 00777 if (preview.zoomlevel > 0) 00778 preview.pages_shown = preview.saved_pages_shown; 00779 if(preview.hdc) { 00780 HBITMAP oldbm = GetCurrentObject(preview.hdc, OBJ_BITMAP); 00781 DeleteDC(preview.hdc); 00782 DeleteObject(oldbm); 00783 preview.hdc = NULL; 00784 } 00785 if(preview.hdc2) { 00786 HBITMAP oldbm = GetCurrentObject(preview.hdc2, OBJ_BITMAP); 00787 DeleteDC(preview.hdc2); 00788 DeleteObject(oldbm); 00789 preview.hdc2 = NULL; 00790 } 00791 00792 preview_bar_show(hMainWnd, FALSE); 00793 DestroyWindow(hwndPreview); 00794 } 00795 00796 BOOL preview_isactive(void) 00797 { 00798 return preview.page != 0; 00799 } 00800 00801 static void draw_preview(HWND hEditorWnd, FORMATRANGE* lpFr, RECT* paper, int page) 00802 { 00803 int bottom; 00804 00805 if (!preview.pageEnds) 00806 { 00807 preview.pageCapacity = 32; 00808 preview.pageEnds = HeapAlloc(GetProcessHeap(), 0, 00809 sizeof(int) * preview.pageCapacity); 00810 if (!preview.pageEnds) return; 00811 } else if (page >= preview.pageCapacity) { 00812 int *new_buffer; 00813 new_buffer = HeapReAlloc(GetProcessHeap(), 0, preview.pageEnds, 00814 sizeof(int) * preview.pageCapacity * 2); 00815 if (!new_buffer) return; 00816 preview.pageCapacity *= 2; 00817 preview.pageEnds = new_buffer; 00818 } 00819 00820 FillRect(lpFr->hdc, paper, GetStockObject(WHITE_BRUSH)); 00821 if (page > 1 && is_last_preview_page(page - 1)) return; 00822 lpFr->chrg.cpMin = page <= 1 ? 0 : preview.pageEnds[page-2]; 00823 bottom = lpFr->rc.bottom; 00824 preview.pageEnds[page-1] = SendMessageW(hEditorWnd, EM_FORMATRANGE, TRUE, (LPARAM)lpFr); 00825 00826 /* EM_FORMATRANGE sets fr.rc.bottom to indicate the area printed in, 00827 * but we want to keep the original for drawing margins */ 00828 lpFr->rc.bottom = bottom; 00829 SendMessageW(hEditorWnd, EM_FORMATRANGE, FALSE, 0); 00830 } 00831 00832 static void update_preview_buttons(HWND hMainWnd) 00833 { 00834 HWND hReBar = GetDlgItem(hMainWnd, IDC_REBAR); 00835 EnableWindow(GetDlgItem(hReBar, ID_PREVIEW_PREVPAGE), preview.page > 1); 00836 EnableWindow(GetDlgItem(hReBar, ID_PREVIEW_NEXTPAGE), 00837 !is_last_preview_page(preview.page) && 00838 !is_last_preview_page(preview.page + preview.pages_shown - 1)); 00839 EnableWindow(GetDlgItem(hReBar, ID_PREVIEW_NUMPAGES), 00840 preview.pages_shown > 1 || 00841 (!is_last_preview_page(1) && preview.zoomlevel == 0)); 00842 EnableWindow(GetDlgItem(hReBar, ID_PREVIEW_ZOOMIN), preview.zoomlevel < 2); 00843 EnableWindow(GetDlgItem(hReBar, ID_PREVIEW_ZOOMOUT), preview.zoomlevel > 0); 00844 } 00845 00846 static LRESULT print_preview(HWND hwndPreview) 00847 { 00848 HPEN hPen, oldPen; 00849 HDC hdc; 00850 HRGN back_rgn, excl_rgn; 00851 RECT window, background; 00852 PAINTSTRUCT ps; 00853 int x, y; 00854 00855 hdc = BeginPaint(hwndPreview, &ps); 00856 GetClientRect(hwndPreview, &window); 00857 back_rgn = CreateRectRgnIndirect(&window); 00858 00859 x = preview.spacing.cx - GetScrollPos(hwndPreview, SB_HORZ); 00860 y = preview.spacing.cy - GetScrollPos(hwndPreview, SB_VERT); 00861 00862 /* draw page outlines */ 00863 hPen = CreatePen(PS_SOLID|PS_INSIDEFRAME, 2, RGB(0,0,0)); 00864 oldPen = SelectObject(hdc, hPen); 00865 background.left = x - 2; 00866 background.right = x + preview.bmScaledSize.cx + 2; 00867 background.top = y - 2; 00868 background.bottom = y + preview.bmScaledSize.cy + 2; 00869 Rectangle(hdc, background.left, background.top, 00870 background.right, background.bottom); 00871 excl_rgn = CreateRectRgnIndirect(&background); 00872 CombineRgn(back_rgn, back_rgn, excl_rgn, RGN_DIFF); 00873 if(preview.pages_shown > 1) 00874 { 00875 background.left += preview.bmScaledSize.cx + preview.spacing.cx; 00876 background.right += preview.bmScaledSize.cx + preview.spacing.cx; 00877 Rectangle(hdc, background.left, background.top, 00878 background.right, background.bottom); 00879 SetRectRgn(excl_rgn, background.left, background.top, 00880 background.right, background.bottom); 00881 CombineRgn(back_rgn, back_rgn, excl_rgn, RGN_DIFF); 00882 } 00883 SelectObject(hdc, oldPen); 00884 DeleteObject(hPen); 00885 FillRgn(hdc, back_rgn, GetStockObject(GRAY_BRUSH)); 00886 DeleteObject(excl_rgn); 00887 DeleteObject(back_rgn); 00888 00889 StretchBlt(hdc, x, y, preview.bmScaledSize.cx, preview.bmScaledSize.cy, 00890 preview.hdc, 0, 0, preview.bmSize.cx, preview.bmSize.cy, SRCCOPY); 00891 00892 draw_margin_lines(hdc, x, y, preview.zoomratio); 00893 00894 if(preview.pages_shown > 1) 00895 { 00896 if (!is_last_preview_page(preview.page)) { 00897 x += preview.spacing.cx + preview.bmScaledSize.cx; 00898 StretchBlt(hdc, x, y, 00899 preview.bmScaledSize.cx, preview.bmScaledSize.cy, 00900 preview.hdc2, 0, 0, 00901 preview.bmSize.cx, preview.bmSize.cy, SRCCOPY); 00902 00903 draw_margin_lines(hdc, x, y, preview.zoomratio); 00904 } else { 00905 background.left += 2; 00906 background.right -= 2; 00907 background.top += 2; 00908 background.bottom -= 2; 00909 FillRect(hdc, &background, GetStockObject(WHITE_BRUSH)); 00910 } 00911 } 00912 00913 preview.window = window; 00914 00915 EndPaint(hwndPreview, &ps); 00916 00917 return 0; 00918 } 00919 00920 static void update_preview_statusbar(HWND hMainWnd) 00921 { 00922 HWND hStatusbar = GetDlgItem(hMainWnd, IDC_STATUSBAR); 00923 HINSTANCE hInst = GetModuleHandleW(0); 00924 WCHAR *p; 00925 WCHAR wstr[MAX_STRING_LEN]; 00926 00927 p = wstr; 00928 if (preview.pages_shown < 2 || is_last_preview_page(preview.page)) 00929 { 00930 static const WCHAR fmt[] = {' ','%','d','\0'}; 00931 p += LoadStringW(hInst, STRING_PREVIEW_PAGE, wstr, MAX_STRING_LEN); 00932 wsprintfW(p, fmt, preview.page); 00933 } else { 00934 static const WCHAR fmt[] = {' ','%','d','-','%','d','\0'}; 00935 p += LoadStringW(hInst, STRING_PREVIEW_PAGES, wstr, MAX_STRING_LEN); 00936 wsprintfW(p, fmt, preview.page, preview.page + 1); 00937 } 00938 SetWindowTextW(hStatusbar, wstr); 00939 } 00940 00941 /* Update for page changes. */ 00942 static void update_preview(HWND hMainWnd) 00943 { 00944 RECT paper; 00945 HWND hEditorWnd = GetDlgItem(hMainWnd, IDC_EDITOR); 00946 HWND hwndPreview = GetDlgItem(hMainWnd, IDC_PREVIEW); 00947 HBITMAP hBitmapCapture; 00948 FORMATRANGE fr; 00949 HDC hdc = GetDC(hwndPreview); 00950 00951 fr.hdcTarget = make_dc(); 00952 fr.rc = fr.rcPage = preview.rcPage; 00953 fr.rc.left += margins.left; 00954 fr.rc.top += margins.top; 00955 fr.rc.bottom -= margins.bottom; 00956 fr.rc.right -= margins.right; 00957 00958 fr.chrg.cpMin = 0; 00959 fr.chrg.cpMax = preview.textlength; 00960 00961 paper.left = 0; 00962 paper.right = preview.bmSize.cx; 00963 paper.top = 0; 00964 paper.bottom = preview.bmSize.cy; 00965 00966 if (!preview.hdc) { 00967 preview.hdc = CreateCompatibleDC(hdc); 00968 hBitmapCapture = CreateCompatibleBitmap(hdc, preview.bmSize.cx, preview.bmSize.cy); 00969 SelectObject(preview.hdc, hBitmapCapture); 00970 } 00971 00972 fr.hdc = preview.hdc; 00973 draw_preview(hEditorWnd, &fr, &paper, preview.page); 00974 00975 if(preview.pages_shown > 1) 00976 { 00977 if (!preview.hdc2) 00978 { 00979 preview.hdc2 = CreateCompatibleDC(hdc); 00980 hBitmapCapture = CreateCompatibleBitmap(hdc, 00981 preview.bmSize.cx, 00982 preview.bmSize.cy); 00983 SelectObject(preview.hdc2, hBitmapCapture); 00984 } 00985 00986 fr.hdc = preview.hdc2; 00987 draw_preview(hEditorWnd, &fr, &fr.rcPage, preview.page + 1); 00988 } 00989 DeleteDC(fr.hdcTarget); 00990 ReleaseDC(hwndPreview, hdc); 00991 00992 InvalidateRect(hwndPreview, NULL, FALSE); 00993 update_preview_buttons(hMainWnd); 00994 update_preview_statusbar(hMainWnd); 00995 } 00996 00997 static void toggle_num_pages(HWND hMainWnd) 00998 { 00999 HWND hReBar = GetDlgItem(hMainWnd, IDC_REBAR); 01000 WCHAR name[MAX_STRING_LEN]; 01001 HINSTANCE hInst = GetModuleHandleW(0); 01002 int nPreviewPages; 01003 01004 preview.pages_shown = preview.pages_shown > 1 ? 1 : 2; 01005 01006 nPreviewPages = preview.zoomlevel > 0 ? preview.saved_pages_shown : 01007 preview.pages_shown; 01008 01009 LoadStringW(hInst, nPreviewPages > 1 ? STRING_PREVIEW_ONEPAGE : 01010 STRING_PREVIEW_TWOPAGES, 01011 name, MAX_STRING_LEN); 01012 01013 SetWindowTextW(GetDlgItem(hReBar, ID_PREVIEW_NUMPAGES), name); 01014 update_preview_sizes(GetDlgItem(hMainWnd, IDC_PREVIEW), TRUE); 01015 update_preview(hMainWnd); 01016 } 01017 01018 /* Returns the page shown that the point is in (1 or 2) or 0 if the point 01019 * isn't inside either page */ 01020 static int preview_page_hittest(POINT pt) 01021 { 01022 RECT rc; 01023 rc.left = preview.spacing.cx; 01024 rc.right = rc.left + preview.bmScaledSize.cx; 01025 rc.top = preview.spacing.cy; 01026 rc.bottom = rc.top + preview.bmScaledSize.cy; 01027 if (PtInRect(&rc, pt)) 01028 return 1; 01029 01030 if (preview.pages_shown <= 1) 01031 return 0; 01032 01033 rc.left += preview.bmScaledSize.cx + preview.spacing.cx; 01034 rc.right += preview.bmScaledSize.cx + preview.spacing.cx; 01035 if (PtInRect(&rc, pt)) 01036 return is_last_preview_page(preview.page) ? 1 : 2; 01037 01038 return 0; 01039 } 01040 01041 LRESULT CALLBACK preview_proc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam) 01042 { 01043 switch(msg) 01044 { 01045 case WM_CREATE: 01046 { 01047 HWND hMainWnd = GetParent(hWnd); 01048 HWND hEditorWnd = GetDlgItem(hMainWnd, IDC_EDITOR); 01049 FORMATRANGE fr; 01050 GETTEXTLENGTHEX gt = {GTL_DEFAULT, 1200}; 01051 HDC hdc = GetDC(hWnd); 01052 HDC hdcTarget = make_dc(); 01053 01054 fr.rc = preview.rcPage = get_print_rect(hdcTarget); 01055 preview.rcPage.bottom += margins.bottom; 01056 preview.rcPage.right += margins.right; 01057 preview.rcPage.top = preview.rcPage.left = 0; 01058 fr.rcPage = preview.rcPage; 01059 01060 preview.bmSize.cx = twips_to_pixels(preview.rcPage.right, GetDeviceCaps(hdc, LOGPIXELSX)); 01061 preview.bmSize.cy = twips_to_pixels(preview.rcPage.bottom, GetDeviceCaps(hdc, LOGPIXELSY)); 01062 01063 preview.textlength = SendMessageW(hEditorWnd, EM_GETTEXTLENGTHEX, (WPARAM)>, 0); 01064 01065 fr.hdc = CreateCompatibleDC(hdc); 01066 fr.hdcTarget = hdcTarget; 01067 fr.chrg.cpMin = 0; 01068 fr.chrg.cpMax = preview.textlength; 01069 DeleteDC(fr.hdc); 01070 DeleteDC(hdcTarget); 01071 ReleaseDC(hWnd, hdc); 01072 01073 update_preview_sizes(hWnd, TRUE); 01074 update_preview(hMainWnd); 01075 break; 01076 } 01077 01078 case WM_PAINT: 01079 return print_preview(hWnd); 01080 01081 case WM_SIZE: 01082 { 01083 update_preview_sizes(hWnd, FALSE); 01084 InvalidateRect(hWnd, NULL, FALSE); 01085 break; 01086 } 01087 01088 case WM_VSCROLL: 01089 case WM_HSCROLL: 01090 { 01091 SCROLLINFO si; 01092 RECT rc; 01093 int nBar = (msg == WM_VSCROLL) ? SB_VERT : SB_HORZ; 01094 int origPos; 01095 01096 GetClientRect(hWnd, &rc); 01097 si.cbSize = sizeof(si); 01098 si.fMask = SIF_ALL; 01099 GetScrollInfo(hWnd, nBar, &si); 01100 origPos = si.nPos; 01101 switch(LOWORD(wParam)) 01102 { 01103 case SB_TOP: /* == SB_LEFT */ 01104 si.nPos = si.nMin; 01105 break; 01106 case SB_BOTTOM: /* == SB_RIGHT */ 01107 si.nPos = si.nMax; 01108 break; 01109 case SB_LINEUP: /* == SB_LINELEFT */ 01110 si.nPos -= si.nPage / 10; 01111 break; 01112 case SB_LINEDOWN: /* == SB_LINERIGHT */ 01113 si.nPos += si.nPage / 10; 01114 break; 01115 case SB_PAGEUP: /* == SB_PAGELEFT */ 01116 si.nPos -= si.nPage; 01117 break; 01118 case SB_PAGEDOWN: /* SB_PAGERIGHT */ 01119 si.nPos += si.nPage; 01120 break; 01121 case SB_THUMBTRACK: 01122 si.nPos = si.nTrackPos; 01123 break; 01124 } 01125 si.fMask = SIF_POS; 01126 SetScrollInfo(hWnd, nBar, &si, TRUE); 01127 GetScrollInfo(hWnd, nBar, &si); 01128 if (si.nPos != origPos) 01129 { 01130 int amount = origPos - si.nPos; 01131 if (msg == WM_VSCROLL) 01132 ScrollWindow(hWnd, 0, amount, NULL, NULL); 01133 else 01134 ScrollWindow(hWnd, amount, 0, NULL, NULL); 01135 } 01136 return 0; 01137 } 01138 01139 case WM_SETCURSOR: 01140 { 01141 POINT pt; 01142 RECT rc; 01143 int bHittest = FALSE; 01144 DWORD messagePos = GetMessagePos(); 01145 pt.x = (short)LOWORD(messagePos); 01146 pt.y = (short)HIWORD(messagePos); 01147 ScreenToClient(hWnd, &pt); 01148 01149 GetClientRect(hWnd, &rc); 01150 if (PtInRect(&rc, pt)) 01151 { 01152 pt.x += GetScrollPos(hWnd, SB_HORZ); 01153 pt.y += GetScrollPos(hWnd, SB_VERT); 01154 bHittest = preview_page_hittest(pt); 01155 } 01156 01157 if (bHittest) 01158 SetCursor(LoadCursorW(GetModuleHandleW(0), 01159 MAKEINTRESOURCEW(IDC_ZOOM))); 01160 else 01161 SetCursor(LoadCursorW(NULL, (WCHAR*)IDC_ARROW)); 01162 01163 return TRUE; 01164 } 01165 01166 case WM_LBUTTONDOWN: 01167 { 01168 int page; 01169 POINT pt; 01170 pt.x = (short)LOWORD(lParam) + GetScrollPos(hWnd, SB_HORZ); 01171 pt.y = (short)HIWORD(lParam) + GetScrollPos(hWnd, SB_VERT); 01172 if ((page = preview_page_hittest(pt)) > 0) 01173 { 01174 HWND hMainWnd = GetParent(hWnd); 01175 01176 /* Convert point from client coordinate to unzoomed page 01177 * coordinate. */ 01178 pt.x -= preview.spacing.cx; 01179 if (page > 1) 01180 pt.x -= preview.bmScaledSize.cx + preview.spacing.cx; 01181 pt.y -= preview.spacing.cy; 01182 pt.x /= preview.zoomratio; 01183 pt.y /= preview.zoomratio; 01184 01185 if (preview.zoomlevel == 0) 01186 preview.saved_pages_shown = preview.pages_shown; 01187 preview.zoomlevel = (preview.zoomlevel + 1) % 3; 01188 preview.zoomratio = 0; 01189 if (preview.zoomlevel == 0 && preview.saved_pages_shown > 1) 01190 { 01191 toggle_num_pages(hMainWnd); 01192 } else if (preview.pages_shown > 1) { 01193 if (page >= 2) preview.page++; 01194 toggle_num_pages(hMainWnd); 01195 } else { 01196 update_preview_sizes(hWnd, TRUE); 01197 InvalidateRect(hWnd, NULL, FALSE); 01198 update_preview_buttons(hMainWnd); 01199 } 01200 01201 if (preview.zoomlevel > 0) { 01202 SCROLLINFO si; 01203 /* Convert the coordinate back to client coordinate. */ 01204 pt.x *= preview.zoomratio; 01205 pt.y *= preview.zoomratio; 01206 pt.x += preview.spacing.cx; 01207 pt.y += preview.spacing.cy; 01208 /* Scroll to center view at that point on the page */ 01209 si.cbSize = sizeof(si); 01210 si.fMask = SIF_PAGE; 01211 GetScrollInfo(hWnd, SB_HORZ, &si); 01212 pt.x -= si.nPage / 2; 01213 SetScrollPos(hWnd, SB_HORZ, pt.x, TRUE); 01214 GetScrollInfo(hWnd, SB_VERT, &si); 01215 pt.y -= si.nPage / 2; 01216 SetScrollPos(hWnd, SB_VERT, pt.y, TRUE); 01217 } 01218 } 01219 } 01220 01221 default: 01222 return DefWindowProcW(hWnd, msg, wParam, lParam); 01223 } 01224 01225 return 0; 01226 } 01227 01228 LRESULT preview_command(HWND hWnd, WPARAM wParam) 01229 { 01230 switch(LOWORD(wParam)) 01231 { 01232 case ID_FILE_EXIT: 01233 PostMessageW(hWnd, WM_CLOSE, 0, 0); 01234 break; 01235 01236 case ID_PREVIEW_NEXTPAGE: 01237 case ID_PREVIEW_PREVPAGE: 01238 { 01239 if(LOWORD(wParam) == ID_PREVIEW_NEXTPAGE) 01240 preview.page++; 01241 else 01242 preview.page--; 01243 01244 update_preview(hWnd); 01245 } 01246 break; 01247 01248 case ID_PREVIEW_NUMPAGES: 01249 toggle_num_pages(hWnd); 01250 break; 01251 01252 case ID_PREVIEW_ZOOMIN: 01253 if (preview.zoomlevel < 2) 01254 { 01255 if (preview.zoomlevel == 0) 01256 preview.saved_pages_shown = preview.pages_shown; 01257 preview.zoomlevel++; 01258 preview.zoomratio = 0; 01259 if (preview.pages_shown > 1) 01260 { 01261 /* Forced switch to one page when zooming in. */ 01262 toggle_num_pages(hWnd); 01263 } else { 01264 HWND hwndPreview = GetDlgItem(hWnd, IDC_PREVIEW); 01265 update_preview_sizes(hwndPreview, TRUE); 01266 InvalidateRect(hwndPreview, NULL, FALSE); 01267 update_preview_buttons(hWnd); 01268 } 01269 } 01270 break; 01271 01272 case ID_PREVIEW_ZOOMOUT: 01273 if (preview.zoomlevel > 0) 01274 { 01275 HWND hwndPreview = GetDlgItem(hWnd, IDC_PREVIEW); 01276 preview.zoomlevel--; 01277 preview.zoomratio = 0; 01278 if (preview.zoomlevel == 0 && preview.saved_pages_shown > 1) { 01279 toggle_num_pages(hWnd); 01280 } else { 01281 update_preview_sizes(hwndPreview, TRUE); 01282 InvalidateRect(hwndPreview, NULL, FALSE); 01283 update_preview_buttons(hWnd); 01284 } 01285 } 01286 break; 01287 01288 case ID_PRINT: 01289 dialog_print(hWnd, preview.wszFileName); 01290 SendMessageW(hWnd, WM_CLOSE, 0, 0); 01291 break; 01292 } 01293 01294 return 0; 01295 } Generated on Fri May 25 2012 04:15:48 for ReactOS by
1.7.6.1
|