Форум программистов «Весельчак У»
  *
Добро пожаловать, Гость. Пожалуйста, войдите или зарегистрируйтесь.
Вам не пришло письмо с кодом активации?

  • Рекомендуем проверить настройки временной зоны в вашем профиле (страница "Внешний вид форума", пункт "Часовой пояс:").
  • У нас больше нет рассылок. Если вам приходят письма от наших бывших рассылок mail.ru и subscribe.ru, то знайте, что это не мы рассылаем.
   Начало  
Наши сайты
Помощь Поиск Календарь Почта Войти Регистрация  
 
Страниц: [1]   Вниз
  Печать  
Автор Тема: Как показать окно информации о подключении БД  (Прочитано 17329 раз)
0 Пользователей и 1 Гость смотрят эту тему.
Boriska
Помогающий

us
Offline Offline

« : 21-10-2015 08:08 » 

Привет форумчане.

Подскажите пжлст. Проект МFC. В OnInitDialog подключение к базе. Процесс не быстрый.
Как из OnInitDialog показать окно с битмапом, сообщающее что идет подключение и потом его
закрыть по окончании подключения или выхода из OnInitDialog
« Последнее редактирование: 21-10-2015 08:11 от Boriska » Записан
Алексей++
глобальный и пушистый
Глобальный модератор

ru
Offline Offline
Сообщений: 13


« Ответ #1 : 22-10-2015 04:57 » 

Boriska,

произведи от CDialog класс, накидай в него картинку. Перед началом процесса отобрази немодально экземпляр этого диалога (создать можно локально в OnInitDialog, по выходу из функции диалог сам закроется и удалится)

Свойство надо будет установить - всегда поверх всех окон (system modal вроде, или appmodal - уже не помню)
« Последнее редактирование: 22-10-2015 05:00 от Алексей++ » Записан

Boriska
Помогающий

us
Offline Offline

« Ответ #2 : 22-10-2015 09:26 » 

Типа так ?
Код: (C++)
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);
.............
}
а в самом диалоге который должен появиться
Код: (C++)
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()
Записан
Алексей++
глобальный и пушистый
Глобальный модератор

ru
Offline 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
Помогающий

us
Offline Offline

« Ответ #4 : 22-10-2015 12:15 » 

Можно в трех словах об этом.
Цитата
А диалог не будет перерисовываться, его надо подпинывать, создав локальную петлю обработки сообщений,
дабы в статье легче рыть.
Записан
Алексей++
глобальный и пушистый
Глобальный модератор

ru
Offline 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
Помогающий

us
Offline Offline

« Ответ #6 : 22-10-2015 16:29 » 

Погоди.
Создается диалог.
CWinApp выгребает сообщения приложения и направляет их в Translate и Dispatch. По пути они заезжают в (DlgProc, PretranslateMessage, карту сообщений созданого диалога) и если нет длительной операции то конвейер крутится. OnInitDialog - реакция на сообщение. Если я в ней порождаю диалог, он появлется, его OnInitDialog срабатывает(но его цикл обработки не работает). Почему ?
Картинка появляется если я толкаю
Код: (C++)
        MSG msg;
        while (::PeekMessage(&msg, NULL, 0, 0, PM_NOREMOVE))
        {
                if (!AfxGetApp()->PumpMessage())
                {
                        ::PostQuitMessage(0);
                        return;
                }
        }
но почему он стоит и если я хочу чтобы там был ProgressBar как и сколько его толкать.
Я просто не могу понять почему он стоит - это же другое окно...
Записан
Алексей++
глобальный и пушистый
Глобальный модератор

ru
Offline 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
Помогающий

us
Offline Offline

« Ответ #8 : 23-10-2015 07:13 » 

Ага кажется догоняю. OnInitDialog реакция на WM_INITDIALOG. Соответственно пока OnInitDialog не завершится WM_INITDIALOG не будет передано в
::DispatchMessage -> не завершится while (::GetMessage..) и -> не будет выбрано следующее сообщение. Цикл приложения в стопоре и ни одно из окон
приложения не получит больше сообщение. т.е все стоит. Т.е я смогу толкать от точки вызова диалога с картинкой до точки вызова длительной операции.
А потом таки буду висеть Жаль до ее окончания?
Записан
Алексей++
глобальный и пушистый
Глобальный модератор

