WindowsのMessengerサービスを使って別のパソコンにメッセージを送る方法。
Windows2000/XPの機能であるMessengerサービスを使えばLANを経由して別のパソコンにメッセージを送りポップアップダイアログを表示することができる。
同じ事はコマンドラインで
net send アドレス メッセージ
を実行することで実現できる。
これと同じことをAPI関数で行うには、NetMessageBufferSendを使う。この関数はWindows2000/XPで使える(Vistaで有効かどうかは知らない)。ただし、あらかじめ送信側でWindowsのMessengerサービスを起動しておく必要がある。
メッセージの送信コードは以下。
/*! @brief WindowsのMessengerサービスを利用してメッセージを送信する @param[in] szAddress 送信先のIPアドレスまたはドメイン名 @param[in] szMessage 送信メッセージ */ void Send(const char* szAddress, const char* szMessage) { WCHAR *address = NULL; WCHAR* msg = NULL; try { int len; //ワイド文字列に変換 len = strlen(szAddress) + 1; address = new WCHAR[len]; MultiByteToWideChar(GetACP(),MB_PRECOMPOSED,szAddress,-1,address,sizeof(WCHAR) * len); len = strlen(szMessage) + 1; msg = new WCHAR[len]; MultiByteToWideChar(GetACP(),MB_PRECOMPOSED,szMessage,-1,msg,sizeof(WCHAR) * len); //送信 NET_API_STATUS Ret = NetMessageBufferSend(NULL,address,NULL,(BYTE *)msg,sizeof(WCHAR) * lstrlenW(msg)); /* Ret の値 NERR_Success 送信成功 ERROR_ACCESS_DENIED ユーザーには、要求した情報へのアクセス権がありません。 ERROR_INVALID_PARAMETER 指定されたパラメータは無効です。 ERROR_NOT_SUPPORTED このネットワークリクエストはサポートされていません。 NERR_NameNotFound ユーザー名が見つかりませんでした。 NERR_NetworkError ネットワークハードウェアの一般的な障害が発生しました。 */ } __finally { //C++Builderの拡張文法。 delete[] address; delete[] msg; } }
ちなみにMessengerサービスの状態を確認するコードは
/*! @brief WindowsのMessengerサービスが使えるかどうかを調べる @retval true 有効 @retval false 無効 */ bool readMessangerServiceStatus(void) { SC_HANDLE scmHandle = ::OpenSCManager( NULL,NULL,SC_MANAGER_ENUMERATE_SERVICE ); if (scmHandle == NULL) { ::GetLastError(); return FALSE; } SC_HANDLE hService = ::OpenService(scmHandle, "Messenger", GENERIC_READ); if (hService == NULL) { ::GetLastError(); ::CloseServiceHandle( scmHandle ); return FALSE; } SERVICE_STATUS status; QueryServiceStatus(hService, &status); ::CloseServiceHandle( hService ); ::CloseServiceHandle( scmHandle ); /* SERVICE_STOPPED: // 停止 SERVICE_START_PENDING: // 起動中 SERVICE_STOP_PENDING: // 停止中 SERVICE_RUNNING: // 実行中 SERVICE_CONTINUE_PENDING: // 継続中 SERVICE_PAUSE_PENDING: // 一時停止中 SERVICE_PAUSED: // 一時停止 */ if (SERVICE_RUNNING == status.dwCurrentState) { return TRUE; } return FALSE; }