2010-10-02 121 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等待下一条消息变为可用。你把这个等待进程视为冻结,据说因为你实际上并没有打算等待消息。

请注意,您可以在应冻结时附加调试器,暂停执行并检查线程的调用堆栈。一旦你发现你的线程和它的调用栈以及它的堆栈正在进行中 - 你可以很好地将问题分离出来,以便知道在哪里阅读已记录的行为。