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