www.pudn.com > doc2pdf-0_7_1.rar > doc2pdf_keystroke.cpp


///////////////////////////////////////////////////////////////////////////// 
//  
// Project:		Doc2pdf 
// 
// File:		doc2pdf_keystroke.cpp 
// 
// Author(s):	Matt Peterson  
// 
// Description:	Passes keystrokes using WM_JOURNAL_PLAYBACK 
// 
///////////////////////////////////////////////////////////////////////////// 
 
#include "doc2pdf_keystroke.h" 
#include "doc2pdf.h" 
 
#define	DELIMETER	'#' 
 
enum SPECIAL_KEYS 
{ 
	ENTER,TAB,ESCAPE,SPACE,BACKSLASH 
}; 
 
enum COMBO_KEYS 
{ 
	COLON,CTLP,ALTN,ALTY 
}; 
 
static UINT WIN2000_A_TO_Z_PARAML[] = \ 
{ 
	0x00001e41,0x00003042,0x00002e43,0x00002044,0x00001245,0x00002146, 
	0x00002247,0x00002348,0x00001749,0x0000244a,0x0000254b,0x0000264c, 
	0x0000324d,0x0000314e,0x0000184f,0x00001950,0x00001051,0x00001352, 
	0x00001f53,0x00001454,0x00001655,0x00002f56,0x00001157,0x00002d58, 
	0x00001559,0x00002c5a 
}; 
 
static UINT WIN2000_A_TO_Z_PARAMH[] = \ 
{ 
	0x0000001e,0x00000030,0x0000002e,0x00000020,0x00000012,0x00000021, 
	0x00000022,0x00000023,0x00000017,0x00000024,0x00000025,0x00000026, 
	0x00000032,0x00000031,0x00000018,0x00000019,0x00000010,0x00000013, 
	0x0000001f,0x00000014,0x00000016,0x00002f56,0x00000011,0x0000002d, 
	0x00000015,0x0000002c 
}; 
 
static UINT WIN2000_PERIOD_TO_9_PARAML[] =\ 
{ 
	0x000034be,0x000035bf,0x00000b30,0x00000231,0x00000332,0x00000433, 
	0x00000534,0x00000635,0x00000736,0x00000837,0x00000938,0x00000a39 
}; 
 
static UINT WIN2000_PERIOD_TO_9_PARAMH[] =\ 
{ 
	0x00000034,0x00000035,0x0000000b,0x00000002,0x00000003,0x00000004, 
	0x00000005,0x00000006,0x00000007,0x00000008,0x00000009,0x0000000a 
}; 
 
static EVENTMSG WIN2000_SPECIAL_KEYS[] =\ 
{ 
	// ENTER 
	{0x00000100,0x00001c0d,0x0000001c,0x00000000,0x00000000}, 
	{0x00000101,0x00001c0d,0x0000001c,0x00000000,0x00000000}, 
	// TAB, 
	{0x00000100,0x00000f09,0x0000000f,0x00000000,0x00000000}, 
	{0x00000101,0x00000f09,0x0000000f,0x00000000,0x00000000}, 
	// ESCAPE 
	{0x00000100,0x0000011b,0x00000001,0x00000000,0x00000000}, 
	{0x00000101,0x0000011b,0x00000001,0x00000000,0x00000000}, 
	// SPACE 
	{0x00000100,0x00003920,0x00000039,0x00000000,0x00000000}, 
	{0x00000101,0x00003920,0x00000039,0x00000000,0x00000000}, 
	// BACKSLASH 
	{0x00000100,0x00002bdc,0x0000002b,0x00000000,0x00000000}, 
	{0x00000101,0x00002bdc,0x0000002b,0x00000000,0x00000000}	 
}; 
 
static EVENTMSG WIN2000_COMBO_KEYS[] =\ 
{ 
	// Colon  
	{0x00000100,0x00003610,0x00008036,0x00000000,0x00000000}, 
	{0x00000100,0x000027ba,0x00000027,0x00000000,0x00000000}, 
	{0x00000101,0x000027ba,0x00000027,0x00000000,0x00000000}, 
	{0x00000101,0x00003610,0x00008036,0x00000000,0x00000000}, 
	// CTRL P 
	{0x00000100,0x00001d11,0x0000001d,0x00000000,0x00000000}, 
	{0x00000100,0x00001950,0x00000019,0x00000000,0x00000000}, 
	{0x00000101,0x00001950,0x00000019,0x00000000,0x00000000}, 
	{0x00000101,0x00001d11,0x0000001d,0x00000000,0x00000000}, 
	// ALT N 
	{0x00000104,0x00003812,0x00000038,0x00000000,0x00000000}, 
	{0x00000104,0x0000314e,0x00000031,0x00000000,0x00000000}, 
	{0x00000105,0x0000314e,0x00000031,0x00000000,0x00000000}, 
	{0x00000101,0x00003812,0x00000038,0x00000000,0x00000000}, 
	// ALT Y 
	{0x00000104,0x00003812,0x00000038,0x00000000,0x00000000}, 
	{0x00000104,0x00001559,0x00000015,0x00000000,0x00000000}, 
	{0x00000105,0x00001559,0x00000015,0x00000000,0x00000000}, 
	{0x00000101,0x00003812,0x00000038,0x00000000,0x00000000}	 
}; 
 
 
 
