新人求教,C++(非MFC)中如何接收键盘消息!

wo叫xiao宝 2013-06-18 08:54:12

最近编程时遇到的问题,想要在程序里接收一个键盘消息(ESC消息),如何实现 ? 求解!
注:程序要求不使用MFC。
想在按下ESc时调用一个菜单类,进行选择退出。如何接收该键盘消息????
...全文
348 16 打赏 收藏 转发到动态 举报
AI 作业
写回复
用AI写文章
16 条回复
切换为时间正序
请发表友善的回复…
发表回复
healer_kx 2013-06-19
  • 打赏
  • 举报
回复
效果不错。加油。
赵4老师 2013-06-19
  • 打赏
  • 举报
回复
#include <conio.h>
#include <windows.h>
int main() {
    int k;

    while (1) {
        if (kbhit()) {
            k=getch();
            if (0==k || 0xE0==k) k=k<<8|getch();
            if (27==k) break;//按Esc键退出
            cprintf("\r\n%04X\r\n",k);
        }
        Sleep(200);
        cprintf(".");
    }
    return 0;
}
zybjtu 2013-06-19
  • 打赏
  • 举报
回复
对,这是windows应用程序的写法。传统,框架简单,利于学习
引用 9 楼 u010819865 的回复:
[quote=引用 4 楼 u010936098 的回复:] 看下面代码中最后一个函数中的switch结构


#include <windows.h>
#include <tchar.h>

HINSTANCE hInst;     
TCHAR szTitle[] = _T("TestWindow");    
TCHAR szWindowClass[] = _T("WNDCLASS_of_test_window");  

ATOM    MyRegisterClass(HINSTANCE hInstance);
BOOL    InitInstance(HINSTANCE, int);
LRESULT CALLBACK WndProc(HWND, UINT, WPARAM, LPARAM);

int APIENTRY _tWinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPTSTR lpCmdLine,int nCmdShow)
{
    MSG msg;
    HACCEL hAccelTable;

    MyRegisterClass(hInstance);
    if (!InitInstance (hInstance, nCmdShow))
    {
        return FALSE;
    }

    while (GetMessage(&msg, NULL, 0, 0))
    {
        if (!TranslateAccelerator(msg.hwnd, hAccelTable, &msg))
        {
            TranslateMessage(&msg);
            DispatchMessage(&msg);
        }
    }

    return (int) msg.wParam;
}



ATOM MyRegisterClass(HINSTANCE hInstance)
{
    WNDCLASSEX wcex;

    wcex.cbSize = sizeof(WNDCLASSEX);

    wcex.style   = CS_HREDRAW | CS_VREDRAW;
    wcex.lpfnWndProc = WndProc;
    wcex.cbClsExtra  = 0;
    wcex.cbWndExtra  = 0;
    wcex.hInstance  = hInstance;
    wcex.hIcon   = NULL;
    wcex.hCursor  = LoadCursor(NULL, IDC_ARROW);
    wcex.hbrBackground = (HBRUSH)(COLOR_WINDOW+1);
    wcex.lpszMenuName = NULL;
    wcex.lpszClassName = szWindowClass;
    wcex.hIconSm  = NULL;

    return RegisterClassEx(&wcex);
}

BOOL InitInstance(HINSTANCE hInstance, int nCmdShow)
{
    HWND hWnd;

    hInst = hInstance;
    hWnd = CreateWindow(szWindowClass, szTitle, WS_OVERLAPPEDWINDOW,CW_USEDEFAULT, 0, CW_USEDEFAULT, 0, NULL, NULL, hInstance, NULL);

    if (!hWnd)
    {
        return FALSE;
    }

    ShowWindow(hWnd, nCmdShow);
    UpdateWindow(hWnd);

    return TRUE;
}

LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
{
    int wmId, wmEvent;
    PAINTSTRUCT ps;
    HDC hdc;

    switch (message)
    {
    case WM_KEYDOWN:
        if( wParam == VK_ESCAPE )
        {
            MessageBox( hWnd, _T("Escape is pressed!"), _T("Key down"), MB_OK);//把这句换成你的代码。
        }
        break;
    case WM_PAINT:
        hdc = BeginPaint(hWnd, &ps);
        // TODO: 在此添加任意绘图代码...
        EndPaint(hWnd, &ps);
        break;
    case WM_DESTROY:
        PostQuitMessage(0);
        break;
    default:
        return DefWindowProc(hWnd, message, wParam, lParam);
    }
    return 0;
}


请问一下,这是windows编程么,好想学的说···[/quote]
进击的搬砖工 2013-06-19
  • 打赏
  • 举报
