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