系统托盘图标的消息循环怎么写

解决方案 »

  1.   

    补充:
        点击图标后弹出菜单,然后再点桌面其他地方后,菜单不消失,怎么办。用的是 popup(x,y);
      

  2.   

    看看吧
    procedure TForm1.Button4Click(Sender: TObject);
    var
      IconData: TNotifyIconData;
      CdRomIcon:TIcon; 
    begin 
        CdRomIcon := TIcon.Create; 
        CdRomIcon.LoadFromFile('D:\程序目录\图象显示效果\黄金时代 我的电脑.ico');
        IconData.cbSize := SizeOf( IconData );
        IconData.Wnd := Handle;
        IconData.uID := 1;
        IconData.uFlags := NIF_ICON or NIF_MESSAGE or NIF_TIP;
        IconData.uCallBackMessage := WM_USER+1;
        IconData.hIcon := CdRomIcon.Handle;
        IconData.szTip := 'CDROM软开关';
        Shell_NotifyIcon( NIM_ADD, @IconData );
    end;procedure TForm1.IconOnClick( var message: Tmessage);
    var
      p : TPoint; 
    begin 
      if (message.lParam = WM_LBUTTONDOWN) then
        ShowWindow(Handle, SW_SHOW );
      if (message.lParam = WM_RBUTTONDOWN) then
        begin
        GetCursorPos(p);
        pop1.Popup( p.x ,p.y );
        end;
      SetWindowLong(Application.Handle,GWL_EXSTYLE,WS_EX_TOOLWINDOW);
      ShowWindow(Handle, SW_HIDE);
    end;
      

  3.   

    Pop1就是采单,但原对你有帮助
      

  4.   

    unit SysTray;interfaceuses
      Windows, Messages, SysUtils, Classes,
      Graphics, Controls, Forms, Dialogs,
      ShellApi, ExtCtrls, Menus, StdCtrls;const
      WM_SYSTRAY = WM_USER + 1;
      IDI_TRAYICON = 0;type
      TPopupMode = set of(pmLeftClick, pmRightClick, pmLeftDblClick, pmRightDblClick);
      TMouseEvent= procedure(Sender: TObject;
                             Button: TMouseButton;
                             X, Y: Integer) of object;  TSysTray = class(TComponent)
      private
        { Private declarations }
        FIcon: TIcon;
        FIconData: TNotifyIconData;
        FParentWindow: HWnd;
        FWindowHandle: HWnd;
        FHint: string;
        FPopupMenu: TPopupMenu;
        FPopupAlign: TPopupAlignment;
        FPopupMode: TPopupMode;
        FActive: boolean;
        FShowDesigning: boolean;    FOnIconMouseDown: TMouseEvent;
        FOnIconDoubleClick: TMouseEvent;    function AddIcon: boolean;
        function DeleteIcon: boolean;
        function ModifyIcon: boolean;    procedure SetIcon(Icon: TIcon);
        procedure SetHint(Hint: string);
        procedure SetActive(Value: boolean);
        procedure SetShowDesigning(Value: boolean);
        procedure FillDataStructure;    procedure WndProc(var Msg: TMessage); message WM_SYSTRAY;  protected
        { Protected declarations }  public
        { Public declarations }
        constructor Create(AOwner: TComponent); override;
        destructor Destroy; override;  published
        { Published declarations }
        property Active: boolean read FActive write SetActive;
        property ShowDesigning: boolean read FShowDesigning write SetShowDesigning;
        property Icon: TIcon Read FIcon write SetIcon;
        property Hint: string read FHint write SetHint;
        property PopupMenu: TPopupMenu read FPopupMenu write FPopupMenu;
        property PopupMode: TPopupMode read FPopupMode write FPopupMode;
        property PopupAlign: TPopupAlignment read FPopupAlign write FPopupAlign;    property OnIconDoubleClick:TMouseEvent
                 read FOnIconDoubleClick write FOnIconDoubleClick;
        property OnIconMouseDown:TMouseEvent
                 read FOnIconMouseDown write FOnIconMouseDown ;
      end;procedure Register;implementationprocedure Register;
    begin
      RegisterComponents('DayDream', [TSysTray]);
    end;constructor TSysTray.Create(AOwner: TComponent);
    begin
      inherited Create(AOwner);
      FIcon := TIcon.Create;
      FHint := 'SysTray Component.';
      FPopupMode := [pmRightClick];
      FPopupAlign := paRight;
      FActive := false;
      FShowDesigning := false;  if (AOwner <> nil) and (AOwner is TForm) then
        FParentWindow := TForm(AOwner).Handle
      else
        FParentWindow := 0;  FWindowHandle := AllocateHWnd(WndProc);  FillDataStructure;
    end;destructor TSysTray.Destroy;
    begin
      try
        if (not (csDesigning in ComponentState) and FActive)
           or ((csDesigning in ComponentState) and FShowDesigning) then
              DeleteIcon;
      finally
        FIcon.Free;
        DeallocateHWnd(FWindowHandle);
      end;
      inherited Destroy;
    end;function TSysTray.AddIcon: boolean;
    begin
      FillDataStructure;
      Result := Shell_NotifyIcon(NIM_ADD, @FIconData);
    end;function TSysTray.DeleteIcon: boolean;
    begin
      Result := Shell_NotifyIcon(NIM_DELETE, @FIconData);
    end;function TSysTray.ModifyIcon: boolean;
    begin
      FillDataStructure;
      if FActive then
        Result := Shell_NotifyIcon(NIM_MODIFY, @FIconData)
      else
        Result := true;
    end;procedure TSysTray.SetIcon(Icon: TIcon);
    begin
      FIcon.Assign(Icon);
      ModifyIcon;
    end;procedure TSysTray.SetHint(Hint: string);
    begin
      if Length(Hint) >= 64 then Hint := Copy(Hint, 1, 63);
      FHint := Hint;
      ModifyIcon;
    end;procedure TSysTray.SetActive(Value: boolean);
    begin
      if Value <> FActive then
      begin
        FActive := Value;
        if not (csDesigning in ComponentState) then
        begin
          case Value of
            true:    AddIcon;
            false:   DeleteIcon;
          end;
        end;
      end;
    end;procedure TSysTray.SetShowDesigning(Value: boolean);
    begin
      if (csDesigning in ComponentState) then
      begin
        if Value <> FShowDesigning then
        begin
          FShowDesigning := Value;
          case Value of
            true:    AddIcon;
            false:   DeleteIcon;
          end;
        end;
      end;
    end;procedure TSysTray.FillDataStructure;
    begin
      With FIconData do
      begin
        uCallbackMessage:=WM_SYSTRAY;
        cbSize := SizeOf(FIconData);
        uID := IDI_TRAYICON;
        wnd := FWindowHandle;
        hIcon := FIcon.Handle;
        StrCopy(FIconData.szTip, PChar(FHint));
        uFlags := NIF_ICON + NIF_TIP + NIF_MESSAGE;
      end;
    end;procedure TSysTray.WndProc(var Msg: TMessage);
    var
      P: TPoint;
    begin
      if (Msg.WParam <> IDI_TRAYICON) then exit;
      if Assigned(FPopupMenu) then
        FPopupMenu.Alignment := FPopupAlign;  GetCursorPos(p);
      case Msg.LParam of
        WM_LBUTTONDOWN:
          begin
            if (pmLeftClick in FPopupMode) and Assigned(FPopupMenu) then
            begin
              SetForegroundWindow(FParentWindow);
              FPopupMenu.Popup(p.x,p.y);
            end;
            if Assigned(FOnIconMouseDown) then
            begin
              SetForegroundWindow(FParentWindow);
              FOnIconMouseDown(Self, mbLeft, p.x, p.y);
            end;
          end;    WM_RBUTTONDOWN:
          begin
            if (pmRightClick in FPopupMode) and Assigned(FPopupMenu) then
            begin
              SetForegroundWindow(FParentWindow);
              FPopupMenu.Popup(p.x,p.y);
            end;
            if Assigned(FOnIconMouseDown) then
            begin
              SetForegroundWindow(FParentWindow);
              FOnIconMouseDown(Self, mbRight, p.x, p.y);
            end;
          end;    WM_LBUTTONDBLCLK:
          begin
            if (pmLeftDblClick in FPopupMode) and Assigned(FPopupMenu) then
            begin
              SetForegroundWindow(FParentWindow);
              FPopupMenu.Popup(p.x,p.y);
            end;
            if Assigned(FOnIconDoubleClick) then
            begin
              SetForegroundWindow(FParentWindow);
              FOnIconDoubleClick(Self, mbLeft, p.x, p.y);
            end;
          end;    WM_RBUTTONDBLCLk:
          begin
            if (pmRightDblClick in FPopupMode) and Assigned(FPopupMenu) then
            begin
              SetForegroundWindow(FParentWindow);
              FPopupMenu.Popup(p.x,p.y);
            end;
            if Assigned(FOnIconDoubleClick) then
            begin
              SetForegroundWindow(FParentWindow);
              FOnIconDoubleClick(Self, mbRight, p.x, p.y);
            end;
          end;    else
          Msg.Result := DefWindowProc(FWindowHandle, Msg.Msg, Msg.wParam, Msg.lParam);
      end;
    end;end.
      

  5.   

    楼上给的代码我看了晕!
    我相信你已经做到了TrayIcom的功能,你的问题就是弹出菜单后,如果不点菜单,才旦就不能消息,很简单,在你 popup(x,y);的前一句写上 self.BringToFront; 就行了。原因很简单。菜单谈出来,如果没选择菜单,菜单会在程序失去焦点的时候自动消息,你弹出菜单的时候程序不是焦点状态,所以也就不会出发失去焦点,所以菜单不能自动小时。