void Doc2pdfKeyEvents::Realloc(int size) 
{ 
	EVENTMSG*	newArray; 
	if(size >= m_Size) 
	{ 
		size *= 2; 
		newArray = new EVENTMSG[size]; 
		if(m_EventArray) 
		{ 
			memcpy(newArray,m_EventArray,m_Size * sizeof(EVENTMSG)); 
			delete [] m_EventArray; 
		} 
		m_EventArray = newArray; 
		m_Size = size; 
	} 
} 
 
int Doc2pdfKeyEvents::CharToEvent(int ch) 
{ 
	int				i; 
	int				index			= 0; 
	SPECIAL_KEYS	specialIndex; 
	COMBO_KEYS		comboIndex; 
 
	if(ch < 0x80) 
	{ 
		ch = tolower(ch); 
	} 
	 
	if(ch >= 'a' && ch <= 'z') 
	{ 
		index = ch - 'a';		 
		goto AZ_CHAR; 
	} 
	else if( ch >= '.' && ch <= '9') 
	{ 
		index = ch - '.'; 
		goto NUM_CHAR; 
	} 
	else 
	{ 
		switch(ch) 
		{ 
		case '\t': 
			specialIndex = TAB;		 
			goto SPECIAL_CHAR;					 
		case '\n': 
			specialIndex = ENTER; 
			goto SPECIAL_CHAR;					 
		case 0x1b: //ESC 
			specialIndex = ESCAPE; 
			goto SPECIAL_CHAR; 
		case ' ': 
			specialIndex = SPACE; 
			goto SPECIAL_CHAR; 
		case '\\': 
			specialIndex = BACKSLASH; 
			goto SPECIAL_CHAR;			 
		case ':': 
			comboIndex = COLON; 
			goto COMBO_CHAR;			 
		case 0x80+ALTN: 
			comboIndex = ALTN; 
			goto COMBO_CHAR;			 
		case 0x80+ALTY: 
			comboIndex = ALTY; 
			goto COMBO_CHAR; 
		case 0x80+CTLP: 
			comboIndex = CTLP; 
			goto COMBO_CHAR; 
		default: 
			break; 
		} 
 
		goto UNKNOWN_CHAR; 
	} 
 
COMBO_CHAR: 
	Realloc(m_Pos + 4); 
	for(i=0;i<4;i++) 
	{ 
		memcpy(&(m_EventArray[m_Pos]),&WIN2000_COMBO_KEYS[(comboIndex * 4) + i],sizeof(EVENTMSG)); 
		m_Pos++; 
	} 
	return 0; 
 
SPECIAL_CHAR: 
	Realloc(m_Pos + 2); 
	for(i=0;i<2;i++) 
	{ 
		memcpy(&(m_EventArray[m_Pos]),&WIN2000_SPECIAL_KEYS[(specialIndex * 2) + i],sizeof(EVENTMSG)); 
		m_Pos++; 
	} 
	return 0; 
 
AZ_CHAR: 
	Realloc(m_Pos + 2); 
	m_EventArray[m_Pos].message = WM_KEYDOWN; 
	m_EventArray[m_Pos].paramL = WIN2000_A_TO_Z_PARAML[index]; 
	m_EventArray[m_Pos].paramH = WIN2000_A_TO_Z_PARAML[index]; 
	m_EventArray[m_Pos].time = 0x00000000; 
	m_EventArray[m_Pos].hwnd = NULL; 
	m_Pos ++; 
	m_EventArray[m_Pos].message = WM_KEYUP; 
	m_EventArray[m_Pos].paramL = WIN2000_A_TO_Z_PARAML[index]; 
	m_EventArray[m_Pos].paramH = WIN2000_A_TO_Z_PARAML[index]; 
	m_EventArray[m_Pos].time = 0x00000000; 
	m_EventArray[m_Pos].hwnd = NULL; 
	m_Pos++; 
 
	return 0; 
 
NUM_CHAR: 
Realloc(m_Pos + 2); 
	m_EventArray[m_Pos].message = WM_KEYDOWN; 
	m_EventArray[m_Pos].paramL = WIN2000_PERIOD_TO_9_PARAML[index]; 
	m_EventArray[m_Pos].paramH = WIN2000_PERIOD_TO_9_PARAML[index]; 
	m_EventArray[m_Pos].time = 0x00000000; 
	m_EventArray[m_Pos].hwnd = NULL; 
	m_Pos ++; 
	m_EventArray[m_Pos].message = WM_KEYUP; 
	m_EventArray[m_Pos].paramL = WIN2000_PERIOD_TO_9_PARAML[index]; 
	m_EventArray[m_Pos].paramH = WIN2000_PERIOD_TO_9_PARAML[index]; 
	m_EventArray[m_Pos].time = 0x00000000; 
	m_EventArray[m_Pos].hwnd = NULL; 
	m_Pos++; 
 
UNKNOWN_CHAR: 
 
	return -1; 
} 
 
