| Версия для печати темы
Нажмите сюда для просмотра этой темы в оригинальном формате |
| Форум программистов > C/C++: Системное программирование и WinAPI > Заставить окно (или часть) перерисоваться |
| Автор: Ibragim 29.7.2005, 01:16 | ||||
| Всем ночи доброй. Такой вот вопрос: есть кусок кода
по этой обработке, по идее, переносится отображние фокуса на другой элемент (мой, я там сам все в WM_PAINT перерисую). Так вот, корректно перерисует он только в том случае, если я, например, спрячу и покажу окно, или закрою его окном другого приложениея, и т.д. А мне нужно сразу. Как сказать - "возьми и перерисуйся"? Добавлено @ 01:19 а, и еще: есть окно
Можно ему как-то сказать подсветить синим заголовок - что оно активно? Заголовок хоть убей серый, неактивный. Заранее спасибо. |
| Автор: chaos 29.7.2005, 08:17 | ||
1) сделай так:
2) за место сет фокус попробуй воспользоваться SetActiveWindow |
| Автор: Ibragim 29.7.2005, 10:36 |
| Спасибо, 1) - без коментариев, все прекрасно тут же заработало. ... а вот 2) не помогает если не делаешь SetFocus - окно вообще не ловит сообщения, а SetActiveWindow ни к чему не приводит - никаких изменений. Может, лажа где-то в WS_XXX ? |
| Автор: chaos 29.7.2005, 11:56 | ||||
а про это по подробнее бы и коду побольше |
| Автор: Ibragim 29.7.2005, 12:48 | ||||
C удовольствием:
Если нужно, вот классы окон:
|
| Автор: Romikgy 29.7.2005, 14:56 | ||
А если после
ShowWindow(hLeftWnd, SW_RESTORE); // ну или SW_SHOW по идее должно помочь. |
| Автор: Rrader 29.7.2005, 15:09 | ||
SetForegroundWindow(hLeftWnd); |
| Автор: chaos 29.7.2005, 16:13 | ||
| вот посмотри решение: сделал я следуюющее: создал дав независимых окна(не установленно свойство WM_CHILD и тп) послетого как создал делаю SetParent
если не понравится решение, попробуй почитать сдесь: http://www.lcard.ru/~nail/frolov/bsp/v17/ch1.htm#ch1_1 |
| Автор: Ibragim 29.7.2005, 17:32 |
| Спасибо за помощь всем откликнувшимся, трудовая ночь начинается, буду попробовать. Сегодня напишу, что получилось. |
| Автор: Ibragim 29.7.2005, 18:16 |
| Да, chaos, спасибо, все заработало!! сэнкс. |
| Автор: Ibragim 29.7.2005, 18:28 |
| господа, а не знаете - как запретить двигать и изменять размеры окна, но иметь у него CAPTION (ну, эдакую синюю или серую панельку с названием вверху)? |
| Автор: Fixin 29.7.2005, 20:53 |
| Обрабатываешь сообщение WM_GETMINMAXINFO, в lParam - указатель на структуру MINMAXINFO. В ней ставь нужные размеры. Или сразу при обработке этого сообщения SetWindowPos(...); |
| Автор: Ibragim 30.7.2005, 17:02 |
| а есть вариант просто убрать такую возможность в стиле окна? ну, например, чтобы пользователю нельзя было "ухватиться" за край окна? |
| Автор: Fixin 30.7.2005, 21:36 |
| Сейчас посмотрю... |
| Автор: Fixin 30.7.2005, 21:56 | ||
Ага, вот стиль окна:
|
| Автор: Ibragim 31.7.2005, 13:14 |
| спасибо, пока не помогло. получается что пользователь может "взяться" за заголовок и сделать все что угодно, в пределах родительского окна, понятно. А мне нужно, чтобы относительно родительского окна размер и положение дочернего окна были всегда жестко закреплены Ну ладно, буду пробовать дальше |
| Автор: Fixin 1.8.2005, 18:01 |
| Так ты как дочернее создаешь? Вроде это автоматом должно быть, те по спец стилю. |
| Автор: Ibragim 2.8.2005, 01:28 |
| Если создавать дочернее, нет переключения между ними - не подсвечиваются заголовок. Мне chaos посоветовал сделать WS_OVELAPPED и потом привязать SetParent(hWnd2, hWnd1); - заработало нормально переключение фокуса, но теперь его можно тягать |
| Автор: chaos 2.8.2005, 08:05 | ||
че значит тягеть, перетаскивать что ли? ты хочешь что бы твои панельки нельзя было перетаскивать? |
| Автор: Ibragim 2.8.2005, 12:44 |
| Да, чтобы у дочернего окна был заголовок (активный или не активный), но пользователь не мог бы начать действия по изменению размера (это сделано - просто нет BORDER) или положения окна (вот как это запретить - не знаю). Само собой, что поскольку окно дочернее, то при изменении размеров родительского окна я пересчитываю размеры дочерних, и при изменении положения родительского окна дочерние перетаскиваются вместе с ним автоматически (так уж окна в Windows устроены). |
| Автор: ManiaK 2.8.2005, 14:48 | ||
Если у окна есть заголовок - его можно тягать, должно быть без вариантов |
| Автор: Romikgy 2.8.2005, 16:28 |
| Либо по таймеру проверяй Top & Left Формы, изменились .... поставь необходимые. |
| Автор: Ibragim 2.8.2005, 16:48 |
| Понятно, буду рисовать сам. Спасибо. Romikgy - мне нужно убрать возможность начать перетаскивание, а не "бороться" с пользователем - он туда, я назад. К тому же зачем лишний раз занимать процессорное время? |
| Автор: p0s0l 2.8.2005, 18:16 | ||
Можно обрабатывать WM_NCHITTEST и просто возвращать всегда HTCLIENT (или HTNOWHERE), тогда изменять размер и таскать окно будет нельзя... |
| Автор: Earnest 3.8.2005, 06:57 |
| В данном случае правильнее рисовать заголовок самому - как ManiaK сказал. Тем более есть для этого готовые функции (точно не помню, кажется DrawFrameControl). И не изобретать лишних сущностей. Вариант от chaos остроумный, но все же это извращение. Хорошо для "поиграться", но в реальной работающей программе... Поверьте, вам хватит извращений, которые и без вас есть в WIndows. |
| Автор: p0s0l 3.8.2005, 07:37 | ||
Т.к. такое окно будет выделяться на фоне других окон, если включены визуальные стили в WinXP. В этом случае надо рисовать через ThemeManager, но, при этом никто не гарантирует, что в следующей версии Microsoft не сделает еще один API для визуалиции окошек... Нужен ли лишний геморрой ради ничего ? Кроме этого, возможно, нужно рисовать кнопочки свертывания, развертывания, закрытия, обрабатывать их нажатие, и учитывать Active окно или нет - легче ли это ? Не знаю, как кому, но вставить 1-2 строчки кода, чтобы запретить двигать окно и изменять размер, имхо, не извращение. |
| Автор: Earnest 3.8.2005, 19:40 |
| Не согласная я 1) Для имитации системных контролов есть DrawFrameControl - она должна рисовать так, как в данный момент установлено в системе. Так что рисование - это тоже 2 строчки. Да и с чего это ты взял, что дочернее окно должно иметь такой же заголовок как overlapped... 2) Одной-двумя строчками кода проблему не решить. Resize - да, можно отбить стилями, а вот чтобы за заголовок таскать нельзя было, да чтобы курсор над ним не менялся... Радикальнее всего - перехватывать NCHITTEST и возвращать HTCLIENT, но тогда забудьте про стандартные кнопочки - не будут они сами работать. А если они не нужны - о чем разговор. 3) Извращение - создавать окно как OVERLAPPED, а потом делать его дочерним. Даже если в данный момент код работает, никто не гарантирует, что в дальнейшем не появится проблем. 4) Нарисовать можно все, что угодно, как бы геморройно это не было. И это уж точно локально и безопасно. |
| Автор: p0s0l 4.8.2005, 00:16 | ||||||||
Также почитай в MSDN об UxTheme Manager
Предположим, нам нужны кнопочки. В твоём случае надо, навскидку: 1. Рисовать кэпшен: DrawCaption ( DrawThemeBackground ) 2. Рисовать кнопочки: DrawFrameControl ( DrawThemeBackground ) 3. Обрабатывать NCHITTEST, чтобы указать, что мышь щелкнула по такой-то кнопочке ( И охото же это тебе делать Как видишь, обработкой одного сообщения не обойтись. При чем ни один из этих пунктов не делается в пару строк кода. Например, кнопочки - нужно учитывать, наведен ли курсор, нажата ли она, узнавать размер кнопочек; кэпшен - активное или неактивное окно, получать размер Caption'а. Всё это усложняется тем, что нужно учитывать визуальные стили. В случае Win9x и классического визуального стиля, нужно использовать старые функции DrawCaption и DrawFrameControl, при включенном визуальном стиле - использовать OpenThemeData + DrawThemeBackground + CloseThemeData (при чем правильно должно быть сделано так, что uxtheme.dll не статически подключается, а динамически, т.к. она есть только в WinXP). И, как я уже говорил, даже если реализовать такой геморройный подход, мы не защищены от будущих нововведений, которые обязательно будут. Тогда нам надо будет добавлять еще 1 вариант рисования, использующий новый API. В моём случае: В обработчике WM_NCHITTEST вызываем стандартный обработчик, в случае, если результат = HTCAPTION, делаем его HTCLIENT... Буквально пара-тройка строк кода, и вуаля, всё готово Ну, убедил, или еще нет ? |
| Автор: Earnest 4.8.2005, 06:23 |
| Проще (меньше кода) - не значит лучше... Верю, верю я насчет тем и стилей, но ведь стандартные средства для рисования все равно есть. Ну, 5 строчек будет. Можно "расширить" API, написав отдельную функцию, которая всегда рисует правильно. Даже если добавятся новые средства рисования - это всего лишь изменения в одной функции. Да и вообще, что касается времени жизни программы - так ли это важно в данном случае? Если речь идет об упражнении или программе для домашнего использования - ради бога, все возражения снимаю. Но если это коммерческая программа, или бесплатная, но долго-живущая и для других, тогда см. п.3. Как еще один аргумент - посмотри код какой-нибудь известной библиотеки контролов - не извращаются там ребята, сами все рисуют как миленькие и пользуются исключительно стандартными приемами. Наверное, лохи При появлении нового API от Микрософт выпускаем новую версию с поддержкой новых бантиков и берем за это дополнительные деньги. Ну и далее, по мелочам: Обрабатывать нужно не NCHITTEST (это же не NC-область)... Прочие обработчики ... рутина, конечно, но если уж приспичило ... я бы вообще свой контрол сделала, для имитации заголовка, чтобы инкапсулировать все намертво. "Издевательство над бедным окном" - это когда overlapped-окно пытаются заставить себя вести как дочернее - это уже генетические эксперименты - скрещивание ежа с ужом. А когда рисуют чего-нибудь на нем - это так, легкий макияж. Стремно выглядящий интерфейс - не самая большая проблема Дельфи... Надеюсь, дельфисты здесь не ходют, а то побьют. |
| Автор: p0s0l 4.8.2005, 07:54 | ||||||||||||||||
Ты так и не объяснила, чем же плохо обрабатывать NCHITTEST - какие же будут последствия ? Опиши их поподробнее, чем же это грозит таким страшным, что нужно вместо 10 секунд сидеть полчаса кодить... Я тебе уже описал несколько минусов твоего способа. Есть и другие проблемы. Например, многие видяхи в настройках имеют всякие штукенции, которые добавляют какие-нибудь кнопочки во все приложения - твоя программа будет обделена этой фичей... Да мало еще чего может быть - мы никак не можем узнать, что винда располагает в титлебарах, может в следующей винде там появяться еще какие дополнительные элементы... Рисовать самому - это уже не стандартно. Давай так же: нафиг нам обычное чтение файлов, будем сами читать структуру FAT32 / NTFS и так читать файлы - чего нам стоит ? Здесь абсолютно такая же ситуация - лишний геморрой, хотя винда сама может всё сделать сама... Это просто-напросто плохой стиль программирования. С таким подходом можно каждую простейшую задачу решать нестандартным способом (хотя есть общепринятый нормальный способ решения задачки). Работать будет, да, но зачем-то надо будет делать лишнюю работу, при этом в будущем будут проблемы. Не вижу смысла в этом. Если требуется рисовать какой-то особый титлебар, тогда да, рисовать надо самому, а в нашем случае этого не требуется, пусть винда решает, как должен выглядеть нормальный титлебар...
И чем интерфейс Дельфи стремен ? Тем что, стандартный виндовый ? Тогда это претензии не к Borland, а Microsoft
(зы: ДОБАВЛЕНО ПОЗЖЕ Блин, я сразу и не заметил, что ты девушка! Эээ.. Пардон А почему, собственно, "Эрнест" ? Я из-за этого и протормозил... |
| Автор: Earnest 6.8.2005, 07:29 | ||
| Стоп-стоп-стоп p0s0l! Мы о разных вещах спорим Я во всем с тобой согласна, что касается максимального использования готового API и т.д. И NCHITTEST обрабатывать не проблема, очень полезное сообщение. Но в данном конкретном случае - с чего все началось - помнишь? Создаем оверлаппед окно, а потом делаем его дочерним - и ради чего? чтобы стандартный заголовок иметь. А потом еще и бороться со стандартным его поведением - не перемещаться и т.д. Вот это мне и не нравится - какой-то проктологический подход. Когда может возникнуть такая задача? Представляю 2 варианта: 1) Куча придоченных окон, собранные вместе на панели - но тогда за заголовок как раз и надо таскать. 2) Страничка проперти в современном стиле, не в окне с закладками, а когда слева дерево, а справа показывается набор параметров для текущего выбора - примерно как VC7 свойства проекта и настройки. Нужен весь описанный геморрой для 2-й задачи? Нужно, чтобы заголовок дочерней странички выглядел точь-в-точь как "настоящий"? А вот хлебнуть каких-нибудь проблем из-за того, что страница изначально создавалась как не-дочерняя - ты уверен, что их не будет? Что она будет получать и генерировать все положенные дочернему окну сообщения? И не посылать ничего лишнего? Будет ли оно с точки зрения системы дочерним, или все же нет? И куча т.д. Можно, конечно, все это проверить... Нет, возможно где-то в недрах MSDN есть статья где русским языком по-английски написано: если popup окну поставить парента, то оно превращается в честное дочернее окно. Может, там заодно написано, что с перетаскиванием за заголовок делать? Не попадалсь мне пока такая статья. Если бы речь шла о том, чтобы прибить к экрану оверлаппед окно - то во всем ты прав, да и не о чем тут спорить. Про Дельфи: про стремные кнопочки - это ты сам сказал, только это я и имела в виду. Мне не нравится язык - потому что это Паскаль (испорченный Вот с базами данных у Дельфи хорошо (но тоже до известных пределов), но меня базы данных последнее время совсем не волнуют.
|
| Автор: p0s0l 6.8.2005, 13:49 | ||||
Я только теперь понял, про что ты говоришь... На счет этого тоже кстати можно поспорить, но спорить не буду, т.к. вопрос на самом деле весьма спорный для меня самого
А что, в других библиотеках так прямо всё и доступно ? Это ж вообщем-то тоже не есть гуд... Ну чего-то это совсем оффтоп пошел, сейчас модератор раздела заругается |
| Автор: ManiaK 8.8.2005, 09:27 | ||
Кхе-кхе... Действительно, начиналось всё с дочернего окна. Зачем там какие-то дополнительные элементы? Открываем MS Word 2003 и тянем в нём тульбарную панельку, утягиваем до обособления в дочернее окно. Обратите внимание на заголовок этого появившегося окна. Теперь меняем стиль на WinXP. Просто? просто. Красиво? красиво. А чего ещё надобно?.. |