b9e37cf5a4d05fc59c9af508af097ccd16dea753
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";
17 TagFontToCell(PCELL pCell
,
30 for (y
= 0; y
< YCELLS
; y
++)
31 for (x
= 0; x
< XCELLS
; x
++)
33 infoPtr
->Cells
[y
][x
].CellExt
.left
= x
* infoPtr
->CellSize
.cx
+ 1;
34 infoPtr
->Cells
[y
][x
].CellExt
.top
= y
* infoPtr
->CellSize
.cy
+ 1;
35 infoPtr
->Cells
[y
][x
].CellExt
.right
= (x
+ 1) * infoPtr
->CellSize
.cx
+ 2;
36 infoPtr
->Cells
[y
][x
].CellExt
.bottom
= (y
+ 1) * infoPtr
->CellSize
.cy
+ 2;
38 CopyRect(&infoPtr
->Cells
[y
][x
].CellInt
,
39 &infoPtr
->Cells
[y
][x
].CellExt
);
41 InflateRect(&infoPtr
->Cells
[y
][x
].CellInt
,
49 DrawActiveCell(PMAP infoPtr
,
53 infoPtr
->pActiveCell
->CellInt
.left
,
54 infoPtr
->pActiveCell
->CellInt
.top
,
55 infoPtr
->pActiveCell
->CellInt
.right
,
56 infoPtr
->pActiveCell
->CellInt
.bottom
);
63 DrawGrid(PMAP infoPtr
,
68 for (y
= 0; y
< YCELLS
; y
++)
69 for (x
= 0; x
< XCELLS
; x
++)
72 infoPtr
->Cells
[y
][x
].CellExt
.left
,
73 infoPtr
->Cells
[y
][x
].CellExt
.top
,
74 infoPtr
->Cells
[y
][x
].CellExt
.right
,
75 infoPtr
->Cells
[y
][x
].CellExt
.bottom
);
78 if (infoPtr
->pActiveCell
)
79 DrawActiveCell(infoPtr
,
86 FillGrid(PMAP infoPtr
,
93 hOldFont
= SelectObject(hdc
,
96 for (y
= 0; y
< YCELLS
; y
++)
97 for (x
= 0; x
< XCELLS
; x
++)
99 ch
= (WCHAR
)((XCELLS
* (y
+ infoPtr
->iYStart
)) + x
);
101 TagFontToCell(&infoPtr
->Cells
[y
][x
], ch
);
106 &infoPtr
->Cells
[y
][x
].CellInt
,
107 DT_CENTER
| DT_VCENTER
| DT_SINGLELINE
);
117 CreateLargeCell(PMAP infoPtr
)
122 &infoPtr
->pActiveCell
->CellExt
);
124 MapWindowPoints(infoPtr
->hMapWnd
,
133 infoPtr
->hLrgWnd
= CreateWindowExW(0,
136 WS_CHILDWINDOW
| WS_VISIBLE
,
139 rLarge
.right
- rLarge
.left
,
140 rLarge
.bottom
- rLarge
.top
,
145 if (!infoPtr
->hLrgWnd
)
154 MoveLargeCell(PMAP infoPtr
)
159 &infoPtr
->pActiveCell
->CellExt
);
161 MapWindowPoints(infoPtr
->hMapWnd
,
170 MoveWindow(infoPtr
->hLrgWnd
,
173 rLarge
.right
- rLarge
.left
,
174 rLarge
.bottom
- rLarge
.top
,
177 InvalidateRect(infoPtr
->hLrgWnd
,
185 SetFont(PMAP infoPtr
,
191 DeleteObject(infoPtr
->hFont
);
193 ZeroMemory(&infoPtr
->CurrentFont
,
196 hdc
= GetDC(infoPtr
->hMapWnd
);
197 infoPtr
->CurrentFont
.lfHeight
= GetDeviceCaps(hdc
,
199 ReleaseDC(infoPtr
->hMapWnd
, hdc
);
201 infoPtr
->CurrentFont
.lfCharSet
= DEFAULT_CHARSET
;
202 wcscpy(infoPtr
->CurrentFont
.lfFaceName
,
205 infoPtr
->hFont
= CreateFontIndirectW(&infoPtr
->CurrentFont
);
207 InvalidateRect(infoPtr
->hMapWnd
,
215 NotifyParentOfSelection(PMAP infoPtr
,
221 if (infoPtr
->hParent
!= NULL
)
223 DWORD dwIdc
= GetWindowLongPtr(infoPtr
->hMapWnd
, GWLP_ID
);
225 * Push directly into the event queue instead of waiting
226 * the parent to be unlocked.
227 * High word of LPARAM is still available for future needs...
229 Ret
= PostMessage(infoPtr
->hParent
,
231 MAKELPARAM((WORD
)dwIdc
, (WORD
)code
),
241 OnClick(PMAP infoPtr
,
251 for (x
= 0; x
< XCELLS
; x
++)
252 for (y
= 0; y
< YCELLS
; y
++)
254 if (PtInRect(&infoPtr
->Cells
[y
][x
].CellInt
,
257 /* if the cell is not already active */
258 if (!infoPtr
->Cells
[y
][x
].bActive
)
260 /* set previous active cell to inactive */
261 if (infoPtr
->pActiveCell
)
263 /* invalidate normal cells, required when
264 * moving a small active cell via keyboard */
265 if (!infoPtr
->pActiveCell
->bLarge
)
267 InvalidateRect(infoPtr
->hMapWnd
,
268 &infoPtr
->pActiveCell
->CellInt
,
272 infoPtr
->pActiveCell
->bActive
= FALSE
;
273 infoPtr
->pActiveCell
->bLarge
= FALSE
;
276 /* set new cell to active */
277 infoPtr
->pActiveCell
= &infoPtr
->Cells
[y
][x
];
278 infoPtr
->pActiveCell
->bActive
= TRUE
;
279 infoPtr
->pActiveCell
->bLarge
= TRUE
;
280 if (infoPtr
->hLrgWnd
)
281 MoveLargeCell(infoPtr
);
283 CreateLargeCell(infoPtr
);
287 /* flick between large and small */
288 if (infoPtr
->pActiveCell
->bLarge
)
290 DestroyWindow(infoPtr
->hLrgWnd
);
291 infoPtr
->hLrgWnd
= NULL
;
295 CreateLargeCell(infoPtr
);
298 infoPtr
->pActiveCell
->bLarge
= (infoPtr
->pActiveCell
->bLarge
) ? FALSE
: TRUE
;
309 OnCreate(PMAP infoPtr
,
316 infoPtr
= HeapAlloc(GetProcessHeap(),
322 SetWindowLongPtrW(hwnd
,
325 if (GetLastError() == 0)
330 infoPtr
->hMapWnd
= hwnd
;
331 infoPtr
->hParent
= hParent
;
333 GetClientRect(hwnd
, &rc
);
334 infoPtr
->ClientSize
.cx
= rc
.right
;
335 infoPtr
->ClientSize
.cy
= rc
.bottom
;
336 infoPtr
->CellSize
.cx
= infoPtr
->ClientSize
.cx
/ XCELLS
;
337 infoPtr
->CellSize
.cy
= infoPtr
->ClientSize
.cy
/ YCELLS
;
339 infoPtr
->pActiveCell
= NULL
;
343 SetScrollRange(hwnd
, SB_VERT
, 0, 255, FALSE
);
344 SetScrollPos(hwnd
, SB_VERT
, 0, TRUE
);
356 OnVScroll(PMAP infoPtr
,
360 INT iYDiff
, iOldYStart
= infoPtr
->iYStart
;
365 infoPtr
->iYStart
-= 1;
369 infoPtr
->iYStart
+= 1;
373 infoPtr
->iYStart
-= YCELLS
;
377 infoPtr
->iYStart
+= YCELLS
;
381 infoPtr
->iYStart
= Pos
;
388 infoPtr
->iYStart
= max(0,
389 min(infoPtr
->iYStart
, 255*16));
391 iYDiff
= iOldYStart
- infoPtr
->iYStart
;
394 SetScrollPos(infoPtr
->hMapWnd
,
399 if (abs(iYDiff
) < YCELLS
)
402 GetClientRect(infoPtr
->hMapWnd
, &rect
);
405 ScrollWindowEx(infoPtr
->hMapWnd
,
407 iYDiff
* infoPtr
->CellSize
.cy
,
416 InvalidateRect(infoPtr
->hMapWnd
,
426 OnPaint(PMAP infoPtr
,
435 if (!GetUpdateRect(infoPtr
->hMapWnd
,
445 hdc
= BeginPaint(infoPtr
->hMapWnd
,
461 EndPaint(infoPtr
->hMapWnd
,
469 MapWndProc(HWND hwnd
,
477 infoPtr
= (PMAP
)GetWindowLongPtrW(hwnd
,
484 if (!OnCreate(infoPtr
,
486 ((LPCREATESTRUCTW
)lParam
)->hwndParent
))
503 case WM_LBUTTONDBLCLK
:
505 NotifyParentOfSelection(infoPtr
,
507 infoPtr
->pActiveCell
->ch
);
523 SetFont(infoPtr
, (LPWSTR
)lParam
);
528 if (!infoPtr
->pActiveCell
) return 0;
529 return infoPtr
->pActiveCell
->ch
;
541 DeleteObject(infoPtr
->hFont
);
542 HeapFree(GetProcessHeap(),
545 SetWindowLongPtrW(hwnd
,
553 Ret
= DefWindowProcW(hwnd
,
566 RegisterMapClasses(HINSTANCE hInstance
)
570 wc
.style
= CS_DBLCLKS
;
571 wc
.lpfnWndProc
= MapWndProc
;
572 wc
.cbWndExtra
= sizeof(PMAP
);
573 wc
.hInstance
= hInstance
;
574 wc
.hCursor
= LoadCursorW(NULL
,
576 wc
.hbrBackground
= (HBRUSH
)(COLOR_WINDOW
+ 1);
577 wc
.lpszClassName
= szMapWndClass
;
579 if (RegisterClassW(&wc
))
581 wc
.lpfnWndProc
= LrgCellWndProc
;
583 wc
.lpszClassName
= szLrgCellWndClass
;
585 return RegisterClassW(&wc
) != 0;
592 UnregisterMapClasses(HINSTANCE hInstance
)
594 UnregisterClassW(szMapWndClass
,
597 UnregisterClassW(szLrgCellWndClass
,