アカウント統合により過去記事再掲:元の投稿日 2016年03月29日
例えばダイアログのサイズを変更した時
あらあら、まあまあ。
というわけで久々にMFCを触ってて、そういや昔これに対応するクラス作ったなーと。VC++6の時なんだけど。
引っ張りだして使ってみたら、今でも普通に使えたんでQiitaにでも貼り付けとこうというお話。
Doxygenが懐かしい
コメントの**@brief**とかはDoxygenというドキュメンテーションツールで、そういや使ってたなーと懐かしんでおりましたとさ。
stratchControl.hpp
/** @file StretchControl.hpp
@brief CStretchControl 定義ファイル
*/
#ifndef __STRETCHCONTROL_HPP__
#define __STRETCHCONTROL_HPP__
/**
@class CStretchControl
@brief 親ウィンドウ(通常はダイアログ)の伸縮にあわせて、伸縮(または移動)するウィンドウのテンプレートクラス
@param T 適用するウィンドウ(TはCWndの派生クラスである必要があります)
@par 概要:
<BR>
親ウィンドウ(通常はダイアログ)の伸縮にあわせて、伸縮(または移動)するウィンドウの
テンプレートクラス
@par 使い方:
<BR>
伸縮(移動)するウィンドウはサブクラス化をサブクラス化します。<BR>
親ウィンドウが WM_SIZE を受信した時に、このクラスの Resizeメソッドを呼び出し
て下さい。
@par 例:
<BR>
ダイアログのエディットコントロールを対象とする場合<BR>
<BR>
1) C***Dlg に CStretchControl<CEdit>型のメンバ変数を追加<BR>
2) OnInitDialogで SubclassDlgItem を呼び出す<BR>
3) OnSize を実装し、Resizeを呼び出す<BR>
*/
template<class T>
class CStretchControl : public T
{
/** @brief 差分を格納する矩形 */
CRect m_rectDiff;
/** @brief 伸縮タイプ */
UINT m_baseType;
/** @brief 保持された幅 */
LONG m_width;
/** @brief 保持された高さ */
LONG m_height;
public:
enum {
normal = 0x00,
top = 0x01,
left = 0x02,
bottom = 0x04,
right = 0x08,
};
/** @brief 標準のコンストラクタ */
CStretchControl() : T(), m_baseType( 0 ), m_width( 0 ), m_height( 0 ) {
}
protected:
/** @brief SubclassWindow を呼び出す前にサブクラス化することを許します */
virtual void PreSubclassWindow() {
CRect rect, me;
GetParent()->GetClientRect( &rect );
GetWindowRect( &me );
m_width = me.Width();
m_height = me.Height();
GetParent()->ScreenToClient( &me );
m_rectDiff.top = me.top - rect.top;
m_rectDiff.left = me.left - rect.left;
m_rectDiff.bottom = me.bottom - rect.bottom;
m_rectDiff.right = me.right - rect.right;
}
public:
/** @brief 伸縮タイプに従ってサイズ変更を実施します */
void Resize() {
if( !m_hWnd ) {
return;
}
CRect rect, me;
GetParent()->GetClientRect( &rect );
me.top = rect.top + m_rectDiff.top;
me.left = rect.left + m_rectDiff.left;
me.bottom = rect.bottom + m_rectDiff.bottom;
me.right = rect.right + m_rectDiff.right;
if( m_baseType & top ) { me.bottom = me.top + m_height; }
if( m_baseType & left ) { me.right = me.left + m_width; }
if( m_baseType & bottom ) { me.top = me.bottom - m_height; }
if( m_baseType & right ) { me.left = me.right - m_width; }
MoveWindow( &me );
InvalidateRect( NULL );
}
/** @brief 伸縮タイプを設定します
@param ui IN 伸縮タイプ
@par 解説
引数 ui には次の値を連結して指定します<BR>
<BR>
normal = 0x00 標準の伸縮をサポートします<BR>
top = 0x01 上を基点として上下には移動のみを行います<BR>
left = 0x02, 左を基点として左右には移動のみを行います<BR>
bottom = 0x04, 下を基点として上下には移動のみを行います<BR>
right = 0x08, 右を基点として左右には移動のみを行います<BR>
<BR>
top, bottom の何れかが指定された場合、ウィンドウは最初の高さを保持します。<BR>
left, right の何れかが指定された場合、ウィンドウは最初の幅を保持します。<BR>
*/
void setBase( UINT ui ) {
m_baseType = ui;
}
/** @brief 伸縮タイプ基点を左下に設定します
*/
void setBase_BottomLeft() {
m_baseType = bottom | left;
}
/** @brief 伸縮タイプ基点を下に設定します */
void setBase_Bottom() {
m_baseType = bottom;
}
/** @brief 伸縮タイプ基点を右下に設定します
*/
void setBase_BottomRight() {
m_baseType = bottom | right;
}
/** @brief 伸縮タイプ基点を右に設定します */
void setBase_Right() {
m_baseType = right;
}
};
#endif // __STRETCHCONTROL_HPP__
使い方
コメントに書いてある通りなんだけど、
・C***Dlg に CStretchControl型のメンバ変数を追加
・OnInitDialogで SubclassDlgItem を呼び出す
・OnSizeでResizeを呼び出す
これだけ。
お手軽。
もしクラスウィザードからCEditとかのコントロール変数を追加した場合は、自分でSubclassDlgItemを呼び出す必要はナッシング。
CEdit m_hoge;
↓
CStretchControl<CEdit> m_hoge;
こんな感じにするだけでよろしい。