Splitterダイアログ

このサンプルは、ツリービューまたはグリッドビューを提供するSplitterダイアログを作成する方法を示します。

Ocguide splitter dialog.png

目次

ダイアログリソースを準備

このダイアログを作成するには、最初にラベルと2つのボタンコントロールを持つダイアログリソースを準備する必要があります。ここで、このサンプルを簡単にするため組込のOriginC\Originlab\ODlg8.dll ファイルにある既存のリソースIDD_SAMPLE_SPLITTER_DLGを使います。

ソースファイルを準備

コードビルダで、新規ボタンNewfile button.png をクリックして、ファイル名を入力し、上述のダイアログリソースと同じパス(OriginのインストールフォルダのOriginC\Originlab サブフォルダ)にセットします。

ヘッダファイルをインクルードする

次のヘッダファイルがサンプルで使われます。上記で作成した ソースファイルに次をコピーします。

#include <..\Originlab\DialogEx.h>
#include <..\Originlab\SplitterControl.h>
#include <..\Originlab\DynaSplitter.h>

ユーザ定義Splitterクラスを追加する

TreeDynaSplitterからクラスを派生することができます。 ほとんどのダイアログの初期化と他のイベント関数のコードは、基底クラスにあり、splitterクラスを軽くします。

class MySplitter : public TreeDynaSplitter
{
public:
	MySplitter(){}
	~MySplitter(){}
	//splitterコントロールを初期化
	int	Init(int nCtrlID, WndContainer& wndParent, LPCSTR lpcszDlgName = NULL)
	{
		TreeDynaSplitter::Init(nCtrlID, wndParent, 0, lpcszDlgName);
		return 0;
	}
	//現在の設定を出力
	void	Output()
	{
		out_tree(m_trSettings);
	}
protected:
	// メッセージマップテーブルとメッセージハンドラを宣言
	DECLARE_MESSAGE_MAP
	BOOL	OnInitSplitter();
	BOOL	InitSettings();
	void	OnRowChange(Control ctrl);
	
private:
	BOOL	constructSettings();	
	BOOL	initSystemInfo(TreeNode& trSys);//システム情報を表示	
	BOOL	initUserInfo(TreeNode& trUser);//ユーザ設定を収集
private:	
	GridTreeControl	m_List; //左パネルのグリッド表示	
	Tree	m_trSettings;//右パネルのsplitterツリー	
	bool	m_bIsInit;//初期化イベントからかどうかを示す
	
};
//コントロールメッセージとイベントをマッピング
BEGIN_MESSAGE_MAP_DERIV(MySplitter, TreeDynaSplitter)
	
	ON_INIT(OnInitSplitter) //splitter設定初期化
	//破棄時にsplitterのサイズと位置を保存
	//これは基底クラスで行われる
	ON_DESTROY(OnDestroy)
	ON_SIZE(OnCtrlResize)
	//コントロールが準備できたら、splitterと位置をリサイズ
	ON_USER_MSG(WM_USER_RESIZE_CONTROLS, OnInitPaneSizs)
	
	//ユーザは左パネルの異なる行を選択
	ON_GRID_ROW_COL_CHANGE(GetMainPaneID(), OnRowChange)
