我有一个用C编写的Windows应用程序(使用gcc / MinGW),除了几个用户界面问题之外,它工作得很好。 一,我根本无法得到从线程更新进度栏。 事实上,我可能无法获取任何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 }
当我说,“只显示消息”,这意味着callback中的MessageBox()函数工作,但不是PostMessage()来更新进度条的位置。
如果我使用PostThreadMessage()将消息发送到主线程的消息循环,我可以拦截它并启动MessageBoxes,所以它肯定工作。 但是,即使我尝试用这种方式更新进度栏。 它仍然不会更新。
我错过了什么?
从用于PBM_STEPIT的MSDN文档 :
wParam Must be zero. lParam Must be zero.
CLR_DEFAULT被定义为0xFF000000L。 如果将代码更改为:
PostMessage(progress_bar, PBM_STEPIT, 0, 0);
我怀疑问题在于你的消息循环。 无论如何,三件事情:
奖金第四点: