メイン | 2006年12月 »

1  2  3  4

2006年11月 記事一覧

2006年11月23日

WAVファイルを再生する

wavファイルを再生したいときはPlaySound()を利用する。

#include "mmsystem.h"

#pragma	comment(lib,"winmm.lib")

void	Test(void)
{
	::PlaySound(_T("C:\\WINDOWS\\Media\\chimes.wav"),NULL,SND_FILENAME | SND_ASYNC); 
}

プロジェクトファイルをダウンロード

マウスカーソルを動かす

マウスカーソルを動かすにはmouse_eventを使う。この関数は引数として使う座標値がスクリーン座標ではないので、GetSystemMetricsで変換して渡す。
Test用の関数を実行すると現在位置から右斜め下に向かってマウスカーソルが勝手に移動する。

//
//	マウスカーソル移動関数
//
void	MoveMouse(UINT nX,UINT nY)
{
	DWORD	dwX;
	DWORD	dwY;

	//スクリーン座標をmouse_event()用の座標に変換
	dwX = nX * 65535 / ::GetSystemMetrics(SM_CXSCREEN);
	dwY = nY * 65535 / ::GetSystemMetrics(SM_CYSCREEN);

	//マウスカーソルを移動
	::mouse_event(MOUSEEVENTF_ABSOLUTE | MOUSEEVENTF_MOVE,dwX,dwY,NULL,NULL);
}


void	Test(void)
{
	int		i;
	POINT	pt;

	//現在のマウスカーソル位置取得
	::GetCursorPos(&pt);

	for(i = 0; i < 30; i++)
	{
		//マウス位置を右斜め下にちょっとずらす
		pt.x += 10;
		pt.y += 10;

		//マウスカーソルを移動
		MoveMouse(pt.x,pt.y);

		//50ミリ秒待機
		::Sleep(50);
	}
}

プロジェクトファイルをダウンロード

ファイルの存在を確認する

指定したファイルがあるかどうかを調べるにはCreateFileを使ってファイルにアクセスできるかどうかを調べる方法と、今回使っているFindFirstFileで検索できるかどうかを使う方法がある。
FindFirstFileの場合は少し改良すればフォルダの存在確認にも使えるので便利だ。

//
//	ファイルの存在を確認する
//
bool	IsFileExist(LPCTSTR pszFile)
{
	HANDLE			hFind;
	WIN32_FIND_DATA	FindFileData;

	hFind = ::FindFirstFile(pszFile,&FindFileData);
	if(hFind == INVALID_HANDLE_VALUE)
		return	false;
	::FindClose(hFind);
	if(FindFileData.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY)
		return	false;		//同名のフォルダがある(ファイルではない)

	return	true;
}

void	Test(void)
{
	bool	ret;

	ret = IsFileExist(_T("c:\\IO.SYS"));

	if(ret)
		::MessageBox(NULL,_T("ファイルは存在します"),_T(""),MB_OK);
	else
		::MessageBox(NULL,_T("ファイルは存在しません"),_T(""),MB_OK);
}

プロジェクトファイルをダウンロード

ファイルがショートカットやリンクかどうかを調べる

指定されたパスがショートカットファイルやリンクファイルかどうかを調べる。

独自にファイルを開くアプリケーションを作るときは先にショートカットかどうかを調べて、ショートカットファイルであればそのリンク先を取得して開く方がいい場合もある。この手の実装漏れはリリース直前のテスト作業でも発見できないことがあるので要注意かもしれない。

#include "shobjidl.h"
#include "shellapi.h"

//
//	ファイルがショートカットかどうか
//
//	正常な.lnkと.urlならtrueが返る
//
bool	IsShortcut(LPCTSTR pszFile)
{
	DWORD_PTR	dwRet;
	SHFILEINFO	info;

	dwRet = ::SHGetFileInfo(pszFile,0,&info, sizeof(SHFILEINFO),SHGFI_ATTRIBUTES);
	if(dwRet == 0)
		return	false;

	return	(info.dwAttributes & SFGAO_LINK) ? true : false;
}



void	Test(void)
{
	bool	ret;

	ret = IsShortcut(_T("c:\\IO.SYS"));

	if(ret)
		::MessageBox(NULL,_T("ショートカットファイルです"),_T(""),MB_OK);
	else
		::MessageBox(NULL,_T("ショートカットファイルではありません"),_T(""),MB_OK);
}

プロジェクトファイルをダウンロード

2006年11月24日

URLの表示回数を取得する

ブラウザーのお気に入りを右クリックしてプロパティを見ると、そのURLを表示した回数を知ることができる。この表示回数をプログラム的に取得するにはGetUrlCacheEntryInfoを利用する。
エラーのときやURLを表示したことがなければ関数はfalseを返す。

googlevideo.gif

