0

我是一个初学者,试图理解 GUI 在几秒钟后冻结的原因。尝试运行它,看看我的意思.. 它不应该永远打印 Hello1 Hello2 Hello3 Hello4 和 Hello5 吗?需要明确的是:停止工作的是 SetWindowText(),所以冻结的是 GUI。我的意思是,应用程序一直在运行,只是“显示文本”部分崩溃了。我知道这一点,因为我在发布之前对其进行了调试。那我错过了什么?为什么会结冰?你知道吗?提前致谢

这是main.cpp:

#define WIN32_LEAN_AND_MEAN
#include <windows.h>
#include "resource.h"

using namespace std;

HINSTANCE hInst;

void sayHello(HWND handle)
{
    BOOL working = true;
    while (working)
    {
        SetWindowText(handle, "Hello1");
        SetWindowText(handle, "Hello2");
        SetWindowText(handle, "Hello3");
        SetWindowText(handle, "Hello4");
        SetWindowText(handle, "Hello5");
    }
}

BOOL CALLBACK DialogProc(HWND hwndDlg, UINT uMsg, WPARAM wParam, LPARAM lParam)
{
    switch(uMsg)
    {
        case WM_INITDIALOG:
            return TRUE;

        case WM_CLOSE:
            EndDialog(hwndDlg, 0);
            return TRUE;

        case WM_COMMAND:
            switch(LOWORD(wParam))
            {
                case IDC_BTN_QUIT:
                    EndDialog(hwndDlg, 0);
                    return TRUE;

                case IDC_BTN_TEST:
                    HWND handle = GetDlgItem(hwndDlg, 1003);
                    sayHello(handle);
                    return TRUE;
            }
    }

    return FALSE;
}


int APIENTRY WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nShowCmd)
{
    hInst = hInstance;

    return DialogBox(hInstance, MAKEINTRESOURCE(DLG_MAIN), NULL, (DLGPROC)DialogProc);
}

这是资源.h:

#include <windows.h>

#define DLG_MAIN 101
#define IDC_BTN_TEST 1001
#define IDC_BTN_QUIT 1002
#define ID_CONTROLSTATIC 1003

这是resource.rc:

#include "resource.h"

DLG_MAIN DIALOGEX 6, 5, 194, 106

CAPTION "Test Application"

BEGIN
  CONTROL "&Test", IDC_BTN_TEST, "Button", 0x10010000, 138,  5, 46, 15
  CONTROL "TEXT HERE", ID_CONTROLSTATIC, "Static", 0x10010000, 35, 35, 50, 8
  CONTROL "&Quit", IDC_BTN_QUIT, "Button", 0x10010000, 138, 29, 46, 15
END
4

2 回答 2

0

所有 Windows GUI 程序的基本结构都是一个消息循环,类似于:

while (GetMessage(&msg, NULL, 0, 0))
{
    TranslateMessage(&msg);
    DispatchMessage(&msg);
}

您的程序在GetMessage调用中等待直到消息到达,然后处理该消息(最终在您的窗口或对话框过程中结束),然后返回GetMessage等待下一条消息。

在您的程序中,消息循环隐藏在对 的调用中DialogBox,但它就在那里。

当您单击IDC_BUTTON_TEST该功能时,sayHello永远不会返回。所以控制永远不会返回到消息循环,所以你不再处理任何消息,你的程序似乎已经挂起。

如果您想与消息循环并行工作,您至少有两种选择:

  1. 创建一个计时器。当您收到一条WM_TIMER消息时,您会做一些工作(例如在列表中显示下一个字符串),然后返回消息循环并等待更多消息。您在每个计时器滴答声上所做的工作越多,您的应用程序的响应速度就越慢。
  2. 创建另一个线程。这可以在不干扰消息循环的情况下连续运行,但可能会更复杂,因为您必须担心线程之间的同步。
于 2012-07-14T10:02:26.030 回答
0

你在这里有一个无限循环:

void sayHello(HWND handle)
{
    BOOL working = true;
    while (working)
    {
        SetWindowText(handle, "Hello1");
        SetWindowText(handle, "Hello2");
        SetWindowText(handle, "Hello3");
        SetWindowText(handle, "Hello4");
        SetWindowText(handle, "Hello5");
    }
}

添加退出循环的条件,例如if(something) working = false;

如果您希望它永远保持打印,您至少需要在命令之间添加一个计时器,因为它打印消息的速度非常快,以至于您不会真正告诉它正在发生。

于 2012-07-14T08:25:58.690 回答