首页
学习
活动
专区
工具
TVP
发布
社区首页 >问答首页 >基本窗口创建

基本窗口创建
EN

Stack Overflow用户
提问于 2018-06-13 01:48:52
回答 1查看 0关注 0票数 0

我在处理Windows窗口时遇到了问题,尽管我以前这样做过一次,而且效果很好。在阅读了有关这个问题的最常见建议之后,它仍然存在。有人能告诉我为什么输入处理中断吗?

预期行为:

  1. 创建一个名为“FirstTry”的窗口
  2. 使其背景变黑,使用PatBlt
  3. 当第一次输入主循环时,在按‘w’之后显示消息框。
  4. 当按Alt+F4、Escape或Close按钮显示关闭消息时,请关闭窗口.

观察到的行为:

  1. 按原计划
  2. 按原计划
  3. MessageBox第一次出现,但不能用“w”重新触发
  4. 窗口不可关闭,除非使用TaskManager(一次显示“关闭应用程序”-MessageBox,但只显示一次)
    • 窗口可拖动,直到第一个“进入循环”-MessageBox关闭,之后其固定
    • 在第一个MessageBox之后,会显示Windows 10的蓝色“繁忙”小圆圈。

系统:

  • Windows 10,版本1803(构建17134.81),64位

来自VS 2017社区版的编译器:

  • vcvarsall.bat AMD 64
  • CL-MTD-NoLogo-FC-zi-W4-WX-wd 4100-wd 4312 FirstTry.cpp/link User32.lib Gdi32.lib
#include "windows.h"

static bool bAppIsRunning = false;
static bool bMessageAlreadyShown = false;

LRESULT CALLBACK win_MainWNDCallback(HWND wnd, UINT msg, WPARAM wParam, LPARAM lParam){
    LRESULT result = 0;
    switch(msg){
        case WM_DESTROY:{
            bAppIsRunning = false;
        }break;
        case WM_CLOSE:{
            bAppIsRunning = false;
        }break;
        case WM_SYSKEYDOWN:
        case WM_SYSKEYUP:
        case WM_KEYDOWN:
        case WM_KEYUP:{
            WPARAM vKeyCode = wParam;
            bool bWasDown = ((lParam & (1 << 30)) != 0);
            bool bIsDown = ((lParam & (1 << 31)) == 0);
            if (bWasDown != bIsDown)
            {
                switch (vKeyCode)
                {
                    case VK_F4:{
                        if ((lParam & (1 << 29)) != 0)
                        {
                            bAppIsRunning = false;
                        }
                    }break;
                    case VK_ESCAPE:{
                        bAppIsRunning = false;
                    }break;
                    default:{
                        result = DefWindowProc(wnd,msg,wParam,lParam);
                    }break;
                }
            }
        }break;
        default:{
            result = DefWindowProc(wnd,msg,wParam,lParam);
        }break;
    }

    return result;
}