#include "wininet.h"
#pragma	comment(lib,"wininet.lib")


//
//	URL表示回数の取得
//
bool	GetVisitsCount(LPCTSTR pszURL,DWORD* pdwCount)
{
	BOOL	fRet;
	BYTE*	pData;
	DWORD	cbInfo;
	LPINTERNET_CACHE_ENTRY_INFO	pInfo;

	if(pdwCount == NULL)
		return	false;

	*pdwCount = 0;
	cbInfo = 0;
	fRet = ::GetUrlCacheEntryInfo(pszURL,NULL,&cbInfo);
	if(cbInfo <= 0)		//fRetはFALSEが返る
		return	false;

	pData = new BYTE[cbInfo];
	if(pData == NULL)
		return	false;

	//データ取得
	pInfo = (LPINTERNET_CACHE_ENTRY_INFO)pData;
	fRet = ::GetUrlCacheEntryInfo(pszURL,pInfo,&cbInfo);
	if(fRet)
		*pdwCount = pInfo->dwHitRate;

	delete	pData;

	return	fRet ? true : false;
}




void	Test(void)
{
	bool	ret;
	DWORD	dwCount;
	TCHAR	pszMessage[1024];

	ret = GetVisitsCount(_T("http://www.google.co.jp/"),&dwCount);

	if(ret)
	{
		_stprintf_s(pszMessage,1024 * sizeof(TCHAR),_T("閲覧数は %d 回です"),dwCount);
		::MessageBox(NULL,pszMessage,_T(""),MB_OK);
	}
	else
		::MessageBox(NULL,_T("取得に失敗しました"),_T(""),MB_OK);
}

プロジェクトファイルをダウンロード

2006年11月25日

NEC PC-98シリーズをチェックする

最近のパソコンはほとんどがAT互換機でWindowsが動いている。ソフト開発をするときもWindowsとInternet Explorerのバージョンにさえ気を配れば問題ない。
とは言うものの今でも古いパソコンを使っているユーザーは少なからずいる。古いパソコンであってもAT互換機であれば問題が生じることはほとんどない。しかしそのようなユーザーの中にはNEC製のPC-98シリーズを使っている人もいる。
アプリケーションのパッケージに動作保証は「AT互換機のみ」と書いておくだけでなく、インストーラーなどでPC-98しりーずであることをチェックして動作保証がないことを警告しておくといいかもしれない。ちなみに古いマシンと言うとMIPSやAlpha、Power PCチップのWindowsパソコンなんてものも存在するが...これらは当時でさえユーザー数が少なかったから考えなくてもいいだろう。

//
//	NEC PC-98シリーズかAT互換機かのチェック
//
bool	IsNEC98(void)
{
	return ((::GetKeyboardType(0) == 7) && ((::GetKeyboardType(1) & 0xff00) == 0x0d00)) ? true : false;
}



void	Test(void)
{
	if(IsNEC98())
		::MessageBox(NULL,_T("このパソコンはNECのPC-98シリーズです"),_T(""),MB_OK);
	else
		::MessageBox(NULL,_T("このパソコンはNECのPC-98シリーズではありません"),_T(""),MB_OK);
}

プロジェクトファイルをダウンロード

実行ファイルのあるフォルダを取得する

「オプションの設定項目をiniファイルとして実行ファイルの存在するフォルダ内に保存したい」というようなときに使えるのがGetModuleFileName関数。この関数では実行ファイルへのフルパスを取得できる。しかし必要なのはフォルダ名の部分までだ。ここではフォルダ名までを取得できる関数を用意した。

依存環境:ATL
#include "atlstr.h"

//
//	実行ファイルの存在するフォルダとファイル名を取得する
//
//実行ファイルが"c:\test\aaa.exe"の場合は、pstrFolderに"c:\test\"、pstrFileに"aaa.exe"が帰る
//pstrFolderの末尾は'\'になる
//
bool	GetExecDir(CAtlString* pstrFolder,CAtlString* pstrFile)
{
	int			nLen;
	errno_t		err;
	TCHAR		pcbPath[_MAX_PATH*2];	//あまり意味はないが2倍値を利用
	TCHAR		pszDrive[_MAX_DRIVE];
	TCHAR		pszFolder[_MAX_DIR];
	TCHAR		pszFile[_MAX_FNAME];
	TCHAR		pszExtent[_MAX_EXT ];

	if(pstrFolder == NULL && pstrFile == NULL)
		return	true;
	if(pstrFolder)
		*pstrFolder = _T("");
	if(pstrFile)
		*pstrFile = _T("");

	//起動ディレクトリ名、ファイル名取得
	nLen = ::GetModuleFileName(NULL,pcbPath,_MAX_PATH*2);
	if(nLen == 0)
		return	false;

	//パスの分解
	err = ::_tsplitpath_s(pcbPath,pszDrive,_MAX_DRIVE,pszFolder,_MAX_DIR,pszFile,_MAX_FNAME,pszExtent,_MAX_EXT);
	if(err != 0)
		return	false;

	//結果保存
	if(pstrFolder)
	{
		*pstrFolder = pszDrive;
		*pstrFolder += pszFolder;
	}
	if(pstrFile)
	{
		*pstrFile = pszFile;
		*pstrFile += pszExtent;
	}

	return	true;
}



