Версия для печати темы
Нажмите сюда для просмотра этой темы в оригинальном формате
Форум программистов > Платформы Windows Mobile и Windows Embedded > Обработка нажатия на кнопку ОК


Автор: Brodyaga 26.2.2009, 17:55
Всем доброго времени суток! Пишу на С++ (MSVC 2005) под WinMobile.. Интересует следующее.. Как сделать так, чтобы при нажатие на кнопку ОК, находящуюся в правом верхнем углу диалога программа не закрывалась, а сворачивалась.. И как повесить на эту кнопку свой обработчик?

Автор: WaReZMEN 26.2.2009, 19:15
Brodyaga, а разве у формы нет события onClose?

Автор: Brodyaga 26.2.2009, 19:54
Есть, но что с того? Мне нужно на кнопку свой обработчик повесить как то...

Автор: Brodyaga 6.3.2009, 10:22
ну что? неужели никто не знает? :(

Событие OnClose не вызывается при нажатии на кнопку ОК..

Автор: Skynin 6.3.2009, 11:18
...Потому что кнопка ОК - закрывает а не сворачивает форму. В правом верхнем углу у формы должен быть крестик (такие вот парадоксы) и тогда форма-приложение будет сворачиваемым.

Насчет  OnClose... пишу на .NET CF - поэтому подсказать о С++ не могу.

Автор: Brodyaga 6.3.2009, 11:47
Тогда, как сделать этот самый крестик? а самое главное как обработать нажатие на эти кнопки.. потому что при нажатии на них во всех диалогах кроме главного, программа просто зависает.. а при нажатии на главном - закрывается...

Автор: Skynin 6.3.2009, 12:37
MyForm.MinimizeBox = true;

Цитата

а самое главное как обработать нажатие на эти кнопки.. 

В C# на .NET CF подпиской на соответствующие события.

Цитата

потому что при нажатии на них во всех диалогах

У меня не зависает.

Автор: Brodyaga 6.3.2009, 13:15
Цитата

В C# на .NET CF подпиской на соответствующие события.

Судя из первого поста С# меня не интересует.

На C# у меня тоже не виснет и минимайзбокс свойство работает корректно..

Автор: ksili 6.3.2009, 13:27
Цитата(Brodyaga @  26.2.2009,  21:55 Найти цитируемый пост)
Как сделать так, чтобы при нажатие на кнопку ОК, находящуюся в правом верхнем углу диалога программа не закрывалась, а сворачивалась..

У меня в этом углу крестик. Расскажи как ты держишь девайс...

Автор: Brodyaga 6.3.2009, 13:32
Что значит как держу? Проект создаю MFC Smart Device Application основанный на диалогах..

Автор: ksili 6.3.2009, 13:41
Проект такого типа я не создавал, но там наверно как и в обычном MFC. В дизайнере диалога щёлкни дважды по этой кнопке и открется её обработчик.

Автор: Brodyaga 6.3.2009, 13:49
smile)) В Дизайнере диалога этой кнопки нет smile

Автор: ksili 6.3.2009, 14:15
Можно попробовать так: найти в свойствах диалога, как отключить эту системную кнопку. Чтоб ее воообще не было. А на ее месте нарисовать свою. А уж для своей кнопки обработчик сможешь приделать.

Автор: Brodyaga 6.3.2009, 14:34
Можно.. Но помоему это будет через одно место... Должен же быть грамотный способ, как то ведь пишут такие приложения на с++ и нормально...

Автор: mrbrooks 12.3.2009, 09:32
Brodyaga, все что тебе нужно - это перехватить событие этой кнопки.
Либо перегрузить функции PreTranslateMessage и перехватить там сообщение WM_COMMAND по параметрам IDOK (я обычно в трей пихаю по нажатию на эту кнопку) и IDCANCEL
Либо в функции InitInstance есть переменная nResponse. Она принимает также принимает значения IDOK и IDCANCEL. Собственно простым оператором ветвления можешь описать свои действия.

Автор: Brodyaga 12.3.2009, 17:26
Первый вопрос:
Как запихнуть в терй по условию нажатия на эту кнопку

