非托管C+;中的默认打印机+; 我在寻找一种使用非托管C++查找Windows默认打印机的方法(找到了很多.NET示例,但没有成功的非托管)。谢谢。

非托管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); 以后,不要用谷歌搜索“非托管”,而是用谷歌

以下内容非常适合使用C中的win32api进行打印++

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