我正在用Visual C ++ 2010 Express编写一个程序,它接受来自用户的按键并更改GUI文本以反映他们按下的东西。我创建了三个线程,一个用于运行表单,一个用于检查输入和编辑GUI,另一个用于检查输入并响应输入(通过生成密钥返回)。但是,在程序启动后,如果我切换到与GUI不同的窗口,GUI线程将停止工作。程序的其余部分将继续正常,但我不能(使用委托)注入GUI线程来更改GUI上的文本。
我会发布我认为是问题根源的代码片段,但如果需要,我可以发布更完整的代码(但不会写给其他人阅读)。
DWORD WINAPI form_run(void* ignore){ //thread to run the GUI
Form1^ form = gcnew Form1(); //create a GUI form object
ThreadStart^ threadDelegate = gcnew ThreadStart( form, &MacroPack::Form1::change_macro_state ); //thread to check for input and change GUI text
Thread^ newThread = gcnew Thread( threadDelegate ); //make the thread
newThread->Start(); //start the thread
Application::Run(form); //run the GUI
done = true; //once the GUI finishes, this bool will alert the other threads to close
return 0;
}
这是在main()线程中创建的第一个线程,由:
调用CreateThread(NULL, 0, (LPTHREAD_START_ROUTINE)&form_run, NULL, 0, &form_thread); //form thread is a DWORD to identify the thread
该线程创建一个运行此函数的线程(减少,但切出的所有内容都是其他所有内容的重命名副本):
public: System::Void change_macro_state(){ //part of a class called Form1, which is the GUI
normal_delegate^ normal_del; //delegate to access an already-running thread in the GUI
normal_del = gcnew normal_delegate(this, &MacroPack::Form1::normal_state); //create the delegate
while(!done){ //keep this thread alive to check for input
if((GetKeyState(VK_DOWN) & 0x80) != 0){ //if the down arrow is pressed
Sleep(200); //waits for another thread to set a bool for the thread to be invoked
this->label12->Invoke(normal_del); //call a function that injects into the GUI thread that changes the GUI text
}
Sleep(1); //to slow down on CPU consumption
}
}
该线程注入GUI线程(注意:我最近学习了Visual C ++,所以我几乎不了解委托以及如何避免跨线程调用,所以我不知道“inject”是否适合代表什么代表do)调用此函数来编辑文本:
private: System::Void normal_state(){ //changes the GUI label text
if(normal_active){ //this bool is changed in another thread, which is why I have the Sleep(200); before this is called
label12->Text="Normal - Inactive"; //change the text
}
else if(!normal_active){ //this bool is changed in another thread, which is why I have the Sleep(200); before this is called
label12->Text="Normal - Active"; //change the text
}
}
我不会包含创建的第三个线程,因为它所做的只是检查是否按下了相同的键(向下箭头),并更改了normal_active bool。我在该线程中放置了bool更改,因为即使GUI停止工作,该线程也会继续正常。
RECAP:当我从GUI窗口切换时,GUI不允许我通过代理更改标签的文本(即使我切换回它也不起作用)。
编辑:我一夜之间回来了,它运作正常。我没有更改任何代码,它的工作方式与它应该完全一样。我不确定问题是什么......答案 0 :(得分:1)
似乎你在其他(工作)线程中操纵UI元素,我建议你可以重写代码,只操纵UI线程中的UI元素(这里,它是你的主线程),如果是你想在其他线程中更改UI元素,发送消息到主要的thead。试一试,祝你好运!