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