DocumentProperties() 関数を使用してプリンター設定を変更する

この記事では、 関数を使用してプリンターの設定を変更する DocumentProperties() 方法について説明します。

元の製品バージョン: プリンタ
元の KB 番号: 167345

概要

DEVMODE 構造体を使用してプリンター設定を変更することは、構造体のフィールドを変更するよりも困難です。 具体的には、デバイスの有効な DEVMODE 構造体には、関数によってのみ変更できるプライベート データが DocumentProperties() 含まれています。

この記事では、 関数を使用して DEVMODE 構造体の内容を変更する方法について説明します DocumentProperties()

詳細

Win32 SDK に記載されている DEVMODE 構造体には、パブリックまたは "デバイスに依存しないデータ" とプライベートデータまたは "デバイス依存データ" が含まれています。 DEVMODE のプライベート部分は、DEVMODE 構造体によって定義されるパブリック 部分の直後に、メモリの連続したバッファー内に存在します。

このバッファーのサイズは、プリンターとプリンター ドライバーのバージョンによって異なるため、プログラムでは予測できません。 さらに、プログラムによって宣言された DEVMODE 構造体には、プライベート デバイス データ用の十分な領域が含まれていません。 プライベート データがない DEVMODE バッファーが、 などのCreateDC()ResetDC()DocumentProperties()関数に渡されると、関数が失敗する可能性があります。

デバイス ドライバーで DEVMODE を確実に使用するには、次の手順に従って DEVMODE を作成して変更します。

  1. デバイスからバッファーの必要なサイズを決定し、それに十分なメモリを割り当てます。

    DocumentProperties() は、最後のパラメーターが 0 に設定されている場合に DEVMODE バッファーに必要なバイト数を返します。 この記事のサンプル コードでは、この手法を使用してバッファーの正しいサイズを判断します。 サンプル コードでは、 の C ランタイム メモリ割り当て関数 malloc() を使用して、十分な大きさのバッファーを割り当てます。 および 関数ResetDC()CreateDC()は、DEVMODE へのポインターをパラメーターとして受け取るためDocumentProperties()、ほとんどのアプリケーションはポインターによってアドレス指定されるメモリを割り当てることができます。

    ただし、グローバル メモリに対して処理する必要がある一般的な PrintDlg() take パラメーターなどの関数。 プログラムがこれらの関数の 1 つのパラメーターとして最終的な DEVMODE バッファーを使用する場合は、 を使用してメモリを割り当て、 を使用 GlobalAlloc() して GlobalLock()バッファーへのポインターを取得する必要があります。

  2. 既定の設定で DEVMODE バッファーを初期化するようにデバイス ドライバーに依頼します。

    サンプル コードでは、2 回目を呼び出 DocumentProperties() して、割り当てられたバッファーを現在の既定の設定で初期化します。 DocumentProperties()コマンドが fMode パラメーターで渡されたときにDM_OUT_BUFFER、pDevModeOutput パラメーターと呼ばれるバッファーをプリンターの現在の設定で埋めます。

  3. DEVMODE のパブリック部分に変更を加え、 を呼び出 DocumentProperties()して、変更を DEVMODE のプライベート部分にマージするようにデバイス ドライバーに依頼します。

    手順 2 の現在の設定でバッファーを初期化した後、サンプル コードは DEVMODE のパブリック部分に変更を加えます。 DEVMODE メンバーの説明については、Win32 SDK のドキュメントを参照してください。 このサンプル コードでは、プリンターで方向と両面 (両面) の設定を使用できるかどうかを判断し、適切に変更します。

    注:

    DEVMODE の dmFields メンバーのフラグは、プリンターが関連付けられている構造体メンバーを使用していることを示すだけです。 プリンターにはさまざまな物理的特性があるため、DEVMODE の文書化された機能のサブセットのみをサポートできます。 DEVMODE のフィールドでサポートされている設定を確認するには、アプリケーションで を使用 DeviceCapabilities()する必要があります。

    その後、サンプル コードは に対して 3 番目の呼び出しを DocumentProperties() 行い、pDevModeInput パラメーターと pDevModeOutput パラメーターの両方で DEVMODE バッファーを渡します。 また、or("|") 演算子を使用して、fMode パラメーターでDM_IN_BUFFERとDM_OUT_BUFFERの組み合わせコマンドを渡します。 これらのコマンドは、入力バッファーに含まれている設定を取得し、それらをデバイスの現在の設定とマージするように関数に指示します。 次に、out パラメーターで指定されたバッファーに結果を書き込みます。

