4/7
Window Messageについて
WindowsはイベントドリブンのOSであり、生じたイベントはウィンドウ メッセージとしてやりとりされる。
イベントは、マウスのクリック、キー操作、タッチスクリーンでのジェスチャーなど目に見えるもののほか、ウィンドウの作成、初期化、終了など内部動作に関わるものまで様々なものがある。
プログラムは、このようなイベントを受け取って、適時必要な動作をすることで、動作をしている。
メッセージはUNIT型すなわちunsigned intであり、Win32(ILP32)およびWin64(LLP64)ともに32ビットである。
元々Win16だった頃の影響を受けており、範囲は次のように16ビット範囲内で概ね定められている。
0x0000 | 〜 | WM_USER-1 | システム用 |
WM_USER(0x0400) | 〜 | WM_APP-1 | プライベートウィンドウクラス用 |
WM_APP (0x8000) | 〜 | 0xBFFF | アプリケーション用整数メッセージ |
0xC000 | 〜 | 0xFFFF | RegisterWindowMessage() 文字列メッセージ |
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.