Форум программистов, компьютерный форум, киберфорум
Наши страницы
Visual C++
Войти
Регистрация
Восстановить пароль
 
 
Рейтинг 4.56/9: Рейтинг темы: голосов - 9, средняя оценка - 4.56
young_snake
6 / 6 / 2
Регистрация: 26.12.2011
Сообщений: 269
1

GUI зависает при выполнении MFC программы

20.05.2015, 14:46. Просмотров 1622. Ответов 35
Метки нет (Все метки)

У меня есть небольшая программка с интерфейсом на мфц, но когда я нажимаю на кнопку и выполняю полезную работу, то окно зависает. Что делать, чтобы все работало нормально и изменения в интерфейсе отображались "в прямом эфире"?

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

0
Лучшие ответы (1)
Similar
Эксперт
41792 / 34177 / 6122
Регистрация: 12.04.2006
Сообщений: 57,940
20.05.2015, 14:46
Ответы с готовыми решениями:

Использование памяти при выполнении программы
Здравствуйте, товарищи. Столкнулись с такой загвоздкой. Есть некая,...

Правильная архитектура программы на MFC
Здорова! Как правильно создавать программы на mfc чтобы они не подвисали?...

Поменять стиль MFC-программы
Как это можно сделать в уже созданном проекте? Спасибо.

MFC: остановка программы в нужном месте
Есть ли команда в mfc для завершения программы в нужном месте? Например при...

MFC. Запрет запуска второй копии программы
Здравстуйте. В главе 3 книги Дж. Рихтера есть простая реализация примера для...

35
Убежденный
Ушел с форума
Эксперт С++
16128 / 7275 / 1181
Регистрация: 02.05.2013
Сообщений: 11,637
Записей в блоге: 1
Завершенные тесты: 1
20.05.2015, 17:13 2
Выполняйте полезную работу в отдельном потоке.
Помимо того, что это освободит GUI, такой подход позволяет дальше
отделять интерфейс от реализации, что считается хорошей практикой.
0
young_snake
6 / 6 / 2
Регистрация: 26.12.2011
Сообщений: 269
20.05.2015, 17:24  [ТС] 3
Можно пример как это сделать? Просто мне нужно чтобы некоторые данные в окне еще в процессе обновлялись.
0
Убежденный
Ушел с форума
Эксперт С++
16128 / 7275 / 1181
Регистрация: 02.05.2013
Сообщений: 11,637
Записей в блоге: 1
Завершенные тесты: 1
20.05.2015, 20:45 4
Лучший ответ Сообщение было отмечено tezaurismosis как решение

Решение

AfxBeginThread (MFC)
https://msdn.microsoft.com/ru-ru/library/s3w9x78e.aspx
1
young_snake
6 / 6 / 2
Регистрация: 26.12.2011
Сообщений: 269
21.05.2015, 10:07  [ТС] 5
Благодарю!

Добавлено через 13 часов 20 минут
Да, снова вопрос, я так нифига и не разобрался.
У меня есть приложение MFC.
Вот я на кнопку повесил обработчик

C++
1
2
3
AfxBeginThread(WorkerThreadProc, THREAD_PRIORITY_NORMAL,0,0,NULL);
MessageBox("Thread Started");
return;
Вот сама функция:
C++
1
2
3
4
5
UINT WorkerThreadProc( LPVOID Param ) 
{
 
    return TRUE;
}
Мне нужно чтобы она выполняла кое-какие просчеты и время от времени меняла значения в ListControl.
Мне нужно просто передать этой функции ссылку на объект лист-контрола, запустить ее и все? Но я не совсем понимаю что такое param и как оттуда доставать значения тогда. А если недостаточно просто передать ссылку на объект то что нужно?
0
-=ЮрА=-
Заблокирован
Автор FAQ
23.05.2015, 22:08 6
Цитата Сообщение от young_snake Посмотреть сообщение
А если недостаточно просто передать ссылку на объект то что нужно?
- передай в LPVOID Param указатель на класс диалога, убери нафик
Цитата Сообщение от Убежденный Посмотреть сообщение
AfxBeginThread (MFC)
(как будто по дургому поток не создать) также убери это
Цитата Сообщение от young_snake Посмотреть сообщение
return;
(какой к чертям ретурн в обработчике)
Вот приблизительная схема
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
void CMyProgDlg::OnButton(){
     if( _beginthread(WorkerThreadProc, 0, this) != (DWORD)-1L )
         AfxMessageBox("ThreadStarted");
}
 
