Создаём свои кнопки, используя TImage и параметр Sender. На delphi
Полтора года назад писал такую статью на одном форуме, на блоге этого нет. В связи с тем, что на этой неделе поднял тему использования Sender: TObject и операторов as и is, распишу всё заново здесь и сейчас :)

Мы используем TImage, столько TImage, сколько нужно кнопок.

Подготовка

У наших кнопок будет три состояния — нажата, не нажата, активна (наведена мышь).
Заранее подготовь три картинки, для трёх этих состояний, и помести в папку программы.
Создадим константы с именами наших картинок:

const
  IM_DOWN: string='down.bmp';
  IM_MAIN:  string='main.bmp';
  IM_HOVER: string='hover.bmp';

Ии, нам надо их менять, подготовимся:

procedure SetState(btn:TImage;vstate:string);
var
  vfile:string;
begin
  vfile:=ExtractFilePath(ParamStr(0))+vstate;
  try
    btn.Picture.LoadFromFile(vfile);
  except
  end;
end;

Здесь мы передаём функции имя файла картинки (из созданных констант) и указание на TImage, с которым нужно такое сотворить.

Так-с, поставим теперь на форму Image1, создадим ему следующие обработчики событий:

procedure TForm1.Image1MouseMove(Sender: TObject; Shift: TShiftState; X,
  Y: Integer);
begin
  SetState(Image1,IM_HOVER);
end;

procedure TForm1.Image1MouseUp(Sender: TObject; Button: TMouseButton;
  Shift: TShiftState; X, Y: Integer);
begin
  SetState(Image1,IM_MAIN);
end;

procedure TForm1.Image1MouseDown(Sender: TObject; Button: TMouseButton;
  Shift: TShiftState; X, Y: Integer);
begin
  SetState(Image1,IM_DOWN);
end;

Тут всё понятно (надеюсь): при нажатии, отжатии, наведении мышью. А как быть, когда мышь уходит?

procedure TForm1.FormMouseMove(Sender: TObject; Shift: TShiftState; X,
  Y: Integer);
begin
  SetState(Image1,IM_MAIN);
end;

Да, с одним TImage работает на ура. Только вот мерцает при движении мышью, это плохо, так ведь?

Тогда добавим еще четыре константы:

const
  BS_UP=1001;         //последнее событие было mouseup
  BS_DOWN=1002;       //последнее событие было mousedown
  BS_HOVER=1003;      //последнее событие было mousemove
  BS_FORM=1004;  //мышь двигается по форме

Куда мы будем их присваивать? Неверно, к свойству tag у TImage, оно зарезервировано специально для таких пожарных случаев.

Сразу приведу модифицированный код:

procedure TForm1.Image1MouseMove(Sender: TObject; Shift: TShiftState; X,
  Y: Integer);
begin
  if Image1.Tag<>BS_HOVER then
    SetState(Image1,IM_HOVER);
  Image1.Tag:=BS_HOVER;
end;

procedure TForm1.Image1MouseUp(Sender: TObject; Button: TMouseButton;
  Shift: TShiftState; X, Y: Integer);
begin
  if Image1.Tag<>BS_UP then
    SetState(Image1,IM_MAIN);
  Image1.Tag:=BS_UP;
end;

procedure TForm1.Image1MouseDown(Sender: TObject; Button: TMouseButton;
  Shift: TShiftState; X, Y: Integer);
begin
  if Image1.Tag<>BS_DOWN then
    SetState(Image1,IM_DOWN);
  Image1.Tag:=BS_DOWN;
end;

procedure TForm1.FormMouseMove(Sender: TObject; Shift: TShiftState; X,
  Y: Integer);
begin
  if Image1.Tag<>BS_FORM then
    SetState(Image1,IM_MAIN);
  Image1.Tag:=BS_FORM;
end;

Обобщение

Вот и настал тот момент… когда нам надо переходить от одного Image1 к любому TImage, на котором произошло событие. Если ты читал мой блог, то уже знаешь, что надо заменить Image1 на (Sender as TImage) во всех обработчиках событий у Image1.

А что делать при движении мышью по форме? Точно, надо перебрать все компоненты TImage на форме, полезный, кстати, навык:

procedure TForm1.FormMouseMove(Sender: TObject; Shift: TShiftState; X,
  Y: Integer);
var
  i:integer;
begin
  for i:=0 to ComponentCount-1 do begin
    if Components[i] is TImage then begin
      if (Components[i] as TImage).Tag<>BS_FORM then
        SetState((Components[i] as TImage),IM_MAIN);
     (Components[i] as TImage).Tag:=BS_FORM;
    end;
  end;
end;

Вроде всё чисто и ясно, могу про это потом отдельный пост написать.

Ну и назначим события при старте формы:

procedure TForm1.FormCreate(Sender: TObject);
var
  i:integer;
begin
  for i:=0 to ComponentCount-1 do begin
    if Components[i] is TImage then begin
      (Components[i] as TImage).OnMouseDown:=Image1MouseDown;
      (Components[i] as TImage).OnMouseUp:=Image1MouseUp;
      (Components[i] as TImage).OnMouseMove:=Image1MouseMove;
    end;
  end;
end;

Итог

Теперь, сколько бы мы TImage не создали в проекте, столько у нас и будет кнопок :)


Свой стиль кнопок на delphi
А вы знали, что google — хиппи? Особенно рано утром :)

Иногда требуется подключить интернет, но возникают проблемы — много провайдеров, разные тарифы — как выбрать? Если ты в Москве, то воспользуйся ссылкой выше.


(c) crystalbit, http://parsers.info

Ах, вот проектик — скачать
А вот rss лента — подписаться