Поиск:

Ответ в темуСоздание новой темы Создание опроса
> UpdateData и поток, Ошибка при вызове UpdateData 
V
    Опции темы
BIV
Дата 21.6.2012, 11:43 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Бывалый
*


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

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



Всем доброе время суток!
Возникла такая сложность: Есть диалоговое окно и в ней текстовое поле IDC_EDIT1, которое названа переменной edit типом int. Есть поток, который пытается занести данные в edit и команды UpdateData

Код

UINT ThreadProc(LPVOID param)  //Создание потоковой функции 
{
    int a=0;
    CpotokiDlg *qwe;
    for(;;)
    qwe->UpdateData(TRUE);
    a++;
    qwe->edit=a;
    qwe->UpdateData(FALSE);
    return 0;
}

BOOL CpotokiDlg::OnInitDialog()
{
    CDialog::OnInitDialog();
    
    ...

    edit=0;
    AfxBeginThread(ThreadProc, this); //Создание потока

    return TRUE;  // return TRUE  unless you set the focus to a control
}


Компиляция прошла успешно, но появляется окно с ошибкой
Run-Time Check Failure #3 - The variable 'qwe' is being used without being initialized.

Что я тут сделал не так?
Как мне обновить данные?
PM MAIL   Вверх
xTr1m
Дата 21.6.2012, 12:39 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 692
Регистрация: 9.2.2005
Где: Москва

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



Тут, ты просто объявляешь указатель (он указывает "вникуда")
Код

CpotokiDlg *qwe;


а тут ты сразу его используешь
Код

qwe->UpdateData(TRUE);


как я понимаю между этими строками забыл
Код

qwe = reinterpret_cast<CpotokiDlg*>(param);


p.s. кстати, цикл 
Код

for(;;)
    qwe->UpdateData(TRUE);

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

Код

UINT ThreadProc(LPVOID param)  //Создание потоковой функции 
{
    int a=0;
    CpotokiDlg *qwe = reinterpret_cast<CpotokiDlg*>(param);

    for(;;)
   {
        qwe->UpdateData(TRUE);
        a++;
        qwe->edit=a;
        qwe->UpdateData(FALSE);
   }

    return 0;
}
BOOL CpotokiDlg::OnInitDialog()
{
    CDialog::OnInitDialog();
    
    ...
    edit=0;
    AfxBeginThread(ThreadProc, this); //Создание потока
    return TRUE;  // return TRUE  unless you set the focus to a control
}



Это сообщение отредактировал(а) xTr1m - 21.6.2012, 12:44
PM MAIL WWW ICQ   Вверх
BIV
Дата 21.6.2012, 12:46 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Бывалый
*


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

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



Поправил
Код

UINT ThreadProc(LPVOID param)  //Создание потоковой функции 
{
    CpotokiDlg *qwe = reinterpret_cast<CpotokiDlg*>(param);
    int a=5;
    for(;;){
    qwe->UpdateData(TRUE);
    a++;
    qwe->edit=a;
    qwe->UpdateData(FALSE);}
    return 0;
}


Но при компиляции Debug, то по прежнему ошибка, если компилить через Release, то нормально, прога запускается и выполняется цикл, но при выходе окно с надписей:
Unhandled exception at 0x7863e574 in potoki.exe: 0xC0000005: Access violation reading location 0x0000c266.

И после него второе:
No symbols are loaded for any call stack frame. The source code cannot be displayed.

Если запустить скомпилированную программу в папке, то вроде работает и ничего не вылетает.
Это нормально?

Добавлено через 8 минут и 40 секунд
Вот так при компиляции Release, при завершении ничего не выскакивает, а при Debug по прежнему не доволен

Код

UINT ThreadProc(LPVOID param)  //Создание потоковой функции 
{
    CpotokiDlg *qwe = reinterpret_cast<CpotokiDlg*>(param);
    int a=5;
    for(;;)
    {
        a++;
        qwe->out(a);
    }
    return 0;
}

void CpotokiDlg::out(int a)
{
    UpdateData(TRUE);
    edit=a;
    UpdateData(FALSE);
}

