Форум программистов
 

Восстановите пароль или Зарегистрируйтесь на форуме, о проблемах и с заказом рекламы пишите сюда - alarforum@yandex.ru, проверяйте папку спам!

Вернуться   Форум программистов > Delphi программирование > Компоненты Delphi
Регистрация

Восстановить пароль
Повторная активизация e-mail

Купить рекламу на форуме - 42 тыс руб за месяц

Ответ
 
Опции темы Поиск в этой теме
Старый 22.06.2011, 03:36   #1
xrob
Форумчанин
 
Регистрация: 18.10.2010
Сообщений: 419
По умолчанию создать TButton с нуля

как я уже понял любой контрол на форме - это окно.
с том числе и обычная кнопка, это окно, имеющее свой handle,
и получающее сообщения от винды.
а имеет ли любое окно Canvas, или это уже добавляется вручную?
вот к примеру так ли работает кнопка?:
1. создается окно
2. это окно начинает получать сообщения от винды
3. когда оно получит сообщение что мышка нажата
(а оно его получит только если мышка будет именно над этим окном, правильно?)
то нарисует изображение нажатой мышки и запустит процедуру OnClick

я примерно представляю как ловить сообщения,
у меня вопрос в том, как создать окно,
и как быть с канвасом?

пытался пошарить в VCL как создаются кнопки,
запутался в иерархии.
ибо TButton с своем Create добавляет только пару строчек и inherited.
его предок - тоже самое, и т.д.

я знаю про CreateWindow,
но не знаю какой там параметр указать, чтоб создалось окно без заголовка.

кому не влом разложите, пожалуйста, по полочкам, как создать TButton с нуля.
и прокоментируйте мой пост, в чем я прав, в чем не прав =)
xrob вне форума Ответить с цитированием
Старый 22.06.2011, 08:47   #2
Nemez
Пользователь
 
Аватар для Nemez
 
Регистрация: 11.02.2008
Сообщений: 69
По умолчанию

Если Вы имеете ввиду динамическое создание объектов, то например так.
Код:
procedure TForm1.Button1Click(Sender: TObject);
var
b: TButton;
begin
b:=tbutton.Create(Self);
b.Left:=0;
b.Top:=0;
b.Caption:='New Button';
b.Parent:=Form1;
end;
При нажатии на кпопку появляется новая кнопка на форме с кординатами 0,0.
Nemez вне форума Ответить с цитированием
Старый 22.06.2011, 08:57   #3
Aliens_wolfs
Форумчанин
 
Регистрация: 16.12.2009
Сообщений: 902
По умолчанию

Создать массив кнопок

Цитата:
private
{TForm}
procedure RunButtonClick(Sender: TObject);
end;

{...}

var
Form1: TForm;
RunButtons: array[1..10] of TButton;

{...}

implementation

{...}

procedure TForm1.RunButtonClick(Sender: TObject);
begin
{Показать событие нажатой кнопки}
ShowMessage('Button' + IntToStr((Sender as TButton).Tag) + ' clicked!');
{Либо по имени отслеживать нажатие}
ShowMessage((Sender as TButton).name + ' clicked!');
end;

procedure TForm1.Button1Click(Sender: TObject);
var
i: Byte;
begin
for i := 1 to 10 do
begin
{Создаем кнопки}
RunButtons[i] := TButton.Create(Self);
with RunButtons[i] do
begin
Parent := Form1;
Caption := 'Button ' + IntToStr(i);
Name := 'Button' + IntToStr(i);
Top := i * Height;
Tag := i;
{Передать событие нажатие кнопок}
OnClick := RunButtonClick;
Visible := True;
end;
end;
end;
При нажатии на кнопку появятся 10 кнопок друг над другом, событие нажатия любой из них отслеживается функцией RunButtonClick, работать с ними через эту функцию например
if (Sender as TButton).name = 'Button1' then и какое то действие
if (Sender as TButton).name = 'Button2' then и какое то действие
либо
if (Sender as TButton).caption = 'Button 1' then и какое то действие
if (Sender as TButton).caption = 'Button 2' then и какое то действие
либо
Case (Sender as TButton).tag of
1:и какое то действие
2:и какое то действие
end;

Последний раз редактировалось Aliens_wolfs; 22.06.2011 в 09:39.
Aliens_wolfs вне форума Ответить с цитированием
Старый 22.06.2011, 11:45   #4
xrob
Форумчанин
 
Регистрация: 18.10.2010
Сообщений: 419
По умолчанию

хаха =), спасибо, конечно за внимание, и за отклики,
однако имел в виду совсем другое...
динамическое создание готовых объектов VCL я изучил уже давно.
и так же давно меня перестал устраивать внешний вид этих объектов,
и я занялся созданием своих контролов.
здесь "контролов" следует понимать в очень общем смысле,
т.е. "элементов управления", ибо по принципу действия и организации
мои объекты имеют мало общего с привычными вам "контролами".
я создал неведомую ё***ю систему, переопределил класс формы,
для работы своих компонентов (чуть позже я расскажу что это за система).
и система работала! =)
и прекрасно работала!
до тех пор, пока я не начал использовать TThread...
все пошло наперекосяк =(
мои компоненты благополучно загибались, но стандартные,
так же присутствовавшие на форме продолжали стабильно работать,
программа не висла, висли мои компоненты.
ну и вся эта история навела меня на мысль, что нужно сделать
свои компоненты как стандартные - по принципу окон и сообщений.

под созданием TButton я имел в виду написание своего класса, аналогичного ему,
а не создание экземпляра готового класса VCL =)
xrob вне форума Ответить с цитированием
Старый 22.06.2011, 12:11   #5
Stilet
Белик Виталий :)
Старожил
 
