С Новым годом! Форум программистов, компьютерный форум, киберфорум
Delphi для начинающих
Войти
Регистрация
Восстановить пароль
Блоги Сообщество Поиск Заказать работу  
 
Рейтинг 4.75/4: Рейтинг темы: голосов - 4, средняя оценка - 4.75
0 / 0 / 0
Регистрация: 18.06.2020
Сообщений: 23

Прошу помощи в отрисовке потомка TEdit

02.12.2024, 12:25. Показов 1041. Ответов 17
Метки нет (Все метки)

Студворк — интернет-сервис помощи студентам
Всем доброго дня!
Сделал потомка TEdit. Хочу что бы его фон и рамка были со скругленными углами.
Нашел в инете подходящий код и немного его подправил. В итоге, скругленный фон получается хорошо, но по углам остаются белые проплешины. Понимаю что это функция WMEraseBkgnd по видимому затирает фон под TEdit.
Как достичь чистой прорисовки? Подскажите куда копать. Уже неделю курю интернет. Без толку.
Вот код:
Delphi
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
unit ADEdit;
 
interface
 
uses
  System.SysUtils, System.Classes, Vcl.Controls, Vcl.StdCtrls, Graphics,
  Messages, Dialogs, Forms, Windows, UITypes;
 
type
  TADEdit = class(TEdit)
  private
    procedure WMNCCalcSize(var Message: TWMNCCalcSize); message WM_NCCALCSIZE;
    procedure WMEraseBkgnd(var Message: TWMEraseBkgnd); message WM_ERASEBKGND;
    function TextExtent(AStr: String): TSize;
  protected
 
  public
    constructor Create(AOwner: TComponent); override;
  published
 
  end;
 
procedure Register;
 
implementation
 
procedure Register;
begin
  RegisterComponents('Altium', [TADEdit]);
end;
 
constructor TADEdit.Create(AOwner: TComponent);
begin
  inherited;
  BorderStyle := bsNone;
  Color := $002E2E2E;
  Height := 21;
  Width := 57;
  Font.Size := 8;
  Font.Color := $00E6E6E6;
  Text := '2.30mm';
end;
 
procedure TADEdit.WMEraseBkgnd(var Message: TWMEraseBkgnd);
var DC: HDC;
begin
   inherited;
   DC := GetWindowDC(Handle);
   FillRgn(DC, CreateRoundRectRgn(0, 0, Width+1, Height+1, 10, 10), Brush.Handle);
   Message.Result := 1;
end;
 
procedure TADEdit.WMNCCalcSize(var Message: TWMNCCalcSize);
var P: PNCCalcSizeParams;
    S: TSize;
begin
  inherited;
  P := Message.CalcSize_Params;
  S := TextExtent('A');
  P.rgrc[0].Top := P.rgrc[0].Top + (Height - S.cy) shr 1;
  P.rgrc[0].Left := P.rgrc[0].Left + 8;
  P.rgrc[0].Right := P.rgrc[0].Right - 2;
  P.rgrc[0].Bottom := P.rgrc[0].Top + S.cy;
end;
 
function TADEdit.TextExtent(AStr: String): TSize;
var DC: HDC;
    SaveFont: HFONT;
begin
  DC := GetDC(0);
  SaveFont := SelectObject(DC, Font.Handle);
  GetTextExtentPoint32(DC, PChar(AStr), Length(AStr), Result);
  SelectObject(DC, SaveFont);
  ReleaseDC(0, DC);
end;
 
end.
А получается вот так:


И второй момент. Очень хочу сменить цвет выделения текста, с синего системного на другой. Можно ли это сделать?
0
IT_Exp
Эксперт
34794 / 4073 / 2104
Регистрация: 17.06.2006
Сообщений: 32,602
Блог
02.12.2024, 12:25
Ответы с готовыми решениями:

