共用方式為


安裝列印處理器

若要安裝列印處理器,安裝應用程式必須呼叫多任務緩衝處理程式的 AddPrintProcessor 函 式。 若要建立列印處理器與列印佇列的關聯,請在 PrintProcessor 專案中的 INF 檔案中列出其檔名。 每個要與列印處理器相關聯的列印佇列都必須包含這個專案。 如需詳細資訊,請參閱 印表機 INF 檔案

當安裝應用程式呼叫多任務緩衝處理器的 AddPrinter 函式時,使用 {PRINTER_INFO_2] ( /windows/win32/printdocs/printer-info-2) 結構作為輸入自變數,它會指定從 INF 檔案取得 (的列印處理器名稱) 做為結構成員。

將列印處理器與已安裝 pnp 的列印佇列建立關聯

如果 隨插即用 (PnP) 管理員偵測並安裝執行 Windows 2000 或 Windows XP 之系統上的列印佇列,而且用來安裝列印佇列的 INF 檔案包含預設 Windows 列印處理器 WinPrint 以外的 PrintProcessor 專案,列印處理器將不會與列印佇列相關聯。 不過,將會安裝列印處理器。

請注意,如果您使用 [新增印表機精靈] 安裝列印佇列,列印處理器就會正確地與列印佇列相關聯。

另請注意,Microsoft Windows Server 2003 和更新版本中的 PnP 管理員會正確地將列印處理器與列印佇列產生關聯。

若要將列印處理器與在 Windows 2000 和 Windows XP 上安裝 隨插即用 的列印佇列產生關聯,請在印表機介面 DLL 的 DrvPrinterEvent 函式中包含PRINTER_EVENT_INITIALIZE案例。 對於 Microsoft Windows Server 2003 和更新版本,不需要在 DrvPrinterEvent 函式中新增PRINTER_EVENT_INITIALIZE案例。

下列程式代碼範例會將 PRINTER_INFO_2 結構的 pPrintProcessor 成員設定為列印處理器的名稱,然後呼叫 SetPrinter 函式來更新印表機的設定。 請注意, gszPrintProc 中的列印處理器名稱必須與 INF 檔案中 PrintProcessor 專案的名稱相同。

BOOL
DrvPrinterEvent(
               LPWSTR  pPrinterName,
               INT     Event,
               DWORD   Flags,
               LPARAM  lParam
               )

{
  PRINTER_DEFAULTS  PrinterDef = {NULL, NULL, PRINTER_ALL_ACCESS};
  HANDLE            hPrinter;
  LPPRINTER_INFO_2  pInfo = NULL;
  DWORD             cbNeeded;
  TCHAR             gszPrintProc[] = TEXT("<Print processor name>");
  BOOL              bRet = TRUE;

  switch (Event)
  {
    case PRINTER_EVENT_INITIALIZE:
      if (OpenPrinter(pPrinterName, &hPrinter, &PrinterDef))
      {
        if ( !GetPrinter( hPrinter, 2, (LPBYTE) pInfo, 0, &cbNeeded ) &&
           (GetLastError() != ERROR_INSUFFICIENT_BUFFER) )
        {
          bRet = FALSE;
        }
        if (bRet == TRUE)
        {
          pInfo = (LPPRINTER_INFO_2) LocalAlloc(LPTR, cbNeeded);
          bRet = pInfo ? TRUE : FALSE;
        }
        if (bRet == TRUE)
        {
          if (GetPrinter(hPrinter, 2, (LPBYTE) pInfo, cbNeeded, &cbNeeded))
          {
            pInfo->pPrintProcessor = gszPrintProc;
            SetPrinter(hPrinter, 2, (LPBYTE) pInfo, 0);
          }
          else 
          {
            bRet = FALSE;
          }
          if (pInfo)
          {
            LocalFree(pInfo);
          }
        }
        ClosePrinter(hPrinter);
      }
      else  // OpenPrinter failed
      {
        bRet = FALSE;
      }
    break;
    // cases for other events

    default:
      break;
  }  // end switch
  return bRet;
}

在印表機驅動程式升級期間將列印處理器與列印佇列建立關聯

更新印表機驅動程式時,更新列印佇列的列印處理器不會變更。 如果新的印表機驅動程式需要特定的印表處理器,列印機介面 DLL 的 DrvUpgradePrinter 函式必須將PRINTER_INFO_2結構的 pPrintProcessor 成員設定為新印表處理器的名稱。 發生這種情況之後,此函式會呼叫 SetPrinter 來更新印表機的設定。 多任務緩衝處理器會針對每部印表機呼叫 DrvUpgradePrinter函 式一次,以確保使用該驅動程式的所有印表機也會使用必要的印表處理器。 下列程式代碼範例示範這些點。

BOOL
DrvUpgradePrinter(
                 DWORD   Level,
                 LPBYTE  pDriverUpgradeInfo
                 )
{
  HANDLE                  hPrinter;
  PRINTER_DEFAULTS        PrinterDef = {NULL, NULL, PRINTER_ALL_ACCESS};
 PDRIVER_UPGRADE_INFO_2  pDUI2;
  LPPRINTER_INFO_2        pInfo = NULL;
 DWORD                   cbNeeded;
  TCHAR                   gszPrintProc[]   = TEXT("<Print processor name>");
  TCHAR                   gszPrintDriver[] = TEXT("<Printer driver name>");
  BOOL                    bRet = TRUE;

  if ((Level == 2)                                            &&
      (pDUI2 = (PDRIVER_UPGRADE_INFO_2)pDriverUpgradeInfo)    &&
      (OpenPrinter(pDUI2->pPrinterName, &hPrinter, &PrinterDef)))
  {
    if ( !GetPrinter( hPrinter, 2, (LPBYTE) pInfo, 0, &cbNeeded )  &&
         (GetLastError() != ERROR_INSUFFICIENT_BUFFER) )
    {
       bRet = FALSE;
    }
    if (bRet == TRUE)
    {
      pInfo = (LPPRINTER_INFO_2) LocalAlloc(LPTR, cbNeeded);
      bRet = pInfo ? TRUE : FALSE;
    }
    if (bRet == TRUE)
    {
      if (GetPrinter(hPrinter, 2, (LPBYTE) pInfo, cbNeeded, &cbNeeded))
      {
      //
      // This function is called for every printer queue that uses a driver
      // for which one or more files were updated. However, we only want to
      // update the printer queue's "driver" by a particular driver.
      //
      if ( !lstrcmpi(pInfo->pDriverName, gszPrintDriver) )
      {
        pInfo->pPrintProcessor =  gszPrintProc;
        SetPrinter(hPrinter, 2, (LPBYTE) pInfo, 0);
      }
    else  // GetPrinter 
    {
      bRet = FALSE;
    }
    if (pInfo)
    {
      LocalFree(pInfo);
    }
    ClosePrinter(hPrinter);
  }
  else  // Level != 2 or pDUI2 == NULL or OpenPrinter failed
  {
    bRet = FALSE;
  }
  return bRet;
}