Como recuperar e definir a impressora padrão no Windows

Traduções deste artigo Traduções deste artigo
ID do artigo: 246772 - Exibir os produtos aos quais esse artigo se aplica.
Aviso
Este artigo se aplica ao Windows 2000. Suporte 2000 termina em 13 de julho de 2010.Windows 2000 End-of-Support Solution Center é um ponto de partida para planejar uma estratégia de migração do Windows 2000. Para obter mais informações, consulte a Microsoft Support Lifecycle Policy.
Expandir tudo | Recolher tudo

Sumário

Você pode recuperar ou definir a impressora padrão usando métodos diferentes, dependendo da versão do Windows que você usar.

Mais Informações

Com o Windows NT 4.0 (e versões anteriores), você não pode usar:
  • Ou SetPrinter ou SetDefaultPrinter para definir a impressora padrão.
  • Ou EnumPrinters ou GetDefaultPrinter para obter a impressora padrão.
Com o Windows NT 4.0, você pode usar:
  • GetProfileString para obter a impressora padrão.
  • WriteProfileString para definir a impressora padrão.
O valor DEVICE que obter ou definir contém três elementos separados por vírgulas, como segue:
      printer name,driver name,port
				
por exemplo:
      My Printer,HPPCL5MS,lpt1:
				
Observe o seguinte:
  • Quando você usa esse método, você deve especificar uma impressora válida, o driver e a porta. Se não, as APIs serão não falhe e pode causar outros programas definir a impressora novamente para a impressora válida anterior ou se tornar confuso.

    Para recuperar o nome da impressora, o nome do driver e o nome de porta de todas as impressoras disponíveis, use o API EnumPrinters.
  • Windows NT mapeia a maioria das referências de arquivo .ini para o registro. Como resultado, GetProfileString e WriteProfileString ainda funcionam como se eles estavam executando sob Windows de 16 bits (Microsoft Windows e Windows para Workgroups).
  • Após definir a impressora padrão com GetPrinter, GetDefaultPrinter ou WriteProfileString, notifica todos os outros programas abertos da alteração por mensagem WM_SETTINGCHANGE a transmissão. Somente programas que tratam essa mensagem reconhecem a alteração.

    WM_SETTINGCHANGE e WM_WININICHANGE são o mesmo; usam WM_SETTINGCHANGE para programas Win32.

Código de exemplo

Exemplo de código a seguir mostra como recuperar a impressora padrão (DPGetDefaultPrinter) e definir a impressora padrão (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
				
o código parece não funcionar em algumas circunstâncias:
  • Se você deixar a chamada SendMessageTimeout, nenhum programa reconhece a alteração até que você reinicie o programa.
  • Se um programa diferente de 32 bits não manipula a mensagem WM_SETTINGCHANGE, o programa não reconhece a impressora padrão foi alterada. Você deve sair e reiniciar o programa para forçá-lo a reconhecer a alteração.
  • MAXBUFFERSIZE é muito pequeno para conter a seguinte seqüência:
    printername,portname,drivername
    					
  • Quando você usa o WriteProfileString API desse código de exemplo (que você deve usar somente para Windows NT 4.0 e versões anteriores), lembre-se de recuperar o nome de porta é passado para WriteProfileString pelo uso de API 32 bits GetPrinter.

    Embora este nome de porta é válido, programas de 16 bits não podem lê-lo e podem ter problemas. Se você usar esse método com o Windows NT (versões 4.0 e anteriores) e programas de 16 bits possuem compreender o novo nome de porta, você deve usar o alias de 16 bits para o nome de porta (NE0x, onde x é um número). Você pode encontrar o mapeamento entre nomes de porta de 32 bits e seus aliases de 16 bits no registro.

Referências

Para obter informações adicionais, clique nos números abaixo para ler os artigos na Base de dados de Conhecimento:
266767COMO: Definir qual impressora é a impressora padrão do sistema
140560COMO: Definir a impressora padrão programaticamente no Windows 95, Windows 98 ou Windows Me

Propriedades

ID do artigo: 246772 - Última revisão: segunda-feira, 12 de fevereiro de 2007 - Revisão: 2.6
A informação contida neste artigo aplica-se a:
  • Microsoft Platform Software Development Kit-January 2000 Edition nas seguintes plataformas
    • 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
  • Microsoft Windows XP Professional
  • the operating system: Microsoft Windows XP 64-Bit Edition
  • Microsoft Windows 2000 Server
Palavras-chave: 
kbmt kbdswgdi2003swept kbgdi kbhowto kbprint KB246772 KbMtpt
Tradução automática
IMPORTANTE: Este artigo foi traduzido por um sistema de tradução automática (também designado por Machine Translation ou MT), não tendo sido portanto traduzido ou revisto por pessoas. A Microsoft possui artigos traduzidos por aplicações (MT) e artigos traduzidos por tradutores profissionais, com o objetivo de oferecer em português a totalidade dos artigos existentes na base de dados de suporte. No entanto, a tradução automática não é sempre perfeita, podendo conter erros de vocabulário, sintaxe ou gramática. A Microsoft não é responsável por incoerências, erros ou prejuízos ocorridos em decorrência da utilização dos artigos MT por parte dos nossos clientes. A Microsoft realiza atualizações freqüentes ao software de tradução automática (MT). Obrigado.
Clique aqui para ver a versão em Inglês deste artigo: 246772

Submeter comentários

 

Contact us for more help

Contact us for more help
Connect with Answer Desk for expert help.
Get more support from smallbusiness.support.microsoft.com