int	Doc2pdfKeyEvents::SpecialToEvent(const CString& str) 
{ 
	char ch; 
 
	if(str.Left(3) == "ALT") 
	{ 
		ch = str.GetAt(3); 
		ch = tolower(ch); 
		switch(ch) 
		{ 
		case 'n': 
			CharToEvent(0x80 + ALTN); 
			break; 
		case 'y': 
			CharToEvent(0x80 + ALTY); 
			break; 
		} 
	} 
	else if(str.Left(3) == "CTL") 
	{ 
		ch = str.GetAt(3); 
		ch = tolower(ch); 
		switch(ch) 
		{ 
		case 'p': 
			CharToEvent(0x80 + CTLP); 
			break; 
		}	 
	}	 
	else if(str.Left(3) == "ESC") 
	{ 
		CharToEvent(0x1b); 
	} 
		 
	return 0; 
} 
 
Doc2pdfKeyEvents::Doc2pdfKeyEvents() 
{ 
	m_EventArray	= NULL; 
	m_Size			= 0; 
	m_Pos			= 0; 
	m_Count			= 0; 
} 
 
Doc2pdfKeyEvents::~Doc2pdfKeyEvents() 
{ 
	if(m_EventArray) delete [] m_EventArray; 
} 
 
 
// Returns zero on success, non-zero if no more keys 
BOOL Doc2pdfKeyEvents::Next() 
{ 
	if(IsEmpty()) 
	{ 
		return TRUE; 
	} 
	m_Pos ++; 
		 
	return FALSE;; 
} 
 
// Returns boolean 
BOOL Doc2pdfKeyEvents::IsEmpty() 
{ 
	if(m_Pos == m_Count) 
	{	 
		return TRUE; 
	} 
 
	return FALSE; 
} 
 
// Returns zero on success, non-zero on error 
int Doc2pdfKeyEvents::GetKeyEvent(EVENTMSG* msg) 
{ 
	memcpy(msg,&(m_EventArray[m_Pos]),sizeof(EVENTMSG)); 
	return 0;	 
} 
 
// Returns zero on success, non-zero on error 
int Doc2pdfKeyEvents::Init(const CString& keys) 
{ 
	int i,j; 
	 
	// Allocate memory 
	Realloc(keys.GetLength() * 2); 
	m_Pos = 0; 
	m_Count = 0; 
 
	// Parse through the string make events 
	for(i=0;i= 'a' && ch <= 'z') 
		{ 
		} 
		else if( ch >= '.' && ch <= '9') 
		{ 
		} 
		else 
		{ 
			switch(ch) 
			{ 
			case '\t':				 
			case '\n':				 
			case 0x1b:				 
			case ' ':				 
			case '\\':				 
			case ':':				 
			case 80+ALTN:				 
			case 80+ALTY: 
				break; 
			default: 
				str.Delete(i); 
				i--; 
				result ++; 
				break; 
			}			 
		}		 
	} 
	return result; 
} 
 
 
 
// The global key event object 
static Doc2pdfKeyEvents	G_KeyEvents; 
HHOOK					G_Hook			= NULL; 
BOOL					G_SysModal		= FALSE; 
 
