Приветствую всех!
Столкнулся тут с одной проблемой. Используем только чистый Windows API без всяких WTL и MFC. Создаем таб-контрол в родительском окне, все ок... Двигаем окно — все ок. Рисуется как надо. Ресайзим окно — получаем так называемый "flickering"- мигание таб-контрола при перерисовке. Причем только при ресайзинге родительского окна. Как ни старался исправить это — нифига не получается... Особенно сильно мигание заметно, если используется неклассическая тема для окон (windows themes). Например, в XP Theme отчетливо видно мигание. Знаю, что для решения подобных проблем с миганием используют двойную буферизацию — вывод в offscreen-поверхность и потом BitBlt... Но опять же, нифига не выходит.
Вопрос, собственно, следующий: кто-нть может показать код, как на Windows API сделать таб контрол, который бы не мигал при ресайзе окна. Причем задача такова, чтобы таб контрол был "приклеен" внутри к правой границе родительского окна и сдвигался-раздвигался и уменьшал-увеличивал свой размер при ресайзе родительского окна.
Здравствуйте, Slava Antonov, Вы писали:
SA>Hello x84, you wrote:
>> Двигаем окно — все ок. Рисуется как надо. Ресайзим окно — получаем так >> называемый "flickering"
SA>Здесь есть SA>как бороться с мерцанием при ресайзинге. См. "Еще одна причина мерцания", SA>и "Clipping child windows".
SA>-- SA>Всего хорошего, Слава SA>http://slava.users.otts.ru
Да я все это читал уже. Вот вы мне попробуйте дать код, который бы создавал простое окошко с табом, прилепленным к правой внутренней границе родительского окна. Таб должен иметь константную ширину (изначально он занимаетне все окно)... По горизонтали размер таба не меняется...Размер таба меняется по вертикали, чтобы соответствовать размерам родительского окна при ресайзинге... такжетаб должен сдвигаться влево-вправо при соответствующем ресайзинге... и самое главное — НЕ МИГАТЬ. Казалось бы, задача тривиальная на первый взгляд, однако, я не видел еще реализации... И у меня у самого покаеще не получилось реализовать... Эдакий таб-контрол на подобие боковой панельки...
x84>Вопрос, собственно, следующий: кто-нть может показать код, как на Windows API сделать таб контрол, который бы не мигал при ресайзе окна. Причем задача такова, чтобы таб контрол был "приклеен" внутри к правой границе родительского окна и сдвигался-раздвигался и уменьшал-увеличивал свой размер при ресайзе родительского окна.
Этот вопрос здесь уже был. Воспользуйтесь поиском, а также натравите Spy++ на Task Manager — все станет понятно.
Я не стал приводить все примеры всех вариантов, которые пробовал.Их было много... пробовал субклассинг, пробовал отлавливать мессаджи и рисовать в офскрин-буфер и т.п... Ничего не помогло... Поэтому я вот взял обычное окно с таб-контролом (мигание заметно только при ресайзинге, если присмотреться к краям таб-контрола). Как изменить этот код, чтобы сохранить ту же функциональность и чтобы таб перестал мигать?
Hello x84, you wrote:
>> Давайте лучше вы приведете ваш код. А мы посмотрим, что там не так. > Как изменить этот код, чтобысохранить ту же функциональность и чтобы таб > перестал мигать?
Хммм... похоже на то, что это беда самого Tab-Control.
Здравствуйте, x84, Вы писали:
x84>Неужели никто не может помочь? Буду очень благодарен
Привет.
Я наверное разочарую, но похоже способа совсем избавиться от мигания нет. Я несколько месяцев назад пытался решить эту проблему, но до конца так это сделать и не удалось.
Наболее неплохие результаты я получил, когда делал следующим образом:
1. Использовал регионы, т.е. когда происходил ресайз, я определял новые появившиеся области и ставил на них регион, соответственно Винда рисовала только в этих областях (если размер окна увеличивался)
Но должен сказать, что данный метод очень геморойный и было много багов, связанных с тем, что надо отлавливать дополнительные условия перерисовки (например над контролом проезжает окно, значит нам надо установить регион на весь контрол и перерисовать его), плюс учитывать child окна. К тому же закладки должны всегда находиться в регионе отрисовки (иначе они глючат).
2. Положил на весь размер контрола child диалог и установил для контрола флажок clip_children. Соответственно диалог не мигал, однако проблему закладок это не решило.
SA>Хммм... похоже на то, что это беда самого Tab-Control.
Да не похоже, что это беда самого контрола...
Вот пример, который мне прислал знакомый прогер на дельфе. Очевидно, что оно не мигает. Как достичь того же на C в MSVC? Пример
Здравствуйте, Romul, Вы писали:
R>Я наверное разочарую, но похоже способа совсем избавиться от мигания нет. Я несколько месяцев назад пытался решить эту проблему, но до конца так это сделать и не удалось.
Да есть способ, я просто уверен в этом... Вот пример, который мне прислал знакомый прогер на дельфе. Очевидно, что оно не мигает. Как достичь того же на C в MSVC? Ведь все равно так или иначе испльзуется WinAPI независимо от языка... Пример
Здравствуйте, x84, Вы писали:
x84>Здравствуйте, Romul, Вы писали:
R>>Я наверное разочарую, но похоже способа совсем избавиться от мигания нет. Я несколько месяцев назад пытался решить эту проблему, но до конца так это сделать и не удалось.
x84>Да есть способ, я просто уверен в этом... Вот пример, который мне прислал знакомый прогер на дельфе. Очевидно, что оно не мигает. Как достичь того же на C в MSVC? Ведь все равно так или иначе испльзуется WinAPI независимо от языка... x84>Пример
Два варианта:
1. Либо ипсользуется double buffer, но способа заставить WinAPI выводить в DC отличный от экранного, я не знаю
2. Delphi по всей видимости не используют оконный класс TAB в чистом виде. Они могут вызывать функции Visual API напрямую для отрисовки отдельных элементов таб контрола. Соответственно, если они его рисуют сами, то могут сначала рисовать в memory DC. В инете (по-моему и на RSDN) есть статейки о том, как самостоятешьно отрисовывать элементы используя Visual API.
Второй вариант вероятнее всего, т.к. я где-то встречал упоминания о том, что Builder (а значит и Delphi) использует именно Visual Style API для отрисовки контролов вместо использования манифестов.
ЗЫ
Если найдешь способ устранения мигания более легким способом, сообщи пожалуйста. Я на это убил недели две, так что интерестно
Здравствуйте, Romul, Вы писали:
R>Два варианта: R>1. Либо ипсользуется double buffer, но способа заставить WinAPI выводить в DC отличный от экранного, я не знаю
Из MSDN:
This section describes the message processing performed by a tab control. Messages specific to tab controls are discussed in other sections of this documentation.
...
WM_PAINT Draws a border around the display area (unless the TCS_BUTTONS style is specified) and paints any tabs that intersect the invalid rectangle. For each tab, it draws the body of the tab (or sends a WM_DRAWITEM message to the parent window) and then draws a border around the tab. If the wParam parameter is non-NULL, the control assumes that the value is an HDC and paints using that device context.
...
Т.е. можно передать DC через WM_PAINT... но как бы я не старался это реализовать — у меня все равно ничего не вышло... может, Вы поможете?
R>2. Delphi по всей видимости не используют оконный класс TAB в чистом виде. Они могут вызывать функции Visual API напрямую для отрисовки отдельных элементов таб контрола. Соответственно, если они его рисуют сами, то могут сначала рисовать в memory DC. В инете (по-моему и на RSDN) есть статейки о том, как самостоятешьно отрисовывать элементы используя Visual API.
Перед тем, как обратиться за помощью на форум, я излазил RSDN...ничего не нашел по этой теме. Может быть, Вы можете дать прямой линк?
R>Второй вариант вероятнее всего, т.к. я где-то встречал упоминания о том, что Builder (а значит и Delphi) использует именно Visual Style API для отрисовки контролов вместо использования манифестов.
Здравствуйте, x84, Вы писали:
x84>Здравствуйте, Romul, Вы писали:
R>>Два варианта: R>>1. Либо ипсользуется double buffer, но способа заставить WinAPI выводить в DC отличный от экранного, я не знаю
x84>Из MSDN: x84>This section describes the message processing performed by a tab control. Messages specific to tab controls x84>are discussed in other sections of this documentation.
x84>Т.е. можно передать DC через WM_PAINT... но как бы я не старался это реализовать — у меня все равно ничего не x84>вышло... может, Вы поможете?
Вызывание WM_PAINT самостоятельно ни к чему не привидет. Его может вызывать только система. Однако быть может поможет хук на эту месагу??? Не знаю, возможно если ее перехватывать и подменять hDC, то что-то и получиться, но вот только, как узнавать, что отрисовка завершена и надо отблитить все на экран?
R>>2. Delphi по всей видимости не используют оконный класс TAB в чистом виде. Они могут вызывать функции Visual R>>API напрямую для отрисовки отдельных элементов таб контрола. Соответственно, если они его рисуют сами, то могуR>>т сначала рисовать в memory DC. В инете (по-моему и на RSDN) есть статейки о том, как самостоятешьно отрисовывR>>ать элементы используя Visual API.
x84>Перед тем, как обратиться за помощью на форум, я излазил RSDN...ничего не нашел по этой теме. Может быть, Вы x84>можете дать прямой линк?
R>>Второй вариант вероятнее всего, т.к. я где-то встречал упоминания о том, что Builder (а значит и Delphi) использует именно Visual Style API для отрисовки контролов вместо использования манифестов.
x84>А что такое Visual Style API ?
Это поддержка XP стилей, экспортируется через uxtheme.dll, присутствующую только в ХП+
x84>Здравствуйте, Andrew S, Вы писали:
AS>>Этот вопрос здесь уже был. Воспользуйтесь поиском, а также натравите Spy++ на Task Manager — все станет понятно.
x84>Пробовал найти поиском, нигде не нашел примеров реализации именно для таб-контрола. Все только слова... Кода нет...
День добрый.
Уфф... Вам же прямым текстом написали — попробуйте посмотреть на Task Manager в Spy++. Попробуйте — увидите, что диалоги вкладок в таск манагере на самом деле не являются дочерними окнами таб контрола. Understand? Ну же, немного самостоятельности, примеры кода нарочно приводить не буду
Здравствуйте, Andrew S, Вы писали:
x84>>Здравствуйте, Andrew S, Вы писали:
AS>Уфф... Вам же прямым текстом написали — попробуйте посмотреть на Task Manager в Spy++. Попробуйте — увидите, что диалоги вкладок в таск манагере на самом деле не являются дочерними окнами таб контрола. Understand?
Я не совсем понял, каким образом эта фраза должна была избавить меня от мигания таб контрола?? Ну не являются они дочерними окнами таб контрола.. и? Что я должен понять? Я ведь еще даже вкладок не создал... только таб контрол... пустой и тупой...
Hello, x84!
You wrote on Mon, 05 Jul 2004 08:54:48 GMT:
AS>> Уфф... Вам же прямым текстом написали — попробуйте посмотреть на Task AS>> Manager в Spy++. Попробуйте — увидите, что диалоги вкладок в таск AS>> манагере на самом деле не являются дочерними окнами таб контрола. AS>> Understand? x> Я не совсем понял, каким образом эта фраза должна была избавить меня от x> мигания таб контрола?? Ну не являются они дочерними окнами таб x> контрола.. и? Что я должен понять? Я ведь еще даже вкладок не создал... x> только таб контрол... пустой и тупой...
Ты его маленький делай — одни закладки. Остальное в нем не нужно.
With best regards, Sergey.
Posted via RSDN NNTP Server 1.9 beta
Одним из 33 полных кавалеров ордена "За заслуги перед Отечеством" является Геннадий Хазанов.
Здравствуйте, x84, Вы писали:
x84>Здравствуйте, Sergey, Вы писали:
S>>Ты его маленький делай — одни закладки. Остальное в нем не нужно.
x84>А причем тут его размер?
Имеется в виду — не создавать тела, а только по размеру заголовков (закладок). Соответвственно мигать будет меньше, т.к. перерисовать будет только заголовок