⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 myaddport.cpp

📁 虚拟打印机
💻 CPP
字号:
/* * * myaddport.cpp *   Copyright (C) 2006 Michael H. Overlin   This program is free software; you can redistribute it and/or modify   it under the terms of the GNU General Public License as published by   the Free Software Foundation; either version 2 of the License, or   (at your option) any later version.   This program is distributed in the hope that it will be useful,   but WITHOUT ANY WARRANTY; without even the implied warranty of   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the   GNU General Public License for more details.   You should have received a copy of the GNU General Public License   along with this program; if not, write to the Free Software   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA      Contact at poster_printer@yahoo.com * */#include "myaddport.h"#include <windows.h>#include <winspool.h>// ****// **** TYPEDEFS AND PROTOTYPES PRIVATE TO MODULE// ****struct ThreadParam {	LPCTSTR lptstrMonitorName;	BOOL bAddPortSucess;};DWORD WINAPI AddPortThreadProc( LPVOID lpParam ) ;BOOL CALLBACK EnumThreadWndProc(HWND hwnd, LPARAM lParam) ;// ****// **** PUBLIC ROUTINES// ****BOOL MyAddPort(LPCTSTR lptstrPortName, DWORD dwMaxWaitMS, 			   DWORD dwNewThreadSliceMS, WaitProc pfn, LPCTSTR lptstrMonitorName) {	const TCHAR atstrDefaultMonitorName[] = TEXT("Local Port");	BOOL bRetValue = FALSE;	DWORD dwMSStart = ::GetTickCount();	ThreadParam tp = { lptstrMonitorName == NULL ? atstrDefaultMonitorName : lptstrMonitorName, FALSE };	DWORD dwThreadID;	HANDLE hThread = ::CreateThread(		NULL,		0,		AddPortThreadProc,		(LPVOID) &tp,		0,		&dwThreadID		);	if (hThread != NULL) {		DWORD dwWaitResult = WAIT_TIMEOUT;		BOOL bKeepWaiting = TRUE;		HWND hwnd = NULL;		HWND hwndEdit = NULL;		while( 			(hwnd == NULL || hwndEdit == NULL) &&			(dwMaxWaitMS == INFINITE || dwMaxWaitMS >= (GetTickCount() - dwMSStart)) &&			dwWaitResult == WAIT_TIMEOUT &&			bKeepWaiting		) {			if (hwnd == NULL) {				EnumThreadWindows(dwThreadID, EnumThreadWndProc, (LPARAM) &hwnd);			}			if (hwnd != NULL) {				hwndEdit = ::FindWindowEx(hwnd, NULL, TEXT("Edit"), NULL);			}			if (pfn != NULL) {				bKeepWaiting = pfn();			} 			if (dwNewThreadSliceMS != 0) {				dwWaitResult = ::WaitForSingleObject(hThread, dwNewThreadSliceMS);			}		}		if (bKeepWaiting) {			if (hwnd != NULL && hwndEdit != NULL) {				// ENTER THE PORT NAME FOR THE USER				::SetWindowText(hwndEdit, lptstrPortName);				// HIT THE OK BUTTON				::PostMessage(hwnd, WM_COMMAND, (WPARAM) IDOK, 0);				// FOR ADDED SAFETY, HIT THE RETURN KEY ALSO				UINT uCode = VK_RETURN;					UINT uScanCode = ::MapVirtualKey(uCode, 0);				::PostMessage(hwnd, WM_CHAR, (WPARAM) uCode, (LPARAM) uScanCode);			}			while(				bKeepWaiting &&				(dwMaxWaitMS == INFINITE || dwMaxWaitMS >= (GetTickCount() - dwMSStart)) &&				dwWaitResult == WAIT_TIMEOUT			) {				if (pfn != NULL) {					bKeepWaiting = pfn();				}				dwWaitResult = ::WaitForSingleObject(hThread, dwNewThreadSliceMS);			}		}		if (dwWaitResult != WAIT_OBJECT_0) {			::TerminateThread(hThread, 0);		} else {			bRetValue = tp.bAddPortSucess;		}		::CloseHandle(hThread);	}	return bRetValue;}// ****// **** PRIVATE ROUTINES// ****static DWORD WINAPI AddPortThreadProc( LPVOID lpParam ) {	ThreadParam *ptp = (ThreadParam *) lpParam;	LPCTSTR lptstrMonitorName = ptp->lptstrMonitorName;	::AddPort(NULL, NULL, const_cast<LPTSTR>(lptstrMonitorName) );	ptp->bAddPortSucess = TRUE;	return 0;}static BOOL CALLBACK EnumThreadWndProc(HWND hwnd, LPARAM lParam) {	HWND *phwnd = (HWND *) lParam;	*phwnd = hwnd;	return FALSE;}// AN ALTERNATIVE WAY TO ADD PORT WITHOUT USER INTERACTION//// http://groups.google.com/group/microsoft.public.development.device.drivers/browse_thread/thread/3422cc39b6afc1bd/ac37398846c3ab1d?lnk=st&q=xcvdata+printer+handle&rnum=3&hl=en#ac37398846c3ab1d//From:	 	"Ashwin [MS]" - view profile//Date:		Mon, Apr 22 2002 7:40 pm//Email: 		ashw...@online.microsoft.com ("Ashwin [MS]")//Groups: 		microsoft.public.development.device.drivers//Not yet rated//Rating:	 //show options////Reply | Reply to Author | Forward | Print | Individual Message | Show original | Report Abuse | Find messages by this author////AFAIK, there is no such procedure for any of the 9x platforms. But I am not//a 9x expert....so I maybe wrong.////For silent programmatic installation of custom local ports, the only//methods available are AddPortEx and XcvData. If you are not able to use//AddPortEx and have to use AddPort, but without user intervention, another//dirty trick is to get the handle of the the dialog box which comes up for//the AddPort popup, then get the handle for the edit control box for filling//up the port name, which the user would otherwise have to do; then call the//Win32 api SetWindowText (please check on this) to fill the port name text//string yourself, programmatically; finally, simulate the click on the "OK"//button by calling ID_OK.////Here are some additional steps from the SDK docs:////The function should perform the following operations://1.      Call OpenPrinter, specifying a printer name with the following format://\\ServerName\,XcvMonitor MonitorName//where ServerName and MonitorName are the server and monitor names received//as AddPortUI function arguments.//The call to OpenPrinter requires a PRINTER_DEFAULTS structure, which is//described in the Platform SDK documentation. The structure's DesiredAccess//member must be set to SERVER_ACCESS_ADMINISTER. Its pDatatype and pDevMode//members can be NULL.//This call causes the print monitor server DLL's XcvOpenPort function to be//called.//2.      Obtain a port name from the user by displaying a dialog box.//3.      Call XcvData, specifying the following input arguments://o       The handle received from OpenPrinter//o       The port name received from the user//o       A customized data name string, such as "PortExists"//This call causes the server DLL's XcvDataPort function to be called. The//XcvDataPort function should return a value that indicates whether the//specified port name has already been used. If it has, the UI DLL should//request another name from the user and call XcvData again.//4.      After a valid new port name has been received, call XcvData again, this//time specifying the following input arguments://o       The handle received from OpenPrinter//o       The validated port name received from the user//o       A data name string of "AddPort"//This call causes the server DLL's XcvDataPort function to be called again.//5.      Obtain port configuration parameters from the user by displaying a//dialog box.//6.      Call XcvData one or more times, specifying customized data name strings,//to send each configuration parameter to the server DLL. Each XcvData call//causes the server's XcvDataPort function to be called.//7.      Call ClosePrinter, specifying the handle received from OpenPrinter. This//causes the server DLL's XcvClosePort function to be called.////Hope this helps////- Ashwin 

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -