繁体   English   中英

C ++-窗口消息循环冻结

[英]C++ - Window Message loop is freezing

我在这里上的这堂课是我在另一堂课的基础上进行的。 它应该能够处理整个创建窗口和其他东西,但是现在似乎陷入了困境。 较旧的版本过去可以正常工作,但我不知道我可能会忘记添加一些内容,导致它像这样挂起。

这是消息循环:

int Window::HandleMessages()
{
    while(GetMessage(&this->windat.msgs, NULL, 0, 0))
    {
        TranslateMessage(&this->windat.msgs);
        DispatchMessage(&this->windat.msgs);
    }
    return this->windat.msgs.wParam;
}

很基本的东西,我不知道为什么,但是它会挂起来...当我运行程序时,它只会向我显示一个空的提示窗口,通过测试,如果我看到了它,它将显示一个消息框在while循环之前使用了它,但在内部却无法使用。 我一直在尝试比较该类和较老的类,但还没有弄清楚这可能有什么问题。 谁能告诉我什么可能触发这种行为? 谢谢


好,现在这让我很困惑。 通过弄乱GetLastError,似乎在实例化Window类之前,即使在Main的开头,也无论如何都将其返回错误2(找不到文件)。 如果我在CreateWindowEx之后的任何时间调用GetLastError,它将返回类似1047之类的错误,关于找不到类之类的信息。 HWND也变为NULL
这是main.cpp的代码:

#include "SimpWin/SimpWin.h"
#include <stdio.h>

//  Make the class name into a global variable
char szClassName[] = "WindowsApp";


void ErrorExit(LPTSTR lpszFunction)
{
    // Retrieve the system error message for the last-error code

    LPVOID lpMsgBuf;
    LPVOID lpDisplayBuf;
    DWORD dw = GetLastError();

    FormatMessage(
        FORMAT_MESSAGE_ALLOCATE_BUFFER |
        FORMAT_MESSAGE_FROM_SYSTEM |
        FORMAT_MESSAGE_IGNORE_INSERTS,
        NULL,
        dw,
        MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT),
        (LPTSTR) &lpMsgBuf,
        0, NULL );

    // Display the error message and exit the process

    lpDisplayBuf = (LPVOID)LocalAlloc(LMEM_ZEROINIT,
        (lstrlen((LPCTSTR)lpMsgBuf) + lstrlen((LPCTSTR)lpszFunction) + 40) * sizeof(TCHAR));
    sprintf((char*)lpDisplayBuf,
        TEXT("%s failed with error %d: %s"),
        lpszFunction, dw, lpMsgBuf);
    MessageBox(NULL, (LPCTSTR)lpDisplayBuf, TEXT("Error"), MB_OK);

    LocalFree(lpMsgBuf);
    LocalFree(lpDisplayBuf);
    ExitProcess(dw);
}

LRESULT CALLBACK WindowProcedure (HWND, UINT, WPARAM, LPARAM);

int WINAPI WinMain (HINSTANCE hThisInstance,
                    HINSTANCE hPrevInstance,
                    LPSTR lpszArgument,
                    int nFunsterStil)

{
    ErrorExit(TEXT("CreateWindowEx"));
    Window* win = Window::CreateWindowClass(hThisInstance, szClassName, WindowProcedure);
    if(!win->Register())
    {
        return 0;
    }


    win->Show(nFunsterStil);

    int res = win->HandleMessages();

    delete win;

    return res;
}


/*  This function is called by the Windows function DispatchMessage()  */

LRESULT CALLBACK WindowProcedure(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
{
    return DefWindowProc (hwnd, message, wParam, lParam);
}

这是Window :: Register函数的代码:

int Window::Register()
{
    if(this->windat.wincl.hIcon == NULL)
    {
        this->windat.wincl.hIcon = LoadIcon(NULL, IDI_APPLICATION);
    }
    if(this->windat.wincl.hIconSm == NULL)
    {
        this->windat.wincl.hIconSm = LoadIcon(NULL, IDI_APPLICATION);
    }

    if(!RegisterClassEx(&this->windat.wincl))
    {
        return 0;
    }



    this->windat.hwnd = CreateWindowEx (
           0,                   /* Extended possibilites for variation */
           (char*) this->windat.sName,                  /* Classname */
           (char*) this->windat.sTitle,       /* Title Text */
           WS_OVERLAPPEDWINDOW | WS_CLIPCHILDREN, /* default window */
           CW_USEDEFAULT,       /* Windows decides the position */
           CW_USEDEFAULT,       /* where the window ends up on the screen */
           this->windat.cDimension.width,         /* The programs width */
           this->windat.cDimension.height,        /* and height in pixels */
           HWND_DESKTOP,        /* The window is a child-window to desktop */
           NULL,                /* No menu */
           this->windat.hInstance,       /* Program Instance handler */
           NULL                 /* No Window Creation data */
           );

    return 1;
}

我在这里迷路了,我不知道为什么这会持续下去...:/

即使它已经很旧了……从MSDN上的GetMessage

GetMessage不同, PeekMessage函数在返回之前不等待消息发布。

也就是说, GetMessage等待下一条消息变为可用。 您将这种进行中的等待视为冻结,这可能是因为您实际上并不打算等待消息。

请注意,您可以在假定的冻结时附加调试器,暂停执行并检查线程的调用堆栈。 一旦找到线程,其调用堆栈以及该堆栈上正在进行的GetMessage ,就可以很好地隔离问题,以了解在何处可以读取已记录的行为。

使用PeekMessage而不是GetMessage。

检查GetMessage()返回值 -如果有错误,您的while循环不会退出。 它看起来应该像这样:

while (GetMessage(&this->windat.msgs, NULL, 0, 0) > 0)
{
 ...
}

好吧,我终于开始工作了! :D

实际上,这与我在这里拥有的完全不相关的类有关。 这是我制作的String类(从Array派生的),并且复制函数有一个错误,它将复制我传递给它的字符数组,但不会更新该类的长度字段...那个复制函数每当我必须通过operator =将类设置为值时,都会调用。 运算符char *将该类转换为c格式字符串所需的长度。 当将ClassName和Title值传递给CreateWindowEx时,我将使用该强制类型转换,它将返回0个字符的数组,这就是发生了什么。
现在,我修复了该库,并且现在可以正常工作了。 感谢:D

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM