Главная страница
    Top.Mail.Ru    Яндекс.Метрика
Форум: "Основная";
Текущий архив: 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.004 c
2-1317796120
Laguna
2011-10-05 10:28
2012.01.15
Обработка ошибок в открывающейся форме


1-1279226968
Deltas
2010-07-16 00:49
2012.01.15
Значки кнопок стандартных диалоговых окон


15-1317372179
oxffff
2011-09-30 12:42
2012.01.15
Вопрос по MDX запросам


4-1253534102
__Алексей__
2009-09-21 15:55
2012.01.15
Доступ из службы к сетевому компбютеру


2-1317911115
vegarulez
2011-10-06 18:25
2012.01.15
Звук при нажатии Enter





Afrikaans Albanian Arabic Armenian Azerbaijani Basque Belarusian Bulgarian Catalan Chinese (Simplified) Chinese (Traditional) Croatian Czech Danish Dutch English Estonian Filipino Finnish French
Galician Georgian German Greek Haitian Creole Hebrew Hindi Hungarian Icelandic Indonesian Irish Italian Japanese Korean Latvian Lithuanian Macedonian Malay Maltese Norwegian
Persian Polish Portuguese Romanian Russian Serbian Slovak Slovenian Spanish Swahili Swedish Thai Turkish Ukrainian Urdu Vietnamese Welsh Yiddish Bengali Bosnian
Cebuano Esperanto Gujarati Hausa Hmong Igbo Javanese Kannada Khmer Lao Latin Maori Marathi Mongolian Nepali Punjabi Somali Tamil Telugu Yoruba
Zulu
Английский Французский Немецкий Итальянский Португальский Русский Испанский