Skip to content

Instantly share code, notes, and snippets.

@bg1bgst333
Created November 21, 2025 01:43
Show Gist options
  • Select an option

  • Save bg1bgst333/a505b29f3280ca788d10106c0b6029fd to your computer and use it in GitHub Desktop.

Select an option

Save bg1bgst333/a505b29f3280ca788d10106c0b6029fd to your computer and use it in GitHub Desktop.
CMultiViewItem::Destroy
// ヘッダのインクルード
// 既定のヘッダ
#include <windows.h> // 標準WindowsAPI
#include <stdio.h> // C標準入出力
#include <commctrl.h> // コモンコントロール
// 独自のヘッダ
#include "MainWindow.h" // CMainWindow
#include "FileDialog.h" // CFileDialog
#include "CustomEdit.h" // CCustomEdit
#include "resource.h"
// ウィンドウクラス登録関数RegisterClass.
BOOL CMainWindow::RegisterClass(HINSTANCE hInstance) {
// ウィンドウクラス名は"CMainWindow".
return CWindow::RegisterClass(hInstance, _T("CMainWindow")); // CWindow::RegisterClassでウィンドウクラス名"CMainWindow"を登録.
}
// ウィンドウクラス登録関数RegisterClass.(メニュー名指定バージョン)
BOOL CMainWindow::RegisterClass(HINSTANCE hInstance, LPCTSTR lpctszMenuName) {
// メニュー名はlpctszMenuName.
return CWindow::RegisterClass(hInstance, _T("CMainWindow"), lpctszMenuName); // CWindow::RegisterClassで, ウィンドウクラス名"CMainWindow", メニュー名lpctszMenuNameを登録.
}
// コンストラクタCMainWindow()
CMainWindow::CMainWindow() {
// メンバの初期化.
m_hInstance = NULL;
m_pMainMenu = NULL;
m_pMultiView = NULL;
}
// デストラクタ~CMainWindow()
CMainWindow::~CMainWindow() {
// メンバの終了処理.
Destroy(); // Destroyで子ウィンドウの破棄.
}
// ウィンドウ作成関数Create.(ウィンドウクラス名省略バージョン.)
BOOL CMainWindow::Create(LPCTSTR lpctszWindowName, DWORD dwStyle, int x, int y, int iWidth, int iHeight, HWND hWndParent, HMENU hMenu, HINSTANCE hInstance) {
// ウィンドウクラス名は"CMainWindow".
return CWindow::Create(_T("CMainWindow"), lpctszWindowName, dwStyle, x, y, iWidth, iHeight, hWndParent, hMenu, hInstance); // CWindow::Createにウィンドウクラス名"CMainWindow"を指定.
}
// ウィンドウ作成関数CreateEx.
BOOL CMainWindow::CreateEx(DWORD dwExStyle, LPCTSTR lpctszWindowName, DWORD dwStyle, int x, int y, int iWidth, int iHeight, HWND hWndParent, HMENU hMenu, HINSTANCE hInstance) {
// ウィンドウクラス名は"CMainWindow".
return CWindow::CreateEx(dwExStyle, _T("CMainWindow"), lpctszWindowName, dwStyle, x, y, iWidth, iHeight, hWndParent, hMenu, hInstance); // CWindow::CreateExにウィンドウクラス名"CMainWindow"を指定.
}
// ウィンドウ破棄関数Destroy
BOOL CMainWindow::Destroy() {
// 変数の初期化.
BOOL bRet = FALSE; // bRetをFALSEで初期化.
// DestroyChildrenを分けたので, 自身のウィンドウ破棄は問題ない.
// まず子ウィンドウの破棄.
DestroyChildren();
// 自身のウィンドウ破棄.
bRet = CWindow::Destroy(); // 戻り値をbRetに格納.
// bRetを返す.
return bRet;
}
// 子ウィンドウ破棄関数DestroyChildren
BOOL CMainWindow::DestroyChildren() {
// 変数の初期化.
BOOL bRet = FALSE; // bRetをFALSEで初期化.
// メンバの終了処理.
if (m_pMultiView != NULL) {
bRet = m_pMultiView->Destroy();
delete m_pMultiView;
m_pMultiView = NULL;
}
// 破棄したらTRUEを返す.
if (bRet) { // TRUEなら.
return TRUE; // TRUEを返す.
}
// 破棄しなければ, CWindowのDestroyChildrenを返す.
return CWindow::DestroyChildren(); // CWindow::DestroyChildrenを返す.
}
// ウィンドウの作成が開始された時.
int CMainWindow::OnCreate(HWND hwnd, LPCREATESTRUCT lpCreateStruct) {
// 親クラスのOnCreateを呼ぶ.
m_hInstance = lpCreateStruct->hInstance;
int iRet = CWindow::OnCreate(hwnd, lpCreateStruct); // CWindow::OnCreateを呼び, 戻り値をiRetに格納.
m_pMainMenu = GetMenu(); // CWindow::GetMenuでm_pMainMenu取得.
if (m_pMainMenu == NULL) { // メニューハンドルが無い場合は, m_pMainMenuがNULLになる.
m_pMainMenu = new CMenu();
BOOL bRet = m_pMainMenu->LoadMenu(lpCreateStruct->hInstance, IDM_MAINMENU);
if (bRet) {
SetMenu(m_pMainMenu);
AddCommandHandler(ID_ITEM_FILE_OPEN, 0, (int(CWindow::*)(WPARAM, LPARAM)) & CMainWindow::OnFileOpen);
// CMultiViewの生成.
m_pMultiView = new CMultiView();
m_pMultiView->Create(_T(""), 0, 0, 0, 640, 480, hwnd, (HMENU)IDC_MULTIVIEW, m_hInstance);
// アイテムの追加.
m_pMultiView->Add(_T("Item0"), 20, 20, 320, 240, m_hInstance);
// マルチビューアイテムの取得.
CMultiViewItem* pItem0 = m_pMultiView->Get(0);
// マルチビューアイテム内にウィンドウを配置.
CCustomEdit* pCustomEdit0 = new CCustomEdit();
pCustomEdit0->Create(_T("Item0-CustomEdit0"), WS_CHILD | WS_VISIBLE | WS_HSCROLL | WS_VSCROLL | ES_MULTILINE | ES_WANTRETURN | ES_AUTOHSCROLL | ES_AUTOVSCROLL, 10, 10, 80, 80, pItem0->m_hWnd, (HMENU)WM_APP + 200, m_hInstance);
pItem0->m_mapChildMap.insert(std::make_pair(_T("CustomEdit0"), pCustomEdit0));
CCustomEdit* pCustomEdit1 = new CCustomEdit();
pCustomEdit1->Create(_T("Item0-CustomEdit1"), WS_CHILD | WS_VISIBLE | WS_HSCROLL | WS_VSCROLL | ES_MULTILINE | ES_WANTRETURN | ES_AUTOHSCROLL | ES_AUTOVSCROLL, 400, 300, 80, 80, pItem0->m_hWnd, (HMENU)WM_APP + 201, m_hInstance);
pItem0->m_mapChildMap.insert(std::make_pair(_T("CustomEdit1"), pCustomEdit1));
}
}
return iRet; // iRetを返す.
}
// ウィンドウが破棄された時.
void CMainWindow::OnDestroy() {
// メニューハンドラの削除.
DeleteCommandHandler(ID_ITEM_FILE_OPEN, 0);
// メニューの終了処理.
CMenu::DeleteMenuHandleMap();
m_pMainMenu = NULL;
// CWindowのOnDestroyを呼ぶ.
CWindow::OnDestroy(); // CWindow::OnDestroyを呼ぶ.
}
// ウィンドウのサイズが変更された時.
void CMainWindow::OnSize(UINT nType, int cx, int cy) {
// マルチビューをメインウィンドウのクライアント領域サイズにリサイズ.
if (m_pMultiView != NULL) {
m_pMultiView->MoveWindow(0, 0, cx, cy);
}
}
// ウィンドウが閉じられる時.
int CMainWindow::OnClose() {
// メッセージボックスで"Close CMainWindow OK?"と表示.
int iRet = MessageBox(m_hWnd, _T("Close CMainWindow OK?"), _T("CMultiViewItem"), MB_OKCANCEL); // MessageBoxで"Close CMainWindow OK?"と表示し, 戻り値をiRetに格納.
if (iRet != IDOK) { // OK以外.(Cancelなど.)
return -1; // -1を返す.
}
// このウィンドウの破棄.(OnCloseの後, ウィンドウの破棄処理が勝手に行われるので, Destroyは不要なのでコメントアウト.)
//Destroy(); // Destroyでこのウィンドウの破棄処理.
// OKなので閉じる.
return CWindow::OnClose(); // 親クラスのOnCloseを呼ぶ.(親クラスのOnCloseは常に閉じる処理になっている.)
}
// 開くが選択された時.
int CMainWindow::OnFileOpen(WPARAM wParam, LPARAM lParam) {
// "開く"ダイアログ
CFileDialog dlg(TRUE, NULL, NULL, OFN_HIDEREADONLY, _T("Text Files(*.txt)|*.txt|All Files(*.*)|*.*||"));
INT_PTR ret = dlg.DoModal();
if (ret == IDOK) {
MessageBox(m_hWnd, dlg.GetOFN().lpstrFile, _T("CMultiViewItem"), MB_OK);
}
// 0を返す.
return 0; // 処理したので0.
}
// ヘッダのインクルード
// 独自のヘッダ
#include "MultiViewItem.h" // CMultiViewItem
// コンストラクタCMultiViewItem
CMultiViewItem::CMultiViewItem() : CUserControl() {
// メンバの初期化.
m_mapChildMap.clear(); // m_mapChildMapをクリア.
}
// デストラクタ~CMultiViewItem
CMultiViewItem::~CMultiViewItem() {
// メンバの終了処理
Destroy(); // Destroyでこのウィンドウの終了処理をする.
}
// ウィンドウクラス登録関数RegisterClass.
BOOL CMultiViewItem::RegisterClass(HINSTANCE hInstance) {
// ウィンドウクラスの登録.
return CUserControl::RegisterClass(hInstance, _T("CMultiViewItem")); // CUserControl::RegisterClassで登録.
}
// ウィンドウクラス登録関数RegisterClass(背景ブラシハンドル指定バージョン.)
BOOL CMultiViewItem::RegisterClass(HINSTANCE hInstance, HBRUSH hbrBackground) {
// ウィンドウクラス名にはlpctszClassName, 背景ブラシハンドルにはhbrBackgroundを指定.
return CUserControl::RegisterClass(hInstance, _T("CMultiViewItem"), hbrBackground); // CUserControl::RegisterClassで登録.
}
// ウィンドウ作成関数Create.
BOOL CMultiViewItem::Create(LPCTSTR lpctszWindowName, DWORD dwStyle, int x, int y, int iWidth, int iHeight, HWND hWndParent, HMENU hMenu, HINSTANCE hInstance) {
// ウィンドウの作成.
return CUserControl::Create(_T("CMultiViewItem"), lpctszWindowName, dwStyle | WS_CHILD | WS_VISIBLE, x, y, iWidth, iHeight, hWndParent, hMenu, hInstance); // CWindow::Createで作成.
}
// ウィンドウの破棄と終了処理関数Destroy.
BOOL CMultiViewItem::Destroy() {
// アイテムの一斉削除.
std::map<tstring, CWindow*>::iterator itor = m_mapChildMap.begin(); // イテレータitorをbegin()で初期化.
while (itor != m_mapChildMap.end()) { // end()まで.
if (itor->second != NULL) { // 値がNULLでなければ.
itor->second->Destroy(); // Destroyで破棄処理.
delete itor->second; // 解放.
itor->second = NULL; // NULLをセット.
}
itor++; // 進む.
}
m_mapChildMap.clear(); // クリア.
// 親クラスのDestroyを呼ぶ.
return CUserControl::Destroy(); // CUserControl::Destroyを呼ぶ.
}
// ウィンドウの作成が開始された時.
int CMultiViewItem::OnCreate(HWND hwnd, LPCREATESTRUCT lpCreateStruct) {
// 常にウィンドウ作成に成功するものとする.
return 0; // 0を返すと, ウィンドウ作成に成功したということになる.
}
// ウィンドウが破棄された時.
void CMultiViewItem::OnDestroy() {
// 親クラスのOnDestroyを呼ぶ.
CUserControl::OnDestroy(); // CUserControl::OnDestroyを呼ぶ.
}
// ウィンドウのサイズが変更された時.
void CMultiViewItem::OnSize(UINT nType, int cx, int cy) {
// 親ウィンドウの既定処理.
CUserControl::OnSize(nType, cx, cy); // CUserControl::OnSizeを呼ぶ.
// ウィンドウサイズの取得.
RECT rc = { 0 };
GetWindowRect(m_hWnd, &rc);
int iWidth = rc.right - rc.left;
int iHeight = rc.bottom - rc.top;
// UM_SIZECHILDを投げる.
WPARAM wParam;
wParam = MAKEWPARAM(iWidth, iHeight);
SendMessage(GetParent(m_hWnd), UM_SIZECHILD, wParam, (LPARAM)m_hWnd);
}
// 子から親へウィンドウサイズ変更の要求が発生した時.
void CMultiViewItem::OnSizeChild(WPARAM wParam, LPARAM lParam) {
// 自身のRECT取得.
RECT rc = { 0 };
GetWindowRect(m_hWnd, &rc);
// 取り出し.
HWND hWndChild = (HWND)lParam;
// 子ウィンドウ(CCustomEdit)のRECTを取得.
RECT rcChild = { 0 };
GetWindowRect(hWndChild, &rcChild);
// 子(CCustomEdit)の右下を自身(CMultiViewItem)のクライアント座標に変換.
POINT ptChildRB = { 0 };
ptChildRB.x = rcChild.right;
ptChildRB.y = rcChild.bottom;
ScreenToClient(GetParent(hWndChild), &ptChildRB);
// 親(CMultiViewItemsPanel)のクライアント座標に変換.
POINT pt = { 0 };
pt.x = rc.left;
pt.y = rc.top;
ScreenToClient(GetParent(m_hWnd), &pt);
// 自身のウィンドウサイズを変更.
int w = rc.right - rc.left;
int h = rc.bottom - rc.top;
if (w < ptChildRB.x) {
w = ptChildRB.x;
}
if (h < ptChildRB.y) {
h = ptChildRB.y;
}
MoveWindow(pt.x, pt.y, w, h, TRUE);
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment