Delphiで、フォーム初期表示時にタスクトレイにアイコン表示させたい

nxrecelinkerは、コメントだけでも許さないマン。。。

task bar exitされないや

SetWindowLong(Application.Handle, GWL_EXSTYLE, WS_EX_TOOLWINDOW);

あたりまえだけど、formは複数あるから一つ消し込んだだけでは消えないだけ??

^^^^

 機能要件

  1. 初期表示時にタスクバーにアイコン表示はしない
  2. 初期表示時にタスクトレイにアイコン表示させる
用語
タスクバー...Wibdowsの下のアイコン
タスクトレイ...右下のアイコン場所
実装方針
①タスクバーから非表示にする場合
...
 
uses ..., ShellAPI;
 
...
 
ShowWindow(Application.Handle, SW_HIDE);
...
②タスクトレイに表示させたい場合
...
 
const
WM_NotifyMessage = WM_USER + 100;
 
uses ..., ShellAPI;
 
...
 
type
...
 private
procedure NotifyMessage(var Msg: TMessage); message WM_NotifyMessage;
 
...
 
var
NotifyIcon: PNotifyIconDataA;
 
...
 
{タスクトレイにアイコン追加}
New(NotifyIcon);
NotifyIcon.cbSize := SizeOf(TNotifyIconDataA);
NotifyIcon.Wnd := Handle;
NotifyIcon.uID := 1;
NotifyIcon.uFlags := NIF_ICON or NIF_MESSAGE or NIF_TIP;
NotifyIcon.uCallbackMessage := WM_NotifyMessage;
NotifyIcon.hIcon := Application.Icon.Handle;
NotifyIcon.szTip := 'タスクトレイのアイコンにマウスを合わせると表示される文字列';
Shell_NotifyIcon(NIM_ADD, NotifyIcon);
 
{タスクトレイからアイコン削除}
NotifyIcon.cbSize := SizeOf(TNotifyIconDataA);
NotifyIcon.Wnd := Handle;
NotifyIcon.uID := 1;
Shell_NotifyIcon(NIM_DELETE, NotifyIcon);
Dispose(NotifyIcon);
 
procedure TForm1.NotifyMessage(var Msg: TMessage);
begin
case Msg.lParam of
 WM_RBUTTONDOWN: Close;
end;
end;
---
error E2029



なんか知らんけどタスクバーけす動作を↓に真似てやったら動作したのと、
ついでになんかアイコンが一周出たぞ。
https://www.blackcat.xyz/article.php/ProgramingFAQ_del0045

アイコン消えたのはたぶん、TnotifyicondataのWndとuflagsが想定外だから??
で、こいつら何してんの?って感じだな。

begin
  with IconData do
  begin
    uid     := 1;
    cbSize  := TNotifyIconData.SizeOf;
    hIcon   := Vcl.forms.Application.Icon.Handle;
    Wnd   := hWndTrayIcon;
    uFlags := NIF_MESSAGE or NIF_ICON or NIF_TIP;
    //szTip :=Toolname;
    StrPLCopy(szTip, PChar('常駐アプリテスト'), 64);
  end;
  Shell_NotifyIcon( NIM_ADD, @IconData ); <-- ここで現れる
end; <-- ここで消えるなんで?
あぁローカルデータだから??


---
CreateMainFormでタスクバー生成しているね。
↓新対応
[Q]
Windows95 で、タスクトレイにアイコンを表示するアプリケーションを作成したので、代わりにメインフォームとタスクバーへのアイコンを非表示にしたいのですが、どうすればよろしいのでしょうか?

[A]
まず、メインフォームを非表示にするには以下のようにします。
プロジェクトソースファイルに Application.ShowMainForm := False; を追加します。

begin
  Application.Initialize;
  Application.ShowMainForm := False;  // ← これを追加します。
  Application.CreateForm(TForm1, Form1);
  Application.Run;
end.

次にタスクバーへアイコンを非表示にするためには以下のようにします。
メインフォームの OnCreate イベントに ShowWindows を呼び出す行を追加します。

procedure TForm1.FormCreate(Sender: TObject);
begin
  ShowWindow(Application.Handle, SW_HIDE);  // ← これを追加します。
end;


notifdataだけだと永続しない。だから常駐なのだろうかね。
message共有のregisterwindowrecreateとかなんだよ。
アプリケーションを常駐させてタスクトレイに登録したい

