// インポート ライブラリ
#pragma comment(lib, "ws2_32.lib")
#include <tchar.h>
#include <WinSock2.h>
#include <Windows.h>
#include <CommCtrl.h>
#include "resource.h"
#define SAFE_FREE(p) if (p) { free((void*)p); p = NULL; }
#define SEC_GEN _T("General")
// 関数プロトタイプ宣言
int GetIniFileName(void);
INT_PTR CALLBACK DialogProc(HWND hDlg, UINT uMsg, WPARAM wParam, LPARAM lParam);
void OnInitDialog(HWND hDlg);
void OnDestroy(HWND hDlg);
void WriteIniFileInt(TCHAR* ptcSec, TCHAR* ptcKey, int iValue);
void OnTimer(HWND hDlg);
void OnOK(HWND hDlg);
void StopTimer(HWND hDlg);
void EnableCtrl(HWND hDlg, BOOL bEnable);
int CheckPort(void);
// グローバル変数
TCHAR g_atcIniFile[_MAX_PATH] = _T("");
HWND g_hProgress;
HWND g_hLabel;
HBRUSH g_hBrush;
UINT g_uiIDEvent = 0;
char g_acHost[256];
int g_iPort;
int g_iInterval;
int g_iTimer;
LPCTSTR lpFile = NULL;
LPCTSTR lpParams = NULL;
//==============================================================================
int APIENTRY _tWinMain(
HINSTANCE hInstance,
HINSTANCE hPrevInstance,
LPTSTR lpCmdLine,
int nCmdShow)
{
WSADATA wsaData;
int iRet;
// WinSockDLLの初期化
iRet = WSAStartup(MAKEWORD(2, 2), &wsaData);
if (iRet != 0) {
return 0;
}
if (GetIniFileName()) {
return 0;
}
DialogBox(hInstance, MAKEINTRESOURCE(IDD_MAIN_DIALOG), NULL, DialogProc);
WSACleanup();
return 0;
}
//------------------------------------------------------------------------------
int GetIniFileName(void)
{
TCHAR atcPath [_MAX_PATH];
TCHAR atcDrive[_MAX_DRIVE];
TCHAR atcDir [_MAX_DIR];
TCHAR atcFName[_MAX_FNAME];
TCHAR atcExt [_MAX_EXT];
if (GetModuleFileName(NULL, atcPath, _countof(atcPath)) == 0) {
return -1;
}
if (_tsplitpath_s(atcPath, atcDrive, atcDir, atcFName, atcExt) != 0) {
return -1;
}
if (_tmakepath_s(g_atcIniFile, atcDrive, atcDir, atcFName, _T("ini")) != 0) {
return -1;
}
return 0;
}
//------------------------------------------------------------------------------
INT_PTR CALLBACK DialogProc(HWND hDlg, UINT uMsg, WPARAM wParam, LPARAM lParam)
{
INT_PTR iRetVal = TRUE; // メッセージを処理した
switch (uMsg) {
case WM_TIMER:
OnTimer(hDlg);
break;
case WM_CTLCOLORSTATIC:
iRetVal = FALSE;
if ((HWND)lParam == g_hLabel) {
iRetVal = (INT_PTR)g_hBrush;
}
break;
case WM_COMMAND:
switch (LOWORD(wParam)) {
case IDOK:
OnOK(hDlg);
break;
case IDCANCEL:
// タイマー停止
StopTimer(hDlg);
break;
}
break;
case WM_INITDIALOG:
OnInitDialog(hDlg);
SetFocus(GetDlgItem(hDlg, IDOK));
iRetVal = FALSE; // SetFocusでフォーカスを設定した場合はFALSE
break;
case WM_CLOSE:
// タイマー停止
StopTimer(hDlg);
EndDialog(hDlg, 0);
break;
case WM_DESTROY:
OnDestroy(hDlg);
break;
default:
iRetVal = FALSE; // メッセージを処理しなかった
}
return iRetVal;
}
//------------------------------------------------------------------------------
void OnInitDialog(HWND hDlg)
{
TCHAR atcStr[256];
int iX;
int iY;
iX = GetPrivateProfileInt(SEC_GEN, _T("iX"), 0, g_atcIniFile);
iY = GetPrivateProfileInt(SEC_GEN, _T("iY"), 0, g_atcIniFile);
SetWindowPos(hDlg, HWND_TOP, iX, iY, 0, 0, SWP_NOSIZE);
GetPrivateProfileString(SEC_GEN, _T("url"), _T(""),
atcStr, _countof(atcStr), g_atcIniFile);
SetDlgItemText(hDlg, IDC_EDIT_URL, atcStr);
g_iInterval = GetPrivateProfileInt(SEC_GEN, _T("iInterval"), 0, g_atcIniFile);
_stprintf_s(atcStr, _T("%d"), g_iInterval);
SetDlgItemText(hDlg, IDC_EDIT_INTERVAL, atcStr);
GetPrivateProfileString(SEC_GEN, _T("file"), _T(""), atcStr, _countof(atcStr), g_atcIniFile);
lpFile = _tcsdup(atcStr);
GetPrivateProfileString(SEC_GEN, _T("params"), _T(""), atcStr, _countof(atcStr), g_atcIniFile);
lpParams = _tcsdup(atcStr);
g_hProgress = GetDlgItem(hDlg, IDC_PROGRESS);
g_hLabel = GetDlgItem(hDlg, IDC_LABEL);
g_hBrush = CreateSolidBrush(RGB(0xFF,0x00,0x00));
ShowWindow(g_hLabel, SW_HIDE);
}
//------------------------------------------------------------------------------
void OnDestroy(HWND hDlg)
{
RECT rc;
TCHAR atcStr[256];
GetWindowRect(hDlg, &rc);
WriteIniFileInt(SEC_GEN, _T("iX"), rc.left);
WriteIniFileInt(SEC_GEN, _T("iY"), rc.top);
GetDlgItemText(hDlg, IDC_EDIT_URL, atcStr, _countof(atcStr));
WritePrivateProfileString(SEC_GEN, _T("url"), atcStr, g_atcIniFile);
WriteIniFileInt(SEC_GEN, _T("iInterval"), g_iInterval);
SAFE_FREE(lpFile);
SAFE_FREE(lpParams);
DeleteObject(g_hBrush);
}
//------------------------------------------------------------------------------
void WriteIniFileInt(TCHAR* ptcSec, TCHAR* ptcKey, int iValue)
{
TCHAR atcBuf[16];
_stprintf_s(atcBuf, _T("%d"), iValue);
WritePrivateProfileString(ptcSec, ptcKey, atcBuf, g_atcIniFile);
}
//------------------------------------------------------------------------------
void OnTimer(HWND hDlg)
{
int iRet;
// タイマーを1減らす
g_iTimer--;
SendMessage(g_hProgress, PBM_SETPOS, g_iTimer, 0);
ShowWindow(g_hLabel, (g_iTimer & 1) ? SW_SHOWNA : SW_HIDE);
if (0 < g_iTimer) {
return;
}
// タイマーが0になったら処理を行う
iRet = CheckPort();
if (iRet < 0) {
StopTimer(hDlg);
MessageBox(hDlg, _T("IPアドレスの取得に失敗しました"), NULL, MB_OK);
return;
}
if (0 < iRet) {
StopTimer(hDlg);
ShellExecute(hDlg, NULL, lpFile, lpParams, NULL, SW_SHOWNORMAL);
MessageBox(hDlg, _T("サーバーへの接続に成功しました"), _T("通知"), MB_OK);
return;
}
g_iTimer = g_iInterval;
// SendMessage(g_hProgress, PBM_SETPOS, g_iTimer, 0);
}
//------------------------------------------------------------------------------
void OnOK(HWND hDlg)
{
TCHAR atcStr[256];
TCHAR* ptcHost;
TCHAR* ptcPort;
TCHAR* ptc;
size_t size;
// インターバル秒数の取得
GetDlgItemText(hDlg, IDC_EDIT_INTERVAL, atcStr, _countof(atcStr));
g_iInterval = _tstoi(atcStr);
// URL
GetDlgItemText(hDlg, IDC_EDIT_URL, atcStr, _countof(atcStr));
// ホスト
ptc = _tcsstr(atcStr, _T("://"));
if (ptc == NULL) {
ptcHost = atcStr;
} else {
ptcHost = ptc + 3;
ptc[2] = _T('\0');
}
// ポート
ptc = _tcspbrk(ptcHost, _T(": "));
if (ptc == NULL) {
MessageBox(hDlg, _T("ポート番号がありません"), NULL, MB_OK);
return;
} else {
ptc[0] = _T('\0');
ptcPort = ptc + 1;
}
wcstombs_s(&size, g_acHost, ptcHost, 256);
g_iPort = _tstoi(ptcPort);
// コントロール無効化
EnableCtrl(hDlg, FALSE);
// タイマー発行
g_uiIDEvent = SetTimer(hDlg, 1, 1000, NULL);
g_iTimer = 1;
SendMessage(g_hProgress, PBM_SETRANGE, 0, MAKELPARAM(0, g_iInterval));
SendMessage(g_hProgress, PBM_SETPOS, g_iTimer, 0);
}
//------------------------------------------------------------------------------
// タイマー停止
void StopTimer(HWND hDlg)
{
if (g_uiIDEvent != 0) {
KillTimer(hDlg, g_uiIDEvent);
g_uiIDEvent = 0;
}
SendMessage(g_hProgress, PBM_SETPOS, 0, 0);
ShowWindow(g_hLabel, SW_HIDE);
// コントロール有効化
EnableCtrl(hDlg, TRUE);
}
void EnableCtrl(HWND hDlg, BOOL bEnable)
{
EnableWindow(GetDlgItem(hDlg, IDC_EDIT_URL), bEnable);
EnableWindow(GetDlgItem(hDlg, IDC_EDIT_INTERVAL), bEnable);
EnableWindow(GetDlgItem(hDlg, IDOK), bEnable);
}
//------------------------------------------------------------------------------
int CheckPort(void)
{
HOSTENT* phe;
SOCKADDR_IN name;
SOCKET sock = INVALID_SOCKET;
int iFlgConnect = 0;
int iRet;
// IPアドレスの取得
phe = gethostbyname(g_acHost);
if (phe == NULL) {
return -1;
}
// サーバーに接続
sock = socket(AF_INET, SOCK_STREAM, 0);
name.sin_family = AF_INET;
name.sin_port = htons(g_iPort);
name.sin_addr = *((IN_ADDR*)phe->h_addr);
iRet = connect(sock, (SOCKADDR*)&name, sizeof name);
if (iRet != 0) {
goto Exit;
}
iFlgConnect = 1;
Exit:
if (iFlgConnect) {
shutdown(sock, SD_BOTH);
}
if (sock != INVALID_SOCKET) {
closesocket(sock);
}
return iFlgConnect;
}
// リソーススクリプト
#include <windows.h>
#include "resource.h"
IDD_MAIN_DIALOG DIALOGEX 0, 0, 240, 100
STYLE WS_POPUPWINDOW | WS_MINIMIZEBOX
EXSTYLE WS_EX_APPWINDOW
CAPTION "Port Checker"
FONT 9, "MS Pゴシック"
BEGIN
LTEXT "URL(&U):",IDC_STATIC,8,8,32,12
EDITTEXT IDC_EDIT_URL,40,8,192,12,ES_AUTOHSCROLL
LTEXT "間隔(&I):",IDC_STATIC,8,28,32,12
EDITTEXT IDC_EDIT_INTERVAL,40,28,24,12
LTEXT "秒",IDC_STATIC,68,28,12,12
LTEXT "http://host:port\nhost port",IDC_STATIC,100,24,100,24
CONTROL "",IDC_PROGRESS,"msctls_progress32",WS_BORDER,8,48,224,12
LTEXT "",IDC_LABEL,8,68,32,12
DEFPUSHBUTTON "開始(&S)",IDOK,132,76,48,16
PUSHBUTTON "中止(&C)",IDCANCEL,184,76,48,16
END