|
|
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.