閱讀英文

共用方式為


列印篩選中的異步通知

重要

新式列印平臺是 Windows 與印表機通訊的慣用方法。 我們建議您使用Microsoft的 IPP 收件匣類別驅動程式,以及列印支援應用程式 (PSA),自定義 Windows 10 和 11 中的列印體驗,以進行印表機裝置開發。

如需詳細資訊,請參閱 新式列印平臺列印支援應用程式設計指南

列印篩選管線具有異步通知功能,與應用程式列印後台處理程式中支援的異步通知非常類似。 Print spooler 中提供的 RouterCreatePrintAsyncNotificationChannel 函式無法列印篩選。 列印篩選必須使用 IPrintClassObjectFactory 介面來建立 IPrintAsyncNotify 物件。

本主題描述如何在列印篩選中使用異步通知功能。

v4 列印驅動程式模型中不支援從列印篩選擲回異步通知。

IPrintClassObjectFactory

IPrintClassObjectFactory 介面可讓您存取通知介面。 下列程式代碼範例說明篩選如何從屬性包取得這個介面。

// This interface is defined as a private member variable in the filter class
IPrintClassObjectFactory  *m_pPrintClassFactory;

// The following code goes in the IntializeFilter method of the filter
VARIANT var;
VariantInit(&var);

HRESULT hr = pIPropertyBag->GetProperty(
    XPS_FP_PRINT_CLASS_FACTORY,
    &var);

if (SUCCEEDED(hr))
{
    hr = V_UNKNOWN(&var)->QueryInterface(
 IID_IPrintClassObjectFactory,
 reinterpret_cast<void **>(&m_pPrintClassFactory));
}

通知通道

使用 IPrintClassObjectFactory 介面,根據篩選的需求,篩選條件可以建立單向或雙向通知通道。 下列程式代碼範例會從上述範例繼續進行,並示範篩選如何建立單向通知通道。

// Create a unidirectional notification channel
IPrintAsyncNotifyChannel  *pIAsyncNotifyChannel;
IPrintAsyncNotify  *pIAsyncNotify;

HRESULT hr = m_pPrintClassFactory->GetPrintClassObject(
 m_bstrPrinter,      // The printer name that was read from the property bag
 IID_IPrintAsyncNotify,
 reinterpret_cast<void**>(&pIAsyncNotify)));

if (SUCCEEDED(hr))
{
    hr = pIAsyncNotify->CreatePrintAsyncNotifyChannel(
 m_jobId,
 const_cast<GUID*>(&MS_ASYNCNOTIFY_UI),
 kPerUser,
 kUniDirectional,
        NULL,
        &pIAsyncNotifyChannel));

   // etc...
}

若要建立雙向通知通道,您可以使用下列程式代碼範例取代上述範例。

// Create a bidirectional notification channel
IPrintAsyncNotifyChannel *pIAsyncNotifyChannel;
IPrintAsyncNotify *pIAsyncNotify;

HRESULT hr = m_pPrintClassFactory->GetPrintClassObject(
 m_bstrPrinterName,   // The printer name that was read from the property bag
 IID_IPrintAsyncNotify,
 reinterpret_cast<void**>(&pIAsyncNotify)));

if (SUCCEEDED(hr))
{
    hr = pIAsyncNotify->CreatePrintAsyncNotifyChannel(
 m_jobId,
 const_cast<GUID*>(& SAMPLE_ASYNCNOTIFY_UI),
 kPerUser,
 kBiDirectional,
 pIAsyncCallback,
        &pIAsyncNotifyChannel));

    // etc...
}

在上述程式代碼範例中,variable pIAsyncCallback 是呼叫端實作 IPrintAsyncNotifyCallback 介面的指標。

在某些情況下,當您完成時,您必須發行雙向通知通道。 若要這樣做,請在 IPrintAsyncNotifyChannel呼叫 Release 方法。 如需何時發行通道的資訊,請參閱 通知通道

模擬和通知

篩選條件在呼叫 IPrintAsyncNotify::CreatePrintAsyncNotifyChannel 方法時,不得模擬用戶帳戶。 列印後台處理程式中的授權機制需要從本地服務帳戶呼叫它。 如果篩選必須模擬提交作業之使用者的帳戶,篩選必須還原為本身,才能呼叫 CreatePrintAsyncNotifyChannel。 呼叫傳回之後,篩選條件可以在必要時還原回用戶帳戶。

即使在本機服務內容中發出通知呼叫,kPerUser 通知仍會傳送給根據作業標識碼的使用者關聯提交作業的使用者。

調整 WDK 範例程式代碼

您可以將 RouterCreatePrintAsyncNotificationChannel 呼叫取代為下列程式代碼範例,從 WDK 範例程式代碼調整通知範例,以在列印篩選中運作。

IPrintAsyncNotify  *pIAsyncNotify;

HRESULT hr = m_pPrintClassFactory->GetPrintClassObject(
 m_bstrPrinterName,      // get it from the property bag
 IID_IPrintAsyncNotify,
 reinterpret_cast<void**>(&pIAsyncNotify)));

if (SUCCEEDED(hr))
{
    hr = pIAsyncNotify->CreatePrintAsyncNotifyChannel(
 // the same arguments as for
 // RouterCreatePrintAsyncNotificationChannel
        );

    // etc...
}