Модераторы: feodorv, GremlinProg, xvr, Fixin
  

Поиск:

Ответ в темуСоздание новой темы Создание опроса
> Как правильно закрыть DialogBox? EndDialog? 
V
    Опции темы
bugmenot
Дата 3.3.2009, 00:43 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


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

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



Добрый день.

Есть у меня DialogBox.
Всегда закрывал его функцией DestroyWindow, но недавно прочитал в MSDN, что надо пользоваться функцией EndDialog.
Изменил на EndDialog, но появилась проблема - если этот диалог создает другое окно, например MessageBox, DestroyWindow его закрывает, а EndDialog - нет.
Что же мне делать? Хотелось бы, чтов всякие MessageBox-ы закрывались.

И еще - надо ли пользоваться функцией PostQuitMessage из WM_DESTROY?

Спасибо!
--------------------
доска объявленийвсе о горных велосипедах 
PM MAIL   Вверх
GremlinProg
Дата 3.3.2009, 17:38 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Комодератор
Сообщений: 2706
Регистрация: 9.8.2005
Где: Тюмень

Репутация: 99
Всего: 106



bugmenot, MessageBox не возвращает дескриптор своего дилога,  каким макаром ты его закрываешь-то, кроме как его же кнопкой?

EndDialog нужно использовать только для окон, созданных вызовами: DialogBox, DialogBoxIndirect, DialogBoxIndirectParam и DialogBoxParam, т.е. теми функциями, которые создают цикл обработки сообщений и имеют процедуру окна
а вот CreateDialog нужно уже уничтожать с помощью DestroyWindow

PostQuitMessage с диалогами использовать не нужно, если они завершаются с помощью EndDialog (опять же, к CreateDialog это не относится, для него нужны и цикл обработки сообщений и PostQuitMessage)

Добавлено через 2 минуты и 8 секунд
Цитата(GremlinProg @  3.3.2009,  19:38 Найти цитируемый пост)
...которые создают цикл обработки сообщений и имеют процедуру окна...

поправка: процедуру диалога


--------------------
"Гений всегда разумнее, чем умнее. Ум — это машина, разум — водитель этой машины."
PM WWW ICQ   Вверх
bugmenot
Дата 3.3.2009, 19:12 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


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

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



Спасибо за ответ...

Цитата(GremlinProg @  3.3.2009,  17:38 Найти цитируемый пост)
bugmenot, MessageBox не возвращает дескриптор своего дилога,  каким макаром ты его закрываешь-то, кроме как его же кнопкой?

Взгляните на следующий код:

Код
#include <windows.h>
#include "resource.h"
#include "buffer.h"

LRESULT CALLBACK DlgProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam);

int __stdcall main()
{
    ExitProcess(DialogBox(GetModuleHandle(NULL), MAKEINTRESOURCE(IDD_DIALOG1), NULL, (DLGPROC)DlgProc));
}

LRESULT CALLBACK DlgProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
{
    switch(uMsg)
    {
    case WM_INITDIALOG:
        SetTimer(hWnd, 1, 1000, NULL);
        SetTimer(hWnd, 2, 3000, NULL);
        break;

    case WM_TIMER:
        switch(wParam)
        {
        case 1:
            MessageBox(hWnd, "MessageBox", "Here is a", MB_OK);
            break;

        case 2:
            DestroyWindow(hWnd);
        //    EndDialog(hWnd, 0);
            break;
        }
        break;

    case WM_COMMAND:
        switch(LOWORD(wParam))
        {
        case IDOK:
            break;

        case IDCANCEL:
            break;
        }
        break;
    }

    return FALSE;
}


Данное онко откроется, будут открываться MessageBox-ы, и через 3 секунды и окно и MessageBox-ы закроются, и процесс завершится.
Но если заменить DestroyWindow на EndDialog (строка 29), закроется только окно.

Так вот вопрос следующий: как поступить правильно, если мне нужно, чтоб эти MessageBox-ы закрылись?

(В аттаче проект для Visual Studio 9. компилируйте в Release.)

Присоединённый файл ( Кол-во скачиваний: 4 )
Присоединённый файл  VC9_project.rar 3,38 Kb
--------------------
доска объявленийвсе о горных велосипедах 
PM MAIL   Вверх
GremlinProg
Дата 3.3.2009, 20:17 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Комодератор
Сообщений: 2706
Регистрация: 9.8.2005
Где: Тюмень

Репутация: 99
Всего: 106



все равно, завершать диалоги нужно корректно, попробуй так:
Код

        case WM_TIMER:
            switch(wParam){
                case 1:{
                    HWND owner    = GetLastActivePopup(hWnd);
                    if(!owner){
                        owner    = hWnd;
                    }
                    MessageBox(owner, "MessageBox", "Here is a", MB_OK);
                    break;
                }
                case 2:{
                    //
                    KillTimer(hWnd, 2);
                    KillTimer(hWnd, 1);
                    //
                    while( AnyPopup() ){
                        EndDialog(GetLastActivePopup(hWnd), IDOK);
                    }
                    EndDialog(hWnd, IDOK);
                    break;
                }
            }
            break;

    case WM_COMMAND:
        switch(LOWORD(wParam))
        {
        case IDOK:
            EndDialog(hWnd, IDOK);
            break;

        case IDCANCEL:
            break;
        }
        break;
    }


Добавлено через 35 секунд
таймеры - тоже