void	Test(void)
{
	CAtlString	strMessage;
	CAtlString	strFolder;
	CAtlString	strExec;

	GetExecDir(&strFolder,&strExec);

	strMessage.Format(_T("フォルダは「%s」、ファイル名は「%s」です"),strFolder,strExec);
	::MessageBox(NULL,strMessage,_T(""),MB_OK);

}

プロジェクトファイルをダウンロード

2006年11月26日

日本語版WTL 7.5のアプリケーションウィザード

■はじめに
WTLはライセンスがCPLのオープンソースプロジェクトとして公開されている。そのためおそらく勝手に日本語化したものを配布しても問題ないと思い用意しました。ライセンス的に問題があるようでしたらお知らせください。削除します。

■メリット
従来の英語版WTLではプロジェクト作成後にリソースエディタでメニューなどの言語を日本語に切り替えて、表示文字列を編集する必要がありました。しかしこの日本語版WTL 7.5ではプロジェクト生成直後から日本語リソースが利用可能です。

■日本語化内容:
 ・WTL 7.5のreadme.html(の一部)
 ・Windowsアプリケーション用アプリケーションウィザード
 ・Windowsアプリケーション用アプリケーションウィザードのセットアップ
 ・アプリケーションウィザードによって生成されるソースコード
 ・アプリケーションウィザードによって生成されるソースコードのコメント

※WTL 7.5のサンプルやWindows CE用のアプリケーションウィザードは日本語化していません。また、ダウンロード可能なファイルにも含まれません。
※WTL 7.5のincldueファイルも含みますが日本語化されていません。
※短時間で翻訳処理したため変な日本語になっている部分があります。


■ダウンロード
日本語版WTL 7.5をダウンロード

■以下は画面例です
wtl75jpmod001_img01.gif

wtl75jpmod001_img02.gif

wtl75jpmod001_img03.gif

wtl75jpmod001_img04.gif

ショートカットを作成する

アプリケーションをインストールするときにプログラムメニューやデスクトップ上にショートカットを生成したいことがある。そのような場合はCOMインターフェースのIShellLinkを通じて作成する。ショートカットファイルの拡張子には「.lnk」を指定する。
また、この方法でURLへのショートカット作成もできるが一般的ではない。作成したい場合はIUniformResourceLocatorを利用するべきだ。

#include <shlobj.h>


//
//	ショートカットの作成
//
//	pszLinkにショートカットを保存します。拡張子に「.lnk」を指定してください。
//	ショートカットのターゲットはpszFile、説明はpszDescription...とオプションを設定できます。
//
bool	CreateShortcut(LPCTSTR pszLink,LPCTSTR pszFile,LPCTSTR pszDescription=NULL,LPCTSTR pszArgs=NULL,LPCTSTR pszWorkingDir=NULL,LPCTSTR pszIconPath=NULL,int nIcon=0,int nShowCmd=SW_SHOWNORMAL)
{
	HRESULT			hr;
	IShellLink*		pIShellLink;
	IPersistFile*	pIPersistFile;

	//IShellLinkの作成
	pIShellLink = NULL;
	hr = ::CoCreateInstance(CLSID_ShellLink,NULL,CLSCTX_INPROC_SERVER,IID_IShellLink,(void**)&pIShellLink);
	if(pIShellLink == NULL || FAILED(hr))
		return	false;

	//IPersistFileの取得
	pIPersistFile = NULL;
	hr = pIShellLink->QueryInterface(IID_IPersistFile,(void**)&pIPersistFile);
	if(pIPersistFile == NULL || FAILED(hr))
	{
		pIShellLink->Release();
		return	false;
	}

	//ショートカット詳細設定
	hr = pIShellLink->SetPath(pszFile);
	if(SUCCEEDED(hr) && pszDescription)
		hr = pIShellLink->SetDescription(pszDescription);
	if(SUCCEEDED(hr) && pszArgs)
		hr = pIShellLink->SetArguments(pszArgs);
	if(SUCCEEDED(hr) && pszWorkingDir)
		hr = pIShellLink->SetWorkingDirectory(pszWorkingDir);
	if(SUCCEEDED(hr) && pszIconPath)
		hr = pIShellLink->SetIconLocation(pszIconPath,nIcon);
	if(SUCCEEDED(hr))
		hr = pIShellLink->SetShowCmd(nShowCmd);


#ifndef UNICODE
	WCHAR*	pwszUnicode;
	int		nLen;

	//Unicode変換
	nLen = ::MultiByteToWideChar(CP_ACP,0,pszLink,-1,NULL,0);
	pwszUnicode = new WCHAR[nLen + 1];
	if(pwszUnicode == NULL)
	{
		pIPersistFile->Release();
		pIShellLink->Release();
		return	false;
	}
	nLen = ::MultiByteToWideChar(CP_ACP,0,pszLink,-1,pwszUnicode,nLen + 1);
	if(nLen == 0)
		hr = E_FAIL;

	//ショートカットの保存
	if(SUCCEEDED(hr))
		hr = pIPersistFile->Save(pwszUnicode,TRUE);

	delete	pwszUnicode;

#else
	//ショートカットの保存
	if(SUCCEEDED(hr))
		hr = pIPersistFile->Save(pszLink,TRUE);
#endif

	pIPersistFile->Release();
	pIShellLink->Release();

	return	SUCCEEDED(hr) ? true : false;
}




