こんにちわ,shogoと申します.
開発環境はWinXP,VC7,MFCです.
CDialogから派生したクラスのOnCreate関数の内部で,
CViewから派生したクラスをCreateして,
貼り付けるコードを書いたのですが,うまくいきませんでした.
BORDERを指定すると,枠は見えるが,Viewの中身が見えないという状態です.
(Dialog以外では,うまくいくのを流用したのでCreateのコードは正しいと思います.)
CDialogにCViewを貼り付けることはできないのでしょうか?
よろしくお願いします.
> こんにちわ
こんにちは.
# 少なくとも,技術系のまじめなサイトで「こんにちわ」はやめましょうよ.
> CDialogから派生したクラスのOnCreate関数の内部で,
> CViewから派生したクラスをCreateして,
> 貼り付けるコードを書いたのですが,うまくいきませんでした.
うまくいかなかったコードを書いて下されば,何が問題なのかはっきりするかも知れま
せん.
それがなければ,推測するしかありません.
> BORDERを指定すると,枠は見えるが,Viewの中身が見えないという状態です.
WS_VISIBLEは指定してますか?
それから,CxxxDialog::OnInitDialogの中で書いた方が良いと思います?
> (Dialog以外では,うまくいくのを流用したのでCreateのコードは正しいと思いま
す.)
正しいならばうまくいくはずではないですか?
プログラミングにあたって,根拠のない判断はとても危険です.
> CDialogにCViewを貼り付けることはできないのでしょうか?
できます.
すいません.訂正です.
誤:それから,CxxxDialog::OnInitDialogの中で書いた方が良いと思います?
正:それから,CxxxDialog::OnInitDialogの中で書いた方が良いと思います.
(疑問形でなく,意見です)
shogoです.
monkeyさん,レスありがとうございます.
> こんにちわ
につきましては,普通に間違えていました.
申し訳ありません.
本題ですが,OnCreate関数ではなく,
OnInitDialogの中でCreateのコードを書きましたら,うまくいきました.
ありがとうございました.
解決をチェックしておいて申し訳ないですが,
追加で質問です.
表示はされましたが,そのViewをクリックすると,なぜかエラーが出ます.
ちなみに,OnInitDialogの中身は,次の通りです.
BOOL CXXXDialog::OnInitDialog()
{
CDialog::OnInitDialog();
// TODO : ここに初期化を追加してください
XXXView = (CXXXView*)RUNTIME_CLASS(CXXXView)->CreateObject();
int x=10,y=10,width=400,height=300;
CRect rect(x,y,x+width,y+height);
if (!XXXView->Create(NULL, NULL, WS_CHILD | WS_VISIBLE,
rect, this, 10000, NULL)){
DestroyWindow();
}
return TRUE; // return TRUE unless you set the focus to a control
// 例外 : OCX プロパティ ページは必ず FALSE を返します。
}
(エラーはFile:viewcore.cppのLine:250と書いてありました)
原因の見当が付かないので原因と思われること,
また,これについての対策を教えていただけないでしょうか?
よろしくお願いします.
> そのViewをクリックすると,なぜかエラーが出ます.
ビューをクリックしたときのエラーならば,ビュークラスの方が怪しい.
CXXXViewクラスでは,どんな定義をしていますか?
> どんな定義
とは具体的に,何のことでしょうか?
自分で宣言した関数など,という解釈ですと,
変数には,CStaticやCButton.
関数は,実際にCStaticなどをCreateする関数
を宣言しています.
他は何もいじっていません.
「実際にCStaticなどをCreateする関数」というのを呼んでも呼ばなくても,
エラーは出てしまいます.
また,DialogからViewをCreateするときに,DocumentをNULLで指定したので,
View側のOnDraw関数の
CDocument* pDoc = GetDocument();
をコメントアウトしても,エラーは出てしまいました.
よろしくお願いします.
>> どんな定義
> とは具体的に,何のことでしょうか?
CXXXViewクラスにメンバ関数の追加をしていないかを確認したかったのです.
ビュー上でクリックしたときにエラーが出るということは,クリックしたときに呼ばれ
るビュークラスのメンバ関数の定義に問題があるのではないかと推測しているわけで
す.
shogoです.
エラー箇所のソースの抜粋です.
int CView::OnMouseActivate(CWnd* pDesktopWnd, UINT nHitTest, UINT message)
{
int nResult = CWnd::OnMouseActivate(pDesktopWnd, nHitTest, message);
if (nResult == MA_NOACTIVATE || nResult == MA_NOACTIVATEANDEAT)
return nResult; // frame does not want to activate
CFrameWnd* pParentFrame = GetParentFrame();
if (pParentFrame != NULL)
{
// eat it if this will cause activation
ASSERT(pParentFrame == pDesktopWnd || pDesktopWnd->IsChild
(pParentFrame)); //ここがエラー箇所
//以下省略
}
このとき,自動変数の表示は,
pDesktopWndがDialog,pParentFrameがMainFrameとなっていました.
(関係ないかもしれないがthisがDialogに貼り付けたViewでした.)
こんなものは,参考になりますでしょうか?
よろしくお願いします.
ここでASSERTしているということは,GetParentFrameがNULL以外の値(フレームウィン
ドウを指すポインタ)を返しているということでしょうか...
でも,おかしいですねぇ.
この方法でダイアログボックスに貼り付けたビューには,フレームウィンドウはないは
ずなんですが.
monkeyさん,レスありがとうございます.
> GetParentFrameがNULL以外の値(フレームウィンドウを指すポインタ)を返している
ということでしょうか
貼り付けるViewの方で,
(CMainFrame*)GetParentFrame();
を呼んでいるのですが,もしかしてこれが原因でしょうか?
(ちなみに呼ぶ理由は,コントロールを動的にCreateするため,
そのIDを同じにならないように取得する目的です.)
よろしくお願いします.
連続レスで申し訳ありません.
> 貼り付けるViewの方で,
> (CMainFrame*)GetParentFrame();
> を呼んでいるのですが,もしかしてこれが原因でしょうか?
を呼ぶことをやめても,エラーは出てしまいました.
>この方法でダイアログボックスに貼り付けたビューには,フレームウィンドウはないは
>ずなんですが.
GetParentFrame() は、トップレベルまで辿ってもフレームウィンドウが
見つからない場合、更にオーナーウィンドウまで探していきます。確か。
#内部で実行される ::GetParent() API 自体がそういう仕様
そうして見つけたフレームウィンドウってのが SDI/MDIアプリのメイン
ウィンドウだったんでしょう。
細かく調べてはいないけど、この手のコードは CView の中にはたくさん
あるんじゃないかな。
ごめんなさい,ダイアログベースだと思い込んでいました.
SDIかMDIならあり得ますね.
SDIかMDIで起動されたダイアログボックスにビューを貼り付けるときは,もうひとつフ
レームウィンドウをかませるとうまくいきます.
(エラー処理は省略していますので,適宜加えて下さい).
BOOL CxxxDlg::OnInitDialog()
{
CDialog::OnInitDialog();
// フレームウィンドウの表示領域
CRect rect( 10, 10, 100, 100 );
// フレームウィンドウの作成情報(ビューだけを指定)
CCreateContext context;
context.m_pNewViewClass = RUNTIME_CLASS(CxxxView);
// フレームウィンドウ~ビュー作成
CFrameWnd* pFrame = static_cast< CFrameWnd* >( RUNTIME_CLASS(CFrameWnd)-
>CreateObject() );
pFrame->Create( NULL, NULL, WS_VISIBLE|WS_CHILD, rect, this, NULL, 0,
&context );
return TRUE;
}
shogoです.
OnInitDialog関数を以下のように変更しました.
BOOL CEmotionDialog::OnInitDialog()
{
CDialog::OnInitDialog();
// TODO : ここに初期化を追加してください
CRect rect(0,0,400,300);
// フレームウィンドウの作成情報(ビューだけを指定)
CCreateContext context;
context.m_pNewViewClass = RUNTIME_CLASS(CXXXView);
// フレームウィンドウ~ビュー作成
CFrameWnd* pFrame = static_cast< CFrameWnd* >( RUNTIME_CLASS(CFrameWnd)-
>CreateObject() );
pFrame->Create( NULL, NULL, WS_VISIBLE|WS_CHILD, rect, this, NULL, 0,
&context );
XXXView = (CXXXView*)RUNTIME_CLASS(CXXXView)->CreateObject();
int x=0,y=0,width=400,height=300;
rect.SetRect(x,y,x+width,y+height);
if (!XXXView->Create(NULL, NULL, WS_CHILD | WS_VISIBLE,
rect, pFrame, 10000, NULL)){
DestroyWindow();
}
}
クリックしてエラーが出るというのはなくなったのですが,
Viewの中のコントロールの反応がありません.
どうすればよいでしょう?
よろしくお願いいたします.