回复
引用 4 楼 u010936098 的回复:
看下面代码中最后一个函数中的switch结构


#include <windows.h>
#include <tchar.h>

HINSTANCE hInst;     
TCHAR szTitle[] = _T("TestWindow");    
TCHAR szWindowClass[] = _T("WNDCLASS_of_test_window");  

ATOM    MyRegisterClass(HINSTANCE hInstance);
BOOL    InitInstance(HINSTANCE, int);
LRESULT CALLBACK WndProc(HWND, UINT, WPARAM, LPARAM);

int APIENTRY _tWinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPTSTR lpCmdLine,int nCmdShow)
{
    MSG msg;
    HACCEL hAccelTable;

    MyRegisterClass(hInstance);
    if (!InitInstance (hInstance, nCmdShow))
    {
        return FALSE;
    }

    while (GetMessage(&msg, NULL, 0, 0))
    {
        if (!TranslateAccelerator(msg.hwnd, hAccelTable, &msg))
        {
            TranslateMessage(&msg);
            DispatchMessage(&msg);
        }
    }

    return (int) msg.wParam;
}



ATOM MyRegisterClass(HINSTANCE hInstance)
{
    WNDCLASSEX wcex;

    wcex.cbSize = sizeof(WNDCLASSEX);

    wcex.style   = CS_HREDRAW | CS_VREDRAW;
    wcex.lpfnWndProc = WndProc;
    wcex.cbClsExtra  = 0;
    wcex.cbWndExtra  = 0;
    wcex.hInstance  = hInstance;
    wcex.hIcon   = NULL;
    wcex.hCursor  = LoadCursor(NULL, IDC_ARROW);
    wcex.hbrBackground = (HBRUSH)(COLOR_WINDOW+1);
    wcex.lpszMenuName = NULL;
    wcex.lpszClassName = szWindowClass;
    wcex.hIconSm  = NULL;

    return RegisterClassEx(&wcex);
}

BOOL InitInstance(HINSTANCE hInstance, int nCmdShow)
{
    HWND hWnd;

    hInst = hInstance;
    hWnd = CreateWindow(szWindowClass, szTitle, WS_OVERLAPPEDWINDOW,CW_USEDEFAULT, 0, CW_USEDEFAULT, 0, NULL, NULL, hInstance, NULL);

    if (!hWnd)
    {
        return FALSE;
    }

    ShowWindow(hWnd, nCmdShow);
    UpdateWindow(hWnd);

    return TRUE;
}

LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
{
    int wmId, wmEvent;
    PAINTSTRUCT ps;
    HDC hdc;

    switch (message)
    {
    case WM_KEYDOWN:
        if( wParam == VK_ESCAPE )
        {
            MessageBox( hWnd, _T("Escape is pressed!"), _T("Key down"), MB_OK);//把这句换成你的代码。
        }
        break;
    case WM_PAINT:
        hdc = BeginPaint(hWnd, &ps);
        // TODO: 在此添加任意绘图代码...
        EndPaint(hWnd, &ps);
        break;
    case WM_DESTROY:
        PostQuitMessage(0);
        break;
    default:
        return DefWindowProc(hWnd, message, wParam, lParam);
    }
    return 0;
}


请问一下,这是windows编程么,好想学的说···
酱油党 2013-06-19
  • 打赏
  • 举报
回复
引用 4 楼 u010936098 的回复:
看下面代码中最后一个函数中的switch结构


#include <windows.h>
#include <tchar.h>

HINSTANCE hInst;     
TCHAR szTitle[] = _T("TestWindow");    
TCHAR szWindowClass[] = _T("WNDCLASS_of_test_window");  

ATOM    MyRegisterClass(HINSTANCE hInstance);
BOOL    InitInstance(HINSTANCE, int);
LRESULT CALLBACK WndProc(HWND, UINT, WPARAM, LPARAM);

int APIENTRY _tWinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPTSTR lpCmdLine,int nCmdShow)
{
    MSG msg;
    HACCEL hAccelTable;

    MyRegisterClass(hInstance);
    if (!InitInstance (hInstance, nCmdShow))
    {
        return FALSE;
    }

    while (GetMessage(&msg, NULL, 0, 0))
    {
        if (!TranslateAccelerator(msg.hwnd, hAccelTable, &msg))
        {
            TranslateMessage(&msg);
            DispatchMessage(&msg);
        }
    }

    return (int) msg.wParam;
}