Второй:
Как быть с другими диалогами? По нажатию кнопки ОК на которых приложение зависает..

Автор: Brodyaga 13.3.2009, 09:42
Цитата

Либо в функции InitInstance есть переменная nResponse. Она принимает также принимает значения IDOK и IDCANCEL. Собственно простым оператором ветвления можешь описать свои действия.


Ну и что... послал я по нажатию на IDOK форме сообщение, чтобы она свернулась.. а она всеровно закрылась...

Код

    INT_PTR nResponse = dlg.DoModal();
    if (nResponse == IDOK)
    {
        ::SendMessage(dlg.GetSafeHwnd(),WM_CLOSE,0,0);
        // TODO: Place code here to handle when the dialog is
        //  dismissed with OK
    }


Она же модально открывается... следовательно в любом случае наверное закроется... Как избежать то этого?

Автор: Brodyaga 13.3.2009, 10:47
Нашёл такую инфу...

вот ссылочки..
http://4pda.ru/forum/index.php?showtopic=6974&pid=77570&mode=threaded&start=
http://www.rsdn.ru/Forum/message/3010001.flat.aspx

как там сказано использовал на диалогах (только не на главном) функцию SHDoneButton после их отображения:

Код

    pDialog->ShowWindow(SW_SHOW);

    ::SHDoneButton(pDialog->GetSafeHwnd(), SHDB_HIDE);


Кнопка ОК действительно исчезла.. появилась кнопка X. Как обработать событие нажатия на эту кнопку?? 

