Справочник функций

Ваш аккаунт

Войти через: 
Забыли пароль?
Регистрация
Информацию о новых материалах можно получать и без регистрации:

Почтовая рассылка

Подписчиков: -1
Последний выпуск: 19.06.2015

Рамка, полная кнопок, и нажатия этих кнопок

2.4K
11 ноября 2008 года
Николай Коровин
58 / / 13.03.2004
Итак, прямая работа с голыми API.
Диалог, у диалога -- обработчик. Если wParam>>16==BN_CLICKED, проверяет wParam&0xFFFF на соответствие идентификаторам кнопок в этом диалоге, и дальше все отлично, словом, классика.
Захотел сделать рамку и наполнить ее кнопками, чтобы кнопки жили одной жизнью вместе с рамкой: вместе становились видимыми, невидимыми, вместе перемещались и т. п. И начались вопросы...

Я тупо назначил СетПэрентом этим кнопкам рамку в качестве родителя. Т. е. у диалога есть дитя -- рамка, у рамки есть дети -- кнопки (которые до этого переназначения тоже были детьми диалога, т. к. переназначение делается уже "по ходу жизни").
Вопрос первый: является ли этот способ нормальным и рекомендуемым?

Естественно, кнопки работать перестали (я бы удивился, если бы не перестали...), потому что BN_CLICKED, естественно, улетает родителю, т. е. рамке, а не "дедушке"-диалогу.
Вопрос второй: как заставить мерзавцев долетать до "родителя родителя" -- до окна диалога с его обработчиком?
288
11 ноября 2008 года
nikitozz
1.2K / / 09.03.2007

Естественно, кнопки работать перестали (я бы удивился, если бы не перестали...), потому что BN_CLICKED, естественно, улетает родителю, т. е. рамке, а не "дедушке"-диалогу.
Вопрос второй: как заставить мерзавцев долетать до "родителя родителя" -- до окна диалога с его обработчиком?



Не знаю насчет нормальности и правильности, но в вашем случае может помочь следующее: переопределяете оконную процедуру для окна рамки, обрабатываете там только нужные вам сообщение (в обработчике можно просто отправить их диалогу), для остальных сообщение вызываете CallWindowProc.

2.4K
11 ноября 2008 года
Николай Коровин
58 / / 13.03.2004
Что-то я запутываться начинаю. Если окно у нас диалог, мы же вроде просто возвращаем обработчиком 0, без CallWindowProc, и дальше сама вызывается стандартная процедура? Или рамка в диалоге -- уже не диалог?
И еще, просто хотелось бы знать:

Что нам мешает назначить рамке тупо тот же обработчик, что и всему родительскому диалогу? (если ответ на предыдущий вопрос -- "нет, рамка -- не диалог", ответ на этот тоже очевиден).

Вроде был какой-то флаг типа "не имеет своего обработчика", который достаточно назначить окну, и BN_CLICKED'ы будут сами передаваться родителю, без ручной передачи обработчиком?
288
11 ноября 2008 года
nikitozz
1.2K / / 09.03.2007
Что-то я запутываться начинаю. Если окно у нас диалог, мы же вроде просто возвращаем обработчиком 0, без CallWindowProc, и дальше сама вызывается стандартная процедура? Или рамка в диалоге -- уже не диалог?
И еще, просто хотелось бы знать:

Что нам мешает назначить рамке тупо тот же обработчик, что и всему родительскому диалогу? (если ответ на предыдущий вопрос -- "нет, рамка -- не диалог", ответ на этот тоже очевиден).

Вроде был какой-то флаг типа "не имеет своего обработчика", который достаточно назначить окну, и BN_CLICKED'ы будут сами передаваться родителю, без ручной передачи обработчиком?



Может я вас действительно неправильно понял. Можете выложить этот кусок кода?

2.4K
11 ноября 2008 года
Николай Коровин
58 / / 13.03.2004
Код:
Открывалка:
DialogBoxParam(hInstance,"TESTS",NULL,Tests,NULL);

Обработчик:
BOOL __export PASCAL Tests (HWND hWnd, unsigned uMsg, WPARAM wParam, LPARAM lParam)
{
    if...
                    Открывалки-закрывалки
    else if (uMsg==WM_COMMAND)
    {
        if (!lParam)...
                                    Меню
        else
        {
            if (wParam>>16==BN_CLICKED)
            {
                if ((wParam&0xFFFF)==B_MAIN) //Просто проверялка, работают ли кнопки
                {
                    cout<<"API calls and IDs OK"<<endl;
                }
                if ((wParam&0xFFFF)==LOCK) //Этот код помещает кнопку в рамку. Для облегчения опытов вынесен сам на кнопку.
                {
                    SetParent (GetDlgItem(hWnd,KEY),GetDlgItem(hWnd,FRAME)); //По этой команде кнопка "ключ" прыгает в рамку "рамка" и дальше живет вместе с ней
                }
                if ((wParam&0xFFFF)==...
                                                                         Тут изучалось поведение кнопки при разных действиях над рамкой
                if ((wParam&0xFFFF)==KEY)
                {
                    Подтвердить, что кнопка "ключ" нажалась
                }
            }
        }
    }
    else return FALSE; //Мы не можем это обработать, это в компетенции АПИ
    return TRUE; //Мы все обработали сами
}


Вот такая хрень. Кнопка "ключ" зрительно нажимается (клики до окна доходят) всегда, а WM_COMMAND с BN_CLICKED доползают до обработчика только до "усыновления" кнопки рамкой.
2.4K
11 ноября 2008 года
Николай Коровин
58 / / 13.03.2004
Кстати, проконтролировал добавочно "if (uMsg==WM_NOTIFY)" и обнаружил, что они вообще не приходят ни при каких нажатиях ни по каким контролам, ни одного сообщения типа "notify" обработчик не получает за всю свою счастливую жизнь. Пуркуа?
14
11 ноября 2008 года
Phodopus
3.3K / / 19.06.2008
Что ты называешь этим загадочным словом "рамка"?? GroupBox что-ли?
2.4K
12 ноября 2008 года
Николай Коровин
58 / / 13.03.2004
Frame. Могу и ее брата GroupBox'а потестить.

Собссно всё, потестил, долгое ли дело... Frame, GroupBox, да хоть гигантская кнопка, на которой живут маленькие дочерние -- все ведет к общему знаменателю, описанному выше. Что, впрочем, естественно и, в общем, ожидалось.
2.4K
15 ноября 2008 года
Николай Коровин
58 / / 13.03.2004
>для остальных сообщение вызываете CallWindowProc.

Я чего-то не понимаю или DefWindowProc?
288
15 ноября 2008 года
nikitozz
1.2K / / 09.03.2007
>для остальных сообщение вызываете CallWindowProc.

Я чего-то не понимаю или DefWindowProc?



Нет, именно CallWindowProc. Эта функция используется при сабклассинге, когда оконную процедуру определенного окна вы заменяете на свою оконную процедуру, в которой обрабатваете лишь нужные вам сообщения, а для остальных вызываете оригинальную процедуру с помощью CallWindowProc.
Почитайте описание функции в MSDN. Там же можно найти и пример сабклассинга.

14
17 ноября 2008 года
Phodopus
3.3K / / 19.06.2008
Когда используется GroupBox, кнопки не становятся его child, а просто лежат поверх него - sibling. Так поступает редактор диалогов MSVC/MFC.
Реклама на сайте | Обмен ссылками | Ссылки | Экспорт (RSS) | Контакты
Добавить статью | Добавить исходник | Добавить хостинг-провайдера | Добавить сайт в каталог