Абрамов № 61, 85, 334(а), 374, 67(б,а). Прошу помочь, мне нужны эти задания для зачета прошу помощи.
Прошу помощи, скачайте файл Абрамов (пожалуйста), номер 61, 85, 334(а), 374, 67(а,б). Помочите чем сможете пожалуйста

Прошу помощи
Вот задали чтобы получить зачет сделать БД на любую свободную тему. Вот я начал делать БД сначала на акцесс а потом подключал в делфи....

Прошу о помощи
Уважаемые пользователи форума, у меня такая беда: -Купил ноутбук SAMSUNG RC530 -Беда в том что он...

17
 Аватар для krapotkin
6847 / 4674 / 1463
Регистрация: 14.04.2014
Сообщений: 20,657
Записей в блоге: 21
02.12.2024, 14:06
в VCL контролы - тонкая обертка над системными
системные - стилизуются только через темы
я не в курсе, есть где дока, как тему VCL изготовить самостоятельно

такие вещи легко делаются в FMX
1
0 / 0 / 0
Регистрация: 18.06.2020
Сообщений: 23
02.12.2024, 14:26  [ТС]
системные - стилизуются только через темы
Это вы имеете ввиду про цвет выделения текста?
такие вещи легко делаются в FMX
Это я решил оставить на крайний случай. Когда совсем безысходность настанет.
0
631 / 526 / 104
Регистрация: 05.08.2022
Сообщений: 2,810
03.12.2024, 22:41
Цитата Сообщение от SilurusGrey Посмотреть сообщение
А получается вот так:
А вопрос-то про что именно? про остающиеся уголки?

Я думаю дело в том, что Windows продолжает считать окно Edit'а прямоугольным. Вы скруглённо закрасили в WMEraseBkgnd, но прямоугольник окна никуда не делся.
Думаю надо на само окно edit'а тоже скруглённый регион наложить, чтобы Windows считала это окно склугленным по форме.

Как именно сделать не подскажу на память, но точно можно нагуглить тьму примеров "окно круглой формы delphi"
1
Модератор
4134 / 2348 / 807
Регистрация: 15.11.2015
Сообщений: 9,357
04.12.2024, 04:35
Лучший ответ Сообщение было отмечено SilurusGrey как решение

Решение

SilurusGrey, сначала нужно залить весь прямоугольник цветом фона родителя. Ну и созданные объекты нужно удалять после использования:
Delphi
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
procedure TADEdit.WMEraseBkgnd(var Message: TWMEraseBkgnd);
var
  DC: HDC;
  rgn: HRGN;
  r: TRect;
begin
  inherited;
  DC := GetWindowDC(Handle);
  r.Left := 0;
  r.Top := 0;
  r.Right := Width;
  r.Bottom := Height;
  FillRect(DC, r, Parent.Brush.Handle);
 
  rgn := CreateRoundRectRgn(0, 0, Width+1, Height+1, 10, 10);
  FillRgn(DC, rgn, Brush.Handle);
  DeleteObject(rgn);
 
  ReleaseDC(Handle, DC);
  Message.Result := 1;
end;
1
Модератор
 Аватар для D1973
9908 / 6445 / 2455
Регистрация: 21.01.2014
Сообщений: 27,358
Записей в блоге: 3
04.12.2024, 04:43
Цитата Сообщение от KSergey9 Посмотреть сообщение
чтобы Windows считала это окно склугленным по форме.
Не совсем: окно как было прямоугольное - так и останется. Скругленное визуальное представление - да, но сам регион окна - это прямоугольник.

Не по теме:

Помню, на всех этих ХР и семерках с их скругленными интерфейсами на слабых машинах были подобные артефакты по углам форм...

1
Модератор
4134 / 2348 / 807
Регистрация: 15.11.2015
Сообщений: 9,357
04.12.2024, 05:39
Тут всё равно в углах останутся артефакты, если за Edit есть другие компоненты.

