【发布时间】:2015-04-21 13:16:25
【问题描述】:
当我通过 CreateWindow 函数创建名为“A”的窗口时,窗口“A”没有响应,但可以在它没有响应之前绘制它。
当我点击“登录”按钮时
unsigned __stdcall ThreadFunc(void *lParam) {
pMsgHead pmsgHead = new MsgHead;
while (RecvMsg(ConnectSocket,pmsgHead,sizeof(MsgHead))) {
switch (pmsgHead->dwCmd) {
case WM_SIGN_IN:
g_hMain=CreateWindow(szMainClass, L"A", WS_OVERLAPPEDWINDOW,
200, 200, 250, 500, 0, 0, hInst, nullptr);
ShowWindow(g_hMain, SW_SHOW);
UpdateWindow(g_hMain);
break;
case WM_BROADCAST:
//DrawText()
break;
}
}
_endthreadex(0);
return 0;
}
但是当我点击“注册”按钮时,它会起作用。
case IDB_SIGN_UP:
g_hSignUp = CreateWindow(szSignUpClass, L"Sign Up", WS_OVERLAPPEDWINDOW,
800, 200, 300, 300, 0, 0, hInst, nullptr);
ShowWindow(g_hSignUp, SW_SHOW);
UpdateWindow(g_hSignUp);
break;
case IDB_SIGN_IN:
{
TCHAR uname[20], psd[20];
GetWindowText(g_hSignInuname, uname, 20);
GetWindowText(g_hSignInpsd, psd, 20);
pMsgHead pmsgHead = new MsgHead;
pmsgHead->dwCmd = WM_SIGN_IN;
wcscpy_s(pmsgHead->tszbuf, uname);
wcscat_s(pmsgHead->tszbuf, L",");
wcscat_s(pmsgHead->tszbuf, psd);
SendMsg(ConnectSocket, pmsgHead, sizeof(MsgHead));
break;
}
我只是在主线程的GetMessage函数和上面的RecvMsg中使用while循环,我使用单步调试程序,一个线程将等待
while(RecvMsg())主线程会在
case IDB_SIGN_IN:中运行'break'然后返回0,如果我仍然使用单步调试,它会提示不加载'wuser32.pdb'
【问题讨论】:
-
您是从另一个线程(不是 main 线程)创建该窗口吗?你不能……
-
@Adriano:没有 main 线程这样的东西。
-
@IInspectable 如果您愿意,我们可以将其称为 UI 线程,或者 - 更好的是 - 已创建 hInst 的线程。一般来说 UI 是单线程的,所以 main 线程是一种 simplification。
-
@Adriano: 嗯... “创建 hInst 的线程” 没有任何意义。 hInst 是指向用于创建进程的模块开头的指针。这是操作系统加载程序的结果;那时还没有创建线程。 GUI 也不是严格的单线程。另一方面,窗口层次结构最好由单个线程拥有。
-
@IInspectable GetModuleHandle() (相当于 WinMain 中的 hInstance 用于可执行文件)将返回一个伪句柄。伪句柄意味着它是一个常量(需要时,每个线程而不是每个进程解析)。 “创建 hInst 的线程”:正是我写的,要成为有效句柄,它必须是 GetModuleHandle(NULL) 或 WinMain 的 hInstance 返回的句柄,如果在 main 线程中(请记住句柄在每个线程中都是正式有效的)。窗口层次结构不是最佳在单个线程中拥有的。它必须在单个线程中拥有(但不同的线程中可能存在不同的层次结构)。
标签: c multithreading debugging winapi