实现上面这种针对车牌号的小键盘。 1、省份和 数字/字母 的切换 2、如果点击 省份按钮,始终省份文字是在edit内容的最前面
首先有个对话框类CmyNumCarDlg, 然后,这个对话框作为父窗口,上面放 省份和 数字/字母 按钮,关闭按钮,以及两个 子窗口 CmyNumPageDlg* pTabPage[2] ;
CmyNumCarDlg文件中涉及到的 键盘窗口调出和 销毁的过程参考 C++小键盘(一)
按钮切换时对应的pTabPage的切换,略。
set strBtnSet1,strBtnSet2; 这两个set容器中分别 insert pTabPage[0]和pTabPage[1]中的按钮的文本内容。
SetSetData(); //set容器中插入值 pTabPage[0] = new CmyNumPageDlg((CSkinEdit*)m_pParentWnd, strBtnSet1,TRUE,this); pTabPage[1] = new CmyNumPageDlg((CSkinEdit*)m_pParentWnd, strBtnSet1,FALSE,this); pTabPage[0]->Create(IDD_DIALOG_NUM_PAGE, this); pTabPage[1]->Create(IDD_DIALOG_NUM_PAGE, this); ....... CreatePageBtn(strBtnSet1,pTabPage[0], CSize(4, 9), CSize(35,35),CPoint(5,5),CSize(4,6),vecBtn1); CreatePageBtn(strBtnSet2, pTabPage[1], CSize(5, 10), CSize(35,35), CPoint(5, 5), CSize(4,6),vecBtn2);下面这个函数,动态创建tab页中的btn,并对button的宽高,以及上下左右间距统一进行设置,并存放在vector容器中,如果要对某个btn改变大小,再另写设置。
void CmyNumCarDlg::CreatePageBtn(set<CString>& myset,CmyNumPageDlg* pDlg,CSize &sizeRC,CSize &sizeWH,CPoint &sizeBegin,CSize &jianju,vector<CSkinButton*> &vecBtn) { //第一个button左上角是起始位置 set<CString>::iterator ite = myset.begin(); POINT pt; SIZE size; for (int i = 0; i < sizeRC.cx; i++) { pt.x = sizeBegin.x; pt.y = sizeBegin.y + i*(sizeWH.cy + jianju.cy); size = sizeWH; //CRect tmpRc(sizeBegin.x, sizeBegin.y+i*(sizeWH.cy+jianju.cy),sizeWH.cx, sizeWH.cy); CRect tmpRc(pt,size); int j=0; for (j=0;j < sizeRC.cy; j++) { CSkinButton* pBtn = new CSkinButton; //new的别忘记释放 if (pBtn->Create(_T(""), WS_CHILD | WS_VISIBLE,tmpRc, pDlg,WM_USER+i*sizeRC.cy+j)) //此处怎样避免ID冲突呢 { pBtn->SetFont(CFont::FromHandle(RenderEngine->GetFont(10))); } InitBtn(pBtn); pBtn->MoveWindow(&tmpRc); pBtn->SetWindowTextW(*ite); vecBtn.push_back(pBtn); ite++; if (ite == myset.end()) return; tmpRc.MoveToX(tmpRc.right + jianju.cx); } } }CmyNumPageDlg这个对话框类是针对每个tab页:
CmyNumPageDlg::CmyNumPageDlg(CSkinEdit* pEdit,set<CString>& myset,BOOL isAllChinese,CWnd* pParent):CmyNumPageDlg(pParent)传入 edit,tab页对应的set容器,是否全是中文(省份那个tab页全是中文)
以下是操作小键盘时的响应:
BOOL CmyNumPageDlg::OnCommand(WPARAM wParam, LPARAM lParam) { CString str; GetDlgItem(LOWORD(wParam))->GetWindowText(str); if (!str.IsEmpty()) { SendCharMsg(LOWORD(wParam)); if (isAllChinese) { ::PostMessage(GetParent()->m_hWnd, WM_COMMAND, MAKEWPARAM(IDC_BUTTON_NUM_NUMABC,BN_CLICKED),(LPARAM)GetParent()->GetDlgItem(IDC_BUTTON_NUM_NUMABC)->m_hWnd); } } return CSkinDialog::OnCommand(wParam, lParam); } void CmyNumPageDlg::SendCharMsg(const UINT& uid) { if (NULL == pEdit) return; CString str; GetDlgItem(uid)->GetWindowText(str); //UINT ascid = 0; //ascid = str[0]; if (isAllChinese) { //如果第一个字符是省会 CString strEdit; pEdit->GetWindowTextW(strEdit); if (!strEdit.IsEmpty()) { CString strTmp(strEdit.GetAt(0)); set<CString>::iterator it = myset.find(strTmp); if (it != myset.end()) { //如果第一个字符是省会简称 strEdit.SetAt(0, str[0]); pEdit->SetWindowTextW(strEdit); } else { strEdit.Insert(0, str[0]); pEdit->SetWindowTextW(strEdit); } } else { strEdit.Insert(0, str[0]); pEdit->SetWindowTextW(strEdit); } int len = strEdit.GetLength(); pEdit->SetSel(len, len); //使光标定位在末尾 return; } if (str == _T("确认")) { ::PostMessage(GetParent()->m_hWnd, WM_COMMAND, MAKEWPARAM(IDCANCEL, BN_CLICKED),(LPARAM)GetParent()->GetDlgItem(IDCANCEL)->m_hWnd); } else if (str == _T("删除")) { ::PostMessage(pEdit->GetSafeHwnd(), WM_CHAR, 8, 0); } else { ::PostMessage(pEdit->GetSafeHwnd(), WM_CHAR, (WPARAM)str[0], 0); } }