xref: /reactos/base/applications/charmap/map.c (revision 7e9f1e67)
1c2c66affSColin Finck /*
2c2c66affSColin Finck  * PROJECT:     ReactOS Character Map
3c2c66affSColin Finck  * LICENSE:     GPL - See COPYING in the top level directory
4c2c66affSColin Finck  * FILE:        base/applications/charmap/map.c
5c2c66affSColin Finck  * PURPOSE:     class implementation for painting glyph region
6c2c66affSColin Finck  * COPYRIGHT:   Copyright 2007 Ged Murphy <gedmurphy@reactos.org>
7*7e9f1e67SKatayama Hirofumi MZ  *              Copyright 2022 Katayama Hirofumi MZ <katayama.hirofumi.mz@gmail.com>
8c2c66affSColin Finck  *
9c2c66affSColin Finck  */
10c2c66affSColin Finck 
11c2c66affSColin Finck #include "precomp.h"
12c2c66affSColin Finck 
13c2c66affSColin Finck #include <stdlib.h>
1499dd2925SCharles Ambrye #include <winnls.h>
15c2c66affSColin Finck 
16c2c66affSColin Finck static const WCHAR szMapWndClass[] = L"FontMapWnd";
17c2c66affSColin Finck static const WCHAR szLrgCellWndClass[] = L"LrgCellWnd";
18c2c66affSColin Finck 
19c2c66affSColin Finck #define MAX_ROWS (0xFFFF / XCELLS) + 1 - YCELLS
20c2c66affSColin Finck 
21c2c66affSColin Finck static
22c2c66affSColin Finck VOID
SetGrid(PMAP infoPtr)23c2c66affSColin Finck SetGrid(PMAP infoPtr)
24c2c66affSColin Finck {
25c2c66affSColin Finck     INT x, y;
26c2c66affSColin Finck     PCELL Cell;
27c2c66affSColin Finck 
28c2c66affSColin Finck     for (y = 0; y < YCELLS; y++)
29c2c66affSColin Finck     for (x = 0; x < XCELLS; x++)
30c2c66affSColin Finck     {
31c2c66affSColin Finck         Cell = &infoPtr->Cells[y][x];
32*7e9f1e67SKatayama Hirofumi MZ         Cell->CellExt.left = x * infoPtr->CellSize.cx + 1;
33*7e9f1e67SKatayama Hirofumi MZ         Cell->CellExt.top = y * infoPtr->CellSize.cy + 1;
34*7e9f1e67SKatayama Hirofumi MZ         Cell->CellExt.right = (x + 1) * infoPtr->CellSize.cx + 2;
35*7e9f1e67SKatayama Hirofumi MZ         Cell->CellExt.bottom = (y + 1) * infoPtr->CellSize.cy + 2;
36c2c66affSColin Finck 
37*7e9f1e67SKatayama Hirofumi MZ         Cell->CellInt = Cell->CellExt;
38*7e9f1e67SKatayama Hirofumi MZ 
39*7e9f1e67SKatayama Hirofumi MZ         InflateRect(&Cell->CellInt, -1, -1);
40*7e9f1e67SKatayama Hirofumi MZ     }
41*7e9f1e67SKatayama Hirofumi MZ }
42*7e9f1e67SKatayama Hirofumi MZ 
43*7e9f1e67SKatayama Hirofumi MZ static
44*7e9f1e67SKatayama Hirofumi MZ VOID
UpdateCells(PMAP infoPtr)45*7e9f1e67SKatayama Hirofumi MZ UpdateCells(PMAP infoPtr)
46c2c66affSColin Finck {
47*7e9f1e67SKatayama Hirofumi MZ     INT x, y;
48*7e9f1e67SKatayama Hirofumi MZ     INT i = XCELLS * infoPtr->iYStart;
49*7e9f1e67SKatayama Hirofumi MZ     WCHAR ch;
50*7e9f1e67SKatayama Hirofumi MZ     PCELL Cell;
51c2c66affSColin Finck 
52*7e9f1e67SKatayama Hirofumi MZ     for (y = 0; y < YCELLS; ++y)
53c2c66affSColin Finck     {
54*7e9f1e67SKatayama Hirofumi MZ         for (x = 0; x < XCELLS; ++x, ++i)
55*7e9f1e67SKatayama Hirofumi MZ         {
56*7e9f1e67SKatayama Hirofumi MZ             if (i < infoPtr->NumValidGlyphs)
57*7e9f1e67SKatayama Hirofumi MZ                 ch = (WCHAR)infoPtr->ValidGlyphs[i];
58*7e9f1e67SKatayama Hirofumi MZ             else
59*7e9f1e67SKatayama Hirofumi MZ                 ch = 0xFFFF;
60c2c66affSColin Finck 
61*7e9f1e67SKatayama Hirofumi MZ             Cell = &infoPtr->Cells[y][x];
62*7e9f1e67SKatayama Hirofumi MZ             Cell->ch = ch;
63*7e9f1e67SKatayama Hirofumi MZ         }
64*7e9f1e67SKatayama Hirofumi MZ     }
65*7e9f1e67SKatayama Hirofumi MZ }
66c2c66affSColin Finck 
67c2c66affSColin Finck static
68c2c66affSColin Finck VOID
FillGrid(PMAP infoPtr,PAINTSTRUCT * ps)69c2c66affSColin Finck FillGrid(PMAP infoPtr,
70c2c66affSColin Finck          PAINTSTRUCT *ps)
71c2c66affSColin Finck {
72c2c66affSColin Finck     HFONT hOldFont;
73c2c66affSColin Finck     INT x, y;
74c2c66affSColin Finck     RECT rc;
75c2c66affSColin Finck     PCELL Cell;
76*7e9f1e67SKatayama Hirofumi MZ     INT i;
77*7e9f1e67SKatayama Hirofumi MZ     HBRUSH hOldBrush, hbrGray = (HBRUSH)GetStockObject(LTGRAY_BRUSH);
78*7e9f1e67SKatayama Hirofumi MZ     HPEN hOldPen, hPenGray = CreatePen(PS_SOLID, 1, RGB(140, 140, 140));
79c2c66affSColin Finck 
80*7e9f1e67SKatayama Hirofumi MZ     UpdateCells(infoPtr);
81*7e9f1e67SKatayama Hirofumi MZ 
82*7e9f1e67SKatayama Hirofumi MZ     hOldFont = SelectObject(ps->hdc, infoPtr->hFont);
83*7e9f1e67SKatayama Hirofumi MZ     hOldPen = SelectObject(ps->hdc, GetStockObject(BLACK_PEN));
84*7e9f1e67SKatayama Hirofumi MZ     hOldBrush = SelectObject(ps->hdc, GetStockObject(WHITE_BRUSH));
85c2c66affSColin Finck 
86c2c66affSColin Finck     i = XCELLS * infoPtr->iYStart;
87c2c66affSColin Finck 
88c2c66affSColin Finck     for (y = 0; y < YCELLS; y++)
89c2c66affSColin Finck     {
90*7e9f1e67SKatayama Hirofumi MZ         for (x = 0; x < XCELLS; x++, i++)
91*7e9f1e67SKatayama Hirofumi MZ         {
92c2c66affSColin Finck             Cell = &infoPtr->Cells[y][x];
93*7e9f1e67SKatayama Hirofumi MZ             if (!IntersectRect(&rc, &ps->rcPaint, &Cell->CellExt))
94*7e9f1e67SKatayama Hirofumi MZ                 continue;
95c2c66affSColin Finck 
96*7e9f1e67SKatayama Hirofumi MZ             rc = Cell->CellExt;
97*7e9f1e67SKatayama Hirofumi MZ             Rectangle(ps->hdc, rc.left, rc.top, rc.right, rc.bottom);
98*7e9f1e67SKatayama Hirofumi MZ 
99*7e9f1e67SKatayama Hirofumi MZ             if (i < infoPtr->NumValidGlyphs)
100c2c66affSColin Finck             {
101*7e9f1e67SKatayama Hirofumi MZ                 DrawTextW(ps->hdc, &Cell->ch, 1, &Cell->CellInt,
102c2c66affSColin Finck                           DT_CENTER | DT_VCENTER | DT_SINGLELINE);
103*7e9f1e67SKatayama Hirofumi MZ                 if (Cell == infoPtr->pActiveCell)
104*7e9f1e67SKatayama Hirofumi MZ                 {
105*7e9f1e67SKatayama Hirofumi MZ                     rc = Cell->CellInt;
106c2c66affSColin Finck 
107*7e9f1e67SKatayama Hirofumi MZ                     /* Draw gray box */
108*7e9f1e67SKatayama Hirofumi MZ                     SelectObject(ps->hdc, GetStockObject(NULL_BRUSH));
109*7e9f1e67SKatayama Hirofumi MZ                     SelectObject(ps->hdc, hPenGray);
110*7e9f1e67SKatayama Hirofumi MZ                     Rectangle(ps->hdc, rc.left, rc.top, rc.right, rc.bottom);
111*7e9f1e67SKatayama Hirofumi MZ                     SelectObject(ps->hdc, hOldPen);
112*7e9f1e67SKatayama Hirofumi MZ                     SelectObject(ps->hdc, hOldBrush);
113*7e9f1e67SKatayama Hirofumi MZ 
114*7e9f1e67SKatayama Hirofumi MZ                     if (GetFocus() == infoPtr->hMapWnd)
115*7e9f1e67SKatayama Hirofumi MZ                     {
116*7e9f1e67SKatayama Hirofumi MZ                         /* Draw focus rectangle */
117*7e9f1e67SKatayama Hirofumi MZ                         InflateRect(&rc, -1, -1);
118*7e9f1e67SKatayama Hirofumi MZ                         DrawFocusRect(ps->hdc, &rc);
119*7e9f1e67SKatayama Hirofumi MZ                     }
120*7e9f1e67SKatayama Hirofumi MZ                 }
121*7e9f1e67SKatayama Hirofumi MZ             }
122*7e9f1e67SKatayama Hirofumi MZ             else
123*7e9f1e67SKatayama Hirofumi MZ             {
124*7e9f1e67SKatayama Hirofumi MZ                 FillRect(ps->hdc, &Cell->CellInt, hbrGray);
125*7e9f1e67SKatayama Hirofumi MZ             }
126*7e9f1e67SKatayama Hirofumi MZ         }
127c2c66affSColin Finck     }
128c2c66affSColin Finck 
129*7e9f1e67SKatayama Hirofumi MZ     SelectObject(ps->hdc, hOldFont);
130*7e9f1e67SKatayama Hirofumi MZ     SelectObject(ps->hdc, hOldPen);
131*7e9f1e67SKatayama Hirofumi MZ     SelectObject(ps->hdc, hOldBrush);
132*7e9f1e67SKatayama Hirofumi MZ     DeleteObject(hPenGray);
133c2c66affSColin Finck }
134c2c66affSColin Finck 
135c2c66affSColin Finck 
136c2c66affSColin Finck static
137c2c66affSColin Finck BOOL
CreateLargeCell(PMAP infoPtr)138c2c66affSColin Finck CreateLargeCell(PMAP infoPtr)
139c2c66affSColin Finck {
140*7e9f1e67SKatayama Hirofumi MZ     RECT rLarge = infoPtr->pActiveCell->CellExt;
141c2c66affSColin Finck 
142*7e9f1e67SKatayama Hirofumi MZ     MapWindowPoints(infoPtr->hMapWnd, infoPtr->hParent, (LPPOINT)&rLarge, 2);
143c2c66affSColin Finck 
144*7e9f1e67SKatayama Hirofumi MZ     InflateRect(&rLarge, XLARGE - XCELLS, YLARGE - YCELLS);
145c2c66affSColin Finck 
146c2c66affSColin Finck     infoPtr->hLrgWnd = CreateWindowExW(0,
147c2c66affSColin Finck                                        szLrgCellWndClass,
148c2c66affSColin Finck                                        NULL,
149c2c66affSColin Finck                                        WS_CHILDWINDOW | WS_VISIBLE,
150c2c66affSColin Finck                                        rLarge.left,
151c2c66affSColin Finck                                        rLarge.top,
152c2c66affSColin Finck                                        rLarge.right - rLarge.left,
153c2c66affSColin Finck                                        rLarge.bottom - rLarge.top,
154c2c66affSColin Finck                                        infoPtr->hParent,
155c2c66affSColin Finck                                        NULL,
156c2c66affSColin Finck                                        hInstance,
157c2c66affSColin Finck                                        infoPtr);
158c2c66affSColin Finck     if (!infoPtr->hLrgWnd)
159c2c66affSColin Finck         return FALSE;
160c2c66affSColin Finck 
161c2c66affSColin Finck     return TRUE;
162c2c66affSColin Finck }
163c2c66affSColin Finck 
164c2c66affSColin Finck 
165c2c66affSColin Finck static
166c2c66affSColin Finck VOID
MoveLargeCell(PMAP infoPtr)167c2c66affSColin Finck MoveLargeCell(PMAP infoPtr)
168c2c66affSColin Finck {
169*7e9f1e67SKatayama Hirofumi MZ     RECT rLarge = infoPtr->pActiveCell->CellExt;
170c2c66affSColin Finck 
171*7e9f1e67SKatayama Hirofumi MZ     MapWindowPoints(infoPtr->hMapWnd, infoPtr->hParent, (LPPOINT)&rLarge, 2);
172c2c66affSColin Finck 
173*7e9f1e67SKatayama Hirofumi MZ     InflateRect(&rLarge, XLARGE - XCELLS, YLARGE - YCELLS);
174c2c66affSColin Finck 
175c2c66affSColin Finck     MoveWindow(infoPtr->hLrgWnd,
176c2c66affSColin Finck                rLarge.left,
177c2c66affSColin Finck                rLarge.top,
178c2c66affSColin Finck                rLarge.right - rLarge.left,
179c2c66affSColin Finck                rLarge.bottom - rLarge.top,
180c2c66affSColin Finck                TRUE);
181c2c66affSColin Finck 
182*7e9f1e67SKatayama Hirofumi MZ     InvalidateRect(infoPtr->hLrgWnd, NULL, TRUE);
183c2c66affSColin Finck }
184c2c66affSColin Finck 
185c2c66affSColin Finck 
186c2c66affSColin Finck static
187c2c66affSColin Finck VOID
GetPossibleCharacters(WCHAR * ch,INT chLen,INT codePageIdx)18899dd2925SCharles Ambrye GetPossibleCharacters(WCHAR* ch, INT chLen, INT codePageIdx)
18999dd2925SCharles Ambrye {
19099dd2925SCharles Ambrye     INT i, j;
19199dd2925SCharles Ambrye 
192*7e9f1e67SKatayama Hirofumi MZ     ZeroMemory(ch, sizeof(ch[0]) * chLen);
19399dd2925SCharles Ambrye 
19499dd2925SCharles Ambrye     if (codePageIdx <= 0 || codePageIdx > SIZEOF(codePages))
19599dd2925SCharles Ambrye     {
19699dd2925SCharles Ambrye         /* this is unicode, so just load up the first MAX_GLYPHS characters
19799dd2925SCharles Ambrye            start at 0x21 to bypass whitespace characters */
19899dd2925SCharles Ambrye         INT len = min(MAX_GLYPHS, chLen);
19999dd2925SCharles Ambrye         for (i = 0x21, j = 0; i < len; i++)
20099dd2925SCharles Ambrye             ch[j++] = (WCHAR)i;
20199dd2925SCharles Ambrye     }
20299dd2925SCharles Ambrye     else
20399dd2925SCharles Ambrye     {
20499dd2925SCharles Ambrye         /* This is a codepage, so use NLS to translate the first 256 characters */
20599dd2925SCharles Ambrye         CHAR multiByteString[256] = { 0 };
20699dd2925SCharles Ambrye         for (i = 0x21; i < SIZEOF(multiByteString); i++)
20799dd2925SCharles Ambrye             multiByteString[i] = (CHAR)i;
20899dd2925SCharles Ambrye 
20999dd2925SCharles Ambrye         if (!MultiByteToWideChar(codePages[codePageIdx - 1], 0, multiByteString, sizeof(multiByteString), ch, chLen))
21099dd2925SCharles Ambrye         {
21199dd2925SCharles Ambrye             /* Failed for some reason, so clear the array */
21299dd2925SCharles Ambrye             memset(ch, 0, sizeof(ch[0]) * chLen);
21399dd2925SCharles Ambrye         }
21499dd2925SCharles Ambrye     }
21599dd2925SCharles Ambrye }
21699dd2925SCharles Ambrye 
21799dd2925SCharles Ambrye 
21899dd2925SCharles Ambrye static
21999dd2925SCharles Ambrye VOID
SetFont(PMAP infoPtr,LPWSTR lpFontName)220c2c66affSColin Finck SetFont(PMAP infoPtr,
221c2c66affSColin Finck         LPWSTR lpFontName)
222c2c66affSColin Finck {
223c2c66affSColin Finck     HDC hdc;
224c2c66affSColin Finck     WCHAR ch[MAX_GLYPHS];
225c2c66affSColin Finck     WORD out[MAX_GLYPHS];
226c2c66affSColin Finck     DWORD i, j;
227c2c66affSColin Finck 
228c2c66affSColin Finck     /* Destroy Zoom window, since it was created with older font */
229c2c66affSColin Finck     DestroyWindow(infoPtr->hLrgWnd);
230c2c66affSColin Finck     infoPtr->hLrgWnd = NULL;
231c2c66affSColin Finck 
232c2c66affSColin Finck     if (infoPtr->hFont)
233c2c66affSColin Finck         DeleteObject(infoPtr->hFont);
234c2c66affSColin Finck 
235c2c66affSColin Finck     ZeroMemory(&infoPtr->CurrentFont,
236c2c66affSColin Finck                sizeof(LOGFONTW));
237c2c66affSColin Finck 
238c2c66affSColin Finck     hdc = GetDC(infoPtr->hMapWnd);
239c2c66affSColin Finck     infoPtr->CurrentFont.lfHeight = GetDeviceCaps(hdc, LOGPIXELSY) / 5;
240c2c66affSColin Finck 
241c2c66affSColin Finck     infoPtr->CurrentFont.lfCharSet =  DEFAULT_CHARSET;
24299dd2925SCharles Ambrye     lstrcpynW(infoPtr->CurrentFont.lfFaceName,
243c2c66affSColin Finck               lpFontName,
24499dd2925SCharles Ambrye               SIZEOF(infoPtr->CurrentFont.lfFaceName));
245c2c66affSColin Finck 
246c2c66affSColin Finck     infoPtr->hFont = CreateFontIndirectW(&infoPtr->CurrentFont);
247c2c66affSColin Finck 
248c2c66affSColin Finck     InvalidateRect(infoPtr->hMapWnd,
249c2c66affSColin Finck                    NULL,
250c2c66affSColin Finck                    TRUE);
251c2c66affSColin Finck 
252c2c66affSColin Finck     // Get all the valid glyphs in this font
253c2c66affSColin Finck 
254c2c66affSColin Finck     SelectObject(hdc, infoPtr->hFont);
255c2c66affSColin Finck 
25699dd2925SCharles Ambrye     // Get the code page associated with the selected 'character set'
25799dd2925SCharles Ambrye     GetPossibleCharacters(ch, MAX_GLYPHS, infoPtr->CharMap);
258c2c66affSColin Finck 
259c2c66affSColin Finck     if (GetGlyphIndicesW(hdc,
260c2c66affSColin Finck                          ch,
261c2c66affSColin Finck                          MAX_GLYPHS,
262c2c66affSColin Finck                          out,
263c2c66affSColin Finck                          GGI_MARK_NONEXISTING_GLYPHS) != GDI_ERROR)
264c2c66affSColin Finck     {
265c2c66affSColin Finck         j = 0;
26699dd2925SCharles Ambrye         for (i = 0; i < MAX_GLYPHS; i++)
267c2c66affSColin Finck         {
26899dd2925SCharles Ambrye             if (out[i] != 0xffff && out[i] != 0x0000 && ch[i] != 0x0000)
269c2c66affSColin Finck             {
270c2c66affSColin Finck                 infoPtr->ValidGlyphs[j] = ch[i];
271c2c66affSColin Finck                 j++;
272c2c66affSColin Finck             }
273c2c66affSColin Finck         }
274c2c66affSColin Finck         infoPtr->NumValidGlyphs = j;
275c2c66affSColin Finck     }
276c2c66affSColin Finck 
277c2c66affSColin Finck     ReleaseDC(infoPtr->hMapWnd, hdc);
278c2c66affSColin Finck 
279c2c66affSColin Finck     infoPtr->NumRows = infoPtr->NumValidGlyphs / XCELLS;
280c2c66affSColin Finck     if (infoPtr->NumValidGlyphs % XCELLS)
281c2c66affSColin Finck         infoPtr->NumRows += 1;
282c2c66affSColin Finck     infoPtr->NumRows = (infoPtr->NumRows > YCELLS) ? infoPtr->NumRows - YCELLS : 0;
283c2c66affSColin Finck 
284c2c66affSColin Finck     SetScrollRange(infoPtr->hMapWnd, SB_VERT, 0, infoPtr->NumRows, FALSE);
285c2c66affSColin Finck     SetScrollPos(infoPtr->hMapWnd, SB_VERT, 0, TRUE);
286c2c66affSColin Finck     infoPtr->iYStart = 0;
287c2c66affSColin Finck }
288c2c66affSColin Finck 
289c2c66affSColin Finck 
290c2c66affSColin Finck static
291c2c66affSColin Finck LRESULT
NotifyParentOfSelection(PMAP infoPtr,UINT code,WCHAR ch)292c2c66affSColin Finck NotifyParentOfSelection(PMAP infoPtr,
293c2c66affSColin Finck                         UINT code,
294c2c66affSColin Finck                         WCHAR ch)
295c2c66affSColin Finck {
296c2c66affSColin Finck     LRESULT Ret = 0;
297c2c66affSColin Finck 
298c2c66affSColin Finck     if (infoPtr->hParent != NULL)
299c2c66affSColin Finck     {
300c2c66affSColin Finck         DWORD dwIdc = GetWindowLongPtr(infoPtr->hMapWnd, GWLP_ID);
301c2c66affSColin Finck         /*
302c2c66affSColin Finck          * Push directly into the event queue instead of waiting
303c2c66affSColin Finck          * the parent to be unlocked.
304c2c66affSColin Finck          * High word of LPARAM is still available for future needs...
305c2c66affSColin Finck          */
306c2c66affSColin Finck         Ret = PostMessage(infoPtr->hParent,
307c2c66affSColin Finck                           WM_COMMAND,
308c2c66affSColin Finck                           MAKELPARAM((WORD)dwIdc, (WORD)code),
309c2c66affSColin Finck                           (LPARAM)LOWORD(ch));
310c2c66affSColin Finck     }
311c2c66affSColin Finck 
312c2c66affSColin Finck     return Ret;
313c2c66affSColin Finck }
314c2c66affSColin Finck 
315c2c66affSColin Finck 
316c2c66affSColin Finck static
317c2c66affSColin Finck VOID
LimitCaretXY(PMAP infoPtr,INT * pX,INT * pY)318*7e9f1e67SKatayama Hirofumi MZ LimitCaretXY(PMAP infoPtr, INT *pX, INT *pY)
319*7e9f1e67SKatayama Hirofumi MZ {
320*7e9f1e67SKatayama Hirofumi MZ     INT i, X = *pX, Y = *pY, iYStart = infoPtr->iYStart;
321*7e9f1e67SKatayama Hirofumi MZ 
322*7e9f1e67SKatayama Hirofumi MZ     i = XCELLS * (iYStart + Y) + X;
323*7e9f1e67SKatayama Hirofumi MZ     while (i >= infoPtr->NumValidGlyphs)
324*7e9f1e67SKatayama Hirofumi MZ     {
325*7e9f1e67SKatayama Hirofumi MZ         if (X > 0)
326*7e9f1e67SKatayama Hirofumi MZ         {
327*7e9f1e67SKatayama Hirofumi MZ             --X;
328*7e9f1e67SKatayama Hirofumi MZ         }
329*7e9f1e67SKatayama Hirofumi MZ         else
330*7e9f1e67SKatayama Hirofumi MZ         {
331*7e9f1e67SKatayama Hirofumi MZ             X = XCELLS - 1;
332*7e9f1e67SKatayama Hirofumi MZ             --Y;
333*7e9f1e67SKatayama Hirofumi MZ         }
334*7e9f1e67SKatayama Hirofumi MZ         i = XCELLS * (iYStart + Y) + X;
335*7e9f1e67SKatayama Hirofumi MZ     }
336*7e9f1e67SKatayama Hirofumi MZ 
337*7e9f1e67SKatayama Hirofumi MZ     *pX = X;
338*7e9f1e67SKatayama Hirofumi MZ     *pY = Y;
339*7e9f1e67SKatayama Hirofumi MZ }
340*7e9f1e67SKatayama Hirofumi MZ 
341*7e9f1e67SKatayama Hirofumi MZ static
342*7e9f1e67SKatayama Hirofumi MZ VOID
SetCaretXY(PMAP infoPtr,INT X,INT Y,BOOL bLarge,BOOL bInvalidateAll)343*7e9f1e67SKatayama Hirofumi MZ SetCaretXY(PMAP infoPtr, INT X, INT Y, BOOL bLarge, BOOL bInvalidateAll)
344*7e9f1e67SKatayama Hirofumi MZ {
345*7e9f1e67SKatayama Hirofumi MZ 
346*7e9f1e67SKatayama Hirofumi MZ     /* set previous active cell to inactive */
347*7e9f1e67SKatayama Hirofumi MZ     if (!bInvalidateAll)
348*7e9f1e67SKatayama Hirofumi MZ     {
349*7e9f1e67SKatayama Hirofumi MZ         InvalidateRect(infoPtr->hMapWnd,
350*7e9f1e67SKatayama Hirofumi MZ                        &infoPtr->pActiveCell->CellInt,
351*7e9f1e67SKatayama Hirofumi MZ                        FALSE);
352*7e9f1e67SKatayama Hirofumi MZ     }
353*7e9f1e67SKatayama Hirofumi MZ 
354*7e9f1e67SKatayama Hirofumi MZ     LimitCaretXY(infoPtr, &X, &Y);
355*7e9f1e67SKatayama Hirofumi MZ     infoPtr->CaretX = X;
356*7e9f1e67SKatayama Hirofumi MZ     infoPtr->CaretY = Y;
357*7e9f1e67SKatayama Hirofumi MZ     UpdateCells(infoPtr);
358*7e9f1e67SKatayama Hirofumi MZ 
359*7e9f1e67SKatayama Hirofumi MZ     /* set new cell to active */
360*7e9f1e67SKatayama Hirofumi MZ     infoPtr->pActiveCell = &infoPtr->Cells[Y][X];
361*7e9f1e67SKatayama Hirofumi MZ     if (!bInvalidateAll)
362*7e9f1e67SKatayama Hirofumi MZ     {
363*7e9f1e67SKatayama Hirofumi MZ         InvalidateRect(infoPtr->hMapWnd,
364*7e9f1e67SKatayama Hirofumi MZ                        &infoPtr->pActiveCell->CellInt,
365*7e9f1e67SKatayama Hirofumi MZ                        FALSE);
366*7e9f1e67SKatayama Hirofumi MZ     }
367*7e9f1e67SKatayama Hirofumi MZ 
368*7e9f1e67SKatayama Hirofumi MZ     /* Create if needed */
369*7e9f1e67SKatayama Hirofumi MZ     if (bLarge)
370*7e9f1e67SKatayama Hirofumi MZ     {
371*7e9f1e67SKatayama Hirofumi MZ         if (infoPtr->hLrgWnd)
372*7e9f1e67SKatayama Hirofumi MZ             MoveLargeCell(infoPtr);
373*7e9f1e67SKatayama Hirofumi MZ         else
374*7e9f1e67SKatayama Hirofumi MZ             CreateLargeCell(infoPtr);
375*7e9f1e67SKatayama Hirofumi MZ     }
376*7e9f1e67SKatayama Hirofumi MZ     else
377*7e9f1e67SKatayama Hirofumi MZ     {
378*7e9f1e67SKatayama Hirofumi MZ         /* Destroy large window */
379*7e9f1e67SKatayama Hirofumi MZ         if (infoPtr->hLrgWnd)
380*7e9f1e67SKatayama Hirofumi MZ         {
381*7e9f1e67SKatayama Hirofumi MZ             DestroyWindow(infoPtr->hLrgWnd);
382*7e9f1e67SKatayama Hirofumi MZ             infoPtr->hLrgWnd = NULL;
383*7e9f1e67SKatayama Hirofumi MZ         }
384*7e9f1e67SKatayama Hirofumi MZ     }
385*7e9f1e67SKatayama Hirofumi MZ 
386*7e9f1e67SKatayama Hirofumi MZ     if (bInvalidateAll)
387*7e9f1e67SKatayama Hirofumi MZ         InvalidateRect(infoPtr->hMapWnd, NULL, FALSE);
388*7e9f1e67SKatayama Hirofumi MZ 
389*7e9f1e67SKatayama Hirofumi MZ     UpdateStatusBar(infoPtr->pActiveCell->ch);
390*7e9f1e67SKatayama Hirofumi MZ }
391*7e9f1e67SKatayama Hirofumi MZ 
392*7e9f1e67SKatayama Hirofumi MZ static
393*7e9f1e67SKatayama Hirofumi MZ VOID
OnClick(PMAP infoPtr,WORD ptx,WORD pty)394c2c66affSColin Finck OnClick(PMAP infoPtr,
395c2c66affSColin Finck         WORD ptx,
396c2c66affSColin Finck         WORD pty)
397c2c66affSColin Finck {
39899dd2925SCharles Ambrye     /*
39999dd2925SCharles Ambrye      * Find the cell the mouse pointer is over.
40099dd2925SCharles Ambrye      * Since each cell is the same size, this can be done quickly using CellSize.
40199dd2925SCharles Ambrye      * Clamp to XCELLS - 1 and YCELLS - 1 because the map can sometimes be slightly
40299dd2925SCharles Ambrye      * larger than infoPtr.CellSize * XCELLS , due to the map size being a non integer
40399dd2925SCharles Ambrye      * multiple of infoPtr.CellSize .
40499dd2925SCharles Ambrye      */
405*7e9f1e67SKatayama Hirofumi MZ     INT x = min(XCELLS - 1, ptx / max(1, infoPtr->CellSize.cx));
406*7e9f1e67SKatayama Hirofumi MZ     INT y = min(YCELLS - 1, pty / max(1, infoPtr->CellSize.cy));
40799dd2925SCharles Ambrye 
408*7e9f1e67SKatayama Hirofumi MZ     SetCaretXY(infoPtr, x, y, TRUE, FALSE);
409c2c66affSColin Finck }
410c2c66affSColin Finck 
411c2c66affSColin Finck 
412c2c66affSColin Finck static
413c2c66affSColin Finck BOOL
MapOnCreate(PMAP infoPtr,HWND hwnd,HWND hParent)4141963e2d1SAmine Khaldi MapOnCreate(PMAP infoPtr,
415c2c66affSColin Finck             HWND hwnd,
416c2c66affSColin Finck             HWND hParent)
417c2c66affSColin Finck {
418c2c66affSColin Finck     RECT rc;
419c2c66affSColin Finck 
420*7e9f1e67SKatayama Hirofumi MZ     infoPtr = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(MAP));
421*7e9f1e67SKatayama Hirofumi MZ     if (!infoPtr)
422*7e9f1e67SKatayama Hirofumi MZ         return FALSE;
423*7e9f1e67SKatayama Hirofumi MZ 
424*7e9f1e67SKatayama Hirofumi MZ     SetWindowLongPtrW(hwnd, 0, (LONG_PTR)infoPtr);
425c2c66affSColin Finck 
426c2c66affSColin Finck     infoPtr->hMapWnd = hwnd;
427c2c66affSColin Finck     infoPtr->hParent = hParent;
428c2c66affSColin Finck 
429c2c66affSColin Finck     GetClientRect(hwnd, &rc);
430c2c66affSColin Finck     infoPtr->ClientSize.cx = rc.right;
431c2c66affSColin Finck     infoPtr->ClientSize.cy = rc.bottom;
432c2c66affSColin Finck     infoPtr->CellSize.cx = infoPtr->ClientSize.cx / XCELLS;
433c2c66affSColin Finck     infoPtr->CellSize.cy = infoPtr->ClientSize.cy / YCELLS;
434c2c66affSColin Finck 
435*7e9f1e67SKatayama Hirofumi MZ     infoPtr->pActiveCell = &infoPtr->Cells[0][0];
436c2c66affSColin Finck 
437c2c66affSColin Finck     SetGrid(infoPtr);
438c2c66affSColin Finck 
439c2c66affSColin Finck     SetScrollPos(infoPtr->hParent, SB_VERT, 0, TRUE);
440*7e9f1e67SKatayama Hirofumi MZ     return TRUE;
441c2c66affSColin Finck }
442c2c66affSColin Finck 
443c2c66affSColin Finck static
444c2c66affSColin Finck VOID
OnVScroll(PMAP infoPtr,INT Value,INT Pos)445c2c66affSColin Finck OnVScroll(PMAP infoPtr,
446c2c66affSColin Finck           INT Value,
447c2c66affSColin Finck           INT Pos)
448c2c66affSColin Finck {
449c2c66affSColin Finck     INT iYDiff, iOldYStart = infoPtr->iYStart;
450*7e9f1e67SKatayama Hirofumi MZ     INT X, Y;
451c2c66affSColin Finck 
452c2c66affSColin Finck     switch (Value)
453c2c66affSColin Finck     {
454c2c66affSColin Finck         case SB_LINEUP:
455c2c66affSColin Finck             infoPtr->iYStart -=  1;
456c2c66affSColin Finck             break;
457c2c66affSColin Finck 
458c2c66affSColin Finck         case SB_LINEDOWN:
459c2c66affSColin Finck             infoPtr->iYStart +=  1;
460c2c66affSColin Finck             break;
461c2c66affSColin Finck 
462c2c66affSColin Finck         case SB_PAGEUP:
463c2c66affSColin Finck             infoPtr->iYStart -= YCELLS;
464c2c66affSColin Finck             break;
465c2c66affSColin Finck 
466c2c66affSColin Finck         case SB_PAGEDOWN:
467c2c66affSColin Finck             infoPtr->iYStart += YCELLS;
468c2c66affSColin Finck             break;
469c2c66affSColin Finck 
470c2c66affSColin Finck         case SB_THUMBTRACK:
471c2c66affSColin Finck             infoPtr->iYStart = Pos;
472c2c66affSColin Finck             break;
473c2c66affSColin Finck 
474*7e9f1e67SKatayama Hirofumi MZ         case SB_TOP:
475*7e9f1e67SKatayama Hirofumi MZ             infoPtr->iYStart = 0;
476*7e9f1e67SKatayama Hirofumi MZ             SetCaretXY(infoPtr, 0, 0, FALSE, TRUE);
477*7e9f1e67SKatayama Hirofumi MZ             return;
478*7e9f1e67SKatayama Hirofumi MZ 
479*7e9f1e67SKatayama Hirofumi MZ         case SB_BOTTOM:
480*7e9f1e67SKatayama Hirofumi MZ             infoPtr->iYStart = infoPtr->NumRows;
481*7e9f1e67SKatayama Hirofumi MZ             SetCaretXY(infoPtr, XCELLS - 1, YCELLS - 1, FALSE, TRUE);
482*7e9f1e67SKatayama Hirofumi MZ             break;
483*7e9f1e67SKatayama Hirofumi MZ 
484c2c66affSColin Finck         default:
485c2c66affSColin Finck             break;
486c2c66affSColin Finck     }
487c2c66affSColin Finck 
488c2c66affSColin Finck     infoPtr->iYStart = max(0, infoPtr->iYStart);
489c2c66affSColin Finck     infoPtr->iYStart = min(infoPtr->iYStart, infoPtr->NumRows);
490c2c66affSColin Finck 
491*7e9f1e67SKatayama Hirofumi MZ     UpdateCells(infoPtr);
492*7e9f1e67SKatayama Hirofumi MZ 
493*7e9f1e67SKatayama Hirofumi MZ     X = infoPtr->CaretX;
494*7e9f1e67SKatayama Hirofumi MZ     Y = infoPtr->CaretY;
495*7e9f1e67SKatayama Hirofumi MZ     LimitCaretXY(infoPtr, &X, &Y);
496*7e9f1e67SKatayama Hirofumi MZ     SetCaretXY(infoPtr, X, Y, IsWindow(infoPtr->hLrgWnd), FALSE);
497*7e9f1e67SKatayama Hirofumi MZ 
498c2c66affSColin Finck     iYDiff = iOldYStart - infoPtr->iYStart;
499c2c66affSColin Finck     if (iYDiff)
500c2c66affSColin Finck     {
501c2c66affSColin Finck         if (infoPtr->hLrgWnd != NULL)
502c2c66affSColin Finck         {
503c2c66affSColin Finck             ShowWindow(infoPtr->hLrgWnd, SW_HIDE);
504c2c66affSColin Finck         }
505c2c66affSColin Finck 
506c2c66affSColin Finck         SetScrollPos(infoPtr->hMapWnd,
507c2c66affSColin Finck                      SB_VERT,
508c2c66affSColin Finck                      infoPtr->iYStart,
509c2c66affSColin Finck                      TRUE);
510c2c66affSColin Finck 
511c2c66affSColin Finck         if (abs(iYDiff) < YCELLS)
512c2c66affSColin Finck         {
513c2c66affSColin Finck             RECT rect;
51499dd2925SCharles Ambrye 
51599dd2925SCharles Ambrye             /* Invalidate the rect around the active cell since a new cell will become active */
516*7e9f1e67SKatayama Hirofumi MZ             if (infoPtr->pActiveCell)
51799dd2925SCharles Ambrye             {
51899dd2925SCharles Ambrye                 InvalidateRect(infoPtr->hMapWnd,
51999dd2925SCharles Ambrye                                &infoPtr->pActiveCell->CellExt,
52099dd2925SCharles Ambrye                                TRUE);
52199dd2925SCharles Ambrye             }
52299dd2925SCharles Ambrye 
523c2c66affSColin Finck             GetClientRect(infoPtr->hMapWnd, &rect);
524c2c66affSColin Finck             rect.top += 2;
525c2c66affSColin Finck             rect.bottom -= 2;
526c2c66affSColin Finck             ScrollWindowEx(infoPtr->hMapWnd,
527c2c66affSColin Finck                            0,
528c2c66affSColin Finck                            iYDiff * infoPtr->CellSize.cy,
529c2c66affSColin Finck                            &rect,
530c2c66affSColin Finck                            &rect,
531c2c66affSColin Finck                            NULL,
532c2c66affSColin Finck                            NULL,
533c2c66affSColin Finck                            SW_INVALIDATE);
534c2c66affSColin Finck         }
535c2c66affSColin Finck         else
536c2c66affSColin Finck         {
537c2c66affSColin Finck             InvalidateRect(infoPtr->hMapWnd,
538c2c66affSColin Finck                            NULL,
539c2c66affSColin Finck                            TRUE);
540c2c66affSColin Finck         }
541c2c66affSColin Finck 
542c2c66affSColin Finck         if (infoPtr->hLrgWnd != NULL)
543c2c66affSColin Finck         {
544c2c66affSColin Finck             ShowWindow(infoPtr->hLrgWnd, SW_SHOW);
545c2c66affSColin Finck         }
546c2c66affSColin Finck     }
547*7e9f1e67SKatayama Hirofumi MZ 
548*7e9f1e67SKatayama Hirofumi MZ     UpdateStatusBar(infoPtr->pActiveCell->ch);
549c2c66affSColin Finck }
550c2c66affSColin Finck 
551c2c66affSColin Finck 
552c2c66affSColin Finck static
553c2c66affSColin Finck VOID
OnPaint(PMAP infoPtr,WPARAM wParam)554c2c66affSColin Finck OnPaint(PMAP infoPtr,
555c2c66affSColin Finck         WPARAM wParam)
556c2c66affSColin Finck {
557c2c66affSColin Finck     PAINTSTRUCT ps;
558c2c66affSColin Finck     HDC hdc;
559c2c66affSColin Finck 
560c2c66affSColin Finck     if (wParam != 0)
561c2c66affSColin Finck     {
562*7e9f1e67SKatayama Hirofumi MZ         if (!GetUpdateRect(infoPtr->hMapWnd, &ps.rcPaint, TRUE))
563c2c66affSColin Finck             return;
564*7e9f1e67SKatayama Hirofumi MZ 
565c2c66affSColin Finck         ps.hdc = (HDC)wParam;
566c2c66affSColin Finck     }
567c2c66affSColin Finck     else
568c2c66affSColin Finck     {
569*7e9f1e67SKatayama Hirofumi MZ         hdc = BeginPaint(infoPtr->hMapWnd, &ps);
570c2c66affSColin Finck         if (hdc == NULL)
571c2c66affSColin Finck             return;
572c2c66affSColin Finck     }
573c2c66affSColin Finck 
574c2c66affSColin Finck     FillGrid(infoPtr, &ps);
575c2c66affSColin Finck 
576c2c66affSColin Finck     if (wParam == 0)
577c2c66affSColin Finck     {
578*7e9f1e67SKatayama Hirofumi MZ         EndPaint(infoPtr->hMapWnd, &ps);
579c2c66affSColin Finck     }
580c2c66affSColin Finck }
581c2c66affSColin Finck 
582*7e9f1e67SKatayama Hirofumi MZ static
583*7e9f1e67SKatayama Hirofumi MZ VOID
MoveUpDown(PMAP infoPtr,INT DY)584*7e9f1e67SKatayama Hirofumi MZ MoveUpDown(PMAP infoPtr, INT DY)
585*7e9f1e67SKatayama Hirofumi MZ {
586*7e9f1e67SKatayama Hirofumi MZ     INT Y = infoPtr->CaretY;
587*7e9f1e67SKatayama Hirofumi MZ 
588*7e9f1e67SKatayama Hirofumi MZ     if (DY < 0) /* Move Up */
589*7e9f1e67SKatayama Hirofumi MZ     {
590*7e9f1e67SKatayama Hirofumi MZ         if (Y <= 0)
591*7e9f1e67SKatayama Hirofumi MZ         {
592*7e9f1e67SKatayama Hirofumi MZ             SendMessageW(infoPtr->hMapWnd, WM_VSCROLL, MAKEWPARAM(SB_LINEUP, 0), 0);
593*7e9f1e67SKatayama Hirofumi MZ             return;
594*7e9f1e67SKatayama Hirofumi MZ         }
595*7e9f1e67SKatayama Hirofumi MZ 
596*7e9f1e67SKatayama Hirofumi MZ         Y -= 1;
597*7e9f1e67SKatayama Hirofumi MZ     }
598*7e9f1e67SKatayama Hirofumi MZ     else if (DY > 0) /* Move Down */
599*7e9f1e67SKatayama Hirofumi MZ     {
600*7e9f1e67SKatayama Hirofumi MZ         if (Y + 1 >= YCELLS)
601*7e9f1e67SKatayama Hirofumi MZ         {
602*7e9f1e67SKatayama Hirofumi MZ             SendMessageW(infoPtr->hMapWnd, WM_VSCROLL, MAKEWPARAM(SB_LINEDOWN, 0), 0);
603*7e9f1e67SKatayama Hirofumi MZ             return;
604*7e9f1e67SKatayama Hirofumi MZ         }
605*7e9f1e67SKatayama Hirofumi MZ 
606*7e9f1e67SKatayama Hirofumi MZ         Y += 1;
607*7e9f1e67SKatayama Hirofumi MZ     }
608*7e9f1e67SKatayama Hirofumi MZ 
609*7e9f1e67SKatayama Hirofumi MZ     SetCaretXY(infoPtr, infoPtr->CaretX, Y, IsWindow(infoPtr->hLrgWnd), FALSE);
610*7e9f1e67SKatayama Hirofumi MZ }
611*7e9f1e67SKatayama Hirofumi MZ 
612*7e9f1e67SKatayama Hirofumi MZ static
613*7e9f1e67SKatayama Hirofumi MZ VOID
MoveLeftRight(PMAP infoPtr,INT DX)614*7e9f1e67SKatayama Hirofumi MZ MoveLeftRight(PMAP infoPtr, INT DX)
615*7e9f1e67SKatayama Hirofumi MZ {
616*7e9f1e67SKatayama Hirofumi MZ     INT X = infoPtr->CaretX;
617*7e9f1e67SKatayama Hirofumi MZ     INT Y = infoPtr->CaretY;
618*7e9f1e67SKatayama Hirofumi MZ 
619*7e9f1e67SKatayama Hirofumi MZ     if (DX < 0) /* Move Left */
620*7e9f1e67SKatayama Hirofumi MZ     {
621*7e9f1e67SKatayama Hirofumi MZ         if (X <= 0) /* at left edge */
622*7e9f1e67SKatayama Hirofumi MZ         {
623*7e9f1e67SKatayama Hirofumi MZ             if (Y <= 0) /* at top */
624*7e9f1e67SKatayama Hirofumi MZ             {
625*7e9f1e67SKatayama Hirofumi MZ                 Y = 0;
626*7e9f1e67SKatayama Hirofumi MZ                 if (infoPtr->iYStart > 0)
627*7e9f1e67SKatayama Hirofumi MZ                     X = XCELLS - 1;
628*7e9f1e67SKatayama Hirofumi MZ                 SendMessageW(infoPtr->hMapWnd, WM_VSCROLL, MAKEWPARAM(SB_LINEUP, 0), 0);
629*7e9f1e67SKatayama Hirofumi MZ             }
630*7e9f1e67SKatayama Hirofumi MZ             else
631*7e9f1e67SKatayama Hirofumi MZ             {
632*7e9f1e67SKatayama Hirofumi MZ                 X = XCELLS - 1;
633*7e9f1e67SKatayama Hirofumi MZ                 Y -= 1;
634*7e9f1e67SKatayama Hirofumi MZ             }
635*7e9f1e67SKatayama Hirofumi MZ         }
636*7e9f1e67SKatayama Hirofumi MZ         else /* Not at left edge */
637*7e9f1e67SKatayama Hirofumi MZ         {
638*7e9f1e67SKatayama Hirofumi MZ             X -= 1;
639*7e9f1e67SKatayama Hirofumi MZ         }
640*7e9f1e67SKatayama Hirofumi MZ     }
641*7e9f1e67SKatayama Hirofumi MZ     else if (DX > 0) /* Move Right */
642*7e9f1e67SKatayama Hirofumi MZ     {
643*7e9f1e67SKatayama Hirofumi MZ         if (X + 1 >= XCELLS) /* at right edge */
644*7e9f1e67SKatayama Hirofumi MZ         {
645*7e9f1e67SKatayama Hirofumi MZ             if (Y + 1 >= YCELLS) /* at bottom */
646*7e9f1e67SKatayama Hirofumi MZ             {
647*7e9f1e67SKatayama Hirofumi MZ                 Y = YCELLS - 1;
648*7e9f1e67SKatayama Hirofumi MZ                 if (infoPtr->iYStart < infoPtr->NumRows)
649*7e9f1e67SKatayama Hirofumi MZ                     X = 0;
650*7e9f1e67SKatayama Hirofumi MZ                 SendMessageW(infoPtr->hMapWnd, WM_VSCROLL, MAKEWPARAM(SB_LINEDOWN, 0), 0);
651*7e9f1e67SKatayama Hirofumi MZ             }
652*7e9f1e67SKatayama Hirofumi MZ             else
653*7e9f1e67SKatayama Hirofumi MZ             {
654*7e9f1e67SKatayama Hirofumi MZ                 X = 0;
655*7e9f1e67SKatayama Hirofumi MZ                 Y += 1;
656*7e9f1e67SKatayama Hirofumi MZ             }
657*7e9f1e67SKatayama Hirofumi MZ         }
658*7e9f1e67SKatayama Hirofumi MZ         else
659*7e9f1e67SKatayama Hirofumi MZ         {
660*7e9f1e67SKatayama Hirofumi MZ             X += 1;
661*7e9f1e67SKatayama Hirofumi MZ         }
662*7e9f1e67SKatayama Hirofumi MZ     }
663*7e9f1e67SKatayama Hirofumi MZ 
664*7e9f1e67SKatayama Hirofumi MZ     SetCaretXY(infoPtr, X, Y, IsWindow(infoPtr->hLrgWnd), FALSE);
665*7e9f1e67SKatayama Hirofumi MZ }
666*7e9f1e67SKatayama Hirofumi MZ 
667*7e9f1e67SKatayama Hirofumi MZ static
668*7e9f1e67SKatayama Hirofumi MZ VOID
OnKeyDown(PMAP infoPtr,WPARAM wParam,LPARAM lParam)669*7e9f1e67SKatayama Hirofumi MZ OnKeyDown(PMAP infoPtr, WPARAM wParam, LPARAM lParam)
670*7e9f1e67SKatayama Hirofumi MZ {
671*7e9f1e67SKatayama Hirofumi MZ     BOOL bCtrlDown = (GetKeyState(VK_CONTROL) < 0);
672*7e9f1e67SKatayama Hirofumi MZ 
673*7e9f1e67SKatayama Hirofumi MZ     switch (wParam)
674*7e9f1e67SKatayama Hirofumi MZ     {
675*7e9f1e67SKatayama Hirofumi MZ         case VK_UP:
676*7e9f1e67SKatayama Hirofumi MZ             if (bCtrlDown)
677*7e9f1e67SKatayama Hirofumi MZ                 SetCaretXY(infoPtr, infoPtr->CaretX, 0, FALSE, FALSE);
678*7e9f1e67SKatayama Hirofumi MZ             else
679*7e9f1e67SKatayama Hirofumi MZ                 MoveUpDown(infoPtr, -1);
680*7e9f1e67SKatayama Hirofumi MZ             break;
681*7e9f1e67SKatayama Hirofumi MZ 
682*7e9f1e67SKatayama Hirofumi MZ         case VK_DOWN:
683*7e9f1e67SKatayama Hirofumi MZ             if (bCtrlDown)
684*7e9f1e67SKatayama Hirofumi MZ                 SetCaretXY(infoPtr, infoPtr->CaretX, YCELLS - 1, FALSE, FALSE);
685*7e9f1e67SKatayama Hirofumi MZ             else
686*7e9f1e67SKatayama Hirofumi MZ                 MoveUpDown(infoPtr, +1);
687*7e9f1e67SKatayama Hirofumi MZ             break;
688*7e9f1e67SKatayama Hirofumi MZ 
689*7e9f1e67SKatayama Hirofumi MZ         case VK_LEFT:
690*7e9f1e67SKatayama Hirofumi MZ             if (bCtrlDown)
691*7e9f1e67SKatayama Hirofumi MZ                 SetCaretXY(infoPtr, 0, infoPtr->CaretY, FALSE, FALSE);
692*7e9f1e67SKatayama Hirofumi MZ             else
693*7e9f1e67SKatayama Hirofumi MZ                 MoveLeftRight(infoPtr, -1);
694*7e9f1e67SKatayama Hirofumi MZ             break;
695*7e9f1e67SKatayama Hirofumi MZ 
696*7e9f1e67SKatayama Hirofumi MZ         case VK_RIGHT:
697*7e9f1e67SKatayama Hirofumi MZ             if (bCtrlDown)
698*7e9f1e67SKatayama Hirofumi MZ                 SetCaretXY(infoPtr, XCELLS - 1, infoPtr->CaretY, FALSE, FALSE);
699*7e9f1e67SKatayama Hirofumi MZ             else
700*7e9f1e67SKatayama Hirofumi MZ                 MoveLeftRight(infoPtr, +1);
701*7e9f1e67SKatayama Hirofumi MZ             break;
702*7e9f1e67SKatayama Hirofumi MZ 
703*7e9f1e67SKatayama Hirofumi MZ         case VK_PRIOR: /* Page Up */
704*7e9f1e67SKatayama Hirofumi MZ             SendMessageW(infoPtr->hMapWnd, WM_VSCROLL, MAKEWPARAM(SB_PAGEUP, 0), 0);
705*7e9f1e67SKatayama Hirofumi MZ             break;
706*7e9f1e67SKatayama Hirofumi MZ 
707*7e9f1e67SKatayama Hirofumi MZ         case VK_NEXT: /* Page Down */
708*7e9f1e67SKatayama Hirofumi MZ             SendMessageW(infoPtr->hMapWnd, WM_VSCROLL, MAKEWPARAM(SB_PAGEDOWN, 0), 0);
709*7e9f1e67SKatayama Hirofumi MZ             break;
710*7e9f1e67SKatayama Hirofumi MZ 
711*7e9f1e67SKatayama Hirofumi MZ         case VK_HOME:
712*7e9f1e67SKatayama Hirofumi MZ             if (bCtrlDown)
713*7e9f1e67SKatayama Hirofumi MZ                 SendMessageW(infoPtr->hMapWnd, WM_VSCROLL, MAKEWPARAM(SB_TOP, 0), 0);
714*7e9f1e67SKatayama Hirofumi MZ             else
715*7e9f1e67SKatayama Hirofumi MZ                 SetCaretXY(infoPtr, 0, infoPtr->CaretY, FALSE, FALSE);
716*7e9f1e67SKatayama Hirofumi MZ             break;
717*7e9f1e67SKatayama Hirofumi MZ 
718*7e9f1e67SKatayama Hirofumi MZ         case VK_END:
719*7e9f1e67SKatayama Hirofumi MZ             if (bCtrlDown)
720*7e9f1e67SKatayama Hirofumi MZ                 SendMessageW(infoPtr->hMapWnd, WM_VSCROLL, MAKEWPARAM(SB_BOTTOM, 0), 0);
721*7e9f1e67SKatayama Hirofumi MZ             else
722*7e9f1e67SKatayama Hirofumi MZ                 SetCaretXY(infoPtr, XCELLS - 1, infoPtr->CaretY, FALSE, FALSE);
723*7e9f1e67SKatayama Hirofumi MZ             break;
724*7e9f1e67SKatayama Hirofumi MZ     }
725*7e9f1e67SKatayama Hirofumi MZ }
726c2c66affSColin Finck 
727c2c66affSColin Finck LRESULT
728c2c66affSColin Finck CALLBACK
MapWndProc(HWND hwnd,UINT uMsg,WPARAM wParam,LPARAM lParam)729c2c66affSColin Finck MapWndProc(HWND hwnd,
730c2c66affSColin Finck            UINT uMsg,
731c2c66affSColin Finck            WPARAM wParam,
732c2c66affSColin Finck            LPARAM lParam)
733c2c66affSColin Finck {
734*7e9f1e67SKatayama Hirofumi MZ     PMAP infoPtr = (PMAP)GetWindowLongPtrW(hwnd, 0);
735c2c66affSColin Finck     LRESULT Ret = 0;
73699dd2925SCharles Ambrye     WCHAR lfFaceName[LF_FACESIZE];
737c2c66affSColin Finck 
738c2c66affSColin Finck     switch (uMsg)
739c2c66affSColin Finck     {
740c2c66affSColin Finck         case WM_CREATE:
741c2c66affSColin Finck         {
7421963e2d1SAmine Khaldi             if (!MapOnCreate(infoPtr,
743c2c66affSColin Finck                              hwnd,
744c2c66affSColin Finck                              ((LPCREATESTRUCTW)lParam)->hwndParent))
745c2c66affSColin Finck             {
746c2c66affSColin Finck                 return (LRESULT)-1;
747c2c66affSColin Finck             }
748c2c66affSColin Finck 
749c2c66affSColin Finck             break;
750c2c66affSColin Finck         }
751c2c66affSColin Finck 
752*7e9f1e67SKatayama Hirofumi MZ         case WM_KEYDOWN:
753*7e9f1e67SKatayama Hirofumi MZ         {
754*7e9f1e67SKatayama Hirofumi MZ             OnKeyDown(infoPtr, wParam, lParam);
755*7e9f1e67SKatayama Hirofumi MZ             break;
756*7e9f1e67SKatayama Hirofumi MZ         }
757*7e9f1e67SKatayama Hirofumi MZ 
758c2c66affSColin Finck         case WM_LBUTTONDOWN:
759c2c66affSColin Finck         {
760*7e9f1e67SKatayama Hirofumi MZ             SetFocus(hwnd);
761*7e9f1e67SKatayama Hirofumi MZ             OnClick(infoPtr, LOWORD(lParam), HIWORD(lParam));
762c2c66affSColin Finck             break;
763c2c66affSColin Finck         }
764c2c66affSColin Finck 
765d90e1061SCharles Ambrye         case WM_MOUSEMOVE:
766d90e1061SCharles Ambrye         {
767d90e1061SCharles Ambrye             if (wParam & MK_LBUTTON)
768d90e1061SCharles Ambrye             {
769*7e9f1e67SKatayama Hirofumi MZ                 OnClick(infoPtr, LOWORD(lParam), HIWORD(lParam));
770d90e1061SCharles Ambrye             }
771d90e1061SCharles Ambrye             break;
772d90e1061SCharles Ambrye         }
773d90e1061SCharles Ambrye 
774c2c66affSColin Finck         case WM_LBUTTONDBLCLK:
775c2c66affSColin Finck         {
776*7e9f1e67SKatayama Hirofumi MZ             if (!infoPtr->pActiveCell || GetFocus() != hwnd)
77799dd2925SCharles Ambrye                 break;
77899dd2925SCharles Ambrye 
779c2c66affSColin Finck             NotifyParentOfSelection(infoPtr,
780c2c66affSColin Finck                                     FM_SETCHAR,
781c2c66affSColin Finck                                     infoPtr->pActiveCell->ch);
782c2c66affSColin Finck 
783*7e9f1e67SKatayama Hirofumi MZ             if (infoPtr->hLrgWnd)
784d90e1061SCharles Ambrye             {
785d90e1061SCharles Ambrye                 DestroyWindow(infoPtr->hLrgWnd);
786d90e1061SCharles Ambrye                 infoPtr->hLrgWnd = NULL;
787d90e1061SCharles Ambrye             }
788c2c66affSColin Finck             break;
789c2c66affSColin Finck         }
790c2c66affSColin Finck 
791c2c66affSColin Finck         case WM_VSCROLL:
792c2c66affSColin Finck         {
793*7e9f1e67SKatayama Hirofumi MZ             OnVScroll(infoPtr, LOWORD(wParam), HIWORD(wParam));
794c2c66affSColin Finck             break;
795c2c66affSColin Finck         }
796c2c66affSColin Finck 
79799dd2925SCharles Ambrye         case FM_SETCHARMAP:
798*7e9f1e67SKatayama Hirofumi MZ             infoPtr->CaretX = infoPtr->CaretY = infoPtr->iYStart = 0;
79999dd2925SCharles Ambrye             infoPtr->CharMap = LOWORD(wParam);
80099dd2925SCharles Ambrye             wcsncpy(lfFaceName,
80199dd2925SCharles Ambrye                     infoPtr->CurrentFont.lfFaceName,
80299dd2925SCharles Ambrye                     SIZEOF(lfFaceName));
80399dd2925SCharles Ambrye             SetFont(infoPtr, lfFaceName);
80499dd2925SCharles Ambrye             break;
80599dd2925SCharles Ambrye 
806c2c66affSColin Finck         case FM_SETFONT:
807*7e9f1e67SKatayama Hirofumi MZ             infoPtr->CaretX = infoPtr->CaretY = infoPtr->iYStart = 0;
808c2c66affSColin Finck             SetFont(infoPtr, (LPWSTR)lParam);
809c2c66affSColin Finck             break;
810c2c66affSColin Finck 
811c2c66affSColin Finck         case FM_GETCHAR:
812c2c66affSColin Finck         {
813c2c66affSColin Finck             if (!infoPtr->pActiveCell) return 0;
814c2c66affSColin Finck             return infoPtr->pActiveCell->ch;
815c2c66affSColin Finck         }
816c2c66affSColin Finck 
817c2c66affSColin Finck         case FM_GETHFONT:
818c2c66affSColin Finck             return (LRESULT)infoPtr->hFont;
819c2c66affSColin Finck 
820c2c66affSColin Finck         case WM_PAINT:
821*7e9f1e67SKatayama Hirofumi MZ             OnPaint(infoPtr, wParam);
822c2c66affSColin Finck             break;
823c2c66affSColin Finck 
824c2c66affSColin Finck         case WM_DESTROY:
825c2c66affSColin Finck             DeleteObject(infoPtr->hFont);
826*7e9f1e67SKatayama Hirofumi MZ             HeapFree(GetProcessHeap(), 0, infoPtr);
827*7e9f1e67SKatayama Hirofumi MZ             SetWindowLongPtrW(hwnd, 0, (LONG_PTR)NULL);
828c2c66affSColin Finck             break;
829*7e9f1e67SKatayama Hirofumi MZ 
830*7e9f1e67SKatayama Hirofumi MZ         case WM_GETDLGCODE:
831*7e9f1e67SKatayama Hirofumi MZ             return DLGC_WANTARROWS;
832*7e9f1e67SKatayama Hirofumi MZ 
833*7e9f1e67SKatayama Hirofumi MZ         case WM_SETFOCUS:
834*7e9f1e67SKatayama Hirofumi MZ         case WM_KILLFOCUS:
835*7e9f1e67SKatayama Hirofumi MZ             if (!infoPtr->hLrgWnd)
836*7e9f1e67SKatayama Hirofumi MZ                 InvalidateRect(hwnd, &(infoPtr->pActiveCell->CellInt), FALSE);
837*7e9f1e67SKatayama Hirofumi MZ             break;
838c2c66affSColin Finck 
839c2c66affSColin Finck         default:
840*7e9f1e67SKatayama Hirofumi MZ             Ret = DefWindowProcW(hwnd, uMsg, wParam, lParam);
841c2c66affSColin Finck             break;
842c2c66affSColin Finck     }
843c2c66affSColin Finck 
844c2c66affSColin Finck     return Ret;
845c2c66affSColin Finck }
846c2c66affSColin Finck 
847c2c66affSColin Finck 
848c2c66affSColin Finck BOOL
RegisterMapClasses(HINSTANCE hInstance)849c2c66affSColin Finck RegisterMapClasses(HINSTANCE hInstance)
850c2c66affSColin Finck {
851c2c66affSColin Finck     WNDCLASSW wc = {0};
852c2c66affSColin Finck 
853c2c66affSColin Finck     wc.style = CS_DBLCLKS;
854c2c66affSColin Finck     wc.lpfnWndProc = MapWndProc;
855c2c66affSColin Finck     wc.cbWndExtra = sizeof(PMAP);
856c2c66affSColin Finck     wc.hInstance = hInstance;
857c2c66affSColin Finck     wc.hCursor = LoadCursorW(NULL,
858c2c66affSColin Finck                             (LPWSTR)IDC_ARROW);
859c2c66affSColin Finck     wc.hbrBackground = (HBRUSH)(COLOR_WINDOW + 1);
860c2c66affSColin Finck     wc.lpszClassName = szMapWndClass;
861c2c66affSColin Finck 
862c2c66affSColin Finck     if (RegisterClassW(&wc))
863c2c66affSColin Finck     {
864c2c66affSColin Finck         wc.lpfnWndProc = LrgCellWndProc;
865c2c66affSColin Finck         wc.cbWndExtra = 0;
866c2c66affSColin Finck         wc.lpszClassName = szLrgCellWndClass;
867c2c66affSColin Finck 
868c2c66affSColin Finck         return RegisterClassW(&wc) != 0;
869c2c66affSColin Finck     }
870c2c66affSColin Finck 
871c2c66affSColin Finck     return FALSE;
872c2c66affSColin Finck }
873c2c66affSColin Finck 
874c2c66affSColin Finck VOID
UnregisterMapClasses(HINSTANCE hInstance)875c2c66affSColin Finck UnregisterMapClasses(HINSTANCE hInstance)
876c2c66affSColin Finck {
877*7e9f1e67SKatayama Hirofumi MZ     UnregisterClassW(szMapWndClass, hInstance);
878*7e9f1e67SKatayama Hirofumi MZ     UnregisterClassW(szLrgCellWndClass, hInstance);
879c2c66affSColin Finck }
880