С++ Builder и потоки (win32 api)
При обращении к компоненту из другого потока приложение зависает. Перед обращением первичный поток, создавший компонент переводится в состояние ожидания. Как только код не переписывал, но лучшее, что получилось, - это зависание при втором обращении.
Вот последняя (но не самая лучшая) версия:
Код:
struct TThreadParam {
TComponent *owner;
HWND hwnd; // хэндл окна, информацию о котором нужно вывести
};
DWORD WINAPI ThreadProcGeneral (LPVOID lparam) {
TThreadParam *param = (TThreadParam *) lparam;
DWORD error;
HANDLE currentThreadHandle = OpenThread (THREAD_ALL_ACCESS,
FALSE, GetCurrentThreadId());
TComponent *owner = param->owner;
TLabeledEdit *lEdit =
(TLabeledEdit *) owner->FindComponent("leHandle");
// выход пока не нужен, мне бы обновление сделать
while (true) {
HWND hwnd = param->hwnd;
if (owner == NULL || hwnd == NULL) {
continue;
}
lEdit->Text = "0x" + IntToHex((int) hwnd, 8); // вот тут зависает
SetEvent (hEventGeneral);
SuspendThread (currentThreadHandle);
}
return 0;
}
void TMainForm::InitThreads () {
hThreadGeneral = = NULL; // хэндл потока, обновляющего вкладку "Общие"
hThreadGeneral = CreateThread (NULL, 0, ThreadProcGeneral, (LPVOID) ¶m,
CREATE_SUSPENDED, NULL);
allThreads[0] = hThreadGeneral;
allEventForThreads[0] = hEventGeneral = CreateEvent (NULL, FALSE, FALSE, NULL);
}
void StartUpdate () {
int i;
for (i = 0; i < COUNT_THREADS; i++) {
ResetEvent (allEventForThreads[i]);
}
for (i = 0; i < COUNT_THREADS; i++) {
ResumeThread(allThreads[i]);
}
}
void __fastcall TMainForm::tvWindowsChange(TObject *Sender, TTreeNode *Node)
{
//
DWORD error;
if (Node->Selected == false) return;
param.hwnd = (HWND) Node->Data;
StartUpdate();
DWORD waitStatus = WaitForMultipleObjects (COUNT_THREADS, allEventForThreads,
TRUE, INFINITE);
error = GetLastError();
switch (waitStatus) {
case WAIT_OBJECT_0:
break;
case WAIT_FAILED:
return;
}
}
|