Открывалка:
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; //Мы все обработали сами
}
Рамка, полная кнопок, и нажатия этих кнопок
Диалог, у диалога -- обработчик. Если wParam>>16==BN_CLICKED, проверяет wParam&0xFFFF на соответствие идентификаторам кнопок в этом диалоге, и дальше все отлично, словом, классика.
Захотел сделать рамку и наполнить ее кнопками, чтобы кнопки жили одной жизнью вместе с рамкой: вместе становились видимыми, невидимыми, вместе перемещались и т. п. И начались вопросы...
Я тупо назначил СетПэрентом этим кнопкам рамку в качестве родителя. Т. е. у диалога есть дитя -- рамка, у рамки есть дети -- кнопки (которые до этого переназначения тоже были детьми диалога, т. к. переназначение делается уже "по ходу жизни").
Вопрос первый: является ли этот способ нормальным и рекомендуемым?
Естественно, кнопки работать перестали (я бы удивился, если бы не перестали...), потому что BN_CLICKED, естественно, улетает родителю, т. е. рамке, а не "дедушке"-диалогу.
Вопрос второй: как заставить мерзавцев долетать до "родителя родителя" -- до окна диалога с его обработчиком?
Цитата: Николай Коровин
Естественно, кнопки работать перестали (я бы удивился, если бы не перестали...), потому что BN_CLICKED, естественно, улетает родителю, т. е. рамке, а не "дедушке"-диалогу.
Вопрос второй: как заставить мерзавцев долетать до "родителя родителя" -- до окна диалога с его обработчиком?
Не знаю насчет нормальности и правильности, но в вашем случае может помочь следующее: переопределяете оконную процедуру для окна рамки, обрабатываете там только нужные вам сообщение (в обработчике можно просто отправить их диалогу), для остальных сообщение вызываете CallWindowProc.
И еще, просто хотелось бы знать:
Что нам мешает назначить рамке тупо тот же обработчик, что и всему родительскому диалогу? (если ответ на предыдущий вопрос -- "нет, рамка -- не диалог", ответ на этот тоже очевиден).
Вроде был какой-то флаг типа "не имеет своего обработчика", который достаточно назначить окну, и BN_CLICKED'ы будут сами передаваться родителю, без ручной передачи обработчиком?
Цитата: Николай Коровин
Что-то я запутываться начинаю. Если окно у нас диалог, мы же вроде просто возвращаем обработчиком 0, без CallWindowProc, и дальше сама вызывается стандартная процедура? Или рамка в диалоге -- уже не диалог?
И еще, просто хотелось бы знать:
Что нам мешает назначить рамке тупо тот же обработчик, что и всему родительскому диалогу? (если ответ на предыдущий вопрос -- "нет, рамка -- не диалог", ответ на этот тоже очевиден).
Вроде был какой-то флаг типа "не имеет своего обработчика", который достаточно назначить окну, и BN_CLICKED'ы будут сами передаваться родителю, без ручной передачи обработчиком?
И еще, просто хотелось бы знать:
Что нам мешает назначить рамке тупо тот же обработчик, что и всему родительскому диалогу? (если ответ на предыдущий вопрос -- "нет, рамка -- не диалог", ответ на этот тоже очевиден).
Вроде был какой-то флаг типа "не имеет своего обработчика", который достаточно назначить окну, и BN_CLICKED'ы будут сами передаваться родителю, без ручной передачи обработчиком?
Может я вас действительно неправильно понял. Можете выложить этот кусок кода?
Код:
Вот такая хрень. Кнопка "ключ" зрительно нажимается (клики до окна доходят) всегда, а WM_COMMAND с BN_CLICKED доползают до обработчика только до "усыновления" кнопки рамкой.
Кстати, проконтролировал добавочно "if (uMsg==WM_NOTIFY)" и обнаружил, что они вообще не приходят ни при каких нажатиях ни по каким контролам, ни одного сообщения типа "notify" обработчик не получает за всю свою счастливую жизнь. Пуркуа?
Что ты называешь этим загадочным словом "рамка"?? GroupBox что-ли?
Собссно всё, потестил, долгое ли дело... Frame, GroupBox, да хоть гигантская кнопка, на которой живут маленькие дочерние -- все ведет к общему знаменателю, описанному выше. Что, впрочем, естественно и, в общем, ожидалось.
Я чего-то не понимаю или DefWindowProc?
Цитата: Николай Коровин
>для остальных сообщение вызываете CallWindowProc.
Я чего-то не понимаю или DefWindowProc?
Я чего-то не понимаю или DefWindowProc?
Нет, именно CallWindowProc. Эта функция используется при сабклассинге, когда оконную процедуру определенного окна вы заменяете на свою оконную процедуру, в которой обрабатваете лишь нужные вам сообщения, а для остальных вызываете оригинальную процедуру с помощью CallWindowProc.
Почитайте описание функции в MSDN. Там же можно найти и пример сабклассинга.
Когда используется GroupBox, кнопки не становятся его child, а просто лежат поверх него - sibling. Так поступает редактор диалогов MSVC/MFC.