Change the translation of the "Help" menu item to "?", so that the menu can be displa...
[reactos.git] / rosapps / smartpdf / src / PdftestWinPreview.cc
1 /* Copyright Krzysztof Kowalczyk 2006-2007
2 License: GPLv2 */
3 #include "win_util.h"
4 #include "PdfEngine.h"
5
6 #include <assert.h>
7
8 #define WIN_CLASS_NAME "PDFTEST_PDF_WIN"
9 #define COL_WINDOW_BG RGB(0xff, 0xff, 0xff)
10
11 static HWND gHwndSplash;
12 static HWND gHwndFitz;
13 static HBRUSH gBrushBg;
14
15 static RenderedBitmap *gBmpSplash, *gBmpFitz;
16
17 /* Set the client area size of the window 'hwnd' to 'dx'/'dy'. */
18 static void resizeClientArea(HWND hwnd, int x, int dx, int dy, int *dx_out)
19 {
20 RECT rc;
21 GetClientRect(hwnd, &rc);
22 if ((rect_dx(&rc) == dx) && (rect_dy(&rc) == dy))
23 return;
24
25 RECT rw;
26 GetWindowRect(hwnd, &rw);
27 int win_dx = rect_dx(&rw) + (dx - rect_dx(&rc));
28 int win_dy = rect_dy(&rw) + (dy - rect_dy(&rc));
29 SetWindowPos(hwnd, NULL, x, 0, win_dx, win_dy, SWP_NOACTIVATE | SWP_NOREPOSITION | SWP_NOZORDER);
30 if (dx_out)
31 *dx_out = win_dx;
32 }
33
34 static void resizeClientAreaToRenderedBitmap(HWND hwnd, RenderedBitmap *bmp, int x, int *dxOut)
35 {
36 int dx = bmp->dx();
37 int dy = bmp->dy();
38 resizeClientArea(hwnd, x, dx, dy, dxOut);
39 }
40
41 static void drawBitmap(HWND hwnd, RenderedBitmap *bmp)
42 {
43 PAINTSTRUCT ps;
44
45 HDC hdc = BeginPaint(hwnd, &ps);
46 SetBkMode(hdc, TRANSPARENT);
47 FillRect(hdc, &ps.rcPaint, gBrushBg);
48
49 HBITMAP hbmp = bmp->createDIBitmap(hdc);
50 if (hbmp) {
51 HDC bmpDC = CreateCompatibleDC(hdc);
52 if (bmpDC) {
53 SelectObject(bmpDC, hbmp);
54 int xSrc = 0, ySrc = 0;
55 int xDest = 0, yDest = 0;
56 int bmpDx = bmp->dx();
57 int bmpDy = bmp->dy();
58 BitBlt(hdc, xDest, yDest, bmpDx, bmpDy, bmpDC, xSrc, ySrc, SRCCOPY);
59 DeleteDC(bmpDC);
60 bmpDC = NULL;
61 }
62 DeleteObject(hbmp);
63 hbmp = NULL;
64 }
65 EndPaint(hwnd, &ps);
66 }
67
68 static void onPaint(HWND hwnd)
69 {
70 if (hwnd == gHwndSplash)
71 if (gBmpSplash)
72 drawBitmap(hwnd, gBmpSplash);
73 if (hwnd == gHwndFitz)
74 if (gBmpFitz)
75 drawBitmap(hwnd, gBmpFitz);
76 }
77
78 static LRESULT CALLBACK WndProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
79 {
80 switch (message)
81 {
82 case WM_CREATE:
83 // do nothing
84 break;
85
86 case WM_ERASEBKGND:
87 return TRUE;
88
89 case WM_PAINT:
90 /* it might happen that we get WM_PAINT after destroying a window */
91 onPaint(hwnd);
92 break;
93
94 case WM_DESTROY:
95 /* WM_DESTROY might be sent as a result of File\Close, in which case CloseWindow() has already been called */
96 break;
97
98 default:
99 return DefWindowProc(hwnd, message, wParam, lParam);
100 }
101 return 0;
102 }
103
104 static BOOL registerWinClass(void)
105 {
106 WNDCLASSEX wcex;
107 ATOM atom;
108
109 wcex.cbSize = sizeof(WNDCLASSEX);
110
111 wcex.style = CS_HREDRAW | CS_VREDRAW;
112 wcex.lpfnWndProc = WndProc;
113 wcex.cbClsExtra = 0;
114 wcex.cbWndExtra = 0;
115 wcex.hInstance = NULL;
116 wcex.hIcon = NULL;
117 wcex.hCursor = LoadCursor(NULL, IDC_ARROW);
118 wcex.hbrBackground = NULL;
119 wcex.lpszMenuName = NULL;
120 wcex.lpszClassName = WIN_CLASS_NAME;
121 wcex.hIconSm = NULL;
122
123 atom = RegisterClassEx(&wcex);
124 if (atom)
125 return TRUE;
126 return FALSE;
127 }
128
129 static bool initWinIfNecessary(void)
130 {
131 if (gHwndSplash)
132 return true;
133
134 if (!registerWinClass())
135 return false;
136
137 gBrushBg = CreateSolidBrush(COL_WINDOW_BG);
138
139 gHwndSplash = CreateWindow(
140 WIN_CLASS_NAME, "Splash",
141 WS_OVERLAPPEDWINDOW,
142 CW_USEDEFAULT, 0,
143 CW_USEDEFAULT, 0,
144 NULL, NULL,
145 NULL, NULL);
146
147 if (!gHwndSplash)
148 return false;
149
150 gHwndFitz = CreateWindow(
151 WIN_CLASS_NAME, "Fitz",
152 WS_OVERLAPPEDWINDOW,
153 CW_USEDEFAULT, 0,
154 CW_USEDEFAULT, 0,
155 NULL, NULL,
156 NULL, NULL);
157
158 if (!gHwndFitz)
159 return false;
160
161 ShowWindow(gHwndSplash, SW_HIDE);
162 ShowWindow(gHwndFitz, SW_HIDE);
163 return true;
164 }
165
166 static void pumpMessages(void)
167 {
168 BOOL isMessage;
169 MSG msg;
170
171 for (;;) {
172 isMessage = PeekMessage(&msg, NULL, 0, 0, PM_REMOVE);
173 if (!isMessage)
174 return;
175 TranslateMessage(&msg);
176 DispatchMessage(&msg);
177 }
178 }
179
180 void PreviewBitmapInit(void)
181 {
182 /* no need to do anything */
183 }
184
185 static void deleteRenderedBitmaps()
186 {
187 delete gBmpSplash;
188 delete gBmpFitz;
189 }
190
191 void PreviewBitmapDestroy(void)
192 {
193 PostQuitMessage(0);
194 pumpMessages();
195 deleteRenderedBitmaps();
196 DeleteObject(gBrushBg);
197 }
198
199 static void UpdateWindows(void)
200 {
201 int fitzDx = 0;
202
203 if (gBmpFitz) {
204 resizeClientAreaToRenderedBitmap(gHwndFitz, gBmpFitz, 0, &fitzDx);
205 ShowWindow(gHwndFitz, SW_SHOW);
206 InvalidateRect(gHwndFitz, NULL, FALSE);
207 UpdateWindow(gHwndFitz);
208 } else {
209 ShowWindow(gHwndFitz, SW_HIDE);
210 }
211
212 if (gBmpSplash) {
213 resizeClientAreaToRenderedBitmap(gHwndSplash, gBmpSplash, fitzDx, NULL);
214 ShowWindow(gHwndSplash, SW_SHOW);
215 InvalidateRect(gHwndSplash, NULL, FALSE);
216 UpdateWindow(gHwndSplash);
217 } else {
218 ShowWindow(gHwndSplash, SW_HIDE);
219 }
220
221 pumpMessages();
222 }
223
224 void PreviewBitmapSplashFitz(RenderedBitmap *bmpSplash, RenderedBitmap *bmpFitz)
225 {
226 if (!initWinIfNecessary())
227 return;
228
229 deleteRenderedBitmaps();
230 gBmpSplash = bmpSplash;
231 gBmpFitz = bmpFitz;
232 UpdateWindows();
233 }
234