2010-10-02 122 views
1

我有這個類,我基於另一個我做了。它應該處理整個創建窗口和東西,但它現在似乎陷入了一個懸念。舊版本以前工作正常,我不知道我可能忘記添加到這個可能會導致它掛起來這樣。C++ - 窗口消息循環凍結

這是消息循環:

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,它似乎返回錯誤2(找不到文件)任何地方,即使我在實例化我的Window類之前,即使在Main的開始處。如果我在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); 
} 

在這裏,這是該窗口的代碼::註冊功能:

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

我在這裏輸了,我不知道爲什麼這種情況正在發生......:/

+0

聽起來就像它正在跳過這一段時間。 – 2010-10-02 14:43:16

回答

0

使用PeekMessage而不是GetMessage。

+0

OK,所以我嘗試了這種方式......再次使用MessageBox搞亂,看起來程序從來沒有收到任何消息,因爲警告框會在while循環中繼續出現,但是當我把它放入內部時if(PeekMessage ...它根本不會出現:/ – user464503 2010-10-02 16:25:58

0

檢查return value to GetMessage() - 如果出現錯誤,您的while循環將不會退出。它應該看起來像這樣:

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

無論類型簽名是什麼意思,GetMessage不返回布爾值。 – 2010-10-02 21:51:05

+0

爲什麼downvote?檢查doc鏈接,報價'返回值可能不爲零,0或者-1' – JBRWilkinson 2010-10-03 20:28:24

0

嗯,我終於得到它的工作! :D

它實際上與我在這裏完全無關的課程有關。它是一個String類(它是Array的後代),我創建的複製函數有一個bug,它會複製我傳遞給它的字符數組,但不會更新類的長度字段... 該複製函數將被調用,每當我不得不通過operator =將類設置爲一個值。運算符char *需要該長度將該類轉換爲c格式字符串。在將ClassName和Title值傳遞給CreateWindowEx時,我會使用該類型,並且它會返回一個0字符的數組,這就是發生地獄的地方。
現在我修復了這個lib,現在工作正常。謝謝:d

+0

你好,但是爲什麼類錯誤讓你認爲它掛在了GetMessage中呢?我的意思是,你認爲它停在GetMessage中,而不是在代碼中的其他地方,對吧? – ransh 2015-02-16 20:26:57

0

即使它很老了......從MSDN on GetMessage

不像GetMessage,該PeekMessage函數不等待消息返回前公佈。

也就是,GetMessage等待下一條消息變爲可用。你把這個等待進程視爲凍結,據說因爲你實際上並沒有打算等待消息。

請注意,您可以在應凍結時附加調試器,暫停執行並檢查線程的調用堆棧。一旦你發現你的線程和它的調用棧以及它的堆棧正在進行中 - 你可以很好地將問題分離出來,以便知道在哪裏閱讀已記錄的行爲。