在DEVMODE結構如記錄由Win32SDK包含公共或"裝置獨立資料"和專用或"裝置相關資料。在DEVMODE的專用部分存在緊跟公共由DEVMODE結構的記憶體的連續緩衝區中定義的部分。
程式不能預測此緩衝區的大小,因為它是印表機驅動程式的不同印表機並從版本的印表機。此外,一個程式只是宣告的DEVMODE結構沒有足夠空間的專用裝置資料。如果缺少專用資料的DEVMODE緩衝區傳遞給函式(如CreateDC()、ResetDC()和DocumentProperties(),可能會失敗,函式。
若要可靠地的裝置驅動程式中使用一個DEVMODE,建立,並按以下步驟修改:
確定所需從該的裝置緩衝區的大小,並且然後會為其分配足夠的記憶體。
DocumentProperties()返回最後一個引數設定為0時所需的DEVMODE緩衝區位元組的數。本文中的示例程式碼使用此技術確定正確緩衝區的大小。然後,示例程式碼使用C執行時記憶體分配函式的malloc()分配足夠大的緩衝區。因為DocumentProperties()和功能(如ResetDC()和CreateDC()採取作為引數的DEVMODE的指標,大多數應用程式可以分配的指標的記憶體。
但是,函式如常見PrintDlg()接受所需為全域性記憶體的控制代碼引數。如果程式使用最終的DEVMODE緩衝區為這些函式的引數,它應分配使用GlobalAlloc()的記憶體,並獲取指向使用GlobalLock()的緩衝區指標。
要求裝置驅動程式初始化DEVMODE緩衝區使用預設設定。
該示例程式碼將呼叫DocumentProperties()第二次初始化分配的緩衝區使用當前的預設設定。DocumentProperties()填充稱為pDevModeOutput引數了印表機的當前設定fMode引數中傳遞DM_OUT_BUFFER命令時的緩衝區。
對在DEVMODE的公共部分進行更改請求裝置驅動程式透過呼叫DocumentProperties()所做的更改合併在DEVMODE的專用部分。
在初始化了在步驟2中的當前設定緩衝區後的程式碼示例對在DEVMODE的公共部分進行更改。請參閱Win32SDK文件的DEVMODE成員的說明。此示例程式碼來確定是否可以使用方向和雙面列印(雙面)設定印表機,並相應地更改它們。
注意:在DEVMODE的dmFields成員A標誌並只表示印表機使用相關的結構成員。印表機具有各種不同的物理特徵,因此,可能只支援DEVMODE的記錄功能的子集。若要確定DEVMODE的欄位的受支援的設定,應用程式應使用DeviceCapabilities()。
該示例程式碼然後使第三個呼叫DocumentProperties(),pDevModeInput和pDevModeOutput引數中傳遞DEVMODE緩衝區。它還使用OR("|")運算子傳遞DM_IN_BUFFER和DM_OUT_BUFFERfMode引數中合併的命令。這些命令告訴函式需要輸入緩衝區中包含任何設定,併合並它們使用當前設定為該裝置。然後它會結果寫入到輸出引數中指定的緩衝區。
注意:DocumentProperties()指向特定印表機的印表機控制代碼:hPrinter。從OpenPrinter(),它還闡釋了示例程式碼獲取此控制代碼。OpenPrinter()需要一個印表機通常是友好名稱印表機的作業系統的外殼程式中顯示的名稱。從EnumPrinters()、返回PrintDlg(),DEVNAMES結構或預設印表機,可以獲取此名稱。
有關預設印表機單擊下面的文章編號,以檢視Microsoft知識庫中的相應:
246772(http://support.microsoft.com/kb/246772/EN-US/)如何檢索並在Windows中設定預設印表機
注意:在這篇文章,分配緩衝區的正確的大小和初始化該緩衝區的前兩個步驟執行與DocumentProperties()。您也可以使用GetPrinter()按照這些步驟。有關其他資訊和這種示例,請單擊下面該文章編號,以檢視Microsoft知識庫中相應:
140285(http://support.microsoft.com/kb/140285/EN-US/)如何使用SetPrinter修改印表機設定
回到頂端
示例程式碼
示例程式碼遵循以下三個的步驟,有關獲得和更改DEVMODE緩衝區。該函式採用指定的印表機,並配置它支援這些功能的情況下列印雙面和以橫向方向的DEVMODE。返回到呼叫方的該結果DEVMODE是適用於使用DEVMODE緩衝區如CreateDC()、SetPrinter()、PrintDlg()或ResetDC()的其他API呼叫。當呼叫方完成使用DEVMODE緩衝區時,呼叫方負責釋放記憶體。
LPDEVMODEGetLandscapeDevMode(HWNDhWnd,char*pDevice)
{
HANDLEhPrinter;
LPDEVMODEpDevMode;
DWORDdwNeeded,dwRet;
/*Startbyopeningtheprinter*/
if(!OpenPrinter(pDevice,&hPrinter,NULL))
returnNULL;
/*
*Step1:
*Allocateabufferofthecorrectsize.
*/
dwNeeded=DocumentProperties(hWnd,
hPrinter,/*Handletoourprinter.*/
pDevice,/*Nameoftheprinter.*/
NULL,/*Askingforsize,so*/
NULL,/*thesearenotused.*/
0);/*Zeroreturnsbuffersize.*/
pDevMode=(LPDEVMODE)malloc(dwNeeded);
*Step2:
*GetthedefaultDevModefortheprinterand
*modifyitforyourneeds.
dwRet=DocumentProperties(hWnd,
hPrinter,
pDevice,
pDevMode,/*Theaddressofthebuffertofill.*/
NULL,/*Notusingtheinputbuffer.*/
DM_OUT_BUFFER);/*Havetheoutputbufferfilled.*/
if(dwRet!=IDOK)
/*Iffailure,cleanupandreturnfailure.*/
free(pDevMode);
ClosePrinter(hPrinter);
}
*MakechangestotheDevModewhicharesupported.
if(pDevMode->dmFields&DM_ORIENTATION)
/*Iftheprintersupportspaperorientation,setit.*/
pDevMode->dmOrientation=DMORIENT_LANDSCAPE;
if(pDevMode->dmFields&DM_DUPLEX)
/*Ifitsupportsduplexprinting,useit.*/
pDevMode->dmDuplex=DMDUP_HORIZONTAL;
*Step3:
*Mergethenewsettingswiththeold.
*Thisgivesthedriveranopportunitytoupdateanyprivate
*portionsoftheDevModestructure.
pDevMode,/*Reuseourbufferforoutput.*/
pDevMode,/*Passthedriverourchanges.*/
DM_IN_BUFFER|/*CommandstoMergeourchangesand*/
DM_OUT_BUFFER);/*writetheresult.*/
/*Finishedwiththeprinter*/
/*ReturnthemodifiedDevModestructure.*/
returnpDevMode;
在DEVMODE結構如記錄由Win32SDK包含公共或"裝置獨立資料"和專用或"裝置相關資料。在DEVMODE的專用部分存在緊跟公共由DEVMODE結構的記憶體的連續緩衝區中定義的部分。
程式不能預測此緩衝區的大小,因為它是印表機驅動程式的不同印表機並從版本的印表機。此外,一個程式只是宣告的DEVMODE結構沒有足夠空間的專用裝置資料。如果缺少專用資料的DEVMODE緩衝區傳遞給函式(如CreateDC()、ResetDC()和DocumentProperties(),可能會失敗,函式。
若要可靠地的裝置驅動程式中使用一個DEVMODE,建立,並按以下步驟修改:
確定所需從該的裝置緩衝區的大小,並且然後會為其分配足夠的記憶體。
DocumentProperties()返回最後一個引數設定為0時所需的DEVMODE緩衝區位元組的數。本文中的示例程式碼使用此技術確定正確緩衝區的大小。然後,示例程式碼使用C執行時記憶體分配函式的malloc()分配足夠大的緩衝區。因為DocumentProperties()和功能(如ResetDC()和CreateDC()採取作為引數的DEVMODE的指標,大多數應用程式可以分配的指標的記憶體。
但是,函式如常見PrintDlg()接受所需為全域性記憶體的控制代碼引數。如果程式使用最終的DEVMODE緩衝區為這些函式的引數,它應分配使用GlobalAlloc()的記憶體,並獲取指向使用GlobalLock()的緩衝區指標。
要求裝置驅動程式初始化DEVMODE緩衝區使用預設設定。
該示例程式碼將呼叫DocumentProperties()第二次初始化分配的緩衝區使用當前的預設設定。DocumentProperties()填充稱為pDevModeOutput引數了印表機的當前設定fMode引數中傳遞DM_OUT_BUFFER命令時的緩衝區。
對在DEVMODE的公共部分進行更改請求裝置驅動程式透過呼叫DocumentProperties()所做的更改合併在DEVMODE的專用部分。
在初始化了在步驟2中的當前設定緩衝區後的程式碼示例對在DEVMODE的公共部分進行更改。請參閱Win32SDK文件的DEVMODE成員的說明。此示例程式碼來確定是否可以使用方向和雙面列印(雙面)設定印表機,並相應地更改它們。
注意:在DEVMODE的dmFields成員A標誌並只表示印表機使用相關的結構成員。印表機具有各種不同的物理特徵,因此,可能只支援DEVMODE的記錄功能的子集。若要確定DEVMODE的欄位的受支援的設定,應用程式應使用DeviceCapabilities()。
該示例程式碼然後使第三個呼叫DocumentProperties(),pDevModeInput和pDevModeOutput引數中傳遞DEVMODE緩衝區。它還使用OR("|")運算子傳遞DM_IN_BUFFER和DM_OUT_BUFFERfMode引數中合併的命令。這些命令告訴函式需要輸入緩衝區中包含任何設定,併合並它們使用當前設定為該裝置。然後它會結果寫入到輸出引數中指定的緩衝區。
注意:DocumentProperties()指向特定印表機的印表機控制代碼:hPrinter。從OpenPrinter(),它還闡釋了示例程式碼獲取此控制代碼。OpenPrinter()需要一個印表機通常是友好名稱印表機的作業系統的外殼程式中顯示的名稱。從EnumPrinters()、返回PrintDlg(),DEVNAMES結構或預設印表機,可以獲取此名稱。
有關預設印表機單擊下面的文章編號,以檢視Microsoft知識庫中的相應:
246772(http://support.microsoft.com/kb/246772/EN-US/)如何檢索並在Windows中設定預設印表機
注意:在這篇文章,分配緩衝區的正確的大小和初始化該緩衝區的前兩個步驟執行與DocumentProperties()。您也可以使用GetPrinter()按照這些步驟。有關其他資訊和這種示例,請單擊下面該文章編號,以檢視Microsoft知識庫中相應:
140285(http://support.microsoft.com/kb/140285/EN-US/)如何使用SetPrinter修改印表機設定
回到頂端
示例程式碼
示例程式碼遵循以下三個的步驟,有關獲得和更改DEVMODE緩衝區。該函式採用指定的印表機,並配置它支援這些功能的情況下列印雙面和以橫向方向的DEVMODE。返回到呼叫方的該結果DEVMODE是適用於使用DEVMODE緩衝區如CreateDC()、SetPrinter()、PrintDlg()或ResetDC()的其他API呼叫。當呼叫方完成使用DEVMODE緩衝區時,呼叫方負責釋放記憶體。
LPDEVMODEGetLandscapeDevMode(HWNDhWnd,char*pDevice)
{
HANDLEhPrinter;
LPDEVMODEpDevMode;
DWORDdwNeeded,dwRet;
/*Startbyopeningtheprinter*/
if(!OpenPrinter(pDevice,&hPrinter,NULL))
returnNULL;
/*
*Step1:
*Allocateabufferofthecorrectsize.
*/
dwNeeded=DocumentProperties(hWnd,
hPrinter,/*Handletoourprinter.*/
pDevice,/*Nameoftheprinter.*/
NULL,/*Askingforsize,so*/
NULL,/*thesearenotused.*/
0);/*Zeroreturnsbuffersize.*/
pDevMode=(LPDEVMODE)malloc(dwNeeded);
/*
*Step2:
*GetthedefaultDevModefortheprinterand
*modifyitforyourneeds.
*/
dwRet=DocumentProperties(hWnd,
hPrinter,
pDevice,
pDevMode,/*Theaddressofthebuffertofill.*/
NULL,/*Notusingtheinputbuffer.*/
DM_OUT_BUFFER);/*Havetheoutputbufferfilled.*/
if(dwRet!=IDOK)
{
/*Iffailure,cleanupandreturnfailure.*/
free(pDevMode);
ClosePrinter(hPrinter);
returnNULL;
}
/*
*MakechangestotheDevModewhicharesupported.
*/
if(pDevMode->dmFields&DM_ORIENTATION)
{
/*Iftheprintersupportspaperorientation,setit.*/
pDevMode->dmOrientation=DMORIENT_LANDSCAPE;
}
if(pDevMode->dmFields&DM_DUPLEX)
{
/*Ifitsupportsduplexprinting,useit.*/
pDevMode->dmDuplex=DMDUP_HORIZONTAL;
}
/*
*Step3:
*Mergethenewsettingswiththeold.
*Thisgivesthedriveranopportunitytoupdateanyprivate
*portionsoftheDevModestructure.
*/
dwRet=DocumentProperties(hWnd,
hPrinter,
pDevice,
pDevMode,/*Reuseourbufferforoutput.*/
pDevMode,/*Passthedriverourchanges.*/
DM_IN_BUFFER|/*CommandstoMergeourchangesand*/
DM_OUT_BUFFER);/*writetheresult.*/
/*Finishedwiththeprinter*/
ClosePrinter(hPrinter);
if(dwRet!=IDOK)
{
/*Iffailure,cleanupandreturnfailure.*/
free(pDevMode);
returnNULL;
}
/*ReturnthemodifiedDevModestructure.*/
returnpDevMode;
}