nanaさん、すいません。
ふと、とても肝心なことを思い出しました。
timeSetEvent は、成功・失敗しか返されず、GetLastError()などでどのようなエラーが発生したのか確認できませんでした。
再度MSDNで確認しました。
http://msdn.microsoft.com/en-us/library ... s.85).aspx
オフトピック
Note This function is obsolete. New applications should use CreateTimerQueueTimer to create a timer-queue timer.
と、書かれてあるように既にこの関数は廃止となっており、CreateTimerQueueTimerを使ってくださいとのことです。
(現状でも使えなくはないですが、何のエラーが起きたのかGetLastError()でエラー情報が取得できません)
オフトピック
あと、timeSetEventは、16個までしかタイマーを作成できないという上限があります。
と、いうことで CreateTimerQueueTimer の使い方を含めたテストコードを載せておくことにします。
それほど違いはありませんので、安心してください。
オフトピック
CreateTimerQueueTimer は、GetLastError()でエラー情報を取得できます。
コード:
#pragma comment(lib, "winmm.lib")
#pragma comment(lib, "ws2_32.lib")
#include <winsock2.h>
#include <stdio.h> // もしくは、#include <iostream> でもOK
void GetErrorMessage(DWORD dwErrorCode)
{
HLOCAL hLocal = NULL;
DWORD systemLocal = MAKELANGID(LANG_NEUTRAL, SUBLANG_NEUTRAL);
BOOL bResult = FormatMessage(FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS | FORMAT_MESSAGE_ALLOCATE_BUFFER, NULL, dwErrorCode, systemLocal, (PTSTR)&hLocal, 0, NULL);
if (!bResult) {
HMODULE hDll = LoadLibraryEx(TEXT("netmsg.dll"), NULL, DONT_RESOLVE_DLL_REFERENCES);
if (hDll != NULL) {
bResult = FormatMessage(FORMAT_MESSAGE_FROM_HMODULE | FORMAT_MESSAGE_IGNORE_INSERTS | FORMAT_MESSAGE_ALLOCATE_BUFFER, hDll, dwErrorCode, systemLocal, (PTSTR)&hLocal, 0, NULL);
FreeLibrary(hDll);
}
}
if (bResult && (hLocal != NULL)) {
fprintf(stderr, TEXT("ErrorCode: %d\r\n%s\r\n"), dwErrorCode, (PTCHAR)LocalLock(hLocal));
LocalFree(hLocal);
}
else {
fprintf(stderr, TEXT("No text found for this error code\r\n"));
}
}
//void CALLBACK Send_loop(UINT timerID, UINT uMsg, DWORD dwUser, DWORD dw1, DWORD dw2) {
// fprintf(stdout, "送信しました。\n");
//}
void CALLBACK Send_loop(PVOID pvContext, BOOLEAN fTimeout) {
fprintf(stdout, "送信しました。\n");
}
int main() {
//例えば、WSAEPROTOTYPE (10041) をセット (※仮にこのエラーが起きたとします)
//http://support.microsoft.com/kb/819124/ja を参照のこと
SetLastError(WSAEPROTOTYPE);
//対応する以下のエラーメッセージを表示
//ソケットの関数呼び出しでプロトコルが指定されましたが、要求したソケットの種類の形式をサポートしていません。
GetErrorMessage(GetLastError());
fprintf(stdout, "\nEnterキーを押下すると次に用意しているtimeSetEventの処理へ進みます。\n");
getchar(); // Enterキーを押下すると次へ進む(注:押下するまでは進みません)
//ここから上は GetErrorMessage のテストコード
//------------------------------------------------------------------------------------
//ここから下は GetErrorMessage の入れる位置の説明です。
//MMRESULT timerID;
//timerID = timeSetEvent(-3, 1, (LPTIMECALLBACK)Send_loop, (DWORD)NULL, TIME_PERIODIC);
HANDLE hTimerQTimer; //もしスコープを外れるようでしたら、staticを付けて static HANDLE hTimerQTimer; としてあげてください。
HANDLE hTimerQ = CreateTimerQueue(); //もしスコープを外れるようでしたら、staticを付けて static HANDLE hTimerQTimer; としてあげてください。
BOOL ret = CreateTimerQueueTimer(&hTimerQTimer, hTimerQ, Send_loop, NULL, 0, 1000, 0);
if (!ret)
{
//ここで使います。基本的には timeSetEventなどのWindows APIを呼び出した直後です。
//GetLastError()というのは直前に実行されたWindows APIの終了コードを返します。
//そのため、他のWindows APIを呼び出すと上書きされてしまうので、
//必ずWindows APIを呼んだ直後に(エラー処理の中で)使用します。
GetErrorMessage(GetLastError());
fprintf(stderr, "タイマー登録に失敗\n");
fprintf(stdout, "\nもう一度Enterキーを押下するとプログラムを終了します。\n");
getchar(); // Enterキーを押下で終了
exit(1);
}
fprintf(stdout, "もう一度Enterキーを押下するとプログラムを終了します。\n");
getchar(); // Enterキーを押下で終了
//timeKillEvent(timerID);
ret = DeleteTimerQueueTimer(hTimerQ, hTimerQTimer, NULL);
if (!ret)
{
GetErrorMessage(GetLastError());
fprintf(stdout, "\nもう一度Enterキーを押下するとプログラムを終了します。\n");
getchar(); // Enterキーを押下で終了
exit(1);
}
return 0;
}
古いAPI なので、ほんと肝心なことを忘れてしまってました。
申し訳ないです。