MFC的DDX失效问题

      以前发生过ddx突然失效的现象,后来解决了,最近又碰到了,后来查了资料才想起来问题所在。

      以前ddx变量是放在别的对话框里的(因为做的是单文档程序),当按了ok或cancel后,系统自动调用了updatedata这个函数。所以,当我们做基于对话框的程序并在源对话框里使用ddx变量时,需要在之前先UpdateData(TRUE)一下。

 

2008.8.28

转载于:https://www.cnblogs.com/zj27sWizardTower/archive/2009/06/09/1499628.html

<think>嗯,用户这次问的是MFC中Edit Control的使用方法,结合之前提供的站内引用来看,用户似乎对控件变量绑定和头文件引用有些混淆。用户可能是个刚开始接触MFC开发的程序员,手头正在处理一个带编辑框的对话框程序。 从引用[1]可以看出用户注意到了DDX_Control这个关键宏,但可能没完全理解其机制。引用[2]则暴露出用户对extern关键字的困惑,这提示我回答时要特别注意变量作用域的问题。用户上次的问题被系统引用打断了,这次需要完整梳理Edit Control的使用链条。 我打算从四个维度展开:首先是控件创建,毕竟这是物理基础;接着重点讲控件变量绑定的两种方式,这里要强调DDX_Control和手动Subclass的区别;然后覆盖常用操作如文本读写,这部分示例代码要足够典型;最后补充滚动条和验证等进阶技巧。用户提到的extern问题其实属于变量声明范畴,我会在变量绑定部分用代码注释特别说明。 注意到用户截取的引用里提到"调试和性能优化工具",可能暗示后续会问性能问题,所以我在相关问题里埋了个编辑框优化的伏笔。另外用户两次都提到资源编辑器,回答时要强调可视化操作的优势,毕竟这是MFC的特色。 对了,示例代码得用中文注释,虽然原文是英文术语但用户显然需要母语解释。变量命名就用m_editExample这样带匈牙利命名法的,既符合MFC习惯又能让用户看清类型关联。滚动条那个WM_VSCROLL消息很容易被新手忽略,必须包含进去。 </think>以下是MFC中Edit Control(编辑控件)的完整使用指南,涵盖核心操作和最佳实践: --- ### **一、基础使用方法** #### 1. **创建Edit Control** - **资源视图创建** 在对话框资源编辑器中拖放Edit Control控件,右键设置属性: - `ID`: 如`IDC_EDIT_INPUT` - `Multiline`: 多行文本支持 - `Want return`: 允许回车换行 - `Vertical scroll`: 添加垂直滚动条 - **代码动态创建** ```cpp CEdit* pEdit = new CEdit(); pEdit->Create(WS_CHILD | WS_VISIBLE | WS_BORDER | ES_MULTILINE, CRect(10, 10, 200, 100), this, IDC_EDIT_DYNAMIC); ``` #### 2. **关联控件变量** - **DDX控件变量绑定**(推荐) 在对话框类头文件中声明变量: ```cpp class CMyDialog : public CDialogEx { // ... CEdit m_editCtrl; // 控件对象 CString m_strText; // 值变量(用于文本存取) }; ``` 在`.cpp`文件中初始化绑定: ```cpp void CMyDialog::DoDataExchange(CDataExchange* pDX) { CDialogEx::DoDataExchange(pDX); DDX_Control(pDX, IDC_EDIT_INPUT, m_editCtrl); // 绑定控件对象 DDX_Text(pDX, IDC_EDIT_INPUT, m_strText); // 绑定文本值变量 } ``` #### 3. **常用操作示例** ```cpp // 设置文本 m_editCtrl.SetWindowTextW(_T("Hello MFC")); // 获取文本 CString strContent; m_editCtrl.GetWindowTextW(strContent); // 限制输入长度(在OnInitDialog中调用) m_editCtrl.SetLimitText(100); // 设为只读 m_editCtrl.SetReadOnly(TRUE); // 滚动到最后一行(多行编辑框) m_editCtrl.LineScroll(m_editCtrl.GetLineCount()); ``` --- ### **二、进阶功能** #### 1. **响应编辑框事件** - **添加消息处理**(如内容修改响应): ```cpp BEGIN_MESSAGE_MAP(CMyDialog, CDialogEx) ON_EN_CHANGE(IDC_EDIT_INPUT, &CMyDialog::OnEnChangeEditInput) END_MESSAGE_MAP() void CMyDialog::OnEnChangeEditInput() { // 实时处理文本变化 UpdateData(TRUE); // 更新m_strText的值 MessageBox(m_strText, _T("当前输入")); } ``` #### 2. **验证输入内容** ```cpp void CMyDialog::OnOK() { UpdateData(TRUE); // 将控件数据更新到变量 if (m_strText.IsEmpty()) { MessageBox(_T("输入不能为空!"), _T("错误"), MB_ICONERROR); m_editCtrl.SetFocus(); // 焦点返回编辑框 return; } CDialogEx::OnOK(); } ``` #### 3. **自定义格式** ```cpp // 设置字体 CFont font; font.CreatePointFont(120, _T("Arial")); m_editCtrl.SetFont(&font); // 文本颜色(需重写OnCtlColor) HBRUSH CMyDialog::OnCtlColor(CDC* pDC, CWnd* pWnd, UINT nCtlColor) { if (pWnd->GetDlgCtrlID() == IDC_EDIT_INPUT) { pDC->SetTextColor(RGB(255, 0, 0)); // 红色文本 return (HBRUSH)GetStockObject(WHITE_BRUSH); } return CDialogEx::OnCtlColor(pDC, pWnd, nCtlColor); } ``` --- ### **三、关键注意事项** 1. **多线程安全** 禁止在非UI线程直接操作Edit Control,需用`PostMessage`传递消息: ```cpp ::PostMessage(m_editCtrl.GetSafeHwnd(), WM_SETTEXT, 0, (LPARAM)_T("线程安全更新")); ``` 2. **内存管理** 动态创建的`CEdit`对象需在对话框析构时手动销毁: ```cpp CMyDialog::~CMyDialog() { if (m_pEditDynamic) delete m_pEditDynamic; } ``` 3. **焦点控制** ```cpp m_editCtrl.SetFocus(); // 设置焦点 m_editCtrl.SetSel(0, -1, TRUE); // 全选文本 ``` --- ### **四、典型问题解决** - **问题:无法更新文本变量** **解决方案**:确保在数据交换前调用`UpdateData(TRUE)`。 - **问题:多行编辑框回车无效** **解决方案**:在资源视图中启用`Want return`属性。 - **问题:输入长度限制失效** **验证**:检查是否在`OnInitDialog()`之后调用`SetLimitText()`。 ---
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值