我有一个用C语言编写的Windows应用程序(使用gcc / MinGW)除了一些UI问题外,效果很好。一,我根本无法从一个线程获取进度条。事实上,我可能无法获得任何UI更新内容。
基本上,我有一个产生一些处理的衍生线程,并且从该线程我尝试更新主线程中的进度条。我尝试使用PostMessage()到主hwnd,但没有运气,即使我可以做其他事情,如打开消息框。但是,不清楚消息框是在线程内还是在主线程上调用。
以下是一些代码:
// in header/globally accessible
HWND wnd; // main application window
HWND progress_bar; //progress bar
typedef struct { //to pass to thread
DWORD mainThreadId;
HWND mainHwnd;
char *filename;
} THREADSTUFF;
//callback function
LRESULT CALLBACK WndProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam){
switch (msg){
case WM_CREATE:{
// create progress bar
progress_bar = CreateWindowEx(
0,
PROGRESS_CLASS,
(LPCTSTR) NULL,
WS_CHILD | WS_VISIBLE,
79,164,455,15,
hwnd,
(HMENU)20,
NULL,
NULL);
SendMessage(progress_bar, PBM_SETSTEP, 1, 0 );
SendMessage(progress_bar, PBM_SETPOS, 0, 0 );
//test to make sure it actually works
SendMessage(progress_bar, PBM_STEPIT, 0, 0 ); //works fine
SendMessage(progress_bar, PBM_STEPIT, 0, 0 ); //works fine
SendMessage(progress_bar, PBM_STEPIT, 0, 0 ); //works fine
SendMessage(progress_bar, PBM_STEPIT, 0, 0 ); //works fine
break;
}
case WM_COMMAND: {
if(LOWORD(wParam)==2){ //do some processing in a thread
//struct of stuff I need to pass to thread
THREADSTUFF *threadStuff;
threadStuff = (THREADSTUFF*)malloc(sizeof(*threadStuff));
threadStuff->mainThreadId = GetCurrentThreadId();
threadStuff->mainHwnd = hwnd;
threadStuff->filename = (void*)&filename;
hThread1 = CreateThread(NULL,0,convertFile (LPVOID)threadStuff,0,NULL);
}else if(LOWORD(wParam)==5){ //update progress bar
MessageBox(hwnd,"I got a message!", "Message", MB_OK | MB_ICONINFORMATION);
PostMessage(progress_bar,PBM_STEPIT,0,0);
}
break;
}
}
}
这一切似乎都运转正常。问题在于:
DWORD WINAPI convertFile(LPVOID params){
//get passed params, this works perfectly fine
THREADSTUFF *tData = (THREADSTUFF*)params;
MessageBox(tData->mainHwnd,tData->filename,"File name",MB_OK | MB_ICONINFORMATION); //yep
PostMessage(tData->mainHwnd,WM_COMMAND,5,0); //only shows message
PostThreadMessage(tData->mainThreadId,WM_COMMAND,5,0); //does nothing
}
当我说“只显示消息”时,这意味着回调中的MessageBox()函数可以工作,而不是PostMessage()来更新进度条的位置。
如果我使用PostThreadMessage()向主线程的消息循环发送消息,我可以拦截它并启动MessageBoxes,这样它肯定有效。但是,即使我尝试以这种方式更新进度条。它仍然不会更新。
我错过了什么?
答案 0 :(得分:1)
来自MSDN documentation for PBM_STEPIT:
wParam
Must be zero.
lParam
Must be zero.
CLR_DEFAULT定义为0xFF000000L。如果您将代码更改为:
会发生什么PostMessage(progress_bar, PBM_STEPIT, 0, 0);
答案 1 :(得分:1)
我怀疑问题在于你的消息循环。无论如何,有三件事: