こんばんはぺろりです。
今日はREAPERのPreferencesに自分のページを追加する方法を説明します。

といってもやるべきことはシンプルで、以下の二つです。
・ページ毎にウィンドウ作成コールバックを実装
・prefs_page_register_t を "prefpage" という名前で登録(plugin_register)
 (この構造体のメモリはどこかに保持しておく)

■Preferencesページ情報の登録
まずはコードを見てみましょう。
prefs_page_register_t prefPageMain; // メインページ用のデータ(どこかに保持しておく)
prefs_page_register_t prefPageChild; // 子供ページ用のデータ(どこかに保持しておく)

// 大項目
memset( &prefPageMain, 0, sizeof(prefPageMain) );
prefPageMain.idstr        = "PREF_PELORI_MAIN"; // ID名(任意)
prefPageMain.displayname  = "Pelori"; // Preferenceに表示される名前
prefPageMain.create       = OnCreatePrefWndMain; // Window生成コールバック
prefPageMain.childrenFlag = true; // 子供がいる
// 登録
plugin_register( "prefpage", &prefPageMain );

// 小項目(子供ページ)
memset( &prefPageChild, 0, sizeof(prefPageChild) );
prefPageChild.idstr        = "PREF_PELORI_CHILD1";
prefPageChild.par_idstr    = prefPageMain.idstr; // 親のIDを指定
prefPageChild.displayname  = "Sub1";
prefPageChild.create       = OnCreatePrefWndChild;
prefPageChild.childrenFlag = false; // 子供はいない
// 登録
plugin_register( "prefpage", &prefPageChild );

ここではメインの大項目とその1階層下に表示できる小項目(子供ページ)を追加しています。
子供ページが不要であれば大項目のページ登録だけでも問題ありません(この場合は prefPageMain.childrenFlag = false にする)。

登録できると以下のような感じにPreferencesウィンドウに表示されることになります。
QS_20180124-022801

次にウィンドウ生成時のコールバック実装ですが、引数に親ウィンドウとなるHWNDが渡されてきますので、このウィンドウに子ウィンドウとしてセットしてやればOKです。
また、呼ばれるタイミングはページの項目を選択した時です(上の例だと"Pelori"や"Sub1"選択時)。
こちらで作ったウィンドウが勝手に破棄されたりはしないようなので、あらかじめウィンドウは作成しておいて、このコールバックで渡されてきたHWNDに毎回子ウィンドウとしてくっつけてやればよいようです。
HWND OnCreatePrefWndMain( HWND hWndParent )
{
	// あらかじめ作っておいたウィンドウのハンドル(ウィンドウ作成まわりは割愛)
	HWND hWndPage;
	// SetParent()の前にWS_CHILDを設定する必要がある
	SetWindowLong( hWndPage, GWL_STYLE,
		 (GetWindowLong(hWndPage, GWL_STYLE) | WS_CHILD) );
	SetParent( hWndPage, hWndParent );
	return hWndPage;
}
小項目(子ページ)側もやることは同様です。

■Preferences情報の登録解除
DLLエントリポイントの終了処理を書くあたりで、prefs_page_register_t のデータの登録解除や自分で作成したウィンドウの破棄等を行います。
plugin_register( "-prefpage", &prefPageChild );
plugin_register( "-prefpage", &prefPageMain );

これでPreferencesウィンドウへのページ追加に関しては完了です。

Preferencesまわりで書ける処理はこの程度のようで、例えば「Preferencesウィンドウが閉じられた」とかいったタイミングを検知する方法は特に提供されていない(?)ようです。
なので、Preferences設定の保存や復帰も自分でいい感じのタイミングに手動で実装する必要があるのではないかと思います。

というところで今回はここまで。
また次回の記事でお会いしましょう。