Аватар для Stilet
 
Регистрация: 23.07.2007
Сообщений: 57,097
По умолчанию

Цитата:
мои компоненты благополучно загибались
А что именно ты в поток вынес?
I'm learning to live...
Stilet вне форума Ответить с цитированием
Старый 22.06.2011, 12:17   #6
JTG
я получил эту роль
Старожил
 
Аватар для JTG
 
Регистрация: 25.05.2007
Сообщений: 3,694
По умолчанию

Цитата:
создать TButton с нуля
Но зачем? Наследуйтесь от TCustomControl и рисуйте что угодно.

Цитата:
до тех пор, пока я не начал использовать TThread
Дайте угадаю, "Canvas does not allow drawing"? У TCanvas есть счётчик блокировок LockCount, но обычно при правильной работе потоков c GUI через synchronize его дёргать не приходится.
пыщь
JTG вне форума Ответить с цитированием
Старый 22.06.2011, 12:46   #7
xrob
Форумчанин
 
Регистрация: 18.10.2010
Сообщений: 419
По умолчанию

в поток я вынес...
а что я вынес?
прога кое-чего скачивает, на это нужно время, и в это время, разумеется окно не должно висеть,
и все кнопочки должны весело подмигивать если водить по ним мышкой.
по мере скачивания прога сообщает одному из компонентов чего она качает,
а он в свою очередь отрисовывает себя на канвасе формы
(у меня все объекты отрисовывают себя на канвасе)
я уже запихнул с синхронизацию все что можно, все обращения к моим компонентам,
но все-равно работает нестабильно.

Да! JTG, "Canvas does not allow drawing", но далеко не каждый раз, что затрудняет отладку.
в основном происходит то, что мои компоненты перестают рисоваться.
программа работает, форму таскаешь, за экран уводишь - канвас стирается и больше не перерисовывается

кстати, у меня еще такой вопрос,
wcx: twndclass;
wcx.lpfnwndproc := @mainwndproc; // адрес оконной процедуры...
как его получить?

есть TForm1.MainWndProc, как я понимаю это procedure of object (?)
как мне получить указатель на эту процедуру, чтоб потом запихать его в wcx.lpfnwndproc ?
xrob вне форума Ответить с цитированием
Старый 22.06.2011, 12:46   #8
Aliens_wolfs
Форумчанин
 
Регистрация: 16.12.2009
Сообщений: 902
По умолчанию

Насчет потока.
В потоке нельзя делать прямое обращение к объектам которые делают визуальные действия, будет всегда ошибка или не правильно работать. С ними нужно работать через функции и обращаться к ним с потока желательно методом Synchronize.

На счет функции TForm1.MainWndProc
Посмотри эту ссылку.
http://www.delphisources.ru/pages/fa...only_api2.html

Пример: Поток без синхронизации
Цитата:
type
TForm1 = class(TForm)
...................
procedure Button1Click(Sender: TObject);
procedure Button2Click(Sender: TObject);
private
{ Private declarations }
public
//функция для потока в TForm1
procedure ThreadsDone(Sender: TObject);
end;

//Поток
TView = class(TThread)
protected
procedure Execute; override;
public
constructor Create; virtual;
destructor Destroy; override;
end;

var
Form1: TForm1;
View: TView; //Имя потока

implementation

{$R *.dfm}

constructor TView.Create;
begin
inherited Create(True);
FreeOnTerminate := True; //Когда поток останавливается он уничтожается сам
resume; //запускаем поток
end;

destructor TView.Destroy;
begin
Terminate;
inherited;
end;

procedure TView.Execute;
begin
//Поток будет работать в функции TForm1
OnTerminate := Form1.ThreadsDone;
//Или так попробовать с вашей функцией если не будет ошибки
OnTerminate := wcx.lpfnwndproc;
end;

procedure TForm1.ThreadsDone(Sender: TObject);
begin
Ваш код
Если идет какой то цикл в потоке то прерывай его например в цикле поставь sleep(10) чтобы не зависал и не грузил процессор

end;

// Пример запуска и остановки потока
procedure TForm1.Button1Click(Sender: TObject);
begin
//Создаем и запускаем поток
View :=TView.Create;
end;

procedure TForm1.Button2Click(Sender: TObject);
begin
//Останавливаем поток
View.Terminate;
end;

Последний раз редактировалось Aliens_wolfs; 22.06.2011 в 16:08.
Aliens_wolfs вне форума Ответить с цитированием
Ответ


Купить рекламу на форуме - 42 тыс руб за месяц



Похожие темы
Тема Автор Раздел Ответов Последнее сообщение
Аналог array of TButton ZBEP Visual C++ 2 27.09.2010 09:52
TButton со всеми вытекающими... PoM4ik Компоненты Delphi 9 25.08.2010 20:32
Цвет TButton guffer Общие вопросы Delphi 3 18.08.2009 12:00
Компонент TButton... slim5 Помощь студентам 7 17.06.2008 17:58
цвет caption в Tbutton EdNovice Компоненты Delphi 5 31.05.2008 22:57