開発環境 |
Microsoft Visual C++ 2010 Express (SP1) |
実行環境 |
Microsoft Windows XP Home Edition (SP3) |
プロジェクトの種類 |
Win32 プロジェクト |
プロジェクト名 |
EzTimer |
アプリケーションの種類 |
Windows アプリケーション |
追加のオプション |
空のプロジェクト |
EzTimer.cpp
#pragma comment(lib, "winmm")
#include <stdio.h>
#include <time.h>
#include <Windows.h>
#include <WindowsX.h>
#include "resource.h"
#define SECT L"General"
#define MAKESMSG(st,ch,d1,d2) (st)<<4|(ch)|(d1)<<8|(d2)<<16
#define CH 0
#define NOTE_NO 69
// 関数プロトタイプ宣言
void GetIniFileName();
INT_PTR CALLBACK DlgProc(HWND hDlg, UINT uMsg, WPARAM wParam, LPARAM lParam);
void OnInitDialog(HWND hDlg);
void OnDestroy(HWND hDlg);
void OnTimer(HWND hDlg);
void OnDrawItem(WPARAM wParam, LPARAM lParam);
void OnOK(HWND hDlg);
BOOL GetDlgData(HWND hDlg);
// 外部変数
TCHAR szIniFile[MAX_PATH];
HFONT hFont;
HWND hClock;
HWND hMessage;
TCHAR szMessage[16];
INT_PTR uIDEvent;
HMIDIOUT hmo;
BOOL alarm = FALSE;
BOOL note = FALSE;
int mode;
int alarmH;
int alarmM;
int timerMS;
time_t timer;
time_t base;
int test = BST_UNCHECKED;
int mute = BST_UNCHECKED;
//==============================================================================
int CALLBACK WinMain(HINSTANCE hInstance, HINSTANCE, LPSTR, int)
{
GetIniFileName();
midiOutOpen(&hmo, MIDI_MAPPER, NULL, 0, CALLBACK_NULL);
midiOutShortMsg(hmo, MAKESMSG(0xc, CH, 0, 0)); // Program Change: Piano
DialogBox(hInstance, MAKEINTRESOURCE(IDD_DIALOG), NULL, DlgProc);
midiOutReset(hmo);
midiOutClose(hmo);
return 0;
}
void GetIniFileName()
{
TCHAR szPath [_MAX_PATH];
TCHAR szDrive [_MAX_DRIVE];
TCHAR szDir [_MAX_DIR];
TCHAR szFName [_MAX_FNAME];
TCHAR szExt [_MAX_EXT];
GetModuleFileName(NULL, szPath, _countof(szPath));
_wsplitpath_s(szPath, szDrive, szDir, szFName, szExt);
_wmakepath_s(szIniFile, szDrive, szDir, szFName, L"ini");
}
INT_PTR CALLBACK DlgProc(HWND hDlg, UINT uMsg, WPARAM wParam, LPARAM lParam)
{
INT_PTR res = TRUE; // メッセージを処理した
switch (uMsg) {
case WM_TIMER:
OnTimer(hDlg);
break;
case WM_DRAWITEM:
OnDrawItem(wParam, lParam);
break;
case WM_COMMAND:
switch (LOWORD(wParam)) {
case IDC_TEST:
test = Button_GetCheck(GetDlgItem(hDlg, IDC_TEST));
break;
case IDC_MUTE:
mute = Button_GetCheck(GetDlgItem(hDlg, IDC_MUTE));
break;
case IDOK: // Start
OnOK(hDlg);
break;
case IDCANCEL: // Stop
mode = 0;
alarm = FALSE;
szMessage[0] = L'\0';
InvalidateRect(hMessage, NULL, FALSE);
break;
}
break;
case WM_INITDIALOG:
OnInitDialog(hDlg);
//SetFocus(GetDlgItem(hDlg, IDC_ALARM_H));
//res = FALSE; // SetFocusでフォーカスを設定した場合はFALSE
break;
case WM_CLOSE:
EndDialog(hDlg, 0);
break;
case WM_DESTROY:
OnDestroy(hDlg);
break;
default:
res = FALSE; // メッセージを処理しなかった
}
return res;
}
void OnInitDialog(HWND hDlg)
{
int nX = GetPrivateProfileInt(SECT, L"X", 100, szIniFile);
int nY = GetPrivateProfileInt(SECT, L"Y", 100, szIniFile);
SetWindowPos(hDlg, HWND_TOP, nX, nY, 0, 0, SWP_NOSIZE);
// フォント作成
LOGFONT lf;
ZeroMemory(&lf, sizeof lf);
lf.lfCharSet = DEFAULT_CHARSET;
lf.lfHeight = 60;
wcscpy_s(lf.lfFaceName, L"Arial Black");
hFont = CreateFontIndirect(&lf);
hClock = GetDlgItem(hDlg, IDC_CLOCK);
hMessage = GetDlgItem(hDlg, IDC_MESSAGE);
uIDEvent = SetTimer(hDlg, 1, 1000, NULL);
Button_SetCheck(GetDlgItem(hDlg, IDC_RADIO1), BST_CHECKED);
mode = 0;
time(&timer);
}
void OnDestroy(HWND hDlg)
{
RECT rc;
GetWindowRect(hDlg, &rc);
TCHAR szBuf[16];
swprintf_s(szBuf, L"%d", rc.left);
WritePrivateProfileString(SECT, L"X", szBuf, szIniFile);
swprintf_s(szBuf, L"%d", rc.top);
WritePrivateProfileString(SECT, L"Y", szBuf, szIniFile);
DeleteObject(hFont);
KillTimer(hDlg, uIDEvent);
}
void OnTimer(HWND hDlg)
{
InvalidateRect(hClock, NULL, FALSE);
if (note) {
midiOutShortMsg(hmo, MAKESMSG(0x8, CH, NOTE_NO, 0)); // Note Off
note = FALSE;
}
time(&timer);
alarm = (test == BST_CHECKED);
switch (mode) {
case 1: // Alarm
{
tm tm;
localtime_s(&tm, &timer);
if (tm.tm_hour == alarmH && tm.tm_min == alarmM) {
alarm = TRUE;
}
}
break;
case 2: // Timer
{
int count = int(base - timer);
if (count <= 0) {
count = 0;
alarm = TRUE;
}
swprintf_s(szMessage, L"%d:%02d", count / 60, count % 60);
InvalidateRect(hMessage, NULL, FALSE);
}
break;
case 3: // Stop Watch
{
int count = int(timer - base);
swprintf_s(szMessage, L"%02d:%02d:%02d", count / 3600, (count / 60) % 60, count % 60);
InvalidateRect(hMessage, NULL, FALSE);
}
break;
}
if (alarm && mute == BST_UNCHECKED) {
midiOutShortMsg(hmo, MAKESMSG(0x9, CH, NOTE_NO, 127)); // Note On
note = TRUE;
}
}
void OnDrawItem(WPARAM wParam, LPARAM lParam)
{
LPDRAWITEMSTRUCT pdi = (LPDRAWITEMSTRUCT)lParam;
HDC hdc = pdi->hDC;
SetBkMode(hdc, TRANSPARENT); // 背景透過モード
HGDIOBJ hFontOld = SelectObject(hdc, hFont);
// 背景塗り潰し
RECT rc;
GetClientRect(pdi->hwndItem, &rc);
FillRect(hdc, &rc, GetSysColorBrush(COLOR_WINDOW));
switch (pdi->CtlID) {
case IDC_CLOCK:
tm tm;
localtime_s(&tm, &timer);
TCHAR clock[8+1];
swprintf_s(clock, L"%02d:%02d:%02d", tm.tm_hour, tm.tm_min, tm.tm_sec);
DrawText(hdc, clock, -1, &rc, DT_CENTER | DT_SINGLELINE | DT_VCENTER);
break;
case IDC_MESSAGE:
SetTextColor(hdc, RGB(255,0,0));
DrawText(hdc, szMessage, -1, &rc, DT_CENTER | DT_SINGLELINE | DT_VCENTER);
break;
}
SelectObject(hdc, hFontOld);
}
void OnOK(HWND hDlg)
{
GetDlgData(hDlg);
switch (mode) {
case 1: // Alarm
swprintf_s(szMessage, L"%02d:%02d:00", alarmH, alarmM);
InvalidateRect(hMessage, NULL, FALSE);
break;
case 2: // Timer
base = timer + (timerMS / 100) * 60 + (timerMS % 100);
break;
case 3: // Stop Watch
base = timer;
break;
}
}
BOOL GetDlgData(HWND hDlg)
{
mode = 0;
for (int n = 0; n < 3; n++) {
if (Button_GetCheck(GetDlgItem(hDlg, IDC_RADIO1 + n)) == BST_CHECKED) {
mode = 1 + n;
break;
}
}
BOOL b;
alarmH = GetDlgItemInt(hDlg, IDC_ALARM_H, &b, FALSE);
alarmM = GetDlgItemInt(hDlg, IDC_ALARM_M, &b, FALSE);
timerMS = GetDlgItemInt(hDlg, IDC_TIMER_MS, &b, FALSE);
return TRUE;
}
resource.h
#define IDD_DIALOG 100
#define IDC_STATIC -1
#define IDC_CLOCK 1000
#define IDC_MESSAGE 1001
#define IDC_ALARM_H 1002
#define IDC_ALARM_M 1003
#define IDC_TIMER_MS 1004
//#define IDC_TIMER_S 1005
#define IDC_TEST 1006
#define IDC_MUTE 1007
#define IDC_RADIO1 1101 // Alarm
#define IDC_RADIO2 1102 // Timer
#define IDC_RADIO3 1103 // Stop Watch
EzTimer.rc
// resource script
#include <Windows.h>
#include "resource.h"
IDD_DIALOG DIALOGEX 100, 100, 140, 165
STYLE WS_POPUPWINDOW | WS_MINIMIZEBOX
EXSTYLE WS_EX_APPWINDOW
CAPTION "EzTimer"
FONT 10, "MS Pゴシック"
BEGIN
LTEXT "",IDC_CLOCK,5,5,130,35,WS_BORDER | SS_OWNERDRAW
LTEXT "",IDC_MESSAGE,5,45,130,35,WS_BORDER | SS_OWNERDRAW
CONTROL "Alarm",IDC_RADIO1,"button",BS_AUTORADIOBUTTON | WS_GROUP,5,85,50,15
CONTROL "Timer",IDC_RADIO2,"button",BS_AUTORADIOBUTTON,5,105,50,15
CONTROL "Stop Watch",IDC_RADIO3,"button",BS_AUTORADIOBUTTON,5,125,50,15
EDITTEXT IDC_ALARM_H,70,86,15,13,WS_GROUP
LTEXT "h",IDC_STATIC,90,88,10,15
EDITTEXT IDC_ALARM_M,105,86,15,13
LTEXT "m",IDC_STATIC,125,88,10,15
EDITTEXT IDC_TIMER_MS,70,106,25,13
LTEXT "mmss",IDC_STATIC,100,108,25,15
// EDITTEXT IDC_TIMER_S,105,106,15,13
// LTEXT "s",IDC_STATIC,125,108,10,15
AUTOCHECKBOX "Test",IDC_TEST,5,145,30,15
AUTOCHECKBOX "Mute",IDC_MUTE,35,145,30,15
PUSHBUTTON "Start",IDOK,70,145,30,15
PUSHBUTTON "Stop",IDCANCEL,105,145,30,15
END
最終更新:2013年06月09日 14:59