// Journal Playback hook procedure 
LRESULT CALLBACK MyPlaybackProc(int nCode,       // hook code 
								WPARAM wParam,  // not used 
	 							LPARAM lParam )  // message being processed 
{ 
	int			result		= 0; 
	 
	if(G_KeyEvents.IsEmpty()) 
	{ 
		Doc2pdfRemoveJournalHook(); 
		goto CALL_NEXT_HOOK; 
	} 
 
	if(G_SysModal) 
	{ 
		goto CALL_NEXT_HOOK; 
	} 
 
	if(nCode < 0) 
	{ 
		goto CALL_NEXT_HOOK; 
	} 
	 
	switch( nCode ) 
	{ 
	case HC_SKIP: 
		G_KeyEvents.Next(); 
		return 0; 
 
	case HC_GETNEXT: 
		G_KeyEvents.GetKeyEvent((EVENTMSG*)lParam); 
		return 0; 
 
	case HC_SYSMODALOFF: 
		G_SysModal = FALSE; 
		break; 
 
	case HC_SYSMODALON: 
		G_SysModal = TRUE; 
		break; 
 
	default: 
		break; 
	} 
 
CALL_NEXT_HOOK: 
 
	return  CallNextHookEx( G_Hook, nCode, wParam, lParam );	 
}  
 
// Install the journal playback hook 
void Doc2pdfInstallJournalHook() 
{ 
	if(G_Hook == NULL) 
	{ 
		G_Hook = SetWindowsHookEx(WH_JOURNALPLAYBACK, 
			                      MyPlaybackProc, 
								  theApp.m_hInstance, 
								  0); 
	} 
} 
 
 
// Send the keystrokes in the string. 
// Example keystroke strings: 
// 
//		Wait for the notewpad window. press ctrl - p, wait for the print 
//      window, and press enter... 
//			"#WFWUntitled - Notepad##CTLP##WFWPrint#\n"  
// 
//		Wait for a window and type "hello world"... 
//			"#WFWUntitled - Notepad#hello world" 
// 
void Doc2pdfSendKeyStrokes(const CString& keystrokes) 
{ 
	G_KeyEvents.Init(keystrokes); 
	Doc2pdfInstallJournalHook(); 
} 
 
 
// Remove the journal playback hook  
void Doc2pdfRemoveJournalHook() 
{ 
	if(G_Hook) 
	{ 
		UnhookWindowsHookEx(G_Hook); 
		G_Hook = NULL; 
	} 
} 
 
 
// Boolean value.  FALSE if timed out 
BOOL Doc2pdfWaitForFile(HINSTANCE hmod,  
						const CString& filename,  
						UINT flags,  
						int timeout) 
{ 
	MSG		msg;  
	CFile	file; 
	BOOL	result = TRUE; 
	time_t	start = time(NULL); 
				 
	SetTimer(NULL,0xabcd0000,1000,NULL); 
		  
	while (GetMessage(&msg, // message structure  
			NULL,           // handle to window to receive the message  
			NULL,           // lowest message to examine  
			NULL)          // highest message to examine  
		   != 0 && GetMessage(&msg, NULL, NULL, NULL) != -1) 
	{  
 
		if(msg.message == WM_TIMER) 
		{ 
			if(file.Open(filename,flags)) 
			{ 
				file.Close();				 
				result = TRUE; 
				break; 
			} 
 
			if(time(NULL) - start >= timeout) 
			{ 
				result = FALSE; 
				break; 
			} 
		} 
		 
		//TranslateMessage(&msg); // translates virtual-key codes  
		DispatchMessage(&msg);  // dispatches message to window  
	}  
 
	KillTimer(NULL,0xabcd0000); 
 
	return result; 
} 
	 
// Boolean value.  FALSE if timed out 
BOOL Doc2pdfWaitForWindow(HINSTANCE hmod,  
						  const CString& title, 
						  int timeout) 
{ 
	MSG		msg;  
	BOOL	result = TRUE; 
	time_t	start; 
 
	start = time(NULL); 
	 
	SetTimer(NULL,0xabcd0000,1000,NULL); 
 
	while (GetMessage(&msg, // message structure  
			NULL,           // handle to window to receive the message  
			NULL,           // lowest message to examine  
			NULL)          // highest message to examine  
		   != 0 && GetMessage(&msg, NULL, NULL, NULL) != -1) 
	{  
 
		if(msg.message == WM_TIMER) 
		{ 
			if(FindWindow(NULL,title)) 
			{ 
				result = TRUE; 
				break; 
			} 
 
			if(time(NULL) - start >= timeout) 
			{ 
				result = FALSE; 
				break; 
			} 
		} 
			 
		//TranslateMessage(&msg); // translates virtual-key codes  
		DispatchMessage(&msg);  // dispatches message to window  
 
	}  
 
	KillTimer(NULL,0xabcd0000); 
 
	return result; 
}