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