文書番号: 246772 - 最終更新日: 2005年11月17日 - リビジョン: 2.2 Windows の通常使うプリンタを取得および設定する方法
使用する Windows のバージョンに応じた異なる方法を使用して、通常使うプリンタの取得や設定を行うことができます。
Windows NT 4.0 (およびそれ以前のバージョン) では、次の方法は使用できません。
-
SetPrinter または SetDefaultPrinter を使用して、通常使うプリンタを設定します。
-
EnumPrinters または GetDefaultPrinter を使用して、通常使うプリンタを取得します。
Windows NT 4.0 では、次の方法が使用できます。
-
GetProfileString を使用して、通常使うプリンタを取得します。
-
WriteProfileString を使用して、通常使うプリンタを設定します。
取得または設定する DEVICE の値には、次のようにコンマで区切られた 3 つの要素が含まれます。
printer name,driver name,port
次に例を示します。
My Printer,HPPCL5MS,lpt1:
次の点に注意します。
-
この方法を使用する場合は、有効なプリンタ、ドライバ、およびポートを指定する必要があります。有効な指定を行わなかった場合でも、API ではエラーが発生しないため、他のプログラムによってプリンタが以前有効であったプリンタに設定し直されたり、混乱が発生したりする可能性があります。
利用可能なすべてのプリンタのプリンタ名、ドライバ名、およびポート名を取得するには、EnumPrinters API を使用します。
-
Windows NT では、.ini ファイルの参照の多くはレジストリにマッピングされています。その結果、GetProfileString と WriteProfileString は、16 ビット Windows (Microsoft Windows および Windows for Workgroups) で実行しているかのように、機能を続けます。
-
GetPrinter、GetDefaultPrinter、WriteProfileString のいずれかを使用して通常使うプリンタを設定した後は、WM_SETTINGCHANGE メッセージをブロードキャストして、実行中の他のすべてのプログラムに変更を通知する必要があります。変更を認識できるのは、このメッセージを処理するプログラムだけです。
WM_SETTINGCHANGE と WM_WININICHANGE は同じものです。Win32 プログラムでは、WM_SETTINGCHANGE を使用します。
サンプル コード
次のサンプル コードは、通常使うプリンタを取得する方法 (DPGetDefaultPrinter) および設定する方法 (DPSetDefaultPrinter) を示したものです。
// You are explicitly linking to GetDefaultPrinter because linking
// implicitly on Windows 95/98 or NT4 results in a runtime error.
// This block specifies which text version you explicitly link to.
#ifdef UNICODE
#define GETDEFAULTPRINTER "GetDefaultPrinterW"
#else
#define GETDEFAULTPRINTER "GetDefaultPrinterA"
#endif
// Size of internal buffer used to hold "printername,drivername,portname"
// string. You may have to increase this for huge strings.
#define MAXBUFFERSIZE 250
/*----------------------------------------------------------------*/
/* DPGetDefaultPrinter */
/* */
/* Parameters: */
/* pPrinterName: Buffer alloc'd by caller to hold printer name. */
/* pdwBufferSize: On input, ptr to size of pPrinterName. */
/* On output, min required size of pPrinterName. */
/* */
/* NOTE: You must include enough space for the NULL terminator! */
/* */
/* Returns: TRUE for success, FALSE for failure. */
/*----------------------------------------------------------------*/
BOOL DPGetDefaultPrinter(LPTSTR pPrinterName, LPDWORD pdwBufferSize)
{
BOOL bFlag;
OSVERSIONINFO osv;
TCHAR cBuffer[MAXBUFFERSIZE];
PRINTER_INFO_2 *ppi2 = NULL;
DWORD dwNeeded = 0;
DWORD dwReturned = 0;
HMODULE hWinSpool = NULL;
PROC fnGetDefaultPrinter = NULL;
// What version of Windows are you running?
osv.dwOSVersionInfoSize = sizeof(OSVERSIONINFO);
GetVersionEx(&osv);
// If Windows 95 or 98, use EnumPrinters.
if (osv.dwPlatformId == VER_PLATFORM_WIN32_WINDOWS)
{
// The first EnumPrinters() tells you how big our buffer must
// be to hold ALL of PRINTER_INFO_2. Note that this will
// typically return FALSE. This only means that the buffer (the 4th
// parameter) was not filled in. You do not want it filled in here.
SetLastError(0);
bFlag = EnumPrinters(PRINTER_ENUM_DEFAULT, NULL, 2, NULL, 0, &dwNeeded, &dwReturned);
{
if ((GetLastError() != ERROR_INSUFFICIENT_BUFFER) || (dwNeeded == 0))
return FALSE;
}
// Allocate enough space for PRINTER_INFO_2.
ppi2 = (PRINTER_INFO_2 *)GlobalAlloc(GPTR, dwNeeded);
if (!ppi2)
return FALSE;
// The second EnumPrinters() will fill in all the current information.
bFlag = EnumPrinters(PRINTER_ENUM_DEFAULT, NULL, 2, (LPBYTE)ppi2, dwNeeded, &dwNeeded, &dwReturned);
if (!bFlag)
{
GlobalFree(ppi2);
return FALSE;
}
// If specified buffer is too small, set required size and fail.
if ((DWORD)lstrlen(ppi2->pPrinterName) >= *pdwBufferSize)
{
*pdwBufferSize = (DWORD)lstrlen(ppi2->pPrinterName) + 1;
GlobalFree(ppi2);
return FALSE;
}
// Copy printer name into passed-in buffer.
lstrcpy(pPrinterName, ppi2->pPrinterName);
// Set buffer size parameter to minimum required buffer size.
*pdwBufferSize = (DWORD)lstrlen(ppi2->pPrinterName) + 1;
}
// If Windows NT, use the GetDefaultPrinter API for Windows 2000,
// or GetProfileString for version 4.0 and earlier.
else if (osv.dwPlatformId == VER_PLATFORM_WIN32_NT)
{
if (osv.dwMajorVersion >= 5) // Windows 2000 or later (use explicit call)
{
hWinSpool = LoadLibrary("winspool.drv");
if (!hWinSpool)
return FALSE;
fnGetDefaultPrinter = GetProcAddress(hWinSpool, GETDEFAULTPRINTER);
if (!fnGetDefaultPrinter)
{
FreeLibrary(hWinSpool);
return FALSE;
}
bFlag = fnGetDefaultPrinter(pPrinterName, pdwBufferSize);
FreeLibrary(hWinSpool);
if (!bFlag)
return FALSE;
}
else // NT4.0 or earlier
{
// Retrieve the default string from Win.ini (the registry).
// String will be in form "printername,drivername,portname".
if (GetProfileString("windows", "device", ",,,", cBuffer, MAXBUFFERSIZE) <= 0)
return FALSE;
// Printer name precedes first "," character.
strtok(cBuffer, ",");
// If specified buffer is too small, set required size and fail.
if ((DWORD)lstrlen(cBuffer) >= *pdwBufferSize)
{
*pdwBufferSize = (DWORD)lstrlen(cBuffer) + 1;
return FALSE;
}
// Copy printer name into passed-in buffer.
lstrcpy(pPrinterName, cBuffer);
// Set buffer size parameter to minimum required buffer size.
*pdwBufferSize = (DWORD)lstrlen(cBuffer) + 1;
}
}
// Clean up.
if (ppi2)
GlobalFree(ppi2);
return TRUE;
}
#undef MAXBUFFERSIZE
#undef GETDEFAULTPRINTER
// You are explicitly linking to SetDefaultPrinter because implicitly
// linking on Windows 95/98 or NT4 results in a runtime error.
// This block specifies which text version you explicitly link to.
#ifdef UNICODE
#define SETDEFAULTPRINTER "SetDefaultPrinterW"
#else
#define SETDEFAULTPRINTER "SetDefaultPrinterA"
#endif
/*-----------------------------------------------------------------*/
/* DPSetDefaultPrinter */
/* */
/* Parameters: */
/* pPrinterName: Valid name of existing printer to make default. */
/* */
/* Returns: TRUE for success, FALSE for failure. */
/*-----------------------------------------------------------------*/
BOOL DPSetDefaultPrinter(LPTSTR pPrinterName)
{
BOOL bFlag;
OSVERSIONINFO osv;
DWORD dwNeeded = 0;
HANDLE hPrinter = NULL;
PRINTER_INFO_2 *ppi2 = NULL;
LPTSTR pBuffer = NULL;
LONG lResult;
HMODULE hWinSpool = NULL;
PROC fnSetDefaultPrinter = NULL;
// What version of Windows are you running?
osv.dwOSVersionInfoSize = sizeof(OSVERSIONINFO);
GetVersionEx(&osv);
if (!pPrinterName)
return FALSE;
// If Windows 95 or 98, use SetPrinter.
if (osv.dwPlatformId == VER_PLATFORM_WIN32_WINDOWS)
{
// Open this printer so you can get information about it.
bFlag = OpenPrinter(pPrinterName, &hPrinter, NULL);
if (!bFlag || !hPrinter)
return FALSE;
// The first GetPrinter() tells you how big our buffer must
// be to hold ALL of PRINTER_INFO_2. Note that this will
// typically return FALSE. This only means that the buffer (the 3rd
// parameter) was not filled in. You do not want it filled in here.
SetLastError(0);
bFlag = GetPrinter(hPrinter, 2, 0, 0, &dwNeeded);
if (!bFlag)
{
if ((GetLastError() != ERROR_INSUFFICIENT_BUFFER) || (dwNeeded == 0))
{
ClosePrinter(hPrinter);
return FALSE;
}
}
// Allocate enough space for PRINTER_INFO_2.
ppi2 = (PRINTER_INFO_2 *)GlobalAlloc(GPTR, dwNeeded);
if (!ppi2)
{
ClosePrinter(hPrinter);
return FALSE;
}
// The second GetPrinter() will fill in all the current information
// so that all you have to do is modify what you are interested in.
bFlag = GetPrinter(hPrinter, 2, (LPBYTE)ppi2, dwNeeded, &dwNeeded);
if (!bFlag)
{
ClosePrinter(hPrinter);
GlobalFree(ppi2);
return FALSE;
}
// Set default printer attribute for this printer.
ppi2->Attributes |= PRINTER_ATTRIBUTE_DEFAULT;
bFlag = SetPrinter(hPrinter, 2, (LPBYTE)ppi2, 0);
if (!bFlag)
{
ClosePrinter(hPrinter);
GlobalFree(ppi2);
return FALSE;
}
// Tell all open programs that this change occurred.
// Allow each program 1 second to handle this message.
lResult = SendMessageTimeout(HWND_BROADCAST, WM_SETTINGCHANGE, 0L,
(LPARAM)(LPCTSTR)"windows", SMTO_NORMAL, 1000, NULL);
}
// If Windows NT, use the SetDefaultPrinter API for Windows 2000,
// or WriteProfileString for version 4.0 and earlier.
else if (osv.dwPlatformId == VER_PLATFORM_WIN32_NT)
{
if (osv.dwMajorVersion >= 5) // Windows 2000 or later (use explicit call)
{
hWinSpool = LoadLibrary("winspool.drv");
if (!hWinSpool)
return FALSE;
fnSetDefaultPrinter = GetProcAddress(hWinSpool, SETDEFAULTPRINTER);
if (!fnSetDefaultPrinter)
{
FreeLibrary(hWinSpool);
return FALSE;
}
bFlag = fnSetDefaultPrinter(pPrinterName);
FreeLibrary(hWinSpool);
if (!bFlag)
return FALSE;
}
else // NT4.0 or earlier
{
// Open this printer so you can get information about it.
bFlag = OpenPrinter(pPrinterName, &hPrinter, NULL);
if (!bFlag || !hPrinter)
return FALSE;
// The first GetPrinter() tells you how big our buffer must
// be to hold ALL of PRINTER_INFO_2. Note that this will
// typically return FALSE. This only means that the buffer (the 3rd
// parameter) was not filled in. You do not want it filled in here.
SetLastError(0);
bFlag = GetPrinter(hPrinter, 2, 0, 0, &dwNeeded);
if (!bFlag)
{
if ((GetLastError() != ERROR_INSUFFICIENT_BUFFER) || (dwNeeded == 0))
{
ClosePrinter(hPrinter);
return FALSE;
}
}
// Allocate enough space for PRINTER_INFO_2.
ppi2 = (PRINTER_INFO_2 *)GlobalAlloc(GPTR, dwNeeded);
if (!ppi2)
{
ClosePrinter(hPrinter);
return FALSE;
}
// The second GetPrinter() fills in all the current<BR/>
// information.
bFlag = GetPrinter(hPrinter, 2, (LPBYTE)ppi2, dwNeeded, &dwNeeded);
if ((!bFlag) || (!ppi2->pDriverName) || (!ppi2->pPortName))
{
ClosePrinter(hPrinter);
GlobalFree(ppi2);
return FALSE;
}
// Allocate buffer big enough for concatenated string.
// String will be in form "printername,drivername,portname".
pBuffer = (LPTSTR)GlobalAlloc(GPTR,
lstrlen(pPrinterName) +
lstrlen(ppi2->pDriverName) +
lstrlen(ppi2->pPortName) + 3);
if (!pBuffer)
{
ClosePrinter(hPrinter);
GlobalFree(ppi2);
return FALSE;
}
// Build string in form "printername,drivername,portname".
lstrcpy(pBuffer, pPrinterName); lstrcat(pBuffer, ",");
lstrcat(pBuffer, ppi2->pDriverName); lstrcat(pBuffer, ",");
lstrcat(pBuffer, ppi2->pPortName);
// Set the default printer in Win.ini and registry.
bFlag = WriteProfileString("windows", "device", pBuffer);
if (!bFlag)
{
ClosePrinter(hPrinter);
GlobalFree(ppi2);
GlobalFree(pBuffer);
return FALSE;
}
}
// Tell all open programs that this change occurred.
// Allow each app 1 second to handle this message.
lResult = SendMessageTimeout(HWND_BROADCAST, WM_SETTINGCHANGE, 0L, 0L,
SMTO_NORMAL, 1000, NULL);
}
// Clean up.
if (hPrinter)
ClosePrinter(hPrinter);
if (ppi2)
GlobalFree(ppi2);
if (pBuffer)
GlobalFree(pBuffer);
return TRUE;
}
#undef SETDEFAULTPRINTER
環境によっては、このコードが機能しない可能性があります。
-
SendMessageTimeout の呼び出しを省略すると、そのプログラムを再起動するまで、他のプログラムで変更が認識されません。
-
別の 32 ビット プログラムが WM_SETTINGCHANGE メッセージを処理しない場合、他のプログラムでは通常使うプリンタの変更が認識されません。変更を認識させるためには、プログラムを終了して再起動する必要があります。
-
MAXBUFFERSIZE が小さいために、次の文字列を保持できない場合があります。
printername,portname,drivername
-
このサンプル コード (Windows NT 4.0 以前のバージョンで使用する必要があります) の WriteProfileString API を使用する場合、WriteProfileString に渡されるポート名は 32 ビット API の GetPrinter を使用して取得されます。
このポート名は有効ですが、16 ビット プログラムからは読み取ることができず、問題が発生する可能性があります。この方法を Windows NT (4.0 以前のバージョン) で使用する場合で、なおかつ 16 ビット プログラムに新しいポート名を認識させる必要がある場合は、ポート名の 16 ビット用の別名 (NE0x、x には番号が入ります) を使用する必要があります。32 ビットのポート名と 16 ビット用の別名のマッピングは、レジストリで確認できます。
関連情報を参照するには、以下の「サポート技術情報」 (Microsoft Knowledge Base) をクリックしてください。
266767?
(http://support.microsoft.com/kb/266767/
)
システムの通常使うプリンタを設定する方法 140560?
(http://support.microsoft.com/kb/140560/
)
[HOWTO] Windows 95、Windows 98、または Windows Me で通常使うプリンタをプログラムから設定する方法
この資料は以下の製品について記述したものです。- Microsoft Platform SDK January 2000 Editionを以下の環境でお使いの場合
- Microsoft Windows 95
- Microsoft Windows 98 Standard Edition
- Microsoft Windows NT Server 4.0 Standard Edition
- Microsoft Windows NT Workstation 4.0 Developer Edition
- Microsoft Windows 2000 Standard Edition
| kbdswgdi2003swept kbgdi kbhowto kbprint KB246772 |
"Microsoft Knowledge Baseに含まれている情報は、いかなる保証もない現状ベースで提供されるものです。Microsoft Corporation及びその関連会社は、市場性および特定の目的への適合性を含めて、明示的にも黙示的にも、一切の保証をいたしません。さらに、Microsoft Corporation及びその関連会社は、本文書に含まれている情報の使用及び使用結果につき、正確性、真実性等、いかなる表明・保証も行ないません。Microsoft Corporation、その関連会社及びこれらの権限ある代理人による口頭または書面による一切の情報提供またはアドバイスは、保証を意味するものではなく、かつ上記免責条項の範囲を狭めるものではありません。Microsoft Corporation、その関連会社 及びこれらの者の供給者は、直接的、間接的、偶発的、結果的損害、逸失利益、懲罰的損害、または特別損害を含む全ての損害に対して、状況のいかんを問わず一切責任を負いません。(Microsoft Corporation、その関連会社 またはこれらの者の供給者がかかる損害の発生可能性を了知している場合を含みます。) 結果的損害または偶発的損害に対する責任の免除または制限を認めていない地域においては、上記制限が適用されない場合があります。なお、本文書においては、文書の体裁上の都合により製品名の表記において商標登録表示、その他の商標表示を省略している場合がありますので、予めご了解ください。" | |