代码之家  ›  专栏  ›  技术社区  ›  Edelcom

如何使用Delphi在活动显示器的右下角显示消息窗口

  •  5
  • Edelcom  · 技术社区  · 15 年前

    最近你看到很多软件在显示 活动屏幕右下角的消息窗口 几秒钟或直到单击关闭按钮(F.I.Norton在检查下载后执行此操作)。

    我想用 德尔福7 (如果可能的话 德尔福2010 ,因为我正在缓慢地将代码迁移到最新版本)。

    我在这里发现了一些关于表单的帖子,这些帖子没有得到关注,但这只是问题的一部分。我也在考虑如何确定这个消息窗口的确切位置(知道F.I.用户可能已将任务栏放在屏幕右侧)。

    提前通知。

    更新日期:2010年1月26日: 从代码开始 drorhan 我创建了以下表单(在Delphi7中),无论任务栏是显示在屏幕的底部、右侧、左侧还是顶部,它都可以工作。

    fPopupMessage.dpr:
    
      object frmPopupMessage: TfrmPopupMessage
        Left = 537
        Top = 233
        AlphaBlend = True
        AlphaBlendValue = 200
        BorderStyle = bsToolWindow
        Caption = 'frmPopupMessage'
        ClientHeight = 48
        ClientWidth = 342
        Color = clBtnFace
        Font.Charset = DEFAULT_CHARSET
        Font.Color = clWindowText
        Font.Height = -11
        Font.Name = 'MS Sans Serif'
        Font.Style = []
        OldCreateOrder = False
        OnClose = FormClose
        OnCreate = FormCreate
        DesignSize = (
          342
          48)
        PixelsPerInch = 96
        TextHeight = 13
        object img: TImage
          Left = 0
          Top = 0
          Width = 64
          Height = 48
          Align = alLeft
          Center = True
          Transparent = True
        end
        object lblMessage: TLabel
          Left = 72
          Top = 8
          Width = 265
          Height = 34
          Alignment = taCenter
          Anchors = [akLeft, akTop, akRight, akBottom]
          AutoSize = False
          Caption = '...'
          Font.Charset = DEFAULT_CHARSET
          Font.Color = clNavy
          Font.Height = -11
          Font.Name = 'Verdana'
          Font.Style = [fsBold]
          ParentFont = False
          Transparent = True
          WordWrap = True
        end
        object tmr: TTimer
          Enabled = False
          Interval = 3000
          OnTimer = tmrTimer
          Left = 16
          Top = 16
        end
      end
    

    fpopupmessage.pas(fpopupmessage.pas)

      unit fPopupMessage;
    
      interface
    
      uses
        Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
        Dialogs, StdCtrls, ExtCtrls, ImgList;
    
      type
        TfrmPopupMessage = class(TForm)
          tmr: TTimer;
          img: TImage;
          lblMessage: TLabel;
          procedure FormCreate(Sender: TObject);
          procedure tmrTimer(Sender: TObject);
          procedure FormClose(Sender: TObject; var Action: TCloseAction);
        private
          { Private declarations }
          bBeingDisplayed : boolean;
          function GetPopupMessage: string;
          procedure SetPopupMessage(const Value: string);
          function GetPopupCaption: string;
          procedure SetPopupCaption(const Value: string);
          function TaskBarHeight: integer;
          function TaskBarWidth: integer;
          procedure ToHiddenPosition;
          procedure ToVisiblePosition;
        public
          { Public declarations }
          procedure StartAnimationToHide;
          procedure StartAnimationToShow;
          property PopupCaption: string read GetPopupCaption write SetPopupCaption;
          property PopupMessage: string read GetPopupMessage write SetPopupMessage;
        end;
    
      var
        frmPopupMessage: TfrmPopupMessage;
    
      procedure DisplayPopup( sMessage:string; sCaption:string = '');
    
      implementation
    
      {$R *.dfm}
    
      const
         DFT_TIME_SLEEP = 5;       // the speed you want to show/hide.Increase/descrease this to make it faster or slower
         DFT_TIME_VISIBLE = 3000;  // number of mili-seconds the form is visible before starting to disappear
         GAP = 2;                  // pixels between form and right and bottom edge of the screen
    
      procedure DisplayPopup( sMessage:string; sCaption:string = '');
      begin
         // we could create the form here if necessary ...
         if not Assigned(frmPopupMessage) then Exit;
    
         frmPopupMessage.PopupCaption := sCaption;
         frmPopupMessage.PopupMessage := sMessage;
         if not frmPopupMessage.bBeingDisplayed
         then begin
            ShowWindow( frmPopupMessage.Handle, SW_SHOWNOACTIVATE);
            frmPopupMessage.Visible := True;
         end;
         frmPopupMessage.StartAnimationToShow;
      end;
    
      procedure TfrmPopupMessage.FormCreate(Sender: TObject);
      begin
        img.Picture.Assign(Application.Icon);
        Caption := '';
        lblMessage.Caption := '';
        bBeingDisplayed := False;
    
        ToHiddenPosition();
      end;
    
      procedure TfrmPopupMessage.FormClose(Sender: TObject; var Action: TCloseAction);
      begin
         tmr.Enabled := False;
         Action := caHide;
         bBeingDisplayed := False;
      end;
    
      function TfrmPopupMessage.TaskBarHeight: integer; // this is just to get the taskbar height to put
      // my form in the correct position
      var
        hTB: HWND;
        TBRect: TRect;
      begin
        hTB := FindWindow('Shell_TrayWnd', '');
        if hTB = 0 then
          Result := 0
        else
        begin
          GetWindowRect(hTB, TBRect);
          if TBRect.Top = 0  // tray bar is positioned to the left or to the right
          then
             Result := 1
          else
             Result := TBRect.Bottom - TBRect.Top;
        end;
      end;
    
      function TfrmPopupMessage.TaskBarWidth: integer; // this is just to get the taskbar height to put
      // my form in the correct position
      var
        hTB: HWND;
        TBRect: TRect;
      begin
        hTB := FindWindow('Shell_TrayWnd', '');
        if hTB = 0 then
          Result := 0
        else
        begin
          GetWindowRect(hTB, TBRect);
          if TBRect.Left = 0  // tray bar is positioned to the left or to the right
          then
             Result := 1
          else
             Result := TBRect.Right - TBRect.Left
        end;
      end;
    
      procedure TfrmPopupMessage.ToHiddenPosition;
      begin
        Self.Left := Screen.Width - TaskbarWidth - Self.Width - GAP;
        Self.Top := Screen.Height - TaskBarHeight;
      end;
    
      procedure TfrmPopupMessage.ToVisiblePosition;
      begin
        Self.Left := Screen.Width - TaskBarWidth - Self.Width - GAP;
        Self.Top := Screen.Height - Self.Height - TaskBarHeight - GAP;
      end;
    
      procedure TfrmPopupMessage.StartAnimationToShow;
      var
        i: integer;
      begin
        if bBeingDisplayed
        then
           ToVisiblePosition()
        else begin
           ToHiddenPosition();
    
           for i := 1 to Self.Height+GAP do
           begin
             Self.Top := Self.Top-1;
             Application.ProcessMessages;
             Sleep(DFT_TIME_SLEEP);
           end;
        end;
        tmr.Interval := DFT_TIME_VISIBLE;
        tmr.Enabled := True;
        bBeingDisplayed := True;
    
      end;
    
      procedure TfrmPopupMessage.StartAnimationToHide;
      var
        i: integer;
      begin
        if not bBeingDisplayed then Exit;
    
        for i := 1 to Self.Height+GAP do
        begin
          Self.Top := Self.Top+1;
          Application.ProcessMessages;
          Sleep(DFT_TIME_SLEEP);
        end;
        bBeingDisplayed := False;
        Visible := False;
      end;
    
      procedure TfrmPopupMessage.tmrTimer(Sender: TObject);
      begin
         tmr.Enabled := False;
         StartAnimationToHide();
      end;
    
      function TfrmPopupMessage.GetPopupMessage: string;
      begin
         Result := lblMessage.Caption;
      end;
    
      procedure TfrmPopupMessage.SetPopupMessage(const Value: string);
      begin
         lblMessage.Caption := Value;
      end;
    
      function TfrmPopupMessage.GetPopupCaption: string;
      begin
         Result := frmPopupMessage.Caption;
      end;
    
      procedure TfrmPopupMessage.SetPopupCaption(const Value: string);
      begin
         frmPopupMessage.Caption := Value;
      end;
    
      end.
    

    在我的测试表单中使用两个按钮:

    procedure TfrmMain.button1Click(Sender: TObject);
    begin
       DisplayPopup('Message displayed at ' + FormatDateTime('ddd mmm yy zzz', Now),'My Program');
       beep;
    end;
    
    procedure TfrmMain.button2Click(Sender: TObject);
    begin
       DisplayPopup('Another message displayed at ' + FormatDateTime('hh:nn zzz', Now),'My Program');
    end;
    

    消息窗体将显示应用程序图标,但我可能会添加一个TimageList并添加一个属性来传递图像索引,以便显示不同的图标。我还将使用dev.express组件中的tcxlabel,因为这将提供垂直位置,但上述单元可以按原样使用。

    我用Delphi7和WindowsXP测试过这个。如果有人将此单元与其他版本的Delphi和/或Windows Vista或Windows 7一起使用,请告诉我此单元是否也可以在那里工作。

    7 回复  |  直到 10 年前
        1
  •  3
  •   Orhan Cinar    15 年前
    unit Unit1;
    
    interface
    
    uses
      Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
      Dialogs, StdCtrls;
    
    type
      TForm1 = class(TForm)
        Button1: TButton;
        procedure FormCreate(Sender: TObject);
        procedure Button1Click(Sender: TObject);
      private
        { Private declarations }
      public
        { Public declarations }
      end;
    
    var
      Form1: TForm1;
    
    implementation
    
    {$R *.dfm}
    
    procedure TForm1.FormCreate(Sender: TObject);
      function TaskBarHeight: integer; // this is just to get the taskbar height to put
      // my form in the correct position
      var
        hTB: HWND;
        TBRect: TRect;
      begin
        hTB := FindWindow('Shell_TrayWnd', '');
        if hTB = 0 then
          Result := 0
        else
        begin
          GetWindowRect(hTB, TBRect);
          Result := TBRect.Bottom - TBRect.Top;
        end;
      end;
    
    begin
      Self.Left := Screen.Width - Self.Width;
      Self.Top := Screen.Height-Self.Height-TaskBarHeight;
    end;
    
    procedure TForm1.Button1Click(Sender: TObject);
    var
      i: integer;
      TimeSleep: integer;
    begin
      TimeSleep := 5; // the speed you want to show/hide.Increase/descrease this to make it faster or slower
      for i := 1 to Self.Height do
      begin
        Self.Top := Self.Top+1;
        Sleep(TimeSleep);
      end;
      // now let's show it again(use this as code as the show code)
      for i := 1 to Self.Height do
      begin
        Self.Top := Self.Top-1;
        Sleep(TimeSleep);
      end;
    end;
    
    end.
    

    通过 http://www.experts-exchange.com/Programming/Languages/Pascal/Delphi/Q_25043483.html

        2
  •  4
  •   RRUZ    15 年前

    尝试使用TjvDesktoAlert组件,该组件包含在 JVCL ,您可以在jvcl\examples\jvdesktopalert\jvdesktopalertdemo.dpr中找到一个示例。

    alt text http://www.agnisoft.com/deepak/blog/DesktopAlert.jpg

        3
  •  2
  •   Kornel Kisielewicz    15 年前

    您要搜索的是系统托盘中的气球提示。对于Winapi将军来说,这里是 nice tutorial 对于它,你不应该有问题翻译到德尔福。

    您可以在Delphi中找到一些气球提示的现成代码。 here .

    一个好的实现是 available here .

        4
  •  1
  •   SimaWB    15 年前

    您可以检查任务栏的位置:

    uses ShellAPI;
    //...
    Var AppBar: TAppbarData;
    //...
    begin
      FillChar(AppBar, sizeof(AppBar), 0);
      AppBar.cbSize := Sizeof(AppBar);
    
      if ShAppBarMessage(ABM_GETTASKBARPOS, AppBar) <> 0 then
      begin
        //AppBar.rc is TRect
      end;
    end;
    

    然后展示你的表格…

        5
  •  1
  •   mghie    15 年前

    你可以使用 Growl for Windows -我认为还没有Delphi库,但是您可以通过UDP消息控制它,所以任何网络库都应该这样做。

        6
  •  1
  •   Orhan Cinar    15 年前
        7
  •  1
  •   jasonpenny    15 年前

    看看“咆哮”,类似于对窗户的咆哮,但我发现更好。 有一个pas文件可以方便地进行接口,它的工作方式非常简单,只需发送Windows消息。

    http://fullphat.net/

    它还允许最终用户对哪些消息进行一定程度的控制,以及衰落前的持续时间等。