P.S.
Событие OnClose не срабатывает... :(

Автор: Brodyaga 20.3.2009, 15:54
Так никто и не ответил :(
Жаль..

Вот как это делается:

в файле где создаётся объект главного диалога есть функция InitInstance(). В ней наш диалог открываеца как модальный:
Код

    CMyDialog* dlg;

    m_pMainWnd = &dlg;
    INT_PTR nResponse = dlg.DoModal();

    if (nResponse == IDOK)
    {
        // TODO: Place code here to handle when the dialog is
        //  dismissed with OK
    }

    return FALSE;

При таком подходе сворачивания конечно не получица. Меняем это и открываем диалог как не модальный, убирая при этом кнопку ОК и ставя на её месте X:
Код

    CMyDialog* dlg;

    dlg = new CMyDialog();
        
    m_pMainWnd = dlg;

    BOOL ret = dlg->Create(IDD_MYDIALOG);

    if(!ret)
        AfxMessageBox(L"Ошибка при создании диалога");

    dlg->ShowWindow(SW_SHOW);

    dlg->ModifyStyle(0, WS_EX_CAPTIONOKBTN, SWP_NOSIZE);
    ::SHDoneButton(dlg->GetSafeHwnd(), SHDB_SHOWCANCEL);
    ::SHDoneButton(dlg->GetSafeHwnd(), SHDB_HIDE);

    return TRUE;


После этого обрабатываем в нашем диалоге событие OnCancelMode:
Код

void CMyDialog::OnCancelMode()
{
    CDialog::OnCancelMode();

    ShowWindow(SW_HIDE);
}


Всё.. Кнопка ОК заменена на Х! И самое главное диалог по нажатию на Х действительно сворачивается! smile

Автор: Brodyaga 26.10.2009, 21:46
Опять вернусь к этому вопросу... для главной формы то сделал.. а как быть с остальными диалоговыми формами?! При нажатию на кнопку ОК которых, приложение виснет, а должно закрывать формы...

Написание обработчика в OnCancelMode() не помогло, так как следом вызывается OnCancelMode() главнйо формы и сворачивает всё формы одной левой... :(

проект MFC Smart Device Application, MSVC 2005.

Автор: Brodyaga 29.10.2009, 16:35
Ну что? есть какиенить предположения, очень надо...

Автор: ksili 30.10.2009, 08:15
Ну у тебя же есть уже свой класс диалогов CMyDialog? Пропиши все эти настройки у него в OnInitDialog , а потом все диалоги в своем приложении создавай как экземляры класса CMyDialog. И у них у всех будет
Цитата(Brodyaga @  20.3.2009,  19:54 Найти цитируемый пост)
Кнопка ОК заменена на Х! И самое главное диалог по нажатию на Х действительно сворачивается!


Автор: Brodyaga 30.10.2009, 08:43
Дык мне нужно чтобы у других как раз была кнопка OK, которая бы закрывала окно. А она есть, но при нажатии на неё приложение виснет...

Цитата

Пропиши все эти настройки у него в OnInitDialog

какие эти? 

Если эти:
Код

   CMyDialog* dlg;

    dlg = new CMyDialog();
        
    m_pMainWnd = dlg;

    BOOL ret = dlg->Create(IDD_MYDIALOG);

    if(!ret)
        AfxMessageBox(L"Ошибка при создании диалога");

    dlg->ShowWindow(SW_SHOW);

    dlg->ModifyStyle(0, WS_EX_CAPTIONOKBTN, SWP_NOSIZE);
    ::SHDoneButton(dlg->GetSafeHwnd(), SHDB_SHOWCANCEL);
    ::SHDoneButton(dlg->GetSafeHwnd(), SHDB_HIDE);

    return TRUE;


То это же я не в InitDialog прописывал, а в InitInstance, главного класса:
Код

class CMyApp : public CWinApp
{
 ...
};

Автор: ksili 30.10.2009, 09:40
Цитата(Brodyaga @  30.10.2009,  12:43 Найти цитируемый пост)
Дык мне нужно чтобы у других как раз была кнопка OK, которая бы закрывала окно

а раньше писал
Цитата(Brodyaga @  27.10.2009,  01:46 Найти цитируемый пост)
для главной формы то сделал.. а как быть с остальными диалоговыми формами?!

вот и понял неправильно 

Ну наверно стоит поставить брекпойнт в оконной функции и посмотреть, что происходит на сообщении WM_CLOSE.

Автор: Brodyaga 30.10.2009, 15:49
Цитата

вот и понял неправильно 

Да, это я неправильно выразился

Цитата

Ну наверно стоит поставить брекпойнт в оконной функции и посмотреть, что происходит на сообщении WM_CLOSE.

Тут нет оконной функции, MFC. Можно подписаться на сообщение WM_CLOSE, но прога туда не переходит :( как быть?

Автор: Brodyaga 31.10.2009, 22:34
Выкладываю пример, в котором можно наблюдать то, о чём я говорю.
Чтобы увидеть это:
1. Запустите приложение
2. Нажмите кнопку "Открыть форму"
3. На открытой форме нажмите кнопку ОК в правом верхнем углу.

Автор: ksili 6.11.2009, 09:57
Я не наблюдаю зависания. По-моему просто на это нажатие нет никакого действия. Кнопка мигает при каждом нажатии, т.е. реагирует.

Автор: Brodyaga 6.11.2009, 20:22
Цитата

Я не наблюдаю зависания.

А попробуй после нажатия на кнопку ОК(в правом верхнем углу) понажимать на кнопки ОК и Cancel на форме..

Автор: ksili 7.11.2009, 07:03
Цитата(Brodyaga @  7.11.2009,  00:22 Найти цитируемый пост)
А попробуй после нажатия на кнопку ОК(в правом верхнем углу) понажимать на кнопки ОК и Cancel на форме..

После первого нажатия на любую кнопки ОК и Cancel перестают реагировать. Так что по-моему дело не только в кнопке ОК в правом верхнем углу. Если будет время, я ещё посмотрю.

Автор: chaos 9.11.2009, 14:41
самый простой способ это не делать приложение на базе диалога. Из-за этого и появляется ок вместо х

или как вариант можно изменить стиль на лету

Добавлено через 5 минут и 3 секунды
Цитата(Brodyaga @  30.10.2009,  12:49 Найти цитируемый пост)
Можно подписаться на сообщение WM_CLOSE, но прога туда не переходит :( как быть? 

тебе надо перегрузить методы OnOk & OnCancel

Powered by Invision Power Board (http://www.invisionboard.com)
© Invision Power Services (http://www.invisionpower.com)