Конференция "Компоненты" » Image-кнопка [D7, WinXP]
 
  • Klim (23.11.07 13:43) [0]
    вообщем была такая цель, написать компонент на основе TImage: три картинки, сначала одна, при наведении мышки, эта картинка сменяется на другую, при MouseDown на третью, все это при условии что новое свойство компонента(ThreeImage) установолено в true. Также нужно добавить события: когда мышь появилась над компонентом, и когда она с него ушла.
    Вроде бы все просто, я начал писать:

    unit ImageM;

    interface

    uses
      Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms,
      Dialogs, ExtCtrls;

    type
      TImageM = class (TImage)
      private
        { Private declarations }
      FPictureMove: TPicture;
      FPictureUp: TPicture;
      FPictureTemp: TPicture;
      Ft: boolean;
      //
        FOnMouseLeave: TNotifyEvent;
        FOnMouseEnter: TNotifyEvent;
        procedure CMMouseEnter(var msg: TMessage);
          message CM_MOUSEENTER;
        procedure CMMouseLeave(var msg: TMessage);
          message CM_MOUSELEAVE;
      //
    ....
      procedure SetPictureMove(Value: TPicture);
      procedure SetPictureUp(Value: TPicture);
      procedure SetPictureTemp(Value: TPicture);
      procedure SetThreeImage(Value: Boolean);
      protected
        { Protected declarations }
        procedure DoMouseEnter; dynamic;
        procedure DoMouseLeave; dynamic;
        //
       procedure MouseUp(Button: TMouseButton; Shift: TShiftState;
         X, Y: Integer); override;
       procedure MouseDown(Button: TMouseButton; Shift: TShiftState;
         X, Y: Integer); override;
      public
      constructor Create(AOwner: TComponent); override;
      destructor Destroy; override;
      //
      property PictureTemp: TPicture read FPictureTemp write SetPictureTemp;
        { Public declarations }
      published
        { Published declarations }
        property OnMouseEnter: TNotifyEvent read FOnMouseEnter write FOnMouseEnter;
        property OnMouseLeave: TNotifyEvent read FOnMouseLeave write FOnMouseLeave;
        property PictureMove: TPicture read FPictureMove write SetPictureMove;
        property PictureUp: TPicture read FPictureUp write SetPictureUp;
        property ThreeImage: boolean read Ft write SetThreeImage;
        //
       property OnMouseDown;
       property OnMouseMove;
       property OnMouseUp;
      end;

    procedure Register;

    implementation

    procedure Register;
    begin
      RegisterComponents('Additional', [TImageM]);
    end;

    { TImageEx }

    procedure TImageM.CMMouseEnter(var msg: TMessage);
    begin
      DoMouseEnter;
    end;

    procedure TImageM.CMMouseLeave(var msg: TMessage);
    begin
      DoMouseLeave;
    end;

    procedure TImageM.DoMouseEnter;
    begin
    if ft then
    Begin
    if Self.PictureMove<>nil then
      begin
      if self.FPictureTemp.Graphic=nil then
      self.SetPictureTemp(Self.Picture);
      Self.Picture.Graphic:=Self.PictureMove.Graphic;
      end;
    End;
    if Assigned(FOnMouseEnter) then
    FOnMouseEnter(Self);
    end;

    procedure TImageM.DoMouseLeave;
    begin
    if ft then
    Begin
    if self.FPictureTemp.Graphic<>nil then
      Self.Picture.Graphic:=self.FPictureTemp.Graphic;
    End;
      if Assigned(FOnMouseLeave) then
         FOnMouseLeave(Self);
    end;
    //
    procedure TImageM.SetPictureMove(Value: TPicture);
    begin
     FPictureMove.Assign(Value);
    end;
    procedure TImageM.SetPictureUp(Value: TPicture);
    begin
     FPictureUp.Assign(Value);
    end;
    procedure TImageM.SetPictureTemp(Value: TPicture);
    begin
     FPictureTemp.Assign(Value);
    end;
    procedure TImageM.SetThreeImage(Value: Boolean);
    begin
     Ft:=Value;
    end;
    //----------
       procedure TImageM.MouseDown(Button: TMouseButton; Shift: TShiftState;
         X, Y: Integer);
    begin
    if ft then
    Begin
    if Self.PictureUp<>nil then
      Self.Picture.Graphic:=Self.PictureUp.Graphic;
    End;
    inherited MouseDown(Button,Shift,X, Y);
    end;
    //
       procedure TImageM.MouseUp(Button: TMouseButton; Shift: TShiftState;
         X, Y: Integer);
    begin
    if ft then
    Begin
    if Self.PictureMove<>nil then
      Self.Picture.Graphic:=Self.PictureMove.Graphic;
    End;
    inherited MouseUp(Button,Shift,X, Y);
    end;
    //----------
    constructor TImageM.Create(AOwner: TComponent);
    begin
     inherited Create(AOwner);
     FPictureMove := TPicture.Create;
     FPictureTemp:= TPicture.Create;
     FPictureUp := TPicture.Create;
    end;

    destructor TImageM.Destroy;
    begin
     FPictureMove.Free;
     FPictureUp.Free;
     FPictureTemp.Free;
     inherited Destroy;
    end;
    //
    end.



    И вроде бы все робит, но есть одна неприятная ситуация.
    В режиме "Дизайна"(конструктора),  когда я навожу на свой имэйдж срабатывает событие(мышь появилась на компоненте), в результате чего Picture заменяется на PictureMove, и изначальная картинка Picture теряется!!!! :((((
    Как это можно исправить??????????
  • Reindeer Moss Eater © (23.11.07 14:08) [1]
    не вызывать обработчик если дизайнтайм
  • Юрий Зотов © (23.11.07 14:44) [2]
    1.
    if not (csDesigning in ComponentState) then
    begin
     ...
    end;

    2.
    Зачем везде писать self, если это подразумевается по дефолту?
  • Klim (23.11.07 20:24) [3]

    > Юрий Зотов ©   (23.11.07 14:44) [2]

    Бальшое спасибо, учту :)))
 
Конференция "Компоненты" » Image-кнопка [D7, WinXP]
Есть новые Нет новых   [134428   +41][b:0][p:0.003]