////////////////////////////////////////////////////////////////////////////////
//
//	モジュール名：	MyuRegReader
//
//	機能：			レジストリから情報を取得するクラス
//
//	主入口名：		
//
//	使用概要/備考：
//
//	  - まず OpenKey() によってキーを開きます。
//
//	  - Get〜()メソッドによって各種情報を取得します。
//
//	  - サブキー（現在開いているキーの中にあるキー）を開く場合は、
//		まず GetKeyHandle() により親キーのキーハンドルを取得し、
//		引数で親キーを指定可能なOpenKey()によってキーを開きます。
//
//		例）
//			MyuRegReader reg_parent;
//			＜中略＞
//			MyuRegReader reg_subkey;
//			reg_subkey.OpenKey( reg_parent.GetKeyHandle(), "Control\\DeviceClasses" );
//
//
//	  - キーがオープンされていた場合、デストラクタにて自動的にクローズされます。
//
//	  - エラーが発生した場合、get_last_detail_message() によって詳細な情報を取得できます。
//
////////////////////////////////////////////////////////////////////////////////

#ifndef __MyuRegReader_H__
#define __MyuRegReader_H__

#include "mwlcommon.h"

//#define MYUREG_QUERY_ERR_VAL	(-1)			//	Query関連のエラーデータ値 ← PG-Reliefに指摘された
#define MYUREG_QUERY_ERR_VAL	(0xFFFFFFFF)	//	Query関連のエラーデータ値


//////	内部的マクロ  //////

//	GetQueryInfoを実行して正常ならVALUE、エラーならERRORを復帰するマクロ
#define CALL_QUERY_AND_RET(VALUE,ERROR)		( GetQueryInfo()==TRUE ? VALUE : ERROR )

//	Openチェックマクロ
#define CHK_KEY_OPENED()		{ if(m_hKey==NULL){print_msg("MyuRegReader Key was not opened!"); return FALSE;} }
#define CHK_KEY_OPENED_NULL()	{ if(m_hKey==NULL){print_msg("MyuRegReader Key was not opened!"); return NULL;} }

//	CutRootKeyName()用
typedef struct{
	const char* szKeyName;
	HKEY hRootKey;
} ROOT_KEY_LIST_ITEM;


//	クラス宣言
class CMyuRegReader : public CMyuDetailMsgBase
{
protected:
	HKEY m_hKey;	//	キーハンドル

	//////////////////////////
	//
	//		Query関連

	DWORD m_dwSubKeyCount;
	DWORD m_dwValuesCount;
	DWORD m_dwMaxSubKeyLen;
	DWORD m_dwMaxValueNameLen;
	DWORD m_dwMaxValueLen;
	BOOL m_bAlreadyQueryFlg;

	//	Query関連の値を初期化する。
	//	（変数を追加した時、ここに追加するのを良く忘れるので
	//	　ヘッダの方、それも変数宣言の直ぐ下に定義しておきます）
	void QueryInfoInit()
	{
		m_dwSubKeyCount = MYUREG_QUERY_ERR_VAL;
		m_dwValuesCount = MYUREG_QUERY_ERR_VAL;
		m_dwMaxSubKeyLen = MYUREG_QUERY_ERR_VAL;
		m_dwMaxValueNameLen = MYUREG_QUERY_ERR_VAL;
		m_dwMaxValueLen = MYUREG_QUERY_ERR_VAL;
		m_bAlreadyQueryFlg = FALSE;
	}

	//	内部メソッド
	BOOL GetQueryInfo();
	HKEY CutRootKeyName( const char** szIoKeyName );

	//	ROOT_KEY_LIST_ITEM を作るメソッド
	ROOT_KEY_LIST_ITEM MakeRootKeyListItem( const char* szKeyName, HKEY hRootKey )
	{
		static ROOT_KEY_LIST_ITEM item;
		item.szKeyName = szKeyName;
		item.hRootKey = hRootKey;
		return item;
	}

public:
	//	コンストラクタ/デストラクタ
	CMyuRegReader();
	CMyuRegReader(const char *szKeyName){
		m_hKey = NULL;
		QueryInfoInit();
		OpenKey(szKeyName);
	}
	CMyuRegReader(CMyuRegReader &parentReg, const char *szKeyName){
		m_hKey = NULL;
		QueryInfoInit();
		OpenKey(parentReg.GetKeyHandle(), szKeyName);
	}
	virtual ~CMyuRegReader();

	//	Open/Close
	BOOL OpenKey( const char* szKeyName );
	BOOL OpenKey( HKEY hParentKey, const char* szKeyName );
	BOOL OpenSubKey( const char* szKeyName );/*{
		HKEY hKeyBkup = m_hKey;
		BOOL b = OpenKey(m_hKey, szKeyName);
		RegCloseKey( hKeyBkup );
		return b;
	}*/
	//int OpenKeyByIndex( HKEY hParentKey, int nKeyIndex );	//	未実装
	void CloseKey();

	//	値取得
	const char* GetValueStr( const char* szValueName );
	const char* GetValueStr( const char* szValueName, char* szOutBuffer, int nOutBufferSize );
	int GetValueDWord( const char* szValueName, DWORD* dwpValue );
	//int GetValueNum( const char* szValueName, int *pnValue );
	BOOL GetValue( const char* szValueName, LPDWORD lpType, LPBYTE lpData, LPDWORD lpcbData );
	int GetValueBin( const char* szValueName, void* szOutBuffer, int nOutBufferSize );

	//	情報取得
	const char* GetSubKeyName( DWORD dwSubKeyIndex );
	const char* GetValueName( DWORD dwValueIndex );

	//	現在のキーに関するあらゆる情報を復帰するメソッド群
	//	エラーの場合は-1を復帰する。
	DWORD GetSubKeyCount() {		return CALL_QUERY_AND_RET( m_dwSubKeyCount, MYUREG_QUERY_ERR_VAL ); }
	DWORD GetValuesCount() {		return CALL_QUERY_AND_RET( m_dwValuesCount, MYUREG_QUERY_ERR_VAL ); }
	DWORD GetMaxSubKeyLen() {		return CALL_QUERY_AND_RET( m_dwMaxSubKeyLen, MYUREG_QUERY_ERR_VAL ); }
	DWORD GetMaxValueNameLen() {	return CALL_QUERY_AND_RET( m_dwMaxValueNameLen, MYUREG_QUERY_ERR_VAL ); }
	DWORD GetMaxValueLen() {		return CALL_QUERY_AND_RET( m_dwMaxValueLen, MYUREG_QUERY_ERR_VAL ); }

	//	キーハンドルを取得
	HKEY GetKeyHandle() { return m_hKey; }

	//	キーハンドルを設定する（一応キーを閉じておいてから）
	void SetKeyHandle( HKEY hSetKey ) { CloseKey(); m_hKey = hSetKey; }
};

#endif//__MyuRegReader_H__