void WorkerThreadProc( LPVOID Param ) {
      CMyProgDlg * pThis = (CMyProgDlg *)Param;
      if( pThis )
      {
            //к примеру
            pThis->Calculate();
      }
}
Добавлено через 1 минуту
Акцентирую внимание для _beginthread WorkerThreadProc должен иметь тип void, создания потоков в свойствах проекта нужно выставить пропертю multythreaded
0
Убежденный
Ушел с форума
Эксперт С++
16128 / 7275 / 1181
Регистрация: 02.05.2013
Сообщений: 11,637
Записей в блоге: 1
Завершенные тесты: 1
23.05.2015, 22:52 7
Цитата Сообщение от -=ЮрА=- Посмотреть сообщение
убери нафик
Цитата Сообщение от Убежденный
AfxBeginThread (MFC)
(как будто по дургому поток не создать)
CWinThread Class
https://msdn.microsoft.com/en-us/library/48xz4yz9%28v=vs.120%29.aspx
The CWinThread class is necessary to make your code and MFC fully thread-safe.
Thread-local data used by the framework to maintain thread-specific information is
managed by CWinThread objects. Because of this dependence on CWinThread to
handle thread-local data, any thread that uses MFC must be created by MFC.
For example, a thread created by the run-time function _beginthread,
_beginthreadex cannot use any MFC APIs.
1
-=ЮрА=-
Заблокирован
Автор FAQ
24.05.2015, 07:35 8
Убежденный, бред это всё мелкомягкий,
For example, a thread created by the run-time function _beginthread,
_beginthreadex cannot use any MFC APIs.
- особенно это. Сделано чтобы насильственно перевести кодеров на удобное для мелкософта АПИ. Я создаю потоки через CreateThread _beginthread и вот как раз AfxBeginThread реже всего юзаю и абсолютно всё АПИ доступно.
НО раз ты такой опытный системник скажи какие отличия в тредконтексте при создании не AfxBeginThread и какое такое АПИ не доступно, не надо цитат с мсдн, просто покажи, например флагами тред контекста, можешь списком загруженных длл(сможешь?).

Не по теме:

ЗЫ:Мелкософт до поределённого времени писал что SetLayeredWindowAttributes - undocumented и strickly not recomended to use а теперь вдруг рефернс написал https://msdn.microsoft.com/en-us/lib...(v=vs.85).aspx, так что не смеши мои кости.

0
Enno
267 / 170 / 40
Регистрация: 25.08.2014
Сообщений: 1,087
Записей в блоге: 1
24.05.2015, 08:09 9
Цитата Сообщение от -=ЮрА=- Посмотреть сообщение
какое такое АПИ не доступно
Возможно имелось ввиду "не следует", мол "попозже мы сделаем так что нельзя будет, так что не рискуйте".
1
-=ЮрА=-
Заблокирован
Автор FAQ
24.05.2015, 08:39 10
Цитата Сообщение от Enno Посмотреть сообщение
Возможно имелось ввиду "не следует", мол "попозже мы сделаем так что нельзя будет, так что не рискуйте".
- никогда мелкософт такого не сделает их AfxBeginThread оплетка над _beginthread, в оплётке до вызова _beginthread идёт установка некоторого количества параметров, чтобы можно было юзать именно MFC exceptions но это не значит что ошибка потока созданного через _beginthread не будет отловлена системой, хотя об отлавливании ошибок разговор другой, к данной теме не относящийся.

Добавлено через 6 минут
Теперь вернёмся к данной теме : раз уж господин Убежденный, такой профи, то должен был не цитировать мсдн, с попыткой занизить мои знания, а по моему глубокому убеждению в первую очередь тыкнутьyoung_snake, носом сюда
Цитата Сообщение от young_snake Посмотреть сообщение
AfxBeginThread(WorkerThreadProc, THREAD_PRIORITY_NORMAL,0,0,NULL);
MessageBox("Thread Started");
- это неправильная организация запуска потока + ещё поток возращает истну, т.е 1 т.е код ошибки(поток без ошибок должен вернуть ноль)
Ниже небольшая схема правильной организации многопоточности с юзанием MFC
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
CWinApp theApp;
 
 
using namespace std;
UINT WorkerThreadProc( LPVOID Param ) ;
 
