Dica do SistemaEste artigo aplica-se a um sistema operativo diferente do que está a utilizar. Foi desactivado o conteúdo do artigo, que pode não ser relevante para si.
Importante
Este artigo aplica-se para o Windows 2000. Suporte para o Windows 2000 termina em 13 de Julho de 2010. O Windows 2000 End-of-Support Solution Center
(http://support.microsoft.com/?scid=http%3a%2f%2fsupport.microsoft.com%2fwin2000)
é um ponto de partida para planear a estratégia de migração a partir do Windows 2000. Para mais informações consulte a Microsoft Support Lifecycle
Policy
(http://support.microsoft.com/lifecycle/)
.
Com o Windows NT 4.0 (e versões anteriores), não é possível utilizar:
Em SetPrinter ou SetDefaultPrinter para definir a impressora predefinida.
Em EnumPrinters ou GetDefaultPrinter para obter a impressora predefinida.
Com o Windows NT 4.0, pode utilizar:
GetProfileString para obter a impressora predefinida.
WriteProfileString para predefinir a impressora.
O valor DEVICE que obter ou definir contém três elementos que são separados por vírgulas, da seguinte forma:
printer name,driver name,port
por exemplo:
My Printer,HPPCL5MS,lpt1:
Note o seguinte:
Quando utilizar este método, tem de especificar uma impressora válida, o controlador e a porta. Se não o fizer, as APIs irão não falhar e poderá causar outros programas definir a impressora novamente para a impressora válida anterior ou ficar confuso.
Para obter o nome da impressora, o nome do controlador e o nome da porta de todas as impressoras disponíveis, utilize EnumPrinters API.
Windows NT mapeia a maioria das referências de ficheiro .ini para o registo. Como resultado, GetProfileString e WriteProfileString funcionar ainda como se estas estavam em execução em Windows de 16 bits (Microsoft Windows e Windows for Workgroups).
Depois de definir a impressora predefinida com GetPrinter, GetDefaultPrinter ou WriteProfileString, notificar todos os outros programas abertos da alteração por mensagem WM_SETTINGCHANGE a difundir. Apenas os programas que processam esta mensagem reconhecer a alteração.
WM_SETTINGCHANGE e WM_WININICHANGE são os mesmos; utilizam WM_SETTINGCHANGE para programas do Win32.
Código de exemplo
O código de exemplo seguinte mostra como obter a impressora predefinida (DPGetDefaultPrinter) e definir a impressora predefinida (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 deixar fora a chamada de SendMessageTimeout, nenhum programa reconhece a alteração até que reinicie o programa.
Se um programa de 32 bits diferente não processa a mensagem WM_SETTINGCHANGE, o programa não reconhecem a que a impressora predefinida foi alterada. Deve sair e reiniciar o programa para forçar a reconhecer a alteração.
MAXBUFFERSIZE é demasiado pequena para conter a seguinte cadeia:
printername,portname,drivername
Quando utilizar o WriteProfileString API a partir deste código de exemplo (que tem utilizam apenas para o Windows NT 4.0 e versões anteriores), lembre-se de ter obtido o nome da porta que é transmitido para WriteProfileString por utilizar a API de 32 bits GetPrinter.
Apesar deste nome de porta é válido, programas de 16 bits não é possível lê-la e poderão ter problemas. Se utilizar este método com o Windows NT (versões 4.0 e anteriores) e programas de 16 bits tem de compreender o novo nome de porta, tem de utilizar o alias de 16 bits para o nome de porta (NE0x, onde x é um número). Pode encontrar o mapeamento entre nomes de portas de 32 bits e os respectivos aliases de 16 bits no registo.
Para obter informações adicionais, clique nos números de artigo existentes abaixo para visualizar os artigos na base de dados de conhecimento da Microsoft:
266767
(http://support.microsoft.com/kb/266767/EN-US/
)
COMO: Definir A impressora é a impressora predefinida do sistema
140560
(http://support.microsoft.com/kb/140560/EN-US/
)
COMO: Definir a impressora predefinida programaticamente no Windows 95, Windows 98 ou Windows Me
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 revisto ou traduzido por humanos. A Microsoft tem artigos traduzidos por aplicações (MT) e artigos traduzidos por tradutores profissionais. O objectivo é simples: oferecer em Português a totalidade dos artigos existentes na base de dados do suporte. Sabemos no entanto que a tradução automática não é sempre perfeita. Esta pode conter erros de vocabulário, sintaxe ou gramática? erros semelhantes aos que um estrangeiro realiza ao falar em Português. A Microsoft não é responsável por incoerências, erros ou estragos realizados na sequência da utilização dos artigos MT por parte dos nossos clientes. A Microsoft realiza actualizações frequentes ao software de tradução automática (MT). Obrigado.
Clique aqui para ver a versão em Inglês deste artigo: 246772
(http://support.microsoft.com/kb/246772/en-us/
)
Qual foi o esforço que despendeu pessoalmente para utilizar este artigo?
Muito baixo
Baixo
Moderado
Elevado
Muito elevado
Diga-nos porquê e o que podemos fazer para melhorar estas informações
Obrigado! Os seus comentários são utilizados para ajudar-nos a melhorar o conteúdo do nosso suporte. Para obter mais opções de assistência, visite a Home Page de Ajuda e Suporte.