Windows API Tab Control flickering
От: x84 Россия  
Дата: 01.07.04 21:59
Оценка:
Приветствую всех!
Столкнулся тут с одной проблемой. Используем только чистый Windows API без всяких WTL и MFC. Создаем таб-контрол в родительском окне, все ок... Двигаем окно — все ок. Рисуется как надо. Ресайзим окно — получаем так называемый "flickering"- мигание таб-контрола при перерисовке. Причем только при ресайзинге родительского окна. Как ни старался исправить это — нифига не получается... Особенно сильно мигание заметно, если используется неклассическая тема для окон (windows themes). Например, в XP Theme отчетливо видно мигание. Знаю, что для решения подобных проблем с миганием используют двойную буферизацию — вывод в offscreen-поверхность и потом BitBlt... Но опять же, нифига не выходит.
Вопрос, собственно, следующий: кто-нть может показать код, как на Windows API сделать таб контрол, который бы не мигал при ресайзе окна. Причем задача такова, чтобы таб контрол был "приклеен" внутри к правой границе родительского окна и сдвигался-раздвигался и уменьшал-увеличивал свой размер при ресайзе родительского окна.
Re: Windows API Tab Control flickering
От: Slava Antonov Россия http://deadbeef.narod.ru
Дата: 01.07.04 23:36
Оценка:
Hello x84, you wrote:

> Двигаем окно — все ок. Рисуется как надо. Ресайзим окно — получаем так

> называемый "flickering"

Здесь есть
как бороться с мерцанием при ресайзинге. См. "Еще одна причина мерцания",
и "Clipping child windows".

--
Всего хорошего, Слава
http://slava.users.otts.ru
Posted via RSDN NNTP Server 1.9 beta
Re[2]: Windows API Tab Control flickering
От: x84 Россия  
Дата: 01.07.04 23:49
Оценка:
Здравствуйте, Slava Antonov, Вы писали:

SA>Hello x84, you wrote:


>> Двигаем окно — все ок. Рисуется как надо. Ресайзим окно — получаем так

>> называемый "flickering"

SA>Здесь есть

SA>как бороться с мерцанием при ресайзинге. См. "Еще одна причина мерцания",
SA>и "Clipping child windows".

SA>--

SA>Всего хорошего, Слава
SA>http://slava.users.otts.ru

Да я все это читал уже. Вот вы мне попробуйте дать код, который бы создавал простое окошко с табом, прилепленным к правой внутренней границе родительского окна. Таб должен иметь константную ширину (изначально он занимаетне все окно)... По горизонтали размер таба не меняется...Размер таба меняется по вертикали, чтобы соответствовать размерам родительского окна при ресайзинге... такжетаб должен сдвигаться влево-вправо при соответствующем ресайзинге... и самое главное — НЕ МИГАТЬ. Казалось бы, задача тривиальная на первый взгляд, однако, я не видел еще реализации... И у меня у самого покаеще не получилось реализовать... Эдакий таб-контрол на подобие боковой панельки...
Re[3]: Windows API Tab Control flickering
От: Slava Antonov Россия http://deadbeef.narod.ru
Дата: 02.07.04 10:27
Оценка:
Hello x84, you wrote:

> Да я все это читал уже. Вот вы мне попробуйте дать код, который бы

> создавал простое окошко с табом

Давайте лучше вы приведете ваш код. А мы посмотрим, что там не так.

--
Всего хорошего, Слава
http://slava.users.otts.ru
Posted via RSDN NNTP Server 1.9 beta
Re: Windows API Tab Control flickering
От: Andrew S Россия http://alchemy-lab.com
Дата: 02.07.04 13:41
Оценка:
x84>Вопрос, собственно, следующий: кто-нть может показать код, как на Windows API сделать таб контрол, который бы не мигал при ресайзе окна. Причем задача такова, чтобы таб контрол был "приклеен" внутри к правой границе родительского окна и сдвигался-раздвигался и уменьшал-увеличивал свой размер при ресайзе родительского окна.

Этот вопрос здесь уже был. Воспользуйтесь поиском, а также натравите Spy++ на Task Manager — все станет понятно.
http://www.rusyaz.ru/pr — стараемся писАть по-русски
Re[4]: Windows API Tab Control flickering
От: x84 Россия  
Дата: 02.07.04 15:17
Оценка:
SA>Давайте лучше вы приведете ваш код. А мы посмотрим, что там не так.



#pragma comment (lib, "comctl32.lib")

#include <windows.h>
#include <windowsx.h>
#include <commctrl.h>

HWND tab;

LRESULT CALLBACK WndProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam)
{
  switch(msg)
  {
  case WM_CLOSE:
    DestroyWindow(hwnd);
    break;
  case WM_SIZE:
    SetWindowPos(tab, HWND_TOP, 
      GET_X_LPARAM(lParam) - 420, 20, 400, GET_Y_LPARAM(lParam) - 40, 
      SWP_NOZORDER);
    break;
  case WM_DESTROY:
    PostQuitMessage(0);
    break;
  default:
    return DefWindowProc(hwnd, msg, wParam, lParam);
  }
  return 0;
}

