]>
Commit | Line | Data |
---|---|---|
46f4442e A |
1 | /* |
2 | ******************************************************************************* | |
3 | * | |
4 | * Copyright (C) 1999-2007, International Business Machines | |
5 | * Corporation and others. All Rights Reserved. | |
6 | * | |
7 | ******************************************************************************* | |
8 | * file name: Layout.cpp | |
9 | * | |
10 | * created on: 08/03/2000 | |
11 | * created by: Eric R. Mader | |
12 | */ | |
13 | ||
14 | #include <windows.h> | |
15 | #include <stdio.h> | |
16 | ||
17 | #include "playout.h" | |
18 | #include "pflow.h" | |
19 | ||
20 | #include "gdiglue.h" | |
21 | #include "ucreader.h" | |
22 | ||
23 | #include "arraymem.h" | |
24 | ||
25 | #include "resource.h" | |
26 | ||
27 | struct Context | |
28 | { | |
29 | le_int32 width; | |
30 | le_int32 height; | |
31 | pf_flow *paragraph; | |
32 | }; | |
33 | ||
34 | typedef struct Context Context; | |
35 | ||
36 | LRESULT CALLBACK WndProc(HWND, UINT, WPARAM, LPARAM); | |
37 | ||
38 | #define APP_NAME "LayoutSample" | |
39 | ||
40 | TCHAR szAppName[] = TEXT(APP_NAME); | |
41 | ||
42 | void PrettyTitle(HWND hwnd, char *fileName) | |
43 | { | |
44 | char title[MAX_PATH + 64]; | |
45 | ||
46 | sprintf(title, "%s - %s", APP_NAME, fileName); | |
47 | ||
48 | SetWindowTextA(hwnd, title); | |
49 | } | |
50 | ||
51 | void InitParagraph(HWND hwnd, Context *context) | |
52 | { | |
53 | SCROLLINFO si; | |
54 | ||
55 | if (context->paragraph != NULL) { | |
56 | // FIXME: does it matter what we put in the ScrollInfo | |
57 | // if the window's been minimized? | |
58 | if (context->width > 0 && context->height > 0) { | |
59 | pf_breakLines(context->paragraph, context->width, context->height); | |
60 | } | |
61 | ||
62 | si.cbSize = sizeof si; | |
63 | si.fMask = SIF_RANGE | SIF_PAGE | SIF_DISABLENOSCROLL; | |
64 | si.nMin = 0; | |
65 | si.nMax = pf_getLineCount(context->paragraph) - 1; | |
66 | si.nPage = context->height / pf_getLineHeight(context->paragraph); | |
67 | SetScrollInfo(hwnd, SB_VERT, &si, TRUE); | |
68 | } | |
69 | } | |
70 | ||
71 | int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, PSTR szCmdLine, int iCmdShow) | |
72 | { | |
73 | HWND hwnd; | |
74 | HACCEL hAccel; | |
75 | MSG msg; | |
76 | WNDCLASS wndclass; | |
77 | LEErrorCode status = LE_NO_ERROR; | |
78 | ||
79 | wndclass.style = CS_HREDRAW | CS_VREDRAW; | |
80 | wndclass.lpfnWndProc = WndProc; | |
81 | wndclass.cbClsExtra = 0; | |
82 | wndclass.cbWndExtra = sizeof(LONG); | |
83 | wndclass.hInstance = hInstance; | |
84 | wndclass.hIcon = LoadIcon(NULL, IDI_APPLICATION); | |
85 | wndclass.hCursor = LoadCursor(NULL, IDC_ARROW); | |
86 | wndclass.hbrBackground = (HBRUSH) GetStockObject(WHITE_BRUSH); | |
87 | wndclass.lpszMenuName = szAppName; | |
88 | wndclass.lpszClassName = szAppName; | |
89 | ||
90 | if (!RegisterClass(&wndclass)) { | |
91 | MessageBox(NULL, TEXT("This demo only runs on Windows 2000!"), szAppName, MB_ICONERROR); | |
92 | ||
93 | return 0; | |
94 | } | |
95 | ||
96 | hAccel = LoadAccelerators(hInstance, szAppName); | |
97 | ||
98 | hwnd = CreateWindow(szAppName, NULL, | |
99 | WS_OVERLAPPEDWINDOW | WS_VSCROLL, | |
100 | CW_USEDEFAULT, CW_USEDEFAULT, | |
101 | 600, 400, | |
102 | NULL, NULL, hInstance, NULL); | |
103 | ||
104 | ShowWindow(hwnd, iCmdShow); | |
105 | UpdateWindow(hwnd); | |
106 | ||
107 | while (GetMessage(&msg, NULL, 0, 0)) { | |
108 | if (!TranslateAccelerator(hwnd, hAccel, &msg)) { | |
109 | TranslateMessage(&msg); | |
110 | DispatchMessage(&msg); | |
111 | } | |
112 | } | |
113 | ||
114 | UnregisterClass(szAppName, hInstance); | |
115 | return msg.wParam; | |
116 | } | |
117 | ||
118 | LRESULT CALLBACK WndProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam) | |
119 | { | |
120 | HDC hdc; | |
121 | Context *context; | |
122 | static le_int32 windowCount = 0; | |
123 | static fm_fontMap *fontMap = NULL; | |
124 | static rs_surface *surface = NULL; | |
125 | static gs_guiSupport *guiSupport = NULL; | |
126 | static le_font *font = NULL; | |
127 | ||
128 | switch (message) { | |
129 | case WM_CREATE: | |
130 | { | |
131 | LEErrorCode fontStatus = LE_NO_ERROR; | |
132 | ||
133 | hdc = GetDC(hwnd); | |
134 | guiSupport = gs_gdiGuiSupportOpen(); | |
135 | surface = rs_gdiRenderingSurfaceOpen(hdc); | |
136 | ||
137 | fontMap = fm_gdiFontMapOpen(surface, "FontMap.GDI", 24, guiSupport, &fontStatus); | |
138 | font = le_scriptCompositeFontOpen(fontMap); | |
139 | ||
140 | if (LE_FAILURE(fontStatus)) { | |
141 | ReleaseDC(hwnd, hdc); | |
142 | return -1; | |
143 | } | |
144 | ||
145 | context = NEW_ARRAY(Context, 1); | |
146 | ||
147 | context->width = 600; | |
148 | context->height = 400; | |
149 | ||
150 | context->paragraph = pf_factory("Sample.txt", font, guiSupport); | |
151 | SetWindowLongPtr(hwnd, 0, (LONG_PTR) context); | |
152 | ||
153 | windowCount += 1; | |
154 | ReleaseDC(hwnd, hdc); | |
155 | ||
156 | PrettyTitle(hwnd, "Sample.txt"); | |
157 | return 0; | |
158 | } | |
159 | ||
160 | case WM_SIZE: | |
161 | { | |
162 | context = (Context *) GetWindowLongPtr(hwnd, 0); | |
163 | context->width = LOWORD(lParam); | |
164 | context->height = HIWORD(lParam); | |
165 | ||
166 | InitParagraph(hwnd, context); | |
167 | return 0; | |
168 | } | |
169 | ||
170 | case WM_VSCROLL: | |
171 | { | |
172 | SCROLLINFO si; | |
173 | le_int32 vertPos; | |
174 | ||
175 | si.cbSize = sizeof si; | |
176 | si.fMask = SIF_ALL; | |
177 | GetScrollInfo(hwnd, SB_VERT, &si); | |
178 | ||
179 | vertPos = si.nPos; | |
180 | ||
181 | switch (LOWORD(wParam)) | |
182 | { | |
183 | case SB_TOP: | |
184 | si.nPos = si.nMin; | |
185 | break; | |
186 | ||
187 | case SB_BOTTOM: | |
188 | si.nPos = si.nMax; | |
189 | break; | |
190 | ||
191 | case SB_LINEUP: | |
192 | si.nPos -= 1; | |
193 | break; | |
194 | ||
195 | case SB_LINEDOWN: | |
196 | si.nPos += 1; | |
197 | break; | |
198 | ||
199 | case SB_PAGEUP: | |
200 | si.nPos -= si.nPage; | |
201 | break; | |
202 | ||
203 | case SB_PAGEDOWN: | |
204 | si.nPos += si.nPage; | |
205 | break; | |
206 | ||
207 | case SB_THUMBTRACK: | |
208 | si.nPos = si.nTrackPos; | |
209 | break; | |
210 | ||
211 | default: | |
212 | break; | |
213 | } | |
214 | ||
215 | si.fMask = SIF_POS; | |
216 | SetScrollInfo(hwnd, SB_VERT, &si, TRUE); | |
217 | GetScrollInfo(hwnd, SB_VERT, &si); | |
218 | ||
219 | context = (Context *) GetWindowLongPtr(hwnd, 0); | |
220 | ||
221 | if (context->paragraph != NULL && si.nPos != vertPos) { | |
222 | ScrollWindow(hwnd, 0, pf_getLineHeight(context->paragraph) * (vertPos - si.nPos), NULL, NULL); | |
223 | UpdateWindow(hwnd); | |
224 | } | |
225 | ||
226 | return 0; | |
227 | } | |
228 | ||
229 | case WM_PAINT: | |
230 | { | |
231 | PAINTSTRUCT ps; | |
232 | SCROLLINFO si; | |
233 | le_int32 firstLine, lastLine; | |
234 | ||
235 | hdc = BeginPaint(hwnd, &ps); | |
236 | SetBkMode(hdc, TRANSPARENT); | |
237 | ||
238 | si.cbSize = sizeof si; | |
239 | si.fMask = SIF_ALL; | |
240 | GetScrollInfo(hwnd, SB_VERT, &si); | |
241 | ||
242 | firstLine = si.nPos; | |
243 | ||
244 | context = (Context *) GetWindowLongPtr(hwnd, 0); | |
245 | ||
246 | if (context->paragraph != NULL) { | |
247 | rs_gdiRenderingSurfaceSetHDC(surface, hdc); | |
248 | ||
249 | // NOTE: si.nPos + si.nPage may include a partial line at the bottom | |
250 | // of the window. We need this because scrolling assumes that the | |
251 | // partial line has been painted. | |
252 | lastLine = min (si.nPos + (le_int32) si.nPage, pf_getLineCount(context->paragraph) - 1); | |
253 | ||
254 | pf_draw(context->paragraph, surface, firstLine, lastLine); | |
255 | } | |
256 | ||
257 | EndPaint(hwnd, &ps); | |
258 | return 0; | |
259 | } | |
260 | ||
261 | case WM_COMMAND: | |
262 | switch (LOWORD(wParam)) { | |
263 | case IDM_FILE_OPEN: | |
264 | { | |
265 | OPENFILENAMEA ofn; | |
266 | char szFileName[MAX_PATH], szTitleName[MAX_PATH]; | |
267 | static char szFilter[] = "Text Files (.txt)\0*.txt\0" | |
268 | "All Files (*.*)\0*.*\0\0"; | |
269 | ||
270 | ofn.lStructSize = sizeof (OPENFILENAMEA); | |
271 | ofn.hwndOwner = hwnd; | |
272 | ofn.hInstance = NULL; | |
273 | ofn.lpstrFilter = szFilter; | |
274 | ofn.lpstrCustomFilter = NULL; | |
275 | ofn.nMaxCustFilter = 0; | |
276 | ofn.nFilterIndex = 0; | |
277 | ofn.lpstrFile = szFileName; | |
278 | ofn.nMaxFile = MAX_PATH; | |
279 | ofn.lpstrFileTitle = szTitleName; | |
280 | ofn.nMaxFileTitle = MAX_PATH; | |
281 | ofn.lpstrInitialDir = NULL; | |
282 | ofn.lpstrTitle = NULL; | |
283 | ofn.Flags = OFN_HIDEREADONLY | OFN_PATHMUSTEXIST; | |
284 | ofn.nFileOffset = 0; | |
285 | ofn.nFileExtension = 0; | |
286 | ofn.lpstrDefExt = "txt"; | |
287 | ofn.lCustData = 0L; | |
288 | ofn.lpfnHook = NULL; | |
289 | ofn.lpTemplateName = NULL; | |
290 | ||
291 | szFileName[0] = '\0'; | |
292 | ||
293 | if (GetOpenFileNameA(&ofn)) { | |
294 | pf_flow *newParagraph; | |
295 | ||
296 | hdc = GetDC(hwnd); | |
297 | rs_gdiRenderingSurfaceSetHDC(surface, hdc); | |
298 | ||
299 | newParagraph = pf_factory(szFileName, font, guiSupport); | |
300 | ||
301 | if (newParagraph != NULL) { | |
302 | context = (Context *) GetWindowLongPtr(hwnd, 0); | |
303 | ||
304 | if (context->paragraph != NULL) { | |
305 | pf_close(context->paragraph); | |
306 | } | |
307 | ||
308 | context->paragraph = newParagraph; | |
309 | InitParagraph(hwnd, context); | |
310 | PrettyTitle(hwnd, szTitleName); | |
311 | InvalidateRect(hwnd, NULL, TRUE); | |
312 | ||
313 | } | |
314 | } | |
315 | ||
316 | //ReleaseDC(hwnd, hdc); | |
317 | ||
318 | return 0; | |
319 | } | |
320 | ||
321 | case IDM_FILE_EXIT: | |
322 | case IDM_FILE_CLOSE: | |
323 | SendMessage(hwnd, WM_CLOSE, 0, 0); | |
324 | return 0; | |
325 | ||
326 | case IDM_HELP_ABOUTLAYOUTSAMPLE: | |
327 | MessageBox(hwnd, TEXT("Windows Layout Sample 0.1\n") | |
328 | TEXT("Copyright (C) 1998-2005 By International Business Machines Corporation and others.\n") | |
329 | TEXT("Author: Eric Mader"), | |
330 | szAppName, MB_ICONINFORMATION | MB_OK); | |
331 | return 0; | |
332 | ||
333 | } | |
334 | break; | |
335 | ||
336 | ||
337 | case WM_DESTROY: | |
338 | { | |
339 | context = (Context *) GetWindowLongPtr(hwnd, 0); | |
340 | ||
341 | if (context != NULL && context->paragraph != NULL) { | |
342 | pf_close(context->paragraph); | |
343 | } | |
344 | ||
345 | DELETE_ARRAY(context); | |
346 | ||
347 | if (--windowCount <= 0) { | |
348 | le_fontClose(font); | |
349 | rs_gdiRenderingSurfaceClose(surface); | |
350 | gs_gdiGuiSupportClose(guiSupport); | |
351 | ||
352 | PostQuitMessage(0); | |
353 | } | |
354 | ||
355 | return 0; | |
356 | } | |
357 | ||
358 | default: | |
359 | return DefWindowProc(hwnd, message, wParam, lParam); | |
360 | } | |
361 | ||
362 | return 0; | |
363 | } |