数字键盘对话框的实现

Pocket PC应用程序中,SIP提供的数字键盘不仅尺寸小,而且不易直接访问。此外,在输入数据之前能够进行一些计算总是有益的。针对这些问题,开发了数字键盘对话框,以帮助在Pocket PC应用程序中输入数字数据。

实现

本文附带的示例应用程序使用两种不同的方法实现数字键盘:窗口控件和无窗口控件。

第一种方法使用常规的Windows控件,如按钮和静态标签来绘制键盘。与常规应用程序中可以找到的静态对话框资源不同,所有控件都是从一个动态创建的对话框资源中创建的。类CDialogTemplate(见示例项目)是基于FlipCode的Dialog Template代码,由Max McGuire编写。

第二种方法(上图所示)不使用窗口控件,而是使用从CSubWnd派生的控件。这些控件位于一个CSubWndContainer中,它是MFCCWnd,负责将所有传入的(和相关的)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); } } }

数字键盘的实现相当直接。正在编辑的值始终是一个可以转换为intCURRENCYdouble。它以客户端选择的格式显示:

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();
沪ICP备2024098111号-1
上海秋旦网络科技中心:上海市奉贤区金大公路8218号1幢 联系电话:17898875485