int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, 
    LPSTR lpCmdLine, int nCmdShow)
{
  InitCommonControls();

  WNDCLASSEX wc;
  HWND hwnd;
  MSG Msg;

  wc.cbSize        = sizeof(WNDCLASSEX);
  wc.style         = CS_HREDRAW | CS_VREDRAW;
  wc.lpfnWndProc   = WndProc;
  wc.cbClsExtra    = 0;
  wc.cbWndExtra    = 0;
  wc.hInstance     = hInstance;
  wc.hIcon         = LoadIcon(NULL, IDI_APPLICATION);
  wc.hCursor       = LoadCursor(NULL, IDC_ARROW);
  wc.hbrBackground = (HBRUSH)GetStockObject(BLACK_BRUSH);
  wc.lpszMenuName  = NULL;
  wc.lpszClassName = "Sample Window";
  wc.hIconSm       = LoadIcon(NULL, IDI_APPLICATION);

  if(!RegisterClassEx(&wc))
  {
    MessageBox(NULL, "Window Registration Failed!", "Error!",
      MB_ICONEXCLAMATION | MB_OK);
    return 0;
  }

  hwnd = CreateWindowEx(
    0,
    "Sample Window",
    "The title of my window",
    WS_OVERLAPPEDWINDOW | WS_CLIPCHILDREN,
    CW_USEDEFAULT, CW_USEDEFAULT, 800, 600,
    NULL, NULL, hInstance, NULL);

  if(hwnd == NULL)
  {
    MessageBox(NULL, "Window Creation Failed!", "Error!",
      MB_ICONEXCLAMATION | MB_OK);
    return 0;
  }

  RECT rect; 
  GetClientRect(hwnd, &rect); 

  tab = CreateWindow(WC_TABCONTROL, "", WS_CHILD | WS_CLIPSIBLINGS | WS_VISIBLE, 
    rect.right - 420, 20, 400, rect.bottom - 40, hwnd, NULL, hInstance, NULL); 
  if (tab == NULL) 
    MessageBox(NULL, "Could not create tab control", "Error!", 
    MB_ICONEXCLAMATION | MB_OK);

  ShowWindow(hwnd, nCmdShow);
  UpdateWindow(hwnd);

  while(GetMessage(&Msg, NULL, 0, 0) > 0)
  {
    TranslateMessage(&Msg);
    DispatchMessage(&Msg);
  }

  return 0;
}


Я не стал приводить все примеры всех вариантов, которые пробовал.Их было много... пробовал субклассинг, пробовал отлавливать мессаджи и рисовать в офскрин-буфер и т.п... Ничего не помогло... Поэтому я вот взял обычное окно с таб-контролом (мигание заметно только при ресайзинге, если присмотреться к краям таб-контрола). Как изменить этот код, чтобы сохранить ту же функциональность и чтобы таб перестал мигать?
Re[2]: Windows API Tab Control flickering
От: x84 Россия  
Дата: 02.07.04 15:18
Оценка:
Здравствуйте, Andrew S, Вы писали:

AS>Этот вопрос здесь уже был. Воспользуйтесь поиском, а также натравите Spy++ на Task Manager — все станет понятно.


Пробовал найти поиском, нигде не нашел примеров реализации именно для таб-контрола. Все только слова... Кода нет...
Re: Windows API Tab Control flickering
От: x84 Россия  
Дата: 03.07.04 01:19
Оценка:
Неужели никто не может помочь? Буду очень благодарен.
Re[5]: Windows API Tab Control flickering
От: Slava Antonov Россия http://deadbeef.narod.ru
Дата: 03.07.04 05:52
Оценка:
Hello x84, you wrote:

>> Давайте лучше вы приведете ваш код. А мы посмотрим, что там не так.

> Как изменить этот код, чтобысохранить ту же функциональность и чтобы таб
> перестал мигать?

Хммм... похоже на то, что это беда самого Tab-Control.

--
Всего хорошего, Слава
http://slava.users.otts.ru
Posted via RSDN NNTP Server 1.9 beta
Re[2]: Windows API Tab Control flickering
От: Romul Россия  
Дата: 03.07.04 14:09
Оценка:
Здравствуйте, x84, Вы писали:

x84>Неужели никто не может помочь? Буду очень благодарен


Привет.

Я наверное разочарую, но похоже способа совсем избавиться от мигания нет. Я несколько месяцев назад пытался решить эту проблему, но до конца так это сделать и не удалось.

Наболее неплохие результаты я получил, когда делал следующим образом:
1. Использовал регионы, т.е. когда происходил ресайз, я определял новые появившиеся области и ставил на них регион, соответственно Винда рисовала только в этих областях (если размер окна увеличивался)
Но должен сказать, что данный метод очень геморойный и было много багов, связанных с тем, что надо отлавливать дополнительные условия перерисовки (например над контролом проезжает окно, значит нам надо установить регион на весь контрол и перерисовать его), плюс учитывать child окна. К тому же закладки должны всегда находиться в регионе отрисовки (иначе они глючат).

