【发布时间】:2010-10-01 16:58:23
【问题描述】:
我正在显示一个 CPrintDialogEx 对话框来选择打印机并修改设置。我设置了 hDevNames 成员,以便选择默认打印机,但我将 hDevMode 设置为 NULL。成功返回时,我从 hDevMode 中提取返回的 DEVMODE 结构中的一些值,例如纸张大小。
我遇到了问题,因为 hDevMode 似乎是使用我传入的默认打印机的值进行初始化的,而不是最终选择的打印机。如何从实际选择的打印机中获取参数?
根据要求,这里是代码的相关部分。为了空间,我已经删除了一些。 TOwnedHandle 是我编写的一个智能指针,用于持有内存句柄并自动锁定它。
CPrintDialogEx dlg(PD_ALLPAGES | PD_NOCURRENTPAGE | PD_NOPAGENUMS | PD_NOSELECTION, this);
ASSERT(dlg.m_pdex.hDevMode == NULL);
ASSERT(dlg.m_pdex.hDevNames == NULL);
dlg.m_pdex.hDevNames = GlobalAlloc(GHND, sizeof(DEVNAMES) + iSizeName);
DEVNAMES * pDevNames = (DEVNAMES *) GlobalLock(dlg.m_pdex.hDevNames);
// ...
GlobalUnlock(dlg.m_pdex.hDevNames);
if ((dlg.DoModal() == S_OK) && (dlg.m_pdex.dwResultAction == PD_RESULT_PRINT))
{
TOwnedHandle<DEVMODE> pDevMode = dlg.m_pdex.hDevMode;
TRACE("Printer config = %dx%d %d\n", (int)pDevMode->dmPaperWidth, (int)pDevMode->dmPaperLength, (int)pDevMode->dmOrientation);
// ...
}
编辑:我确定如果我不设置 hDevNames 参数就不会出现问题。我想知道我是否发现了一个 Windows 错误?这是在 XP 中,我没有更新版本的 Windows 方便测试。
我已经将代码提炼成一个不使用 MFC 的测试,这严格来说是一个 Windows API 问题。这就是全部内容,除了 pDefaultPrinter 的定义之外没有遗漏任何内容 - 但当然它不再做任何有用的事情了。
PRINTDLGEX ex = {sizeof(PRINTDLGEX)};
ex.hwndOwner = m_hWnd;
ex.Flags = PD_ALLPAGES | PD_NOCURRENTPAGE | PD_NOPAGENUMS | PD_NOSELECTION;
ex.nStartPage = START_PAGE_GENERAL;
#if 1
int iSizeName = (strlen(pDefaultPrinter) + 1) * sizeof(char);
ex.hDevNames = GlobalAlloc(GHND, sizeof(DEVNAMES) + iSizeName);
DEVNAMES * pDevNames = (DEVNAMES *) GlobalLock(ex.hDevNames);
ASSERT(pDevNames != NULL);
pDevNames->wDeviceOffset = sizeof(DEVNAMES);
strcpy((char *)pDevNames + pDevNames->wDeviceOffset, pDefaultPrinter);
GlobalUnlock(ex.hDevNames);
#endif
HRESULT hr = PrintDlgEx(&ex);
if ((hr == S_OK) && (ex.dwResultAction == PD_RESULT_PRINT))
{
DEVMODE * pdm = (DEVMODE *) GlobalLock(ex.hDevMode);
ASSERT(pdm != NULL);
TRACE("Printer config = %dx%d %d\n", (int)pdm->dmPaperWidth, (int)pdm->dmPaperLength, (int)pdm->dmOrientation);
GlobalUnlock(ex.hDevMode);
DEVNAMES * pdn = (DEVNAMES *) GlobalLock(ex.hDevNames);
ASSERT(pdn != NULL);
TRACE(_T("Printer device = %s\n"), (char *)pdn + pdn->wDeviceOffset);
GlobalUnlock(ex.hDevNames);
}
如果我无法解决问题,我很想听听解决方法。
【问题讨论】:
-
很难出错。发布显示 DoModal 和 GetDevMode 的代码。
-
不错的收获...很难被发现。