Форум: "Основная";
Текущий архив: 2012.01.15;
Скачать: [xml.tar.bz2];
ВнизTButton, Windows Vista/7, интересное поведение Найти похожие ветки
← →
gosha52 (2010-07-16 13:05) [0]Всем привет.
Ребята, особенно продвинутые в паскале, вы не обращали внимание, что кнопки созданные в дельфи с манифестом поддержки тем, ведут себя не совсем так, как ведут себя стандартные кнопки в Windows Vista/7 ? Я имею в виду плавные эффекты затухания когда фокус находится на кнопке и когда просто проводишь над кнопкой курсором мышки. Пробовал все версии дельфи, ничего не помогает, везде отсутствуют эти эффекты, вот и непонимаю почему. Версия контролов в манифесте вроде как 6.0 и это последняя на сегодня версия. Вообщем странно и хочется всё-таки понять по какой причине происходит такое досадное недоразумение. В инете покапал, что-то ничего не нашел. Главное в окнах стандартных диалогов эти эффекты присутствуют, т.к. создает их сама windows. Может кто-то сталкивался и нашел способ?
← →
Deltas © (2010-07-16 13:34) [1]Попробуй создать окно и кнопку в нем на чистом Win API (CreateWindowEx()). Возможно, в последних версиях Windows были добавлены новые стили окон и расширенные стили окон. Я тоже заинтересован в этом вопросе.
← →
gosha52 (2010-07-16 13:39) [2]Это метод от противного конечно хорош, но не хочется проходить все стадии поиска, если кто-то уже до тебя нашел и может поделится информацией.
← →
gosha52 (2010-07-16 15:58) [3]Для потомков:
Это проблема VCL, винда естественно и знать не знает о таком классе как TButton, который подсовывается в ClassName при создании контрола. Если вместо ClassName подсовывать BUTTON, то все будет работать как положено, но для этого нужно писать свой компонент, или использовать чистый win api.
← →
Deltas © (2010-07-16 17:27) [4]
> gosha52 (16.07.10 15:58) [3]
Не все так просто.procedure TButton.CreateParams(var Params: TCreateParams);
const
ButtonStyles: array[Boolean] of DWORD = (BS_PUSHBUTTON, BS_DEFPUSHBUTTON);
begin
inherited CreateParams(Params);
CreateSubClass(Params, "BUTTON");
Params.Style := Params.Style or ButtonStyles[FDefault];
end;
Класс окна TButton является подклассом BUTTON. И обработчик сообщений по умолчанию (DefWindowProc()) для окон класса TButton точно такой же как и у окон класса BUTTON.
И, если, окно класса BUTTON работает под Windows Vista (Windows 7) с плавными графическими эффектами, то ты прав - это проблема VCL. Но, для обхода проблемы не обязательно писать на чистом Win API, нужно покопаться в исходниках VCL и найти что именно приводит к некорректной работе кнопки.
← →
gosha52 (2010-07-17 11:10) [5]Deltas,
Может я что-то недогоняю, но а что такое подкласс? CreateSubClass лишь получает информацию о классе и копирует все параметры в Params для регистрации своего класса, разве нет? Главное то, что в CreateWindowEx в конечном итоге передается TButton, а не BUTTON. Я думаю дело именно в том, что создается окно с другим именем класса, после чего винда перестает применять все эти эффекты к таким контролам.
← →
gosha52 (2010-07-17 11:58) [6]Я проверил свою последнюю гипотезу и оказался не прав. Все эффекты присутствуют после создания кнопки с другим именем класса:
procedure TForm1.Button1Click(Sender: TObject);
var Params: TCreateParams;
begin
if GetClassInfo(HInstance, "BUTTON", Params.WindowClass) then
begin
Params.WindowClass.lpszClassName := "TRealButton";
if (Windows.RegisterClass(Params.WindowClass) > 0) then
CreateWindowEx (0, "TRealButton", "Real Button", WS_CHILD or WS_VISIBLE or BS_PUSHBUTTON, 30, 30, 100, 50, Handle, 100, HInstance, nil);
end;
end;
Видать мое первое предположение с проблемой в глубине VCL всё-таки наиболее верно. Попробую покапать TWinControl.
← →
Deltas © (2010-07-17 12:06) [7]http://msdn.microsoft.com/en-us/library/ms633569(VS.85).aspx
Особое внимание в статье рекомендую обратить на
- window procedure subclassing
- window procedure superclassing
На самом деле, класс окна TButton является суперклассом класса окна BUTTON (следуя терминологии MSDN). TButton отличается от BUTTON только названием класса и оконной процедурой (это видно из TButton.CreateWnd() в исходных текстах VCL). Насколько я понимаю, класс окна TButton является суперклассом BUTTON только потому что оконная процедура TButton вызывает для обработки сообщений по умолчанию оконную процедуру класса BUTTON (ее адрес сохраняется в поле FDefWndProc).
Вот еще одна статья на русском:
http://forum.vingrad.ru/forum/topic-69246.html
Но MSDN я всегда доверяю больше.
← →
gosha52 (2010-07-17 12:20) [8]
> Насколько я понимаю, класс окна TButton является суперклассом
> BUTTON только потому что оконная процедура TButton вызывает
> для обработки сообщений по умолчанию оконную процедуру класса
> BUTTON (ее адрес сохраняется в поле FDefWndProc).
Да, именно так и есть, иначе бы не рисовалась кнопка или любой другой "наследуемый" контрол.
В общем проблема найдена, она зарыта в DoubleBuffered, который у меня True для формы, а значит и для всех контролов на этой форме по умолчанию. Интресно, что TEdit при этом работает достаточно сносно с эффектами затухания своих границ.
← →
Deltas © (2010-07-17 12:27) [9]
> gosha52 (17.07.10 12:20) [8]
> В общем проблема найдена, она зарыта в DoubleBuffered, который
> у меня True для формы, а значит и для всех контролов на
> этой форме по умолчанию.
А поподробнее? Для решения проблемы нужно DoubleBuffered для кнопки установить False?
← →
gosha52 (2010-07-17 12:29) [10]
> А поподробнее? Для решения проблемы нужно DoubleBuffered
> для кнопки установить False?
Да, для кнопки, для комбобокса и любых других контролов, на которых не отображаются соответствующие эффекты.
← →
gosha52 (2010-07-17 12:31) [11]За исключением конечно всяких TBitBtn, TSpeedButton, где все рисуется внутри vcl.
← →
Deltas © (2010-07-17 12:50) [12]
> gosha52 (17.07.10 12:29) [10]
Согласен. Судя по исходным текстам VCL DoubleBuffered, установленный равным False, приводит к обработке сообщений WM_ERASEBKGND, WM_PAINT по умолчанию.
> gosha52 (17.07.10 12:31) [11]
У TSpeedButton нет свойства DoubleBuffered, т.к. он не является потомком TWinControl. А вот TBitBtn является прямым потомком TButton и свойство DoubleBuffered у него все же есть.
← →
Deltas © (2010-07-17 13:00) [13]Кстати, в Delphi 5 и в Delphi 7, свойство DoubleBuffered описано как public (не published) и по умолчанию всегда установлено False.
← →
KilkennyCat © (2010-07-17 20:26) [14]любопытно так же делфи 4, 3, 2, 1, 0 и т.д.
← →
gosha52 (2010-07-18 18:32) [15]
> А вот TBitBtn является прямым потомком TButton и свойство
> DoubleBuffered у него все же есть.
Но это ему не поможет, т.к. кнопка рисуется внутри Buttons.pas.
← →
0x00FF00 (2010-07-18 22:19) [16]
> любопытно так же делфи 4, 3, 2, 1, 0 и т.д.
Куда, в минус что ли?
Delphi (-1).0 %)
← →
KilkennyCat © (2010-07-18 22:57) [17]
> 0x00FF00 (18.07.10 22:19) [16]
ну, всякие там турбопаскали с турбовиженом... у них тож явно проблемы будут.
Страницы: 1 вся ветка
Форум: "Основная";
Текущий архив: 2012.01.15;
Скачать: [xml.tar.bz2];
Память: 0.49 MB
Время: 0.003 c