DoDataExchange整理

CWnd::DoDataExchange是一个虚拟函数,用于对话框数据的交换和验证。该函数由UpdateData调用,不应直接调用。在自定义对话框类中重载此函数可以利用框架的自动数据交换和验证功能。ClassWizard可以帮助生成包含DDX和DDV调用的重载版本。在某些情况下,如动态生成的对话框,初始化代码可以放在DoDataExchange中,或者可以通过重载OnInitDialog来实现。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

CWnd::DoDataExchange
virtual void DoDataExchange( CDataExchange* pDX );
参数: pDX 指向CDataExchange对象的指针。 

框架调用这个函数以交换并校验对话框数据。
永远不要直接调用这个函数。它是由UpdateData成员函数所调用的。可调用UpdateData函数以初始化对话框控件或从对话框获取数据。
当你从CDialog继承应用程序特有的对话框类时,如果你想要利用框架的自动数据交换和校验功能,你需要重载这个成员函数。ClassWizard将为你编写这个成员函数的重载版本,包含了对话框数据交换(DDX)和校验(DDV)全局函数调用所需的“数据映射”。
要自动生成这个函数的重载版本,首先用对话框编辑器创建一个对话框资源,然后继承一个应用程序特有的对话框类。然后调用ClassWizard并用它来把变量、数据和校验范围与新对话框的不同控件关联起来。ClassWizard将写入重载的DoDataExchange,其中包含了数据映射。
// MyDialog.cpp: 实现文件 // #include "pch.h" #include "Z3MFCLibrary.h" #include "afxdialogex.h" #include "MyDialog.h" #include "zwapi_file.h" #include "VxApi.h" #include <windows.h> #include <tlhelp32.h> #include <oaidl.h> #include <comdef.h> #include <ocidl.h> // 实现CreateClassEnumerator函数(解决链接错误) HRESULT __stdcall CreateClassEnumerator(REFCLSID clsid, IEnumMoniker** ppenum, DWORD dwFlags) { if (ppenum == nullptr) return E_INVALIDARG; *ppenum = nullptr; // 创建系统类枚举器 IEnumMoniker* pEnum = nullptr; HRESULT hr = CoCreateInstance(CLSID_SystemDeviceEnum, nullptr, CLSCTX_INPROC_SERVER, IID_IEnumMoniker, (void**)&pEnum); if (FAILED(hr)) return hr; // 创建类枚举器 hr = pEnum->EnumClassesOfCategories(1, &clsid, 0, nullptr, ppenum); pEnum->Release(); return hr; } IMPLEMENT_DYNAMIC(MyDialog, CDialogEx) MyDialog::MyDialog(CWnd* pParent /*=nullptr*/) : CDialogEx(IDD_DIALOG1, pParent) { } MyDialog::~MyDialog() { } void MyDialog::DoDataExchange(CDataExchange* pDX) { CDialogEx::DoDataExchange(pDX); DDX_Control(pDX, IDC_BUTTON1, m_btn_export_import); DDX_Control(pDX, IDC_COMBO1, m_cmbPMWindows); } BEGIN_MESSAGE_MAP(MyDialog, CDialogEx) ON_BN_CLICKED(IDC_BUTTON1, &MyDialog::OnBnClickedExportAndImport) END_MESSAGE_MAP() // 对话框初始化 BOOL MyDialog::OnInitDialog() { CDialogEx::OnInitDialog(); RefreshPMInstances(); // 初始化时加载所有PowerMill实例 return TRUE; } // 枚举PowerMill窗口的回调函数(静态成员函数) BOOL CALLBACK MyDialog::EnumPMWindowsProc(HWND hwnd, LPARAM lParam) { // 获取参数(实例信息向量的指针) std::vector<PMInstanceInfo>* pInstances = reinterpret_cast<std::vector<PMInstanceInfo>*>(lParam); if (!pInstances) return TRUE; // 检查窗口是否可见(使用全局API) if (!::IsWindowVisible(hwnd)) return TRUE; // 获取窗口标题(使用全局API) TCHAR szTitle[256] = { 0 }; ::GetWindowText(hwnd, szTitle, 255); CString title = szTitle; // 筛选标题包含"PowerMill"的窗口 if (title.Find(_T("PowerMill")) == -1) return TRUE; // 获取进程ID(使用全局API) DWORD processId = 0; ::GetWindowThreadProcessId(hwnd, &processId); if (processId == 0) return TRUE; // 添加到实例列表 PMInstanceInfo info; info.index = pInstances->size() + 1; // 序号从1开始 info.processId = processId; info.hwnd = hwnd; info.title = title; pInstances->push_back(info); return TRUE; } // 刷新PowerMill实例列表(显示序号和进程ID) void MyDialog::RefreshPMInstances() { m_pmInstances.clear(); m_cmbPMWindows.ResetContent(); // 枚举所有PowerMill窗口 ::EnumWindows(EnumPMWindowsProc, reinterpret_cast<LPARAM>(&m_pmInstances)); // 添加到组合框(格式:序号 - PID:进程ID - 标题) for (const auto& info : m_pmInstances) { CString itemText; itemText.Format(_T("%d - PID:%d - %s"), info.index, info.processId, info.title.Left(30)); // 限制标题长度 m_cmbPMWindows.AddString(itemText); } // 默认选中第一个实例 if (m_pmInstances.size() > 0) { m_cmbPMWindows.SetCurSel(0); } } // 通过进程ID获取对应的PowerMill COM接口 IDispatch* MyDialog::GetPMInstanceByPID(DWORD pid) { // 初始化COM HRESULT hr = CoInitializeEx(NULL, COINIT_APARTMENTTHREADED); if (FAILED(hr)) return nullptr; // 获取PowerMill的CLSID CLSID clsid; hr = CLSIDFromProgID(L"PowerMILL.Application", &clsid); if (FAILED(hr)) { CoUninitialize(); return nullptr; } // 枚举所有正在运行的PowerMill实例 IEnumMoniker* pEnumMoniker = nullptr; hr = CreateClassEnumerator(clsid, &pEnumMoniker, 0); if (FAILED(hr) || !pEnumMoniker) { CoUninitialize(); return nullptr; } IMoniker* pMoniker = nullptr; IDispatch* pPMApp = nullptr; ULONG fetched = 0; // 遍历所有实例,匹配进程ID while (pEnumMoniker->Next(1, &pMoniker, &fetched) == S_OK) { // 获取实例的进程ID DWORD instancePid = 0; IBindCtx* pBindCtx = nullptr; if (CreateBindCtx(0, &pBindCtx) == S_OK) { ULONG len = 0; LPOLESTR displayName = nullptr; if (pMoniker->GetDisplayName(pBindCtx, nullptr, &displayName) == S_OK) { // 从显示名称中提取进程ID(格式类似"PowerMILL.Application.19:1234") CString displayStr(displayName); int colonPos = displayStr.ReverseFind(':'); if (colonPos != -1) { CString pidStr = displayStr.Mid(colonPos + 1); instancePid = _ttoi(pidStr); } SysFreeString(displayName); } pBindCtx->Release(); } // 匹配目标进程ID if (instancePid == pid) { // 获取该实例的COM接口 hr = pMoniker->BindToObject(nullptr, nullptr, IID_IDispatch, (void**)&pPMApp); if (SUCCEEDED(hr)) { pMoniker->Release(); break; } } pMoniker->Release(); } pEnumMoniker->Release(); CoUninitialize(); return pPMApp; } // 导出X_T文件 bool MyDialog::ExportXtFile(CString& filePath) { filePath = _T("C:\\Users\\Administrator\\Desktop\\Test.x_t"); svxPARAData exportData; evxErrors result = cvxFileExportInit(VX_EXPORT_TYPE_PARA_TEXT, 0, &exportData); if (result != ZW_API_NO_ERROR) { AfxMessageBox(_T("初始化导出参数失败!"), MB_OK | MB_ICONERROR); return false; } exportData.Coordinate = 0; exportData.OutPut = 1; exportData.FileVer = 19; exportData.WriteFreeCrv = TRUE; exportData.WriteFreePnt = FALSE; exportData.HealErr = FALSE; exportData.ExportType = 0; exportData.ExcludeGeom = VX_EXCLUDE_BLANKED; result = cvxFileExport(VX_EXPORT_TYPE_PARA_TEXT, (LPCSTR)CStringA(filePath), &exportData); if (result != ZW_API_NO_ERROR) { CString errMsg; errMsg.Format(_T("X_T文件导出失败!错误代码: %d"), result); AfxMessageBox(errMsg, MB_OK | MB_ICONERROR); return false; } return true; } // 导入到选定的PowerMill实例 bool MyDialog::ImportToPowerMill(const CString& filePath) { // 检查文件是否存在 if (_taccess(filePath, 0) == -1) { AfxMessageBox(_T("X_T文件不存在!"), MB_OK | MB_ICONERROR); return false; } // 检查是否有选中的实例 int selectedIndex = m_cmbPMWindows.GetCurSel(); if (selectedIndex == CB_ERR || m_pmInstances.empty()) { AfxMessageBox(_T("请先选择一个运行中的PowerMill实例!"), MB_OK | MB_ICONERROR); return false; } // 获取选中实例的进程ID DWORD targetPid = m_pmInstances[selectedIndex].processId; // 获取对应实例的COM接口 IDispatch* pPMApp = GetPMInstanceByPID(targetPid); if (!pPMApp) { AfxMessageBox(_T("无法连接到选中的PowerMill实例!"), MB_OK | MB_ICONERROR); return false; } // 执行导入命令 bool success = false; try { // 构造命令 CString command; command.Format(_T("FORM RIBBON BACKSTAGE CLOSE IMPORT MODEL FILEOPEN \"%s\""), filePath); // 获取命令执行方法ID(尝试常见方法名) DISPID dispid; LPOLESTR methodNames[] = { L"DoCommand", L"ExecuteCommand", L"RunCommand" }; HRESULT hr = E_FAIL; for (auto methodName : methodNames) { hr = pPMApp->GetIDsOfNames(IID_NULL, &methodName, 1, LOCALE_SYSTEM_DEFAULT, &dispid); if (SUCCEEDED(hr)) break; } if (FAILED(hr)) { throw _T("未找到可用的命令执行方法(DoCommand/ExecuteCommand/RunCommand)"); } // 准备参数 VARIANT varArg; VariantInit(&varArg); varArg.vt = VT_BSTR; varArg.bstrVal = SysAllocString(command); DISPPARAMS dispParams = { &varArg, NULL, 1, 0 }; VARIANT result; VariantInit(&result); // 执行命令 hr = pPMApp->Invoke(dispid, IID_NULL, LOCALE_SYSTEM_DEFAULT, DISPATCH_METHOD, &dispParams, &result, NULL, NULL); if (FAILED(hr)) { throw _T("命令执行失败,可能是命令格式错误"); } success = true; VariantClear(&varArg); VariantClear(&result); } catch (LPCTSTR errMsg) { CString msg; msg.Format(_T("导入失败:%s\n实例PID: %d"), errMsg, targetPid); AfxMessageBox(msg, MB_OK | MB_ICONERROR); } // 释放资源 if (pPMApp) { pPMApp->Release(); } return success; } // 按钮点击事件 void MyDialog::OnBnClickedExportAndImport() { // 刷新实例列表(确保最新) RefreshPMInstances(); // 检查是否有PowerMill实例在运行 if (m_pmInstances.empty()) { AfxMessageBox(_T("未检测到运行中的PowerMill实例!"), MB_OK | MB_ICONERROR); return; } // 导出X_T文件 CString xtFilePath; if (!ExportXtFile(xtFilePath)) { return; } // 导入到选定的PowerMill实例 if (ImportToPowerMill(xtFilePath)) { CString msg; msg.Format(_T("操作完成!\n已导入到PowerMill实例(PID: %d)"), m_pmInstances[m_cmbPMWindows.GetCurSel()].processId); AfxMessageBox(msg, MB_OK | MB_ICONINFORMATION); } } 严重性 代码 说明 项目 文件 行 抑制状态 详细信息 错误 C2039 "EnumClassesOfCategories": 不是 "IEnumMoniker" 的成员 Z3MFCLibrary C:\Users\Administrator\Desktop\Z3MFCLibrary\MyDialog.cpp 32 错误 C2065 “CLSID_SystemDeviceEnum”: 未声明的标识符 Z3MFCLibrary C:\Users\Administrator\Desktop\Z3MFCLibrary\MyDialog.cpp 26 错误(活动) E0020 未定义标识符 "CLSID_SystemDeviceEnum" Z3MFCLibrary C:\Users\Administrator\Desktop\Z3MFCLibrary\MyDialog.cpp 26 错误(活动) E0135 类 "IEnumMoniker" 没有成员 "EnumClassesOfCategories" Z3MFCLibrary C:\Users\Administrator\Desktop\Z3MFCLibrary\MyDialog.cpp 32
最新发布
08-20
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值