![]() |
![]() |
![]() |
![]() ![]() ![]() ![]() ![]() ![]() ![]() ![]() ![]() ![]() |
![]() |
![]() |
To access the contents, click the chapter and section titles.
Fast Track Visual C++ 6.0 Programming
If the Notepad function is not open, FindWindow() returns NULL, and we should open the Notepad ourselves. Launching a Windows ProgramTo start up a programalso called launching a programwe use the Create-Process() function. We need to set up two structures to launch Notepad: a START-UPINFO structure and a PROCESS_INFORMATION structure. void CJournalView::OnFilePlay() { CWnd* WordPad = FindWindow(NULL, Untitled - NotePad); if(WordPad == NULL){ STARTUPINFO StartupInfo; ⇐ PROCESS_INFORMATION ProcessInfo; ⇐ . . . We also need to clear the STARTUPINFO structure. Instead of setting all its members to 0 individually, we use memset() here. Next, we place the size of the STARTUPINFO structure in its own cb member. void CJournalView::OnFilePlay() { CWnd* WordPad = FindWindow(NULL, Untitled - NotePad); if(WordPad == NULL){
STARTUPINFO StartupInfo; PROCESS_INFORMATION ProcessInfo; memset(&StartupInfo, 0, sizeof(StartupInfo)); ⇐ StartupInfo.cb = sizeof(StartupInfo); ⇐ . . . Now were ready to launch the Notepad program, which we do with CreateProcess(), and to get a pointer to it with FindWindow(). void CJournalView::OnFilePlay() { CWnd* WordPad = FindWindow(NULL, Untitled - NotePad); if(WordPad == NULL){ STARTUPINFO StartupInfo; PROCESS_INFORMATION ProcessInfo; memset(&StartupInfo, 0, sizeof(StartupInfo)); StartupInfo.cb = sizeof(StartupInfo); CreateProcess(c:\\windows\\notepad.exe, NULL, NULL, NULL, FALSE, 0, NULL, NULL, &StartupInfo, &ProcessInfo); ⇐ WordPad = FindWindow(NULL, Untitled - NotePad); ⇐ } Now that Notepad is ready, we make sure it has the input focus with the BringWindowToTop() function. void CJournalView::OnFilePlay() { CWnd* WordPad = FindWindow(NULL, Untitled - NotePad); if(WordPad == NULL){ . . . } WordPad->BringWindowToTop(); ⇐ . . . } Were ready to play the recorded events into the Notepad program. We keep track of the number of events weve played back in a variable named PlayedEvents to make sure we play back all recorded events. We initialize that variable to 0 here: void CJournalView::OnFilePlay() { CWnd* WordPad = FindWindow(NULL, Untitled - NotePad); if(WordPad == NULL){ . . . } WordPad->BringWindowToTop(); PlayedEvents = 0; ⇐ . . . Now we unhook the record hook and place a new playback hook in place instead with SetWindowsHokEx(), connecting that new hook to a new procedure, PlayProcedure(). { CWnd* WordPad = FindWindow(NULL, Untitled - NotePad); if(WordPad == NULL){ . . .
} WordPad->BringWindowToTop(); PlayedEvents = 0; UnhookWindowsHookEx(Hook); ⇐ Hook = SetWindowsHookEx(WH_JOURNALPLAYBACK, PlayProcedure, GetModuleHandle(NULL), 0); ⇐ } At this point, weve installed the record and playback hooks as needed. The next step is to write the two hook procedures, RecordProcedure() and PlayProcedure(). Recording EventsWe record keystrokes in the RecordProcedure() function. This function takes three parametersan event code, wParam, and lParamand returns a result of type LRESULT. This function is a Windows callback function, which means that Windows calls it after weve registered it, so we declare it like this in the views header (note that RecordProcedure() is not a member function of the view class): // JournalView.h : interface of the CJournalView class // ///////////////////////////////////////////////////////////////////////////// #if !defined(AFX_JOURNALVIEW_H__6433B67B_A86C_11D1_887F_D42B07C10710__INCLUDED_) #define AFX_JOURNALVIEW_H__6433B67B_A86C_11D1_887F_D42B07C10710__INCLUDED_ #if _MSC_VER > 1000 #pragma once #endif // _MSC_VER > 1000 LRESULT CALLBACK RecordProcedure(int nCode, WPARAM wParam, LPARAM lParam); ⇐ . . . Now add the function itself to the end of the view classs file, JournalView.cpp. LRESULT CALLBACK RecordProcedure(int nCode, WPARAM wParam, LPARAM lParam){ . . . Because other hooks may be connected, we first call the CallNextHookEx() procedure, which calls the next hook in the chain. LRESULT CALLBACK RecordProcedure(int nCode, WPARAM wParam, LPARAM lParam){ LRESULT Result = CallNextHookEx(Hook, nCode, wParam, lParam); ⇐ . . . The kind of events were looking for have an event code of HC_ACTION. We dont want to handle other types of events, such as system events, so we make sure nCode is set to HC_ACTION. LRESULT CALLBACK RecordProcedure(int nCode, WPARAM wParam, LPARAM lParam){ LRESULT Result = CallNextHookEx(Hook, nCode, wParam, lParam); if (nCode != HC_ACTION) ⇐ return(Result); ⇐ . . . If nCode is equal to HC_ACTION, lParam is a pointer to an EVENTMSG structure, which looks like this: typedef struct tagEVENTMSG {
UINT paramL; UINT paramH; DWORD time; HWND hwnd; } EVENTMSG; This is how Windows handles events. For every event, a Windows event structure is created. The first member of this structure, message, holds the type of this message. Because were looking for keystroke messages, we record both WM_KEYDOWN and WM_KEYUP messages.
|
![]() |
Products | Contact Us | About Us | Privacy | Ad Info | Home
Use of this site is subject to certain Terms & Conditions, Copyright © 1996-2000 EarthWeb Inc. All rights reserved. Reproduction whole or in part in any form or medium without express written permission of EarthWeb is prohibited. Read EarthWeb's privacy statement. |