ReactOS  0.4.12-dev-36-g472787f
GridView.cpp
Go to the documentation of this file.
1 /*
2 * PROJECT: ReactOS Character Map
3 * LICENSE: GPL - See COPYING in the top level directory
4 * FILE: base/applications/charmap/GridView.cpp
5 * PURPOSE: Class for for the window which contains the font matrix
6 * COPYRIGHT: Copyright 2015 Ged Murphy <gedmurphy@reactos.org>
7 */
8 
9 
10 #include "precomp.h"
11 #include "GridView.h"
12 #include "Cell.h"
13 
14 
15 /* DATA *****************************************************/
16 
17 extern HINSTANCE g_hInstance;
18 
19 
20 /* PUBLIC METHODS **********************************************/
21 
23  m_xNumCells(20),
24  m_yNumCells(10),
25  m_ScrollPosition(0),
26  m_NumRows(0)
27 {
28  m_szMapWndClass = L"CharGridWClass";
29 }
30 
32 {
33 }
34 
35 bool
38  )
39 {
40  WNDCLASSW wc = { 0 };
41  wc.style = CS_DBLCLKS;
43  wc.cbWndExtra = sizeof(CGridView *);
46  wc.hbrBackground = (HBRUSH)(COLOR_WINDOW + 1);
48 
49  if (RegisterClassW(&wc))
50  {
53  NULL,
55  0,0,0,0,
56  hParent,
57  NULL,
58  g_hInstance,
59  this);
60 
61  }
62 
63  return !!(m_hwnd != NULL);
64 }
65 
66 bool
68  _In_ CAtlString& FontName
69  )
70 {
71 
72  // Create a temporary container for the new font
73  CurrentFont NewFont = { 0 };
74  NewFont.FontName = FontName;
75 
76  // Get the DC for the full grid window
77  HDC hdc;
78  hdc = GetDC(m_hwnd);
79  if (hdc == NULL) return false;
80 
81  // Setup the logfont structure
82  NewFont.Font.lfHeight = 0; // This is set in WM_SIZE
83  NewFont.Font.lfCharSet = DEFAULT_CHARSET;
84  StringCchCopyW(NewFont.Font.lfFaceName, LF_FACESIZE, FontName);
85 
86  // Get a handle to the new font
87  NewFont.hFont = CreateFontIndirectW(&NewFont.Font);
88  if (NewFont.hFont == NULL)
89  {
90  ReleaseDC(m_hwnd, hdc);
91  return false;
92  }
93 
94  // Setup an array of all possible non-BMP indices
95  WCHAR ch[MAX_GLYPHS];
96  for (int i = 0; i < MAX_GLYPHS; i++)
97  ch[i] = (WCHAR)i;
98 
99  HFONT hOldFont;
100  hOldFont = (HFONT)SelectObject(hdc, NewFont.hFont);
101 
102  // Translate all the indices into glyphs
104  DWORD Status;
105  Status = GetGlyphIndicesW(hdc,
106  ch,
107  MAX_GLYPHS,
108  out,
110  ReleaseDC(m_hwnd, hdc);
111  if (Status == GDI_ERROR)
112  {
113  SelectObject(hdc, hOldFont);
114  return false;
115  }
116 
117  // Loop all the glyphs looking for valid ones
118  // and store those in our font data
119  int j = 0;
120  for (int i = 0; i < MAX_GLYPHS; i++)
121  {
122  if (out[i] != 0xffff)
123  {
124  NewFont.ValidGlyphs[j] = ch[i];
125  j++;
126  }
127  }
128  NewFont.NumValidGlyphs = j;
129 
130  // Calculate the number of rows required to hold all glyphs
132  if (NewFont.NumValidGlyphs % m_xNumCells)
133  m_NumRows += 1;
134 
135  // Set the scrollbar in relation to the rows
137 
138  // We're done, update the current font
139  m_CurrentFont = NewFont;
140 
141  // We changed the font, we'll need to repaint the whole window
143  NULL,
144  TRUE);
145 
146  return true;
147 }
148 
149 
150 
151 /* PRIVATE METHODS **********************************************/
152 
153 bool
155  )
156 {
157  // Go through all the cells and calculate
158  // their coordinates within the grid
159  for (int y = 0; y < m_yNumCells; y++)
160  for (int x = 0; x < m_xNumCells; x++)
161  {
162  RECT CellCoordinates;
163  CellCoordinates.left = x * m_CellSize.cx;
164  CellCoordinates.top = y * m_CellSize.cy;
165  CellCoordinates.right = (x + 1) * m_CellSize.cx + 1;
166  CellCoordinates.bottom = (y + 1) * m_CellSize.cy + 1;
167 
168  m_Cells[y][x]->SetCellCoordinates(CellCoordinates);
169  }
170 
171  return true;
172 }
173 
174 LRESULT
176  _In_ HWND hwnd,
178  )
179 {
180  m_hwnd = hwnd;
181  m_hParent = hParent;
182 
183  // C++ doesn't allow : "CCells ***C = new CCell***[x * y]"
184  // so we have to build the 2d array up manually
185  m_Cells = new CCell**[m_yNumCells]; // rows
186  for (int i = 0; i < m_yNumCells; i++)
187  m_Cells[i] = new CCell*[m_xNumCells]; // columns
188 
189  for (int y = 0; y < m_yNumCells; y++)
190  for (int x = 0; x < m_xNumCells; x++)
191  {
192  m_Cells[y][x] = new CCell(m_hwnd);
193  }
194 
195  // Give the first cell focus
196  SetCellFocus(m_Cells[0][0]);
197 
198  return 0;
199 }
200 
201 LRESULT
203  _In_ INT Width,
204  _In_ INT Height
205  )
206 {
207  // Get the client area of the main dialog
208  RECT ParentRect;
209  GetClientRect(m_hParent, &ParentRect);
210 
211  // Calculate the grid size using the parent
212  m_ClientCoordinates.left = ParentRect.left + 25;
213  m_ClientCoordinates.top = ParentRect.top + 50;
216 
217  // Resize the grid window
219  NULL,
225 
226  // Get the client area we can draw on. The position we set above includes
227  // a scrollbar which we obviously can't draw on. GetClientRect gives us
228  // the size without the scroll, and it's more efficient than getting the
229  // scroll metrics and calculating the size from that
230  RECT ClientRect;
231  GetClientRect(m_hwnd, &ClientRect);
232  m_CellSize.cx = ClientRect.right / m_xNumCells;
233  m_CellSize.cy = ClientRect.bottom / m_yNumCells;
234 
235  // Let all the cells know about their new coords
237 
238  // We scale the font size up or down depending on the cell size
239  if (m_CurrentFont.hFont)
240  {
241  // Delete the existing font
243 
244  HDC hdc;
245  hdc = GetDC(m_hwnd);
246  if (hdc)
247  {
248  // Update the font size with respect to the cell size
251  ReleaseDC(m_hwnd, hdc);
252  }
253  }
254 
255  // Redraw the whole grid
256  InvalidateRect(m_hwnd, &ClientRect, TRUE);
257 
258  return 0;
259 }
260 
261 VOID
263  _In_ INT Pos)
264 {
265 
266  INT PrevScrollPosition = m_ScrollPosition;
267 
268  switch (Value)
269  {
270  case SB_LINEUP:
271  m_ScrollPosition -= 1;
272  break;
273 
274  case SB_LINEDOWN:
275  m_ScrollPosition += 1;
276  break;
277 
278  case SB_PAGEUP:
280  break;
281 
282  case SB_PAGEDOWN:
284  break;
285 
286  case SB_THUMBTRACK:
288  break;
289 
290  default:
291  break;
292  }
293 
294  // Make sure we don't scroll past row 0 or max rows
297 
298  // Check if there's a difference from the previous position
299  INT ScrollDiff;
300  ScrollDiff = PrevScrollPosition - m_ScrollPosition;
301  if (ScrollDiff)
302  {
303  // Set the new scrollbar position in the scroll box
305  SB_VERT,
306  m_ScrollPosition,
307  TRUE);
308 
309  // Check if the scrollbar has moved more than the
310  // number of visible rows (draged or paged)
311  if (abs(ScrollDiff) < m_yNumCells)
312  {
313  RECT rect;
314  GetClientRect(m_hwnd, &rect);
315 
316  // Scroll the visible cells which remain within the grid
317  // and invalidate any new ones which appear from the top / bottom
319  0,
320  ScrollDiff * m_CellSize.cy,
321  &rect,
322  &rect,
323  NULL,
324  NULL,
325  SW_INVALIDATE);
326  }
327  else
328  {
329  // All the cells need to be redrawn
331  NULL,
332  TRUE);
333  }
334  }
335 }
336 
337 LRESULT
340  )
341 {
342  PAINTSTRUCT PaintStruct = { 0 };
343  HDC LocalHdc = NULL;
344  BOOL bSuccess = FALSE;
345 
346  // Check if we were passed a DC
347  if (hdc == NULL)
348  {
349  // We weren't, let's get one
350  LocalHdc = BeginPaint(m_hwnd, &PaintStruct);
351  if (LocalHdc) bSuccess = TRUE;
352  }
353  else
354  {
355  // Use the existing DC and just get the region to paint
356  bSuccess = GetUpdateRect(m_hwnd,
357  &PaintStruct.rcPaint,
358  TRUE);
359  if (bSuccess)
360  {
361  // Update the struct with the DC we were passed
362  PaintStruct.hdc = (HDC)hdc;
363  }
364  }
365 
366  // Make sure we have a valid DC
367  if (bSuccess)
368  {
369  // Paint the grid and chars
370  DrawGrid(&PaintStruct);
371 
372  if (LocalHdc)
373  {
374  EndPaint(m_hwnd, &PaintStruct);
375  }
376  }
377 
378  return 0;
379 }
380 
381 LRESULT
382 CALLBACK
384  HWND hwnd,
385  UINT uMsg,
386  WPARAM wParam,
387  LPARAM lParam
388  )
389 {
390  CGridView *This;
391  LRESULT RetCode = 0;
392 
393  // Get the object pointer from window context
394  This = (CGridView *)GetWindowLongPtr(hwnd, GWLP_USERDATA);
395  if (This == NULL)
396  {
397  // Check that this isn't a create message
398  if (uMsg != WM_CREATE)
399  {
400  // Don't handle null info pointer
401  goto HandleDefaultMessage;
402  }
403  }
404 
405  switch (uMsg)
406  {
407  case WM_CREATE:
408  {
409  // Get the object pointer from the create param
410  This = (CGridView *)((LPCREATESTRUCT)lParam)->lpCreateParams;
411 
412  // Store the pointer in the window's global user data
414 
415  This->OnCreate(hwnd, ((LPCREATESTRUCTW)lParam)->hwndParent);
416  break;
417  }
418 
419  case WM_SIZE:
420  {
421  INT Width, Height;
422  Width = LOWORD(lParam);
423  Height = HIWORD(lParam);
424 
425  This->OnSize(Width, Height);
426  break;
427  }
428 
429  case WM_VSCROLL:
430  {
431  INT Value, Pos;
432  Value = LOWORD(wParam);
433  Pos = HIWORD(wParam);
434 
435  This->OnVScroll(Value, Pos);
436  break;
437  }
438 
439  case WM_PAINT:
440  {
441  This->OnPaint((HDC)wParam);
442  break;
443  }
444 
445  case WM_DESTROY:
446  {
447  This->DeleteCells();
448  break;
449  }
450 
451  default:
452  {
453 HandleDefaultMessage:
454  RetCode = DefWindowProcW(hwnd, uMsg, wParam, lParam);
455  break;
456  }
457  }
458 
459  return RetCode;
460 }
461 
462 
463 void
465  _In_ LPPAINTSTRUCT PaintStruct
466  )
467 {
468  // Calculate which glyph to start at based on scroll position
469  int i;
471 
472  // Make sure we have the correct font on the DC
473  HFONT hOldFont;
474  hOldFont = (HFONT)SelectFont(PaintStruct->hdc,
476 
477  // Traverse all the cells
478  for (int y = 0; y < m_yNumCells; y++)
479  for (int x = 0; x < m_xNumCells; x++)
480  {
481  // Update the glyph for this cell
483  m_Cells[y][x]->SetChar(ch);
484 
485  // Tell it to paint itself
486  m_Cells[y][x]->OnPaint(*PaintStruct);
487  i++;
488  }
489 
490  SelectObject(PaintStruct->hdc, hOldFont);
491 
492 }
493 
494 void
496 {
497  if (m_Cells == nullptr)
498  return;
499 
500  // Free cells withing the 2d array
501  for (int i = 0; i < m_yNumCells; i++)
502  delete[] m_Cells[i];
503  delete[] m_Cells;
504 
505  m_Cells = nullptr;
506 }
507 
508 void
510  _In_ CCell* NewActiveCell
511  )
512 {
513  if (m_ActiveCell)
514  {
515  // Remove focus from any existing cell
516  m_ActiveCell->SetFocus(false);
518  }
519 
520  // Set the new active cell and give it focus
521  m_ActiveCell = NewActiveCell;
522  m_ActiveCell->SetFocus(true);
523 }
_In_opt_ ULONG _Out_ PULONG Value
Definition: rtlfuncs.h:2327
#define HDC
Definition: msvc.h:22
#define abs(i)
Definition: fconv.c:206
const DOCKBAR PVOID HWND HWND * hwnd
Definition: tooldock.h:22
#define SB_PAGEDOWN
Definition: winuser.h:569
CurrentFont m_CurrentFont
Definition: GridView.h:35
#define SB_PAGEUP
Definition: winuser.h:568
#define max(a, b)
Definition: svc.c:63
GLenum GLclampf GLint GLenum GLuint GLenum GLenum GLsizei GLenum const GLvoid GLfloat GLfloat GLfloat GLfloat GLclampd GLint GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLint GLint GLint GLshort GLshort GLshort GLubyte GLubyte GLubyte GLuint GLuint GLuint GLushort GLushort GLushort GLbyte GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLfloat GLint GLint GLint GLint GLshort GLshort GLshort GLshort GLubyte GLubyte GLubyte GLubyte GLuint GLuint GLuint GLuint GLushort GLushort GLushort GLushort GLboolean GLboolean GLboolean GLboolean GLint GLenum GLsizei const GLvoid GLenum GLint GLenum GLint GLint GLsizei GLint GLenum GLint GLint GLint GLint GLsizei GLenum GLsizei const GLuint GLboolean GLenum GLenum GLint GLsizei GLenum GLsizei GLenum const GLvoid GLboolean const GLboolean GLenum const GLdouble const GLfloat const GLdouble const GLfloat GLenum GLint GLint GLint GLint GLint GLint j
Definition: glfuncs.h:98
#define TRUE
Definition: types.h:120
#define LF_FACESIZE
Definition: dimm.idl:39
HWND m_hwnd
Definition: GridView.h:21
UINT style
Definition: winuser.h:3129
bool Create(_In_ HWND hParent)
Definition: GridView.cpp:36
void DeleteCells()
Definition: GridView.cpp:495
HWND m_hParent
Definition: GridView.h:22
HDC WINAPI GetDC(_In_opt_ HWND)
#define SB_VERT
Definition: winuser.h:553
__wchar_t WCHAR
Definition: xmlstorage.h:180
bool UpdateCellCoordinates()
Definition: GridView.cpp:154
LPRECT GetCellCoordinates()
Definition: Cell.h:24
LONG lfHeight
Definition: dimm.idl:59
void SetChar(_In_ WCHAR ch)
Definition: Cell.h:27
BYTE lfCharSet
Definition: dimm.idl:67
#define CALLBACK
Definition: compat.h:27
ush Pos
Definition: deflate.h:92
int m_NumRows
Definition: GridView.h:33
LONG top
Definition: windef.h:297
bool SetFont(_In_ CAtlString &FontName)
Definition: GridView.cpp:67
HGDIOBJ WINAPI SelectObject(_In_ HDC, _In_ HGDIOBJ)
Definition: dc.c:1497
BOOL WINAPI DeleteObject(_In_ HGDIOBJ)
INT m_ScrollPosition
Definition: GridView.h:32
#define WS_CHILD
Definition: pedump.c:617
LONG left
Definition: windef.h:296
#define SWP_NOZORDER
Definition: winuser.h:1232
BOOL WINAPI EndPaint(_In_ HWND, _In_ const PAINTSTRUCT *)
#define WCHAR
Definition: msvc.h:43
#define DEFAULT_CHARSET
Definition: wingdi.h:382
LONG right
Definition: windef.h:298
#define COLOR_WINDOW
Definition: winuser.h:908
int32_t INT
Definition: typedefs.h:56
static BOOLEAN bSuccess
Definition: drive.cpp:419
#define SetWindowLongPtr
Definition: treelist.c:70
& rect
Definition: startmenu.cpp:1413
WPARAM wParam
Definition: combotst.c:138
#define _In_opt_
Definition: no_sal2.h:213
LRESULT WINAPI DefWindowProcW(_In_ HWND, _In_ UINT, _In_ WPARAM, _In_ LPARAM)
UINT_PTR WPARAM
Definition: windef.h:207
void SetCellCoordinates(_In_ RECT &Coordinates)
Definition: Cell.cpp:89
INT INT y
Definition: msvc.h:62
ATOM WINAPI RegisterClassW(_In_ CONST WNDCLASSW *)
GLenum GLclampf GLint i
Definition: glfuncs.h:14
LONG_PTR LPARAM
Definition: windef.h:208
CCell *** m_Cells
Definition: GridView.h:29
HDC WINAPI BeginPaint(_In_ HWND, _Out_ LPPAINTSTRUCT)
STRSAFEAPI StringCchCopyW(STRSAFE_LPWSTR pszDest, size_t cchDest, STRSAFE_LPCWSTR pszSrc)
Definition: strsafe.h:149
WNDPROC lpfnWndProc
Definition: winuser.h:3130
int WINAPI ReleaseDC(_In_opt_ HWND, _In_ HDC)
RECT m_ClientCoordinates
Definition: GridView.h:27
#define GWLP_USERDATA
Definition: treelist.c:63
HDC hdc
Definition: msvc.h:53
smooth NULL
Definition: ftsmooth.c:416
HFONT WINAPI CreateFontIndirectW(_In_ const LOGFONTW *)
static HWND hwndParent
Definition: cryptui.c:300
LONG cx
Definition: windef.h:324
LPCWSTR lpszClassName
Definition: winuser.h:3138
int WINAPI ScrollWindowEx(_In_ HWND, _In_ int, _In_ int, _In_opt_ LPCRECT, _In_opt_ LPCRECT, _In_opt_ HRGN, _Out_opt_ LPRECT, _In_ UINT)
#define WM_DESTROY
Definition: winuser.h:1591
#define MAX_GLYPHS
Definition: precomp.h:15
void SetCellFocus(_In_ CCell *NewActiveCell)
Definition: GridView.cpp:509
LOGFONTW Font
Definition: GridView.h:9
unsigned int BOOL
Definition: ntddk_ex.h:94
int cbWndExtra
Definition: winuser.h:3132
USHORT ValidGlyphs[MAX_GLYPHS]
Definition: GridView.h:11
#define SB_THUMBTRACK
Definition: winuser.h:573
#define WM_SIZE
Definition: winuser.h:1593
LRESULT OnSize(_In_ INT Width, _In_ INT Height)
Definition: GridView.cpp:202
Definition: Cell.h:2
LRESULT OnPaint(_In_opt_ HDC hdc)
Definition: GridView.cpp:338
unsigned int UINT
Definition: ndis.h:50
BOOL WINAPI InvalidateRect(_In_opt_ HWND, _In_opt_ LPCRECT, _In_ BOOL)
unsigned short WORD
Definition: ntddk_ex.h:93
static FILE * out
Definition: regtests2xml.c:44
unsigned long DWORD
Definition: ntddk_ex.h:95
HCURSOR WINAPI LoadCursorW(_In_opt_ HINSTANCE, _In_ LPCWSTR)
Definition: cursoricon.c:2074
#define GGI_MARK_NONEXISTING_GLYPHS
Definition: wingdi.h:1066
#define WM_PAINT
Definition: winuser.h:1602
SIZE m_CellSize
Definition: GridView.h:28
static const WCHAR L[]
Definition: oid.c:1087
HWND WINAPI CreateWindowExW(_In_ DWORD dwExStyle, _In_opt_ LPCWSTR lpClassName, _In_opt_ LPCWSTR lpWindowName, _In_ DWORD dwStyle, _In_ int X, _In_ int Y, _In_ int nWidth, _In_ int nHeight, _In_opt_ HWND hWndParent, _In_opt_ HMENU hMenu, _In_opt_ HINSTANCE hInstance, _In_opt_ LPVOID lpParam)
BOOL WINAPI GetUpdateRect(_In_ HWND, _Out_opt_ LPRECT, _In_ BOOL)
const DOCKBAR PVOID HWND hParent
Definition: tooldock.h:22
CAtlStringW FontName
Definition: GridView.h:8
#define CS_DBLCLKS
Definition: winuser.h:646
#define WS_TABSTOP
Definition: pedump.c:634
#define SW_INVALIDATE
Definition: winuser.h:2533
#define SelectFont(hdc, hfont)
Definition: windowsx.h:486
Status
Definition: gdiplustypes.h:24
~CGridView()
Definition: GridView.cpp:31
HCURSOR hCursor
Definition: winuser.h:3135
#define _In_
Definition: no_sal2.h:204
BOOL WINAPI GetClientRect(_In_ HWND, _Out_ LPRECT)
int m_xNumCells
Definition: GridView.h:24
USHORT NumValidGlyphs
Definition: GridView.h:12
bool OnPaint(_In_ PAINTSTRUCT &PaintStruct)
Definition: Cell.cpp:43
LRESULT OnCreate(_In_ HWND hwnd, _In_ HWND hParent)
Definition: GridView.cpp:175
INT x
Definition: msvc.h:62
HBRUSH hbrBackground
Definition: winuser.h:3136
__int3264 LONG_PTR
Definition: mstsclib_h.h:276
HFONT hFont
Definition: GridView.h:10
CCell * m_ActiveCell
Definition: GridView.h:30
#define min(a, b)
Definition: monoChain.cc:55
#define SB_LINEDOWN
Definition: winuser.h:565
#define SB_LINEUP
Definition: winuser.h:564
#define WS_VSCROLL
Definition: pedump.c:627
#define SWP_SHOWWINDOW
Definition: winuser.h:1233
BOOL WINAPI SetScrollRange(_In_ HWND, _In_ int, _In_ int, _In_ int, _In_ BOOL)
VOID OnVScroll(_In_ INT Value, _In_ INT Pos)
Definition: GridView.cpp:262
static DWORD *static HFONT(WINAPI *pCreateFontIndirectExA)(const ENUMLOGFONTEXDVA *)
HINSTANCE hInstance
Definition: winuser.h:3133
#define IDC_ARROW
Definition: winuser.h:682
#define WM_CREATE
Definition: winuser.h:1590
CAtlStringW m_szMapWndClass
Definition: GridView.h:19
int m_yNumCells
Definition: GridView.h:25
DWORD WINAPI GetGlyphIndicesW(_In_ HDC hdc, _In_reads_(c) LPCWSTR lpstr, _In_ int c, _Out_writes_(c) LPWORD pgi, _In_ DWORD fl)
WCHAR lfFaceName[LF_FACESIZE]
Definition: dimm.idl:72
#define HIWORD(l)
Definition: typedefs.h:246
LONG bottom
Definition: windef.h:299
BOOL WINAPI SetWindowPos(_In_ HWND, _In_opt_ HWND, _In_ int, _In_ int, _In_ int, _In_ int, _In_ UINT)
#define GetWindowLongPtr
Definition: treelist.c:73
HINSTANCE g_hInstance
Definition: MainWindow.cpp:18
WCHAR * LPWSTR
Definition: xmlstorage.h:184
static LRESULT CALLBACK MapWndProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
Definition: GridView.cpp:383
LONG_PTR LRESULT
Definition: windef.h:209
#define GDI_ERROR
Definition: wingdi.h:1290
#define WS_VISIBLE
Definition: pedump.c:620
void SetFocus(_In_ bool HasFocus)
Definition: Cell.h:25
LONG cy
Definition: windef.h:325
int WINAPI SetScrollPos(_In_ HWND, _In_ int, _In_ int, _In_ BOOL)
LPARAM lParam
Definition: combotst.c:139
#define LOWORD(l)
Definition: pedump.c:82
#define WM_VSCROLL
Definition: winuser.h:1720
void DrawGrid(_In_ LPPAINTSTRUCT PaintStruct)
Definition: GridView.cpp:464