Search code examples
delphifeedback

Simulate a webpage feedback button


I like to place a feedback button on may main (MDIParent) form that simulates those in webpages.

Like it to grow when the mouse goes over it. Just like the web. The form with questions and the send of the data, I really don't need it, just the visual stuff.

Is there any such component ?. I don't think it's difficult to do, but if it already exist it will same me some time.

Thanks


Solution

  • To make an animated slide panel you can use a code like follows:

    unit Unit1;
    
    interface
    
    uses
      Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
      Dialogs, StdCtrls, ExtCtrls;
    
    type
      TForm1 = class(TForm)
        procedure FormCreate(Sender: TObject);
      private
        FFeedbackBtn: TPanel;
        FFeedbackPanel: TPanel;
        procedure OnFeedbackBtnMouseEnter(Sender: TObject);
        procedure OnFeedbackPanelMouseLeave(Sender: TObject);
      public
        { Public declarations }
      end;
    
    var
      Form1: TForm1;
    
    implementation
    
    {$R *.dfm}
    
    procedure TForm1.FormCreate(Sender: TObject);
    begin
      FFeedbackBtn := TPanel.Create(Self);
      FFeedbackBtn.Parent := Self;
      FFeedbackBtn.Anchors := [akLeft, akTop, akBottom];
      FFeedbackBtn.Caption := '';
      FFeedbackBtn.SetBounds(0, 0, 40, ClientHeight);
      FFeedbackBtn.OnMouseEnter := OnFeedbackBtnMouseEnter;
    
      FFeedbackPanel := TPanel.Create(Self);
      FFeedbackPanel.Parent := Self;
      FFeedbackPanel.Anchors := [akLeft, akTop, akBottom];
      FFeedbackPanel.Caption := 'Feedback panel';
      FFeedbackPanel.Visible := False;
      FFeedbackPanel.SetBounds(0, 0, 250, ClientHeight);
      FFeedbackPanel.OnMouseLeave := OnFeedbackPanelMouseLeave;
    end;
    
    procedure TForm1.OnFeedbackBtnMouseEnter(Sender: TObject);
    begin
      AnimateWindow(FFeedbackPanel.Handle, 150, AW_ACTIVATE or AW_SLIDE or
        AW_HOR_POSITIVE);
    end;
    
    procedure TForm1.OnFeedbackPanelMouseLeave(Sender: TObject);
    begin
      AnimateWindow(FFeedbackPanel.Handle, 150, AW_HIDE or AW_SLIDE or
        AW_HOR_NEGATIVE);
    end;
    
    end.
    

    Update:

    Here's another version of the above, now with a vertical text like a typical feedback button has, rendered on a paint box stretched on the button panel:

    unit Unit1;
    
    interface
    
    uses
      Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
      Dialogs, StdCtrls, ExtCtrls;
    
    type
      TForm1 = class(TForm)
        procedure FormCreate(Sender: TObject);
      private
        FFeedbackBtn: TPanel;
        FFeedbackBtnOverlay: TPaintBox;
        FFeedbackPanel: TPanel;
        procedure OnFeedbackBtnMouseEnter(Sender: TObject);
        procedure OnFeedbackPanelMouseLeave(Sender: TObject);
        procedure OnFeedbackBtnOverlayPaint(Sender: TObject);
      public
        { Public declarations }
      end;
    
    var
      Form1: TForm1;
    
    implementation
    
    {$R *.dfm}
    
    procedure TForm1.FormCreate(Sender: TObject);
    begin
      FFeedbackBtn := TPanel.Create(Self);
      FFeedbackBtn.Parent := Self;
      FFeedbackBtn.Anchors := [akLeft, akTop, akBottom];
      FFeedbackBtn.Caption := '';
      FFeedbackBtn.Color := $0000B3FF;
      FFeedbackBtn.ParentBackground := False;
      FFeedbackBtn.SetBounds(0, 0, 40, ClientHeight);
    
      FFeedbackBtnOverlay := TPaintBox.Create(Self);
      FFeedbackBtnOverlay.Parent := FFeedbackBtn;
      FFeedbackBtnOverlay.Align := alClient;
      FFeedbackBtnOverlay.OnPaint := OnFeedbackBtnOverlayPaint;
      FFeedbackBtnOverlay.OnMouseEnter := OnFeedbackBtnMouseEnter;
    
      FFeedbackPanel := TPanel.Create(Self);
      FFeedbackPanel.Parent := Self;
      FFeedbackPanel.Anchors := [akLeft, akTop, akBottom];
      FFeedbackPanel.Caption := 'Feedback panel';
      FFeedbackPanel.Color := $0000F9FF;
      FFeedbackPanel.ParentBackground := False;
      FFeedbackPanel.Visible := False;
      FFeedbackPanel.SetBounds(0, 0, 250, ClientHeight);
      FFeedbackPanel.OnMouseLeave := OnFeedbackPanelMouseLeave;
    end;
    
    procedure TForm1.OnFeedbackBtnMouseEnter(Sender: TObject);
    begin
      AnimateWindow(FFeedbackPanel.Handle, 150, AW_ACTIVATE or AW_SLIDE or
        AW_HOR_POSITIVE);
    end;
    
    procedure TForm1.OnFeedbackPanelMouseLeave(Sender: TObject);
    begin
      AnimateWindow(FFeedbackPanel.Handle, 150, AW_HIDE or AW_SLIDE or
        AW_HOR_NEGATIVE);
    end;
    
    procedure TForm1.OnFeedbackBtnOverlayPaint(Sender: TObject);
    var
      S: string;
      X, Y: Integer;
    begin
      S := 'Feedback...';
      with FFeedbackBtnOverlay do
      begin
        Canvas.Brush.Color := $0000B3FF;
        Canvas.FillRect(ClientRect);
        Canvas.Font.Orientation := 900;
        X := (ClientWidth - Canvas.TextHeight(S)) div 2;
        Y := ClientHeight - (ClientHeight - Canvas.TextWidth(S)) div 2;
        Canvas.TextOut(X, Y, S);
      end;
    end;
    
    end.
    

    And the result:

    Result

    You should also implement some logic to prevent user to hide the feedback panel when will actually filling the fields, but it's a natural weakness of such kind of a feedback form.