Почему бы само окно не сделать скруглённым? Тогда на углах не останутся артефакты от фона:
Delphi
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
unit ADEdit;
 
interface
 
uses
  System.SysUtils, System.Classes, Vcl.Controls, Vcl.StdCtrls, Graphics,
  Messages, Dialogs, Forms, Windows, UITypes;
 
type
  TADEdit = class(TEdit)
  private
    FRGN: HRGN;
    procedure WMNCCalcSize(var Message: TWMNCCalcSize); message WM_NCCALCSIZE;
    procedure WMSize(var Message: TWMSize); message WM_SIZE;
    procedure WMEraseBkgnd(var Message: TWMEraseBkgnd); message WM_ERASEBKGND;
    function TextExtent(AStr: String): TSize;
  protected
 
  public
    constructor Create(AOwner: TComponent); override;
  published
 
  end;
 
procedure Register;
 
implementation
 
procedure Register;
begin
  RegisterComponents('Altium', [TADEdit]);
end;
 
constructor TADEdit.Create(AOwner: TComponent);
begin
  inherited;
  BorderStyle := bsNone;
  Color := $002E2E2E;
  Height := 21;
  Width := 57;
  Font.Size := 8;
  Font.Color := $00E6E6E6;
  Text := '2.30mm';
  FRGN := 0;
end;
 
procedure TADEdit.WMEraseBkgnd(var Message: TWMEraseBkgnd);
var DC: HDC;
begin
  inherited;
  DC := GetWindowDC(Handle);
  FillRect(DC, Rect(0, 0, Width, Height), Brush.Handle);
  ReleaseDC(Handle, DC);
  Message.Result := 1;
end;
 
procedure TADEdit.WMNCCalcSize(var Message: TWMNCCalcSize);
var P: PNCCalcSizeParams;
    S: TSize;
begin
  inherited;
  P := Message.CalcSize_Params;
  S := TextExtent('A');
  P.rgrc[0].Top := P.rgrc[0].Top + (Height - S.cy) shr 1;
  P.rgrc[0].Left := P.rgrc[0].Left + 8;
  P.rgrc[0].Right := P.rgrc[0].Right - 2;
  P.rgrc[0].Bottom := P.rgrc[0].Top + S.cy;
end;
 
procedure TADEdit.WMSize(var Message: TWMSize);
begin
  SetWindowRGN(Handle, 0, false);
  DeleteObject(FRGN);
  FRGN := CreateRoundRectRgn(0, 0, Width+1, Height+1, 10, 10);
  SetWindowRGN(Handle, FRGN, false);
  inherited;
end;
 
function TADEdit.TextExtent(AStr: String): TSize;
var DC: HDC;
    SaveFont: HFONT;
begin
  DC := GetDC(0);
  SaveFont := SelectObject(DC, Font.Handle);
  GetTextExtentPoint32(DC, PChar(AStr), Length(AStr), Result);
  SelectObject(DC, SaveFont);
  ReleaseDC(0, DC);
end;
 
end.
Добавлено через 5 минут
По хорошему, нужно ещё при уничтожении объекта удалить и регион тоже.
1
0 / 0 / 0
Регистрация: 18.06.2020
Сообщений: 23
04.12.2024, 11:44  [ТС]
Всем доброго дня!
И спасибо за участие.
AzAtom, Ваш код в 5-ом посте отлично сработал. То что нужно. Спасибо!

А с цветом выделения текста можно что нибудь нашаманить?
0
Модератор
 Аватар для D1973
9908 / 6445 / 2455
Регистрация: 21.01.2014
Сообщений: 27,358
Записей в блоге: 3
04.12.2024, 12:01
Цитата Сообщение от SilurusGrey Посмотреть сообщение
А с цветом выделения текста можно что нибудь нашаманить?
Не уверен. Цвет выделения определяется операционной системой и даже VCL-стилями не правится...
1
631 / 526 / 104
Регистрация: 05.08.2022
Сообщений: 2,810
04.12.2024, 14:01
Цитата Сообщение от SilurusGrey Посмотреть сообщение
А с цветом выделения текста можно что нибудь нашаманить?
Не изменяется цвет текста в edit

