近日在為一個數據應用寫數據輸入界面,大量的編輯框要想實現快速的輸入就是有設計良好的符合工作流程的TAB鍵序。相信,不少的人在使用具有大量編輯框的程序時都有這樣的想法和感概。而我這個對話框界面主要輸入的是數字,因此如果使用TAB鍵作編輯框之間的跳轉會在使用數字鍵盤時不方便。因此,就考慮了用回車鍵來實現TAB鍵的功能。因為MFC對話框的特點,基于MFC對話框的對話框按下回車鍵會調用框架內的的OnOk成員函數導至退出。即使你去掉IDC_OK按鍵的BS_DEFPUSHBUTTON 屬性也是不行的。必須重載WM_GETDEFID,因為當用戶按下回車鍵時,Windows發送WM_GETDEFID消息來獲得缺省的命令ID,Windows再將它作為WM_COMMAND發送,所以重載這個消息必須在高位字中返回DC_HASDEFID。 如下所例:
BEGIN_MESSAGE_MAP(CMyDlg, CDialog) ON_MESSAGE(DM_GETDEFID, OnGetDefID) ... END_MESSAGE_MAP()
LRESULT CMyDlg::OnGetDefID(WPARAM wp, LPARAM lp) { return MAKELONG(0,DC_HASDEFID); }
這是一種方法,另外一種方法是在消息循環處著手處理。重載PreTranslateMessage這個虛函數,將消息隊列中有關鍵盤按下的消息給攔載下來,在框架之前處理WM_KEYDOWN消息。判斷是按下回車鍵后,我們可以用GetNextDlgTabItem 函數獲得TAB鍵序中下一個或上一個接受TAB鍵的控件句柄。示例代碼如下:
view plaincopy to clipboardprint?
BOOL CKeydownDlg::PreTranslateMessage(MSG* pMsg)
{
if (pMsg->message == WM_KEYDOWN && pMsg->wParam == VK_RETURN)
{
CWnd *mwnd = GetNextDlgTabItem (GetFocus()); //取得當前焦點控件的下一個控件的句柄
if (mwnd)
{
mwnd->SetFocus(); //設置下一件控件得到輸入焦點
return TRUE;
}
}
return CDialog::PreTranslateMessage(pMsg);
}
BOOL CKeydownDlg::PreTranslateMessage(MSG* pMsg)
{
if (pMsg->message == WM_KEYDOWN && pMsg->wParam == VK_RETURN)
{
CWnd *mwnd = GetNextDlgTabItem (GetFocus()); //取得當前焦點控件的下一個控件的句柄
if (mwnd)
{
mwnd->SetFocus(); //設置下一件控件得到輸入焦點
return TRUE;
}
}
return CDialog::PreTranslateMessage(pMsg);
}
但是,各位有沒有注意到。這樣處理之后,雖然可以在各個控件之進行輸入焦點的轉移。可是當一個按鈕控件獲得了焦點之后,也是按下回車鍵。以前我們習慣中或者說預料中按下該按鈕的后應該執行的功能沒有被執行,而焦點又跑到按鈕之后的控件上去了。這就是上面代碼的不足之處,雖然實現了焦點由回車鍵控件轉移,但是按鈕卻不能用回車鍵來操作了。只以用鼠標,這和大家習慣不合。而且,在快速的數據輸入中不能用回車鍵來按下這個按鈕卻要用鼠標來點擊也有違當初我們要快速這樣一個目的。所以,還得對以上代碼做適當的修改。代碼如下。在這里增加了對當前焦點控件類的判斷,即如果當前控件是按鈕(Button)那么就不執行焦點跳轉而是構造一條WM_COMMAND消息發送給程序,讓程序以為是鼠標點擊了該按鈕。從而執行了這個按鈕具有的功能而不是什么也不做的焦點轉移。
view plaincopy to clipboardprint?
BOOL CKeydownDlg::PreTranslateMessage(MSG* pMsg)
{
if (pMsg->message == WM_KEYDOWN && pMsg->wParam == VK_RETURN)
{
CWnd *wnd = GetFocus ();
if (wnd != NULL)
{
char str[256];
CString ClassName = _T("Button");
GetClassName (wnd->m_hWnd, str, 256);
if (ClassName == str)
{
UINT i = wnd->GetDlgCtrlID ();
SendMessage (WM_COMMAND, i, (LPARAM)wnd->m_hWnd);
return TRUE;
}
}
CWnd *mwnd = GetNextDlgTabItem (wnd);
if (mwnd)
{
mwnd->SetFocus();
return TRUE;
}
}
return CDialog::PreTranslateMessage(pMsg);
}
標簽:
本站文章除注明轉載外,均為本站原創或翻譯。歡迎任何形式的轉載,但請務必注明出處、不得修改原文相關鏈接,如果存在內容上的異議請郵件反饋至chenjj@fc6vip.cn
文章轉載自:CSDN