左のようなダイアログボックスが表示されます。
これに適当な入力を行いOKボタンを押すと
左のようなメッセージボックスが表示されます。
ただそれだけです。
今回のプログラムでは使わないコントロールを削除しました。
ヘッダーファイルもいらないIDの定義は削除しておきましょう。
オプションで「時刻」か「日付」かを選んでこれを
表示させるようにします。
プログラムの修正は簡単です。
一番手っ取り早い方法は、GetTimeStr関数に
日付か時刻表示を指定する引数を持たせて
time_strにその指定の文字列をコピーするだけですね。
では、呼び出し側も修正しましょう。ウィンドウプロシージャの中の WM_TIMERの所をほんの少し書き直すだけです。int GetTimeStr(int sw) { char *str_org1 = "%2d時%2d分%2d秒"; char *str_org2 = "%2d年%2d月%2d日"; time_t long_time; struct tm *now_time; time(&long_time); now_time = localtime(&long_time); switch (sw) { case 1: sprintf(time_str, str_org1, now_time->tm_hour, now_time->tm_min, now_time->tm_sec); break; case 0: sprintf(time_str, str_org2, now_time->tm_year, now_time->tm_mon + 1, now_time->tm_mday); break; default: MessageBox(NULL, (LPCSTR)"エラーです", (LPCSTR)"エラー", MB_OK); return (-1); } return 0; }
あとは、GetTimeStr関数のプロトタイプを直すのと、不要な変数の削除だけです。case WM_TIMER: GetTimeStr(radio1); SetWindowText(hWnd, (LPCSTR)time_str); break;
オプションで、「日付」を選択すると次のようになります。// timer.cpp #include <windows.h> #include <time.h> #include <stdio.h> #include "timer.h" LRESULT CALLBACK WndProc(HWND, UINT, WPARAM, LPARAM); LRESULT CALLBACK MyDlgProc(HWND, UINT, WPARAM, LPARAM); BOOL InitApp(HINSTANCE, LPCSTR); BOOL InitInstance(HINSTANCE, LPCSTR, int); int GetTimeStr(int); int SetWinCenter(HWND); HINSTANCE hInst1; char time_str[64]; int radio1 = 1; int radio2 = 0; //ラジオボタンが押されているかどうか int WINAPI WinMain(HINSTANCE hCurInst, HINSTANCE hPrevInst, LPSTR lpsCmdLine, int nCmdShow) { MSG msg; char szClassName[] = "timer"; //ウィンドウクラス hInst1 = hCurInst; if (!hPrevInst) { if (!InitApp(hCurInst, szClassName)) return FALSE; } if (!InitInstance(hCurInst, szClassName, nCmdShow)) { return FALSE; } while (GetMessage(&msg, NULL, 0, 0)) { TranslateMessage(&msg); DispatchMessage(&msg); } return msg.wParam; } //ウィンドウ・クラスの登録 BOOL InitApp(HINSTANCE hInst, LPCSTR szClassName) { WNDCLASS wc; wc.style = CS_HREDRAW | CS_VREDRAW; wc.lpfnWndProc = WndProc; //プロシージャ名 wc.cbClsExtra = 0; wc.cbWndExtra = 0; wc.hInstance = hInst; //インスタンス wc.hIcon = LoadIcon(NULL, IDI_APPLICATION); wc.hCursor = LoadCursor(NULL, IDC_ARROW); wc.hbrBackground = GetStockObject(WHITE_BRUSH); wc.lpszMenuName = NULL/*"TIMERMENU"*/; //メニュー名 wc.lpszClassName = (LPCSTR)szClassName; return (RegisterClass(&wc)); } //ウィンドウの生成 BOOL InitInstance(HINSTANCE hInst, LPCSTR szClassName, int nCmdShow) { HWND hWnd; HMENU hMenu; int i; hWnd = CreateWindow(szClassName, NULL, //タイトルバーにこの名前が表示されます WS_CAPTION | WS_SYSMENU, //ウィンドウの種類 9999, //X座標 9999, //Y座標 0, //幅 0, //高さ NULL, //親ウィンドウのハンドル、親を作るときはNULL NULL, //メニューハンドル、クラスメニューを使うときはNULL hInst, //インスタンスハンドル NULL); if (!hWnd) return FALSE; ShowWindow(hWnd, SW_MINIMIZE); UpdateWindow(hWnd); hMenu = GetSystemMenu(hWnd, FALSE); for (i = 0; i <= 5; i++) DeleteMenu(hMenu, 0, MF_BYPOSITION); AppendMenu(hMenu, MF_STRING, IDM_OPTION, "オプション"); DrawMenuBar(hWnd); return TRUE; } //ウィンドウプロシージャ LRESULT CALLBACK WndProc(HWND hWnd, UINT msg, WPARAM wp, LPARAM lp) { int id; switch (msg) { case WM_SYSCOMMAND: switch (wp) { case IDM_OPTION: DialogBox(hInst1, "OPTDLG", hWnd, (DLGPROC)MyDlgProc); break; default: return(DefWindowProc(hWnd, msg, wp, lp)); break; } break; case WM_CREATE: if(SetTimer(hWnd, ID_MYTIMER, 1000, NULL) == 0) { MessageBox(hWnd, (LPCSTR)"タイマー失敗!", (LPCSTR)"失敗", MB_OK | MB_ICONEXCLAMATION); } break; case WM_TIMER: GetTimeStr(radio1); SetWindowText(hWnd, (LPCSTR)time_str); break; case WM_CLOSE: id = MessageBox(hWnd, (LPCSTR)"終了してもよいですか", (LPCSTR)"終了確認", MB_YESNO | MB_ICONQUESTION); if (id == IDYES) { if(KillTimer(hWnd, ID_MYTIMER) == TRUE) { MessageBox(hWnd, (LPCSTR)"タイマーを殺しました!", (LPCSTR)"タイマー削除の成功", MB_OK | MB_ICONEXCLAMATION); } DestroyWindow(hWnd); } break; case WM_DESTROY: PostQuitMessage(0); break; default: return (DefWindowProc(hWnd, msg, wp, lp)); } return 0L; } int GetTimeStr(int sw) { char *str_org1 = "%2d時%2d分%2d秒"; char *str_org2 = "%2d年%2d月%2d日"; time_t long_time; struct tm *now_time; time(&long_time); now_time = localtime(&long_time); switch (sw) { case 1: sprintf(time_str, str_org1, now_time->tm_hour, now_time->tm_min, now_time->tm_sec); break; case 0: sprintf(time_str, str_org2, now_time->tm_year, now_time->tm_mon + 1, now_time->tm_mday); break; default: MessageBox(NULL, (LPCSTR)"エラーです", (LPCSTR)"エラー", MB_OK); return (-1); } return 0; } //ダイアログプロシージャ LRESULT CALLBACK MyDlgProc(HWND hDlgWnd, UINT msg, WPARAM wp, LPARAM lp) { switch (msg) { case WM_INITDIALOG: SendMessage(GetDlgItem(hDlgWnd, IDC_RADIO1), BM_SETCHECK, (WPARAM)radio1, 0L); SendMessage(GetDlgItem(hDlgWnd, IDC_RADIO2), BM_SETCHECK, (WPARAM)radio2, 0L); SetWinCenter(hDlgWnd); return TRUE; case WM_COMMAND: switch (LOWORD(wp)) { case IDOK: if(IsDlgButtonChecked(hDlgWnd, IDC_RADIO1) == BST_CHECKED) { radio1 = 1; } else { radio1 = 0;} if(IsDlgButtonChecked(hDlgWnd, IDC_RADIO2) == BST_CHECKED) { radio2 = 1; } else { radio2 = 0;} EndDialog(hDlgWnd, IDOK); break; case IDCANCEL: EndDialog(hDlgWnd, IDCANCEL); break; default: return FALSE; } default: return FALSE; } return TRUE; } int SetWinCenter(HWND hWnd) { HWND hDeskWnd; RECT deskrc, rc; int x, y; hDeskWnd = GetDesktopWindow(); GetWindowRect(hDeskWnd, (LPRECT)&deskrc); GetWindowRect(hWnd, (LPRECT)&rc); x = (deskrc.right - (rc.right-rc.left)) / 2; y = (deskrc.bottom - (rc.bottom-rc.top)) / 2; SetWindowPos(hWnd, HWND_TOP, x, y, (rc.right-rc.left), (rc.bottom-rc.top),SWP_SHOWWINDOW); return 0; }
これで、一応「timer.exe」の完成とします。不満な点はまだいくつもあります。
「日付」を表示している間1秒に1回表示し直す必要があるのか?
いったん終了すると、次回起動時は必ず時刻表示になっている。
重複起動してしまう・・などなどです。これらの不満点を解決してみて下さい。
Update Apr/09/1997 By Y.Kumei