ATOM MyRegisterClass(HINSTANCE hInstance)
{
    WNDCLASSEX wcex;

    wcex.cbSize = sizeof(WNDCLASSEX);

    wcex.style   = CS_HREDRAW | CS_VREDRAW;
    wcex.lpfnWndProc = WndProc;
    wcex.cbClsExtra  = 0;
    wcex.cbWndExtra  = 0;
    wcex.hInstance  = hInstance;
    wcex.hIcon   = NULL;
    wcex.hCursor  = LoadCursor(NULL, IDC_ARROW);
    wcex.hbrBackground = (HBRUSH)(COLOR_WINDOW+1);
    wcex.lpszMenuName = NULL;
    wcex.lpszClassName = szWindowClass;
    wcex.hIconSm  = NULL;

    return RegisterClassEx(&wcex);
}

BOOL InitInstance(HINSTANCE hInstance, int nCmdShow)
{
    HWND hWnd;

    hInst = hInstance;
    hWnd = CreateWindow(szWindowClass, szTitle, WS_OVERLAPPEDWINDOW,CW_USEDEFAULT, 0, CW_USEDEFAULT, 0, NULL, NULL, hInstance, NULL);

    if (!hWnd)
    {
        return FALSE;
    }

    ShowWindow(hWnd, nCmdShow);
    UpdateWindow(hWnd);

    return TRUE;
}

LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
{
    int wmId, wmEvent;
    PAINTSTRUCT ps;
    HDC hdc;

    switch (message)
    {
    case WM_KEYDOWN:
        if( wParam == VK_ESCAPE )
        {
            MessageBox( hWnd, _T("Escape is pressed!"), _T("Key down"), MB_OK);//把这句换成你的代码。
        }
        break;
    case WM_PAINT:
        hdc = BeginPaint(hWnd, &ps);
        // TODO: 在此添加任意绘图代码...
        EndPaint(hWnd, &ps);
        break;
    case WM_DESTROY:
        PostQuitMessage(0);
        break;
    default:
        return DefWindowProc(hWnd, message, wParam, lParam);
    }
    return 0;
}

这个就可以。。。不过是WIN32的。。。估计楼主的也是
  • 打赏
  • 举报
回复
引用 3 楼 u010914313 的回复:
[quote=引用 1 楼 u010936098 的回复:] 在窗口过程中检查WM_KEYDOWN消息
不是MFC....就只有一个窗口[/quote] 所有的Windows程序都接收WM_的系统消息。你收到这个消息就可以了。不一定非得是MFC程序
  • 打赏
  • 举报
回复
大家给楼主贴出 一堆 WINDOWS编程案例。。 同为菜鸟的我, 只能高速 楼主 ,C++ 只是一种编程的工具,而做成一个软件,不是只用C++ 就行的吧? 楼主去看完 WINDOWS编程什么都懂了。。。
wo叫xiao宝 2013-06-19
  • 打赏
  • 举报
回复
引用 4 楼 u010936098 的回复:
看下面代码中最后一个函数中的switch结构


#include <windows.h>
#include <tchar.h>

HINSTANCE hInst;     
TCHAR szTitle[] = _T("TestWindow");    
TCHAR szWindowClass[] = _T("WNDCLASS_of_test_window");  

ATOM    MyRegisterClass(HINSTANCE hInstance);
BOOL    InitInstance(HINSTANCE, int);
LRESULT CALLBACK WndProc(HWND, UINT, WPARAM, LPARAM);

int APIENTRY _tWinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPTSTR lpCmdLine,int nCmdShow)
{
    MSG msg;
    HACCEL hAccelTable;

    MyRegisterClass(hInstance);
    if (!InitInstance (hInstance, nCmdShow))
    {
        return FALSE;
    }

    while (GetMessage(&msg, NULL, 0, 0))
    {
        if (!TranslateAccelerator(msg.hwnd, hAccelTable, &msg))
        {
            TranslateMessage(&msg);
            DispatchMessage(&msg);
        }
    }

    return (int) msg.wParam;
}



ATOM MyRegisterClass(HINSTANCE hInstance)
{
    WNDCLASSEX wcex;

    wcex.cbSize = sizeof(WNDCLASSEX);

    wcex.style   = CS_HREDRAW | CS_VREDRAW;
    wcex.lpfnWndProc = WndProc;
    wcex.cbClsExtra  = 0;
    wcex.cbWndExtra  = 0;
    wcex.hInstance  = hInstance;
    wcex.hIcon   = NULL;
    wcex.hCursor  = LoadCursor(NULL, IDC_ARROW);
    wcex.hbrBackground = (HBRUSH)(COLOR_WINDOW+1);
    wcex.lpszMenuName = NULL;
    wcex.lpszClassName = szWindowClass;
    wcex.hIconSm  = NULL;

    return RegisterClassEx(&wcex);
}