END_MESSAGE_MAP_DERIV
BOOL	MySplitter::OnInitSplitter()
{
	TreeDynaSplitter::OnInitSplitter(&m_List);
	constructSettings();	//ツリー設定を構築
	InitSettings(); //ツリー設定をsplitter GUIに
	SetReady();
	return TRUE;
}
//ユーザが異なる行を選択するとき、右パネルを更新
void	MySplitter::OnRowChange(Control ctrl)
{
	if ( !m_bReady )
		return;
	//現在のブランチのサブノードを表示
	TreeNode trCurrent = ShowListContent(-1, true, m_bIsInit);
	if ( trCurrent )
	{
		//レジストリから設定をロード
		string strTag = trCurrent.tagName;
		LoadBranchSetting(GetDlgName(), strTag);
	}
	m_bIsInit = false;
	return;
}
//splitter設定を初期化
BOOL	MySplitter::InitSettings()
{
	m_bIsInit = true;
	///GUIの問題を避けるため、準備状態がセットしない
	m_bReady = false;
	//表示のためのsplitter treeをセット
	ShowList(m_trSettings, ATRN_STOP_LEVEL);
	m_bReady = true; //準備状態をリセット
	SelectRow(0); //最初の行を選択
	return TRUE;
}
BOOL	MySplitter::constructSettings()
{
	TreeNode trSys = m_trSettings.AddNode("System");
	trSys.SetAttribute(STR_LABEL_ATTRIB, "System Information");
	initSystemInfo(trSys);
	
	TreeNode trUser = m_trSettings.AddNode("User");
	trUser.SetAttribute(STR_LABEL_ATTRIB, "User Settings");
	initUserInfo(trUser);
	return TRUE;
}
//Originの基本情報を表示
//OS関連の情報も表示可能
BOOL	MySplitter::initSystemInfo(TreeNode& trSys)
{
	if ( !trSys )
		return FALSE;
	
	char szUser[LIC_USERINFO_NAME_COMPANY_MAXLEN];
	char szCompany[LIC_USERINFO_NAME_COMPANY_MAXLEN];
	char szSerial[LIC_OTHER_INFO_MAXLEN];
	char szRegCode[LIC_OTHER_INFO_MAXLEN];
	DWORD dwProd = GetLicenseInfo(szUser, szCompany, szSerial, szRegCode);
	string strProduct;
	switch( dwProd & 0x000000FF )
	{
	case ORGPRODUCTTYPE_EVALUATION:
		strProduct = "Evaluation";
		break;
	case ORGPRODUCTTYPE_STUDENT:
		strProduct = "Student";
		break;
	case ORGPRODUCTTYPE_REGULAR:
		strProduct = "Regular";
		break;
	case ORGPRODUCTTYPE_PRO:
		strProduct = "Professional";
		break;
	default:
		strProduct = "Unknown";
		break;
	}
	GETN_USE(trSys)
	GETN_STR(UserName, "User Name", szUser)
	GETN_READ_ONLY_EX(2)
	GETN_STR(Company, "Company Name", szCompany)
	GETN_READ_ONLY_EX(2)
	GETN_STR(SeriNum, "Serial Number", szSerial)
	GETN_READ_ONLY_EX(2)
	GETN_STR(RegCode, "Register Code", szRegCode)
	GETN_READ_ONLY_EX(2)
	GETN_STR(Product, "Product Version", strProduct)
	GETN_READ_ONLY_EX(2)
	return TRUE;
}
//ユーザ情報と設定を収集するコントロール
BOOL	MySplitter::initUserInfo(TreeNode& trUser)
{
	if ( !trUser )
		return FALSE;
	GETN_USE(trUser)
	GETN_STRLIST(Language, "Language", "English", "|English|German")
	GETN_STR(UserID, "User ID", "")
	GETN_PASSWORD(Password, "Password", "")
	GETN_STR(Email, "Email", "user@originlab.com")
	
	return TRUE;
}

ユーザ定義Splitterダイアログクラスを追加する

splitterダイアログは、splitterコントロールオブジェクトを含み、ダイアログはsplitterコントロールを初期化し、適切なイベントにメッセージを渡します。

//ダイアログ名は、レジストリに設定を保存するのに使用
#define	STR_DLG_NAME	"My Splitter Dialog"
class MySplitterDlg : public MultiPaneDlg
{
public:
	//リソースIDとそのDLLはダイアログリソースを含む
	MySplitterDlg() : MultiPaneDlg(IDD_SAMPLE_SPLITTER_DLG, "ODlg8")
	{
	}
	~MySplitterDlg()
	{
	}
	//ユーザが閉じるまでダイアログを開く
	int	DoModalEx(HWND hParent = NULL)
	{
		//メッセージマップをセット
		InitMsgMap();
		return DoModal(hParent, DLG_NO_DEFAULT_REPOSITION);
	}
	//ダイアログを開く前にコントロールと他の設定を初期化
	BOOL	OnInitDialog();
	//ダイアログ初期化が完了したとき
	BOOL	OnReady();
	//ユーザが'Output'ボタンをクリックしたとき

	BOOL	OnOutput(Control ctrl);
protected:
	DECLARE_MESSAGE_MAP
private:
	MySplitter	m_Splitter;
	
};
//マップダイアログメッセージ
BEGIN_MESSAGE_MAP(MySplitterDlg)
	ON_INIT(OnInitDialog)
	ON_READY(OnReady)
	ON_BN_CLICKED(IDC_LOAD, OnOutput)
END_MESSAGE_MAP
BOOL	MySplitterDlg::OnInitDialog()
{
	//ボタンのテキストを意味のあるテキストに変更
	GetDlgItem(IDC_LOAD).Text = "Output";
	GetDlgItem(IDCANCEL).Text = "Close";
	m_Splitter.Init(IDC_FB_BOX, *this, STR_DLG_NAME);
	return TRUE;
}
BOOL	MySplitterDlg::OnReady()
{
	//ダイアログを更新
	UpdateDlgShow();
	SetInitReady();
	//準備状態を位置とサイズを初期化
	m_Splitter.OnReady();
	return TRUE;
}
BOOL	MySplitterDlg::OnOutput(Control ctrl)
{
	//現在のユーザ設定を出力
	m_Splitter.Output();
	return TRUE;
}

ダイアログを開く

上記のステップの後、すべてのコードを保存し、ビルドし、次の関数を実行して、スプリッターダイアログを実行します。

void	test_MySplitterDlg()
{
	MySplitterDlg dlg;
	dlg.DoModalEx(GetWindow());
}