2012-07-14 53 views
0

這是一個初學者,試圖理解爲什麼GUI會在幾秒鐘後凍結的原因。 嘗試運行它,看看我的意思。 它不應該繼續打印Hello1 Hello2 Hello3 Hello4和Hello5永遠不會? 要清楚:它是停止執行作業的SetWindowText(),所以它是凍結的GUI。 我的意思是,應用程序繼續運行,它只是「顯示文本」部分,即崩潰。 我知道這一點,因爲我發佈之前調試它。 那麼我錯過了什麼?爲什麼會凍結? 你知道嗎? 在此先感謝在這個基於對話框的應用程序中,幾秒鐘後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 
+0

你有一個無限循環... – leppie 2012-07-14 08:05:31

+0

這並不能解釋它掛起的原因。可以? – 2012-07-14 08:46:34

回答

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;

如果您希望它永久保持打印,您至少需要在兩個命令之間添加一個計時器,因爲它是如此快速地打印消息,以至於您無法真正瞭解它是如何發生的。

+0

當然,我忘了提及sayHello()只是另一個更長的函數的替身。無論如何,我應該如何編碼才能工作而不會凍結? – 2012-07-14 08:32:19

+1

在另一個線程上運行該工作,並讓您的UI線程可用於處理UI事件。 – 2012-07-14 14:18:21

+0

是雷蒙德,這正是我現在要做的。但我從來沒有與我的生活中的線程。所以爲了節省我的時間,我需要有人爲我編寫工作代碼。我相信這不是一個太大的努力,考慮我的應用程序是多麼微小。謝謝 – 2012-07-14 16:22:20

0

所有的Windows GUI程序的基本結構是一個消息循環,這是一樣的東西:

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

你的程序在GetMessage呼叫等待,直至有消息到達,然後處理消息(最終結束了在你的窗口或對話框中),然後返回到GetMessage等待下一條消息。

在您的程序中,消息循環隱藏在DialogBox的調用中,但它在那裏。

當您單擊IDC_BUTTON_TEST時,函數sayHello從不返回。所以控制永遠不會返回到消息循環,所以你不會再處理任何消息,並且你的程序似乎已經掛起。

如果你想在消息循環並行做的工作,你至少有兩個選擇:

  1. 創建一個定時器。當您收到WM_TIMER消息時,您會做一些工作(如顯示列表中的下一個字符串),然後返回到消息循環並等待更多消息。你在每個計時器上做的工作越多,你的應用程序的響應就越少。
  2. 創建另一個線程。這可以持續運行而不會干擾消息循環,但可能更復雜,因爲您必須擔心線程之間的同步。
+0

它是有道理的。所以你說的是消息循環有一些時間限制,使得它掛起來,是正確的?好。我開始在WM_TIMER和線程上搜索,我發現了一些我很快就會讀到的東西。同時你能告訴我你將如何實現WM_TIMER或線程方式?我的意思是你能顯示代碼嗎?非常感謝 – 2012-07-14 10:45:13

+0

消息循環沒有截止日期。如果你永遠不會重新進入消息循環,那麼你永遠不會處理消息,所以你的對話框沒有響應。要使用計時器調用[SetTimer](http://msdn.microsoft.com/en-us/library/windows/desktop/ms644906%28v=vs.85%29.aspx)創建計時器(也許當按鈕被按下)並在'DialogProc'中處理[WM_TIMER](http://msdn.microsoft.com/en-us/library/windows/desktop/ms644902%28v=vs.85%29.aspx)。 – arx 2012-07-14 12:48:46

+0

難道你不能顯示代碼,所以我可以理解? – 2012-07-14 13:29:49