int _tmain(int argc, TCHAR* argv[], TCHAR* envp[])
{
    int nRetCode = 0;
 
    // initialize MFC and print and error on failure
    if (!AfxWinInit(::GetModuleHandle(NULL), NULL, ::GetCommandLine(), 0))
    {
        // TODO: change error code to suit your needs
        cerr << _T("Fatal Error: MFC initialization failed") << endl;
        nRetCode = 1;
    }
    else
    {
        // TODO: code your application's behavior here.
        AfxBeginThread(WorkerThreadProc, theApp, THREAD_PRIORITY_NORMAL,0,0,NULL);
        system("pause");
    }
 
    return nRetCode;
}
 
UINT WorkerThreadProc( LPVOID Param ) 
{
 
    MessageBox(GetForegroundWindow(), "I'm started", "Thread message", MB_OK);
    return 0;
}

Не по теме:

Меня на форуме задевает только одно, какие-то бездари процитировав мсдн или вики, становятся эдакими "гуру -экспертами", хотя на практике багаж знаний не превышает багажа знаний обычного начинающего при этом такие горе эксперты осмеливаются делать замечания людям которые кое что объективно знают явно получше.

0
young_snake
6 / 6 / 2
Регистрация: 26.12.2011
Сообщений: 269
24.05.2015, 10:29  [ТС] 11
Да незачем тут пиписьками мериться.
Так вот, return в обработчике был, потому что у меня был там отладочный код, который на тот момент мне не нужен был, и я заретурнил чтобы комменты не писать. Собственно вопрос был в том как менять элементы интерфейса, оказалось что нужно обмениваться сообщениями с главными диалоговым окном и писать обработчики сообщений. Сейчас вроде все работает нормально. За примеры кода спасибо.
0
-=ЮрА=-
Заблокирован
Автор FAQ
24.05.2015, 10:45 12
Цитата Сообщение от young_snake Посмотреть сообщение
Да незачем тут пиписьками мериться.
Так вот, return в обработчике был, потому что у меня был там отладочный код, который на тот момент мне не нужен был, и я заретурнил чтобы комменты не писать. Собственно вопрос был в том как менять элементы интерфейса, оказалось что нужно обмениваться сообщениями с главными диалоговым окном и писать обработчики сообщений. Сейчас вроде все работает нормально. За примеры кода спасибо.
- у тебя было три глупости
Глупость 1
Цитата Сообщение от young_snake Посмотреть сообщение
AfxBeginThread(WorkerThreadProc, THREAD_PRIORITY_NORMAL,0,0,NULL);
- это прототип для CRuntimeClass в первом параметре а нужен был прототип для CThreadProc
Цитата Сообщение от young_snake Посмотреть сообщение
return TRUE;
- глупость 2 не ретурн ошбка а ритурн не ноль без наличии ошибки как таковой(автоматом запускали обработчик ошибки)
Глупость 3 с ретиурном в обработчике ты пояснил, ладно убедительно
Цитата Сообщение от young_snake Посмотреть сообщение
который на тот момент мне не нужен был,
, но изначельно в коде этого видно не было, поэтому и сделал акцент и на данном моменте
Цитата Сообщение от young_snake Посмотреть сообщение
За примеры кода спасибо.
- не за что, правда в твоём исполнении это так прозвучало что помочь ещё раз желание лично у меня не возникнет.
1
young_snake
6 / 6 / 2
Регистрация: 26.12.2011
Сообщений: 269
24.05.2015, 12:02  [ТС] 13
Нет, мне действительно такая помощь полезна потому что в концепции многопоточных приложений в MFC я смыслю мало. Просто срач тут это как-то не в тему показался.
0
-=ЮрА=-
24.05.2015, 12:35
  #14

Не по теме:

Цитата Сообщение от young_snake Посмотреть сообщение
Нет, мне действительно такая помощь полезна потому что в концепции многопоточных приложений в MFC я смыслю мало. Просто срач тут это как-то не в тему показался.
- это не в тебе вина, меня многи тут достали и надо ставить людей на место, а то борзеют не в меру, тут твоя тема ну не знаю что ли оказалась между двух огней. Я всегда приветсвую людей кодящих ГУИ через действительно заточенный под это MFC, а опыт это дело наживное, если интересно зайди сюда http://www.firststeps.ru/mfc/steps/ там много интересных вещей.

