2 *******************************************************************************
4 * © 2016 and later: Unicode, Inc. and others.
5 * License & terms of use: http://www.unicode.org/copyright.html#License
7 *******************************************************************************
8 *******************************************************************************
10 * Copyright (C) 1999-2007, International Business Machines
11 * Corporation and others. All Rights Reserved.
13 *******************************************************************************
14 * file name: Layout.cpp
16 * created on: 08/03/2000
17 * created by: Eric R. Mader
23 #include "paragraph.h"
25 #include "GDIGUISupport.h"
26 #include "GDIFontMap.h"
27 #include "UnicodeReader.h"
28 #include "ScriptCompositeFontInstance.h"
32 #define ARRAY_LENGTH(array) (sizeof array / sizeof array[0])
41 LRESULT CALLBACK
WndProc(HWND
, UINT
, WPARAM
, LPARAM
);
43 #define APP_NAME "LayoutSample"
45 TCHAR szAppName
[] = TEXT(APP_NAME
);
47 void PrettyTitle(HWND hwnd
, char *fileName
)
49 char title
[MAX_PATH
+ 64];
51 sprintf(title
, "%s - %s", APP_NAME
, fileName
);
53 SetWindowTextA(hwnd
, title
);
56 void InitParagraph(HWND hwnd
, Context
*context
)
60 if (context
->paragraph
!= NULL
) {
61 // FIXME: does it matter what we put in the ScrollInfo
62 // if the window's been minimized?
63 if (context
->width
> 0 && context
->height
> 0) {
64 context
->paragraph
->breakLines(context
->width
, context
->height
);
67 si
.cbSize
= sizeof si
;
68 si
.fMask
= SIF_RANGE
| SIF_PAGE
| SIF_DISABLENOSCROLL
;
70 si
.nMax
= context
->paragraph
->getLineCount() - 1;
71 si
.nPage
= context
->height
/ context
->paragraph
->getLineHeight();
72 SetScrollInfo(hwnd
, SB_VERT
, &si
, TRUE
);
76 int WINAPI
WinMain(HINSTANCE hInstance
, HINSTANCE hPrevInstance
, PSTR szCmdLine
, int iCmdShow
)
82 LEErrorCode status
= LE_NO_ERROR
;
84 wndclass
.style
= CS_HREDRAW
| CS_VREDRAW
;
85 wndclass
.lpfnWndProc
= WndProc
;
86 wndclass
.cbClsExtra
= 0;
87 wndclass
.cbWndExtra
= sizeof(LONG
);
88 wndclass
.hInstance
= hInstance
;
89 wndclass
.hIcon
= LoadIcon(NULL
, IDI_APPLICATION
);
90 wndclass
.hCursor
= LoadCursor(NULL
, IDC_ARROW
);
91 wndclass
.hbrBackground
= (HBRUSH
) GetStockObject(WHITE_BRUSH
);
92 wndclass
.lpszMenuName
= szAppName
;
93 wndclass
.lpszClassName
= szAppName
;
95 if (!RegisterClass(&wndclass
)) {
96 MessageBox(NULL
, TEXT("This demo only runs on Windows 2000!"), szAppName
, MB_ICONERROR
);
101 hAccel
= LoadAccelerators(hInstance
, szAppName
);
103 hwnd
= CreateWindow(szAppName
, NULL
,
104 WS_OVERLAPPEDWINDOW
| WS_VSCROLL
,
105 CW_USEDEFAULT
, CW_USEDEFAULT
,
107 NULL
, NULL
, hInstance
, NULL
);
109 ShowWindow(hwnd
, iCmdShow
);
112 while (GetMessage(&msg
, NULL
, 0, 0)) {
113 if (!TranslateAccelerator(hwnd
, hAccel
, &msg
)) {
114 TranslateMessage(&msg
);
115 DispatchMessage(&msg
);
119 UnregisterClass(szAppName
, hInstance
);
123 LRESULT CALLBACK
WndProc(HWND hwnd
, UINT message
, WPARAM wParam
, LPARAM lParam
)
127 static le_int32 windowCount
= 0;
128 static GDIFontMap
*fontMap
= NULL
;
129 static GDISurface
*surface
= NULL
;
130 static GDIGUISupport
*guiSupport
= new GDIGUISupport();
131 static ScriptCompositeFontInstance
*font
= NULL
;
136 LEErrorCode fontStatus
= LE_NO_ERROR
;
139 surface
= new GDISurface(hdc
);
141 fontMap
= new GDIFontMap(surface
, "FontMap.GDI", 24, guiSupport
, fontStatus
);
142 font
= new ScriptCompositeFontInstance(fontMap
);
144 if (LE_FAILURE(fontStatus
)) {
145 ReleaseDC(hwnd
, hdc
);
149 context
= new Context();
151 context
->width
= 600;
152 context
->height
= 400;
154 context
->paragraph
= Paragraph::paragraphFactory("Sample.txt", font
, guiSupport
);
155 SetWindowLongPtr(hwnd
, GWLP_USERDATA
, (LONG_PTR
) context
);
158 ReleaseDC(hwnd
, hdc
);
160 PrettyTitle(hwnd
, "Sample.txt");
166 context
= (Context
*) GetWindowLongPtr(hwnd
, GWLP_USERDATA
);
167 context
->width
= LOWORD(lParam
);
168 context
->height
= HIWORD(lParam
);
170 InitParagraph(hwnd
, context
);
179 si
.cbSize
= sizeof si
;
181 GetScrollInfo(hwnd
, SB_VERT
, &si
);
185 switch (LOWORD(wParam
))
212 si
.nPos
= si
.nTrackPos
;
220 SetScrollInfo(hwnd
, SB_VERT
, &si
, TRUE
);
221 GetScrollInfo(hwnd
, SB_VERT
, &si
);
223 context
= (Context
*) GetWindowLongPtr(hwnd
, GWLP_USERDATA
);
225 if (context
->paragraph
!= NULL
&& si
.nPos
!= vertPos
) {
226 ScrollWindow(hwnd
, 0, context
->paragraph
->getLineHeight() * (vertPos
- si
.nPos
), NULL
, NULL
);
237 le_int32 firstLine
, lastLine
;
239 hdc
= BeginPaint(hwnd
, &ps
);
240 SetBkMode(hdc
, TRANSPARENT
);
242 si
.cbSize
= sizeof si
;
244 GetScrollInfo(hwnd
, SB_VERT
, &si
);
248 context
= (Context
*) GetWindowLongPtr(hwnd
, GWLP_USERDATA
);
250 if (context
->paragraph
!= NULL
) {
251 surface
->setHDC(hdc
);
253 // NOTE: si.nPos + si.nPage may include a partial line at the bottom
254 // of the window. We need this because scrolling assumes that the
255 // partial line has been painted.
256 lastLine
= min (si
.nPos
+ (le_int32
) si
.nPage
, context
->paragraph
->getLineCount() - 1);
258 context
->paragraph
->draw(surface
, firstLine
, lastLine
);
266 switch (LOWORD(wParam
)) {
270 char szFileName
[MAX_PATH
], szTitleName
[MAX_PATH
];
271 static char szFilter
[] = "Text Files (.txt)\0*.txt\0"
272 "All Files (*.*)\0*.*\0\0";
274 ofn
.lStructSize
= sizeof (OPENFILENAMEA
);
275 ofn
.hwndOwner
= hwnd
;
276 ofn
.hInstance
= NULL
;
277 ofn
.lpstrFilter
= szFilter
;
278 ofn
.lpstrCustomFilter
= NULL
;
279 ofn
.nMaxCustFilter
= 0;
280 ofn
.nFilterIndex
= 0;
281 ofn
.lpstrFile
= szFileName
;
282 ofn
.nMaxFile
= MAX_PATH
;
283 ofn
.lpstrFileTitle
= szTitleName
;
284 ofn
.nMaxFileTitle
= MAX_PATH
;
285 ofn
.lpstrInitialDir
= NULL
;
286 ofn
.lpstrTitle
= NULL
;
287 ofn
.Flags
= OFN_HIDEREADONLY
| OFN_PATHMUSTEXIST
;
289 ofn
.nFileExtension
= 0;
290 ofn
.lpstrDefExt
= "txt";
293 ofn
.lpTemplateName
= NULL
;
295 szFileName
[0] = '\0';
297 if (GetOpenFileNameA(&ofn
)) {
299 surface
->setHDC(hdc
);
301 Paragraph
*newParagraph
= Paragraph::paragraphFactory(szFileName
, font
, guiSupport
);
303 if (newParagraph
!= NULL
) {
304 context
= (Context
*) GetWindowLongPtr(hwnd
, GWLP_USERDATA
);
306 if (context
->paragraph
!= NULL
) {
307 delete context
->paragraph
;
310 context
->paragraph
= newParagraph
;
311 InitParagraph(hwnd
, context
);
312 PrettyTitle(hwnd
, szTitleName
);
313 InvalidateRect(hwnd
, NULL
, TRUE
);
318 //ReleaseDC(hwnd, hdc);
325 SendMessage(hwnd
, WM_CLOSE
, 0, 0);
328 case IDM_HELP_ABOUTLAYOUTSAMPLE
:
329 MessageBox(hwnd
, TEXT("Windows Layout Sample 0.1\n")
330 TEXT("Copyright (C) 1998-2005 By International Business Machines Corporation and others.\n")
331 TEXT("Author: Eric Mader"),
332 szAppName
, MB_ICONINFORMATION
| MB_OK
);
341 context
= (Context
*) GetWindowLongPtr(hwnd
, GWLP_USERDATA
);
343 if (context
!= NULL
&& context
->paragraph
!= NULL
) {
344 delete context
->paragraph
;
349 if (--windowCount
<= 0) {
360 return DefWindowProc(hwnd
, message
, wParam
, lParam
);