4/7

 Window Messageについて

WindowsはイベントドリブンのOSであり、生じたイベントはウィンドウ メッセージとしてやりとりされる。

イベントは、マウスのクリック、キー操作、タッチスクリーンでのジェスチャーなど目に見えるもののほか、ウィンドウの作成、初期化、終了など内部動作に関わるものまで様々なものがある。

プログラムは、このようなイベントを受け取って、適時必要な動作をすることで、動作をしている。

メッセージはUNIT型すなわちunsigned intであり、Win32(ILP32)およびWin64(LLP64)ともに32ビットである。

元々Win16だった頃の影響を受けており、範囲は次のように16ビット範囲内で概ね定められている。

0x0000WM_USER-1システム用
WM_USER(0x0400)WM_APP-1プライベートウィンドウクラス用
WM_APP (0x8000)0xBFFFアプリケーション用整数メッセージ
0xC0000xFFFFRegisterWindowMessage() 文字列メッセージ
0x10000 将来のために予約

アプリケーションが、システムのメッセージと衝突させずに独自のメッセージを作りたい場合、0x8000〜0xBFFFを用いることができる。

0x8000はWM_APPとして定義されていることから、WM_APP+1、のようにWM_APPからのオフセットで表現すると分かり易い。

単機能レベルでのタスクトレイの表示

ソースコードは下記です。

//{$WARNINGS OFF}


program TrayIconNonForm;


uses

  Windows,

  Classes,

  Messages,

  System.UITypes,

  SysUtils,

  Forms,

  ShellAPI,

  Dialogs;


{$R *.RES}


var

  Msg         : TMsg;

  NotifyIcon  : TNotifyIconData;

  //HotKeyID1   : Integer;

  //SetKey1     : Cardinal;

  //SetShift1   : Cardinal;


//-----------------------------------------------------------------------------

//  トレイアイコンとホットキーの登録

//-----------------------------------------------------------------------------

procedure TrayIconTouroku;

begin

  //トレイアイコンの情報の初期化

  FillChar(NotifyIcon, SizeOf(TNotifyIconData), #0);

  //各種情報を設定

  NotifyIcon.cbSize           := SizeOf(TNotifyIconData);

  NotifyIcon.Wnd              := Application.Handle;

  NotifyIcon.hIcon            := Application.Icon.Handle;

  NotifyIcon.uCallbackMessage := WM_APP + 100;

  NotifyIcon.uID              := 1;

  NotifyIcon.uFlags           := NIF_ICON or NIF_MESSAGE or NIF_TIP;

  StrPLCopy(NotifyIcon.szTip, PChar('常駐アプリテスト'), 64);

  //トレイアイコンの登録

  Shell_NotifyIcon(NIM_ADD,Addr(NotifyIcon));



  //グローバルホットキー(ショートカットキー)の登録

  //多い場合は配列の使用が良

  //SetKey1   := Ord('A');

  //SetShift1 := MOD_CONTROL;

  //HotKeyID1 := GlobalAddAtom('MyHotkey1');

  //RegisterHotKey(Application.Handle, HotKeyID1, SetShift1, SetKey1);

end;


//-----------------------------------------------------------------------------

//  メッセージ処理用ウィンドウプロシージャー

//  [Ctrl]+[A]キーで常駐終了

//  タスクトレイの本アプリのアイコン上のマウス右ボタン押下でメッセージを表示

//-----------------------------------------------------------------------------

function MainAppProc(hWindow: HWND; Msg: UINT; WParam: WPARAM; LParam: LPARAM):

  LRESULT; stdcall; export;

begin

  Result := 0;


  case Msg of

  //WM_HOTKEY:

  //  begin

  //    PostQuitMessage(0);

  //  end;

  WM_APP + 100:

    begin

      if LParam = WM_LBUTTONDOWN then begin

        MessageDlg('トレイアイコンで,マウス右ボタンが押されました',

                   mtInformation,

                   [mbOK],

                   0);

        //ダイアログを[X]ボタンで閉じてしまった場合の対策

        //[X]ボタンと[Alt]+[F4]では常駐を終了させない

        Result := 1;


      end;

    end;

  else

    begin

      Result := DefWindowProc( hWindow, Msg, wParam, lParam );

    end;

  end;

end;


//-----------------------------------------------------------------------------

//  ホットキーとトレイアイコンの登録削除

//-----------------------------------------------------------------------------

procedure TrayIconOwari;

begin

  //グロパールホットキーの登録解除

  //GlobalDeleteAtom(HotkeyID1);

  //UnRegisterHotKey(Application.Handle, HotKeyID1);


  //トレイアイコンの削除

  Shell_NotifyIcon(NIM_DELETE, @NotifyIcon);

end;


//=============================================================================

//  このサンプルは

//  1. タスクバーにアプリのアイコンを表示しない

//  2. メインフォーム非表示(作成していない)

//  3. メッセージを処理するためにウィンドウプロシージャーを置き換える

//  4. タスクトレイにアイコンを登録し[Ctrl]+[A]を検出すと終了する

//=============================================================================

begin

  //メッセージ処理のためにアプリのウィンドウプロシージャーを置き換える

  SetWindowLong(Application.Handle, GWL_WNDPROC, NativeInt(@MainAppProc));


  TrayIconTouroku;

  //終了のメッセージがくるまでループ

  while GetMessage(Msg, 0, 0, 0) do begin

    TranslateMessage(Msg);

    DispatchMessage(Msg);

  end;

  TrayIconOwari;


  MessageDlg('終了です', mtInformation, [mbOK], 0);

  System.Halt(Msg.wParam);

end.

Next Post Previous Post
No Comment
Add Comment
comment url