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; }