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