我这里有这个课程,是根据我的另一个课程制作的。它应该处理整个创建窗口和东西,但它似乎现在陷入困境。旧版本以前工作正常,我不知道我可能忘记添加到这个可能导致它像这样挂起的那个。
这是消息循环:
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循环之前使用它,但在里面它不起作用。我一直试图比较这个类和旧类,并没有弄清楚这可能是什么问题。谁能告诉我什么可能触发这种行为? 感谢
#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);
}
这里是Window :: Register函数的代码:
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 :(得分:0)
使用PeekMessage而不是GetMessage。
答案 1 :(得分:0)
检查return value to GetMessage() - 如果有错误,你的while循环将不会退出。它应该是这样的:
while (GetMessage(&this->windat.msgs, NULL, 0, 0) > 0)
{
...
}
答案 2 :(得分:0)
好吧,我终于搞定了! :d
这实际上与我在这里完全不相关的课程有关。它是我做的一个String类(来自Array),复制函数有一个bug,它会复制我传递给它的字符数组,但是不会更新类的长度字段......
每当我必须通过operator =将类设置为一个值时,就会调用该复制函数。操作符char *需要长度才能将类转换为c格式字符串。当我将ClassName和Title值传递给CreateWindowEx时,我会使用该转换,它会返回一个0个字符的数组,这就是地狱发生的地方。
现在我修复了这个库,它现在工作正常。谢谢:D
答案 3 :(得分:0)
即使它很老......来自MSDN on GetMessage
:
与
GetMessage
不同,PeekMessage
函数不会在返回之前等待发布消息。
也就是说,GetMessage
等待下一条消息可用。你把这个正在进行的等待视为冻结,据说是因为你实际上没有打算等待消息。
请注意,您可以在假定冻结时附加调试器,暂停执行并检查线程的调用堆栈。一旦你发现你的线程及其调用堆栈及其GetMessage
正在堆栈中进行 - 你就可以很好地隔离问题,以便知道在哪里阅读记录的行为。