C/C++ - [решено] С++ Builder и потоки (win32 api)

Ответить
Аватара пользователя
st_dark

C/C++ - [решено] С++ Builder и потоки (win32 api)

Сообщение st_dark »

При обращении к компоненту из другого потока приложение зависает. Перед обращением первичный поток, создавший компонент переводится в состояние ожидания. Как только код не переписывал, но лучшее, что получилось, - это зависание при втором обращении.

Вот последняя (но не самая лучшая) версия:





Код:

Код: Выделить всё

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) &param,
		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;
	}
}
Аватара пользователя
st_dark

Re: C/C++ - [решено] С++ Builder и потоки (win32 api)

Сообщение st_dark »

Всё, разобрался. Не надо было первичный поток приостанавливать. Может это и неправильно, но это работает.



Код:

Код: Выделить всё

void __fastcall TMainForm::tvWindowsChange(TObject *Sender, TTreeNode *Node)
{    
        if (Node->Selected == false) return;
    param.hwnd = (HWND) Node->Data;
    StartUpdate();    
}
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 (hwnd == NULL) {
            continue;
        }                 
        lEdit->Text = "0x" + IntToHex((int) hwnd, 8);    // вот тут уже не зависает                         
        SuspendThread (currentThreadHandle);
    }
    return 0;
}
Ответить

Вернуться в «Программирование и базы данных»