« 2006年11月 | メイン | 2007年01月 »

前の10件 1  2  3  4  5  6  7  8  9  10

2006年12月 記事一覧

IE用ツールバーを表示したり消去する

Googleツールバーに代表されるInternet Explorer用ツールバーなどのデスクバンド(IDeskBand)を表示したり消去するにはIWebBrowser2::ShowBrowserBarを利用する。
この関数は処理に成功しても失敗しても常にS_OKを返すので注意。また、引数として使われているVARIANT用のBOOL(VARIANT_TRUEとVARIANT_FALSE)はTRUE!=0、FALSE==0という関係ではないので気をつける必要がある。

デスクバンドのCLSID(GUID)はレジストリに登録されているものを用いる。ここでは例として検索用のエクスプローラーバーのGUIDを利用した。

#include "comdef.h"
#include "exdisp.h"
#include "mshtml.h"


//
//	デスクバンドを表示/非表示する
//
//pszClsidに_T("{30D02401-6A81-11D0-8274-00C04FD5AE38}")のようなデスクバンドのGUIDを指定
//
bool	ShowDeskBandI(IWebBrowser2* pIWebBrowser2,LPCTSTR pszClsid,bool bShow)
{
	VARIANT	vtBandGUID;
	VARIANT	vtShow;
	VARIANT	vEmpty;

	if(pIWebBrowser2 == NULL || pszClsid == NULL || *pszClsid == NULL)
		return	false;

	::VariantInit(&vEmpty);
	V_VT(&vtShow)	= VT_BOOL;
	vtShow.boolVal	= bShow ? VARIANT_TRUE : VARIANT_FALSE;
	vtBandGUID.vt	= VT_BSTR;
#ifdef	UNICODE
	vtBandGUID.bstrVal = ::SysAllocString(pszClsid);
#else
	{
		////////////////////////////////
		//char*からWCHAR*へ変換
		//
		WCHAR*	pszWchar;
		{
			int		nLen;

			//Unicodeに必要な文字数の取得
			nLen = ::MultiByteToWideChar(CP_THREAD_ACP,0,pszClsid,-1,NULL,0);
			pszWchar = new WCHAR[nLen];
			if(pszWchar)
			{
				//変換
				nLen = ::MultiByteToWideChar(CP_THREAD_ACP,0,pszClsid,(int)::strlen(pszClsid)+1,pszWchar,nLen);
				if(nLen == 0)
				{
					delete	pszWchar;
					pszWchar = NULL;
				}
			}
		}
		vtBandGUID.bstrVal = ::SysAllocString(pszWchar);

		delete	pszWchar;		//処理が終わったらdelete
	}
#endif

	//戻り値は必ず(?)成功なのでチェックしない
	::Sleep(0);
	pIWebBrowser2->ShowBrowserBar(&vtBandGUID,&vtShow,&vEmpty);

	::SysFreeString(vtBandGUID.bstrVal);

	return	true;
}



bool	Test2(void)
{
	HRESULT			hr;
	IWebBrowser2*	pIWebBrowser2;

	//IE起動
	pIWebBrowser2 = NULL;
	hr = ::CoCreateInstance(CLSID_InternetExplorer,NULL,CLSCTX_SERVER,IID_IWebBrowser2,(void**)&pIWebBrowser2);
	if(FAILED(hr) || pIWebBrowser2 == NULL)
		return	false;

	//IE可視化
	hr = pIWebBrowser2->put_Visible(VARIANT_TRUE);
	if(FAILED(hr))
	{
		pIWebBrowser2->Release();
		return	false;
	}

	//デスクバンド表示
	ShowDeskBandI(pIWebBrowser2,_T("{30D02401-6A81-11D0-8274-00C04FD5AE38}"),true);
	pIWebBrowser2->Release();

	return	true;
}



bool	Test(void)
{
	::CoInitialize(NULL);

	Test2();

	::CoUninitialize();

	return	true;
}

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

