|
|
1.1 root 1: #include <windows.h>
2: #include <memory.h>
3: #include <stdio.h>
4: #include <ctype.h>
5: #include "console.h"
6:
1.1.1.2 ! root 7: /* Microsoft Developer Support
! 8: Copyright (c) 1992 Microsoft Corporation */
! 9:
1.1 root 10: #define MAX_MACRO_EVENTS 256
11: #define ALT_PRESSED (RIGHT_ALT_PRESSED | LEFT_ALT_PRESSED)
12: #define CONTROL_KEY (RIGHT_ALT_PRESSED | LEFT_ALT_PRESSED | \
13: RIGHT_CTRL_PRESSED | LEFT_CTRL_PRESSED | ENHANCED_KEY)
14:
15: /************************************************************************
16: * FUNCTION: demoWriteIn(HANDLE hConOut) *
17: * *
18: * PURPOSE: demonstrate WriteConsoleInput by implementing a macro *
19: * recording facility that writes the recorded keystrokes to *
20: * the input queue for playback. *
21: * *
22: * INPUT: the console buffer to record from and playback to *
23: * *
24: * RETURNS: none *
25: *************************************************************************/
26:
27:
28: void demoWriteIn(HANDLE hConOut)
29: {
30: BOOL bSuccess;
31: HANDLE hStdIn; /* standard input handle */
32: INPUT_RECORD inputBuffer; /* buffer to hold a single console input record */
33: INPUT_RECORD irMacroBuf[MAX_MACRO_EVENTS]; /* array of input events */
34: DWORD dwInputEvents;
35: DWORD dwBytesWritten, dwRecordsWritten;
36: CHAR bOutBuf[256]; /* buffer to format event information into */
37: BOOL bRecording = FALSE; /* TRUE if recording a macro */
38: int iir; /* index into macro input buffer */
39: CHAR c;
40:
1.1.1.2 ! root 41: setConTitle(__FILE__);
1.1 root 42: myPuts(hConOut, "\n\nLet's implement a simple macro record/playback facility.\n"
43: "Hit Alt+R to record, and Alt+P to playback. After turning\n"
44: "on Record mode, enter some keystrokes or mouse clicks.\n"
45: "Hit Alt+R to turn Record mode off, and Alt+P to playback\n"
46: "your keystrokes. I'll use the WriteConsoleInput API to\n"
47: "insert the recorded events into the input buffer.\n"
48: "Hit ESC at any time to return.");
49: hStdIn = GetStdHandle(STD_INPUT_HANDLE);
1.1.1.2 ! root 50: PERR(hStdIn != INVALID_HANDLE_VALUE, "GetStdHandle");
1.1 root 51: for(;;)
52: {
53: /* if our macro event buffer is full, leave Record mode */
54: if (iir == MAX_MACRO_EVENTS && bRecording)
55: {
56: bRecording = FALSE;
57: putStatusLine(hConOut, "");
58: }
59: /* read an input event from the input event queue */
60: bSuccess = ReadConsoleInput(hStdIn, &inputBuffer, 1, &dwInputEvents);
61: PERR(bSuccess, "ReadConsoleInput");
62: switch (inputBuffer.EventType)
63: {
64: case KEY_EVENT:
65: if (inputBuffer.Event.KeyEvent.wVirtualKeyCode == VK_ESCAPE)
66: return;
67: /* get the character that we read */
68: c = inputBuffer.Event.KeyEvent.uChar.AsciiChar;
69: if (!bRecording)
70: {
71: /* ignore key releases */
72: if (!inputBuffer.Event.KeyEvent.bKeyDown)
73: break;
74: /* display the key event info on the status line */
75: sprintf(bOutBuf, "key: virtual=%d ascii=%c",
76: inputBuffer.Event.KeyEvent.wVirtualKeyCode, c);
77: putStatusLine(hConOut, bOutBuf);
78: /* if it's printable, and no control keys are down, show it */
79: if (isprint(c) && !(inputBuffer.Event.KeyEvent.dwControlKeyState &
80: CONTROL_KEY))
81: {
82: bSuccess = WriteFile(hConOut, &c, sizeof(c), &dwBytesWritten,
83: NULL);
84: PERR(bSuccess, "WriteFile");
85: }
86: /* is it an 'r' key? Is either the left or right ALT key down? */
87: if (c == 'r' && (inputBuffer.Event.KeyEvent.dwControlKeyState &
88: (ALT_PRESSED)))
89: {
90: bRecording = TRUE;
91: iir = 0; /* reset macro buffer pointer to beginning */
92: putStatusLine(hConOut, "RECORDING...");
93: }
94: /* is it a 'p' key? Is either the left of right ALT key down? */
95: if (c == 'p' && (inputBuffer.Event.KeyEvent.dwControlKeyState &
96: (ALT_PRESSED)))
97: {
98: /* stuff all the input events into the input buffer */
99: bSuccess = WriteConsoleInput(hStdIn, /* console input buffer */
100: irMacroBuf, /* address of the buffer for write data */
101: iir, /* number of records to write */
102: &dwRecordsWritten); /* returns number of records written */
103: PERR(bSuccess, "WriteConsoleInput");
104: }
105: }
106: else /* we're recording */
107: {
108: if (inputBuffer.Event.KeyEvent.bKeyDown)
109: {
110: /* is it an 'r' key? Is either the left or right ALT key down? */
111: if (c == 'r' && (inputBuffer.Event.KeyEvent.dwControlKeyState &
112: (ALT_PRESSED)))
113: {
114: bRecording = FALSE;
115: putStatusLine(hConOut, "");
116: break;
117: }
118: /* we need to ignore the 'playback' keystroke or we'll */
119: /* automatically start playing back during playback! */
120: if (c == 'p' && (inputBuffer.Event.KeyEvent.dwControlKeyState &
121: (ALT_PRESSED)))
122: break;
123: /* if it's printable, and no control keys are down, show it */
124: if (isprint(c) && !(inputBuffer.Event.KeyEvent.dwControlKeyState &
125: CONTROL_KEY))
126: {
127: bSuccess = WriteFile(hConOut, &c, sizeof(c), &dwBytesWritten,
128: NULL);
129: PERR(bSuccess, "WriteFile");
130: }
131: }
132: /* store the key event in the macro buffer */
133: memcpy(&irMacroBuf[iir++], &inputBuffer, sizeof(inputBuffer));
134: } /* else */
135: break;
136: case MOUSE_EVENT:
137: if (!bRecording)
138: {
139: sprintf(bOutBuf, "mouse: %s at %d, %d",
140: (inputBuffer.Event.MouseEvent.dwEventFlags == MOUSE_MOVED ?
141: "moved" : "clicked"), inputBuffer.Event.MouseEvent.dwMousePosition.X,
142: inputBuffer.Event.MouseEvent.dwMousePosition.Y);
143: putStatusLine(hConOut, bOutBuf);
144: }
145: else /* copy the mouse event into the macro buffer */
146: memcpy(&irMacroBuf[iir++], &inputBuffer, sizeof(inputBuffer));
147: break;
148: case WINDOW_BUFFER_SIZE_EVENT:
149: if (!bRecording)
150: {
151: sprintf(bOutBuf, "window: %d, %d",
152: inputBuffer.Event.WindowBufferSizeEvent.dwSize.X,
153: inputBuffer.Event.WindowBufferSizeEvent.dwSize.Y);
154: putStatusLine(hConOut, bOutBuf);
155: Sleep(1000);
156: }
157: break;
158: } /* switch */
159: } /* while */
160: return;
161: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.