PM MAIL   Вверх
xTr1m
Дата 21.6.2012, 13:03 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 692
Регистрация: 9.2.2005
Где: Москва

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



Вообще проблема в том, что окна между потоками должны передаваться по HWND (ну так во всяком случае рекомендуется). Но вот такой код почему-то не работает. Может кто из более опытных знает. Мне тоже стало интересно, поэтому покопаюсь. 

Код

...
edit=0;
AfxBeginThread(ThreadProc, GetSafeHwnd()); //Создание потока
...

UINT ThreadProc(LPVOID param)  //Создание потоковой функции 
{
    int a=0;
    HWND hWnd = reinterpret_cast<HWND>(param);
    CWnd *pWnd = CWnd::FromHandle(hWnd);
    CBug1Dlg *qwe = reinterpret_cast<CBug1Dlg*>(pWnd);
    
    for(;;)
    {
        qwe->UpdateData(TRUE);
        a++;
        qwe->edit=a;
        qwe->UpdateData(FALSE);
    }
    return 0;
}


Добавлено @ 13:07
Можно вот так

Код

UINT ThreadProc(LPVOID param)  //Создание потоковой функции 
{
    int a=0;
    HWND hWnd = reinterpret_cast<HWND>(param);
    CWnd *pWnd = CWnd::FromHandle(hWnd);
    CBug1Dlg *qwe = reinterpret_cast<CBug1Dlg*>(pWnd);
    
    CString str;
    for(;;)
    {
        str.Format(L"%d", ++a);
        qwe->GetDlgItem(IDC_EDIT1)->SetWindowText(str);
    }
    return 0;
}


но это без механизма UpdateData

Это сообщение отредактировал(а) xTr1m - 21.6.2012, 13:07
PM MAIL WWW ICQ   Вверх
BIV
Дата 21.6.2012, 13:27 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Бывалый
*


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

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



qwe->GetDlgItem(IDC_EDIT1)->SetWindowText(str);
Работает, но у меня при завершении появляется окошко с ошибкой.

В моем случае не появлялась.
Говорят что в Release лучше не компилить, якобы это не безопасно. Хотелось бы знать почему. В Debug по прежнему не могу
PM MAIL   Вверх
xTr1m
Дата 21.6.2012, 13:31 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 692
Регистрация: 9.2.2005
Где: Москва

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



странно. у меня такой пример завершается нормально. что пишет про ошибку? (хотя по-хорошему, нужно завершить поток)
а нельзя оставлять такой релиз, так как потом может всплыть что угодно и когда угодно, этакая мина, которая рано или поздно взорвется. Так как в дебаге просто предупреждают, что мол, нехорошо так делать.

ну вот так вот можно еще
Код

UINT ThreadProc(LPVOID param)  //Создание потоковой функции
{
    int a=0;
    HWND hWnd = reinterpret_cast<HWND>(param);
    CWnd *pWnd = CWnd::FromHandle(hWnd);
    CBug1Dlg *qwe = reinterpret_cast<CBug1Dlg*>(pWnd);
    
    CString str;
    for(;;)
    {
        CWnd *pEdit = qwe->GetDlgItem(IDC_EDIT1);
        if(NULL == pEdit || FALSE == ::IsWindow(hWnd))
            break;

        str.Format(L"%d", ++a);
        pEdit->SetWindowText(str);
    }
    return 0;
}


Это сообщение отредактировал(а) xTr1m - 21.6.2012, 13:34
PM MAIL WWW ICQ   Вверх
BIV
Дата 21.6.2012, 14:34 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Бывалый
*


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

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



Все, ошибки возникали из-за моей глупости, как раз забыл поток завершить.
Думаю, проблема решена. Главное что работает)) xTr1m, спасибо!)
PM MAIL   Вверх
  
Ответ в темуСоздание новой темы Создание опроса
0 Пользователей читают эту тему (0 Гостей и 0 Скрытых Пользователей)
0 Пользователей:
« Предыдущая тема | Visual C++/MFC/WTL | Следующая тема »


 




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


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

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