int CALLBACK WinMain(HINSTANCE HInstance, HINSTANCE HPrevInstance, LPSTR LpCmdLine, int NCmdShow){

    WNDCLASSA wndCLass = {};
    wndCLass.style = CS_HREDRAW | CS_VREDRAW;
    wndCLass.lpfnWndProc = win_MainWNDCallback;
    wndCLass.hInstance = HInstance;
    wndCLass.lpszClassName = (LPCSTR)"WindowClass";

    if(RegisterClassA(&wndCLass)){

        HWND wnd = CreateWindowExA(
            0, wndCLass.lpszClassName, (LPCSTR)"FirstTry", 
            WS_OVERLAPPEDWINDOW | WS_VISIBLE, 
            CW_USEDEFAULT, CW_USEDEFAULT, 
            1240, 720,
            0, 0, HInstance, 0);

        if(wnd){
            bAppIsRunning = true;

            HDC DeviceContext = GetDC(wnd);
            PatBlt(DeviceContext, 0, 0, 1240, 720, BLACKNESS);
            ReleaseDC(wnd, DeviceContext);

            while(bAppIsRunning){

                if(!bMessageAlreadyShown){
                    MessageBoxA(NULL, (LPCSTR)"Successfully entered loop.", (LPCSTR)"Success!", MB_ICONINFORMATION | MB_OK);
                    bMessageAlreadyShown = true;
                }

                MSG msg;
                while(PeekMessageA(&msg, 0, 0, 0, PM_REMOVE)){
                    switch(msg.message){
                        case WM_QUIT:{
                        bAppIsRunning = false;
                        }break;
                        case WM_SYSKEYDOWN:
                        case WM_SYSKEYUP:
                        case WM_KEYDOWN:
                        case WM_KEYUP:{
                            WPARAM vKeyCode = msg.wParam;
                            bool bWasDown = ((msg.lParam & (1<<30)) != 0);
                            bool bIsDown = ((msg.lParam & (1<<31)) != 0);
                            if(bIsDown != bWasDown){
                                switch(vKeyCode){
                                    case 'W':{
                                        bMessageAlreadyShown = false;
                                    }break;
                                    case VK_ESCAPE:{
                                        bAppIsRunning = false;
                                    }break;
                                    default:{
                                        TranslateMessage(&msg);
                                        DispatchMessageA(&msg);
                                    }break;
                                }
                            }
                        }
                    }
                }
                Sleep(250);
            }
            MessageBoxA(NULL, (LPCSTR)"Closing Application.", (LPCSTR)"Bye bye!", MB_ICONINFORMATION | MB_OK);
        }
    }
    return ERROR_SUCCESS;
}
EN

回答 1

Stack Overflow用户

发布于 2018-06-13 11:25:06

试一试更像这样的东西:

#include <windows.h>

static bool bMessageAlreadyShown = false; 

LRESULT CALLBACK win_MainWNDCallback(HWND wnd, UINT msg, WPARAM wParam, LPARAM lParam) {
    switch (msg) {
        case WM_DESTROY:
            PostQuitMessage(0);
            return 0;

        case WM_SYSKEYDOWN:
        case WM_SYSKEYUP:
        case WM_KEYDOWN:
        case WM_KEYUP: {
            WPARAM vKeyCode = wParam;
            bool bWasDown = ((lParam & (1 << 30)) != 0);
            bool bIsDown = ((lParam & (1 << 31)) == 0);
            if (bWasDown != bIsDown) {
                switch (vKeyCode) {
                    case 'W':
                    case VK_ESCAPE:
                        DestroyWindow(wnd);
                        return 0;
                }
            }
            break;
        }

        case WM_ERASEBKGND:
            PatBlt((HDC)wParam, 0, 0, 1240, 720, BLACKNESS);
            return 0;
    }

    return DefWindowProc(wnd, msg, wParam, lParam);;
}

int CALLBACK WinMain(HINSTANCE HInstance, HINSTANCE HPrevInstance, LPSTR LpCmdLine, int NCmdShow) {
    WNDCLASSA wndCLass = {};
    wndCLass.style = CS_HREDRAW | CS_VREDRAW;
    wndCLass.lpfnWndProc = win_MainWNDCallback;
    wndCLass.hInstance = HInstance;
    wndCLass.lpszClassName = TEXT("WindowClass");

    if (RegisterClassA(&wndCLass)) {
        HWND wnd = CreateWindowExA( 0, wndCLass.lpszClassName, TEXT("FirstTry"), WS_OVERLAPPEDWINDOW | WS_VISIBLE, CW_USEDEFAULT, CW_USEDEFAULT, 1240, 720, 0, 0, HInstance, 0);
        if (wnd) {
            MSG msg;
            while (GetMessage(&msg, 0, 0, 0)) {
                if (!bMessageAlreadyShown) {
                    MessageBoxA(NULL, TEXT("Successfully entered loop."), TEXT("Success!"), MB_ICONINFORMATION | MB_OK);
                    bMessageAlreadyShown = true;
                }
                TranslateMessage(&msg);
                DispatchMessage(&msg);
            }
        }
    }

    MessageBoxA(NULL, TEXT("Closing Application."), TEXT("Bye bye!"), MB_ICONINFORMATION | MB_OK);

    return ERROR_SUCCESS;
}
票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/-100004875

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档