Boriska
Помогающий
Offline
|
|
« : 21-10-2015 08:08 » |
|
Привет форумчане.
Подскажите пжлст. Проект МFC. В OnInitDialog подключение к базе. Процесс не быстрый. Как из OnInitDialog показать окно с битмапом, сообщающее что идет подключение и потом его закрыть по окончании подключения или выхода из OnInitDialog
|
|
« Последнее редактирование: 21-10-2015 08:11 от Boriska »
|
Записан
|
|
|
|
Алексей++
глобальный и пушистый
Глобальный модератор
Offline
Сообщений: 13
|
|
« Ответ #1 : 22-10-2015 04:57 » |
|
Boriska,
произведи от CDialog класс, накидай в него картинку. Перед началом процесса отобрази немодально экземпляр этого диалога (создать можно локально в OnInitDialog, по выходу из функции диалог сам закроется и удалится)
Свойство надо будет установить - всегда поверх всех окон (system modal вроде, или appmodal - уже не помню)
|
|
« Последнее редактирование: 22-10-2015 05:00 от Алексей++ »
|
Записан
|
|
|
|
Boriska
Помогающий
Offline
|
|
« Ответ #2 : 22-10-2015 09:26 » |
|
Типа так ? BOOL CMyDlg::OnInitDialog() { ............. ............. HWND h_Wnd = m_splashDlg.m_hWnd; if (h_Wnd == NULL)m_splashDlg.Create(IDD_SPLASH_SCREEN, NULL); m_splashDlg.ShowWindow(SW_SHOW); ............. m_splashDlg.EndDialog(0); ............. } а в самом диалоге который должен появиться BOOL CSplashDlg::OnInitDialog() { CDialogEx::OnInitDialog();
m_bmp.LoadBitmap(IDB_CONNECT); ((CStatic*)GetDlgItem(IDC_PICTURE))->SetBitmap(m_bmp); // m_picture.SetBitmap(m_bmp);
// TODO: Add extra initialization here return TRUE; // return TRUE unless you set the focus to a control } если так то так я делал. Диалог появляется, но картинки на нем нет все время работы OnInitDialog(). Если же убрать m_splashDlg.EndDialog(0); то картинка появляется в момент появления диалога CMyDlg по окончанию OnInitDialog()
|
|
|
Записан
|
|
|
|
Алексей++
глобальный и пушистый
Глобальный модератор
Offline
Сообщений: 13
|
|
« Ответ #3 : 22-10-2015 09:37 » |
|
картинку проще в редакторе ресурсов установить А диалог не будет перерисовываться, его надо подпинывать, создав локальную петлю обработки сообщений, как описано , например, тут https://msdn.microsoft.com/en-us/library/windows/desktop/ms644936(v=vs.85).aspxДобавлено через 2 минуты и 25 секунд:а в CMyDlg::OnInitDialog() надо просто создать и показать диалог ... ... CSplashDlg dlg(this); dlg.Create(...); dlg.Show(); детали не вспомню, разбирайся ) Добавлено через 3 минуты и 39 секунд:ещё вариант - открыть модальный CSplashDlg CSplashDlg dlg(this); dlg.doModal(); там петля уже будет, а вот уже в самом CSplashDlg , в каком-нибудь обработчике таймера начать выполнять процедуру обработки. В обработчике же периодически проверять завершение. Указатель передан (this) , так что вызвать нужную функцию из твоего внешнего диалога не составит труда Добавлено через 2 минуты и 32 секунды:но с модальным вариант удобен, когда функция не блокирует обработку петли, опять же. Если блокирует, первый вариант лучше Добавлено через 2 минуты и 25 секунд:Можно также разместить работу с базой в отдельном потоке (не забывая про межпоточную синхронизацию). Тогда лаги не будут сказываться на GUI , но придётся дополнительно повозиться над общением GUI и БД
|
|
« Последнее редактирование: 22-10-2015 09:48 от Алексей1153 »
|
Записан
|
|
|
|
Boriska
Помогающий
Offline
|
|
« Ответ #4 : 22-10-2015 12:15 » |
|
Можно в трех словах об этом. А диалог не будет перерисовываться, его надо подпинывать, создав локальную петлю обработки сообщений, дабы в статье легче рыть.
|
|
|
Записан
|
|
|
|
Алексей++
глобальный и пушистый
Глобальный модератор
Offline
Сообщений: 13
|
|
« Ответ #5 : 22-10-2015 12:27 » |
|
можно даже больше, чем в трёх http://frolov-lib.ru/books/bsp/v11/ch1_4.htmВ данном случае в локальной петле можно обрабатывать только рисовальные сообщения (указать диапазон WM_PAINT,WM_PAINT)
|
|
« Последнее редактирование: 22-10-2015 12:32 от Алексей++ »
|
Записан
|
|
|
|
Boriska
Помогающий
Offline
|
|
« Ответ #6 : 22-10-2015 16:29 » |
|
Погоди. Создается диалог. CWinApp выгребает сообщения приложения и направляет их в Translate и Dispatch. По пути они заезжают в (DlgProc, PretranslateMessage, карту сообщений созданого диалога) и если нет длительной операции то конвейер крутится. OnInitDialog - реакция на сообщение. Если я в ней порождаю диалог, он появлется, его OnInitDialog срабатывает(но его цикл обработки не работает). Почему ? Картинка появляется если я толкаю MSG msg; while (::PeekMessage(&msg, NULL, 0, 0, PM_NOREMOVE)) { if (!AfxGetApp()->PumpMessage()) { ::PostQuitMessage(0); return; } } но почему он стоит и если я хочу чтобы там был ProgressBar как и сколько его толкать. Я просто не могу понять почему он стоит - это же другое окно...
|
|
|
Записан
|
|
|
|
Алексей++
глобальный и пушистый
Глобальный модератор
Offline
Сообщений: 13
|
|
« Ответ #7 : 22-10-2015 17:14 » |
|
Boriska, тебе не нужно все сообщения обрабатывать, нужно только рисование обеспечить WM_PAINT и, конечно же PM_REMOVE, нужно же удалять сообщения BOOL ...::OnInitDialog() { CDialog::OnInitDialog();
while(!операция закончилась) { выполнить часть операции();
//обработка рисования GUI //локальная петля обработки while (::PeekMessage(&msg, NULL, WM_PAINT, WM_PAINT, PM_REMOVE)) { ::TranslateMessage(&msg); ::DispatchMessage(&msg); } }
return 1; }
Почему сообщения не работают без пинка ? Ну так ты же находишься в обработчике сообщений, вызванном из main , то есть, по сути, внутри функции DispatchMessage (вызванной из main). Как думаешь, почему основная петля не работает при этом ? )))
|
|
|
Записан
|
|
|
|
Boriska
Помогающий
Offline
|
|
« Ответ #8 : 23-10-2015 07:13 » |
|
Ага кажется догоняю. OnInitDialog реакция на WM_INITDIALOG. Соответственно пока OnInitDialog не завершится WM_INITDIALOG не будет передано в ::DispatchMessage -> не завершится while (::GetMessage..) и -> не будет выбрано следующее сообщение. Цикл приложения в стопоре и ни одно из окон приложения не получит больше сообщение. т.е все стоит. Т.е я смогу толкать от точки вызова диалога с картинкой до точки вызова длительной операции. А потом таки буду висеть до ее окончания?
|
|
|
Записан
|
|
|
|
Алексей++
глобальный и пушистый
Глобальный модератор
Offline
Сообщений: 13
|
|
« Ответ #9 : 23-10-2015 07:31 » |
|
Boriska, да
Но тут по меньшей мере три решения 1) если возможно, квантовать операцию (в моём предыдущем посте функция "выполнить часть операции();") 2) передать в функцию операции callback, который будет вызывать отрисовку 3) разместить выполнение операции в другом потоке
кстати, что там конкретно за операция то ? Чтобы прикинуть, что с ней делать
|
|
|
Записан
|
|
|
|
Boriska
Помогающий
Offline
|
|
« Ответ #10 : 23-10-2015 08:32 » |
|
коннект к MySQL которая в другой сети. Соответственно квантовать тут нечего.
|
|
|
Записан
|
|
|
|
Алексей++
глобальный и пушистый
Глобальный модератор
Offline
Сообщений: 13
|
|
« Ответ #11 : 23-10-2015 08:52 » |
|
попробуй покрутить метод setConnectOptions - нужно как-то отправить запрос на подключение, но не дожидаться окончания А в момент, когда нужно работать с базой, проверять IsConnected() вот тут поройся https://dev.mysql.com/doc/refman/5.1/en/mysql-options.htmlMYSQL_OPT_CONNECT_TIMEOUT
|
|
|
Записан
|
|
|
|
Boriska
Помогающий
Offline
|
|
« Ответ #12 : 07-11-2015 09:33 » |
|
Алексей++что ты здесь подразумевал, я этот пункт не понял 2) передать в функцию операции callback, который будет вызывать отрисовку
|
|
|
Записан
|
|
|
|
Алексей++
глобальный и пушистый
Глобальный модератор
Offline
Сообщений: 13
|
|
« Ответ #13 : 08-11-2015 15:10 » |
|
|
|
|
Записан
|
|
|
|
Boriska
Помогающий
Offline
|
|
« Ответ #14 : 08-11-2015 16:40 » |
|
Алексей++, Что есть callback я знаю. В трех словах реализацию дай пожалуйста. В другом потоке, понимаю, приложение не будет висеть. Но как тут применить callback, чтоб помог, ума не приложу.
|
|
|
Записан
|
|
|
|
Алексей++
глобальный и пушистый
Глобальный модератор
Offline
Сообщений: 13
|
|
« Ответ #15 : 09-11-2015 05:39 » |
|
Boriska, а зачем всё в кучу сваливать то ? Обратный вызов оставь для однопоточности, а если ты долгую операцию разместил в другом потоке, то мониторь результат из главного потока и всё. Про синхронизацию данных не забывай только. В другом потоке, понимаю, приложение не будет висеть. - скажем так, "висеть" будет тот поток, где долгая операция, а поток с GUI (основной) висеть не будет при этом
|
|
|
Записан
|
|
|
|
Boriska
Помогающий
Offline
|
|
« Ответ #16 : 09-11-2015 09:41 » |
|
Алексей++, я не свалил в кучу. Может знаки препинания не расставил, а ты прочел как будто я решил и нить породить и вариант с callback. Эдакого бульдогоносорога родить. Я хотел сказать, что как решить свою проблему вариантами 1 и 3 я понял, а как вариантом 2 нет.
|
|
|
Записан
|
|
|
|
Алексей++
глобальный и пушистый
Глобальный модератор
Offline
Сообщений: 13
|
|
« Ответ #17 : 10-11-2015 06:12 » |
|
Boriska, в твоём случае никак не применить - потому что функция подключения к базе не принимает такого параметра ))
|
|
|
Записан
|
|
|
|
|