0
young_snake
6 / 6 / 2
Регистрация: 26.12.2011
Сообщений: 269
24.05.2015, 13:18  [ТС] 15
Да, вот еще хотел спросить. WinAPI довольно сложен, MFC конечно частично упрощает задачу, но какие еще варианты есть создания графических приложений не используя .NET, чем сейчас разработчики пользуются? Я знаю что есть VCL, но профессионалы, как мне говорили, используют студию. Получаются они на MFC пишут или на своих каких-то библиотеках, основанных на ней. А рядовые разработчики что тогда используют?
0
-=ЮрА=-
Заблокирован
Автор FAQ
24.05.2015, 14:06 16
young_snake, VCL это Борландовская ветка развития того же MFC , да что говорить даже контролы оиднаково выглядят. Касатльно АПИ и МФК, МФК был создан "для профи", чтобы человек "рисовал гуй" не тратятя тучу времени на создание окна, а посвящал это время чему то другому, но не прописыванию case-ов в WindowProc и т.д(я тоже не понимаю АПИ-шников не кодящих с МФК и МФК-шников пишщух в АПИ-стайле). В остальном все ГУёвые либы, на самом деле "гуёвые" и не важно что ими пользуются, бездарям не хочется тратить время на изучение чего то достойного, нахватывают кодов всяких кастомных UI с каких то полукустарных ресурсов а после плодят на вфорумах темы мол то то не работает то это, то там течёт то ещё где то.
И да развею бытующее мнение что MFC мертва, оно мертва для бездарностей, мелкософт же по прежнему рисует гуи с ней, хотя "правящие индусы в компании" всё время толкают концепт проектов в сторону NET приложений.
0
Enno
267 / 170 / 40
Регистрация: 25.08.2014
Сообщений: 1,087
Записей в блоге: 1
24.05.2015, 14:36 17
Цитата Сообщение от young_snake Посмотреть сообщение
какие еще варианты есть создания графических приложений не используя .NET
Есть в MSVS встроенный редактор форм. Растянул кнопки, назначил им ID.
0
Убежденный
Ушел с форума
Эксперт С++
16128 / 7275 / 1181
Регистрация: 02.05.2013
Сообщений: 11,637
Записей в блоге: 1
Завершенные тесты: 1
24.05.2015, 18:52 18
Цитата Сообщение от -=ЮрА=- Посмотреть сообщение
Сделано чтобы насильственно перевести кодеров на удобное для мелкософта АПИ. Я создаю потоки через CreateThread _beginthread и вот как раз AfxBeginThread реже всего юзаю и абсолютно всё АПИ доступно.
Я тоже, не поверишь, юзаю в основном _beginthreadex (не _beginthread,
ибо у нее есть некоторые недостатки). А AfxBeginThread дал только потому,
что это рекомендованный способ создания потоков в MFC-приложениях.

Цитата Сообщение от -=ЮрА=- Посмотреть сообщение
НО раз ты такой опытный системник скажи какие отличия в тредконтексте при создании не AfxBeginThread и какое такое АПИ не доступно, не надо цитат с мсдн, просто покажи, например флагами тред контекста, можешь списком загруженных длл(сможешь?).
Ну давай я специально для тебя подберу примерчик, который будет
работать только с AfxBeginThread ? Только с условием, что после этого
ты перестанешь нести чушь в стиле "меня тут снова обидели" ?

Цитата Сообщение от -=ЮрА=- Посмотреть сообщение
ЗЫ:Мелкософт до поределённого времени писал что SetLayeredWindowAttributes - undocumented и strickly not recomended to use а теперь вдруг рефернс написал https://msdn.microsoft.com/en-us/lib...(v=vs.85).aspx, так что не смеши мои кости.
Теперь вдруг - это когда ? 5 лет назад, что ли ?
Дока на эту функцию есть в Windows 7 SDK (подозреваю, что в старых тоже).

Цитата Сообщение от -=ЮрА=- Посмотреть сообщение
раз уж господин Убежденный, такой профи, то должен был не цитировать мсдн, с попыткой занизить мои знания
Ты уж извини, но у тебя какая-то мания преследования. Я давно заметил, кстати.
При этом ты часто сам первый начинаешь кидаться какашками и провоцировать людей
на такого же уровня ответы. А потом возмущаешься, что тебя тут поддевают и достают.
Какая неожиданность, да ? Ну а лично мне ты и твои знания глубоко фиолетовы.

Цитата Сообщение от -=ЮрА=- Посмотреть сообщение
Меня на форуме задевает только одно, какие-то бездари процитировав мсдн или вики, становятся эдакими "гуру -экспертами", хотя на практике багаж знаний не превышает багажа знаний обычного начинающего при этом такие горе эксперты осмеливаются делать замечания людям которые кое что объективно знают явно получше.
Типично.
В следующий раз позволишь себе такое высказывание - получишь минус.