BOOL InitInstance(HINSTANCE hInstance, int nCmdShow)
{
    HWND hWnd;

    hInst = hInstance;
    hWnd = CreateWindow(szWindowClass, szTitle, WS_OVERLAPPEDWINDOW,CW_USEDEFAULT, 0, CW_USEDEFAULT, 0, NULL, NULL, hInstance, NULL);

    if (!hWnd)
    {
        return FALSE;
    }

    ShowWindow(hWnd, nCmdShow);
    UpdateWindow(hWnd);

    return TRUE;
}

LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
{
    int wmId, wmEvent;
    PAINTSTRUCT ps;
    HDC hdc;

    switch (message)
    {
    case WM_KEYDOWN:
        if( wParam == VK_ESCAPE )
        {
            MessageBox( hWnd, _T("Escape is pressed!"), _T("Key down"), MB_OK);//把这句换成你的代码。
        }
        break;
    case WM_PAINT:
        hdc = BeginPaint(hWnd, &ps);
        // TODO: 在此添加任意绘图代码...
        EndPaint(hWnd, &ps);
        break;
    case WM_DESTROY:
        PostQuitMessage(0);
        break;
    default:
        return DefWindowProc(hWnd, message, wParam, lParam);
    }
    return 0;
}

我们还没学windows编程,看这代码还真是晕啊 其实就是看不懂的说
  • 打赏
  • 举报
回复
引用 13 楼 u010914313 的回复:
[quote=引用 7 楼 CKnightx 的回复:] [quote=引用 3 楼 u010914313 的回复:] [quote=引用 1 楼 u010936098 的回复:] 在窗口过程中检查WM_KEYDOWN消息
不是MFC....就只有一个窗口[/quote] 所有的Windows程序都接收WM_的系统消息。你收到这个消息就可以了。不一定非得是MFC程序[/quote] 表示我只是学了半年的C++基础,什么消息的还真是不懂...[/quote] 那就先去学Win32 程序设计吧,上来就搞MFC,很多东西你都是模糊的。 步子不能迈大了,会扯着蛋
wo叫xiao宝 2013-06-19
  • 打赏
  • 举报
回复
引用 7 楼 CKnightx 的回复:
[quote=引用 3 楼 u010914313 的回复:] [quote=引用 1 楼 u010936098 的回复:] 在窗口过程中检查WM_KEYDOWN消息
不是MFC....就只有一个窗口[/quote] 所有的Windows程序都接收WM_的系统消息。你收到这个消息就可以了。不一定非得是MFC程序[/quote] 表示我只是学了半年的C++基础,什么消息的还真是不懂...
www_adintr_com 2013-06-18
  • 打赏
  • 举报
回复
WM_KEYDOWN 又不是 MFC 定义的....
橡木疙瘩 2013-06-18
  • 打赏
  • 举报
回复
如果是控制台应用的话,要想接收escape按键,就不能用标准输入输入函数来接收用户输入,需要使用控制台输入函数_getch():

#include <conio.h>
#include <iostream>

int _tmain(int argc, _TCHAR* argv[])
{
    int ch  = _getch();
    std::cout << ch;
    if( ch == 27 )
    {
        std::cout << "\nEscape pressed!\n";
    }
    else
    {
        std::cout << "\n" << char(ch) << " pressed!\n";
    }
	return 0;
}

橡木疙瘩 2013-06-18
  • 打赏
  • 举报
回复
看下面代码中最后一个函数中的switch结构


#include <windows.h>
#include <tchar.h>

HINSTANCE hInst;     
TCHAR szTitle[] = _T("TestWindow");    
TCHAR szWindowClass[] = _T("WNDCLASS_of_test_window");  

ATOM    MyRegisterClass(HINSTANCE hInstance);
BOOL    InitInstance(HINSTANCE, int);
LRESULT CALLBACK WndProc(HWND, UINT, WPARAM, LPARAM);

int APIENTRY _tWinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPTSTR lpCmdLine,int nCmdShow)
{
    MSG msg;
    HACCEL hAccelTable;

    MyRegisterClass(hInstance);
    if (!InitInstance (hInstance, nCmdShow))
    {
        return FALSE;
    }

    while (GetMessage(&msg, NULL, 0, 0))
    {
        if (!TranslateAccelerator(msg.hwnd, hAccelTable, &msg))
        {
            TranslateMessage(&msg);
            DispatchMessage(&msg);
        }
    }

    return (int) msg.wParam;
}



