Поиск:

Ответ в темуСоздание новой темы Создание опроса
> С++ Builder и потоки (win32 api), Обратиться к компоненту из потока 
V
    Опции темы
StDark
Дата 17.12.2011, 19:01 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 3
Регистрация: 14.5.2011

Репутация: нет
Всего: нет



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


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;
    }

}

PM MAIL   Вверх
SVN74
Дата 18.12.2011, 01:35 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 740
Регистрация: 5.5.2008
Где: Комсомольск на Дн епре

Репутация: 11
Всего: 18



для VCL надо использовать  TThread
либо SendMessage для событий формы, на прямую нельзя...

Это сообщение отредактировал(а) SVN74 - 18.12.2011, 01:37
PM MAIL WWW   Вверх
StDark
Дата 18.12.2011, 07:09 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 3
Регистрация: 14.5.2011

Репутация: нет
Всего: нет



А надо бы... Вот фрагмент, в котором добавляются элементы в TreeNode :

Код

DWORD WINAPI ThreadFunc3()
  {
    ProcInfo();
    MemoryInfo();
  }


void MemoryInfo()
  {
     int n = 20;
     MEMORYSTATUSEX mem;
     String S;
     TTreeNode* Node;
     Node = Form3->TreeView2->Items->Add(NULL, "Память");
     mem.dwLength = sizeof(MEMORYSTATUSEX);
     GlobalMemoryStatusEx(&mem);
     S = "Общая физическая";
     MakeString(&S, n + 12);
     S += IntToStr((__int64)mem.ullTotalPhys/(1024*1024)) + " Мбайт";
     Form3->TreeView2->Items->AddChild(Node, S);
     S = "Доступная физическая";
     MakeString(&S, n + 9);
     S += IntToStr((__int64)mem.ullAvailPhys/(1024*1024)) + " Мбайт";
     Form3->TreeView2->Items->AddChild(Node, S);
     S = "Общая вирутальная";
     MakeString(&S, n + 11);
     S += IntToStr((__int64)mem.ullTotalVirtual/(1024*1024)) + " Мбайт";
     Form3->TreeView2->Items->AddChild(Node, S);
     S = "Доступная вирутальная";
     MakeString(&S, n + 8);
     S += IntToStr((__int64)mem.ullAvailVirtual/(1024*1024)) + " Мбайт";
     Form3->TreeView2->Items->AddChild(Node, S);
  }

HANDLE WorkThread4()//создать поток для выполнения функции
  {
    DWORD WINAPI ThreadFunc4();
    DWORD IDThread;
    HANDLE hThread;
    hThread = CreateThread(NULL, 0, (LPTHREAD_START_ROUTINE) ThreadFunc4, NULL,
                           CREATE_SUSPENDED, &IDThread);
    SetThreadPriority(hThread, THREAD_PRIORITY_BELOW_NORMAL);
    return hThread;
 }


PM MAIL   Вверх
StDark
Дата 18.12.2011, 10:38 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 3
Регистрация: 14.5.2011

Репутация: нет
Всего: нет



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

Код

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;
}

PM MAIL   Вверх
Dem_max
Дата 18.12.2011, 11:38 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
***


Профиль
Группа: Завсегдатай
Сообщений: 1780
Регистрация: 12.4.2007

Репутация: 14
Всего: 39



Цитата

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

крайне не правильно.
Вообще прочитай тут притом внимательно, а то нагородил геморрою
http://rxlib.ru/WinLesson/bles2_1.htm


--------------------
Американские программисты долго не могли понять, почему русские при зависании Windоws всё время повторяют "Твой зайка написал" ("Yоur bunnу wrоte")
PM MAIL   Вверх
  
Ответ в темуСоздание новой темы Создание опроса
Правила форума "С++ Builder"
Rrader

Запрещается!

1. Публиковать ссылки на вскрытые компоненты

2. Обсуждать взлом компонентов и делиться вскрытыми компонентами

  • Литературу по С++ Builder обсуждаем здесь
  • Действия модераторов можно обсудить здесь
  • С просьбами о написании курсовой, реферата и т.п. обращаться сюда
  • Настоятельно рекомендуем заглянуть в DRKB (Delphi Russian Knowledge Base) - крупнейший в рунете сборник материалов по Дельфи


Если Вам понравилась атмосфера форума, заходите к нам чаще! С уважением, Rrader.

 
0 Пользователей читают эту тему (0 Гостей и 0 Скрытых Пользователей)
0 Пользователей:
« Предыдущая тема | C++ Builder | Следующая тема »


 




[ Время генерации скрипта: 0.0436 ]   [ Использовано запросов: 22 ]   [ GZIP включён ]


Реклама на сайте     Информационное спонсорство

 
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности     Powered by Invision Power Board(R) 1.3 © 2003  IPS, Inc.