| Версия для печати темы
Нажмите сюда для просмотра этой темы в оригинальном формате |
| Форум программистов > Visual C++/MFC/WTL > Как убрать рамку фокуса у CButton с BS_BITMAP ??? |
| Автор: AK84 3.12.2009, 05:14 |
| Народ, помогите, пожалуйста, вот с такой проблемой - Как убрать у CButton с BS_BITMAP пунктирную рамочку, которая отрисовывается при получении кнопкой фокуса??? Я уже сутки (!) живу в гугле и танцую с бубном шаманские танцы, но получается всё-равно вот это: ![]() Как должно быть / хотелось бы: Есть диалоговое окно, в нём CButton с BS_BITMAP, гружу в него один bitmap (SetBitmap()). Всё красиво, пока кнопка не получает фокус (хоть по табу, хоть мышей), и тут появляется эта ... пунктирная рамочка. Нужно, чтоб её небыло Сразу же напишу, что создать свой контрол и отрисовывать кнопку я НЕ МОГУ. Не могу не потому, что не умею, а потому что это не я придумал, но так надо. Также не могу использовать чужие контролы и CBitmapButton. ТОЛЬКО CButton. :( Что пытался сделать: Танцы с бубном начались с попытки сделать не через битмап, а через иконку. Не помогло. Потом были разные комбинаций стилей у самой кнопки, CWnd кнопки и самого диалогового окна. Не помогло. Потом попытка сделать через CImageList (хотя это не желательно в моём проекте :((). Не помогло. Потом разные извращения с отдачей-отбиранием фокусов. На этом этапе добился того, что рамки нет, пока не нажмёшь на кнопку. Нажимаешь - появляется. Отпускаешь - пропадает. Но в момент, когда кнопка рисуется "нажатой" - эта рамка есть После этих всех экспериментов пришёл к интересному выводу - если в OnInitDialog главного диалогового окна вызвать MessageBox или DoModal() какого-нибудь диалога, то после их (MB или другого диалога) закрытия рамка не появляется Я уже обрадовался и решил, что хоть через ж..., но я таки сделаю это, но оказалось, что обрадовался слишком рано :( Выкидывать MessageBox при старте мне нельзя (сразу должен главный диалог показаться). Решил пойти другим путём - создал пустой диалог, вызываю его DoModal() в OnInitDialog главного диалога и в OnInitDialog() пустого диалога делаю OnOK(). Не работает - рамка появляется. Тогда решил поставить таймер в пустом диалоге и закрыть его через 100мс по таймеру - то же самое. Начал вообще извращаться - нажимаю программно в пустом диалоге Esc или Alt+F4 - диалог закрывается, но рамка есть Пошёл ещё другим путём - запустил SPY, посмотрел, кто кому какие мессаджи шлёт. Шлю то же самое - НЕ РАБОТАЕТ - рамка ЕСТЬ! Вот на этом моменте у меня начала потихоньку съезжать крыша и решил за помощью обратиться. Как эту фигню побороть?? Везде народ с этой рамкой борется отрисовкой своих кнопок, но мне НЕЛЬЗЯ. Только голый CButton. Подскажите, плииииииз, хоть в какую сторону копать и что из MSDN курить Заранее спасибо. P.S. Забыл добавить. Если это важно, то пишу в Студии 2008. ОС - Vista Ultimate SP2 x64. P.P.S. Наткнулся на одном форуме на разговор, о том, что такой глюк (когда эта рамка появляется когда ей вздумается и так же точно пропадает) был в Win2000, потом вроде пофиксили. Мож винда виновата? |
| Автор: Earnest 3.12.2009, 08:32 |
| Насколько я знаю, способо только один - своя отрисовка, т.е. OwnerDraw. Можно избежать появления рамки по клавиатуре, убрав стиль TABSTOP, но от фокуса при нажатии это не спасет. Так что увы... А что такого запрещенного в сабклассинге? Не говори никому, как ты это сделал |
| Автор: AK84 3.12.2009, 09:40 |
| Хорошо, тогда вот такой вопрос - чем можно отловить само нажатие и удерживание на кнопке? Я уже почти додумал, как это сделать (уже даже не через ж..., а через хз что В сабклассинге запрещённого ничего нет, просто у заказчика БАГ В ДНК! Блин, не так вопрос сформулировал. Какие мессаджи надо ловить, когда кнопка фокус получает, но ещё нажата? WM_LBUTTONDOWN? Я пробовал и у меня там с ним чего-то не срослось, но ща ещё гляну. Подскажите, куда ещё копать по этому поводу??? |
| Автор: Earnest 3.12.2009, 09:52 |
| Когда мышка уезжает с нажатой кнопки, то происходит сброс капчи. Как конкретно оно реализовано, не знаю, но то, что при нажатии Capture ставится, а потом снимается - факт. Скорее всего, обрабатывается MOUSEMOVE и при съезде с кнопки вызывается ReleaseCapture. Попробуй отловить WM_CAPTURECHANGED. Если тебе можно перехватывать другие сообщения, то и WM_PAINT можно, ибо все это есть сабклассинг. И вообще, скажи заказчику, что любое изменение стандартное поведения кнопки - это сабклассинг. Добавлено через 1 минуту и 54 секунды Ах да, если делать кнопку OwnerDraw, то за реализацию прорисовки отвечает родительское окно. Так что кнопка вовсе даже не меняется. |
| Автор: AK84 3.12.2009, 10:06 |
| Угумсь, в общих чертах понятно. Пошёл копать дальше. Если посчитаете, что тема будет интересна ещё кому-то - не закрывайте пока, я сегодня вечером или завтра отпишусь, что из этого всего получилось. Спасибо за помощь. P.S. Хотел + нажать, а мне говорит - 100 постов давай. БУ! |