開発環境 Microsoft Visual C++ 2010 Express (SP1)
実行環境 Microsoft Windows XP Home Edition (SP3)
プロジェクトの種類 Win32 プロジェクト
プロジェクト名 PortChecker
アプリケーションの種類 Windows アプリケーション
追加のオプション 空のプロジェクト
文字セット Unicode

PortChecker.iniの例
[General]
file=D:\etc\morse
params=-l200 "トラ"

PortChecker.cpp
// インポート ライブラリ
#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;
}
 

resource.h
#define IDD_MAIN_DIALOG		100
 
#define IDC_STATIC		-1
#define IDC_EDIT_URL		1000
#define IDC_EDIT_INTERVAL	1001
#define IDC_PROGRESS		1002
#define IDC_LABEL		1003
 

PortChecker.rc
// リソーススクリプト
 
#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
 
最終更新:2013年03月01日 21:45