即日起在codingBlog上分享您的技术经验即可获得积分,积分可兑换现金哦。

C++小键盘(一)

编程语言 u013478518 14℃ 0评论

这里写图片描述

实现这样的小键盘。

  1. 首先,对话框中有这样的一个带 图标按钮的edit:

这里写图片描述

实现这样一个带图标按钮的edit的效果,可参考 郭延明 博客中自绘类 CSkinEdit的实现。

  1. 我们想实现的效果是:点击icon时弹出小键盘,点击键盘外的别处或者点击键盘上的关闭按钮时,键盘消失


    涉及到三个窗口:edit,edit所在的dlg,小键盘。


    处理过程:


    edit的OnNcLButtonUp中发给 dlg 自定义的键盘消息UM_NUMKEYBOARDABC,


    dlg中响应自定义消息UM_NUMKEYBOARDABC,调出小键盘。
  2. OnNcLButtonUp中的代码:
void CSkinEdit::OnNcLButtonUp(UINT nHitTest, CPoint point)
{
    CWnd *pWnd = GetParent();
    if ( pWnd != NULL && pWnd->GetSafeHwnd() != NULL )
    {
        CRect rcIcon;
        CPoint pt;
        GetCursorPos(&pt);
        GetIconRect(rcIcon);
        if (PtInRect(&rcIcon, pt))
        {
            pWnd->PostMessage(WM_COMMAND, GetDlgCtrlID());
            if (0 == keyBoardState)
                ::SendMessage(GetParent()->m_hWnd, UM_NUMKEYBOARDABC, (WPARAM)this, (LPARAM)&CPoint(rcIcon.right - 200, rcIcon.bottom));
            else if (1 == keyBoardState)
                ::SendMessage(GetParent()->m_hWnd, UM_NUMKEYBOARD, (WPARAM)this, (LPARAM)&CPoint(rcIcon.right, rcIcon.bottom));
            else if (2 == keyBoardState)
                ::SendMessage(GetParent()->m_hWnd, UM_NUMCAR, (WPARAM)this, (LPARAM)&CPoint(rcIcon.right, rcIcon.bottom));
        }
    }
    __super::OnNcLButtonUp(nHitTest, point);
}

说明:因为程序中还有别的小键盘,这里是UM_NUMKEYBOARDABC消息对应的小键盘。

在dlg中,对消息的处理的代码(此处调出小键盘):

LRESULT CmyAddDlg::NumABCKeyBoard(WPARAM wParam, LPARAM lParam)
{
    CEdit *pe = (CEdit*)wParam;
    CPoint pt = *((CPoint*)lParam);
    NumKeyABC(pe, pt, pabcdlg);
    return 0;
}
  1. 下面是小键盘的实现:


    CmyNumABCDlg.h中


    写个CmyNumABCDlg对话框类;还有


    void NumKeyABC(CEdit* pEdit, const CPoint& pt, CmyNumABCDlg* pdlg)这个函数。
//参数1:小键盘所属的edit,
//参数2:小键盘弹出位置
//参数3:小键盘窗口
void NumKeyABC(CEdit* pEdit, const CPoint& pt, CmyNumABCDlg* pdlg)
{
    if (NULL == pdlg)
    {
        pdlg = new CmyNumABCDlg(pEdit);
        pdlg->Create(IDD_DIALOG_NUMABC, NULL);
        pdlg->ShowWindow(SW_SHOW);
    }
    pdlg->SetEdit(pEdit);
    pdlg->SetWindowPos(NULL, pt.x, pt.y, 0, 0, SWP_NOSIZE);
}

小键盘类:


因为是CmyNumABCDlg对象是在堆分配空间(pdlg = new CmyNumABCDlg(pEdit);),所以一定要在PostNcDestroy中 有 delete this;这句。

关闭窗口是 在


void Destroy()中调DestroyWindow()销毁窗口这句。

实现点击 键盘外的别处时,键盘销毁,是通过响应WM_ACTIVE消息,下面这段代码,其中isDestroyed初始为FALSE:

void CmyNumABCDlg::OnActivate(UINT nState, CWnd* pWndOther, BOOL bMinimized)
{
    CSkinDialog::OnActivate(nState, pWndOther, bMinimized);
    if (FALSE == isDestroyed)
    {
        if (WA_INACTIVE == nState)
        {
            isDestroyed = TRUE;
            Destroy();
        }
    }
}

下面是响应小键盘按钮,获取按钮文本信息,给edit发的WM_CHAR消息,达到操作edit的效果

BOOL CmyNumABCDlg::OnCommand(WPARAM wParam, LPARAM lParam)
{
    CString str;
    GetDlgItem(LOWORD(wParam))->GetWindowText(str);
    UINT ascid = str[0];
    if ((ascid >= 48 && ascid <= 57) || (ascid >= 65 && ascid <= 90) || (ascid >= 97 && ascid <= 122))
        SendCharMsg(LOWORD(wParam));
    switch (LOWORD(wParam))
    {
    case IDC_BTN_KGANG:
    case IDC_BTN_KBACK:
    case IDC_BTN_KPOT:
    case IDC_BTN_KCLOSE:
    case IDC_BTN_KCHANGE:
        SendCharMsg(LOWORD(wParam));
    default:
        break;
    }
    return CSkinDialog::OnCommand(wParam, lParam);
}
void CmyNumABCDlg::SendCharMsg(const UINT& uid)
{
    if (NULL == pEdit)
        return;
    CString str;
    GetDlgItem(uid)->GetWindowText(str);
    UINT ascid = 0;
    if (str != _T("关闭") && str != _T("←") && str != _T("大写/小写"))
    {
        for (int i = 0; i < str.GetLength(); i++)
        {
            ascid = str[i];
            ::PostMessage(pEdit->GetSafeHwnd(), WM_CHAR, ascid, 0);
        }
    }
    else if (_T("←") == str)
    {
        ::PostMessage(pEdit->GetSafeHwnd(), WM_CHAR, 8, 0);
    }
    else if (_T("大写/小写") == str)
    {
        int  add = -32;//原本是小写
        UINT ad = 0;
        CString str;
        GetDlgItem(1327)->GetWindowText(str);
        ad = str[0];
        if (65 == ad)
            add = 32;
        else if (97 == ad)
            add = -32;
        CString changed;
        for (UINT id = 1327; id <= 1351; id++)
        {
            changed.Format(_T("%c"),ad+add);
            GetDlgItem(id)->SetWindowTextW(changed);
            ad++;
        }
    }
}

上面的 for (UINT id = 1327; id <= 1351; id++)


对字母 大小写切换为了循环方便,使用的是连续的ID号。

–欢迎指正和补充,谢谢!–

转载请注明:CodingBlog » C++小键盘(一)

喜欢 (0)or分享 (0)
发表我的评论
取消评论

*

表情