Ваш первый код для установки полей верен.
Однако все становится сложно, из-за того, как работает VCL, базовое окно, созданное для данного элемента управления VCL, может быть воссоздано в ответ на изменения, внесенные в VCL.свойства во время выполнения (некоторые изменения свойств могут быть применены только на уровне Windows API путем удаления и повторного создания окна).Хотя порядок сообщений (обычно) не меняется в разных версиях Windows, могут быть введены дополнительные сообщения, некоторые из которых могут изменить порядок, в котором код VCL, обернутый вокруг этих окон, может срабатывать или мешать поведению этого кода.
Возможно также, что в базовых окнах Windows API было введено поведение, которое VCL не обслуживает (опять же, скорее всего, это происходит при смешивании низкоуровневых вызовов API, как в этом случае).
Это особенно актуально при смешивании поведения VCL с низкоуровневыми прямыми вызовами API - как в этом случае.
Существуют и другие вещи, которые могут мешать определенным настройкам после применения, что требует от вассамостоятельно уничтожьте и заново создайте окно и повторно примените свои собственные настройки.
Я видел другие сообщения о проблемах в этой области с тем же кодом (не Delphi) в разных версиях XP - похоже, чтоизменение, внесенное в SP2, которое оказало некоторое влияние наего область.
В случае EM_SETMARGINS У меня была та же проблема, что и вы, и я исправил ее, посмотрев, как элемент управления TButtonEdit сумел применить требуемые поля.(который работал, по крайней мере, на моей установке Windows 7.)
Возможно, мне стало легче благодаря тому, что я реализовал собственный элемент управления вместо того, чтобы пытаться применить поля к некоторому существующему редактированиюконтроль.В приведенных ниже фрагментах кода TCustomPickEdit - это мой пользовательский класс управления, который включает в себя объект fButton , который содержит все настройки, относящиеся к кнопке выбора.Вам нужно будет внести соответствующие коррективы, чтобы применить этот код в вашей конкретной ситуации.
То, что я обнаружил, было следующим:
Поля необходимо было применить как минимум в 3 местах.Во-первых, всякий раз, когда параметры, которые могут повлиять на поля, были изменены, во-вторых, всякий раз, когда создавался дескриптор окна элемента управления для редактирования, и, наконец, всякий раз, когда изменяется шрифт в элементе управления для редактирования:
Даже с полямиПравильно установленный прямоугольник отсечения элемента управления необходимо отрегулировать для обеспечения правильного рисования.Это потребовало переопределить WndProc элемента управления редактированием и перехватить пару сообщений.Этот WndProc также необходим для ответа на уведомление об изменении шрифта для повторного применения полей в случае изменения шрифта элемента управления редактирования.
Код для работы с каждымиз них в моем случае показано ниже:
procedure TCustomPickEdit.ConfigureButton;
// 1. Apply margins when button settings are changed
begin
fButton.Caption := Button.Caption;
fButton.Flat := Button.Flat;
fButton.Glyph := Button.Glyph;
fButton.NumGlyphs := Button.NumGlyphs;
fButton.Visible := Button.Visible;
ApplyMargins;
end;
procedure TCustomPickEdit.CreateHandle;
// 2. Apply margins when underlying window handle is created
begin
inherited;
ApplyMargins;
end;
procedure TCustomPickEdit.WndProc(var aMessage: TMessage);
// 3. Adjust clipping rectangle for correct drawing
// 4. Apply margins when font is changed
var
top: Integer;
begin
case aMessage.Msg of
CN_CTLCOLORSTATIC,
CN_CTLCOLOREDIT : if Button.Visible then
begin
top := fButton.Top;
if ThemeServices.ThemesEnabled and Ctl3D then
Inc(top);
ExcludeClipRect(aMessage.WParam, fButton.Left,
top + 1,
fButton.Left + fButton.Width,
fButton.Height);
end;
end;
inherited;
case aMessage.Msg of
CM_FONTCHANGED : if NOT (csLoading in ComponentState) then
ApplyMargins;
end;
end;