Не знаю есть ли там рабочий ответ

Похоже над полностью отрисовку/редактирование для Edit переписывать самостоятельно

Добавлено через 11 минут
Цитата Сообщение от D1973 Посмотреть сообщение
но сам регион окна - это прямоугольник.
По каким признакам вы это определяете?
Не в плане спора, уточнения ради
1
0 / 0 / 0
Регистрация: 18.06.2020
Сообщений: 23
04.12.2024, 14:27  [ТС]
Не знаю есть ли там рабочий ответ
Не, ответа нет.
0
Модератор
4134 / 2348 / 807
Регистрация: 15.11.2015
Сообщений: 9,357
04.12.2024, 14:59
Цитата Сообщение от SilurusGrey Посмотреть сообщение
AzAtom, Ваш код в 5-ом посте отлично сработал. То что нужно.
В №7 получше будет в плане артефактов на фоне. Можно и картинку подкладывать, закругления останутся.

Добавлено через 1 минуту
Баг увидел - при частичной перерисовке затирается текст. То есть, если задвинули окно за край экрана и потом вытягивать, то текст затирается. Попробую поправить.

Добавлено через 20 минут
Пока не получилось исправить.

Добавлено через 38 секунд
Нужно как-то отсекать часть, не заливать то, что не нужно обновлять.
1
0 / 0 / 0
Регистрация: 18.06.2020
Сообщений: 23
04.12.2024, 16:49  [ТС]
А подскажите еще такой момент.
Мне нужно в этом TADEdit перехватить события OnEnter и OnExit.
Объявляю так:
Code
1
2
protected
    procedure Enter; override;
Компилятор ругается - Method 'Enter' not found in base class.

А вот на это не ругается:
Code
1
2
protected
    procedure Click; override;
Хотя и OnClick и OnEnter присутствуют в событиях класса TEdit.
Что я делаю не так?
0
Супер-модератор
Эксперт Pascal/DelphiАвтор FAQ
 Аватар для volvo
33371 / 21497 / 8234
Регистрация: 22.10.2011
Сообщений: 36,893
Записей в блоге: 12
04.12.2024, 17:19
Лучший ответ Сообщение было отмечено SilurusGrey как решение

Решение

Цитата Сообщение от SilurusGrey Посмотреть сообщение
Компилятор ругается - Method 'Enter' not found in base class.
Правильно ругается. Нет метода Enter, есть DoEnter/DoExit, их и перегружай...
0
0 / 0 / 0
Регистрация: 18.06.2020
Сообщений: 23
04.12.2024, 17:50  [ТС]
Цитата Сообщение от volvo Посмотреть сообщение
есть DoEnter/DoExit, их и перегружай...
Да, спасибо уже нашел про это.
0
Модератор
 Аватар для D1973
9908 / 6445 / 2455
Регистрация: 21.01.2014
Сообщений: 27,358
Записей в блоге: 3
04.12.2024, 19:15
Цитата Сообщение от KSergey9 Посмотреть сообщение
По каким признакам вы это определяете?
Окно создается API-шной функцией CreateWindow



среди ее параметров 2 отвечают за размер создаваемого окна. Другой фигуры, размеры которой определяются только шириной и высотой, окромя прямоугольника (квадрат - частный случай) я не знаю.
0
Модератор
4134 / 2348 / 807
Регистрация: 15.11.2015
Сообщений: 9,357
04.12.2024, 19:32
D1973, а как же SetWindowRgn? Прямоугольник по прежнему как бы есть, но по факту его нет на экране и для мыши тоже его нет.
0
Модератор
 Аватар для D1973