ru
Offline Offline
Сообщений: 13


« Ответ #9 : 23-10-2015 07:31 » 

Boriska, да

Но тут по меньшей мере три решения
1) если возможно, квантовать операцию (в моём предыдущем посте функция "выполнить часть операции();")
2) передать в функцию операции callback, который будет вызывать отрисовку
3) разместить выполнение операции в другом потоке

кстати, что там конкретно за операция то ? Чтобы прикинуть, что с ней делать
Записан

Boriska
Помогающий

us
Offline Offline

« Ответ #10 : 23-10-2015 08:32 » 

коннект к MySQL которая в другой сети. Соответственно квантовать тут нечего.
Записан
Алексей++
глобальный и пушистый
Глобальный модератор

ru
Offline Offline
Сообщений: 13


« Ответ #11 : 23-10-2015 08:52 » 

попробуй покрутить метод setConnectOptions - нужно как-то отправить запрос на подключение, но не дожидаться окончания

А в момент, когда нужно работать с базой, проверять IsConnected()

вот тут поройся
https://dev.mysql.com/doc/refman/5.1/en/mysql-options.html

MYSQL_OPT_CONNECT_TIMEOUT


Записан

Boriska
Помогающий

us
Offline Offline

« Ответ #12 : 07-11-2015 09:33 » 

Алексей++
что ты здесь подразумевал, я этот пункт не понял
Цитата
2) передать в функцию операции callback, который будет вызывать отрисовку
Записан
Алексей++
глобальный и пушистый
Глобальный модератор

ru
Offline Offline
Сообщений: 13


« Ответ #13 : 08-11-2015 15:10 » 

Boriska, вот тут примерно описано, что это
https://ru.wikipedia.org/wiki/Callback_(%D0%BF%D1%80%D0%BE%D0%B3%D1%80%D0%B0%D0%BC%D0%BC%D0%B8%D1%80%D0%BE%D0%B2%D0%B0%D0%BD%D0%B8%D0%B5)
Записан

Boriska
Помогающий

us
Offline Offline

« Ответ #14 : 08-11-2015 16:40 » 

Алексей++, Что есть callback я знаю. В трех словах реализацию дай пожалуйста. В другом потоке, понимаю, приложение не будет висеть. Но как тут применить callback, чтоб помог, ума не приложу.
Записан
Алексей++
глобальный и пушистый
Глобальный модератор

ru
Offline Offline
Сообщений: 13


« Ответ #15 : 09-11-2015 05:39 » 

Boriska, а зачем всё в кучу сваливать то ? Обратный вызов оставь для однопоточности, а если ты долгую операцию разместил в другом потоке, то мониторь результат из главного потока и всё. Про синхронизацию данных не забывай только.

В другом потоке, понимаю, приложение не будет висеть.
- скажем так, "висеть" будет тот поток, где долгая операция, а поток с GUI (основной) висеть не будет при этом
Записан

Boriska
Помогающий

us
Offline Offline

« Ответ #16 : 09-11-2015 09:41 » 

Алексей++, я не свалил в кучу. Может знаки препинания не расставил, а ты прочел как будто я решил и нить породить и вариант с callback. Эдакого бульдогоносорога родить.
Я хотел сказать, что как решить свою проблему вариантами 1 и 3 я понял, а как вариантом 2 нет.
Записан
Алексей++
глобальный и пушистый
Глобальный модератор

ru
Offline Offline
Сообщений: 13


« Ответ #17 : 10-11-2015 06:12 » new

Boriska, в твоём случае никак не применить - потому что функция подключения к базе не принимает такого параметра ))
Записан

Страниц: [1]   Вверх
  Печать  
 

Powered by SMF 1.1.21 | SMF © 2015, Simple Machines