2006年12月16日

Windows VistaでVisual Studio 2005を使う

最近HDD容量が足りなくなってきていたので2.5インチSATA 160GBを1週間ぐらい前に注文したが、それがようやく昨日届いた。せっかくWindows Vistaの製品版もあることなのでこれを機会に開発環境をWindows Vistaで組むことに。

インストール前に「ユーザーアカウント制御」を無効に設定する。コントロールパネルの「ユーザーアカウントと家族のための安全設定」をクリック、そして「ユーザーアカウント」、「ユーザーアカウント制御の有効化または無効化」と進み、「ユーザーアカウント制御(UAC)を使ってコンピュータの保護に役立てる」のチェックをはずして「OK」ボタンを押せばいい。


そして実際にインストールするときの順序は…

1.Windows Vista Ultimate
2.Visual Studio 2005 Professional
3.MSDNライブラリ
4.Windows SDK
5.Visual Studio 2005 Service Pack 1
(6.Vista Support Update:開発中のため手に入らないが、本来ならここでインストール)
7.Visual Studio 2005 Extensions for WCF, WPF
8.Visual Studio 2005 Extensions for WF
9.WTL 8.0

というようにした。DDKやDirectX SDKなどを入れたい場合は4と5の間でインストールすればいいだろう。ちなみにここに挙げたもののなかで金を出さないと手に入らないのは1のWindows Vistaのみ。ほかは無料でのダウンロードが可能。


ダウンロード先は…