9908 / 6445 / 2455
Регистрация: 21.01.2014
Сообщений: 27,358
Записей в блоге: 3
04.12.2024, 20:05
Цитата Сообщение от AzAtom Посмотреть сообщение
а как же SetWindowRgn?
Но это ведь только визуализация: что внутри полигона - видно, вовне - нет. Но попробуйте нарисовать этот полигон, выходящий за границы прямоугольного окна... А что касается мыши - тоже понятно: внутри полигона за обработку клика мыши отвечает окно, вне региона - родитель окна, к примеру, рабочий стол.
0
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
BasicMan
Эксперт
29316 / 5623 / 2384
Регистрация: 17.02.2009
Сообщений: 30,364
Блог
04.12.2024, 20:05
Помогаю со студенческими работами здесь

Прошу помощи
Вот создал сайт. ОН ТУТ существует 2 месяца. после пересчёта - ТИЦ стал 40, PR 3. Посматрите плиз, что мне нужно сделать чтоб...

Прошу помощи
Есть у меня отладочная плата на которой я экспериментирую. И вот возникла идея, сделать нечто своими руками на базе МК. Я со...

Прошу помощи
Помогите, знающие люди, что я сделал неправильно на новом сайте Способы заработка в интернет

Прошу помощи
Здравствуйте, %username%. Прошу помочь с решением следующей задачи: Есть документ "Договор на поставку". В нём указана...

Прошу помощи
Помогите пожалуйста... необходимо написать прогу, не понимаю как Создайте 2 сценария (top_ten_on_cpu и top_ten_on_mem). Эти сценарии...


Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
18
Ответ Создать тему
Новые блоги и статьи
WordPad для Windows 11
Jel 10.01.2026
WordPad для Windows 11 — это приложение, которое восстанавливает классический текстовый редактор WordPad в операционной системе Windows 11. После того как Microsoft исключила WordPad из. . .
Classic Notepad for Windows 11
Jel 10.01.2026
Old Classic Notepad for Windows 11 Приложение для Windows 11, позволяющее пользователям вернуть классическую версию текстового редактора «Блокнот» из Windows 10. Программа предоставляет более. . .
Почему дизайн решает?
Neotwalker 09.01.2026
В современном мире, где конкуренция за внимание потребителя достигла пика, дизайн становится мощным инструментом для успеха бренда. Это не просто красивый внешний вид продукта или сайта — это. . .
Модель микоризы: классовый агентный подход 3
anaschu 06.01.2026
aa0a7f55b50dd51c5ec569d2d10c54f6/ O1rJuneU_ls https:/ / vkvideo. ru/ video-115721503_456239114
Owen Logic: О недопустимости использования связки «аналоговый ПИД» + RegKZR
ФедосеевПавел 06.01.2026
Owen Logic: О недопустимости использования связки «аналоговый ПИД» + RegKZR ВВЕДЕНИЕ Введу сокращения: аналоговый ПИД — ПИД регулятор с управляющим выходом в виде числа в диапазоне от 0% до. . .
Модель микоризы: классовый агентный подход 2
anaschu 06.01.2026
репозиторий https:/ / github. com/ shumilovas/ fungi ветка по-частям. коммит Create переделка под биомассу. txt вход sc, но sm считается внутри мицелия. кстати, обьем тоже должен там считаться. . . .
Расчёт токов в цепи постоянного тока
igorrr37 05.01.2026
/ * Дана цепь постоянного тока с сопротивлениями и напряжениями. Надо найти токи в ветвях. Программа составляет систему уравнений по 1 и 2 законам Кирхгофа и решает её. Последовательность действий:. . .
Новый CodeBlocs. Версия 25.03
palva 04.01.2026
Оказывается, недавно вышла новая версия CodeBlocks за номером 25. 03. Когда-то давно я возился с только что вышедшей тогда версией 20. 03. С тех пор я давно снёс всё с компьютера и забыл. Теперь. . .
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2026, CyberForum.ru