以下の内容はhttps://donadona.hatenablog.jp/entry/2026/03/22/133348より取得しました。


Redmineダウンローダ開発メモ(9) 正規ビューワーの開発-CMFCTabCtrlの表示方法・サイズ変更方法

Redmineダウンローダ開発メモ(8) 簡易ビューワーの開発-ひとくぎり - ドナドナされるプログラマのメモの続き。

個別Issueしか開けなかった簡易ビューワーをもとに、複数のIssueを開いたりRedmineプロジェクト全体に対する検索ができる正規ビューワーを作る。

CMFCTabCtrlでのタブコントロール表示方法

複数のIssueを開く機能はタブコントロールで実現する。自分が今まで使ってきたCTabCtrlはドキュメントごとのタブ生成・削除には不向き(タブに「閉じる」アイコンを付けられないなど)なので、今回はCMFCTabCtrl(とベースクラス: CMFCBaseTabCtrl)を使うことにした。

しかし、CMFCTabCtrlはリソースエディタでサポートされていない。そのうえ、CMFCTabCtrlとCTabCtrlは継承関係にないため、普通のタブコントロールを配置したうえでクラスをCMFCTabCtrlにしてもうまくいかない。

以下、変数追加時のクラスをCMFCTabCtrlにした場合の挙動。OnInitDialog内にてタブコントロール変数のm_hWndからCreate()時に登録されたウィンドウクラス名を調べたところ、本来ならAfx:TabWnd:83e70000:8:10003:10みたいになっているはずなのにSysTabControl32となっていた。これはCTabCtrlのCreate()実行時に登録されるウィンドウクラスなので、どうやら変数追加時のクラスをCMFCTabCtrlにしてもDDX_ControlではCTabCtrlのCreate()を呼び出すようだ。だめじゃん。

ということは、DDX_Controlは使わずに手動でOnInitDialog内でCreateすれば解決のはず・・・なのだが、まだ表示されない。少し悩んだあと、描画は非標準コントロールが実施していることに気づき、リソースエディタ上のタブコントロールを「非表示」にしてみた。ビンゴ!無事、CMFCTabCtrlが表示されるようになった。無事解決。

	// CMFCTabCtrlの生成
	CRect rect;
	GetDlgItem(IDC_TAB_VIEWER)->GetWindowRect(&rect);
	ScreenToClient(&rect);
	if (!m_CtrlTabViewer.Create(CMFCTabCtrl::STYLE_3D, rect, this, IDC_TAB_VIEWER, CMFCTabCtrl::LOCATION_TOP, WS_VISIBLE | WS_CHILD)) {
		TRACE(_T("Failed to create tab control\n"));
		return FALSE;
	}

タブコントロールの「表示」を非表示にすることでCMFCTabCtrlを表示できた

CMFCTabCtrlのサイズ変更方法

CMFCTabCtrlはOnSize()を受け取ると各タブに登録したCWnd*に対しWM_SIZEを送出し適切な大きさにしてくれる。すばらしい。だがしかし、1点だけ注意事項がある。リソースエディタ上でサイズ調整の種類を「両方」に設定しても、ダイアログサイズ変更時にCMFCTabCtrlへWM_SIZEが飛ばないため、CMFCTabCtrlのOnSize()が呼び出されないのだ。マイクロソフトがCTabViewと無関係に設計したツケがここにも・・・。しょうがないので、ダイアログ側のOnSize()から手動でCMFCTabCtrlの大きさを変更する。すなわち、ダイアログのサイズ変更により自動でサイズ変更されたIDC_TAB_VIEWERからサイズを取得し、CMFTabCtrlへ変更後のサイズを与える。

void CRedmineViewerDlg::OnSize(UINT nType, int cx, int cy)
{
	CDialogEx::OnSize(nType, cx, cy);

	if (m_hWnd == NULL || m_CtrlTabViewer.m_hWnd == NULL)
		return;

	CRect rect;
	
	GetDlgItem(IDC_TAB_VIEWER)->GetWindowRect(&rect);
	ScreenToClient(&rect);
	m_CtrlTabViewer.MoveWindow(&rect);
}

なお、WebView2と連携させるときは、CMFCTabCtrlに登録したCWnd子クラスより手動でWebView2のput_Bounds()を呼び出す。この時に使うCRect領域情報は、CMFcTabCtrl::GetWndArea()で一発取得できる。楽。

	CRect rect;
	m_pParent->m_CtrlTabViewer.GetWndArea(rect);
	m_WebViewController->put_Bounds(rect);

次: 

Redmineダウンローダ開発メモ(10) 正規ビューワーの開発-タブ追加の流れ - ドナドナされるプログラマのメモ




以上の内容はhttps://donadona.hatenablog.jp/entry/2026/03/22/133348より取得しました。
このページはhttp://font.textar.tv/のウェブフォントを使用してます

不具合報告/要望等はこちらへお願いします。
モバイルやる夫Viewer Ver0.14