void	Test(void)
{
	bool	ret;

	//COM初期化
	::CoInitialize(NULL);

	ret = CreateShortcut(_T("c:\\test.lnk"),_T("c:\\windows\\notepad.exe"),_T("メモ帳"));
	if(ret)
		::MessageBox(NULL,_T("ショートカットの作成に成功しました"),_T(""),MB_OK);
	else
		::MessageBox(NULL,_T("ショートカットの作成に失敗しました"),_T(""),MB_OK);

	//COM開放
	::CoUninitialize();
}

プロジェクトファイルをダウンロード

URLショートカットを作成する

アプリケーションをインストールするときにお気に入りにURLを追加したいことがある。そのような場合はCOMインターフェースのIUniformResourceLocatorを通じて作成する。ショートカットファイルの拡張子には「.url」を指定する。

#include <shlobj.h>
#include <intshcut.h>


//
//	URLショートカットの作成
//
//	pszLinkにショートカットを保存します。拡張子に「.url」を指定してください。
//
bool	CreateInternetShortcut(LPCTSTR pszFile,LPCTSTR pszURL)
{
	HRESULT			hr;
	IPersistFile*	pIPersistFile;
	IUniformResourceLocator*	pIUniformResourceLocator;

	pIUniformResourceLocator = NULL;
	hr = ::CoCreateInstance(CLSID_InternetShortcut,NULL,CLSCTX_INPROC_SERVER,IID_IUniformResourceLocator,(void**)&pIUniformResourceLocator);
	if(pIUniformResourceLocator == NULL || FAILED(hr))
		return	false;

	hr = pIUniformResourceLocator->QueryInterface(IID_IPersistFile,(void**)&pIPersistFile);
	if(pIPersistFile == NULL || FAILED(hr))
	{
		pIUniformResourceLocator->Release();
		return	false;
	}

	hr = pIUniformResourceLocator->SetURL(pszURL,0);

#ifdef  _UNICODE
	if(SUCCEEDED(hr))
		hr = pIPersistFile->Save(pszFile,TRUE);
#else
	WCHAR*	pwszUnicode;
	int		nLen;

	//Unicode変換
	nLen = ::MultiByteToWideChar(CP_ACP,0,pszFile,-1,NULL,0);
	pwszUnicode = new WCHAR[nLen + 1];
	if(pwszUnicode == NULL)
	{
		pIPersistFile->Release();
		pIUniformResourceLocator->Release();
		return	false;
	}
	nLen = ::MultiByteToWideChar(CP_ACP,0,pszFile,-1,pwszUnicode,nLen + 1);
	if(nLen == 0)
		hr = E_FAIL;

	//ショートカットの保存
	if(SUCCEEDED(hr))
		hr = pIPersistFile->Save(pwszUnicode,TRUE);

	delete	pwszUnicode;
#endif

	pIPersistFile->Release();
	pIUniformResourceLocator->Release();

	return	SUCCEEDED(hr) ? true : false;
}




void	Test(void)
{
	bool	ret;

	//COM初期化
	::CoInitialize(NULL);

	ret = CreateInternetShortcut(_T("c:\\test.url"),_T("http://www.google.co.jp/"));
	if(ret)
		::MessageBox(NULL,_T("ショートカットの作成に成功しました"),_T(""),MB_OK);
	else
		::MessageBox(NULL,_T("ショートカットの作成に失敗しました"),_T(""),MB_OK);

	//COM開放
	::CoUninitialize();
}

プロジェクトファイルをダウンロード

1  2  3  4





usefullcode@gmail.com

About 2006年11月

2006年11月にブログ「UsefullCode.net」に投稿されたすべてのエントリーです。

次の記事は2006年12月です。

他にも多くのエントリーがあります。メインページ記事一覧も見てください。