admin管理员组文章数量:1122846
Tell me please how to use IPrintDialogServices
interface when using IPrintDialogCallback::SelectionChange
to get and change printer settings.
I'm trying to use this construct, but I don't understand how to initialize the 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;
}
};
UPDATE
Please tell me how to change the duplex mode for the selected printer?
I'm trying to use this construct but it is not working:
struct PrintDialogCallback : public IPrintDialogCallback, public IObjectWithSite
{
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;
} else
if (riid == IID_IObjectWithSite) {
*ppv = static_cast<IObjectWithSite*>(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 {
if (m_pServices) {
WCHAR printerName[MAX_PATH];
UINT nameLen = ARRAYSIZE(printerName);
if (SUCCEEDED(m_pServices->GetCurrentPrinterName(printerName, &nameLen)) && nameLen > 0) {
HANDLE hPrinter = NULL;
if (OpenPrinter(printerName, &hPrinter, NULL)) {
UINT devModeSize = 0;
if (SUCCEEDED(m_pServices->GetCurrentDevMode(nullptr, &devModeSize)) && devModeSize > 0) {
HGLOBAL hDevMode = GlobalAlloc(GHND, devModeSize);
LPDEVMODE pDevMode = (LPDEVMODE)GlobalLock(hDevMode);
if (SUCCEEDED(m_pServices->GetCurrentDevMode(pDevMode, &devModeSize))) {
if (pDevMode->dmFields & DM_DUPLEX) {
pDevMode->dmDuplex = DMDUP_VERTICAL;
LONG res = DocumentProperties(NULL, hPrinter, printerName, pDevMode, pDevMode, DM_IN_BUFFER | DM_OUT_BUFFER);
}
}
GlobalUnlock(hDevMode);
GlobalFree(hDevMode);
}
ClosePrinter(hPrinter);
}
}
}
return S_FALSE;
}
virtual HRESULT STDMETHODCALLTYPE SetSite(IUnknown *pSite) noexcept final {
if (m_pServices) {
m_pServices->Release();
m_pServices = nullptr;
}
if (m_pSite) {
m_pSite->Release();
m_pSite = nullptr;
}
if (pSite) {
m_pSite = pSite;
m_pSite->AddRef();
m_pSite->QueryInterface(IID_PPV_ARGS(&m_pServices));
}
return S_OK;
}
virtual HRESULT STDMETHODCALLTYPE GetSite(REFIID riid, void **ppvSite) noexcept final {
if (m_pSite)
return m_pSite->QueryInterface(riid, ppvSite);
*ppvSite = nullptr;
return E_NOINTERFACE;
}
IUnknown *m_pSite = nullptr;
IPrintDialogServices* m_pServices = nullptr;
};
Tell me please how to use IPrintDialogServices
interface when using IPrintDialogCallback::SelectionChange
to get and change printer settings.
I'm trying to use this construct, but I don't understand how to initialize the 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;
}
};
UPDATE
Please tell me how to change the duplex mode for the selected printer?
I'm trying to use this construct but it is not working:
struct PrintDialogCallback : public IPrintDialogCallback, public IObjectWithSite
{
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;
} else
if (riid == IID_IObjectWithSite) {
*ppv = static_cast<IObjectWithSite*>(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 {
if (m_pServices) {
WCHAR printerName[MAX_PATH];
UINT nameLen = ARRAYSIZE(printerName);
if (SUCCEEDED(m_pServices->GetCurrentPrinterName(printerName, &nameLen)) && nameLen > 0) {
HANDLE hPrinter = NULL;
if (OpenPrinter(printerName, &hPrinter, NULL)) {
UINT devModeSize = 0;
if (SUCCEEDED(m_pServices->GetCurrentDevMode(nullptr, &devModeSize)) && devModeSize > 0) {
HGLOBAL hDevMode = GlobalAlloc(GHND, devModeSize);
LPDEVMODE pDevMode = (LPDEVMODE)GlobalLock(hDevMode);
if (SUCCEEDED(m_pServices->GetCurrentDevMode(pDevMode, &devModeSize))) {
if (pDevMode->dmFields & DM_DUPLEX) {
pDevMode->dmDuplex = DMDUP_VERTICAL;
LONG res = DocumentProperties(NULL, hPrinter, printerName, pDevMode, pDevMode, DM_IN_BUFFER | DM_OUT_BUFFER);
}
}
GlobalUnlock(hDevMode);
GlobalFree(hDevMode);
}
ClosePrinter(hPrinter);
}
}
}
return S_FALSE;
}
virtual HRESULT STDMETHODCALLTYPE SetSite(IUnknown *pSite) noexcept final {
if (m_pServices) {
m_pServices->Release();
m_pServices = nullptr;
}
if (m_pSite) {
m_pSite->Release();
m_pSite = nullptr;
}
if (pSite) {
m_pSite = pSite;
m_pSite->AddRef();
m_pSite->QueryInterface(IID_PPV_ARGS(&m_pServices));
}
return S_OK;
}
virtual HRESULT STDMETHODCALLTYPE GetSite(REFIID riid, void **ppvSite) noexcept final {
if (m_pSite)
return m_pSite->QueryInterface(riid, ppvSite);
*ppvSite = nullptr;
return E_NOINTERFACE;
}
IUnknown *m_pSite = nullptr;
IPrintDialogServices* m_pServices = nullptr;
};
Share
Improve this question
edited Nov 27, 2024 at 16:21
Remy Lebeau
594k34 gold badges495 silver badges834 bronze badges
asked Nov 22, 2024 at 13:41
Helg1980Helg1980
1291 silver badge10 bronze badges
1
|
1 Answer
Reset to default 2Per the PRINTDLGEX
documentation:
lpCallback
Type: LPUNKNOWN
A pointer to an application-defined callback object.
The object should contain the
IPrintDialogCallback
class to receive messages for the child dialog box in the lower portion of the General page.The callback object should also contain the
IObjectWithSite
class to receive a pointer to theIPrintDialogServices
interface. ThePrintDlgEx
function callsIUnknown::QueryInterface
on the callback object for bothIID_IPrintDialogCallback
andIID_IObjectWithSite
to determine which interfaces are supported.If you do not want to retrieve any of the callback information, set
lpCallback
to NULL.
And per the IPrintDialogCallback::InitDone()
documentation:
If your callback object implements the
IObjectWithSite
interface, thePrintDlgEx
function calls theIObjectWithSite::SetSite
method to pass anIPrintDialogServices
pointer to the callback object. ThePrintDlgEx
function calls theIObjectWithSite::SetSite
method before calling theInitDone
method. This enables yourInitDone
implementation to use theIPrintDialogServices
methods to retrieve information about the currently selected printer.
For example:
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;
}
};
本文标签:
版权声明:本文标题:c++ - How to use IPrintDialogServices interface when using IPrintDialogCallback::SelectionChange() to get and change printer set 内容由网友自发贡献,该文观点仅代表作者本人, 转载请联系作者并注明出处:http://www.betaflare.com/web/1736303447a1931890.html, 本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌抄袭侵权/违法违规的内容,一经查实,本站将立刻删除。
SelectionChange
method is a notification callback. You are not supposed to make changes from there. Regardless, the documentation forInitDone
explains when and how to get to anIPrintDialogServices
interface. – IInspectable Commented Nov 22, 2024 at 14:51