2.Visual Studio 2005(Team Suite 180 日間評価版)
3.MSDNライブラリ(2006年8月版)
4.Windows SDK
5.Visual Studio 2005 Service Pack 1(ベータ版。英語版は正式版がリリースされたので数週間以内に日本語版も正式版が出るはず)
7.Visual Studio 2005 Extensions for WCF, WPF(2006年11月CTP版。Visual C#を利用しないのなら不要?)
8.Visual Studio 2005 Extensions for WF(Visual C#を利用しないのなら不要?)
9.WTL 8.0


インストールに際して注意しなければいけないのは、Windows SDKのインストール直後に「スタート」メニューの「Microsoft Windows SDK」内にある「Integrate Windows SDK with Visual Studio 2005」を実行して、SDKのパスを登録すること。これをしなかったらVisual Studio 2005標準のPlatform SDKのインクルードやライブラリが使われてしまい、インストールする意味がない。
また、WTL 8.0のインストール後はVisual Studio 2005上で手動でパス設定を行わなければならない。


現状ではWindows Vista上でVisual Studio 2005を利用するための環境はまだ完全には整っていない。そのためインストールするときにはVisual Studio 2005 Service Pack 1、Vista Support Update、Visual Studio 2005 Extensionsなどの新しいものが公開されていないかを確かめた方がいい。

Windows VistaでNASを使う

nas01.gif
Windows Vistaに移行して最初に困ったことはNAS(Terastation)へ接続できない問題。
ユーザー名とパスワードを正しく入れてもログオンできない。ネット上を探したら「NASとPCの日時が30分でも差異があるとNG」という情報があったが、日時を合わせても接続できない。ドメイン参加ではなくワークグループなのでその辺りの対処も無意味…。Terastationのメーカーホームページを見ても「Windows Vistaをサポート」という情報があるのみ。方法までは載っていなかった。

nas02.gif
1時間ほどさんざん悩んだ挙句にようやく解決方法を見つけた。コントロールパネルの「管理ツール」を開き、

nas03.gif
さらに「ローカルセキュリティポリシー」を見る。

nas04.gif
その中に「ネットワークセキュリティ:LAN Manager認証レベル」という項目があるので、それをダブルクリックして、

nas05.gif
デフォルトの「NTMv2応答のみを送信する」から「LMとNTLM応答を送信する」に変更する。

nas06.gif
この設定を行ったら無事にNASに接続できた。

エディットコントロールの入力禁止文字を設定する

test67.gif
エディットコントロールに入力したくない文字を設定するときは、Windows2000以降に備わっているSHLimitInputEditを利用すると簡単に実装できる。
この関数はエクスプローラなどでファイル名をユーザーに入力させるときの注意用に作られたもので、図のようなバルーンで入力禁止文字が表示される。このとき表示される「ファイル名に次の文字は使えません:」という文字列は変更することができない(少なくとも私はその方法を知らない)。そのため簡単に入力禁止文字の設定はできるが使用範囲が限られてしまうのが残念な点だ。

実装ではIShellFolderとIItemNameLimitsを備えたCOMインターフェースを作成し、それを引数としてSHLimitInputEditに渡せばいい。

ここでは以下のようにプロジェクトを作成した。

1.WTLのアプリケーションウイザードでダイアログアプリケーションを作成
2.リソースエディタでエディットコントロールを追加(コントロールIDはIDC_EDIT1)
3.MainDlg.hにCOMインターフェースを追加
4.MainDlg.hのOnInitDialog内でSHLimitInputEditを実行


依存環境:ATL/WTL

■MainDlg.hのダイアログ定義の前に追加
MIDL_INTERFACE("28997A04-63A4-421d-BF58-154F7BD82E8A")
IDnpEditChars : public IUnknown
{
public:
};


class ATL_NO_VTABLE CDnpEditChars : 
	public CComObjectRootEx<CComSingleThreadModel>,
	public IShellFolder,
	public IItemNameLimits,
	public IDnpEditChars
{
public:
	CDnpEditChars()
	{
	}

	BEGIN_COM_MAP(CDnpEditChars)
		COM_INTERFACE_ENTRY(IDnpEditChars)
		COM_INTERFACE_ENTRY(IShellFolder)
		COM_INTERFACE_ENTRY(IItemNameLimits)
	END_COM_MAP()

	DECLARE_PROTECT_FINAL_CONSTRUCT()


	//IItemNameLimits
	STDMETHOD(GetMaxLength)(LPCWSTR pszName,int *piMaxNameLen)
	{
		return	E_NOTIMPL;
	}
	STDMETHOD(GetValidCharacters)(LPWSTR *ppwszValidChars,LPWSTR *ppwszInvalidChars)
	{
		//「?」と「*」を入力不可能な文字にする

		*ppwszValidChars = NULL;

		*ppwszInvalidChars = (WCHAR*)::CoTaskMemAlloc(sizeof(WCHAR) * 20);
		if(*ppwszInvalidChars == NULL)
			return	E_FAIL;

		::wcscpy_s(*ppwszInvalidChars,20 * sizeof(WCHAR),L"?*");

		return	S_OK;
	}


	//IShellFolder
	STDMETHOD(BindToObject)(LPCITEMIDLIST pidl,LPBC pbc,REFIID riid,VOID **ppvOut)
	{
		return	E_NOTIMPL;
	}
	STDMETHOD(BindToStorage)(LPCITEMIDLIST pidl,LPBC pbc,REFIID riid,VOID **ppvOut)
	{
		return	E_NOTIMPL;
	}
	STDMETHOD(CompareIDs)(LPARAM lParam,LPCITEMIDLIST pidl1,LPCITEMIDLIST pidl2)
	{
		return	E_NOTIMPL;
	}
	STDMETHOD(CreateViewObject)(HWND hwndOwner,REFIID riid,VOID **ppvOut)
	{
		return	E_NOTIMPL;
	}
	STDMETHOD(EnumObjects)(HWND hwndOwner,SHCONTF grfFlags,IEnumIDList **ppenumIDList)
	{
		return	E_NOTIMPL;
	}
	STDMETHOD(GetAttributesOf)(UINT cidl,LPCITEMIDLIST *apidl,SFGAOF *rgfInOut)
	{
		return	E_NOTIMPL;
	}
	STDMETHOD(GetDisplayNameOf)(LPCITEMIDLIST pidl,DWORD uFlags,LPSTRRET lpName)
	{
		return	E_NOTIMPL;
	}
	STDMETHOD(GetUIObjectOf)(HWND hwndOwner,UINT cidl,LPCITEMIDLIST *apidl,REFIID riid,UINT *rgfReserved,VOID **ppv)
	{
		return	E_NOTIMPL;
	}
	STDMETHOD(ParseDisplayName)(HWND hwnd,LPBC pbc,LPOLESTR pwszDisplayName,ULONG *pchEaten,LPITEMIDLIST *ppidl,ULONG *pdwAttributes)
	{
		return	E_NOTIMPL;
	}
	STDMETHOD(SetNameOf)(HWND hwndOwner,LPCITEMIDLIST pidl,LPCOLESTR lpszName,DWORD uFlags,LPITEMIDLIST *ppidlOut)
	{
		return	E_NOTIMPL;
	}

};

■MainDlg.hのOnInitDialog()内に追加
		HRESULT	hr;
		CComPtr<IDnpEditChars>	pIDnpEditChars;

		pIDnpEditChars = new CComObject<CDnpEditChars>;
		hr = ::SHLimitInputEdit(GetDlgItem(IDC_EDIT1).m_hWnd,(IShellFolder*)(IDnpEditChars*)pIDnpEditChars);
		if(FAILED(hr))
			MessageBox(_T("設定に失敗しました"));

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

ファイル共有ダイアログを表示する

test68_01.gif
Windows XP以降であればShowShareFolderUIを利用することで図のようなフォルダ共有ダイアログを開ける。ShowShareFolderUIはヘッダーとして用意されていないのでLoadLibraryとGetProcAddressを利用して呼ぶ必要がある。

この関数はhParentWndにNULLを指定するとS_OKが返るもののダイアログが表示されないので注意。

test68_02.gif
また、指定するフォルダによってはこの図のようにファイル共有ダイアログが開くこともある。


ここではWTLでダイアログベースのアプリケーションを作成。MainDlg.hに必要な実装を追加してプロジェクトを作成した。

■MainDlg.h内に追加
//
//	フォルダの共有ダイアログを表示する
//
//Windows XP以降で有効。
//hParentWnd == NULLはNG。必ず親ウインドウを指定すること!
//
//アプリケーションの開始時CoInitialize、終了時CoUninitializeが呼ばれていないとNG
//
bool	ShowShareFolderUI(HWND hParentWnd,LPCTSTR pszPath)
{
	HMODULE	hModule;
	HRESULT	hr;

	HRESULT	(CALLBACK* pfnShowShareFolderUI)(HWND hwndParent,LPCWSTR pszPath);

	if(hParentWnd == NULL)
		return	false;

	hModule = ::LoadLibrary(_T("ntshrui.dll"));
	if(hModule == NULL)
		return	false;

	(*(FARPROC*)&pfnShowShareFolderUI) = ::GetProcAddress(hModule,"ShowShareFolderUI");

	if(pfnShowShareFolderUI)
	{
#ifdef UNICODE
		hr = pfnShowShareFolderUI(hParentWnd,pszPath);
#else
		{
			////////////////////////////////
			//char*からWCHAR*へ変換
			//
			WCHAR*	pszWchar;
			{
				int		nLen;

				//Unicodeに必要な文字数の取得
				nLen = ::MultiByteToWideChar(CP_THREAD_ACP,0,pszPath,-1,NULL,0);
				pszWchar = new WCHAR[nLen];
				if(pszWchar)
				{
					//変換
					nLen = ::MultiByteToWideChar(CP_THREAD_ACP,0,pszPath,(int)::strlen(pszPath)+1,pszWchar,nLen);
					if(nLen == 0)
					{
						delete	pszWchar;
						pszWchar = NULL;
					}
				}
			}

			hr = pfnShowShareFolderUI(hParentWnd,pszWchar);

			delete	pszWchar;		//処理が終わったらdelete
		}
#endif
	}
	else
		hr = E_FAIL;

	::FreeLibrary(hModule);

	return	SUCCEEDED(hr) ? true : false;
}

■MainDlg.hのOnInitDialog()内に追加
		ShowShareFolderUI(m_hWnd,_T("c:\\"));
		ShowShareFolderUI(m_hWnd,_T("c:\\_down"));

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


ゴミ箱内のアイテム数と占有容量を取得する

test69.gif
SHQueryRecycleBinを利用するとゴミ箱に入っているファイルやフォルダの合計数とそれらの合計容量(単位:bytes)を取得できる。

注意すべき点は取得できた値は64ビット値のため、printfなどで数値から文字列に変更するときには「%I64d」のように64ビット処理する必要があることだ。

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

#include "shellapi.h"


bool	Test(void)
{
	HRESULT			hr;
	SHQUERYRBINFO	sShQueryRbInfo;

	::ZeroMemory(&sShQueryRbInfo,sizeof(SHQUERYRBINFO));
	sShQueryRbInfo.cbSize = sizeof(SHQUERYRBINFO);

	hr = ::SHQueryRecycleBin(NULL,&sShQueryRbInfo);
	if(FAILED(hr))
		return	false;

	CAtlString	strMessage;

	strMessage.Format(_T("アイテム数:%I64d\n容量:%I64d MB\n"),sShQueryRbInfo.i64NumItems,sShQueryRbInfo.i64Size / (1024*1024));

	::MessageBox(NULL,strMessage,_T("ゴミ箱の中身"),MB_OK);

	return	true;
}

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

2006年12月17日

Visual Studio 2005 サービスパック1をインストールする

vs2005sp1_04.gif
昨夜調べたときは気がつかなかったのだがVisual Studio 2005 Service Pack 1の日本語版がリリースされていた。
Visual Studio® 2005 Team Suite SP1」でダウンロード可能。名前が"Team Suite"となっているが、Visual Studio 2005 Professionalなどのサービスパックも兼ねている。

vs2005sp1_05.gif
ベータ版のとき同様にreadmeなどは含まれず、修正内容が明記されていない。詳しいことは「Microsoft Connect」(ログイン必要)内で公開されている。

vs2005sp1_06.gif
私の環境ではここまでのインストールに1時間近く要した。





vs2005sp1_07.gif
サービスパックのインストール後、Visual Studio 2005を起動すると...「Visual Studio 2005 SP1を使用するには、Windows Vista用更新プログラムが必要です。」と言われる。この「Windows Vista用更新プログラム」は現時点ではリリースされていないので無視して「続行」ボタンを押すことになる。

Windows Vista環境以外ではおそらくこのメッセージは表示されない。ちなみに画面のリンクは…リンク切れだった。






vs2005sp1_01.gif
ちなみにベータ版のサービスパックがインストールされていると「アップグレード修正プログラムをインストールできません」と言われてしまう。

vs2005sp1_02.gif
その場合はコントロールパネルの「プログラムと機能」の「インストールされた更新プログラムを表示」から...

vs2005sp1_03.gif
Visual Studio 2005 Service Pack 1 Betaをアンインストールしてから作業する必要がある。このアンインストール作業にもかなり時間を要し、また、途中でVisual Studio 2005のCD-ROMが必要になるのでかなり面倒。

Windows Vistaのエディション名を取得する

Windows Vistaのエディションを取得するにはGetProductInfoを利用すると楽にできる。ただしこのAPIはWindows Vista以降に備わるものなので、そのまま利用すると実行ファイルをWindows 2000で動かせなくなる。そのためLoadLibrary、GetProcAddressを利用して実行時に呼び出すようにした方がいい。

また、GetProductInfoで取得できた値が「PRODUCT_ULTIMATE」だからと言って「Windows Vista Ultimate Edition」とは限らない。今後Windows Vistaの後継OSが出た時もこのAPIが使われることが考えられるためだ。そのため「Windows Vista Ultimate Edition」としたい場合は、GetVersionExで取得したWindowsのメジャーバージョンおよびマイナーバージョンをもチェックするといい。

「PRODUCT_ULTIMATE」などが定義されていないというエラーが出てビルドできない場合は、Windows SDKがきちんとインストールされているかを確認すること。

ちなみに各プロダクトタイプはwinnt.hの中で以下のように定義されている。
//
// Product types
// This list grows with each OS release.
//
// There is no ordering of values to ensure callers
// do an equality test i.e. greater-than and less-than
// comparisons are not useful.
//
// NOTE: Values in this list should never be deleted.
//       When a product-type 'X' gets dropped from a
//       OS release onwards, the value of 'X' continues
//       to be used in the mapping table of GetProductInfo.
//

#define PRODUCT_UNDEFINED                       0x00000000

#define PRODUCT_ULTIMATE                        0x00000001
#define PRODUCT_HOME_BASIC                      0x00000002
#define PRODUCT_HOME_PREMIUM                    0x00000003
#define PRODUCT_ENTERPRISE                      0x00000004
#define PRODUCT_HOME_BASIC_N                    0x00000005
#define PRODUCT_BUSINESS                        0x00000006
#define PRODUCT_STANDARD_SERVER                 0x00000007
#define PRODUCT_DATACENTER_SERVER               0x00000008
#define PRODUCT_SMALLBUSINESS_SERVER            0x00000009
#define PRODUCT_ENTERPRISE_SERVER               0x0000000A
#define PRODUCT_STARTER                         0x0000000B
#define PRODUCT_DATACENTER_SERVER_CORE          0x0000000C
#define PRODUCT_STANDARD_SERVER_CORE            0x0000000D
#define PRODUCT_ENTERPRISE_SERVER_CORE          0x0000000E
#define PRODUCT_ENTERPRISE_SERVER_IA64          0x0000000F
#define PRODUCT_BUSINESS_N                      0x00000010
#define PRODUCT_WEB_SERVER                      0x00000011
#define PRODUCT_CLUSTER_SERVER                  0x00000012
#define PRODUCT_HOME_SERVER                     0x00000013
#define PRODUCT_STORAGE_EXPRESS_SERVER          0x00000014
#define PRODUCT_STORAGE_STANDARD_SERVER         0x00000015
#define PRODUCT_STORAGE_WORKGROUP_SERVER        0x00000016
#define PRODUCT_STORAGE_ENTERPRISE_SERVER       0x00000017
#define PRODUCT_SERVER_FOR_SMALLBUSINESS        0x00000018
#define PRODUCT_SMALLBUSINESS_SERVER_PREMIUM    0x00000019

#define PRODUCT_UNLICENSED                      0xABCDABCD

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



bool	Test(void)
{
	HMODULE	hModule;
	BOOL	ret;
	DWORD	dwType;
	CAtlString	strMessage;

	BOOL (CALLBACK* pfnGetProductInfo)(DWORD dwOSMajorVersion,DWORD dwOSMinorVersion,DWORD dwSpMajorVersion,DWORD dwSpMinorVersion,PDWORD pdwReturnedProductType);

	hModule = ::LoadLibrary(_T("kernel32.dll"));
	if(hModule == NULL)
		return	false;

	(*(FARPROC*)&pfnGetProductInfo) = ::GetProcAddress(hModule,"GetProductInfo");

	ret = FALSE;
	if(pfnGetProductInfo)
	{
		OSVERSIONINFOEX	sInfoEx;

		::ZeroMemory(&sInfoEx,sizeof(OSVERSIONINFOEX));
		sInfoEx.dwOSVersionInfoSize = sizeof(OSVERSIONINFOEX);
		ret = ::GetVersionEx((LPOSVERSIONINFO)&sInfoEx);

		if(ret)
			ret = pfnGetProductInfo(sInfoEx.dwMajorVersion,sInfoEx.dwMinorVersion,sInfoEx.wServicePackMajor,sInfoEx.wServicePackMinor,&dwType);
	}

	if(ret)
	{
		switch(dwType)
		{
		case	PRODUCT_ULTIMATE:
			strMessage = _T("PRODUCT_ULTIMATE");
			break;

		case	PRODUCT_HOME_BASIC:
			strMessage = _T("PRODUCT_HOME_BASIC");
			break;

		case	PRODUCT_HOME_PREMIUM:
			strMessage = _T("PRODUCT_HOME_PREMIUM");
			break;

		case	PRODUCT_ENTERPRISE:
			strMessage = _T("PRODUCT_ENTERPRISE");
			break;

		case	PRODUCT_HOME_BASIC_N:
			strMessage = _T("PRODUCT_HOME_BASIC_N");
			break;

		case	PRODUCT_BUSINESS:
			strMessage = _T("PRODUCT_BUSINESS");
			break;

		case	PRODUCT_STANDARD_SERVER:
			strMessage = _T("PRODUCT_STANDARD_SERVER");
			break;

		case	PRODUCT_DATACENTER_SERVER:
			strMessage = _T("PRODUCT_DATACENTER_SERVER");
			break;

		case	PRODUCT_SMALLBUSINESS_SERVER:
			strMessage = _T("PRODUCT_SMALLBUSINESS_SERVER");
			break;

		case	PRODUCT_ENTERPRISE_SERVER:
			strMessage = _T("PRODUCT_ENTERPRISE_SERVER");
			break;

		case	PRODUCT_STARTER:
			strMessage = _T("PRODUCT_STARTER");
			break;

		case	PRODUCT_DATACENTER_SERVER_CORE:
			strMessage = _T("PRODUCT_DATACENTER_SERVER_CORE");
			break;

		case	PRODUCT_STANDARD_SERVER_CORE:
			strMessage = _T("PRODUCT_STANDARD_SERVER_CORE");
			break;

		case	PRODUCT_ENTERPRISE_SERVER_CORE:
			strMessage = _T("PRODUCT_ENTERPRISE_SERVER_CORE");
			break;

		case	PRODUCT_ENTERPRISE_SERVER_IA64:
			strMessage = _T("PRODUCT_ENTERPRISE_SERVER_IA64");
			break;

		case	PRODUCT_BUSINESS_N:
			strMessage = _T("PRODUCT_BUSINESS_N");
			break;

		case	PRODUCT_WEB_SERVER:
			strMessage = _T("PRODUCT_WEB_SERVER");
			break;

		case	PRODUCT_CLUSTER_SERVER:
			strMessage = _T("PRODUCT_CLUSTER_SERVER");
			break;

		case	PRODUCT_HOME_SERVER:
			strMessage = _T("PRODUCT_HOME_SERVER");
			break;

		case	PRODUCT_STORAGE_EXPRESS_SERVER:
			strMessage = _T("PRODUCT_STORAGE_EXPRESS_SERVER");
			break;

		case	PRODUCT_STORAGE_STANDARD_SERVER:
			strMessage = _T("PRODUCT_STORAGE_STANDARD_SERVER");
			break;

		case	PRODUCT_STORAGE_WORKGROUP_SERVER:
			strMessage = _T("PRODUCT_STORAGE_WORKGROUP_SERVER");
			break;

		case	PRODUCT_STORAGE_ENTERPRISE_SERVER:
			strMessage = _T("PRODUCT_STORAGE_ENTERPRISE_SERVER");
			break;

		case	PRODUCT_SERVER_FOR_SMALLBUSINESS:
			strMessage = _T("PRODUCT_SERVER_FOR_SMALLBUSINESS");
			break;

		case	PRODUCT_SMALLBUSINESS_SERVER_PREMIUM:
			strMessage = _T("PRODUCT_SMALLBUSINESS_SERVER_PREMIUM");
			break;

		case	PRODUCT_UNLICENSED:
			strMessage = _T("PRODUCT_UNLICENSED");
			break;

		default:
			strMessage.Format(_T("Unknown Type(%d)"),dwType);
		}
	}

	::FreeLibrary(hModule);

	::MessageBox(NULL,strMessage,_T(""),MB_OK);

	return	true;
}

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

ユーザーが管理者権限を持っているかどうか調べる

ユーザーが管理者権限を持っている(Administrator)かどうかをチェックするにはIsUserAnAdminを利用する。
このAPIはWindows 2000以降のもののためWindows 9xやNT 4.0もターゲットにしている場合はGetProcAddressを利用して動的に実行する必要がある。

#include "shlobj.h"


void	Test(void)
{
	if(::IsUserAnAdmin())
		::MessageBox(NULL,_T("管理者権限があります"),_T(""),MB_OK);
	else
		::MessageBox(NULL,_T("管理者権限がありません"),_T(""),MB_OK);
}

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

Windows Vista(製品版)のAPI実装はまだ未完成?!

test72.gif
Windows Vistaから追加されたAPIの1つのSHOpenWithDialogがある。これは「ファイルを開くプログラムの選択」ダイアログを表示するために用意された。ちょっと前まではAPI名が「OpenAsDialog」となっていたが、SHOpenWithDialogに変更されている。

このAPIでは引数にOPENASINFO構造体を利用する。この構造体はメンバ変数としてTCHAR*型が利用されているが...実際にテストしたところUnicodeしか受け付けない。そのため下に用意したテストコードのように(TCHAR*)でキャストする必要がある。

また、実行時には図のようなダイアログが表示される。しかし、プログラムを選択しても指定したファイルは開かない。SHOpenWithDialogの戻り値はS_FALSEが返る(この値は成功を示すので戻り値をSUCCEEDED(hr)のようにしてチェックできないことに注意!)。

ファイルが開かないのは単純にSHOpenWithDialogの使い方を間違えているだけかもしれない。しかし以上のことを考えてみると、Windows VistaのAPI実装にはまだ未完成の部分があるのかもしれない。

#include "shlobj.h"

bool	Test(void)
{
	HMODULE	hModule;
	HRESULT	hr;

	HRESULT (CALLBACK* pfnSHOpenWithDialog)(HWND hwndParent,POPENASINFO poainfo);

	hModule = ::LoadLibrary(_T("shell32.dll"));
	if(hModule == NULL)
		return	false;

	//MSDNではAPI名が「OpenAsDialog」のことがあるが、VistaではSHOpenWithDialogのみ実装されている
	(*(FARPROC*)&pfnSHOpenWithDialog) = ::GetProcAddress(hModule,"SHOpenWithDialog");

	if(pfnSHOpenWithDialog)
	{
		OPENASINFO	sInfo;

		::ZeroMemory(&sInfo,sizeof(OPENASINFO));
		sInfo.pcszFile = (TCHAR*)L"c:\\aa.txt";		//Unicodeで指定
		sInfo.pcszClass = NULL;
		sInfo.oaifInFlags = OAIF_ALLOW_REGISTRATION;

		//S_FALSEが返ることがある!
		hr = pfnSHOpenWithDialog(NULL,&sInfo);
	}
	else
		hr = E_FAIL;

	::FreeLibrary(hModule);

	return	(hr == S_OK) ? true : false;
}

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

前の10件 1  2  3  4  5  6  7  8  9  10





usefullcode@gmail.com

About 2006年12月

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

前の記事は2006年11月です。

次の記事は2007年01月です。

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