--------------------
"Гений всегда разумнее, чем умнее. Ум — это машина, разум — водитель этой машины."
PM WWW ICQ   Вверх
bugmenot
Дата 3.3.2009, 20:49 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


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

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



Цитата(GremlinProg @  3.3.2009,  20:17 Найти цитируемый пост)
AnyPopup()

msdn: "This function is provided only for compatibility with 16-bit versions of Microsoft Windows. It is generally not useful."

Цитата(GremlinProg @  3.3.2009,  20:17 Найти цитируемый пост)
if(!owner){

msdn: "The return value identifies the most recently active pop-up window. The return value is the same as the hWnd parameter, if any of the following conditions are met: ..." (То есть, никак не ноль)

Сделал так:
Код

    case WM_TIMER:
        switch(wParam)
        {
        case 1:
            MessageBox(GetLastActivePopup(hWnd), "MessageBox", "Here is a", MB_OK);
            break;

        case 2:
            HWND hPopup;

            KillTimer(hWnd, 1);
            KillTimer(hWnd, 2);

            do
            {
                hPopup = GetLastActivePopup(hWnd);
                EndDialog(hPopup, 0);
            }
            while(hPopup != hWnd);
            break;
        }
        break;


Вполне устраивает. Большое спасибо.
--------------------
доска объявленийвсе о горных велосипедах 
PM MAIL   Вверх
bugmenot
Дата 3.3.2009, 21:39 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


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

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



msdn: "The return value is the same as the hWnd parameter, if any of the following conditions are met: ... The window identified by hWnd does not own any pop-up windows."

Так что по моему все нормально smile

Edit: Я не разговариваю сам с собой, просто товарищ GremlinProg зачем-то удалил свое сообщение %)

Это сообщение отредактировал(а) bugmenot - 3.3.2009, 21:41
--------------------
доска объявленийвсе о горных велосипедах 
PM MAIL   Вверх
GremlinProg
Дата 3.3.2009, 21:49 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Комодератор
Сообщений: 2706
Регистрация: 9.8.2005
Где: Тюмень

Репутация: 99
Всего: 106



да, все верно, просто внимание не обратил на описание GetLastActivePopup


--------------------
"Гений всегда разумнее, чем умнее. Ум — это машина, разум — водитель этой машины."
PM WWW ICQ   Вверх
bugmenot
Дата 10.3.2009, 19:31 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


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

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



Обычно этот метод работает, но иногда появляется непонятный глюк: GetLastActivePopup все время возвращает одно и то же значение - последнего MessageBox-а, и программа зависает.
Как воспроизвести с данным примером: после появления второго MessageBox-а, переведите фокус на другое окно (например taskbar).

Почему такое происходит, и как решить? Спасибо.
--------------------
доска объявленийвсе о горных велосипедах 
PM MAIL   Вверх
GremlinProg
Дата 10.3.2009, 20:11 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Комодератор
Сообщений: 2706
Регистрация: 9.8.2005
Где: Тюмень

Репутация: 99
Всего: 106



поставь
Код

SetForegroundWindow(::GetLastActivePopup(hWnd));

перед циклом do


--------------------
"Гений всегда разумнее, чем умнее. Ум — это машина, разум — водитель этой машины."
PM WWW ICQ   Вверх
bugmenot
Дата 10.3.2009, 20:18 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


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

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



Помогает, но окно "прыгает" перед закрытием, если фокус не на нем.
Заменил на SetActiveWindow, вроде работает как надо.

Спасибо.
--------------------
доска объявленийвсе о горных велосипедах 
PM MAIL   Вверх
GremlinProg
Дата 10.3.2009, 20:19 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Комодератор
Сообщений: 2706
Регистрация: 9.8.2005
Где: Тюмень

Репутация: 99
Всего: 106



кстати, удалил я сообщение только чтобы не флудить, поскольку смысл его был примерно таким: "нет, не привильно, а, да, правильно"


--------------------
"Гений всегда разумнее, чем умнее. Ум — это машина, разум — водитель этой машины."
PM WWW ICQ   Вверх
  
Ответ в темуСоздание новой темы Создание опроса
Правила форума "C/C++: Системное программирование и WinAPI"
Fixin
GremlinProg
xvr
feodorv
  • Большое количество информации и примеров с использованием функций WinAPI можно найти в MSDN
  • Описание сообщений, уведомлений и примеров с использованием компонент WinAPI (BUTTON, EDIT, STATIC, и т.п.), можно найти в MSDN Control Library
  • Непосредственно, перед созданием новой темы, проверьте заголовок и удостоверьтесь, что он отражает суть обсуждения.
  • После заполнения поля "Название темы", обратите внимание на наличие и содержание панели "А здесь смотрели?", возможно Ваш вопрос уже был решен.
  • Приводите часть кода, в которой предположительно находится проблема или ошибка.
  • Если указываете код, пользуйтесь тегами [code][/code], или их кнопочными аналогами.
  • Если вопрос решен, воспользуйтесь соответствующей ссылкой, расположенной напротив названия темы.
  • Один топик - один вопрос!
  • Перед тем как создать тему - прочтите это .

На данный раздел распространяются Правила форума и Правила раздела С++:Общие вопросы .


Если Вам понравилась атмосфера форума, заходите к нам чаще! С уважением, Chipset, Step, Fixin, GremlinProg, xvr. feodorv.

 
0 Пользователей читают эту тему (0 Гостей и 0 Скрытых Пользователей)
0 Пользователей:
« Предыдущая тема | C/C++: Системное программирование и WinAPI | Следующая тема »


 




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


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

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