Форум программистов
 

Восстановите пароль или Зарегистрируйтесь на форуме, о проблемах и с заказом рекламы пишите сюда - alarforum@yandex.ru, проверяйте папку спам!

Вернуться   Форум программистов > Низкоуровневое программирование > Win Api
Регистрация

Восстановить пароль
Повторная активизация e-mail

Купить рекламу на форуме - 42 тыс руб за месяц

Ответ
 
Опции темы Поиск в этой теме
Старый 24.12.2016, 13:40   #1
BLACK_RAIN
Форумчанин
 
Регистрация: 13.02.2012
Сообщений: 867
По умолчанию при ресайзе окна мерцают кнопки

Здравствуйте.
Созадаю GUI. По задумке, под каждым контролом есть свой статик, который сабклассируется и получает уведомления от контрола на нем.
например, кнопка с иконкой создается вот так:
Код:

  fStyle := WS_CHILD or WS_VISIBLE;
  fControlWindowHandle := CreateWindow('static','', fStyle or WS_CLIPCHILDREN,
                    fLeft, fTop, fWidth,fHeight, aOwnerWnd, 0, HInstance, nil);
      fHandle := CreateWindow('Button','', fStyle or BS_OWNERDRAW,
                    0, 0, fWidth,fHeight, fControlWindowHandle, 0, HInstance, nil);
  fOldControlProc := SetWindowLong(fControlWindowHandle, GWL_WNDPROC, LongInt(@ControlWndProc));
{......
..........
Загрузка иконки и т.п.
............
.........}

function ControlWndProc(wnd: HWND; msg: Cardinal; WPar: WPARAM; LPar: LPARAM): LRESULT; stdcall;
var
  dis : PDrawItemStruct;
begin
  case msg of

    WM_DRAWITEM:
    begin
      if Assigned(OnDrawButton) then
      begin
        dis := pdrawitemstruct(LPar);
        OnDrawButton(Self, dis); // Выполняется RedrawButton
      end;

    end;

  else
    begin
      Result := CallWindowProc(Pointer(fOldControlProc), wnd, msg, WPar, LPar);
    end;
  end;
end;

procedure TWinApiIconButton.RedrawButton;
begin
  GetDC;  //получает DC
  Winapi.Windows.FillRect(DC,ClientRect, Brush.fHandle);
  if (fIcon<>nil) and (fIcon.Handle>0) then
  begin
    DrawIconEx(DC,0,0, fIcon.fHandle, Width,Height, 0, 0, DI_NORMAL);
  end;
  ReleaseDC; // отпускает DC
end;
У меня контролы WinAPI завёрнуты в классы, что несколько запутывает код. Да и вообще многие скажут, что это сомнительное решение.
Но если писать как положено - без обёртывания в классы, то кнопки всё-равно мерцают при ресайзе.
Чем больше в окне кнопок, тем сильнее мерцание.
Предполагаю, что это из-за контрольных статиков под каждой кнопкой, но без них ничего не будет работать, как задумано.
Мерцают только контролы с классом "button". Есть и ListBox'ы и ListView - они при ресайзе окна почти не мерцают.
Почему же сильно мерцают кнопки? Даже если создать кнопку без стиля BS_OWNERDRAW она всё-равно мерцает.
Видео прилагается: https://youtu.be/mXrkQx569Nw

Последний раз редактировалось BLACK_RAIN; 24.12.2016 в 13:46.
BLACK_RAIN вне форума Ответить с цитированием
Старый 24.12.2016, 16:01   #2
waleri
Старожил
 
Регистрация: 13.07.2012
Сообщений: 6,493
По умолчанию

WS_CLIPCHILDREN в родительском окне (aOwnerWnd).
В своих статиках надо осторожней с WM_ERASEBKGND.
waleri вне форума Ответить с цитированием
Старый 24.12.2016, 16:29   #3
BLACK_RAIN
Форумчанин
 
Регистрация: 13.02.2012
Сообщений: 867
По умолчанию

Цитата:
Сообщение от waleri Посмотреть сообщение
WS_CLIPCHILDREN в родительском окне (aOwnerWnd).
есть он там
Цитата:
Сообщение от waleri Посмотреть сообщение
В своих статиках надо осторожней с WM_ERASEBKGND.
в каком смысле?
BLACK_RAIN вне форума Ответить с цитированием
Старый 24.12.2016, 16:57   #4
waleri
Старожил
 
Регистрация: 13.07.2012
Сообщений: 6,493
По умолчанию

В прямом.
Erase сначала стирает все, потом поверх этого рисуем. В итоге имеем мерцание.
waleri вне форума Ответить с цитированием
Старый 25.12.2016, 08:30   #5
BLACK_RAIN
Форумчанин
 
Регистрация: 13.02.2012
Сообщений: 867
По умолчанию

то есть, в оконной процедуре статика надо принять сообщение WM_ERASEBKG и вернуть 0?
BLACK_RAIN вне форума Ответить с цитированием
Старый 26.12.2016, 08:24   #6
BLACK_RAIN
Форумчанин
 
Регистрация: 13.02.2012
Сообщений: 867
По умолчанию

Погуглил вчера WM_ERASEBKND.
Только складывается впечатление, что это действует только на главное окно, а не на дочерние. Какой бы результат я ни возвращал - 0 или 1 - статики всё-равно мерцают при таскании за зеленый статик (см. видео).
А если принимать WM_ERASEBKND в главном окне или убрать стили CS_HREDRAW CS_VREDRAW, то статики почти совсем перестают мерцать при ресайзе главного окна. Однако, иногда, всё-равно слегка подмерцивают.
BLACK_RAIN вне форума Ответить с цитированием
Старый 26.12.2016, 10:24   #7
waleri
Старожил
 
Регистрация: 13.07.2012
Сообщений: 6,493
По умолчанию

А у вас точно выставлен WS_CLIPCHILDREN в главном окне?
waleri вне форума Ответить с цитированием
Старый 26.12.2016, 10:28   #8
BLACK_RAIN
Форумчанин
 
Регистрация: 13.02.2012
Сообщений: 867
По умолчанию

Цитата:
Сообщение от waleri Посмотреть сообщение
А у вас точно выставлен WS_CLIPCHILDREN в главном окне?
в главном окне программы - да.
в статиках тоже нужен? Пробовал и с ним и без него.
BLACK_RAIN вне форума Ответить с цитированием
Ответ


Купить рекламу на форуме - 42 тыс руб за месяц

Опции темы Поиск в этой теме
Поиск в этой теме:

Расширенный поиск


Похожие темы
Тема Автор Раздел Ответов Последнее сообщение
Изменение размера картинки при ресайзе формы JoLan Компоненты Delphi 2 31.07.2012 15:07
Создание всплывающего окна при нажатии кнопки MihOla Microsoft Office Access 0 11.11.2011 13:03
Мерцают участки на TFT мониторе SunnyVic Компьютерное железо 0 04.11.2010 19:38
глюки OnSelectCell при ресайзе грида в нем joker Компоненты Delphi 2 10.12.2009 12:09
Кнопки окна предупреждения mephist Microsoft Office Excel 2 21.07.2009 18:35