创建托盘代码: Nid.cbSize:=sizeof(TNotifyIconData);
 Nid.Wnd:=Handle;
 Nid.uID:=1000;
 Nid.uFlags:=NIF_MESSAGE or NIF_ICON or NIF_TIP;
 Nid.uCallbackMessage:=WM_TRAYNOTIFY;
 Nid.hIcon:=Application.Icon.Handle;
 Nid.szTip:=‘214’;
 Shell_NotifyIcon(NIM_ADD,@Nid);
 Icon:= TIcon.Create;
 Icon.Handle:=LoadIcon(hinstance,‘abc’);刚开始form1.bordersytle:=bsSingle;当改为bsNone时,托盘就消失了。这是为什么,应该怎么做?

解决方案 »

  1.   

    估计是因为建FORM时      case CreateStyle of
            bsNone:
              begin
                if (Parent = nil) and (ParentWindow = 0) then
                  Style := Style or WS_POPUP;
                Icons := [];
              end;所以没有了ICON
      

  2.   

    FWM_TASKBARCREATED := RegisterWindowMessageW('TaskbarCreated');Self.Perform(FWM_TASKBARCREATED, 0, 0);
      

  3.   

    procedure WndProc(var MyMessage: TMessage); override;procedure TfMain.WndProc(var MyMessage: TMessage);
    begin
      ...
      if MyMessage.Msg = FWM_TASKBARCREATED then //托盘栏防崩溃处理
      begin
        TrayIcon.NotifyDelete(Self.Handle);
        TrayIcon.NotifyAdd(Self.Handle, Self.Showing);
      end
      else
        //调用父类的WndProc方法处理其它消息
        inherited;
      

  4.   

    ”调用父类的WndProc方法处理其它消息“无从下手,请高人明见
      

  5.   


    第一句放在程序初始化的地方,因为这个消息值是靠系统生成的,每次启动系统不一样。第二句放在你修改窗体风格为bsNone之后,等于你谎报军情,告诉当前窗体“资源管理器崩溃了”。
      

  6.   

    form1.bordersytle改变时会导致窗口重新初始化,所以不建议动态改变。你可以发消息代替这个属性。
    例如:如果你想将窗口改为无边框,则执行:procedure TForm1.Button1Click(Sender: TObject);
    begin
     SetWindowLong(Handle,GWL_STYLE,GetWindowLong(Handle,GWL_STYLE) and (not WS_CAPTION));
    end;
      

  7.   

    这段代码在04年写的,后来修改了一点,是一个简单的托盘栏类,简单的不能再简单了。
    {*******************************************************}
    {                                                       }
    {       托盘栏图标类单元                                }
    {                                                       }
    {       版权所有 (C) 2006 高亚男                        }
    {                                                       }
    {       2006-9-7                                        }
    {                                                       }
    {*******************************************************}unit ClsTrayIcon;interface
    uses
    Windows, {Menus, }Messages, Graphics, Classes;
    type
      TTrayIcon = class(TComponent)
      private
    //   FPopupMenu: TPopupMenu;
        FActiveIcon: TIcon;
        FDeActiveIcon: TIcon;
        FParent: TComponent;
        function TrayMessage(hDlg: THandle; dwMessage: DWORD; uID: UINT; hIcon: HICON): boolean;
      public
       property ActiveIcon: TIcon read FActiveIcon Write FActiveIcon;
        property DeActiveIcon: TIcon read FDeActiveIcon write FDeActiveIcon;
    //   property PopupMenu: TPopupMenu read FPopupMenu write FPopupMenu;
        constructor Create(AOwner:TComponent); override;
        destructor Destroy; override;
        procedure NotifyAdd(hDlg: HWND; State: Boolean);
        procedure StateChange(hDlg: HWND; State: Boolean);
        procedure NotifyDelete(hDlg: HWND);
    end;
    const
    MYWM_NOTIFYICON = WM_USER + 100;     //托盘栏图标消息
    var
    TrayIcon: TTrayIcon;
    implementation
    uses
    ShellApi;const
    IDS_TrayIconTip: WideString = '看好你的鴨子!';
    const
    TrayIconID = 2052;function TTrayIcon.TrayMessage(hDlg: THandle; dwMessage: DWORD; uID: UINT; hIcon: HICON): boolean;
    var
      tnd: NOTIFYICONDATAW;
    begin
    tnd.cbSize := SizeOf(tnd);
    tnd.Wnd := hDlg;
    tnd.uID := uID; tnd.uFlags := NIF_MESSAGE or NIF_ICON or NIF_TIP;
    tnd.uCallbackMessage := MYWM_NOTIFYICON;
    tnd.hIcon := hIcon;
    lstrcpynW(tnd.szTip, PWideChar(IDS_TrayIconTip), SizeOf(tnd.szTip) div SizeOf(tnd.szTip[0]));
    Result := Shell_NotifyIconW(dwMessage, @tnd); if hIcon = 0 then
       DestroyIcon(hIcon);
    end;procedure TTrayIcon.StateChange(hDlg: HWND; State: Boolean);
    var
    MyIcon: HICON;
    begin
    if State then
      MyIcon := ActiveIcon.Handle
      else
        MyIcon := DeActiveIcon.Handle; TrayMessage(hDlg, NIM_MODIFY, TrayIconID, MyIcon);
    end;procedure TTrayIcon.NotifyDelete(hDlg: HWND);
    begin
    TrayMessage(hDlg, NIM_DELETE, TrayIconID, 0);
    end;procedure TTrayIcon.NotifyAdd(hDlg: HWND; State: Boolean);
    var
    MyIcon: HICON;
    begin
    if State then
         MyIcon := ActiveIcon.Handle
      else
         MyIcon := DeActiveIcon.Handle;
    TrayMessage(hDlg, NIM_ADD, TrayIconID, MyIcon);
    end;constructor TTrayIcon.Create(AOwner: TComponent);
    begin
      inherited;
      FParent := AOwner;
      FActiveIcon := TIcon.Create;
      FDeActiveIcon := TIcon.Create;
    end;destructor TTrayIcon.Destroy;
    begin
      FActiveIcon.Free;
      FDeActiveIcon.Free;
      inherited;
    end;initialization
    finalization
    end.
      

  8.   

    这个是主窗体的部分代码。
    我的主窗体默认是不关闭的,点击那个右上方的x仅仅是缩小到托盘栏,双击图标可以打开主窗口。
    想要关闭程序,需要单独用一个菜单写一个close。
    不好意思,这里用的都是Tnt组件库,自己替换成相应的类。
    SetForegroundWindow指令是必须的,否则当你呼叫出菜单后,却没有理会他,那个菜单会让你很无奈,这是MSDN上写的,MS的程序员发现了这个BUG,却没有去修复。  TfMain = class(TfEditorTemplate)
        pmTrayIcon: TTntPopupMenu;
        miOpenMainForm: TTntMenuItem;
        miExit: TTntMenuItem;
        procedure miOpenMainFormClick(Sender: TObject);
        procedure miExitClick(Sender: TObject);
      private
        FWM_TASKBARCREATED: LongWord;       //防崩溃消息
      protected
        procedure WndProc(var MyMessage: TMessage); override;
      public
        { Public declarations }
      end;procedure TfMain.miExitClick(Sender: TObject);
    // 关闭程序
    begin
      inherited;
      Close;
    end;procedure TfMain.miOpenMainFormClick(Sender: TObject);
    // 显示主窗体
    begin
      inherited;
      Self.Show;
      Application.Restore;
      SetForegroundWindow(Self.Handle);
    end;procedure TfMain.WndProc(var MyMessage: TMessage);
    var
      pt: TPoint;
    begin
      case MyMessage.Msg of
      WM_CREATE:      // 注册消息,防止系统崩溃
        FWM_TASKBARCREATED := RegisterWindowMessageW('TaskbarCreated');
      WM_CLOSE:       // 关闭事件
        PostMessageW(Self.Handle, WM_SYSCOMMAND, SC_MINIMIZE, 0);
      WM_SYSCOMMAND: begin
        case MyMessage.WParam of
        SC_MINIMIZE:  // 窗体最小化
        begin
          Application.Minimize;
          Self.Hide;
        end
        else
          inherited;
        end;
      end;
      MYWM_NOTIFYICON:
        case MyMessage.lParam of
        WM_LBUTTONDBLCLK:  //鼠标左键双击
        begin
          if Self.Showing then
            PostMessageW(Self.Handle, WM_SYSCOMMAND, SC_MINIMIZE, 0)
          else
            Self.miOpenMainForm.Click;
        end;
        WM_RBUTTONDOWN:   //鼠标右键被按下
        begin
          GetCursorPos(pt);
          SetForegroundWindow(Self.Handle);
          pmTrayIcon.Popup(pt.x,pt.y);
        end
        else
          //调用父类的WndProc方法处理其它消息
          inherited;
        end;
      else
        if MyMessage.Msg = FWM_TASKBARCREATED then //托盘栏防崩溃处理
        begin
          TrayIcon.NotifyDelete(Self.Handle);
          TrayIcon.NotifyAdd(Self.Handle, Self.Showing);
        end
        else
          //调用父类的WndProc方法处理其它消息
          inherited;
      end;
    end;
      

  9.   


    procedure TCustomForm.SetBorderStyle(Value: TFormBorderStyle);
    begin
      if FBorderStyle <> Value then
      begin
        FBorderStyle := Value;
        AutoScroll := FBorderStyle in [bsSizeable, bsSizeToolWin];
        if not (csDesigning in ComponentState) then RecreateWnd;
      end;
    end;procedure TWinControl.RecreateWnd;
    begin
      if FHandle <> 0 then Perform(CM_RECREATEWND, 0, 0);// <===引发CM_RECREATEWND消息,执行CMRecreateWnd处理过程
    end;procedure TWinControl.CMRecreateWnd(var Message: TMessage);
    var
      WasFocused: Boolean;
    begin
      WasFocused := Focused;
      DestroyHandle;          // <=== 这里是关键,句柄被销毁了。
      UpdateControlState;
      if WasFocused and (FHandle <> 0) then Windows.SetFocus(FHandle);
    end;