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);
}

ここにresource.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も戻りません。したがって、制御がメッセージ ループに戻らないため、これ以上メッセージを処理せず、プログラムがハングしたように見えます。

メッセージ ループと並行して作業を行いたい場合は、少なくとも 2 つの選択肢があります。

  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 に答える