Naoと申します。
ただ今、VisualStudio2005のMFCにおいてSDIプログラムを作成しています。
CSplitterWndを使用して、4分割いたしました。
現在は4分割という事で、分割バーは3つあるのですが、その内の一本は固定したいのです。
その分割バーに対してWM_LBUTTONDOWNを無効にするやり方で出来そうなのですが、
その分割バーだけを無効にする方法はどのようにすればいいのでしょうか?
ご教授宜しくお願いいたします。
4分割しているということなので、
CMainFrameクラスでCSplitterWnd型のメンバ変数を3つ用意しているのではないでしょう
か?
その中のひとつを(WM_LBUTTONDOWN,WM_MOUSEMOVEをインプリメントした)CSplitterWndを
派生したクラスに変更してあげればいいだけでうまくいくと思います。
方法1
WM_LBUTTONDOWNが来た時に、カーソルの座標とペインの幅や高さを元に、
計算すればどのバーか判断できそう。
方法2
CSplitterWndをサブクラス化して、バーが必ず無効になるクラスを作る。
そのペインに通常のCSplitterWndを入れてやれば、一本だけ固定された
バーが得られるでしょう。私だったらこの方法でやります。
ご参考
http://athomejp.com/goldfish/mfc/cobject/3viewwindow.asp
http://athomejp.com/goldfish/mfc/cobject/nomove.asp
Blueさん たいちうさん
回答してくださってありがとうございます。
Blueさん
>4分割しているということなのでCMainFrameクラスでCSplitterWnd型のメンバ変数を3つ
用意しているのではないでしょうか?
はい。Blueさんのおっしゃる通りです。MainFrame.hの中において、
CSplitterWnd m_wndSplitter1,m_wndSplitter2,m_wndSplitter3
とメンバ変数を用意しております。
>その中のひとつを(WM_LBUTTONDOWN,WM_MOUSEMOVEをインプリメントした)CSplitterWndを
派生したクラスに変更してあげればいいだけでうまくいくと思います。
すみません。間違っているかも知れませんが、自分が思った事を記載します。
CSplitterWnd m_wndSplitter1,m_wndSplitter2
CSplitterWnd1(カスタム)m_wndSpliter3
このようにするという事でしょうか?
たいちうさん
方法2の
>CSplitterWndをサブクラス化して
この部分ですが、Blueさんのおっしゃっている[インプリメントした]という意味で
しょうか?
勉強不足ですみません。もし同じでしたらこの方法を試してみます。
> このようにするという事でしょうか?
そうです。
一度試してだめだったら質問してください。
やらないで質問は無駄が多くなりますので。
>一度試してだめだったら質問してください。
やらないで質問は無駄が多くなりますので。
申し訳ありませんでした。以後気をつけます。
上手く行きませんでした。やった手順を記載します。
①新しいクラスとしてCSplitterWnd1というクラスを追加しました。
②CSplitterWnd1のメンバ変数として、m_wndSplitter2を追加しました。
③CSplitterWnd1のイベントとして、WM_LBUTTONDOWNを追加して、この関数の中の
記述をコメントアウトしました。
たいちうさんの参考リンクではこのような感じだったので、真似をしてみました。
でも分割バーは動いてしまいます。
このように記述しました。
MainFrame.h内
CSplitterWnd m_wndSplitter,m_wndSplitter1; ///変更前m_wndSplitter2があった
CSplitterWnd1 m_wndSplitter2; ///追記した部分
MainFrame.cpp内
BOOL CMainFrame::OnCreateClient(LPCREATESTRUCT lpcs, CCreateContext* pContext)
{
if(!m_wndSplitter.CreateStatic(this,1,2))
return FALSE;
if(!m_wndSplitter1.CreateStatic(&m_wndSplitter,2,1,WS_CHILD | WS_VISIBLE |
WS_BORDER,m_wndSplitter.IdFromRowCol(0,1)))
return FALSE;
if(!m_wndSplitter2.CreateStatic(&m_wndSplitter1,2,1,WS_CHILD | WS_VISIBLE |
WS_BORDER,m_wndSplitter1.IdFromRowCol(1,0)))
return FALSE;
if(!m_wndSplitter.CreateView(0,0,RUNTIME_CLASS(ClView),CSize(120,100),pContext)
||
!m_wndSplitter1.CreateView(0,0,RUNTIME_CLASS(CView),CSize(100,200),pContext) ||
!m_wndSplitter2.CreateView(0,0,RUNTIME_CLASS(CView),CSize(100,40),pContext) ||
!m_wndSplitter2.CreateView(1,0,RUNTIME_CLASS(CView),CSize(100,150),pContext))
{
m_wndSplitter.DestroyWindow();
return FALSE;
}
return TRUE;
}
このような感じになっているのですが、分割バーを固定したい部分は
!m_wndSplitter2.CreateView(1,0,RUNTIME_CLASS(C***View),CSize(100,150),pContext)
のペインなのですが、普通に動いてしまいます。
どのようにすれば、いいのでしょうか?
長くなってしまいましたが、宜しくお願いいたします。
私の方法2はBlueさんの方法とかぶってしまいましたね。同じ意味です。
> たいちうさんの参考リンクではこのような感じだったので、真似をしてみました。
> でも分割バーは動いてしまいます。
とりあえず、入れ子にしないで(CSplitterWnd1のみで)、
動かないようにはできましたか?
> CSplitterWnd1のメンバ変数として、m_wndSplitter2を追加しました。
CSplitterWndとそのサブクラスのインスタンスは、
CMainFrameのメンバ変数にするのが良いと思います。
# 入れ子のSplitter Windowを1つのクラスと考えて設計すると、
# 内側は外側のメンバ変数とすべきかもしれませんが、
# まず、サンプルに近い形で完成させて、
# 余力があれば、カプセル化を進めましょう。
たいちうさんご回答ありがとうございます。
たいちうさんの前の回答に2番目に貼ってあったリンク(2分割でもバー無効)
も出来ませんでした。
一度プロジェクトを作成し直してシンプルにそのリンクの内容を実行しましたけど、
分割バーは固定されませんでした。
/////////////2分割ソース///////////////////////////
~CMainFrame.h内~
CSplitterWnd m_wndSplitter1;
~CMainFrame.cpp内~
BOOL CMainFrame::OnCreateClient(LPCREATESTRUCT lpcs, CCreateContext* pContext)
{
if (!m_wndSplitter1.CreateStatic(this, 1, 2)) return FALSE;
if (!m_wndSplitter1.CreateView(
0,0,
RUNTIME_CLASS(CSplitter1View),
CSize(100,100), pContext)) return FALSE;
if (!m_wndSplitter1.CreateView(
0, 1,
RUNTIME_CLASS(CSplitter1View),
CSize(0,0), pContext)) return FALSE;
return TRUE;
}
////////////////////////////ここまで//////////////////////////
///////////////////リンク先の作業////////////////////////////
①新しいクラスを作成しました。作成したクラスCSplitterWndOrgに対して
~SplitterWndOrg.h内~
class CSplitterWndOrg : public CSplitterWnd /////CWndをCSplitterWndに変更
~SplitterWndOrg.cpp内~
BEGIN_MESSAGE_MAP(COrgSplitterWnd,CSplitterWnd); 上記と同じ変更
②CSplitterWndOrgのイベントにWM_LBUTTONDOWNを追加しました。
void COrgSplitterWnd::OnLButtonDown(
UINT nFlags, CPoint point)
{
//CSplitterWnd ::OnLButtonDown(nFlags, point); ///コメントアウトしました。
}
これで一応バーは動かなくなると記載されているのですが、動いてしまいます。
なにか記述が足りないのでしょうか?
ご教授していただけますでしょうか?宜しくお願いいたします。
>これで一応バーは動かなくなると記載されているのですが、動いてしまいます。
>CSplitterWnd m_wndSplitter1;
を
CSplitterWndOrg m_wndSplitter1;
に書き換えていますか?
>CSplitterWndOrg m_wndSplitter1;
に書き換えていますか?
この部分を書き換えていませんでした。
MainFrm.h内の
CSplitterWnd m_wndSplitter1を CSplitterWndOrg m_wndSplitter1に変更した
所、エラーが発生しました。
mainfrm.h(42) : error C2146 構文エラー ';'が識別子'm_wndSplitter1'の前に必要です。
mainfrm.h(42) : error C4430 型指定子がありません -intと仮定しました。
mainfrm.h(112) : error C2065 'm_wndSplitter1': 定義されていない識別子です。
mainfrm.h(42) CSplitterWndOrg m_wndSplitter1 //// この場所
mainfrm.h(112) if(!m_wndSplitter1.CreateStatic(this,1,2)) return FALSE //この場所
こんな感じのエラーが出てしまいヘッダファイルのインクルードし忘れかと思い、
新しく作ったクラスとMainFrm.h内に新しく作成したクラスのヘッダファイルをインク
ルードしたのですが、エラーが増減しませんでした。
宜しくお願いいたします。
>エラーが発生しました。
ヘッダファイル(SplitterWndOrg.h)をインクルードしていますか?
インクルードしないと、CSplitterWndOrgが何者かはCMainFrameで
理解できないので当然エラーになります。
# ちゅうか、基本なのでは?
すみません、読み落としていたようです。
>こんな感じのエラーが出てしまいヘッダファイルのインクルードし忘れかと思い、
>新しく作ったクラスとMainFrm.h内に新しく作成したクラスのヘッダファイルをインク
>ルードしたのですが、エラーが増減しませんでした。
本当にそうですか?
リビルドしても同じですか?
インクルードしているファイルは正しいですか?
(SplitterWndOrgの定義の書かれていないヘッダファイルではないか?)
Blueさん
多分
~SplitterWndorg.h内~
IMPLEMENT_DYNAMIC(CSplitterWndOrg,CWnd)
CSplitterWndOrg::CSplitterWndOrg()
{
}
CSplitterWndOrg::~CSplitterWndOrg()
{
}
BEGIN_MESSAGE_MAP(CSplitterWndOrg,CSplitterWnd)
ON_WM_LBUTTONDOWN()
END_MESSAGE_MAP()
void CSplitterWndOrg::OnLButtonDown(UINT nFlags,CPoint point);
{
//CSplitterWnd::OnLButtonDown(nFlags,point);
}
このような感じになっているCSplitterWndOrg.hをMainFrm.cppにインクルード
しているのですが、何か間違っているでしょうか?
宜しくお願いいたします。
>~SplitterWndorg.h内~
ってSplitterWndorg.cppではないでしょうか?
class CSplitterWndOrg : public CSplitterWnd
と記述があるファイルをインクルードしないとだめですよ?
class CSplitterWndOrg : public CSplitterWnd となっているのなら、
1つ間違い見っけ。
× IMPLEMENT_DYNAMIC(CSplitterWndOrg,CWnd)
○ IMPLEMENT_DYNAMIC(CSplitterWndOrg,CSplitterWnd)
その他のマクロも、チェックしてください。