非托管C+;中的默认打印机+; 我在寻找一种使用非托管C++查找Windows默认打印机的方法(找到了很多.NET示例,但没有成功的非托管)。谢谢。
以下内容非常适合使用C中的win32api进行打印++非托管C+;中的默认打印机+; 我在寻找一种使用非托管C++查找Windows默认打印机的方法(找到了很多.NET示例,但没有成功的非托管)。谢谢。,c++,windows,unmanaged,default,printing,C++,Windows,Unmanaged,Default,Printing,以下内容非常适合使用C中的win32api进行打印++ char szPrinterName[255]; unsigned long lPrinterNameLength; GetDefaultPrinter( szPrinterName, &lPrinterNameLength ); HDC hPrinterDC; hPrinterDC = CreateDC("WINSPOOL\0", szPrinterName, NULL, NULL); 以后,不要用谷歌搜索“非托管”,而是用谷歌
char szPrinterName[255];
unsigned long lPrinterNameLength;
GetDefaultPrinter( szPrinterName, &lPrinterNameLength );
HDC hPrinterDC;
hPrinterDC = CreateDC("WINSPOOL\0", szPrinterName, NULL, NULL);
以后,不要用谷歌搜索“非托管”,而是用谷歌搜索“win32/subject/”或“win32 api/subject/”GetDefaultPrinter应该可以做到这一点。这将获得要传递给CreateDC进行打印的名称。以下是如何获取当前打印机列表以及默认打印机列表(如果有一个设置为默认打印机) 另请注意:如果用户没有打印机或未将打印机设置为默认打印机,则默认打印机名称长度为零是有效的 还应支持处理长打印机名称,因此首先使用NULL作为缓冲区指针调用GetDefaultPrinter将返回名称长度,然后可以分配足够大的名称缓冲区来保存名称
DWORD numprinters;
DWORD defprinter=0;
DWORD dwSizeNeeded=0;
DWORD dwItem;
LPPRINTER_INFO_2 printerinfo = NULL;
// Get buffer size
EnumPrinters ( PRINTER_ENUM_LOCAL | PRINTER_ENUM_CONNECTIONS , NULL, 2, NULL, 0, &dwSizeNeeded, &numprinters );
// allocate memory
//printerinfo = (LPPRINTER_INFO_2)HeapAlloc ( GetProcessHeap (), HEAP_ZERO_MEMORY, dwSizeNeeded );
printerinfo = (LPPRINTER_INFO_2)new char[dwSizeNeeded];
if ( EnumPrinters ( PRINTER_ENUM_LOCAL | PRINTER_ENUM_CONNECTIONS, // what to enumerate
NULL, // printer name (NULL for all)
2, // level
(LPBYTE)printerinfo, // buffer
dwSizeNeeded, // size of buffer
&dwSizeNeeded, // returns size
&numprinters // return num. items
) == 0 )
{
numprinters=0;
}
{
DWORD size=0;
// Get the size of the default printer name.
GetDefaultPrinter(NULL, &size);
if(size)
{
// Allocate a buffer large enough to hold the printer name.
TCHAR* buffer = new TCHAR[size];
// Get the printer name.
GetDefaultPrinter(buffer, &size);
for ( dwItem = 0; dwItem < numprinters; dwItem++ )
{
if(!strcmp(buffer,printerinfo[dwItem].pPrinterName))
defprinter=dwItem;
}
delete buffer;
}
}
dwordnumprinters;
DWORD defprinter=0;
DWORD DWSIZENEDED=0;
DWORD dwItem;
LPPRINTER_INFO_2 printerinfo=NULL;
//获取缓冲区大小
枚举打印机(打印机枚举本地打印机枚举连接、NULL、2、NULL、0、&DWSIZENEDED、&numprinters);
//分配内存
//printerinfo=(LPPRINTER\u INFO\u 2)HeapAlloc(GetProcessHeap(),HEAP\u ZERO\u内存,dwsizeneed);
printerinfo=(LPPRINTER_INFO_2)新字符[dwsizeneded];
if(枚举打印机)(打印机(枚举)本地|打印机(枚举)连接,//枚举什么
NULL,//打印机名称(全部为NULL)
2、//级别
(LPBYTE)printerinfo,//缓冲区
dwSizeNeeded,//缓冲区大小
&dwSizeNeeded,//返回大小
&numprinters//返回项目数
) == 0 )
{
numprinters=0;
}
{
DWORD大小=0;
//获取默认打印机名称的大小。
GetDefaultPrinter(空,大小(&S);
如果(尺寸)
{
//分配一个足够大的缓冲区以容纳打印机名称。
TCHAR*buffer=新的TCHAR[size];
//获取打印机名称。
GetDefaultPrinter(缓冲区和大小);
对于(dwItem=0;dwItem 非托管C++不存在(并且管理C++现在是C++ + CLI),如果你引用C++,使用非托管作为标签只是令人伤心……/p>< p>如何在Windows中检索和设置默认打印机:
现在不可用文章的代码:
// 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
//您正在显式链接到GetDefaultPrinter,因为
//在Windows 95/98或NT4上隐式地导致运行时错误。
//此块指定显式链接到的文本版本。
#ifdef UNICODE
#定义GETDEFAULTPRINTER“GetDefaultPrinterW”
#否则
#定义GETDEFAULTPRINTER“GetDefaultPrinterA”
#恩迪夫
//用于保存“printername、drivername、portname”的内部缓冲区大小
//绳子。对于大型字符串,您可能必须增加该值。
#定义MAXBUFFERSIZE 250
/*----------------------------------------------------------------*/
/*DPGetDefaultPrinter*/
/* */
/*参数:**/
/*pPrinterName:调用者分配缓冲区以保存打印机名称。*/
/*pdwBufferSize:输入时,ptr为pPrinterName的大小。*/
/*输出时,pPrinterName的最小所需大小。*/
/* */
/*注意:必须为空终止符提供足够的空间!*/
/* */
/*返回:成功为TRUE,失败为FALSE。*/
/*----------------------------------------------------------------*/
布尔DPGetDefaultPrinter(LPTSTR内部名称,LPDWORD pdwBufferSize)
{
BOOL-bFlag;
OSVERSIONINFO osv;
TCHAR cBuffer[MAXBUFFERSIZE];
打印机_INFO_2*ppi2=NULL;
DWORD=0;
DWORD=0;
HMODULE hWinSpool=NULL;
PROC fnGetDefaultPrinter=NULL;
//您正在运行什么版本的Windows?
osv.dwOSVersionInfoSize=sizeof(OSVERSIONINFO);
GetVersionEx(&osv);
//如果是Windows 95或98,请使用EnumPrinters。
if(osv.dwPlatformId==VER\u PLATFORM\u WIN32\u WINDOWS)
{
//第一个EnumPrinters()告诉您缓冲区必须有多大
//将保存所有打印机信息2。请注意,这将
//通常返回FALSE。这只意味着缓冲区(第四个
//参数)未填写。您不希望在此处填写。
SetLastError(0);
bFlag=EnumPrinters(打印机\枚举\默认值,NULL,2,NULL,0,&dwNeeded,&dwReturned);
{
如果((GetLastError()!=ERROR_缓冲区不足)| |(DWRequired==0))
返回FALSE;
}
//为打印机\信息\ 2分配足够的空间。
ppi2=(打印机信息2*)全局ALLOC(需要GPTR、DWTR);
如果(!ppi2)
返回FALSE;
//第二个EnumPrinters()将填充所有当前信息。
bFlag=EnumPrinters(打印机\枚举\默认值,NULL,2,(LPBYTE)ppi2,dwNeeded,&dwNeeded,&dwReturned);
如果(!bFlag)
{
GlobalFree(ppi2);
返回FALSE;
}
//如果指定的缓冲区太小,请设置所需大小并失败。
如果((DWORD)lstrlen(ppi2->pPrinterName)>=*pdwBufferSize)
{
*pdwBufferSize=(DWORD)lstrlen(ppi2->pPrinterName)+1;
GlobalFree(ppi2);
返回FALSE;
}
//将打印机名称复制到传入的缓冲区中。
lstrcpy(pPrinterName,ppi2->pPrinterName);
//将缓冲区大小参数设置为所需的最小缓冲区大小。
*pdwBufferSize=(DWORD)lstrlen(ppi2->pPrinterName)+1;
}
//如果是Windows NT,请使用适用于Windows 2000的GetDefaultPrinter API,
//或GetProfileString(适用于4.0及更低版本)。
否则如果(osv.dwPlatformI