// XCharMap.cpp Version 1.0
//
// Author: Hans Dietrich
// hdietrich2@hotmail.com
//
// Description:
// XCharMap.cpp implements CXCharMap, a class to display a
// dialog containing a character grid.
//
// History
// Version 1.0 - 2003 June 4
// - Initial public release
//
// This software is released into the public domain. You are free to use it
// in any way you like.
//
// This software is provided "as is" with no expressed or implied warranty.
// I accept no liability for any damage or loss of business that this software
// may cause.
//
///////////////////////////////////////////////////////////////////////////////
#include "stdafx.h"
#include "XCharMapTest.h"
#include "XCharMap.h"
#include "Clipboard.h"
#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif
#define LEFT_CLICK_COLOR RGB(224,255,255)
#define RIGHT_CLICK_COLOR RGB(255,255,192)
///////////////////////////////////////////////////////////////////////////////
// CXCharMap dialog
BEGIN_MESSAGE_MAP(CXCharMap, CDialog)
//{{AFX_MSG_MAP(CXCharMap)
ON_WM_CTLCOLOR()
ON_BN_CLICKED(IDC_SELECT, OnSelect)
ON_BN_CLICKED(IDC_COPY, OnCopy)
ON_CBN_KILLFOCUS(IDC_FONT_NAME, OnSelChange)
ON_CBN_SELCHANGE(IDC_FONT_NAME, OnSelChange)
ON_MESSAGE(WM_XCHAR_LEFTCLICK, OnLeftClick)
ON_MESSAGE(WM_XCHAR_RIGHTCLICK, OnRightClick)
ON_MESSAGE(WM_XCHAR_SELCHANGE, OnSelChange)
//}}AFX_MSG_MAP
END_MESSAGE_MAP()
///////////////////////////////////////////////////////////////////////////////
// ctor
CXCharMap::CXCharMap(CWnd* pParent /*=NULL*/)
: CDialog(CXCharMap::IDD, pParent)
{
//{{AFX_DATA_INIT(CXCharMap)
m_strCharsToCopy = _T("");
//}}AFX_DATA_INIT
m_pCharGrid = NULL;
m_bEnableCharsToCopy = TRUE;
m_bEnableClicks = TRUE;
m_bEnableCharacterCode = TRUE;
}
///////////////////////////////////////////////////////////////////////////////
// dtor
CXCharMap::~CXCharMap()
{
if (m_pCharGrid)
delete m_pCharGrid;
m_pCharGrid = NULL;
}
///////////////////////////////////////////////////////////////////////////////
// DoDataExchange
void CXCharMap::DoDataExchange(CDataExchange* pDX)
{
CDialog::DoDataExchange(pDX);
//{{AFX_DATA_MAP(CXCharMap)
DDX_Control(pDX, IDC_FONT_NAME, m_cmbFont);
DDX_CBString(pDX, IDC_FONT_NAME, m_strFont);
DDX_Text(pDX, IDC_CHARSTOCOPY, m_strCharsToCopy);
//}}AFX_DATA_MAP
}
///////////////////////////////////////////////////////////////////////////////
// OnInitDialog
BOOL CXCharMap::OnInitDialog()
{
TRACE(_T("in CXCharMap::OnInitDialog\n"));
CDialog::OnInitDialog();
m_brLeftClick.CreateSolidBrush(LEFT_CLICK_COLOR);
m_brRightClick.CreateSolidBrush(RIGHT_CLICK_COLOR);
m_cmbFont.m_style = CFontPreviewCombo::NAME_THEN_SAMPLE;
m_cmbFont.Init();
CRect rect;
GetDlgItem(IDC_CODEFRAME)->GetWindowRect(&rect);
ScreenToClient(&rect);
m_pCharGrid = new CXCharGrid(1, 1, this);
m_pCharGrid->Create(CPoint(rect.left, rect.top), this, 20);
m_pCharGrid->SetLeftClick(-1, -1, LEFT_CLICK_COLOR);
m_pCharGrid->SetRightClick(-1, -1, RIGHT_CLICK_COLOR);
OnSelChange();
if (!m_bEnableCharsToCopy)
{
// disable Characters to copy windows
GetDlgItem(IDC_STATIC1)->EnableWindow(FALSE);
GetDlgItem(IDC_CHARSTOCOPY)->EnableWindow(FALSE);
GetDlgItem(IDC_SELECT)->EnableWindow(FALSE);
GetDlgItem(IDC_COPY)->EnableWindow(FALSE);
// hide Characters to copy windows
GetDlgItem(IDC_STATIC1)->ShowWindow(SW_HIDE);
GetDlgItem(IDC_CHARSTOCOPY)->ShowWindow(SW_HIDE);
GetDlgItem(IDC_SELECT)->ShowWindow(SW_HIDE);
GetDlgItem(IDC_COPY)->ShowWindow(SW_HIDE);
}
if (!m_bEnableClicks)
{
// disable Left/Right click windows
GetDlgItem(IDC_STATIC2)->EnableWindow(FALSE);
GetDlgItem(IDC_LEFTCLICK)->EnableWindow(FALSE);
GetDlgItem(IDC_STATIC3)->EnableWindow(FALSE);
GetDlgItem(IDC_RIGHTCLICK)->EnableWindow(FALSE);
// hide Left/Right click windows
GetDlgItem(IDC_STATIC2)->ShowWindow(SW_HIDE);
GetDlgItem(IDC_LEFTCLICK)->ShowWindow(SW_HIDE);
GetDlgItem(IDC_STATIC3)->ShowWindow(SW_HIDE);
GetDlgItem(IDC_RIGHTCLICK)->ShowWindow(SW_HIDE);
}
if (!m_bEnableCharsToCopy && !m_bEnableClicks)
{
CRect rectSelect;
GetDlgItem(IDC_SELECT)->GetWindowRect(&rectSelect);
ScreenToClient(&rectSelect);
// hide horizontal rule
GetDlgItem(IDC_STATIC4)->ShowWindow(SW_HIDE);
// move Cancel button
CRect rect;
GetDlgItem(IDCANCEL)->GetWindowRect(&rect);
ScreenToClient(&rect);
int nOldTop = rect.top;
int h = rect.Height();
int nNewTop = rectSelect.top + 1;
rect.top = nNewTop;
rect.bottom = rect.top + h;
GetDlgItem(IDCANCEL)->MoveWindow(&rect);
// move OK button
GetDlgItem(IDOK)->GetWindowRect(&rect);
ScreenToClient(&rect);
rect.top = nNewTop;
rect.bottom = rect.top + h;
GetDlgItem(IDOK)->MoveWindow(&rect);
// shrink dialog
CRect rectDlg;
GetWindowRect(&rectDlg);
h = rectDlg.Height();
rectDlg.bottom = rectDlg.top + h - (nOldTop - nNewTop);
MoveWindow(&rectDlg);
}
return TRUE; // return TRUE unless you set the focus to a control
// EXCEPTION: OCX Property Pages should return FALSE
}
///////////////////////////////////////////////////////////////////////////////
// OnOK
void CXCharMap::OnOK()
{
m_nLeftClickRow = m_pCharGrid->m_nLeftClickRow;
m_nLeftClickCol = m_pCharGrid->m_nLeftClickCol;
m_nRightClickRow = m_pCharGrid->m_nRightClickRow;
m_nRightClickCol = m_pCharGrid->m_nRightClickCol;
CDialog::OnOK();
}
///////////////////////////////////////////////////////////////////////////////
// OnSelChange
void CXCharMap::OnSelChange()
{
// The selection hasn't changed yet, so change it
if (!::IsWindow(m_cmbFont.m_hWnd))
return;
CString sText = _T("");
int index = m_cmbFont.GetCurSel();
if (index != CB_ERR)
{
m_cmbFont.GetLBText(index, sText);
m_cmbFont.SetWindowText(sText);
m_strFont = sText;
}
else
{
if ((index = m_cmbFont.FindStringExact(0, m_strFont)) != CB_ERR)
{
m_cmbFont.SetCurSel(index);
m_cmbFont.GetLBText(index, sText);
m_cmbFont.SetWindowText(sText);
}
else
{
m_strFont = "Courier New";
}
}
if ((index = m_cmbFont.FindStringExact(0, m_strFont)) != CB_ERR)
{
m_cmbFont.SetCurSel(index);
m_cmbFont.SetWindowText(m_strFont);
}
UpdateData(TRUE);
if (m_strFont.IsEmpty())
m_strFont = "Courier New";
if (sText.IsEmpty())
sText = m_strFont;
LOGFONT logfont;
memset(&logfont, 0, sizeof(logfont));
logfont.lfStrikeOut = FALSE;
logfont.lfUnderline = FALSE;
strncpy(logfont.lfFaceName, m_strFont, LF_FACESIZE);
logfont.lfHeight = -16;
logfont.lfWeight = 400; //Regular
logfont.lfItalic = FALSE;
m_font.DeleteObject();
m_font.CreateFontIndirect(&logfont);
CFont* pFont = GetFont();
pFont->GetLogFont(&logfont);
strncpy(logfont.lfFaceName, m_strFont, LF_FACESIZE);
m_pCharGrid->SetFont(&m_font);
m_pCharGrid->Invalidate(FALSE);
m_pCharGrid->UpdateWindow();
GetDlgItem(IDC_LEFTCLICK)->SetFont(&m_font);
GetDlgItem(IDC_RIGHTCLICK)->SetFont(&m_font);
GetDlgItem(IDC_CHARSTOCOPY)->SetFont(&m_font);
RedrawWindow(NULL, NULL, RDW_UPDATENOW|RDW_ALLCHILDREN|RDW_ERASE);
}
///////////////////////////////////////////////////////////////////////////////
// OnSelect
void CXCharMap::OnSelect()
{
UpdateData(TRUE);
CString s;
((CStatic*) GetDlgItem(IDC_LEFTCLICK))->GetWindowText(s);
if (!s.IsEmpty())
{
m_strCharsToCopy += s;
UpdateData(FALSE);
}
}
///////////////////////////////////////////////////////////////////////////////
// OnCopy
void CXCharMap::OnCopy()
{
UpdateData(TRUE);
if (!m_strCharsToCopy.IsEmpty())
CClipboard::SetText(m_strCharsToCopy);
}
///////////////////////////////////////////////////////////////////////////////
// OnCtlColor
HBRUSH CXCharMap::OnCtlColor(CDC* pDC, CWnd* pWnd, UINT nCtlColor)
{
HBRUSH hbr = CDialog::OnCtlColor(pDC, pWnd, nCtlColor);
DWORD dwStyle;
int nCtrlID = pWnd->GetDlgCtrlID();
switch (nCtlColor)
{
case CTLCOLOR_STATIC:
dwStyle = ::GetWindowLong(pWnd->m_hWnd, GWL_STYLE);
if (nCtrlID == IDC_LEFTCLICK)
{
pDC->SetBkColor(LEFT_CLICK_COLOR);
hbr = (HBRUSH) m_brLeftClick;
}
if (nCtrlID == IDC_RIGHTCLICK)
{
pDC->SetBkColor(RIGHT_CLICK_COLOR);
hbr = m_brRightClick;
}
break;
default:
break;
}
return hbr;
}
///////////////////////////////////////////////////////////////////////////////
// OnLeftClick
LONG CXCharMap::OnLeftClick(UINT, LONG lParam)
{
int nSelectedRow = LOWORD(lParam);
int nSelectedCol = HIWORD(lParam);
int nNewChar = nSelectedCol | nSelectedRow << 4;
char s[10];
s[0] = (char) nNewChar;
s[1] = 0;
((CStatic*) GetDlgItem(IDC_LEFTCLICK))->SetWindowText(s);
return TRUE;
}
///////////////////////////////////////////////////////////////////////////////
// OnRightClick
LONG CXCharMap::OnRightClick(UINT, LONG lParam)
{
int nSelectedRow = LOWORD(lParam);
int nSelectedCol = HIWORD(lParam);
int nNewChar = nSelectedCol | nSelectedRow << 4;
char s[10];
s[0] = (char) nNewChar;
s[1] = 0;
((CStatic*) GetDlgItem(IDC_RIGHTCLICK))->SetWindowText(s);
return TRUE;
}
///////////////////////////////////////////////////////////////////////////////
// OnSelChange
LONG CXCharMap::OnSelChange(UINT, LONG lParam)
{
int nSelectedRow = LOWORD(lParam);
int nSelectedCol = HIWORD(lParam);
int nNewChar = nSelectedCol | nSelectedRow << 4;
char s[10];
s[0] = (char) nNewChar;
s[1] = 0;
if (m_bEnableCharacterCode)
{
CString str1 = _T("");
str1.Format(_T("Character Map - 0x%02X \\%03o Alt+0%03u"),
nNewChar, nNewChar, nNewChar);
SetWindowText(str1);
}
return TRUE;
}