
C ++で小さなユーティリティを一緒に書きましょう。 プログラムでシステム内の何かを監視し、何かが起こったときに通知領域にアイコンを表示させます。 たとえば、チェックはファイルまたはマップされたドライブに対して行われます。 ファイルはありません-アイコンが1つ、ファイルが1つ表示されました-アイコンが変更されました。
このようなアイコンは、暗号化されたドライブの接続を監視します。 たぶん、エラーが発生したり、ネットワークドライブへの接続が存在するプロトコルファイルの外観を監視する必要があります。
開発には、無料のVisual C ++ Express Editionを使用できます。
新しいWin32プロジェクトの作成を選択し、プロジェクトに「Tray」という名前を付けます。 [次へ]ボタンを使用して、プロジェクト設定に移動し、[空のプロジェクト]ボックスをオンにします。
挨拶から始めましょう
C ++ファイル(.cpp)をプロジェクトに追加し、「Tray」という名前を付けます。 このような最小限のプログラムから始めましょう。 テキストを入力して実行してみてください。
#include <windows.h> #include <tchar.h> // int APIENTRY _tWinMain(HINSTANCE instance, HINSTANCE, LPTSTR, int) { MessageBox(0, TEXT(""), TEXT(""), 0); return 0; }
MessageBox()を呼び出すと挨拶が表示され、プログラムは終了します。 成功したら、先に進みます。
メインウィンドウ
基本的にウィンドウは必要ありません。メインのユーザーインターフェイスはアイコンです。 ただし、アイコンを作成してメッセージを処理するにはウィンドウが必要です。
ウィンドウを作成するには、メッセージ処理関数WndProc()を定義し、ウィンドウクラスをWNDCLASSEX構造体に登録し、CreateWindowEx()関数で実際にウィンドウを作成する必要があります。
#include <windows.h> #include <tchar.h> // LRESULT CALLBACK WndProc(HWND window, UINT message, WPARAM wParam, LPARAM lParam) { switch (message) { // case WM_DESTROY: PostQuitMessage(0); break; default: return DefWindowProc(window, message, wParam, lParam); } return 0; } // int APIENTRY _tWinMain(HINSTANCE instance, HINSTANCE, LPTSTR, int) { // WNDCLASSEX main = { 0 }; main.cbSize = sizeof(WNDCLASSEX); main.hInstance = instance; main.lpszClassName = TEXT("Main"); main.lpfnWndProc = WndProc; RegisterClassEx(&main); // HWND window = CreateWindowEx(0, TEXT("Main"), NULL, 0, 0, 0, 0, 0, NULL, NULL, instance, NULL); MessageBox(0, TEXT(""), TEXT(""), 0); return 0; }
メインウィンドウは表示されないため、すべてのパラメーターが最小限になります。 プログラムを実行してみてください-その仕事で何も変わっていません。
アイコン出力
アイコンの実際の出力は、Shell_NotifyIcon()関数によって実行されます。 彼女はパラメータとしてNOTIFYICONDATA構造を必要とし、このウィンドウにはウィンドウへのハンドルが必要です。
NOTIFYICONDATA構造体をグローバル変数Iconに保存します。 まだ有用です。 ウェルカムウィンドウの前にアイコンを作成し、プログラムを終了する前にアイコンを削除します。
#include <windows.h> #include <tchar.h> // NOTIFYICONDATA Icon = { 0 }; // // ... // int APIENTRY _tWinMain(HINSTANCE instance, HINSTANCE, LPTSTR, int) { // ... // ... // Icon.cbSize = sizeof(NOTIFYICONDATA); Icon.hWnd = window; Icon.uVersion = NOTIFYICON_VERSION; Icon.uCallbackMessage = WM_USER; Icon.hIcon = LoadIcon(NULL, IDI_SHIELD); Icon.uFlags = NIF_MESSAGE | NIF_ICON; Shell_NotifyIcon(NIM_ADD, &Icon); MessageBox(0, TEXT(""), TEXT(""), 0); // Shell_NotifyIcon(NIM_DELETE, &Icon); return 0; }
次に、実行するプログラムを実行します。 アイコンは起動時に表示され、ダイアログボックスで[OK]をクリックすると消えます。 アイコンの外観は、hIconパラメーターで指定されます。 LoadIcon()関数を使用して、標準のIDI_SHIELDアイコンをそこに配置します。
メッセージ処理サイクル
ようこそダイアログを削除します。 プログラムを起動すると、通知領域にアイコンのみが表示されます。 アイコンを右クリックしてプログラムを終了します。 プログラムの完了について尋ねるウィンドウが表示されます。
マウスボタンがクリックされたアイコンからメッセージ処理機能にメッセージ処理を追加します。 グリーティングがあった場所にメッセージ処理ループを挿入します。
... // LRESULT CALLBACK WndProc(HWND window, UINT message, WPARAM wParam, LPARAM lParam) { switch (message) { // case WM_USER: if (lParam == WM_RBUTTONDOWN) if (MessageBox(NULL, TEXT(" ?"), TEXT("Tray"), MB_YESNO) == IDYES) DestroyWindow(window); break; // ... } return 0; } // int APIENTRY _tWinMain(HINSTANCE instance, HINSTANCE, LPTSTR, int) { // ... // ... // ... // MSG message; while (GetMessage(&message, NULL, 0, 0)) { TranslateMessage(&message); DispatchMessage(&message); } // Shell_NotifyIcon(NIM_DELETE, &Icon); return 0; }
起動後、プログラムはアイコンのみを表示し、マウスのクリックを待ちます。
タイマーチェック
今では、すべてが開始されたために何をするかが残っています。 1秒に1回、ファイルチェックが実行されます。 そのようなファイルが表示される場合、アイコンが変更されます。 タイマーはSetTimer()関数によって有効になります。この関数の時間間隔はミリ秒単位で指定する必要があります。
ファイル自体の存在をチェックする機能は、さまざまな方法で実装できます。 属性を取得して確認する方法を次に示します。
/ bool FileExists(PTSTR path) { return GetFileAttributes(path) != INVALID_FILE_ATTRIBUTES; }
GetFileAttributes()関数が指定されたパスのファイル属性を読み取れない場合、ファイルは存在しません。 パスとして、ファイルへのパスを指定し、ファイルの存在を確認します。 また、ディスクへのパスを設定すると、ディスクの可用性が確認されます。 「P:」ドライブの存在を確認するとします。
毎回アイコンを再描画しないように、グローバル変数で以前の状態を保存し、状態が変更された場合にのみ新しい画像でShell_NotifyIcon()を呼び出します。 これがプログラムのフルバージョンです。
#include <windows.h> #include <tchar.h> // NOTIFYICONDATA Icon = { 0 }; // bool State = false; // // bool FileExists(PTSTR path) { return GetFileAttributes(path) != INVALID_FILE_ATTRIBUTES; } // LRESULT CALLBACK WndProc(HWND window, UINT message, WPARAM wParam, LPARAM lParam) { switch (message) { // case WM_TIMER: { bool check = FileExists(TEXT("P:\\")); if (State != check) { if (State) Icon.hIcon = LoadIcon(NULL, IDI_SHIELD); else Icon.hIcon = LoadIcon(NULL, IDI_WARNING); Icon.uFlags = NIF_ICON; Shell_NotifyIcon(NIM_MODIFY, &Icon); State = check; } break; } // case WM_USER: if (lParam == WM_RBUTTONDOWN) if (MessageBox(NULL, TEXT(" ?"), TEXT("Tray"), MB_YESNO) == IDYES) DestroyWindow(window); break; // case WM_DESTROY: PostQuitMessage(0); break; default: return DefWindowProc(window, message, wParam, lParam); } return 0; } // int APIENTRY _tWinMain(HINSTANCE instance, HINSTANCE, LPTSTR, int) { // WNDCLASSEX main = { 0 }; main.cbSize = sizeof(WNDCLASSEX); main.hInstance = instance; main.lpszClassName = TEXT("Main"); main.lpfnWndProc = WndProc; RegisterClassEx(&main); // HWND window = CreateWindowEx(0, TEXT("Main"), NULL, 0, 0, 0, 0, 0, NULL, NULL, instance, NULL); // Icon.cbSize = sizeof(NOTIFYICONDATA); Icon.hWnd = window; Icon.uVersion = NOTIFYICON_VERSION; Icon.uCallbackMessage = WM_USER; Icon.hIcon = LoadIcon(NULL, IDI_SHIELD); Icon.uFlags = NIF_MESSAGE | NIF_ICON; Shell_NotifyIcon(NIM_ADD, &Icon); // SetTimer(window, 0, 1000, NULL); // MSG message; while (GetMessage(&message, NULL, 0, 0)) { TranslateMessage(&message); DispatchMessage(&message); } // Shell_NotifyIcon(NIM_DELETE, &Icon); return 0; }
リリースの構成では、プログラムTray.exeのサイズは8 KBでした。