注:

DocumentProperties() は、プリンターへのハンドルによる特定のプリンターを指します: hPrinter。 このハンドルは、 から OpenPrinter()取得され、サンプル コードも示されています。 OpenPrinter() にはプリンターの名前が必要です。これは通常、オペレーティング システムのシェルに表示されるプリンターのフレンドリ名です。 この名前は、 によってEnumPrinters()PrintDlg()返される DEVNAMES 構造体から、または既定のプリンターから取得できます。

この記事では、バッファーの正しいサイズを割り当て、そのバッファーを初期化する最初の 2 つの手順を で DocumentProperties()実行します。 を使用 GetPrinter()して、次の手順に従うこともできます。

詳細とこの例については、「 SetPrinter 関数を使用してプリンター設定を変更する」を参照してください。

サンプル コード

サンプル コードは、DEVMODE バッファーを取得および変更するための次の 3 つの手順に従います。 この関数は、名前付きプリンターを受け取り、これらの機能をサポートしている場合は、両面印刷と横向きで印刷するように DEVMODE を構成します。 呼び出し元に返される結果の DEVMODE は、DEVMODE バッファー (、SetPrinter()PrintDlg()、 などCreateDC()) を使用する他の API 呼び出しにResetDC()適しています。 呼び出し元が DEVMODE バッファーを使用して完了すると、呼び出し元はメモリの解放を担当します。

 LPDEVMODE GetLandscapeDevMode(HWND hWnd, char *pDevice)
 {
    HANDLE hPrinter;
    LPDEVMODE pDevMode;
    DWORD dwNeeded, dwRet;
    
    /* Start by opening the printer */ 
    if (!OpenPrinter(pDevice, &hPrinter, NULL))
        return NULL;
    
    /*
    * Step 1:
    * Allocate a buffer of the correct size.
    */ 
    dwNeeded = DocumentProperties(hWnd,
    hPrinter, /* Handle to our printer. */ 
    pDevice, /* Name of the printer. */ 
    NULL, /* Asking for size, so */ 
    NULL, /* these are not used. */ 
    0); /* Zero returns buffer size. */ 
    pDevMode = (LPDEVMODE)malloc(dwNeeded);
    
    /*
    * Step 2:
    * Get the default DevMode for the printer and
    * modify it for your needs.
    */ 
    dwRet = DocumentProperties(hWnd,
    hPrinter,
    pDevice,
    pDevMode, /* The address of the buffer to fill. */ 
    NULL, /* Not using the input buffer. */ 
    DM_OUT_BUFFER); /* Have the output buffer filled. */ 
    if (dwRet != IDOK)
    {
        /* If failure, cleanup and return failure. */ 
        free(pDevMode);
        ClosePrinter(hPrinter);
        return NULL;
    }
    
    /*
    * Make changes to the DevMode which are supported.
    */ 
    if (pDevMode->dmFields & DM_ORIENTATION)
    {
        /* If the printer supports paper orientation, set it.*/ 
        pDevMode->dmOrientation = DMORIENT_LANDSCAPE;
    }
    
    if (pDevMode->dmFields & DM_DUPLEX)
    {
        /* If it supports duplex printing, use it. */ 
        pDevMode->dmDuplex = DMDUP_HORIZONTAL;
    }
    
    /*
    * Step 3:
    * Merge the new settings with the old.
    * This gives the driver an opportunity to update any private
    * portions of the DevMode structure.
    */ 
    dwRet = DocumentProperties(hWnd,
    hPrinter,
    pDevice,
    pDevMode, /* Reuse our buffer for output. */ 
    pDevMode, /* Pass the driver our changes. */ 
    DM_IN_BUFFER | /* Commands to Merge our changes and */ 
    DM_OUT_BUFFER); /* write the result. */ 
    
    /* Finished with the printer */ 
    ClosePrinter(hPrinter);
    
    if (dwRet != IDOK)
    {
        /* If failure, cleanup and return failure. */ 
        free(pDevMode);
        return NULL;
    }
    
    /* Return the modified DevMode structure. */ 
    return pDevMode;
}