Цитата Сообщение от -=ЮрА=- Посмотреть сообщение
меня многи тут достали
А по-моему, ситуация как раз обратная.

Цитата Сообщение от -=ЮрА=-
и надо ставить людей на место, а то борзеют не в меру
Мягче надо быть, мягче. На вещи смотреть шире, а к людям быть терпимее
1
-=ЮрА=-
Заблокирован
Автор FAQ
24.05.2015, 19:14 19

Не по теме:

Цитата Сообщение от Убежденный Посмотреть сообщение
Ну давай я специально для тебя подберу примерчик, который будет
работать только с AfxBeginThread ? Только с условием, что после этого
ты перестанешь нести чушь в стиле "меня тут снова обидели" ?
- давай!
Цитата Сообщение от Убежденный Посмотреть сообщение
При этом ты часто сам первый начинаешь кидаться какашками и провоцировать людей
на такого же уровня ответы.
- вспоминай лучше
Цитата Сообщение от Убежденный Посмотреть сообщение
А по-моему, ситуация как раз обратная.
- я кого то тут трогаю, не, а ты вспоминай.



Добавлено через 4 минуты
Цитата Сообщение от Убежденный Посмотреть сообщение
Типично.

Не по теме:

В следующий раз позволишь себе такое высказывание - получишь минус.

Не по теме:

- о да, ты крут, честно!
Жду пример.



Добавлено через 9 минут
Цитата Сообщение от Убежденный Посмотреть сообщение
Ну давай я специально для тебя подберу примерчик, который будет
работать только с AfxBeginThread ?
- да пожалуйста без искуственных бряков на call функции, малоли ты напишешь длл в которой стоит подмена в таблице вызовов _beginthread(кто тебя знает), увижу такое пеняй на себя. В студию давай реальный пример кода где кроме AfxBeginThread ну никак.
Вобщем я буду ждать.
0
Убежденный
Ушел с форума
Эксперт С++
16128 / 7275 / 1181
Регистрация: 02.05.2013
Сообщений: 11,637
Записей в блоге: 1
Завершенные тесты: 1
24.05.2015, 22:09 20
Цитата Сообщение от -=ЮрА=- Посмотреть сообщение
скажи какие отличия в тредконтексте при создании не AfxBeginThread и какое такое АПИ не доступно, не надо цитат с мсдн, просто покажи
C++
1
2
CPrintDialogEx Dlg;
HRESULT const Result = Dlg.DoModal();
Если вызвать этот код в потоке, созданном AfxBeginThread, то все окей, появляется
стандартный диалог настройки принтера и потом DoModal возвращает корректное
значение (PD_RESULT_XXX). Если же выполнить этот код в потоке, созданном при
помощи CreateThread или _beginthread(ex), никакого диалога показано не будет, а
DoModal вернет 0x80070006 (The handle is invalid). Проверено на VC++2008SP1 и
VC2013upd4, в Windows XP SP2 и Windows 7 SP1 x64.

А ответ здесь:
Visual Studio\VC\altmfc\src\mfc\dlgprntx.cpp
C++
1
2
3
4
5
6
7
8
9
10
HRESULT CPrintDialogEx::HandleMessage(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam, LRESULT* plResult)
{
    // set up m_hWnd the first time
    if(m_hWnd == NULL)
        Attach(hWnd);
 
    // we need to set this, because the message comes from the another loop
    _AFX_THREAD_STATE* pThreadState = _afxThreadState.GetData();
    
    // ...
_afxThreadState - это thread-local (TLS). В потоке, созданном не AfxBeginThread,
нужного слота в _afxThreadState нету, поэтому DoModal завершается с ошибкой.
1
24.05.2015, 22:09
MoreAnswers
Эксперт
37091 / 29110 / 5898
Регистрация: 17.06.2006
Сообщений: 43,301
24.05.2015, 22:09

Сложно ли научится создавать WIN32 программы с MFC?
Я могу создавать консольные программы на С++ и хотел бы знать сложно ли...

нужен совет в подправке программы (приложение MFC)
Вот код файла реализации. Как сделать так, чтобы не было &quot;промаргивания&quot; экрана...

Как в процессе работы программы можно изменить размер диалога (MFC)
Есть у меня окно вида CModelView и немодальный диалог CModelDialog. Как менять...


Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
20
Ответ Создать тему
Опции темы

КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin® Version 3.8.9
Copyright ©2000 - 2018, vBulletin Solutions, Inc.
Рейтинг@Mail.ru