Похоже, что единственным обходным решением является владелец-ничья или сторонний кнопочный элемент управления Check out the Glass Button by Roy Klever или, как указано в записи QC, приведенной ниже, TBitBtn с DoubleBuffered = false, что было принятым ответом выше на этот вопрос.
Это ошибка в Windows Aero DWM, а также ошибка в общих элементах управления Windows или ошибка в том, как иерархия класса VCL обрабатывает общие сообщения окна управления и рисует при рисовании на стекле. Короче говоря, общие элементы управления Windows не рисуют правильно на стекле, или, скорее, DWM-композиция (Aero) нарушена. Сюрприз Сюрприз.
В стандартном компоненте кнопки VCL используется клавиша Window Class BUTTON из общих элементов управления Windows.
Обратите внимание, что TSpeedButton не использует общий элемент управления Windows и не имеет этой проблемы. однако он также не принимает фокус.
Похоже, что Embarcadero знает об этой проблеме, это QC# 75246, которая закрыта, потому что это действительно ошибка в общей библиотеке управления, так как Will not Fix, с предложением использовать TBitBtn. Кнопки не одни, это часть группы отчетов QC, включая панели и другие общие элементы управления.
Однако у меня есть коммерческий TcxButton (часть компонентов express express), который принимает фокус клавиатуры и не делает этого сбоя. Любой код, который использует общее управление кнопки управления Win32, похоже, имеет эту проблему. Возможно, что хакер низкого уровня Win32 API может найти обходное решение для этого. Я изучаю это. Этот ответ будет обновлен, если я это выясню.
Одна интересная деталь: TcxButton имеет три стиля рисования, cxButton.LookAndFeel.Kind = {lfOffice11, lfFlat, lfStandard}. Выбор lfOffice11 снова добавляет этот сбой. Это похоже на странное взаимодействие между стеклянным элементом в aero в Vista/Win7 и общим кодом рисования кнопки управления/xptheme.
Возможно, единственным обходным решением является использование кнопки управления кнопками с полным приложением и не использование обычных кнопок управления Windows или любого кнопочного элемента управления, который опирается на движок темы XP для рисования кнопок, на панели аэрообъектива ,
Редактировать: 28 июля кто-то в Embarcadero закрыл вышеуказанную запись QC, что было ошибкой. Я настоятельно призываю их снова открыть его, если только уточнить, действительно ли это ошибка Windows в общей DLL-модулях управления.
Если вы хотите поиграть, сделайте копию исходного кода VCL для классов TButton и TCustomButton из StdCtrls, как я здесь сделал, измените CNCtlColorBtn, чтобы вы запустили одну из трех вещей - PerformEraseBackground, DrawParentBackground или унаследован, и посмотрите результаты. Интересный материал.
procedure TCustomGlassButton.CNCtlColorBtn(var Message: TWMCtlColorBtn);
begin
PerformEraseBackground(Self, Message.ChildDC);
Message.Result := GetStockObject(NULL_BRUSH);
(*
with ThemeServices do
if ThemesEnabled then
begin
if (Parent <> nil) and Parent.DoubleBuffered then
PerformEraseBackground(Self, Message.ChildDC)
else
DrawParentBackground(Handle, Message.ChildDC, nil, False);
{ Return an empty brush to prevent Windows from overpainting we just have created. }
Message.Result := GetStockObject(NULL_BRUSH);
end
else
inherited;
*)
end;
Some interesting reading on Vista era glass/DWM/aero APIs (C++ developers blog)
У вас есть источники для минимального применения, показывающие это поведение? (.dfm и .pas простой формы) –
@Jeroen: Я могу воспроизвести это поведение с помощью простой формы, содержащей TButton и устанавливающий стеклянный каркас, чтобы кнопка была на стекле. Я просто не могу подключиться к QC в данный момент, поэтому я не могу узнать, есть ли подобная ошибка, уже поданная. –
Интересное поведение - когда button.doublebuffered - true, но форма doublebuffered - false, я получаю один цвет (черный) вокруг кнопки, и когда оба значения true, я получаю другой цвет (как указано выше, серый или clBtnFace), и когда кнопка не имеет двойной буферизации, текст выглядит серым. Таким образом, невозможно использовать кнопку на стекле в delphi 2010, если она не выглядит как дерьмо? –