2 * PROJECT: ReactOS Character Map
3 * LICENSE: GPL - See COPYING in the top level directory
4 * FILE: base/applications/charmap/map.c
5 * PURPOSE: class implementation for painting glyph region
6 * COPYRIGHT: Copyright 2007 Ged Murphy <gedmurphy@reactos.org>
12 static const WCHAR szMapWndClass
[] = L
"FontMapWnd";
13 static const WCHAR szLrgCellWndClass
[] = L
"LrgCellWnd";
16 TagFontToCell(PCELL pCell
,
28 for (y
= 0; y
< YCELLS
; y
++)
29 for (x
= 0; x
< XCELLS
; x
++)
31 infoPtr
->Cells
[y
][x
].CellExt
.left
= x
* infoPtr
->CellSize
.cx
+ 1;
32 infoPtr
->Cells
[y
][x
].CellExt
.top
= y
* infoPtr
->CellSize
.cy
+ 1;
33 infoPtr
->Cells
[y
][x
].CellExt
.right
= (x
+ 1) * infoPtr
->CellSize
.cx
+ 2;
34 infoPtr
->Cells
[y
][x
].CellExt
.bottom
= (y
+ 1) * infoPtr
->CellSize
.cy
+ 2;
36 CopyRect(&infoPtr
->Cells
[y
][x
].CellInt
,
37 &infoPtr
->Cells
[y
][x
].CellExt
);
39 InflateRect(&infoPtr
->Cells
[y
][x
].CellInt
,
46 DrawActiveCell(PMAP infoPtr
,
50 infoPtr
->pActiveCell
->CellInt
.left
,
51 infoPtr
->pActiveCell
->CellInt
.top
,
52 infoPtr
->pActiveCell
->CellInt
.right
,
53 infoPtr
->pActiveCell
->CellInt
.bottom
);
59 DrawGrid(PMAP infoPtr
,
64 for (y
= 0; y
< YCELLS
; y
++)
65 for (x
= 0; x
< XCELLS
; x
++)
68 infoPtr
->Cells
[y
][x
].CellExt
.left
,
69 infoPtr
->Cells
[y
][x
].CellExt
.top
,
70 infoPtr
->Cells
[y
][x
].CellExt
.right
,
71 infoPtr
->Cells
[y
][x
].CellExt
.bottom
);
74 if (infoPtr
->pActiveCell
)
75 DrawActiveCell(infoPtr
,
81 FillGrid(PMAP infoPtr
,
88 hOldFont
= SelectObject(hdc
,
91 for (y
= 0; y
< YCELLS
; y
++)
92 for (x
= 0; x
< XCELLS
; x
++)
94 ch
= (WCHAR
)((XCELLS
* (y
+ infoPtr
->iYStart
)) + x
);
96 TagFontToCell(&infoPtr
->Cells
[y
][x
], ch
);
101 &infoPtr
->Cells
[y
][x
].CellInt
,
102 DT_CENTER
| DT_VCENTER
| DT_SINGLELINE
);
111 CreateLargeCell(PMAP infoPtr
)
116 &infoPtr
->pActiveCell
->CellExt
);
118 MapWindowPoints(infoPtr
->hMapWnd
,
127 infoPtr
->hLrgWnd
= CreateWindowExW(0,
130 WS_CHILDWINDOW
| WS_VISIBLE
,
133 rLarge
.right
- rLarge
.left
,
134 rLarge
.bottom
- rLarge
.top
,
139 if (!infoPtr
->hLrgWnd
)
147 MoveLargeCell(PMAP infoPtr
)
152 &infoPtr
->pActiveCell
->CellExt
);
154 MapWindowPoints(infoPtr
->hMapWnd
,
163 MoveWindow(infoPtr
->hLrgWnd
,
166 rLarge
.right
- rLarge
.left
,
167 rLarge
.bottom
- rLarge
.top
,
170 InvalidateRect(infoPtr
->hLrgWnd
,
177 SetFont(PMAP infoPtr
,
183 DeleteObject(infoPtr
->hFont
);
185 ZeroMemory(&infoPtr
->CurrentFont
,
188 hdc
= GetDC(infoPtr
->hMapWnd
);
189 infoPtr
->CurrentFont
.lfHeight
= GetDeviceCaps(hdc
,
191 ReleaseDC(infoPtr
->hMapWnd
, hdc
);
193 infoPtr
->CurrentFont
.lfCharSet
= DEFAULT_CHARSET
;
194 wcscpy(infoPtr
->CurrentFont
.lfFaceName
,
197 infoPtr
->hFont
= CreateFontIndirectW(&infoPtr
->CurrentFont
);
199 InvalidateRect(infoPtr
->hMapWnd
,
206 NotifyParentOfSelection(PMAP infoPtr
,
212 if (infoPtr
->hParent
!= NULL
)
214 DWORD dwIdc
= GetWindowLongPtr(infoPtr
->hMapWnd
, GWLP_ID
);
216 * Push directly into the event queue instead of waiting
217 * the parent to be unlocked.
218 * High word of LPARAM is still available for future needs...
220 Ret
= PostMessage(infoPtr
->hParent
,
222 MAKELPARAM((WORD
)dwIdc
, (WORD
)code
),
231 OnClick(PMAP infoPtr
,
241 for (x
= 0; x
< XCELLS
; x
++)
242 for (y
= 0; y
< YCELLS
; y
++)
244 if (PtInRect(&infoPtr
->Cells
[y
][x
].CellInt
,
247 /* if the cell is not already active */
248 if (!infoPtr
->Cells
[y
][x
].bActive
)
250 /* set previous active cell to inactive */
251 if (infoPtr
->pActiveCell
)
253 /* invalidate normal cells, required when
254 * moving a small active cell via keyboard */
255 if (!infoPtr
->pActiveCell
->bLarge
)
257 InvalidateRect(infoPtr
->hMapWnd
,
258 &infoPtr
->pActiveCell
->CellInt
,
262 infoPtr
->pActiveCell
->bActive
= FALSE
;
263 infoPtr
->pActiveCell
->bLarge
= FALSE
;
266 /* set new cell to active */
267 infoPtr
->pActiveCell
= &infoPtr
->Cells
[y
][x
];
268 infoPtr
->pActiveCell
->bActive
= TRUE
;
269 infoPtr
->pActiveCell
->bLarge
= TRUE
;
270 if (infoPtr
->hLrgWnd
)
271 MoveLargeCell(infoPtr
);
273 CreateLargeCell(infoPtr
);
277 /* flick between large and small */
278 if (infoPtr
->pActiveCell
->bLarge
)
280 DestroyWindow(infoPtr
->hLrgWnd
);
281 infoPtr
->hLrgWnd
= NULL
;
285 CreateLargeCell(infoPtr
);
288 infoPtr
->pActiveCell
->bLarge
= (infoPtr
->pActiveCell
->bLarge
) ? FALSE
: TRUE
;
298 OnCreate(PMAP infoPtr
,
305 infoPtr
= HeapAlloc(GetProcessHeap(),
311 SetWindowLongPtrW(hwnd
,
314 if (GetLastError() == 0)
319 infoPtr
->hMapWnd
= hwnd
;
320 infoPtr
->hParent
= hParent
;
322 GetClientRect(hwnd
, &rc
);
323 infoPtr
->ClientSize
.cx
= rc
.right
;
324 infoPtr
->ClientSize
.cy
= rc
.bottom
;
325 infoPtr
->CellSize
.cx
= infoPtr
->ClientSize
.cx
/ XCELLS
;
326 infoPtr
->CellSize
.cy
= infoPtr
->ClientSize
.cy
/ YCELLS
;
328 infoPtr
->pActiveCell
= NULL
;
332 SetScrollRange(hwnd
, SB_VERT
, 0, 255, FALSE
);
333 SetScrollPos(hwnd
, SB_VERT
, 0, TRUE
);
344 OnVScroll(PMAP infoPtr
,
348 INT iYDiff
, iOldYStart
= infoPtr
->iYStart
;
353 infoPtr
->iYStart
-= 1;
357 infoPtr
->iYStart
+= 1;
361 infoPtr
->iYStart
-= YCELLS
;
365 infoPtr
->iYStart
+= YCELLS
;
369 infoPtr
->iYStart
= Pos
;
376 infoPtr
->iYStart
= max(0,
377 min(infoPtr
->iYStart
, 255*16));
379 iYDiff
= iOldYStart
- infoPtr
->iYStart
;
382 SetScrollPos(infoPtr
->hMapWnd
,
387 if (abs(iYDiff
) < YCELLS
)
390 GetClientRect(infoPtr
->hMapWnd
, &rect
);
393 ScrollWindowEx(infoPtr
->hMapWnd
,
395 iYDiff
* infoPtr
->CellSize
.cy
,
404 InvalidateRect(infoPtr
->hMapWnd
,
413 OnPaint(PMAP infoPtr
,
422 if (!GetUpdateRect(infoPtr
->hMapWnd
,
432 hdc
= BeginPaint(infoPtr
->hMapWnd
,
448 EndPaint(infoPtr
->hMapWnd
,
455 MapWndProc(HWND hwnd
,
463 infoPtr
= (PMAP
)GetWindowLongPtrW(hwnd
,
470 if (!OnCreate(infoPtr
,
472 ((LPCREATESTRUCTW
)lParam
)->hwndParent
))
489 case WM_LBUTTONDBLCLK
:
491 NotifyParentOfSelection(infoPtr
,
493 infoPtr
->pActiveCell
->ch
);
509 SetFont(infoPtr
, (LPWSTR
)lParam
);
514 if (!infoPtr
->pActiveCell
) return 0;
515 return infoPtr
->pActiveCell
->ch
;
527 DeleteObject(infoPtr
->hFont
);
528 HeapFree(GetProcessHeap(),
531 SetWindowLongPtrW(hwnd
,
539 Ret
= DefWindowProcW(hwnd
,
552 RegisterMapClasses(HINSTANCE hInstance
)
556 wc
.style
= CS_DBLCLKS
;
557 wc
.lpfnWndProc
= MapWndProc
;
558 wc
.cbWndExtra
= sizeof(PMAP
);
559 wc
.hInstance
= hInstance
;
560 wc
.hCursor
= LoadCursorW(NULL
,
562 wc
.hbrBackground
= (HBRUSH
)(COLOR_WINDOW
+ 1);
563 wc
.lpszClassName
= szMapWndClass
;
565 if (RegisterClassW(&wc
))
567 wc
.lpfnWndProc
= LrgCellWndProc
;
569 wc
.lpszClassName
= szLrgCellWndClass
;
571 return RegisterClassW(&wc
) != 0;
578 UnregisterMapClasses(HINSTANCE hInstance
)
580 UnregisterClassW(szMapWndClass
,
583 UnregisterClassW(szLrgCellWndClass
,