ATOM MyRegisterClass(HINSTANCE hInstance)
{
    WNDCLASSEX wcex;

    wcex.cbSize = sizeof(WNDCLASSEX);

    wcex.style   = CS_HREDRAW | CS_VREDRAW;
    wcex.lpfnWndProc = WndProc;
    wcex.cbClsExtra  = 0;
    wcex.cbWndExtra  = 0;
    wcex.hInstance  = hInstance;
    wcex.hIcon   = NULL;
    wcex.hCursor  = LoadCursor(NULL, IDC_ARROW);
    wcex.hbrBackground = (HBRUSH)(COLOR_WINDOW+1);
    wcex.lpszMenuName = NULL;
    wcex.lpszClassName = szWindowClass;
    wcex.hIconSm  = NULL;

    return RegisterClassEx(&wcex);
}

BOOL InitInstance(HINSTANCE hInstance, int nCmdShow)
{
    HWND hWnd;

    hInst = hInstance;
    hWnd = CreateWindow(szWindowClass, szTitle, WS_OVERLAPPEDWINDOW,CW_USEDEFAULT, 0, CW_USEDEFAULT, 0, NULL, NULL, hInstance, NULL);

    if (!hWnd)
    {
        return FALSE;
    }

    ShowWindow(hWnd, nCmdShow);
    UpdateWindow(hWnd);

    return TRUE;
}

LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
{
    int wmId, wmEvent;
    PAINTSTRUCT ps;
    HDC hdc;

    switch (message)
    {
    case WM_KEYDOWN:
        if( wParam == VK_ESCAPE )
        {
            MessageBox( hWnd, _T("Escape is pressed!"), _T("Key down"), MB_OK);//把这句换成你的代码。
        }
        break;
    case WM_PAINT:
        hdc = BeginPaint(hWnd, &ps);
        // TODO: 在此添加任意绘图代码...
        EndPaint(hWnd, &ps);
        break;
    case WM_DESTROY:
        PostQuitMessage(0);
        break;
    default:
        return DefWindowProc(hWnd, message, wParam, lParam);
    }
    return 0;
}

wo叫xiao宝 2013-06-18
  • 打赏
  • 举报
回复
引用 1 楼 u010936098 的回复:
在窗口过程中检查WM_KEYDOWN消息
不是MFC....就只有一个窗口
wo叫xiao宝 2013-06-18
  • 打赏
  • 举报
回复


在这个界面接收ESC消息可以吗?可以的话如何实现?
橡木疙瘩 2013-06-18
  • 打赏
  • 举报
回复
在窗口过程中检查WM_KEYDOWN消息
内容概要:本文介绍了DeepSeek在职场的应用,从提示语技巧到多场景应用,涵盖了DeepSeek的基础模型(V3)、深度思考模型(R1)及其联网搜索功能。文详细描述了DeepSeek的模型对比,包括操作规范、结果导向、路径灵活性、响应模式和风险特征等方面。此外,还探讨了DeepSeek在制作可视化图表、PPT、海报、视频以及批量生成新媒体文案等具体应用场景的使用方法和技巧。最后,文章展示了DeepSeek在市场调查、AI应用开发等方面的应用实例,强调了其在人机协同和共生领域的潜力。 适用人群:适用于希望提升工作效率和创新能力的职场人士,特别是从事数据分析、内容创作、市场营销、AI开发等领域的专业人士。 使用场景及目标:①通过DeepSeek的基础模型(V3)和深度思考模型(R1)进行高效的任务处理和复杂推理;②利用DeepSeek制作可视化图表、PPT、海报和视频,提高内容创作的质量和效率;③通过DeepSeek进行市场调查和AI应用开发,优化业务流程并推动创新。 其他说明:DeepSeek不仅提供了强大的AI工具,还强调了人机协同的重要性。用户在使用过程应注意操作规范,结合实际需求选择合适的模型,并充分利用DeepSeek的各项功能来实现高效的职场应用。文还提到了多个国际竞赛的获奖情况,展示了DeepSeek团队在AI领域的卓越实力。

65,187

社区成员

发帖
与我相关
我的任务
社区描述
C++ 语言相关问题讨论,技术干货分享,前沿动态等
c++ 技术论坛(原bbs)
社区管理员
  • C++ 语言社区
  • encoderlee
  • paschen
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
  1. 请不要发布与C++技术无关的贴子
  2. 请不要发布与技术无关的招聘、广告的帖子
  3. 请尽可能的描述清楚你的问题,如果涉及到代码请尽可能的格式化一下

试试用AI创作助手写篇文章吧