Pocket PC 数字键盘






4.40/5 (6投票s)
一种在袖珍电脑上更轻松地接受数字输入的方式。
引言
在袖珍电脑上输入数字一直是个难题。SIP 提供的数字键盘太小且不易直接访问。此外,在输入数据之前能够执行一些计算始终是件好事。
考虑到这些问题,我开发了数字键盘对话框,以帮助在袖珍电脑应用程序中输入数字数据。
实现
我在本文中包含的示例应用程序使用两种不同的方法实现了数字键盘:窗口控件和无窗口控件。
第一种方法使用常规 Windows 控件,例如按钮和静态标签来绘制键盘。与常规应用程序中可以找到的静态对话框资源不同,所有控件都是从动态创建的对话框资源创建的。类 CDialogTemplate
(请参阅示例项目)基于 Max McGuire 在 FlipCode 上的 对话框模板 代码。
第二种方法(如图所示)不使用窗口控件,而是使用从 CSubWnd
派生的对象。这些对象位于一个 CSubWndContainer
上,它是 MFC 的 CWnd
,负责将所有传入的(和相关的)Windows 消息分派到包含的 CSubWnd
对象。每个 CSubWnd
派生对象负责绘制自己的矩形并处理单击事件。CSubWndContainer
分派绘制请求的方式如下:
void CSubWndContainer::OnPaint() { CPaintDC dc(this); CSubWndCont::iterator pos, end = m_cont.end(); HFONT hFontOld; hFontOld = (HFONT)::SelectObject(dc, m_hFont); // // Paint all sub windows // for(pos = m_cont.begin(); pos != end; ++pos) if(dc.RectVisible(&(*pos)->GetRect())) (*pos)->Paint(dc); ::SelectObject(dc, hFontOld); }
为了使单击处理更容易(并减少虚拟函数的数量),所有与单击相关的 Windows 消息都分派到一个 CSubWnd
函数
void CSubWndContainer::OnLButtonDown(UINT nFlags, CPoint point) { m_pSubWnd = SubWndFromPoint(point); if(m_pSubWnd) m_pSubWnd->Click(CLICK_DOWN, point); } void CSubWndContainer::OnLButtonUp(UINT nFlags, CPoint point) { if(m_pSubWnd) m_pSubWnd->Click(CLICK_UP, point); } void CSubWndContainer::OnLButtonDblClk(UINT nFlags, CPoint point) { m_pSubWnd = SubWndFromPoint(point); if(m_pSubWnd) m_pSubWnd->Click(CLICK_DOWN | CLICK_DOUBLE, point); }
示例代码使用两个 CSubWnd
派生类:CSubStatic
用于实现顶部的静态控件,而 CSubButton
实现所有键盘按钮。请注意,该类如何绕过 Windows 内置的双击处理
void CSubButton::Click(DWORD dwClick, POINT pt) { bool bOn = (dwClick & CLICK_DOWN); ASSERT(m_pWnd); // // Make a double click work right // if(dwClick & CLICK_DOUBLE) Click(CLICK_UP, pt); if(m_rc.PtInRect(pt)) { // // Inside this button // if(IsActive() && !bOn) { CWnd* pParent = m_pWnd->GetParent(); if(pParent) pParent->SendMessage(WM_COMMAND, m_nID, (LPARAM)m_pWnd->GetSafeHwnd()); } Activate(bOn); } else { // // Outside this button // if(IsActive()) Activate(false); } }
数字键盘的实现非常简单。正在编辑的值始终是一个 double
,可以转换为 int
或 CURRENCY
。它以客户端选择的格式显示
enum Format { fmtInteger, // An integer fmtNumber, // Locale number fmtCurrency // Locale currency };
要使用此类,请使用适当的构造函数参数创建 CNumPadDlg
的实例
CNumPadDlg(enum Format format, BOOL bTemplate, CWnd* pParent = NULL);
在调用对象的 DoModal
函数之前,使用以下方法之一设置键盘值:
void SetIntValue(int nVal); void SetDblValue(double dblVal); void SetCurValue(CURRENCY cyVal);
使用相应的获取函数检索键盘值:
int GetIntValue(); double GetDblValue(); CURRENCY GetCurValue();
就是这样!
最终注释
此代码使用 Giuseppe Govi 的 STL 实现。它有点精简,但足以满足大多数袖珍电脑应用程序的需求(并且与 eVC3 兼容)。