コンポーネントをつかう人が多いんでしょうね。MLでは少ない話題です。このようなAPLを何十本も作るんでなければ、直接コーディングしてみませんか。
要領は、APIのShell_NotifyIcon関数を使うことです。TaskTrayへの登録と削除は簡単にできます。
頭を悩ますのは、どんなアイコンを使うのかと、TaskTrayに送られてくるメッセージを自分で決めなければならないことです。

const
  WM_MY_TRAYICON = WM_APP + $300; // 適当です

// ProcessMesageに配慮--無くても良い
procedure TForm1.FormClose(Sender: TObject; var Action: TCloseAction);
begin
  // WM_QUIT メッセージを受け取る時
  if Application.Terminated then
  begin
    ShowWindow(Application.Handle, SW_HIDE);
    Visible := False;
    Action := caNone;
  end;
end;

// アイコンをトレイに登録--ここではメインアイコンを使用
procedure TForm1.CreateTaskBarIcon;
var
  NotifyData: TNotifyIconData;
begin
  with NotifyData do
  begin
    cbSize := SizeOf(TNotifyIconData);
    Wnd    := hWndTrayIcon;
    uID    := 0;
    uFlags := NIF_MESSAGE or NIF_ICON or NIF_TIP;
    szTip  := 'Traybar Tip';
    hIcon  := Application.Icon.Handle;
    uCallbackMessage := WM_MY_TRAYICON;// 独自に定義
  end;
  Shell_NotifyIcon( NIM_ADD, @NotifyData );
end;

// アイコンを削除
procedure TForm1.DeleteTaskBarIcon;
var
  NotifyData: TNotifyIconData;
begin
  with NotifyData do
  begin
    cbSize := SizeOf(TNotifyIconData);
    Wnd    := hWndTrayIcon;
    uID    := 0;
  end;
  Shell_NotifyIcon( NIM_DELETE, @NotifyData );
end;

// 起動直後はトレイにアイコン表示のみ
procedure TForm1.FormCreate(Sender: TObject);
begin
  // uTaskBarRecrate は TForm1 の private に UINT 型で宣言
  // 新しい UtilWindow を作成し、ブロードキャストメッセージのみを受け取らせる
  uTaskBarRecreate := RegisterWindowMessage('TaskbarCreated');
  // hWndTrayIcon は TForm1 の private に HWND 型で宣言
  // メッセージ送信先を指定
  hWndTrayIcon := AllocateHWnd(TaskTrayWndProc);

  CreateTaskBarIcon;
  ShowWindow(Application.Handle,SW_HIDE);
  Application.ShowMainForm := False;
end;

// 終了した時にトレイのアイコンを削除
procedure TForm1.FormDestroy(Sender: TObject);
begin
  DeleteTaskBarIcon;
  DeallocateHWnd(hWndTrayIcon);
end;

// タスクトレイに来るWM_MY_TRAYICONメッセージを受信
procedure TForm1.TaskTrayWndProc(var Msg: TMessage);
var
  ps: TPoint;
begin
  Case Msg.LParam of
    WM_LBUTTONDBLCLK:
      begin
        Visible := true;
        ShowWindow(Application.Handle,SW_SHOW);
        //ShowWindow(Application.Handle,SW_RESTORE);
      end;
    WM_RBUTTONUP:
      begin
        GetCursorPos(ps);
        SetForegroundWindow(Handle);
        // フォームにポップアップメニューがあるとする
        PopupMenu1.Popup(ps.x,ps.y);
        PostMessage(Handle, WM_NULL, 0,0);
      end;
    else
      // タスクバーが移動・再構築された場合に消えたアイコンを再生成
      if (Msg.LParam = LongInt(uTaskBarRecreate)) then
        CreateTaskBarIcon;
  end;
end;

AllocateHWnd 関数の戻り値のウィンドウハンドルを利用すれば他のメッセージ受信先/送信先として利用できるので、TrayIcon のメッセージ送信先に利用しました。

ファイルモンキーでの隠し方とvclでの隠し方。
ファイルモンキーのきーたきじ

タスクバーの非表示はこれかな?
でもけんしょうしなきゃ
if (GAppWnd = 0) and (StrComp(lpszClass, 'TFMAppClass') = 0) then
// hwnd を TApplication のウィンドウハンドルとして保存しておく
GAppWnd := hwnd
else begin
// もしも TApplication が visible(=タスクバーに表示されている)
// なら、非表示にする!
if (GAppWnd <> 0) and (IsWindowVisible(GAppWnd)) then
ShowWindow(GAppWnd, SW_HIDE);

Next Post Previous Post
No Comment
Add Comment
comment url