2. Положил на весь размер контрола child диалог и установил для контрола флажок clip_children. Соответственно диалог не мигал, однако проблему закладок это не решило.


Закладки мигают всегда
Re[6]: Windows API Tab Control flickering
От: x84 Россия  
Дата: 03.07.04 19:34
Оценка:
SA>Хммм... похоже на то, что это беда самого Tab-Control.

Да не похоже, что это беда самого контрола...
Вот пример, который мне прислал знакомый прогер на дельфе. Очевидно, что оно не мигает. Как достичь того же на C в MSVC?
Пример
Re[3]: Windows API Tab Control flickering
От: x84 Россия  
Дата: 03.07.04 19:36
Оценка:
Здравствуйте, Romul, Вы писали:

R>Я наверное разочарую, но похоже способа совсем избавиться от мигания нет. Я несколько месяцев назад пытался решить эту проблему, но до конца так это сделать и не удалось.


Да есть способ, я просто уверен в этом... Вот пример, который мне прислал знакомый прогер на дельфе. Очевидно, что оно не мигает. Как достичь того же на C в MSVC? Ведь все равно так или иначе испльзуется WinAPI независимо от языка...
Пример
Re[4]: Windows API Tab Control flickering
От: Romul Россия  
Дата: 04.07.04 09:06
Оценка:
Здравствуйте, 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 для отрисовки контролов вместо использования манифестов.

ЗЫ
Если найдешь способ устранения мигания более легким способом, сообщи пожалуйста. Я на это убил недели две, так что интерестно
Re[5]: Windows API Tab Control flickering
От: x84 Россия  
Дата: 04.07.04 10:13
Оценка:
Здравствуйте, 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 для отрисовки контролов вместо использования манифестов.


А что такое Visual Style API ?
Re[6]: Windows API Tab Control flickering
От: Romul Россия  
Дата: 04.07.04 10:40
Оценка:
Здравствуйте, 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, присутствующую только в ХП+

Вот линка на статью по Visual Style API
http://rsdn.ru/article/winshell/themes.xml
Автор(ы): Акжан Абдулин
Дата: 04.12.2001


Если есть свежий MSDN, то в поиске можно поискать DrawThemeText и перейти на соответствующий раздел
Re[3]: Windows API Tab Control flickering
От: Andrew S Россия http://alchemy-lab.com
Дата: 05.07.04 07:18
Оценка:
x84>Здравствуйте, Andrew S, Вы писали:

AS>>Этот вопрос здесь уже был. Воспользуйтесь поиском, а также натравите Spy++ на Task Manager — все станет понятно.


x84>Пробовал найти поиском, нигде не нашел примеров реализации именно для таб-контрола. Все только слова... Кода нет...


День добрый.
Уфф... Вам же прямым текстом написали — попробуйте посмотреть на Task Manager в Spy++. Попробуйте — увидите, что диалоги вкладок в таск манагере на самом деле не являются дочерними окнами таб контрола. Understand? Ну же, немного самостоятельности, примеры кода нарочно приводить не буду
http://www.rusyaz.ru/pr — стараемся писАть по-русски
Re[4]: Windows API Tab Control flickering
От: x84 Россия  
Дата: 05.07.04 08:54
Оценка:
Здравствуйте, Andrew S, Вы писали:

x84>>Здравствуйте, Andrew S, Вы писали:


AS>Уфф... Вам же прямым текстом написали — попробуйте посмотреть на Task Manager в Spy++. Попробуйте — увидите, что диалоги вкладок в таск манагере на самом деле не являются дочерними окнами таб контрола. Understand?

Я не совсем понял, каким образом эта фраза должна была избавить меня от мигания таб контрола?? Ну не являются они дочерними окнами таб контрола.. и? Что я должен понять? Я ведь еще даже вкладок не создал... только таб контрол... пустой и тупой...
Re[5]: Windows API Tab Control flickering
От: Sergey Россия  
Дата: 05.07.04 09:06
Оценка:
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 полных кавалеров ордена "За заслуги перед Отечеством" является Геннадий Хазанов.
Re[6]: Windows API Tab Control flickering
От: x84 Россия  
Дата: 05.07.04 09:07
Оценка:
Здравствуйте, Sergey, Вы писали:

S>Ты его маленький делай — одни закладки. Остальное в нем не нужно.


А причем тут его размер?
Re[7]: Windows API Tab Control flickering
От: Romul Россия  
Дата: 05.07.04 09:14
Оценка:
Здравствуйте, x84, Вы писали:

x84>Здравствуйте, Sergey, Вы писали:


S>>Ты его маленький делай — одни закладки. Остальное в нем не нужно.


x84>А причем тут его размер?


Имеется в виду — не создавать тела, а только по размеру заголовков (закладок). Соответвственно мигать будет меньше, т.к. перерисовать будет только заголовок
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.