任务是这样的:
编写一个程序,显示有关鼠标坐标、控制键状态(ALT、CTRL、SHIFT)、扫描码和给定控制台位置按下键的 ASCII 码的信息。要显示结果,请使用SetConsoleCursorPosition,()、wsprintf()、WriteConsole() 函数。
我重新阅读了文档,查看了示例(最后一个太混乱了)。由于键是象征性的,您将不得不使用另一个函数来编写它们TranslateMessage。
关于击键执行的问题,最好的方法是什么。(突出显示问题所在的代码块)。
目前我有这个代码:
#include "stdafx.h"
#include <cstring>
#include <iostream>
#include <stdio.h>
#include <conio.h>
#include <windows.h>
#include <winuser.h>
#define STR_SIZE 256
#define BUFSIZE 65535
#define SHIFTED 0x8000
int main() {
setlocale(LC_ALL, "rus");
HANDLE hIn, hOut;
DWORD size = STR_SIZE;
char result[STR_SIZE];
FreeConsole();
AllocConsole();
SetConsoleOutputCP(1251);
hIn = GetStdHandle(STD_INPUT_HANDLE);
hOut = GetStdHandle(STD_OUTPUT_HANDLE);
GetDC(NULL); // дескриптор стола
POINT p; // структура для координат
COORD cord; // структура COORD, которая указывает позицию курсора
cord.X = 0; // координата X структуры COORD
cord.Y = 0; // координата Y структуры COORD
//------------------------------------------------------------------
HWND hwndMain;
HACCEL haccl;
UINT uMsg;
UINT wParam;
LONG lParam;
HWND hwnd;
MSG msg;
switch (wParam)
{
case 0x10:
/*SHIFT key.*/
printf("SHIFT pressed", wParam);
break;
case 0x11:
/*CTRL key.*/
printf("CTRL pressed", wParam);
break;
case 0x12:
/*ALT key. */
printf("ALT pressed", wParam);
break;
default:
printf("OTHER pressed", wParam);
/* Обработка воспроизводимых символов. */
break;
}
while (GetMessage(&msg, (HWND)NULL, 0, 0))
{
if (TranslateAccelerator(hwndMain, haccl, &msg) == 0)
{
TranslateMessage(&msg);
DispatchMessage(&msg);
}
}
//-----------------------------------------------------------------------------
while (1) {
wsprintf(result, "Позиция курсора: ");
WriteConsole(hOut, result, strlen(result), nullptr, nullptr);
GetCursorPos(&p);
wsprintf(result, "x = %4ld, y = %4ld\r\n", p.x, p.y);
WriteConsole(hOut, result, strlen(result), nullptr, nullptr);
SetConsoleCursorPosition(GetStdHandle(STD_OUTPUT_HANDLE), cord);
}
return 0;
}
升级版:
#include "stdafx.h"
#include <stdlib.h>
#include <locale.h>
#include <stdio.h>
#include <windows.h>
#include <tchar.h>
VOID ErrorExit(LPCSTR);
VOID KeyEventProc(KEY_EVENT_RECORD);
VOID MouseEventProc(MOUSE_EVENT_RECORD);
#define STR_SIZE 256
#define BUFSIZE 65535
#define SHIFTED 0x8000
HANDLE hStdin;
HANDLE hOut;
DWORD fdwSaveOldMode;
DWORD scan = 0; //скан-код последней клавиши
wchar_t code = 0; //код символа последней клавиши
bool alt, ctrl, shift; //состояние управляющих клавиш
void PrintData() {
DWORD size = STR_SIZE;
char result[STR_SIZE];
//GetDC(NULL); // дескриптор стола
POINT p; // структура для координат
COORD cord; // структура COORD, которая указывает позицию курсора
cord.X = 0; // координата X структуры COORD
cord.Y = 0; // координата Y структуры COORD
SetConsoleCursorPosition(hOut, cord);
wsprintf(result, "Позиция курсора: ");
WriteConsole(hOut, result, strlen(result), nullptr, nullptr);
GetCursorPos(&p);
wsprintf(result, "x = %4ld, y = %4ld\r\n", p.x, p.y);
WriteConsole(hOut, result, strlen(result), nullptr, nullptr);
if (scan != 0) {
wsprintf(result, "Последняя нажатая клавиша\nScan code: %4u\r\n", (UINT)scan);
WriteConsole(hOut, result, strlen(result), nullptr, nullptr);
wsprintf(result, "Character code: %4u\r\n", (UINT)code);
WriteConsole(hOut, result, strlen(result), nullptr, nullptr);
if (ctrl) wsprintf(result, "CTRL:(+) "); else wsprintf(result, "CTRL:(-) ");
WriteConsole(hOut, result, strlen(result), nullptr, nullptr);
if (shift) wsprintf(result, "SHIFT:(+) "); else wsprintf(result, "SHIFT:(-) ");
WriteConsole(hOut, result, strlen(result), nullptr, nullptr);
if (alt) wsprintf(result, "ALT:(+) "); else wsprintf(result, "ALT:(-) ");
WriteConsole(hOut, result, strlen(result), nullptr, nullptr);
}
}
int main()
{
//setlocale(LC_ALL, "Russian");
SetConsoleCP(1251);
SetConsoleOutputCP(1251);
DWORD cNumRead, fdwMode, i;
INPUT_RECORD irInBuf[128];
// Get the standard input handle.
hStdin = GetStdHandle(STD_INPUT_HANDLE);
hOut = GetStdHandle(STD_OUTPUT_HANDLE);
// Save the current input mode, to be restored on exit.
if (!GetConsoleMode(hStdin, &fdwSaveOldMode))
ErrorExit("GetConsoleMode");
// Enable the window and mouse input events.
fdwMode = ENABLE_WINDOW_INPUT | ENABLE_MOUSE_INPUT;
if (!SetConsoleMode(hStdin, fdwMode))
ErrorExit("SetConsoleMode");
// Loop to read and handle input events.
while (1)
{
// Wait for the events.
if (!ReadConsoleInput(
hStdin, // input buffer handle
irInBuf, // buffer to read into
128, // size of read buffer
&cNumRead)) // number of records read
ErrorExit("ReadConsoleInput");
// Dispatch the events to the appropriate handler.
for (i = 0; i < cNumRead; i++)
{
switch (irInBuf[i].EventType)
{
case KEY_EVENT: // keyboard input
KeyEventProc(irInBuf[i].Event.KeyEvent);
break;
case MOUSE_EVENT: // mouse input
MouseEventProc(irInBuf[i].Event.MouseEvent);
break;
case WINDOW_BUFFER_SIZE_EVENT:
case FOCUS_EVENT:
case MENU_EVENT:
break;
}
}
}
// Restore input mode on exit.
SetConsoleMode(hStdin, fdwSaveOldMode);
return 0;
}
VOID KeyEventProc(KEY_EVENT_RECORD ker)
{
if (ker.bKeyDown) {
scan = ker.wVirtualScanCode;
code = ker.uChar.UnicodeChar;
if ((ker.dwControlKeyState & SHIFT_PRESSED) > 0) shift = true; else shift = false;
if ((ker.dwControlKeyState & LEFT_ALT_PRESSED) > 0 ||
(ker.dwControlKeyState & RIGHT_ALT_PRESSED) > 0) alt = true;
else alt = false;
if ((ker.dwControlKeyState & LEFT_CTRL_PRESSED) > 0 ||
(ker.dwControlKeyState & RIGHT_CTRL_PRESSED) > 0) ctrl = true;
else ctrl = false;
PrintData();
}
}
VOID MouseEventProc(MOUSE_EVENT_RECORD mer)
{
if (mer.dwEventFlags == MOUSE_MOVED) {
PrintData();
}
}
VOID ErrorExit(LPCSTR lpszMessage)
{
fprintf(stderr, "%s\n", lpszMessage);
// Restore input mode on exit.
SetConsoleMode(hStdin, fdwSaveOldMode);
ExitProcess(0);
}
系统不会将控制台应用程序的键盘事件发送给控制台应用程序进程,而是发送给拥有控制台窗口的系统进程(csrss 或 conhost,具体取决于操作系统),创建消息循环是没有用的。要处理此类事件,您需要使用特殊函数来处理控制台输入:
读取输入缓冲区事件 - Microsoft Docs