2010-01-25 22 views
5

En estos días se ve un montón de software que muestra ventanas de mensajes en la esquina inferior derecha de la pantalla activa durante unos segundos o hasta que finalice se hace clic en el botón (fi Norton hace esto después de haber comprobado una descarga).Cómo mostrar una ventana de mensaje en la esquina inferior derecha de la pantalla activa usando Delphi

me gustaría hacer esto utilizando Delphi 7 (y si es posible Delphi 2010, ya que estoy migrando lentamente mi código para la versión más reciente).

Encontré algunas publicaciones aquí en SO con respecto a formularios que no reciben atención, pero eso es solo una parte del problema. Estoy pensando también en la forma de determinar la posición exacta de esta ventana de mensaje (fi sabiendo que un usuario puede ventaja de su barra de tareas a la derecha de la pantalla.

Thx por adelantado.

Actualización 26 Ene , 10:a partir del código de drorhan creé la siguiente forma (en Delphi 7), que funciona si la barra de tareas aparece en la parte inferior, la derecha, la izquierda o hacia la parte superior del schreen

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 
.

y

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. 

Para ser utilizado como prueba en mi forma con dos botones:

forma
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; 

El mensaje se mostrará el icono de la aplicación, pero probablemente añadirán un TImageList y agregar una propiedad para pasar un índice de imagen para que pueda mostrar diferentes iconos. También usaré TcxLabel de los componentes Dev.Express ya que esto proporcionará una posición vertical, pero la unidad anterior se puede usar tal cual.

He probado esto con Delphi 7 y Windows XP. Si alguien usa esta unidad con otra versión de Delphi y/o Windows Vista o Windows 7, dígame si esta unidad también funcionará allí.

Respuesta

3
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. 

través http://www.experts-exchange.com/Programming/Languages/Pascal/Delphi/Q_25043483.html

2

Lo que está buscando son Consejos de globo en una bandeja del sistema. Para WinAPI general aquí hay un nice tutorial para él, que no debería tener problemas para traducir a Delphi.

Puede encontrar un código listo para usar para puntas de globo en Delphi here.

Una buena implementación es available here.

+1

pensé Consejos Bolloon en la bandeja del sistema siempre están conectados a un icono en la SY bandeja de tallo. Quizás sin embargo Me gustaría tener cualquier forma Delphi (con lo que quiera colocar en él, texto, imágenes, etc.) para que se coloque en la parte inferior derecha de la pantalla activa y para que se muestre sin que reciba el foco. – Edelcom

1

se puede comprobar dónde está la barra de tareas:

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; 

Y a continuación, mostrar la forma de ...

1

usted podría utilizar Growl for Windows - Creo que no hay una biblioteca Delphi para él todavía, pero puede controlarlo a través de mensajes UDP, por lo que cualquier biblioteca de red debería hacerlo.

+0

Actualización: parece haber algún código para controlar Growl en http://growl.matf.de. – mghie

+0

Gracias por la sugerencia, pero quiero controlar los mensajes y verme a mí mismo sin que los usuarios tengan que instalar el software adicional. – Edelcom

1

Salida Gruñido, similar a gruñir para Windows, pero he encontrado a ser mejor. Hay un archivo Pas para la interfaz fácil, y la forma en que funciona es muy simple, con solo enviar mensajes de Windows.

http://fullphat.net/

También permite al usuario final una cierta cantidad de control de los mensajes, que a ver, la duración antes de desaparecer, etc.

+0

Thx para el enlace, pero no quiero obligar al usuario final a instalar software adicional. Aunque la idea detrás de Snarl es buena (simplemente no es lo que estoy buscando en este momento). – Edelcom

4

Trate de usar el componente wich TJvDesktopAlert está incluido en el JVCL, se pueden encontrar un ejemplo en los ejemplos jvcl \ \ JvDesktopAlert \ JvDesktopAlertDemo.dpr

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

+0

Thx por la respuesta. Desafortunadamente, no uso los componentes JVCL, aunque lo instalé una vez. Veré el código para ver cómo lo hacen, pero heredaron su propia clase TJvExForm. No quiero arrastrar muchos códigos o clases solo por esto. – Edelcom

Cuestiones relacionadas