From 0c46da86bf5f5bb44ca7e1e4a8e21c38579a7f25 Mon Sep 17 00:00:00 2001 From: Dylan Smith Date: Fri, 29 Jan 2010 03:02:41 -0500 Subject: [PATCH] wordpad: Implement zooming in for print preview. The preview is now drawn onto it's own window rather directly onto the client area of the top level window. This is done to allow for scrollbars, since the page won't usually fit in the window when zoomed in. Refactoring was needed as a result of this, and in order to provide more granularity for updates to avoid EM_FORMATRANGE messages being sent when the page the same page is being displayed. --- programs/wordpad/Da.rc | 2 + programs/wordpad/De.rc | 2 + programs/wordpad/En.rc | 2 + programs/wordpad/Fr.rc | 2 + programs/wordpad/Hu.rc | 2 + programs/wordpad/Ja.rc | 2 + programs/wordpad/Ko.rc | 2 + programs/wordpad/Lt.rc | 2 + programs/wordpad/Nl.rc | 2 + programs/wordpad/No.rc | 2 + programs/wordpad/Pl.rc | 2 + programs/wordpad/Pt.rc | 2 + programs/wordpad/Ru.rc | 2 + programs/wordpad/Si.rc | 2 + programs/wordpad/Sv.rc | 2 + programs/wordpad/Tr.rc | 2 + programs/wordpad/Zh.rc | 2 + programs/wordpad/print.c | 423 ++++++++++++++++++++++++++++--------- programs/wordpad/wordpad.c | 21 +- programs/wordpad/wordpad.h | 15 +- 20 files changed, 386 insertions(+), 107 deletions(-) diff --git a/programs/wordpad/Da.rc b/programs/wordpad/Da.rc index 34789469e5e..b57a45e96a9 100644 --- a/programs/wordpad/Da.rc +++ b/programs/wordpad/Da.rc @@ -218,6 +218,8 @@ BEGIN STRING_PREVIEW_PREVPAGE, "Forrige side" STRING_PREVIEW_TWOPAGES, "To sider" STRING_PREVIEW_ONEPAGE, "n side" + STRING_PREVIEW_ZOOMIN, "Zoom in" + STRING_PREVIEW_ZOOMOUT, "Zoom out" STRING_PREVIEW_CLOSE, "Luk" END diff --git a/programs/wordpad/De.rc b/programs/wordpad/De.rc index 18181b2efba..6f6a982c6c3 100644 --- a/programs/wordpad/De.rc +++ b/programs/wordpad/De.rc @@ -220,6 +220,8 @@ BEGIN STRING_PREVIEW_PREVPAGE, "&Vorherige" STRING_PREVIEW_TWOPAGES, "Zwei Seiten" STRING_PREVIEW_ONEPAGE, "Eine Seite" + STRING_PREVIEW_ZOOMIN, "Zoom in" + STRING_PREVIEW_ZOOMOUT, "Zoom out" STRING_PREVIEW_CLOSE, "&Schließen" END diff --git a/programs/wordpad/En.rc b/programs/wordpad/En.rc index b6ade3aaf3d..03e17f82f1e 100644 --- a/programs/wordpad/En.rc +++ b/programs/wordpad/En.rc @@ -210,6 +210,8 @@ BEGIN STRING_PREVIEW_PREVPAGE, "Previous page" STRING_PREVIEW_TWOPAGES, "Two pages" STRING_PREVIEW_ONEPAGE, "One page" + STRING_PREVIEW_ZOOMIN, "Zoom in" + STRING_PREVIEW_ZOOMOUT, "Zoom out" STRING_PREVIEW_CLOSE, "Close" STRING_UNITS_CM, "cm" END diff --git a/programs/wordpad/Fr.rc b/programs/wordpad/Fr.rc index 9691c0b0cc3..34d3db44e32 100644 --- a/programs/wordpad/Fr.rc +++ b/programs/wordpad/Fr.rc @@ -221,6 +221,8 @@ BEGIN STRING_PREVIEW_PREVPAGE, "Page précédente" STRING_PREVIEW_TWOPAGES, "Deux pages" STRING_PREVIEW_ONEPAGE, "Une page" + STRING_PREVIEW_ZOOMIN, "Zoom in" + STRING_PREVIEW_ZOOMOUT, "Zoom out" STRING_PREVIEW_CLOSE, "Fermer" END diff --git a/programs/wordpad/Hu.rc b/programs/wordpad/Hu.rc index 74926e1e597..dc2363551ed 100644 --- a/programs/wordpad/Hu.rc +++ b/programs/wordpad/Hu.rc @@ -218,6 +218,8 @@ BEGIN STRING_PREVIEW_PREVPAGE, "Previous page" STRING_PREVIEW_TWOPAGES, "Two pages" STRING_PREVIEW_ONEPAGE, "One page" + STRING_PREVIEW_ZOOMIN, "Zoom in" + STRING_PREVIEW_ZOOMOUT, "Zoom out" STRING_PREVIEW_CLOSE, "Close" END diff --git a/programs/wordpad/Ja.rc b/programs/wordpad/Ja.rc index fc21c5a4e74..013820c6050 100644 --- a/programs/wordpad/Ja.rc +++ b/programs/wordpad/Ja.rc @@ -221,6 +221,8 @@ BEGIN STRING_PREVIEW_PREVPAGE, "前のページ" STRING_PREVIEW_TWOPAGES, "2ページ" STRING_PREVIEW_ONEPAGE, "1ページ" + STRING_PREVIEW_ZOOMIN, "Zoom in" + STRING_PREVIEW_ZOOMOUT, "Zoom out" STRING_PREVIEW_CLOSE, "閉じる" END diff --git a/programs/wordpad/Ko.rc b/programs/wordpad/Ko.rc index 2e460afdae9..705644fb9ce 100644 --- a/programs/wordpad/Ko.rc +++ b/programs/wordpad/Ko.rc @@ -212,6 +212,8 @@ BEGIN STRING_PREVIEW_PREVPAGE, " " STRING_PREVIEW_TWOPAGES, " " STRING_PREVIEW_ONEPAGE, " " + STRING_PREVIEW_ZOOMIN, "Zoom in" + STRING_PREVIEW_ZOOMOUT, "Zoom out" STRING_PREVIEW_CLOSE, "ݱ" STRING_UNITS_CM, "cm" END diff --git a/programs/wordpad/Lt.rc b/programs/wordpad/Lt.rc index 91fbfcaba91..667a9c551a9 100644 --- a/programs/wordpad/Lt.rc +++ b/programs/wordpad/Lt.rc @@ -221,6 +221,8 @@ BEGIN STRING_PREVIEW_PREVPAGE, "Ankstesnis puslapis" STRING_PREVIEW_TWOPAGES, "Du puslapiai" STRING_PREVIEW_ONEPAGE, "Vienas puslapis" + STRING_PREVIEW_ZOOMIN, "Zoom in" + STRING_PREVIEW_ZOOMOUT, "Zoom out" STRING_PREVIEW_CLOSE, "Užverti" END diff --git a/programs/wordpad/Nl.rc b/programs/wordpad/Nl.rc index 10729e41df5..3d1891d6dbd 100644 --- a/programs/wordpad/Nl.rc +++ b/programs/wordpad/Nl.rc @@ -211,6 +211,8 @@ BEGIN STRING_PREVIEW_PREVPAGE, "Vorige pagina" STRING_PREVIEW_TWOPAGES, "Twee pagina's" STRING_PREVIEW_ONEPAGE, "Een pagina" + STRING_PREVIEW_ZOOMIN, "Zoom in" + STRING_PREVIEW_ZOOMOUT, "Zoom out" STRING_PREVIEW_CLOSE, "Sluiten" END diff --git a/programs/wordpad/No.rc b/programs/wordpad/No.rc index 5a4fdbf8c30..44487db9fa0 100644 --- a/programs/wordpad/No.rc +++ b/programs/wordpad/No.rc @@ -220,6 +220,8 @@ BEGIN STRING_PREVIEW_PREVPAGE, "Forrige side" STRING_PREVIEW_TWOPAGES, "To sider" STRING_PREVIEW_ONEPAGE, "Én side" + STRING_PREVIEW_ZOOMIN, "Zoom in" + STRING_PREVIEW_ZOOMOUT, "Zoom out" STRING_PREVIEW_CLOSE, "Lukk" END diff --git a/programs/wordpad/Pl.rc b/programs/wordpad/Pl.rc index ab72104e5d0..9371f78bbff 100644 --- a/programs/wordpad/Pl.rc +++ b/programs/wordpad/Pl.rc @@ -219,6 +219,8 @@ BEGIN STRING_PREVIEW_PREVPAGE, "Poprz. strona" STRING_PREVIEW_TWOPAGES, "Two pages" STRING_PREVIEW_ONEPAGE, "One page" + STRING_PREVIEW_ZOOMIN, "Zoom in" + STRING_PREVIEW_ZOOMOUT, "Zoom out" STRING_PREVIEW_CLOSE, "Zamknij" END diff --git a/programs/wordpad/Pt.rc b/programs/wordpad/Pt.rc index fd512c9f1aa..ec4708aad99 100644 --- a/programs/wordpad/Pt.rc +++ b/programs/wordpad/Pt.rc @@ -222,6 +222,8 @@ BEGIN STRING_PREVIEW_PREVPAGE, "Página anterior" STRING_PREVIEW_TWOPAGES, "Duas páginas" STRING_PREVIEW_ONEPAGE, "Uma página" + STRING_PREVIEW_ZOOMIN, "Zoom in" + STRING_PREVIEW_ZOOMOUT, "Zoom out" STRING_PREVIEW_CLOSE, "Fechar" END diff --git a/programs/wordpad/Ru.rc b/programs/wordpad/Ru.rc index 2841f2ff694..01f78fe9275 100644 --- a/programs/wordpad/Ru.rc +++ b/programs/wordpad/Ru.rc @@ -221,6 +221,8 @@ BEGIN STRING_PREVIEW_PREVPAGE, "Предыдущая страница" STRING_PREVIEW_TWOPAGES, "Две страницы" STRING_PREVIEW_ONEPAGE, "Одна страница" + STRING_PREVIEW_ZOOMIN, "Zoom in" + STRING_PREVIEW_ZOOMOUT, "Zoom out" STRING_PREVIEW_CLOSE, "Закрыть" END diff --git a/programs/wordpad/Si.rc b/programs/wordpad/Si.rc index 1b6d37fd41c..fbf25285d7c 100644 --- a/programs/wordpad/Si.rc +++ b/programs/wordpad/Si.rc @@ -220,6 +220,8 @@ BEGIN STRING_PREVIEW_PREVPAGE, "Prejšnja" STRING_PREVIEW_TWOPAGES, "Dve strani" STRING_PREVIEW_ONEPAGE, "Ena stran" + STRING_PREVIEW_ZOOMIN, "Zoom in" + STRING_PREVIEW_ZOOMOUT, "Zoom out" STRING_PREVIEW_CLOSE, "Zapri" END diff --git a/programs/wordpad/Sv.rc b/programs/wordpad/Sv.rc index d94e6e3d190..0e97c8d7bb8 100644 --- a/programs/wordpad/Sv.rc +++ b/programs/wordpad/Sv.rc @@ -220,6 +220,8 @@ BEGIN STRING_PREVIEW_PREVPAGE, "Föregående sida" STRING_PREVIEW_TWOPAGES, "Två sidor" STRING_PREVIEW_ONEPAGE, "En sida" + STRING_PREVIEW_ZOOMIN, "Zoom in" + STRING_PREVIEW_ZOOMOUT, "Zoom out" STRING_PREVIEW_CLOSE, "Stäng" END diff --git a/programs/wordpad/Tr.rc b/programs/wordpad/Tr.rc index 92290371d37..ddfa4c0ac61 100644 --- a/programs/wordpad/Tr.rc +++ b/programs/wordpad/Tr.rc @@ -220,6 +220,8 @@ BEGIN STRING_PREVIEW_PREVPAGE, "Previous page" STRING_PREVIEW_TWOPAGES, "Two pages" STRING_PREVIEW_ONEPAGE, "One page" + STRING_PREVIEW_ZOOMIN, "Zoom in" + STRING_PREVIEW_ZOOMOUT, "Zoom out" STRING_PREVIEW_CLOSE, "Close" END diff --git a/programs/wordpad/Zh.rc b/programs/wordpad/Zh.rc index d8ceec43a1a..e9ab5af2920 100644 --- a/programs/wordpad/Zh.rc +++ b/programs/wordpad/Zh.rc @@ -223,6 +223,8 @@ BEGIN STRING_PREVIEW_PREVPAGE, "上一页" STRING_PREVIEW_TWOPAGES, "双页" STRING_PREVIEW_ONEPAGE, "单页" + STRING_PREVIEW_ZOOMIN, "Zoom in" + STRING_PREVIEW_ZOOMOUT, "Zoom out" STRING_PREVIEW_CLOSE, "关闭" END diff --git a/programs/wordpad/print.c b/programs/wordpad/print.c index 18a6de16799..79b43a6f494 100644 --- a/programs/wordpad/print.c +++ b/programs/wordpad/print.c @@ -33,6 +33,12 @@ typedef struct _previewinfo HDC hdcSized; HDC hdcSized2; RECT window; + RECT rcPage; + SIZE bmSize; + SIZE bmScaledSize; + SIZE spacing; + float zoomratio; + int zoomlevel; LPWSTR wszFileName; } previewinfo, *ppreviewinfo; @@ -42,6 +48,8 @@ static HGLOBAL devNames; static RECT margins; static previewinfo preview; +extern const WCHAR wszPreviewWndClass[]; + static const WCHAR var_pagemargin[] = {'P','a','g','e','M','a','r','g','i','n',0}; static LPWSTR get_print_file_filter(HWND hMainWnd) @@ -448,7 +456,9 @@ static void preview_bar_show(HWND hMainWnd, BOOL show) AddTextButton(hReBar, STRING_PREVIEW_NEXTPAGE, ID_PREVIEW_NEXTPAGE, BANDID_PREVIEW_BTN2); AddTextButton(hReBar, STRING_PREVIEW_PREVPAGE, ID_PREVIEW_PREVPAGE, BANDID_PREVIEW_BTN3); AddTextButton(hReBar, STRING_PREVIEW_TWOPAGES, ID_PREVIEW_NUMPAGES, BANDID_PREVIEW_BTN4); - AddTextButton(hReBar, STRING_PREVIEW_CLOSE, ID_FILE_EXIT, BANDID_PREVIEW_BTN5); + AddTextButton(hReBar, STRING_PREVIEW_ZOOMIN, ID_PREVIEW_ZOOMIN, BANDID_PREVIEW_BTN5); + AddTextButton(hReBar, STRING_PREVIEW_ZOOMOUT, ID_PREVIEW_ZOOMOUT, BANDID_PREVIEW_BTN6); + AddTextButton(hReBar, STRING_PREVIEW_CLOSE, ID_FILE_EXIT, BANDID_PREVIEW_BTN7); hStatic = CreateWindowW(WC_STATICW, NULL, WS_VISIBLE | WS_CHILD, 0, 0, 0, 0, @@ -471,23 +481,220 @@ static void preview_bar_show(HWND hMainWnd, BOOL show) } } +static const int min_spacing = 10; + +static void update_preview_scrollbars(HWND hwndPreview, RECT *window) +{ + SCROLLINFO sbi; + sbi.cbSize = sizeof(sbi); + sbi.fMask = SIF_PAGE|SIF_RANGE; + sbi.nMin = 0; + if (preview.zoomlevel == 0) + { + /* Hide scrollbars when zoomed out. */ + sbi.nMax = 0; + sbi.nPage = window->right; + SetScrollInfo(hwndPreview, SB_HORZ, &sbi, TRUE); + sbi.nPage = window->bottom; + SetScrollInfo(hwndPreview, SB_VERT, &sbi, TRUE); + } else { + if (!preview.hdc2) + sbi.nMax = preview.bmScaledSize.cx + min_spacing * 2; + else + sbi.nMax = preview.bmScaledSize.cx * 2 + min_spacing * 3; + sbi.nPage = window->right; + SetScrollInfo(hwndPreview, SB_HORZ, &sbi, TRUE); + /* Change in the horizontal scrollbar visibility affects the + * client rect, so update the client rect. */ + GetClientRect(hwndPreview, window); + sbi.nMax = preview.bmScaledSize.cy + min_spacing * 2; + sbi.nPage = window->bottom; + SetScrollInfo(hwndPreview, SB_VERT, &sbi, TRUE); + } +} + +static void update_preview_sizes(HWND hwndPreview, BOOL zoomLevelUpdated) +{ + RECT window; + + GetClientRect(hwndPreview, &window); + + /* The zoom ratio isn't updated for partial zoom because of resizing the window. */ + if (zoomLevelUpdated || preview.zoomlevel != 1) + { + float ratio, ratioHeight, ratioWidth; + if (preview.zoomlevel == 2) + { + ratio = 1.0; + } else { + ratioHeight = (window.bottom - min_spacing * 2) / (float)preview.bmSize.cy; + + if(preview.hdc2) + ratioWidth = ((window.right - min_spacing * 3) / 2.0) / (float)preview.bmSize.cx; + else + ratioWidth = (window.right - min_spacing * 2) / (float)preview.bmSize.cx; + + if(ratioWidth > ratioHeight) + ratio = ratioHeight; + else + ratio = ratioWidth; + + if (preview.zoomlevel == 1) + ratio += (1.0 - ratio) / 2; + } + preview.zoomratio = ratio; + } + + preview.bmScaledSize.cx = preview.bmSize.cx * preview.zoomratio; + preview.bmScaledSize.cy = preview.bmSize.cy * preview.zoomratio; + + preview.spacing.cy = max(min_spacing, (window.bottom - preview.bmScaledSize.cy) / 2); + + if(!preview.hdc2) + preview.spacing.cx = (window.right - preview.bmScaledSize.cx) / 2; + else + preview.spacing.cx = (window.right - preview.bmScaledSize.cx * 2) / 3; + if (preview.spacing.cx < min_spacing) + preview.spacing.cx = min_spacing; + + update_preview_scrollbars(hwndPreview, &window); +} + +/* Update for zoom ratio changes with same page. */ +static void update_scaled_preview(HWND hMainWnd) +{ + HWND hwndPreview = GetDlgItem(hMainWnd, IDC_PREVIEW); + preview.window.right = 0; + InvalidateRect(hwndPreview, NULL, TRUE); +} + +LRESULT CALLBACK preview_proc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam) +{ + switch(msg) + { + case WM_CREATE: + { + HWND hEditorWnd = GetDlgItem(GetParent(hWnd), IDC_EDITOR); + FORMATRANGE fr; + GETTEXTLENGTHEX gt = {GTL_DEFAULT, 1200}; + HDC hdc = GetDC(hWnd); + HDC hdcTarget = make_dc(); + + fr.rc = preview.rcPage = get_print_rect(hdcTarget); + preview.rcPage.bottom += margins.bottom; + preview.rcPage.right += margins.right; + preview.rcPage.top = preview.rcPage.left = 0; + fr.rcPage = preview.rcPage; + + preview.bmSize.cx = twips_to_pixels(preview.rcPage.right, GetDeviceCaps(hdc, LOGPIXELSX)); + preview.bmSize.cy = twips_to_pixels(preview.rcPage.bottom, GetDeviceCaps(hdc, LOGPIXELSY)); + + fr.hdc = CreateCompatibleDC(hdc); + fr.hdcTarget = hdcTarget; + fr.chrg.cpMin = 0; + fr.chrg.cpMax = SendMessageW(hEditorWnd, EM_GETTEXTLENGTHEX, (WPARAM)>, 0); + preview.pages = get_num_pages(hEditorWnd, fr); + DeleteDC(fr.hdc); + + update_preview_sizes(hWnd, TRUE); + break; + } + + case WM_PAINT: + return print_preview(hWnd); + + case WM_SIZE: + { + update_preview_sizes(hWnd, FALSE); + update_scaled_preview(hWnd); + break; + } + + case WM_VSCROLL: + case WM_HSCROLL: + { + SCROLLINFO si; + RECT rc; + int nBar = (msg == WM_VSCROLL) ? SB_VERT : SB_HORZ; + int origPos; + + GetClientRect(hWnd, &rc); + si.cbSize = sizeof(si); + si.fMask = SIF_ALL; + GetScrollInfo(hWnd, nBar, &si); + origPos = si.nPos; + switch(LOWORD(wParam)) + { + case SB_TOP: /* == SB_LEFT */ + si.nPos = si.nMin; + break; + case SB_BOTTOM: /* == SB_RIGHT */ + si.nPos = si.nMax; + break; + case SB_LINEUP: /* == SB_LINELEFT */ + si.nPos -= si.nPage / 10; + break; + case SB_LINEDOWN: /* == SB_LINERIGHT */ + si.nPos += si.nPage / 10; + break; + case SB_PAGEUP: /* == SB_PAGELEFT */ + si.nPos -= si.nPage; + break; + case SB_PAGEDOWN: /* SB_PAGERIGHT */ + si.nPos += si.nPage; + break; + case SB_THUMBTRACK: + si.nPos = si.nTrackPos; + break; + } + si.fMask = SIF_POS; + SetScrollInfo(hWnd, nBar, &si, TRUE); + GetScrollInfo(hWnd, nBar, &si); + if (si.nPos != origPos) + { + int amount = origPos - si.nPos; + if (msg == WM_VSCROLL) + ScrollWindow(hWnd, 0, amount, NULL, NULL); + else + ScrollWindow(hWnd, amount, 0, NULL, NULL); + } + return 0; + } + + default: + return DefWindowProcW(hWnd, msg, wParam, lParam); + } + + return 0; +} + void init_preview(HWND hMainWnd, LPWSTR wszFileName) { + HWND hwndPreview; + HINSTANCE hInstance = GetModuleHandleW(0); preview.page = 1; preview.hdc = 0; preview.hdc2 = 0; preview.wszFileName = wszFileName; + preview.zoomratio = 0; + preview.zoomlevel = 0; preview_bar_show(hMainWnd, TRUE); + + hwndPreview = CreateWindowExW(0, wszPreviewWndClass, NULL, + WS_VISIBLE | WS_CHILD | WS_VSCROLL | WS_HSCROLL, + 0, 0, 200, 10, hMainWnd, (HMENU)IDC_PREVIEW, hInstance, NULL); } void close_preview(HWND hMainWnd) { + HWND hwndPreview = GetDlgItem(hMainWnd, IDC_PREVIEW); preview.window.right = 0; preview.window.bottom = 0; preview.page = 0; preview.pages = 0; preview_bar_show(hMainWnd, FALSE); + DestroyWindow(hwndPreview); } BOOL preview_isactive(void) @@ -669,46 +876,53 @@ static void draw_preview_page(HDC hdc, HDC* hdcSized, FORMATRANGE* lpFr, float r static void draw_preview(HWND hEditorWnd, FORMATRANGE* lpFr, int bmWidth, int bmHeight, RECT* paper, int page) { HBITMAP hBitmapCapture = CreateCompatibleBitmap(lpFr->hdc, bmWidth, bmHeight); + int bottom; char_from_pagenum(hEditorWnd, lpFr, page); SelectObject(lpFr->hdc, hBitmapCapture); FillRect(lpFr->hdc, paper, GetStockObject(WHITE_BRUSH)); + bottom = lpFr->rc.bottom; SendMessageW(hEditorWnd, EM_FORMATRANGE, TRUE, (LPARAM)lpFr); - /* EM_FORMATRANGE sets fr.rc to indicate the area printed in, but we want to - keep the original for drawing margins */ - lpFr->rc = get_print_rect(lpFr->hdcTarget); + /* EM_FORMATRANGE sets fr.rc.bottom to indicate the area printed in, + * but we want to keep the original for drawing margins */ + lpFr->rc.bottom = bottom; SendMessageW(hEditorWnd, EM_FORMATRANGE, FALSE, 0); } -LRESULT print_preview(HWND hMainWnd) +static void update_preview_buttons(HWND hMainWnd) +{ + HWND hReBar = GetDlgItem(hMainWnd, IDC_REBAR); + EnableWindow(GetDlgItem(hReBar, ID_PREVIEW_PREVPAGE), preview.page > 1); + EnableWindow(GetDlgItem(hReBar, ID_PREVIEW_NEXTPAGE), preview.hdc2 ? + (preview.page + 1) < preview.pages : + preview.page < preview.pages); + EnableWindow(GetDlgItem(hReBar, ID_PREVIEW_NUMPAGES), preview.pages > 1 && preview.zoomlevel == 0); + EnableWindow(GetDlgItem(hReBar, ID_PREVIEW_ZOOMIN), preview.zoomlevel < 2); + EnableWindow(GetDlgItem(hReBar, ID_PREVIEW_ZOOMOUT), preview.zoomlevel > 0); +} + +LRESULT print_preview(HWND hwndPreview) { FORMATRANGE fr; - GETTEXTLENGTHEX gt; HDC hdc; RECT window, background; - int bmWidth, bmHeight, bmNewWidth, bmNewHeight; - float ratioWidth, ratioHeight, ratio; - int xOffset, yOffset; - int barheight; - float spacing = 10.0; - HWND hReBar = GetDlgItem(hMainWnd, IDC_REBAR); PAINTSTRUCT ps; + HWND hMainWnd = GetParent(hwndPreview); + POINT scrollpos; - hdc = BeginPaint(hMainWnd, &ps); - GetClientRect(hMainWnd, &window); + hdc = BeginPaint(hwndPreview, &ps); + GetClientRect(hwndPreview, &window); fr.hdcTarget = make_dc(); - fr.rc = get_print_rect(fr.hdcTarget); - fr.rcPage.left = 0; - fr.rcPage.top = 0; - fr.rcPage.bottom = fr.rc.bottom + margins.bottom; - fr.rcPage.right = fr.rc.right + margins.right; - - bmWidth = twips_to_pixels(fr.rcPage.right, GetDeviceCaps(hdc, LOGPIXELSX)); - bmHeight = twips_to_pixels(fr.rcPage.bottom, GetDeviceCaps(hdc, LOGPIXELSY)); + fr.rc = fr.rcPage = preview.rcPage; + fr.rc.left += margins.left; + fr.rc.top += margins.top; + fr.rc.bottom -= margins.bottom; + fr.rc.right -= margins.right; if(!preview.hdc) { + GETTEXTLENGTHEX gt; RECT paper; HWND hEditorWnd = GetDlgItem(hMainWnd, IDC_EDITOR); @@ -721,111 +935,113 @@ LRESULT print_preview(HWND hMainWnd) preview.hdc2 = CreateCompatibleDC(hdc); } - fr.hdc = preview.hdc; gt.flags = GTL_DEFAULT; gt.codepage = 1200; fr.chrg.cpMin = 0; fr.chrg.cpMax = SendMessageW(hEditorWnd, EM_GETTEXTLENGTHEX, (WPARAM)>, 0); paper.left = 0; - paper.right = bmWidth; + paper.right = preview.bmSize.cx; paper.top = 0; - paper.bottom = bmHeight; - - if(!preview.pages) - preview.pages = get_num_pages(hEditorWnd, fr); + paper.bottom = preview.bmSize.cy; fr.hdc = preview.hdc; - draw_preview(hEditorWnd, &fr, bmWidth, bmHeight, &paper, preview.page); + draw_preview(hEditorWnd, &fr, preview.bmSize.cx, preview.bmSize.cy, &paper, preview.page); if(preview.hdc2) { fr.hdc = preview.hdc2; - draw_preview(hEditorWnd, &fr, bmWidth, bmHeight, &paper, preview.page + 1); + draw_preview(hEditorWnd, &fr, preview.bmSize.cx, preview.bmSize.cy, &fr.rcPage, preview.page + 1); } - EnableWindow(GetDlgItem(hReBar, ID_PREVIEW_PREVPAGE), preview.page > 1); - EnableWindow(GetDlgItem(hReBar, ID_PREVIEW_NEXTPAGE), preview.hdc2 ? - (preview.page + 1) < preview.pages : - preview.page < preview.pages); - EnableWindow(GetDlgItem(hReBar, ID_PREVIEW_NUMPAGES), preview.pages > 1); + update_preview_buttons(hMainWnd); } - barheight = SendMessageW(hReBar, RB_GETBARHEIGHT, 0, 0); - ratioHeight = (window.bottom - spacing * 2 - barheight) / (float)bmHeight; - - if(preview.hdc2) - ratioWidth = ((window.right - spacing * 3) / 2.0) / (float)bmWidth; - else - ratioWidth = (window.right - spacing * 2) / (float)bmWidth; - - if(ratioWidth > ratioHeight) - ratio = ratioHeight; - else - ratio = ratioWidth; - - bmNewWidth = (int)((float)bmWidth * ratio); - bmNewHeight = (int)((float)bmHeight * ratio); - - yOffset = ((window.bottom - bmNewHeight + barheight) / 2); - - if(!preview.hdc2) - xOffset = (window.right - bmNewWidth) / 2; - else - xOffset = (window.right - bmNewWidth * 2) / 3; - - window.top = barheight; FillRect(hdc, &window, GetStockObject(GRAY_BRUSH)); - background.left = xOffset - 2; - background.right = xOffset + bmNewWidth + 2; - background.top = yOffset - 2; - background.bottom = yOffset + bmNewHeight + 2; + scrollpos.x = GetScrollPos(hwndPreview, SB_HORZ); + scrollpos.y = GetScrollPos(hwndPreview, SB_VERT); + + background.left = preview.spacing.cx - 2 - scrollpos.x; + background.right = background.left + preview.bmScaledSize.cx + 4; + background.top = preview.spacing.cy - 2 - scrollpos.y; + background.bottom = background.top + preview.bmScaledSize.cy + 4; FillRect(hdc, &background, GetStockObject(BLACK_BRUSH)); + if(preview.hdc2) + { + background.left += preview.bmScaledSize.cx + preview.spacing.cx; + background.right += preview.bmScaledSize.cx + preview.spacing.cx; + + FillRect(hdc, &background, GetStockObject(BLACK_BRUSH)); + } + if(window.right != preview.window.right || window.bottom != preview.window.bottom) { - draw_preview_page(preview.hdc, &preview.hdcSized, &fr, ratio, bmNewWidth, bmNewHeight, bmWidth, bmHeight); + draw_preview_page(preview.hdc, &preview.hdcSized, &fr, preview.zoomratio, + preview.bmScaledSize.cx, preview.bmScaledSize.cy, + preview.bmSize.cx, preview.bmSize.cy); if(preview.hdc2) { - background.left += bmNewWidth + xOffset; - background.right += bmNewWidth + xOffset; - - FillRect(hdc, &background, GetStockObject(BLACK_BRUSH)); - - draw_preview_page(preview.hdc2, &preview.hdcSized2, &fr, ratio, bmNewWidth, bmNewHeight, bmWidth, bmHeight); + draw_preview_page(preview.hdc2, &preview.hdcSized2, &fr, preview.zoomratio, + preview.bmScaledSize.cx, preview.bmScaledSize.cy, + preview.bmSize.cx, preview.bmSize.cy); } } - BitBlt(hdc, xOffset, yOffset, bmNewWidth, bmNewHeight, preview.hdcSized, 0, 0, SRCCOPY); + BitBlt(hdc, preview.spacing.cx - scrollpos.x, preview.spacing.cy - scrollpos.y, + preview.bmScaledSize.cx, preview.bmScaledSize.cy, + preview.hdcSized, 0, 0, SRCCOPY); if(preview.hdc2) { - BitBlt(hdc, xOffset * 2 + bmNewWidth, yOffset, bmNewWidth, bmNewHeight, preview.hdcSized2, 0, 0, SRCCOPY); + BitBlt(hdc, preview.spacing.cx * 2 + preview.bmScaledSize.cx - scrollpos.x, + preview.spacing.cy - scrollpos.y, preview.bmScaledSize.cx, + preview.bmScaledSize.cy, preview.hdcSized2, 0, 0, SRCCOPY); } DeleteDC(fr.hdcTarget); preview.window = window; - EndPaint(hMainWnd, &ps); + EndPaint(hwndPreview, &ps); return 0; } -static void update_preview(HWND hWnd) +/* Update for page changes. */ +static void update_preview(HWND hMainWnd) { - RECT rc; - DeleteDC(preview.hdc); preview.hdc = 0; - preview.window.right = 0; + update_scaled_preview(hMainWnd); +} - GetClientRect(hWnd, &rc); - rc.top += SendMessageW(GetDlgItem(hWnd, IDC_REBAR), RB_GETBARHEIGHT, 0, 0); - InvalidateRect(hWnd, &rc, TRUE); +static void toggle_num_pages(HWND hMainWnd) +{ + HWND hReBar = GetDlgItem(hMainWnd, IDC_REBAR); + WCHAR name[MAX_STRING_LEN]; + HINSTANCE hInst = GetModuleHandleW(0); + + if(preview.hdc2) + { + DeleteDC(preview.hdc2); + preview.hdc2 = 0; + } else + { + if(preview.page == preview.pages) + preview.page--; + preview.hdc2 = (HDC)-1; + } + + LoadStringW(hInst, preview.hdc2 ? STRING_PREVIEW_ONEPAGE : STRING_PREVIEW_TWOPAGES, + name, MAX_STRING_LEN); + + SetWindowTextW(GetDlgItem(hReBar, ID_PREVIEW_NUMPAGES), name); + update_preview_sizes(GetDlgItem(hMainWnd, IDC_PREVIEW), TRUE); + update_preview(hMainWnd); } LRESULT preview_command(HWND hWnd, WPARAM wParam) @@ -849,29 +1065,38 @@ LRESULT preview_command(HWND hWnd, WPARAM wParam) break; case ID_PREVIEW_NUMPAGES: - { - HWND hReBar = GetDlgItem(hWnd, IDC_REBAR); - WCHAR name[MAX_STRING_LEN]; - HINSTANCE hInst = GetModuleHandleW(0); + toggle_num_pages(hWnd); + break; - if(preview.hdc2) + case ID_PREVIEW_ZOOMIN: + if (preview.zoomlevel < 2) { - DeleteDC(preview.hdc2); - preview.hdc2 = 0; - } else - { - if(preview.page == preview.pages) - preview.page--; - preview.hdc2 = (HDC)-1; + preview.zoomlevel++; + preview.zoomratio = 0; + if (preview.hdc2) + { + /* Forced switch to one page when zooming in. */ + toggle_num_pages(hWnd); + } else { + HWND hwndPreview = GetDlgItem(hWnd, IDC_PREVIEW); + update_preview_sizes(hwndPreview, TRUE); + update_scaled_preview(hWnd); + update_preview_buttons(hWnd); + } } + break; - LoadStringW(hInst, preview.hdc2 ? STRING_PREVIEW_ONEPAGE : STRING_PREVIEW_TWOPAGES, - name, MAX_STRING_LEN); - - SetWindowTextW(GetDlgItem(hReBar, ID_PREVIEW_NUMPAGES), name); - update_preview(hWnd); - } - break; + case ID_PREVIEW_ZOOMOUT: + if (preview.zoomlevel > 0) + { + HWND hwndPreview = GetDlgItem(hWnd, IDC_PREVIEW); + preview.zoomlevel--; + preview.zoomratio = 0; + update_preview_sizes(hwndPreview, TRUE); + update_scaled_preview(hWnd); + update_preview_buttons(hWnd); + } + break; case ID_PRINT: dialog_print(hWnd, preview.wszFileName); diff --git a/programs/wordpad/wordpad.c b/programs/wordpad/wordpad.c index ed43ce5c618..0bbe3604438 100644 --- a/programs/wordpad/wordpad.c +++ b/programs/wordpad/wordpad.c @@ -56,6 +56,9 @@ static const WCHAR wszMainWndClass[] = {'W','O','R','D','P','A','D','T','O','P', static const WCHAR stringFormat[] = {'%','2','d','\0'}; +const WCHAR wszPreviewWndClass[] = {'P','r','t','P','r','e','v','i','e','w',0}; +LRESULT CALLBACK preview_proc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam); + static HWND hMainWnd; static HWND hEditorWnd; static HWND hFindWnd; @@ -2447,7 +2450,7 @@ static LRESULT OnSize( HWND hWnd, WPARAM wParam, LPARAM lParam ) { int nStatusSize = 0; RECT rc; - HWND hwndEditor = GetDlgItem(hWnd, IDC_EDITOR); + HWND hwndEditor = preview_isactive() ? GetDlgItem(hWnd, IDC_PREVIEW) : GetDlgItem(hWnd, IDC_EDITOR); HWND hwndStatusBar = GetDlgItem(hWnd, IDC_STATUSBAR); HWND hwndReBar = GetDlgItem(hWnd, IDC_REBAR); HWND hRulerWnd = GetDlgItem(hWnd, IDC_RULER); @@ -2550,9 +2553,7 @@ static LRESULT CALLBACK WndProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lPara } break; case WM_PAINT: - if(preview_isactive()) - return print_preview(hWnd); - else + if(!preview_isactive()) return DefWindowProcW(hWnd, msg, wParam, lParam); default: @@ -2592,6 +2593,18 @@ int CALLBACK WinMain(HINSTANCE hInstance, HINSTANCE hOldInstance, LPSTR szCmdPar wc.lpszClassName = wszMainWndClass; RegisterClassW(&wc); + wc.style = CS_HREDRAW | CS_VREDRAW; + wc.lpfnWndProc = preview_proc; + wc.cbClsExtra = 0; + wc.cbWndExtra = 0; + wc.hInstance = hInstance; + wc.hIcon = NULL; + wc.hCursor = LoadCursor(NULL, IDC_IBEAM); + wc.hbrBackground = GetSysColorBrush(COLOR_WINDOW); + wc.lpszMenuName = NULL; + wc.lpszClassName = wszPreviewWndClass; + RegisterClassW(&wc); + registry_read_winrect(&rc); hMainWnd = CreateWindowExW(0, wszMainWndClass, wszAppTitle, WS_CLIPCHILDREN|WS_OVERLAPPEDWINDOW, rc.left, rc.top, rc.right-rc.left, rc.bottom-rc.top, NULL, NULL, hInstance, NULL); diff --git a/programs/wordpad/wordpad.h b/programs/wordpad/wordpad.h index b51bec8fcb0..26aa41a1828 100644 --- a/programs/wordpad/wordpad.h +++ b/programs/wordpad/wordpad.h @@ -49,6 +49,8 @@ #define ID_PREVIEW_NEXTPAGE 1017 #define ID_PREVIEW_PREVPAGE 1018 #define ID_PREVIEW_NUMPAGES 1019 +#define ID_PREVIEW_ZOOMIN 1020 +#define ID_PREVIEW_ZOOMOUT 1021 #define ID_ALIGN_LEFT 1100 #define ID_ALIGN_CENTER 1101 @@ -84,7 +86,7 @@ #define ID_TOGGLE_STATUSBAR 1502 #define ID_TOGGLE_RULER 1503 -#define PREVIEW_BUTTONS 5 +#define PREVIEW_BUTTONS 7 #define FILELIST_ENTRIES 4 #define FILELIST_ENTRY_LENGTH 33 @@ -101,7 +103,9 @@ #define BANDID_PREVIEW_BTN3 8 #define BANDID_PREVIEW_BTN4 9 #define BANDID_PREVIEW_BTN5 10 -#define BANDID_PREVIEW_BUFFER 11 +#define BANDID_PREVIEW_BTN6 11 +#define BANDID_PREVIEW_BTN7 12 +#define BANDID_PREVIEW_BUFFER 13 #define ID_WORDWRAP_NONE 0 #define ID_WORDWRAP_WINDOW 1 @@ -145,6 +149,7 @@ #define IDC_FONTLIST 2013 #define IDC_SIZELIST 2014 #define IDC_RULER 2015 +#define IDC_PREVIEW 2016 #define IDD_DATETIME 2100 #define IDD_NEWFILE 2101 @@ -187,9 +192,11 @@ #define STRING_PREVIEW_PREVPAGE 1450 #define STRING_PREVIEW_TWOPAGES 1451 #define STRING_PREVIEW_ONEPAGE 1452 -#define STRING_PREVIEW_CLOSE 1453 +#define STRING_PREVIEW_ZOOMIN 1453 +#define STRING_PREVIEW_ZOOMOUT 1454 +#define STRING_PREVIEW_CLOSE 1455 -#define STRING_UNITS_CM 1454 +#define STRING_UNITS_CM 1456 #define STRING_DEFAULT_FILENAME 1700 #define STRING_PROMPT_SAVE_CHANGES 1701