) :
m_hParent(hParent),
m_CellCoordinates(CellCoordinates),
- ch(L'*'),
+ m_Char(L'*'),
m_bHasFocus(false),
m_bIsLarge(false)
{
if (NeedsPaint == FALSE)
return false;
+
+
// Draw the cell border
BOOL b = Rectangle(PaintStruct.hdc,
- m_CellCoordinates.left,
- m_CellCoordinates.top,
- m_CellCoordinates.right,
- m_CellCoordinates.bottom);
+ m_CellCoordinates.left,
+ m_CellCoordinates.top,
+ m_CellCoordinates.right,
+ m_CellCoordinates.bottom);
+
+ // Calculate an internal drawing canvas for the cell
+ RECT Internal;
+ CopyRect(&Internal, &m_CellCoordinates);
+ InflateRect(&Internal, -1, -1);
// Check if this cell has focus
if (m_bHasFocus)
{
- // Take a copy of the border dims and make it slightly smaller
- RECT Internal;
- CopyRect(&Internal, &m_CellCoordinates);
- InflateRect(&Internal, -1, -1);
-
// Draw the smaller cell to make it look selected
Rectangle(PaintStruct.hdc,
Internal.left,
Internal.bottom);
}
- return true;
+ int Success;
+ Success = DrawTextW(PaintStruct.hdc,
+ &m_Char,
+ 1,
+ &Internal,
+ DT_CENTER | DT_VCENTER | DT_SINGLELINE);
+
+ return (Success != 0);
}
void
CGridView::CGridView() :
m_xNumCells(20),
- m_yNumCells(10)
+ m_yNumCells(10),
+ ScrollPosition(0)
{
m_szMapWndClass = L"CharGridWClass";
}
}
bool
-CGridView::UpdateGridLayout(
+CGridView::SetFont(
+ _In_ CAtlString& FontName
+ )
+{
+
+ // Create a temperary container for the new font
+ CurrentFont NewFont = { 0 };
+ NewFont.FontName = FontName;
+
+ // Get the DC for the full grid window
+ HDC hdc;
+ hdc = GetDC(m_hwnd);
+ if (hdc == NULL) return false;
+
+ // Setup the logfont structure
+ NewFont.Font.lfHeight = GetDeviceCaps(hdc, LOGPIXELSY) / 5;
+ NewFont.Font.lfCharSet = DEFAULT_CHARSET;
+ StringCchCopyW(NewFont.Font.lfFaceName, LF_FACESIZE, FontName);
+
+ // Get a handle to the new font
+ NewFont.hFont = CreateFontIndirectW(&NewFont.Font);
+ if (NewFont.hFont == NULL)
+ {
+ ReleaseDC(m_hwnd, hdc);
+ return false;
+ }
+
+ // Setup an array of all possible non-BMP indices
+ WCHAR ch[MAX_GLYPHS];
+ for (int i = 0; i < MAX_GLYPHS; i++)
+ ch[i] = (WCHAR)i;
+
+ HFONT hOldFont;
+ hOldFont = (HFONT)SelectObject(hdc, NewFont.hFont);
+
+ // Translate all the indices into glyphs
+ WORD out[MAX_GLYPHS];
+ DWORD Status;
+ Status = GetGlyphIndicesW(hdc,
+ ch,
+ MAX_GLYPHS,
+ out,
+ GGI_MARK_NONEXISTING_GLYPHS);
+ ReleaseDC(m_hwnd, hdc);
+ if (Status == GDI_ERROR)
+ {
+ SelectObject(hdc, hOldFont);
+ return false;
+ }
+
+ // Loop all the glyphs looking for valid ones
+ // and store those in our font data
+ int j = 0;
+ for (int i = 0; i < MAX_GLYPHS; i++)
+ {
+ if (out[i] != 0xffff)
+ {
+ NewFont.ValidGlyphs[j] = ch[i];
+ j++;
+ }
+ }
+ NewFont.NumValidGlyphs = j;
+
+ // Calculate the number of rows required to hold all glyphs
+ int Rows = NewFont.NumValidGlyphs / m_xNumCells;
+ if (NewFont.NumValidGlyphs % m_xNumCells)
+ Rows += 1;
+
+ // Set the scrollbar in relation to the rows
+ SetScrollRange(m_hwnd, SB_VERT, 0, Rows, FALSE);
+
+ // We're done, update the current font
+ m_CurrentFont = NewFont;
+
+ // We changed the font, we'll need to repaint the whole window
+ InvalidateRect(m_hwnd,
+ NULL,
+ TRUE);
+
+ return true;
+}
+
+
+
+/* PRIVATE METHODS **********************************************/
+
+bool
+CGridView::UpdateCellCoordinates(
)
{
// Go through all the cells and calculate
for (int x = 0; x < m_xNumCells; x++)
{
RECT CellCoordinates;
- CellCoordinates.left = x * m_CellSize.cx + 1;
- CellCoordinates.top = y * m_CellSize.cy + 1;
- CellCoordinates.right = (x + 1) * m_CellSize.cx + 2;
- CellCoordinates.bottom = (y + 1) * m_CellSize.cy + 2;
+ CellCoordinates.left = x * m_CellSize.cx;
+ CellCoordinates.top = y * m_CellSize.cy;
+ CellCoordinates.right = (x + 1) * m_CellSize.cx + 1;
+ CellCoordinates.bottom = (y + 1) * m_CellSize.cy + 1;
m_Cells[y][x]->SetCellCoordinates(CellCoordinates);
}
m_ClientCoordinates.right = ParentRect.right - m_ClientCoordinates.left - 10;
m_ClientCoordinates.bottom = ParentRect.bottom - m_ClientCoordinates.top - 70;
+ // Resize the grid window
SetWindowPos(m_hwnd,
NULL,
m_ClientCoordinates.left,
m_ClientCoordinates.bottom,
SWP_NOZORDER | SWP_SHOWWINDOW);
- // Get the client area we can draw on. The position we set above
- // includes a scrollbar. GetClientRect gives us the size without
- // the scroll, and it more efficient than getting the scroll
- // metrics and calculating the size
+ // Get the client area we can draw on. The position we set above includes
+ // a scrollbar which we obvioulsy can't draw on. GetClientRect gives us
+ // the size without the scroll, and it more efficient than getting the
+ // scroll metrics and calculating the size from that
RECT ClientRect;
GetClientRect(m_hwnd, &ClientRect);
m_CellSize.cx = ClientRect.right / m_xNumCells;
m_CellSize.cy = ClientRect.bottom / m_yNumCells;
- UpdateGridLayout();
+ // Let all the cells know about their new coords
+ UpdateCellCoordinates();
return 0;
}
+VOID
+CGridView::OnVScroll(_In_ INT Value,
+ _In_ INT Pos)
+{
+
+ INT PrevScrollPosition = ScrollPosition;
+
+ switch (Value)
+ {
+ case SB_LINEUP:
+ ScrollPosition -= 1;
+ break;
+
+ case SB_LINEDOWN:
+ ScrollPosition += 1;
+ break;
+
+ case SB_PAGEUP:
+ ScrollPosition -= m_yNumCells;
+ break;
+
+ case SB_PAGEDOWN:
+ ScrollPosition += m_yNumCells;
+ break;
+
+ case SB_THUMBTRACK:
+ ScrollPosition = Pos;
+ break;
+
+ default:
+ break;
+ }
+
+ INT ScrollDiff;
+ ScrollDiff = PrevScrollPosition - ScrollPosition;
+ if (ScrollDiff)
+ {
+ // Set the new scrollbar position in the scroll box
+ SetScrollPos(m_hwnd,
+ SB_VERT,
+ ScrollPosition,
+ TRUE);
+
+ // Check if the scrollbar has moved more than the
+ // number of visible rows (draged or paged)
+ if (abs(ScrollDiff) < m_yNumCells)
+ {
+ RECT rect;
+ GetClientRect(m_hwnd, &rect);
+
+ // Scroll the visible cells which remain within the grid
+ // and invalid any new ones which appear from the top / bottom
+ ScrollWindowEx(m_hwnd,
+ 0,
+ ScrollDiff * m_CellSize.cy,
+ &rect,
+ &rect,
+ NULL,
+ NULL,
+ SW_INVALIDATE);
+ }
+ else
+ {
+ // All the cells need to be redrawn
+ InvalidateRect(m_hwnd,
+ NULL,
+ TRUE);
+ }
+ }
+}
+
LRESULT
CGridView::OnPaint(
_In_opt_ HDC hdc
}
}
+ // Make sure we have a valid DC
if (bSuccess)
{
+ // Paint the grid and chars
DrawGrid(&PaintStruct);
if (LocalHdc)
break;
}
+ case WM_VSCROLL:
+ {
+ INT Value, Pos;
+ Value = LOWORD(wParam);
+ Pos = HIWORD(wParam);
+
+ This->OnVScroll(Value, Pos);
+ break;
+ }
+
case WM_PAINT:
{
This->OnPaint((HDC)wParam);
_In_ LPPAINTSTRUCT PaintStruct
)
{
+ // Calculate which glyph to start at based on scroll position
+ int i;
+ i = m_xNumCells * ScrollPosition;
+
+ // Make sure we have the correct font on the DC
+ HFONT hOldFont;
+ hOldFont = (HFONT)SelectFont(PaintStruct->hdc,
+ m_CurrentFont.hFont);
+
// Traverse all the cells and tell them to paint themselves
for (int y = 0; y < m_yNumCells; y++)
for (int x = 0; x < m_xNumCells; x++)
{
+ WCHAR ch = (WCHAR)m_CurrentFont.ValidGlyphs[i];
+ m_Cells[y][x]->SetChar(ch);
+
m_Cells[y][x]->OnPaint(*PaintStruct);
+
+ i++;
}
+
+ SelectObject(PaintStruct->hdc, hOldFont);
+
}
void
LANGUAGE LANG_ENGLISH, SUBLANG_ENGLISH_US
-IDD_CHARMAP DIALOGEX 6, 6, 292, 224
+IDD_CHARMAP DIALOGEX 6, 6, 290, 224
FONT 8, "MS Shell Dlg", 0, 0
STYLE WS_OVERLAPPED | WS_CAPTION | WS_SYSMENU | WS_MINIMIZEBOX
CAPTION "ReactOS Character Map"
WS_CHILD | WS_VISIBLE | WS_TABSTOP, 74, 186, 114, 13
DEFPUSHBUTTON "Select", IDC_SELECT, 194, 186, 44, 13
PUSHBUTTON "Copy", IDC_COPY, 242, 186, 44, 13, WS_DISABLED
- //CONTROL "Advanced view", IDC_CHECK_ADVANCED, "Button", BS_AUTOCHECKBOX |
- // WS_TABSTOP, 8, 208, 95, 10
- //LTEXT "Charset:", IDC_STATIC, 8, 8, 48, 8
- //COMBOBOX IDC_COMBO_CHARSET, 72, 4, 116, 80, CBS_DROPDOWNLIST | WS_VSCROLL | WS_TABSTOP
- //LTEXT "Group by:", IDC_STATIC, 8, 28, 50, 8
- //COMBOBOX IDC_COMBO_GROUPBY, 72, 24, 116, 80, CBS_DROPDOWNLIST | WS_VSCROLL | WS_TABSTOP
- //PUSHBUTTON "Search", IDC_BUTTON_SEARCH, 200, 44, 50, 14
- //EDITTEXT IDC_EDIT_SEARCH, 72, 44, 116, 14, ES_AUTOHSCROLL
- //LTEXT "Search for:", IDC_STATIC, 8, 48, 42, 8
- //LTEXT "Unicode:", IDC_STATIC, 200, 8, 30, 8
- //EDITTEXT IDC_EDIT_UNICODE, 236, 4, 28, 12, ES_AUTOHSCROLL
END
STRINGTABLE