QList<QPrinterInfo> QPrinterInfo::availablePrinters() { QList<QPrinterInfo> printers; DWORD needed = 0; DWORD returned = 0; if (!EnumPrinters(PRINTER_ENUM_LOCAL | PRINTER_ENUM_CONNECTIONS, NULL, 4, 0, 0, &needed, &returned)) { LPBYTE buffer = new BYTE[needed]; if (EnumPrinters(PRINTER_ENUM_LOCAL | PRINTER_ENUM_CONNECTIONS, NULL, 4, buffer, needed, &needed, &returned)) { PPRINTER_INFO_4 infoList = reinterpret_cast<PPRINTER_INFO_4>(buffer); QPrinterInfo defPrn = defaultPrinter(); for (uint i = 0; i < returned; ++i) { QString printerName(QString::fromWCharArray(infoList[i].pPrinterName)); QPrinterInfo printerInfo(printerName); if (printerInfo.printerName() == defPrn.printerName()) printerInfo.d_ptr->isDefault = true; printers.append(printerInfo); } } delete [] buffer; } return printers; }
static void EnumeratePrinters() { PRINTER_INFO_5 *info5Arr = NULL; DWORD bufSize = 0, printersCount; bool fOk = EnumPrinters(PRINTER_ENUM_LOCAL | PRINTER_ENUM_CONNECTIONS, NULL, 5, (LPBYTE)info5Arr, bufSize, &bufSize, &printersCount); if (!fOk) { info5Arr = (PRINTER_INFO_5 *)malloc(bufSize); fOk = EnumPrinters(PRINTER_ENUM_LOCAL | PRINTER_ENUM_CONNECTIONS, NULL, 5, (LPBYTE)info5Arr, bufSize, &bufSize, &printersCount); } if (!info5Arr) return; assert(fOk); if (!fOk) return; printf("Printers: %ld\n", printersCount); for (DWORD i = 0; i < printersCount; i++) { const WCHAR *printerName = info5Arr[i].pPrinterName; const WCHAR *printerPort = info5Arr[i].pPortName; bool fDefault = false; if (info5Arr[i].Attributes & PRINTER_ATTRIBUTE_DEFAULT) fDefault = true; wprintf(L"Name: %s, port: %s, default: %d\n", printerName, printerPort, (int)fDefault); } WCHAR buf[512]; bufSize = dimof(buf); fOk = GetDefaultPrinter(buf, &bufSize); if (!fOk) { if (ERROR_FILE_NOT_FOUND == GetLastError()) printf("No default printer\n"); } free(info5Arr); }
static char *printer_add_enum(int param, char *buffer, int offset, int *nprinters_ptr) { DWORD needed, nprinters; buffer = srealloc(buffer, offset+512); /* * Exploratory call to EnumPrinters to determine how much space * we'll need for the output. Discard the return value since it * will almost certainly be a failure due to lack of space. */ EnumPrinters(param, NULL, ENUM_LEVEL, buffer+offset, 512, &needed, &nprinters); if (needed < 512) needed = 512; buffer = srealloc(buffer, offset+needed); if (EnumPrinters(param, NULL, ENUM_LEVEL, buffer+offset, needed, &needed, &nprinters) == 0) return NULL; *nprinters_ptr += nprinters; return buffer; }
HDC UPrinter::getHDC() { DWORD dwNeeded, dwReturned ; HDC hdc ; PRINTER_INFO_4 * pinfo4 ; PRINTER_INFO_5 * pinfo5 ; if (GetVersion () & 0x80000000) // Windows 98 { EnumPrinters (PRINTER_ENUM_DEFAULT, NULL, 5, NULL, 0, &dwNeeded, &dwReturned) ; pinfo5 = (PRINTER_INFO_5 *)malloc (dwNeeded) ; EnumPrinters (PRINTER_ENUM_DEFAULT, NULL, 5, (PBYTE) pinfo5, dwNeeded, &dwNeeded, &dwReturned) ; hdc = CreateDC (NULL, pinfo5->pPrinterName, NULL, NULL) ; free (pinfo5) ; } else // Windows NT { EnumPrinters (PRINTER_ENUM_LOCAL, NULL, 4, NULL, 0, &dwNeeded, &dwReturned) ; pinfo4 = (PRINTER_INFO_4 *)malloc (dwNeeded) ; EnumPrinters (PRINTER_ENUM_LOCAL, NULL, 4, (PBYTE) pinfo4, dwNeeded, &dwNeeded, &dwReturned) ; hdc = CreateDC (NULL, pinfo4->pPrinterName, NULL, NULL) ; free (pinfo4) ; } return hdc ; }
BOOL CMainDlg::EnumerateLocalPrinters(HTREEITEM parent) { PRINTER_INFO_2 *pInfo; DWORD need, ret, i; EnumPrinters(PRINTER_ENUM_LOCAL, NULL, 2, NULL, 0, &need, &ret); pInfo = (PRINTER_INFO_2 *) new BYTE[need]; EnumPrinters(PRINTER_ENUM_LOCAL, NULL, 2, (LPBYTE) pInfo, need, &need, &ret); for (i = 0; i < ret; i++) m_tree.InsertItem(pInfo[i].pPrinterName, 1, 1, parent, NULL); delete pInfo; m_tree.Expand(parent); return TRUE; }
static void EnumeratePrinters() { str::Str<WCHAR> output; PRINTER_INFO_5 *info5Arr = nullptr; DWORD bufSize = 0, printersCount; bool fOk = EnumPrinters(PRINTER_ENUM_LOCAL | PRINTER_ENUM_CONNECTIONS, nullptr, 5, nullptr, bufSize, &bufSize, &printersCount); if (fOk || GetLastError() == ERROR_INSUFFICIENT_BUFFER) { info5Arr = (PRINTER_INFO_5 *)malloc(bufSize); fOk = EnumPrinters(PRINTER_ENUM_LOCAL | PRINTER_ENUM_CONNECTIONS, nullptr, 5, (LPBYTE)info5Arr, bufSize, &bufSize, &printersCount); } if (!fOk || !info5Arr) { output.AppendFmt(L"Call to EnumPrinters failed with error %#x", GetLastError()); MessageBox(nullptr, output.Get(), L"SumatraPDF - EnumeratePrinters", MB_OK | MB_ICONERROR); free(info5Arr); return; } ScopedMem<WCHAR> defName(GetDefaultPrinterName()); for (DWORD i = 0; i < printersCount; i++) { const WCHAR *printerName = info5Arr[i].pPrinterName; const WCHAR *printerPort = info5Arr[i].pPortName; bool fDefault = str::Eq(defName, printerName); output.AppendFmt(L"%s (Port: %s, attributes: %#x%s)\n", printerName, printerPort, info5Arr[i].Attributes, fDefault ? L", default" : L""); DWORD bins = DeviceCapabilities(printerName, printerPort, DC_BINS, nullptr, nullptr); DWORD binNames = DeviceCapabilities(printerName, printerPort, DC_BINNAMES, nullptr, nullptr); CrashIf(bins != binNames); if (0 == bins) { output.Append(L" - no paper bins available\n"); } else if (bins == (DWORD)-1) { output.AppendFmt(L" - Call to DeviceCapabilities failed with error %#x\n", GetLastError()); } else { ScopedMem<WORD> binValues(AllocArray<WORD>(bins)); DeviceCapabilities(printerName, printerPort, DC_BINS, (WCHAR *)binValues.Get(), nullptr); ScopedMem<WCHAR> binNameValues(AllocArray<WCHAR>(24 * binNames)); DeviceCapabilities(printerName, printerPort, DC_BINNAMES, binNameValues.Get(), nullptr); for (DWORD j = 0; j < bins; j++) { output.AppendFmt(L" - '%s' (%d)\n", binNameValues.Get() + 24 * j, binValues.Get()[j]); } } } free(info5Arr); MessageBox(nullptr, output.Get(), L"SumatraPDF - EnumeratePrinters", MB_OK | MB_ICONINFORMATION); }
OSStatus CSecondPage::LoadPrinterNames() { PBYTE buffer = NULL; OSStatus err = 0; // // rdar://problem/3701926 - Printer can't be installed twice // // First thing we want to do is make sure the printer isn't already installed. // If the printer name is found, we'll try and rename it until we // find a unique name // DWORD dwNeeded = 0, dwNumPrinters = 0; BOOL ok = EnumPrinters(PRINTER_ENUM_LOCAL, NULL, 4, NULL, 0, &dwNeeded, &dwNumPrinters); err = translate_errno( ok, errno_compat(), kUnknownErr ); if ((err == ERROR_INSUFFICIENT_BUFFER) && (dwNeeded > 0)) { try { buffer = new unsigned char[dwNeeded]; } catch (...) { buffer = NULL; } require_action( buffer, exit, kNoMemoryErr ); ok = EnumPrinters(PRINTER_ENUM_LOCAL, NULL, 4, buffer, dwNeeded, &dwNeeded, &dwNumPrinters); err = translate_errno( ok, errno_compat(), kUnknownErr ); require_noerr( err, exit ); for (DWORD index = 0; index < dwNumPrinters; index++) { PRINTER_INFO_4 * lppi4 = (PRINTER_INFO_4*) (buffer + index * sizeof(PRINTER_INFO_4)); m_printerNames[lppi4->pPrinterName] = lppi4->pPrinterName; } } exit: if (buffer != NULL) { delete [] buffer; } return err; }
static int prn_query( Handle self, const char * printer, LPPRINTER_INFO_2 info) { DWORD returned, needed; LPPRINTER_INFO_2 ppi, useThis = nil; int i; Bool useDefault = ( printer == nil || strlen( printer) == 0); char * device; EnumPrinters( PRINTER_ENUM_FAVORITE | PRINTER_ENUM_LOCAL, nil, 2, nil, 0, &needed, &returned); ppi = ( LPPRINTER_INFO_2) malloc( needed + 4); if ( !ppi) return 0; if ( !EnumPrinters( PRINTER_ENUM_FAVORITE | PRINTER_ENUM_LOCAL, nil, 2, ( LPBYTE) ppi, needed, &needed, &returned)) { apiErr; free( ppi); return 0; } if ( returned == 0) { apcErr( errNoPrinters); free( ppi); return 0; } device = apc_prn_get_default( self); for ( i = 0; i < returned; i++) { if ( useDefault && device && ( strcmp( device, ppi[ i]. pPrinterName) == 0)) { useThis = &ppi[ i]; break; } if ( !useDefault && ( strcmp( printer, ppi[ i]. pPrinterName) == 0)) { useThis = &ppi[ i]; break; } } if ( useDefault && useThis == nil) useThis = ppi; if ( useThis) ppi_create( info, useThis); if ( !useThis) apcErr( errInvPrinter); free( ppi); return useThis ? 1 : -2; }
PrinterInfo* apc_prn_enumerate( Handle self, int * count) { DWORD returned, needed; LPPRINTER_INFO_2 ppi; PPrinterInfo list; char *printer; int i; *count = 0; objCheck nil; EnumPrinters( PRINTER_ENUM_FAVORITE | PRINTER_ENUM_LOCAL, nil, 2, nil, 0, &needed, &returned); ppi = ( LPPRINTER_INFO_2) malloc( needed + 4); if ( !ppi) return nil; if ( !EnumPrinters( PRINTER_ENUM_FAVORITE | PRINTER_ENUM_LOCAL, nil, 2, ( LPBYTE) ppi, needed, &needed, &returned)) { apiErr; free( ppi); return nil; } if ( returned == 0) { apcErr( errNoPrinters); free( ppi); return nil; } printer = apc_prn_get_default( self); list = ( PPrinterInfo) malloc( returned * sizeof( PrinterInfo)); if ( !list) { free( ppi); return nil; } for ( i = 0; i < returned; i++) { strncpy( list[ i]. name, ppi[ i]. pPrinterName, 255); list[ i]. name[ 255] = 0; strncpy( list[ i]. device, ppi[ i]. pPortName, 255); list[ i]. device[ 255] = 0; list[ i]. defaultPrinter = (( printer != nil) && ( strcmp( printer, list[ i]. name) == 0)); } *count = returned; free( ppi); return list; }
HDC GetPrinterDC () { DWORD dwNeeded, dwReturned; HDC hdc; PRINTER_INFO_4 *pinfo4; EnumPrinters(PRINTER_ENUM_LOCAL, NULL, 4, NULL, 0, &dwNeeded, &dwReturned); pinfo4 = (PPRINTER_INFO_4) malloc(dwNeeded); EnumPrinters(PRINTER_ENUM_LOCAL, NULL, 4, (PBYTE) pinfo4, dwNeeded, &dwNeeded, &dwReturned); hdc = CreateDC(NULL, pinfo4[2].pPrinterName, NULL, NULL); free(pinfo4); return hdc; }
static BOOL test_EnumPrinters(struct torture_context *tctx, LPSTR servername) { DWORD levels[] = { 1, 2, 5 }; DWORD success[] = { 1, 1, 1 }; DWORD i; DWORD flags = PRINTER_ENUM_NAME; LPBYTE buffer = NULL; for (i=0; i < ARRAY_SIZE(levels); i++) { DWORD needed = 0; DWORD returned = 0; DWORD err = 0; char tmp[1024]; torture_comment(tctx, "Testing EnumPrinters level %d", levels[i]); EnumPrinters(flags, servername, levels[i], NULL, 0, &needed, &returned); err = GetLastError(); if (err == ERROR_INSUFFICIENT_BUFFER) { err = 0; buffer = malloc(needed); torture_assert(tctx, buffer, "malloc failed"); if (!EnumPrinters(flags, servername, levels[i], buffer, needed, &needed, &returned)) { err = GetLastError(); } } if (err) { sprintf(tmp, "EnumPrinters failed level %d on [%s] (buffer size = %d), error: %s\n", levels[i], servername, needed, errstr(err)); if (success[i]) { torture_fail(tctx, tmp); } else { torture_warning(tctx, tmp); } } if (tctx->print) { print_printer_info_bylevel(levels[i], buffer, returned); } free(buffer); buffer = NULL; } return TRUE; }
char * get_queues(void) { int i; DWORD count, needed; PRINTER_INFO_1 *prinfo; char *enumbuffer; char *buffer; char *p; /* enumerate all available printers */ EnumPrinters(PRINTER_ENUM_CONNECTIONS | PRINTER_ENUM_LOCAL, NULL, 1, NULL, 0, &needed, &count); if (needed == 0) { /* no printers */ enumbuffer = malloc(4); if (enumbuffer == (char *)NULL) return NULL; memset(enumbuffer, 0, 4); return enumbuffer; } enumbuffer = malloc(needed); if (enumbuffer == (char *)NULL) return NULL; if (!EnumPrinters(PRINTER_ENUM_CONNECTIONS | PRINTER_ENUM_LOCAL, NULL, 1, (LPBYTE) enumbuffer, needed, &needed, &count)) { char buf[256]; free(enumbuffer); sprintf(buf, "EnumPrinters() failed, error code = %d", GetLastError()); MessageBox((HWND) NULL, buf, szAppName, MB_OK | MB_ICONSTOP); return NULL; } prinfo = (PRINTER_INFO_1 *) enumbuffer; if ((buffer = malloc(PORT_BUF_SIZE)) == (char *)NULL) { free(enumbuffer); return NULL; } /* copy printer names to single buffer */ p = buffer; for (i = 0; i < count; i++) { if (strlen(prinfo[i].pName) + 1 < (PORT_BUF_SIZE - (p - buffer))) { strcpy(p, prinfo[i].pName); p += strlen(p) + 1; } } *p = '\0'; /* double null at end */ free(enumbuffer); return buffer; }
int prtr_enum_devices() { int size = 0; if (EnumPrinters(PRINTER_ENUM_LOCAL, NULL, 2, _printers, sizeof(PRINTER_INFO_2)*PRINT_BUFFER_SIZE, &size, &_printer_count) == 0) return -1; return _printer_count; }
static PRINTER_INFO_2 *GetPrinters( int *pCount ) { DWORD dwNeeded = 0, dwReturned = 0; PRINTER_INFO_2 *result = NULL; DWORD dwFlags = PRINTER_ENUM_LOCAL | PRINTER_ENUM_CONNECTIONS; DBG_ASSERT(pCount!=NULL); *pCount = 0; BOOL fResult = EnumPrinters(dwFlags, NULL, 2, NULL, 0, &dwNeeded, &dwReturned); while (!fResult) { if (GetLastError()!=ERROR_INSUFFICIENT_BUFFER) break; PRINTER_INFO_2* oldResult = result; result = (PRINTER_INFO_2*) realloc( result, dwNeeded ); if( result == NULL ) { free(oldResult); break; } fResult = EnumPrinters(dwFlags, NULL, 2, (BYTE*) result, dwNeeded, &dwNeeded, &dwReturned); } *pCount = dwReturned; return result; }
void MainFrame::EnumInstalledDriver() { // 清空界面中list中显示的打印机列表 CContainerUI* pDriverList = static_cast<CContainerUI*>(paint_manager_.FindControl(_T("driver_list"))); if (pDriverList != NULL) pDriverList->RemoveAll(); // 枚举本地计算机上所有安装的打印机驱动(实际使用时可以只枚举自家的打印机驱动) LPBYTE lpBuffer = NULL; DWORD dwNeeded = 0,dwReturned = 0; EnumPrinters(PRINTER_ENUM_LOCAL, NULL, 1, NULL, 0, &dwNeeded, &dwReturned); if (dwNeeded == 0) return; lpBuffer = (LPBYTE)malloc(dwNeeded); if (lpBuffer == NULL) return; EnumPrinters(PRINTER_ENUM_LOCAL, NULL, 1, lpBuffer, dwNeeded, &dwNeeded, &dwReturned); for (DWORD dwIndex = 0; (dwIndex < dwReturned) && (pDriverList != NULL); dwIndex++) { COptionUI* pDriver = new COptionUI(); if (pDriver != NULL) { pDriver->ApplyAttributeList(_T("padding=\"15,0,0,0\" height=\"35\" textpadding=\"20,0,0,0\" align=\"left\" normalimage=\"res='124' restype='png' dest='0,10,15,25'\" hotimage=\"res='125' restype='png' dest='0,10,15,25'\" selectedimage=\"res='126' restype='png' dest='0,10,15,25'\"")); pDriver->SetText(((PRINTER_INFO_1*)lpBuffer + dwIndex)->pName); pDriverList->Add(pDriver); } } LPTSTR lpDefaultPrinter; GetDefaultPrinter(NULL, &dwNeeded); lpDefaultPrinter = (LPTSTR)malloc(dwNeeded * sizeof(TCHAR)); GetDefaultPrinter((LPTSTR)lpDefaultPrinter, &dwNeeded); free(lpDefaultPrinter); free(lpBuffer); }
static BOOL test_EachPrinter(struct torture_context *tctx, LPSTR servername, LPSTR architecture, LPPRINTER_DEFAULTS defaults) { DWORD needed = 0; DWORD returned = 0; DWORD err = 0; char tmp[1024]; DWORD i; DWORD flags = PRINTER_ENUM_NAME; PPRINTER_INFO_1 buffer = NULL; BOOL ret = TRUE; torture_comment(tctx, "Testing EnumPrinters level %d", 1); EnumPrinters(flags, servername, 1, NULL, 0, &needed, &returned); err = GetLastError(); if (err == ERROR_INSUFFICIENT_BUFFER) { err = 0; buffer = (PPRINTER_INFO_1)malloc(needed); torture_assert(tctx, buffer, "malloc failed"); if (!EnumPrinters(flags, servername, 1, (LPBYTE)buffer, needed, &needed, &returned)) { err = GetLastError(); } } if (err) { sprintf(tmp, "EnumPrinters failed level %d on [%s] (buffer size = %d), error: %s\n", 1, servername, needed, errstr(err)); torture_fail(tctx, tmp); } for (i=0; i < returned; i++) { ret &= test_OnePrinter(tctx, buffer[i].pName, architecture, defaults); } free(buffer); return ret; }
static PRINTER_INFO_5 *GetDefaultPrinters( int *pCount ) { DWORD dwNeeded = 0, dwReturned = 0; PRINTER_INFO_5 *result = NULL; DWORD dwFlags = PRINTER_ENUM_DEFAULT; DBG_ASSERT(pCount!=NULL); *pCount = 0; BOOL fResult = EnumPrinters(dwFlags, NULL, 5, NULL, 0, &dwNeeded, &dwReturned); while (!fResult) { if (GetLastError()!=ERROR_INSUFFICIENT_BUFFER) break; result = (PRINTER_INFO_5*) realloc( result, dwNeeded ); if( result == NULL ) break; fResult = EnumPrinters(dwFlags, NULL, 5, (BYTE*) result, dwNeeded, &dwNeeded, &dwReturned); } *pCount = dwReturned; return result; }
uint printer_start_enum(void) { DWORD size = 0, num = 0; while ( !EnumPrinters(PRINTER_ENUM_LOCAL | PRINTER_ENUM_CONNECTIONS, 0, 4, (LPBYTE)printer_info, size, &size, &num) && GetLastError() == ERROR_INSUFFICIENT_BUFFER ) { printer_info = realloc(printer_info, size); } return num; }
void PrintFiles(FileList* SrcPanel) { _ALGO(CleverSysLog clv(L"Alt-F5 (PrintFiles)")); string strPrinterName; DWORD Needed = 0, Returned; DWORD FileAttr; string strSelName; size_t DirsCount=0; size_t SelCount=SrcPanel->GetSelCount(); if (!SelCount) { _ALGO(SysLog(L"Error: !SelCount")); return; } // проверка каталогов _ALGO(SysLog(L"Check for FILE_ATTRIBUTE_DIRECTORY")); SrcPanel->GetSelName(nullptr,FileAttr); while (SrcPanel->GetSelName(&strSelName,FileAttr)) { if (TestParentFolderName(strSelName) || (FileAttr & FILE_ATTRIBUTE_DIRECTORY)) DirsCount++; } if (DirsCount==SelCount) return; EnumPrinters(PRINTER_ENUM_LOCAL | PRINTER_ENUM_CONNECTIONS, nullptr, PRINTER_INFO_LEVEL, nullptr, 0, &Needed, &Returned); if (!Needed) return; block_ptr<PRINTER_INFO> pi(Needed); if (!EnumPrinters(PRINTER_ENUM_LOCAL|PRINTER_ENUM_CONNECTIONS,nullptr,PRINTER_INFO_LEVEL,(LPBYTE)pi.get(),Needed,&Needed,&Returned)) { Global->CatchError(); Message(MSG_WARNING|MSG_ERRORTYPE,1,MSG(MPrintTitle),MSG(MCannotEnumeratePrinters),MSG(MOk)); return; } { _ALGO(CleverSysLog clv2(L"Show Menu")); LangString strTitle; string strName; if (SelCount==1) { SrcPanel->GetSelName(nullptr,FileAttr); SrcPanel->GetSelName(&strName,FileAttr); strSelName = TruncStr(strName,50); strTitle = MPrintTo; strTitle << InsertQuote(strSelName); } else { _ALGO(SysLog(L"Correct: SelCount-=DirsCount")); SelCount-=DirsCount; strTitle = MPrintFilesTo; strTitle << SelCount; } VMenu2 PrinterList(strTitle,nullptr,0,ScrY-4); PrinterList.SetFlags(VMENU_WRAPMODE|VMENU_SHOWAMPERSAND); PrinterList.SetPosition(-1,-1,0,0); AddToPrintersMenu(&PrinterList,pi.get(),Returned); if (PrinterList.Run()<0) { _ALGO(SysLog(L"ESC")); return; } strPrinterName = NullToEmpty(static_cast<const wchar_t*>(PrinterList.GetUserData(nullptr, 0))); } HANDLE hPrinter; if (!OpenPrinter(UNSAFE_CSTR(strPrinterName), &hPrinter,nullptr)) { Global->CatchError(); Message(MSG_WARNING|MSG_ERRORTYPE,1,MSG(MPrintTitle),MSG(MCannotOpenPrinter), strPrinterName.data(),MSG(MOk)); _ALGO(SysLog(L"Error: Cannot Open Printer")); return; } { _ALGO(CleverSysLog clv3(L"Print selected Files")); SCOPED_ACTION(SaveScreen); auto PR_PrintMsg = [](){ Message(0, 0, MSG(MPrintTitle), MSG(MPreparingForPrinting)); }; SCOPED_ACTION(TPreRedrawFuncGuard)(std::make_unique<PreRedrawItem>(PR_PrintMsg)); SetCursorType(false, 0); PR_PrintMsg(); auto hPlugin=SrcPanel->GetPluginHandle(); int PluginMode=SrcPanel->GetMode()==PLUGIN_PANEL && !Global->CtrlObject->Plugins->UseFarCommand(hPlugin,PLUGIN_FARGETFILE); SrcPanel->GetSelName(nullptr,FileAttr); while (SrcPanel->GetSelName(&strSelName,FileAttr)) { if (TestParentFolderName(strSelName) || (FileAttr & FILE_ATTRIBUTE_DIRECTORY)) continue; int Success=FALSE; string FileName; string strTempDir, strTempName; if (PluginMode) { if (FarMkTempEx(strTempDir)) { api::CreateDirectory(strTempDir,nullptr); auto ListItem = SrcPanel->GetLastSelectedItem(); if (ListItem) { PluginPanelItem PanelItem; FileList::FileListToPluginItem(*ListItem, &PanelItem); if (Global->CtrlObject->Plugins->GetFile(hPlugin,&PanelItem,strTempDir,strTempName,OPM_SILENT)) FileName = strTempName; else api::RemoveDirectory(strTempDir); FreePluginPanelItem(PanelItem); } } } else FileName = strSelName; api::File SrcFile; if(SrcFile.Open(FileName, GENERIC_READ, FILE_SHARE_READ|FILE_SHARE_WRITE, nullptr, OPEN_EXISTING)) { DOC_INFO_1 di1 = {UNSAFE_CSTR(FileName)}; if (StartDocPrinter(hPrinter,1,(LPBYTE)&di1)) { char Buffer[8192]; DWORD Read,Written; Success=TRUE; while (SrcFile.Read(Buffer, sizeof(Buffer), Read) && Read > 0) if (!WritePrinter(hPrinter,Buffer,Read,&Written)) { Global->CatchError(); Success=FALSE; break; } EndDocPrinter(hPrinter); } SrcFile.Close(); } if (!strTempName.empty()) { DeleteFileWithFolder(strTempName); } if (Success) SrcPanel->ClearLastGetSelection(); else { if (Message(MSG_WARNING|MSG_ERRORTYPE,2,MSG(MPrintTitle),MSG(MCannotPrint), strSelName.data(),MSG(MSkip),MSG(MCancel))) break; } } ClosePrinter(hPrinter); } SrcPanel->Redraw(); }
BOOL EnumGeneric( IN PROC fnEnum, IN DWORD Level, IN PBYTE *ppEnumData, IN DWORD cbBuf, OUT LPDWORD pcbReturned, OUT LPDWORD pcReturned, IN PVOID Arg1, IN PVOID Arg2, IN PVOID Arg3 ) { BOOL rc; BOOL UnknownFunction = FALSE; DWORD cbRealloc; if( fnEnum == (PROC)EnumPrinters ) rc = EnumPrinters( (DWORD)Arg1, (LPTSTR)Arg2, COMMON_ARGS ); // Flags Name else if( fnEnum == (PROC)EnumJobs ) rc = EnumJobs( (HANDLE)Arg1, (DWORD)Arg2, (DWORD)Arg3, COMMON_ARGS ); // hPrinter FirstJob NoJobs else if( fnEnum == (PROC)EnumPrinterDrivers ) rc = EnumPrinterDrivers( (LPTSTR)Arg1, (LPTSTR)Arg2, COMMON_ARGS ); // pName pEnvironment else if( fnEnum == (PROC)EnumForms ) rc = EnumForms( (HANDLE)Arg1, COMMON_ARGS ); // hPrinter else if( fnEnum == (PROC)EnumMonitors ) rc = EnumMonitors( (LPTSTR)Arg1, COMMON_ARGS ); // pName else if( fnEnum == (PROC)EnumPorts ) rc = EnumPorts( (LPTSTR)Arg1, COMMON_ARGS ); // pName else if( fnEnum == (PROC)EnumPrintProcessors ) rc = EnumPrintProcessors( (LPTSTR)Arg1, (LPTSTR)Arg2, COMMON_ARGS ); // pName pEnvironment else if( fnEnum == (PROC)EnumPrintProcessorDatatypes ) rc = EnumPrintProcessorDatatypes( (LPTSTR)Arg1, (LPTSTR)Arg2, COMMON_ARGS ); // pName pPrintProcessorName else { *ppEnumData = NULL; UnknownFunction = TRUE; DBGMSG( DBG_ERROR, ( "EnumGeneric called with unknown function\n" ) ); rc = FALSE; } if( ( rc == FALSE ) && ( UnknownFunction == FALSE ) ) { if( GetLastError( ) == ERROR_INSUFFICIENT_BUFFER ) { cbRealloc = *pcbReturned; DBGMSG( DBG_TRACE, ( "EnumGeneric: Reallocating %d (0x%x) bytes @%08x\n", cbBuf, cbBuf, *ppEnumData ) ); if( cbBuf == 0 ) *ppEnumData = AllocSplMem( cbRealloc ); else *ppEnumData = ReallocSplMem( *ppEnumData, cbRealloc ); cbBuf = cbRealloc; if( *ppEnumData ) { DBGMSG( DBG_TRACE, ( "EnumGeneric: %d (0x%x) bytes reallocated @%08x\n", cbBuf, cbBuf, *ppEnumData ) ); if( fnEnum == (PROC)EnumPrinters ) rc = EnumPrinters( (DWORD)Arg1, (LPTSTR)Arg2, COMMON_ARGS ); // Flags Name else if( fnEnum == (PROC)EnumJobs ) rc = EnumJobs( (HANDLE)Arg1, (DWORD)Arg2, (DWORD)Arg3, COMMON_ARGS ); // hPrinter FirstJob NoJobs else if( fnEnum == (PROC)EnumPrinterDrivers ) rc = EnumPrinterDrivers( (LPTSTR)Arg1, (LPTSTR)Arg2, COMMON_ARGS ); // pName pEnvironment else if( fnEnum == (PROC)EnumForms ) rc = EnumForms( (HANDLE)Arg1, COMMON_ARGS ); // hPrinter else if( fnEnum == (PROC)EnumMonitors ) rc = EnumMonitors( (LPTSTR)Arg1, COMMON_ARGS ); // pName else if( fnEnum == (PROC)EnumPorts ) rc = EnumPorts( (LPTSTR)Arg1, COMMON_ARGS ); // pName else if( fnEnum == (PROC)EnumPrintProcessors ) rc = EnumPrintProcessors( (LPTSTR)Arg1, (LPTSTR)Arg2, COMMON_ARGS ); // pName pEnvironment else if( fnEnum == (PROC)EnumPrintProcessorDatatypes ) rc = EnumPrintProcessorDatatypes( (LPTSTR)Arg1, (LPTSTR)Arg2, COMMON_ARGS ); // pName pPrintProcessorName /* If things haven't worked out, free up the buffer. * We do this because otherwise the caller will not know * whether the pointer is valid any more, * since ReallocSplMem might have failed. */ if( rc == FALSE ) { if( *ppEnumData ) FreeSplMem( *ppEnumData ); *ppEnumData = NULL; *pcbReturned = 0; *pcReturned = 0; } /* Don't rely on pcbReturned having the same value * that was passed in: */ else *pcbReturned = cbRealloc; } } else { if( *ppEnumData ) FreeSplMem( *ppEnumData ); *ppEnumData = NULL; *pcbReturned = 0; *pcReturned = 0; rc = FALSE; } } else *pcbReturned = cbBuf; return rc; }
/* get number of printers, default printer number and printer names */ void kGUISystemMINGW::GetPrinters(void) { DWORD numprinters; DWORD defprinter=0; DWORD dwSizeNeeded=0; DWORD dwItem; LPPRINTER_INFO_2 printerinfo = NULL; // Get buffer size kGUI::Trace("EnumPrinters ( PRINTER_ENUM_LOCAL | PRINTER_ENUM_CONNECTIONS , NULL, 2, NULL, 0, &dwSizeNeeded, &numprinters );\n"); 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 ); kGUI::Trace("printerinfo = (LPPRINTER_INFO_2)new char[%d];\n",dwSizeNeeded); printerinfo = (LPPRINTER_INFO_2)new char[dwSizeNeeded]; kGUI::Trace("EnumPrinters ( PRINTER_ENUM_LOCAL | PRINTER_ENUM_CONNECTIONS,NULL,2,(LPBYTE)printerinfo,dwSizeNeeded,&dwSizeNeeded,&numprinters);\n"); 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 ) { kGUI::Trace("No printers found!;\n"); numprinters=0; } { DWORD size=0; /* if no default printer is set then GetDefaultPrinter will leave this unitlzd */ // Get the size of the default printer name. kGUI::Trace("GetDefaultPrinter(NULL, &size);\n"); GetDefaultPrinter(NULL, &size); kGUI::Trace("done GetDefaultPrinter size=%d;\n",size); if(size) { // Allocate a buffer large enough to hold the printer name. kGUI::Trace("TCHAR* buffer = new TCHAR[%d];\n",size); TCHAR* buffer = new TCHAR[size]; // Get the printer name. kGUI::Trace("GetDefaultPrinter(buffer, &size);\n"); GetDefaultPrinter(buffer, &size); for ( dwItem = 0; dwItem < numprinters; dwItem++ ) { kGUI::Trace("printername[%d]='%s'\n",dwItem,printerinfo[dwItem].pPrinterName); if(!strcmp(buffer,printerinfo[dwItem].pPrinterName)) defprinter=dwItem; } kGUI::Trace("delete buffer;\n"); delete buffer; } } kGUI::Trace("copying printer names numprinters=%d,defaultprinter=%d;\n",numprinters,defprinter); /* copy printer info */ m_numprinters=numprinters; m_defprinternum=defprinter; if(m_numprinters) { m_printers.Init(m_numprinters,0); for(unsigned int i=0;i<m_numprinters;++i) m_printers.GetEntryPtr(i)->SetName(printerinfo[i].pPrinterName); } if(printerinfo) delete []printerinfo; /* if no printers, then add a default 'no printer' so print code doesn't crash */ if(!m_numprinters) { m_numprinters=1; m_printers.Init(m_numprinters,0); m_printers.GetEntryPtr(0)->SetName("No Printers"); m_printers.GetEntryPtr(0)->SetDefaultPageSize(); } kGUI::Trace("exiting GetPrinters();\n"); }
void PrintFiles(Panel *SrcPanel) { _ALGO(CleverSysLog clv(L"Alt-F5 (PrintFiles)")); string strPrinterName; DWORD Needed,Returned; int PrinterNumber; DWORD FileAttr; string strSelName; long DirsCount=0; int SelCount=SrcPanel->GetSelCount(); if (!SelCount) { _ALGO(SysLog(L"Error: !SelCount")); return; } // проверка каталогов _ALGO(SysLog(L"Check for FILE_ATTRIBUTE_DIRECTORY")); SrcPanel->GetSelName(nullptr,FileAttr); while (SrcPanel->GetSelName(&strSelName,FileAttr)) { if (TestParentFolderName(strSelName) || (FileAttr & FILE_ATTRIBUTE_DIRECTORY)) DirsCount++; } if (DirsCount==SelCount) return; PRINTER_INFO *pi = nullptr; if (EnumPrinters(PRINTER_ENUM_LOCAL|PRINTER_ENUM_CONNECTIONS,nullptr,PRINTER_INFO_LEVEL,nullptr,0,&Needed,&Returned) || Needed<=0) return; pi = (PRINTER_INFO *)xf_malloc(Needed); if (!EnumPrinters(PRINTER_ENUM_LOCAL|PRINTER_ENUM_CONNECTIONS,nullptr,PRINTER_INFO_LEVEL,(LPBYTE)pi,Needed,&Needed,&Returned)) { Message(MSG_WARNING|MSG_ERRORTYPE,1,MSG(MPrintTitle),MSG(MCannotEnumeratePrinters),MSG(MOk)); xf_free(pi); return; } { _ALGO(CleverSysLog clv2(L"Show Menu")); string strTitle; string strName; if (SelCount==1) { SrcPanel->GetSelName(nullptr,FileAttr); SrcPanel->GetSelName(&strName,FileAttr); TruncStr(strName,50); strSelName=strName; InsertQuote(strSelName); strTitle.Format(MSG(MPrintTo), strSelName.CPtr()); } else { _ALGO(SysLog(L"Correct: SelCount-=DirsCount")); SelCount-=DirsCount; strTitle.Format(MSG(MPrintFilesTo),SelCount); } VMenu PrinterList(strTitle,nullptr,0,ScrY-4); PrinterList.SetFlags(VMENU_WRAPMODE|VMENU_SHOWAMPERSAND); PrinterList.SetPosition(-1,-1,0,0); AddToPrintersMenu(&PrinterList,pi,Returned); PrinterList.Process(); PrinterNumber=PrinterList.Modal::GetExitCode(); if (PrinterNumber<0) { xf_free(pi); _ALGO(SysLog(L"ESC")); return; } int nSize = PrinterList.GetUserDataSize(); wchar_t *PrinterName = strPrinterName.GetBuffer(nSize); PrinterList.GetUserData(PrinterName, nSize); strPrinterName.ReleaseBuffer(); } HANDLE hPrinter; if (!OpenPrinter((wchar_t*)strPrinterName.CPtr(),&hPrinter,nullptr)) { Message(MSG_WARNING|MSG_ERRORTYPE,1,MSG(MPrintTitle),MSG(MCannotOpenPrinter), strPrinterName,MSG(MOk)); xf_free(pi); _ALGO(SysLog(L"Error: Cannot Open Printer")); return; } { _ALGO(CleverSysLog clv3(L"Print selected Files")); //SaveScreen SaveScr; TPreRedrawFuncGuard preRedrawFuncGuard(PR_PrintMsg); SetCursorType(FALSE,0); PR_PrintMsg(); HANDLE hPlugin=SrcPanel->GetPluginHandle(); int PluginMode=SrcPanel->GetMode()==PLUGIN_PANEL && !CtrlObject->Plugins.UseFarCommand(hPlugin,PLUGIN_FARGETFILE); SrcPanel->GetSelName(nullptr,FileAttr); while (SrcPanel->GetSelName(&strSelName,FileAttr)) { if (TestParentFolderName(strSelName) || (FileAttr & FILE_ATTRIBUTE_DIRECTORY)) continue; int Success=FALSE; LPCWSTR FileName = nullptr; string strTempDir, strTempName; if (PluginMode) { if (FarMkTempEx(strTempDir)) { apiCreateDirectory(strTempDir,nullptr); FileListItem ListItem; if (SrcPanel->GetLastSelectedItem(&ListItem)) { PluginPanelItem PanelItem; FileList::FileListToPluginItem(&ListItem,&PanelItem); if (CtrlObject->Plugins.GetFile(hPlugin,&PanelItem,strTempDir,strTempName,OPM_SILENT)) FileName = strTempName; else apiRemoveDirectory(strTempDir); FileList::FreePluginPanelItem(&PanelItem); } } } else FileName = strSelName; File SrcFile; if(SrcFile.Open(FileName, GENERIC_READ, FILE_SHARE_READ|FILE_SHARE_WRITE, nullptr, OPEN_EXISTING)) { DOC_INFO_1 di1 = {const_cast<LPWSTR>(FileName)}; if (StartDocPrinter(hPrinter,1,(LPBYTE)&di1)) { char Buffer[8192]; DWORD Read,Written; Success=TRUE; while (SrcFile.Read(Buffer, sizeof(Buffer), Read) && Read > 0) if (!WritePrinter(hPrinter,Buffer,Read,&Written)) { Success=FALSE; break; } EndDocPrinter(hPrinter); } SrcFile.Close(); } if (!strTempName.IsEmpty()) { DeleteFileWithFolder(strTempName); } if (Success) SrcPanel->ClearLastGetSelection(); else { if (Message(MSG_WARNING|MSG_ERRORTYPE,2,MSG(MPrintTitle),MSG(MCannotPrint), strSelName,MSG(MSkip),MSG(MCancel))) break; } } ClosePrinter(hPrinter); } SrcPanel->Redraw(); xf_free(pi); }
static void hb_GetDefaultPrinter( PHB_ITEM pPrinterName ) { #if ! defined( HB_OS_WIN_CE ) HB_BOOL bResult = HB_FALSE; hb_itemPutC( pPrinterName, NULL ); if( hb_iswin2k() ) /* Windows 2000 or later */ { typedef BOOL( WINAPI * DEFPRINTER ) ( LPTSTR, LPDWORD ); DEFPRINTER fnGetDefaultPrinter; HMODULE hWinSpool = hbwapi_LoadLibrarySystem( TEXT( "winspool.drv" ) ); if( hWinSpool ) { fnGetDefaultPrinter = ( DEFPRINTER ) GetProcAddress( hWinSpool, HB_WINAPI_FUNCTION_NAME( "GetDefaultPrinter" ) ); if( fnGetDefaultPrinter ) { TCHAR lpPrinterName[ 256 ]; DWORD dwSize = HB_SIZEOFARRAY( lpPrinterName ) - 1; bResult = ( *fnGetDefaultPrinter )( lpPrinterName, &dwSize ); HB_ITEMPUTSTR( pPrinterName, lpPrinterName ); } FreeLibrary( hWinSpool ); } } if( ! bResult ) /* Win9x and Windows NT 4.0 or earlier & 2000+ if necessary for some reason i.e. dll could not load! */ { TCHAR lpPrinterName[ 256 ]; DWORD dwSize = GetProfileString( TEXT( "windows" ), TEXT( "device" ), TEXT( "" ), lpPrinterName, ( DWORD ) HB_SIZEOFARRAY( lpPrinterName ) - 1 ); if( dwSize && dwSize < HB_SIZEOFARRAY( lpPrinterName ) ) { dwSize = 0; while( lpPrinterName[ dwSize ] != '\0' && lpPrinterName[ dwSize ] != ',' ) dwSize++; lpPrinterName[ dwSize ] = '\0'; bResult = HB_TRUE; HB_ITEMPUTSTRLEN( pPrinterName, lpPrinterName, dwSize ); } } if( ! bResult && hb_iswin9x() ) { /* This option should never be required but is included because of this article http://support.microsoft.com/kb/246772/en-us This option will not enumerate any network printers. From the SDK technical reference for EnumPrinters(); If Level is 2 or 5, Name is a pointer to a null-terminated string that specifies the name of a server whose printers are to be enumerated. If this string is NULL, then the function enumerates the printers installed on the local machine. */ DWORD dwNeeded = 0, dwReturned = 0; if( EnumPrinters( PRINTER_ENUM_DEFAULT, NULL, 2, NULL, 0, &dwNeeded, &dwReturned ) ) { if( dwNeeded ) { PRINTER_INFO_2 * pPrinterInfo = ( PRINTER_INFO_2 * ) hb_xgrab( dwNeeded ); if( EnumPrinters( PRINTER_ENUM_DEFAULT, NULL, 2, ( LPBYTE ) pPrinterInfo, dwNeeded, &dwNeeded, &dwReturned ) && dwReturned ) HB_ITEMPUTSTR( pPrinterName, pPrinterInfo->pPrinterName ); hb_xfree( pPrinterInfo ); } } } #else hb_itemPutC( pPrinterName, NULL ); #endif }
LRESULT CALLBACK WndProc (HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam) { static TCHAR szDevice[32], szWindowText[64] ; static int cxChar, cyChar, nCurrentDevice = IDM_SCREEN, nCurrentInfo = IDM_BASIC ; static DWORD dwNeeded, dwReturned ; static PRINTER_INFO_4 * pinfo4 ; static PRINTER_INFO_5 * pinfo5 ; DWORD i ; HDC hdc, hdcInfo ; HMENU hMenu ; HANDLE hPrint ; PAINTSTRUCT ps ; TEXTMETRIC tm ; switch (message) { case WM_CREATE : hdc = GetDC (hwnd) ; SelectObject (hdc, GetStockObject (SYSTEM_FIXED_FONT)) ; GetTextMetrics (hdc, &tm) ; cxChar = tm.tmAveCharWidth ; cyChar = tm.tmHeight + tm.tmExternalLeading ; ReleaseDC (hwnd, hdc) ; // fall through case WM_SETTINGCHANGE: hMenu = GetSubMenu (GetMenu (hwnd), 0) ; while (GetMenuItemCount (hMenu) > 1) DeleteMenu (hMenu, 1, MF_BYPOSITION) ; // Get a list of all local and remote printers // // First, find out how large an array we need; this // call will fail, leaving the required size in dwNeeded // // Next, allocate space for the info array and fill it // // Put the printer names on the menu. if (GetVersion () & 0x80000000) // Windows 98 { EnumPrinters (PRINTER_ENUM_LOCAL, NULL, 5, NULL, 0, &dwNeeded, &dwReturned) ; pinfo5 = malloc (dwNeeded) ; EnumPrinters (PRINTER_ENUM_LOCAL, NULL, 5, (PBYTE) pinfo5, dwNeeded, &dwNeeded, &dwReturned) ; for (i = 0 ; i < dwReturned ; i++) { AppendMenu (hMenu, (i+1) % 16 ? 0 : MF_MENUBARBREAK, i + 1, pinfo5[i].pPrinterName) ; } free (pinfo5) ; } else // Windows NT { EnumPrinters (PRINTER_ENUM_LOCAL, NULL, 4, NULL, 0, &dwNeeded, &dwReturned) ; pinfo4 = malloc (dwNeeded) ; EnumPrinters (PRINTER_ENUM_LOCAL, NULL, 4, (PBYTE) pinfo4, dwNeeded, &dwNeeded, &dwReturned) ; for (i = 0 ; i < dwReturned ; i++) { AppendMenu (hMenu, (i+1) % 16 ? 0 : MF_MENUBARBREAK, i + 1, pinfo4[i].pPrinterName) ; } free (pinfo4) ; } AppendMenu (hMenu, MF_SEPARATOR, 0, NULL) ; AppendMenu (hMenu, 0, IDM_DEVMODE, TEXT ("Properties")) ; wParam = IDM_SCREEN ; // fall through case WM_COMMAND : hMenu = GetMenu (hwnd) ; if (LOWORD (wParam) == IDM_SCREEN || // IDM_SCREEN & Printers LOWORD (wParam) < IDM_DEVMODE) { CheckMenuItem (hMenu, nCurrentDevice, MF_UNCHECKED) ; nCurrentDevice = LOWORD (wParam) ; CheckMenuItem (hMenu, nCurrentDevice, MF_CHECKED) ; } else if (LOWORD (wParam) == IDM_DEVMODE) // Properties selection { GetMenuString (hMenu, nCurrentDevice, szDevice, sizeof (szDevice) / sizeof (TCHAR), MF_BYCOMMAND); if (OpenPrinter (szDevice, &hPrint, NULL)) { PrinterProperties (hwnd, hPrint) ; ClosePrinter (hPrint) ; } } else // info menu items { CheckMenuItem (hMenu, nCurrentInfo, MF_UNCHECKED) ; nCurrentInfo = LOWORD (wParam) ; CheckMenuItem (hMenu, nCurrentInfo, MF_CHECKED) ; } InvalidateRect (hwnd, NULL, TRUE) ; return 0 ; case WM_INITMENUPOPUP : if (lParam == 0) EnableMenuItem (GetMenu (hwnd), IDM_DEVMODE, nCurrentDevice == IDM_SCREEN ? MF_GRAYED : MF_ENABLED) ; return 0 ; case WM_PAINT : lstrcpy (szWindowText, TEXT ("Device Capabilities: ")) ; if (nCurrentDevice == IDM_SCREEN) { lstrcpy (szDevice, TEXT ("DISPLAY")) ; hdcInfo = CreateIC (szDevice, NULL, NULL, NULL) ; } else { hMenu = GetMenu (hwnd) ; GetMenuString (hMenu, nCurrentDevice, szDevice, sizeof (szDevice), MF_BYCOMMAND) ; hdcInfo = CreateIC (NULL, szDevice, NULL, NULL) ; } lstrcat (szWindowText, szDevice) ; SetWindowText (hwnd, szWindowText) ; hdc = BeginPaint (hwnd, &ps) ; SelectObject (hdc, GetStockObject (SYSTEM_FIXED_FONT)) ; if (hdcInfo) { switch (nCurrentInfo) { case IDM_BASIC : DoBasicInfo (hdc, hdcInfo, cxChar, cyChar) ; break ; case IDM_OTHER : DoOtherInfo (hdc, hdcInfo, cxChar, cyChar) ; break ; case IDM_CURVE : case IDM_LINE : case IDM_POLY : case IDM_TEXT : DoBitCodedCaps (hdc, hdcInfo, cxChar, cyChar, nCurrentInfo - IDM_CURVE) ; break ; } DeleteDC (hdcInfo) ; } EndPaint (hwnd, &ps) ; return 0 ; case WM_DESTROY : PostQuitMessage (0) ; return 0 ; } return DefWindowProc (hwnd, message, wParam, lParam) ; }