请告诉我在使用
IPrintDialogServices
获取和更改打印机设置时如何使用 IPrintDialogCallback::SelectionChange
界面。
我正在尝试使用这个构造,但我不明白如何初始化
IPrintDialogServices
:
struct PrintDialogCallback : public IPrintDialogCallback
{
public:
PrintDialogCallback()
{}
private:
virtual HRESULT STDMETHODCALLTYPE QueryInterface(REFIID riid, void **ppv) noexcept final {
if (riid == IID_IUnknown || riid == IID_IPrintDialogCallback) {
*ppv = static_cast<IPrintDialogCallback*>(this);
AddRef();
return S_OK;
}
*ppv = nullptr;
return E_NOINTERFACE;
}
virtual ULONG STDMETHODCALLTYPE AddRef() noexcept final {
return 1;
}
virtual ULONG STDMETHODCALLTYPE Release() noexcept final {
return 1;
}
virtual HRESULT STDMETHODCALLTYPE HandleMessage(HWND hDlg, UINT uMsg, WPARAM wParam, LPARAM lParam,
LRESULT *pResult) noexcept final {
return S_FALSE;
}
virtual HRESULT STDMETHODCALLTYPE InitDone() noexcept final {
return S_FALSE;
}
virtual HRESULT STDMETHODCALLTYPE SelectionChange() noexcept final {
IPrintDialogServices *pServices = nullptr;
// ? how to init pServices ?
if (pServices) {
wchar_t printerName[256] = {};
UINT psize = ARRAYSIZE(printerName);
HRESULT hr = pServices->GetCurrentPrinterName(printerName, &psize);
if (SUCCEEDED(hr)) {
wprintf(L"Selected printer: %s\n", printerName);
}
// Other settings
// DEVMODE *pDevMode = ...;
// UINT pcbSize = sizeof(DEVMODE);
// hr = pServices->GetCurrentDevMode(pDevMode, &pcbSize);
// if (SUCCEEDED(hr) && pDevMode) {
// wprintf(L"Printer paper size: %d\n", pDevMode->dmPaperSize);
// }
pServices->Release();
}
return S_FALSE;
}
};
PRINTDLGEX
文档:
lpCallback
类型:LPUNKNOWN
指向应用程序定义的回调对象的指针。
该对象应包含
类,以接收常规页面下部子对话框的消息。IPrintDialogCallback
回调对象还应包含
类,以接收指向IObjectWithSite
接口的指针。IPrintDialogServices
函数在PrintDlgEx
和IUnknown::QueryInterface
的回调对象上调用IID_IPrintDialogCallback
来确定哪个支持接口。IID_IObjectWithSite
如果您不想检索任何回调信息,请将
设置为 NULL。lpCallback
IPrintDialogCallback::InitDone()
文档:
接口,则IObjectWithSite
函数会调用PrintDlgEx
方法以将IObjectWithSite::SetSite
指针传递给回调对象。IPrintDialogServices
函数称为在调用PrintDlgEx
方法之前先调用IObjectWithSite::SetSite
方法。这使您的InitDone
实现能够使用InitDone
方法来检索有关当前所选打印机的信息。IPrintDialogServices
例如:
struct PrintDialogCallback : public IObjectWithSite, public IPrintDialogCallback
{
private:
IUnknown* m_Site = nullptr;
IPrintDialogServices* m_Services = nullptr;
public:
PrintDialogCallback() = default;
~PrintDialogCallback() { SetSite(nullptr); }
virtual HRESULT STDMETHODCALLTYPE QueryInterface(REFIID riid, void **ppv) noexcept final {
if (riid == IID_IUnknown) {
*ppv = static_cast<IUnknown*>(static_cast<IPrintDialogCallback*>(this));
AddRef();
return S_OK;
}
else if (riid == IID_IObjectWithSite) {
*ppv = static_cast<IObjectWithSite*>(this);
AddRef();
return S_OK;
}
else if (riid == IID_IPrintDialogCallback) {
*ppv = static_cast<IPrintDialogCallback*>(this);
AddRef();
return S_OK;
}
*ppv = nullptr;
return E_NOINTERFACE;
}
virtual ULONG STDMETHODCALLTYPE AddRef() noexcept final {
return 1;
}
virtual ULONG STDMETHODCALLTYPE Release() noexcept final {
return 1;
}
virtual HRESULT STDMETHODCALLTYPE GetSite(REFIID riid, void **ppvSite) noexcept final {
if (m_Site)
return m_Site->QueryInterface(riid, ppvSite);
*ppvSite = nullptr;
return E_NOINTERFACE;
}
virtual HRESULT STDMETHODCALLTYPE SetSite(IUnknown *pUnkSite) noexcept final {
if (m_Services) {
m_Services->Release();
m_Services = nullptr;
}
if (m_Site) {
m_Site->Release();
m_Site = nullptr;
}
if (pUnkSite) {
m_Site = pUnkSite;
m_Site->AddRef();
m_Site->QueryInterface(IID_PPV_ARGS(&m_Services));
}
return S_OK;
}
virtual HRESULT STDMETHODCALLTYPE HandleMessage(HWND hDlg, UINT uMsg, WPARAM wParam, LPARAM lParam,
LRESULT *pResult) noexcept final {
return S_FALSE;
}
virtual HRESULT STDMETHODCALLTYPE InitDone() noexcept final {
return S_FALSE;
}
virtual HRESULT STDMETHODCALLTYPE SelectionChange() noexcept final {
if (m_Services) {
wchar_t printerName[256] = {};
UINT psize = ARRAYSIZE(printerName);
HRESULT hr = m_Services->GetCurrentPrinterName(printerName, &psize);
if (SUCCEEDED(hr)) {
wprintf(L"Selected printer: %s\n", printerName);
}
// Other settings
// DEVMODE *pDevMode = ...;
// UINT pcbSize = sizeof(DEVMODE);
// hr = m_Services->GetCurrentDevMode(pDevMode, &pcbSize);
// if (SUCCEEDED(hr) && pDevMode) {
// wprintf(L"Printer paper size: %d\n", pDevMode->dmPaperSize);
// }
// ...
}
return S_FALSE;
}
};