关于dialog和控件回车键消息处理的小问题
我在一个dialog上放了一个CTreeCtrl(设置为可编辑),在一个tree item上编辑后想回车确定,但是这个回车被dialog的OnOK()处理了,如果去掉这个OnOK(),dialog就直接退出了。现在我想做的是:按下回车键时,
1、如果当前正在编辑tree item,能得到TVN_ENDLABELEDIT通知消息
2、否则才调用OnOK()。
另:如果从CTreeCtrl派生一个子类,怎样才能对话框资源编辑里画的那个CTreeCtrl直接联系起来?
问题点数:30、回复次数:11Top
1 楼ghz(冰河)回复于 2001-12-14 18:40:56 得分 6
1、重载OnOk,不要返回CDialog::的OnOK,向CTreeCtrl发ENDLABELEDIT的消息就行了
2、给那个控件加个Control型的变量,用你的新类Top
2 楼jiangsheng(蒋晟.Net[MVP])回复于 2001-12-14 18:41:16 得分 15
BUG: ESC/ENTER Keys Do Not Work When Editing CTreeCtrl Labels
ID: Q167960
--------------------------------------------------------------------------------
The information in this article applies to:
Microsoft Visual C++, 32-bit Editions, versions 2.0, 2.1, 2.2, 4.0, 4.0a, 4.1, 4.2, 4.2b, 5.0, 6.0
--------------------------------------------------------------------------------
SYMPTOMS
When you edit labels in a CTreeCtrl, you are allowed to press the ESC key to cancel the changes or press the ENTER key to accept the changes. However, when the CTreeCtrl is a child window of a dialog box (CDialog), a formview window (CFormView), or a property page (CPropertyPage), the ESC or ENTER keys do not function as expected.
CAUSE
IsDialogMessage() function is called in the PreTranslateInput() function which in turn is called in the PreTranslateMessage() function of all CFormView or CDialog derived classes mentioned above. The ESC and ENTER keys are processed in IsDialogMessage() but are not passed on to the edit control created by the tree-view control. Thus, these keystrokes have no effect.
RESOLUTION
For Visual C++ 4.xx and later, we can trap the ESC and ENTER keystroke messages in the PreTranslateMessage() function for all CFormView, CDialog (modal or modeless) and CPropertyPage (either in modal or modeless CPropertySheet) derived classes.
In the code below, m_TreeCtrl is a member variable of those derived classes and it is of CTreeCtrl data type, and CMyXxx can be any CFormView, CDialog, or CPropertyPage derived class.
BOOL CMyXxx::PreTranslateMessage(MSG* pMsg)
{
// If edit control is visible in tree view control, when you send a
// WM_KEYDOWN message to the edit control it will dismiss the edit
// control. When the ENTER key was sent to the edit control, the
// parent window of the tree view control is responsible for updating
// the item's label in TVN_ENDLABELEDIT notification code.
if (pMsg->message == WM_KEYDOWN &&
pMsg->wParam == VK_RETURN || pMsg->wParam == VK_ESCAPE)
{
CEdit* edit = m_TreeCtrl.GetEditControl();
if (edit)
{
edit->SendMessage(WM_KEYDOWN, pMsg->wParam, pMsg->lParam);
return TRUE;
}
}
// CXxxx can be a CFormView, Cdialog, or CPropertyPage class.
return CXxxx::PreTranslateMessage(pMsg);
}
For Visual C++ 2.xx, since PreTranslateMessage() is not called for modal CDialog-derived classes, the sample code above does not apply to the modal dialog and property page in a modal CPropertySheet derived class. In this situation, those keystroke messages can be trapped in the overridden OnOK() (for Enter key) and OnCancel() (for Esc key) functions in either CDialog or CPropertySheet derived-class. The sample code works fine even in the absence of both the OK and Cancel buttons from the dialog resource template.
NOTE: It is too late to trap those keystroke messages in CPropertyPage's OnOK() and OnCancel() functions. Therefore, we have to do it in CPropertySheet-derived class.
A new member function called IsTreeCtrlEditMessage() is added to the CDialog or CPropertySheet derived-class. This function sends a WM_KEYDOWN message to the tree-view's edit control when it is the window with focus. And it is being called in both overridden OnOK() and OnCancel() functions. The CMyDxxx in the sample code below can either be a CDialog or a CPropertySheet derived-class. Note that the MODAL_PROPERTYSHEET constant is declared and used in IsTreeCtrlEditMessage() so the same code can be applied to both CDialog and CPropertySheet derived-classes.
// Set MODAL_PROPERTYSHEET to 1 for modal CPropertySheet-derived class
// and 0 for CDialog-derived class.
#define MODAL_PROPERTYSHEET 1
BOOL CMyDxxx::IsTreeCtrlEditMessage(WPARAM KeyCode)
{
BOOL rvalue = FALSE;
// pWnd is a pointer to either an active CPropertyPage of the modal
// CPropertySheet or a modal CDialog object.
CWnd* pWnd = this;
#if MODAL_PROPERTYSHEET
pWnd = GetActivePage();
#endif
// IDC_TREECTRL is the ID of the tree view control.
CTreeCtrl *treectrl = (CTreeCtrl *) pWnd->GetDlgItem(IDC_TREECTRL);
if (!treectrl)
return rvalue;
// If the edit control of the tree view control has the input focus,
// sending a WM_KEYDOWN message to the edit control will dismiss the
// edit control. When ENTER key was sent to the edit control, the
// parentwindow of the tree view control is responsible for updating
// the item's label in TVN_ENDLABELEDIT notification code.
CWnd* focus = GetFocus();
CEdit* edit = treectrl->GetEditControl();
if ((CEdit *) focus == edit)
{
edit->SendMessage(WM_KEYDOWN, KeyCode);
rvalue = TRUE;
}
return rvalue;
}
void CMyDxxx::OnOK()
{
// Do not dismiss the dialog object if ENTER key was sent to the tree
// view's edit control. You may call the CDialog::OnOK() function if
// this is for CDialog.
if (!IsTreeCtrlEditMessage(VK_RETURN))
EndDialog(IDOK);
}
void CMyDxxx::OnCancel()
{
// Do not dismiss the dialog object if ESC key was sent to the tree
// view's edit control. You might call the CDialog::Cancel()
// function if this is for CDialog.
if (!IsTreeCtrlEditMessage(VK_ESCAPE))
EndDialog(IDCANCEL);
}
STATUS
Microsoft has confirmed this to be a bug in the Microsoft products listed at the beginning of this article.
MORE INFORMATION
For more information about CTreeCtrl, please refer to the MFC online help and Win32 SDK help files.
REFERENCES
For additional information, please see the following article in the Microsoft Knowledge Base:
Q130691 BUG: ESC/ENTER Keys Don't Work When Editing Labels in TreeView
(c) Microsoft Corporation 1997, All Rights Reserved. Contributions by Yeong-Kah Tam, Microsoft Corporation
© Microsoft Corporation 1997, All Rights Reserved.
Contributions by Yeong-Kah Tam, Microsoft Corporation
Additional query words:
Keywords : kbui kbMFC kbTreeView KbUIDesign kbVC kbVC200bug kbVC210bug kbVC220bug kbVC400bug kbVC410bug kbVC420bug kbVC500bug kbVC600bug kbGrpMFCATL
Version : winnt:2.0,2.1,2.2,4.0,4.0a,4.1,4.2,4.2b,5.0,6.0
Platform : winnt
Issue type : kbbug
Technology : kbvc
Last Reviewed: March 6, 2000
© 2000 Microsoft Corporation. All rights reserved. Terms of Use.
--------------------------------------------------------------------------------
Send feedback to MSDN.Look here for MSDN Online resources. Top
3 楼wkgenius()回复于 2001-12-14 18:55:34 得分 3
重载PreTranslateMessage函数,将WM_RETURN消息截获,然后发给那个控件。
或者直接将它的属性设为Default也行。Top
4 楼sgr0426()回复于 2001-12-14 19:19:54 得分 3
用subclassdlg(),可以解决你的类与资源相连系的问题Top
5 楼brows(眉头)回复于 2001-12-14 19:37:34 得分 0
多谢。
to ghz(浪子)/wkgenius:
在OnOK()或PreTranslateMessage(),里怎么知道当前是否在编辑treeitem?
怎么处理escape也是同样的问题。Top
6 楼wangao88(呆子)回复于 2001-12-14 19:39:14 得分 0
重载PreTranslateMessage函数,将WM_RETURN消息截获,然后发给那个控件。
或者直接将它的属性设为Default也行。 Top
7 楼bluecrest(高歌)回复于 2001-12-14 19:50:25 得分 3
在dialog相关的那个类中
把派生mytreectrl成员捆绑倒那个nid上
(在member variable标签下add variable)Top
8 楼brows(眉头)回复于 2001-12-14 20:13:48 得分 0
照jiangsheng(蒋晟)的例子解决了第一个问题。Top
9 楼woodswoods(woodswoods)回复于 2001-12-14 20:37:32 得分 0
1.去掉对话框中按钮的DEFAULT属性,敲回车就不会直接退出了.
2.先得到对话框的指针,然后得到树形控件的指针,不就可以了吗?
例如:
对话框为:CTestDlg; 树形控件为它的一个成员变量:CTreeCtrl *m_pTree;
调用时:CTestDlg dlg;
dlg.m_pTree;
Top
10 楼xiaoxiaohan(萧晓寒)回复于 2001-12-14 22:07:32 得分 0
重载OnOk.Top
11 楼brows(眉头)回复于 2001-12-19 14:03:23 得分 0
问题解决了,怎么给分啊?Top




