![]() |
|
|
|||||||
| Регистрация | << Правила форума >> | FAQ | Пользователи | Календарь | Поиск | Сообщения за сегодня | Все разделы прочитаны |
![]() |
|
|
Опции темы | Поиск в этой теме | Опции просмотра |
|
#1
|
|||
|
|||
|
Здравствуйте!
Столкнулся с ситуацией, объяснения которой найти не могу. Суть такова: Создаю класс, на основе TCustomControl, в методе Paint прорисовываю так сказать "подложку", после чего вызываю функцию CreateWindowEx, которая создает поле ввода, с параметрами описанными в первом попавшемся примере (при компиляции примера проблем нет). После компиляции получаю следующее: Поле ввода отображается, но при открытии диспетчера задач видно, как каждую секунду количество используемой приложением памяти увеличивается. Не могу найти причину - дело в неправильном вызове CreateWindowEx или все гораздо сложнее и создавать подобные элементы необходимо не прямым вызовом функций api? на всякий случай вот код функции: Код:
hEdit := CreateWindowEx(WS_EX_CLIENTEDGE,'edit', '', WS_CHILD or WS_VISIBLE or ES_LEFT or WS_TABSTOP, 10, 10, 80, 20, Handle, 0, hInstance, nil); Подскажите, в какую сторону копать Заранее спасибо! |
|
#2
|
||||
|
||||
|
Ну ты гигант мысли. Событие OnPaint (WM_PAINT) вызывается системой при каждом случае, когда требуется перерисовать окно. Перерисовали, и что дальше? Дальше у тебя создаётся ещё одно, неизвестно кому нужное, окно. И это может происходить десятки раз в секунду. Вот и считай.
Кстати, а чем TCustomEdit не угодил? Последний раз редактировалось angvelem, 26.09.2011 в 01:59. |
|
#3
|
|||
|
|||
|
angvelem, спасибо! Теперь ситуация начинает проясняться. TCustomEdit не угодил тем, что кроме поля ввода должены быть еще элементы управления. В таком случае создавать окна нужно до наступления события OnPaint, а в OnPaint уже только отображать/перерисовывать?
Не совсем понятен принцип. Когда нужно рисовать свои окна так, чтобы это было правильно? |
|
#4
|
||||
|
||||
|
создавать в constructor"е, удалять в destructor"е. не забыв переписать SetParent, Notification и SetBounds. посмотри реализацию TLabeledEdit для начала.
|
|
#5
|
|||
|
|||
|
NumLock, спасибо!
Боюсь это был не последний вопрос. *ушел смотреть реализацию TLabeledEdit* |
|
#6
|
|||
|
|||
|
NumLock,
в TLabeledEdit создается экземпляр класса класса TBoundLabel, могу ли я действовать по тому же принципу, если я использую не готовый класс, а рисую через api? |
|
#7
|
||||
|
||||
|
нарисуй в MS Paint как должен выглядеть твой компонент и что должен делать?
|
|
#8
|
|||
|
|||
|
Все просто. Есть Edit и Button. При нажатии на кнопку открывается окно, в котором есть некий справочник, в нем выбирается значение и вставляется в Edit. Но сразу предупрежу, что создание внутри компонента экземпляров TEdit и Tbutton неприемлимо в моем случае, вот поэтому и необходимо нарисовать.
|
|
#9
|
||||
|
||||
|
не понятно почему неприемлемо использование TEdit и TButton? это куда проще, чем самому реализовывать эти объекты графически: рисовать кнопку и ее нажатие, рисовать поле и текст в нем, навигация и редактирование текста в поле ввода...
|
|
#10
|
|||
|
|||
|
Это слишком ресурсоемкий вариант, очень важна производительность. Может посоветуете какую-нибудь литературу, где рассматривается хотя бы частично мой вопрос?
Я уже много всего просмотрел, не могу найти ничего подобного. |
|
#11
|
||||
|
||||
![]() Код:
unit EditButtonControl;
interface
uses
// Dialogs,
Windows, Messages, SysUtils, Classes, Graphics, Controls;
type
TEditButtonControl = class(TCustomControl)
private
FEdit: String;
FButton: String;
FOnClick: TNotifyEvent;
procedure SetEdit(const Value: String);
procedure SetButton(const Value: String);
protected
procedure Paint; override;
procedure WMLButtonDown(var Message: TWMLButtonDown);
message WM_LBUTTONDOWN;
public
constructor Create(AOwner: TComponent); override;
procedure SetBounds(ALeft, ATop, AWidth, AHeight: Integer); override;
published
property Edit: String read FEdit write SetEdit;
property Button: String read FButton write SetButton;
property OnClick: TNotifyEvent read FOnClick write FOnClick;
end;
procedure Register;
implementation
procedure Register;
begin
RegisterComponents('Internet', [TEditButtonControl]);
end;
{ TEditButtonControl }
constructor TEditButtonControl.Create(AOwner: TComponent);
begin
inherited Create(AOwner);
FEdit:='TEdit';
FButton:='TButton';
end;
procedure TEditButtonControl.Paint;
var
ARect: TRect;
begin
Canvas.Brush.Color:=clBtnFace;
Canvas.FillRect(ClientRect);
ARect:=Rect(0, 0, Width, Height);
DrawEdge(Canvas.Handle, ARect, EDGE_RAISED, BF_RECT);
ARect:=Rect(10, 10, Width-10, 10+21);
Canvas.Brush.Color:=clWindow;
Canvas.FillRect(ARect);
DrawEdge(Canvas.Handle, ARect, EDGE_SUNKEN, BF_RECT);
InflateRect(ARect, -4, 0);
DrawText(Canvas.Handle, PChar(FEdit), -1, ARect,
DT_LEFT or DT_SINGLELINE or DT_VCENTER);
ARect:=Rect(10, 10+21+10, 10+75, 10+21+10+25);
Canvas.Brush.Color:=clBtnFace;
Canvas.FillRect(ARect);
DrawEdge(Canvas.Handle, ARect, EDGE_RAISED, BF_RECT);
DrawText(Canvas.Handle, PChar(FButton), -1, ARect,
DT_CENTER or DT_SINGLELINE or DT_VCENTER);
end;
procedure TEditButtonControl.SetBounds(ALeft, ATop, AWidth, AHeight: Integer);
begin
AWidth:=200;
AHeight:=76;
inherited SetBounds(ALeft, ATop, AWidth, AHeight);
end;
procedure TEditButtonControl.WMLButtonDown(var Message: TWMLButtonDown);
begin
inherited;
if (Message.XPos>=10) and (Message.XPos<=85) and (Message.YPos>=10+21+10)
and (Message.YPos<=10+21+10+25) then
begin
if Assigned(FOnClick) then FOnClick(Self);
// Edit:=InputBox('InputBox', 'Text:', '');
end;
end;
procedure TEditButtonControl.SetEdit(const Value: String);
begin
if Value<>FEdit then
begin
FEdit:=Value;
Invalidate;
end;
end;
procedure TEditButtonControl.SetButton(const Value: String);
begin
if Value<>FButton then
begin
FButton:=Value;
Invalidate;
end;
end;
end.http://data.cod.ru/125935 |
|
#12
|
|||
|
|||
|
NumLock, спасибо за очень познавательный пример!! Но для меня это усложненный путь, может подскажете как правильно создавать окна внутри компонента?
|
|
#13
|
|||
|
|||
|
http://codege.org/projects/visg/
мне как-то помогал, возможно уже есть другие альтернативы |
|
#14
|
||||
|
||||
|
Код:
unit EditButtonControl;
interface
uses
StdCtrls,
Windows, Messages, SysUtils, Classes, Graphics, Controls;
type
TEditButtonControl = class(TCustomControl)
private
FEdit: TEdit;
FButton: TButton;
FOnClick: TNotifyEvent;
procedure OnButtonClick(Sender: TObject);
protected
procedure Paint; override;
procedure SetParent(AParent: TWinControl); override;
procedure Notification(AComponent: TComponent;
Operation: TOperation); override;
public
constructor Create(AOwner: TComponent); override;
destructor Destroy; override;
procedure SetBounds(ALeft, ATop, AWidth, AHeight: Integer); override;
published
property OnClick: TNotifyEvent read FOnClick write FOnClick;
end;
procedure Register;
implementation
procedure Register;
begin
RegisterComponents('Internet', [TEditButtonControl]);
end;
{ TEditButtonControl }
constructor TEditButtonControl.Create(AOwner: TComponent);
begin
inherited Create(AOwner);
FEdit:=TEdit.Create(Self);
FButton:=TButton.Create(Self);
FButton.Caption:='Click me...';
FButton.OnClick:=OnButtonClick;
end;
destructor TEditButtonControl.Destroy;
begin
// if Assigned(FEdit) then FEdit.Free;
// if Assigned(FButton) then FButton.Free;
inherited Destroy;
end;
procedure TEditButtonControl.Paint;
var
ARect: TRect;
begin
Canvas.Brush.Color:=clBtnFace;
Canvas.FillRect(ClientRect);
ARect:=Rect(0, 0, Width, Height);
DrawEdge(Canvas.Handle, ARect, EDGE_RAISED, BF_RECT);
end;
procedure TEditButtonControl.SetBounds(ALeft, ATop, AWidth, AHeight: Integer);
begin
AWidth:=200;
AHeight:=76;
if Assigned(FEdit) then
begin
FEdit.Left:=ALeft+10;
FEdit.Top:=ATop+10;
if Assigned(FButton) then
begin
FButton.Left:=ALeft+10;
FButton.Top:=ATop+10+FEdit.Height+10;
end;
end;
inherited SetBounds(ALeft, ATop, AWidth, AHeight);
end;
procedure TEditButtonControl.SetParent(AParent: TWinControl);
begin
inherited SetParent(AParent);
if Assigned(FEdit) then FEdit.Parent:=AParent;
if Assigned(FButton) then FButton.Parent:=AParent;
end;
procedure TEditButtonControl.Notification(AComponent: TComponent;
Operation: TOperation);
begin
inherited Notification(AComponent, Operation);
if (AComponent=FEdit) and (Operation=opRemove) then FEdit:=nil;
if (AComponent=FButton) and (Operation=opRemove) then FButton:=nil;
end;
procedure TEditButtonControl.OnButtonClick(Sender: TObject);
begin
Windows.Beep(1000, 10);
end;
end. |
|
#15
|
|||
|
|||
|
Цитата:
![]() |