CDialogにCViewを貼り付ける – プログラミング – Home

CDialogにCViewを貼り付ける
 
通知
すべてクリア

[解決済] CDialogにCViewを貼り付ける

固定ページ 1 / 2

shogo
 shogo
(@shogo)
ゲスト
結合: 20年前
投稿: 31
Topic starter  

こんにちわ,shogoと申します.

開発環境はWinXP,VC7,MFCです.

CDialogから派生したクラスのOnCreate関数の内部で,
CViewから派生したクラスをCreateして,
貼り付けるコードを書いたのですが,うまくいきませんでした.
BORDERを指定すると,枠は見えるが,Viewの中身が見えないという状態です.
(Dialog以外では,うまくいくのを流用したのでCreateのコードは正しいと思います.)

CDialogにCViewを貼り付けることはできないのでしょうか?

よろしくお願いします.


引用未解決
トピックタグ
monkey
 monkey
(@monkey)
ゲスト
結合: 21年前
投稿: 70
 

> こんにちわ

こんにちは.
# 少なくとも,技術系のまじめなサイトで「こんにちわ」はやめましょうよ.

> CDialogから派生したクラスのOnCreate関数の内部で,
> CViewから派生したクラスをCreateして,
> 貼り付けるコードを書いたのですが,うまくいきませんでした.

うまくいかなかったコードを書いて下されば,何が問題なのかはっきりするかも知れま
せん.
それがなければ,推測するしかありません.

> BORDERを指定すると,枠は見えるが,Viewの中身が見えないという状態です.

WS_VISIBLEは指定してますか?
それから,CxxxDialog::OnInitDialogの中で書いた方が良いと思います?

> (Dialog以外では,うまくいくのを流用したのでCreateのコードは正しいと思いま
す.)

正しいならばうまくいくはずではないですか?
プログラミングにあたって,根拠のない判断はとても危険です.

> CDialogにCViewを貼り付けることはできないのでしょうか?

できます.


返信引用
monkey
 monkey
(@monkey)
ゲスト
結合: 21年前
投稿: 70
 

すいません.訂正です.

誤:それから,CxxxDialog::OnInitDialogの中で書いた方が良いと思います?
正:それから,CxxxDialog::OnInitDialogの中で書いた方が良いと思います.
(疑問形でなく,意見です)


返信引用
shogo
 shogo
(@shogo)
ゲスト
結合: 20年前
投稿: 31
Topic starter  

shogoです.

monkeyさん,レスありがとうございます.

> こんにちわ
につきましては,普通に間違えていました.
申し訳ありません.

本題ですが,OnCreate関数ではなく,
OnInitDialogの中でCreateのコードを書きましたら,うまくいきました.
ありがとうございました.


返信引用
shogo
 shogo
(@shogo)
ゲスト
結合: 20年前
投稿: 31
Topic starter  

解決をチェックしておいて申し訳ないですが,
追加で質問です.

表示はされましたが,その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と書いてありました)

原因の見当が付かないので原因と思われること,
また,これについての対策を教えていただけないでしょうか?
よろしくお願いします.


返信引用
monkey
 monkey
(@monkey)
ゲスト
結合: 21年前
投稿: 70
 

> そのViewをクリックすると,なぜかエラーが出ます.

ビューをクリックしたときのエラーならば,ビュークラスの方が怪しい.
CXXXViewクラスでは,どんな定義をしていますか?


返信引用
shogo
 shogo
(@shogo)
ゲスト
結合: 20年前
投稿: 31
Topic starter  

> どんな定義
とは具体的に,何のことでしょうか?

自分で宣言した関数など,という解釈ですと,
変数には,CStaticやCButton.
関数は,実際にCStaticなどをCreateする関数
を宣言しています.
他は何もいじっていません.

「実際にCStaticなどをCreateする関数」というのを呼んでも呼ばなくても,
エラーは出てしまいます.
また,DialogからViewをCreateするときに,DocumentをNULLで指定したので,
View側のOnDraw関数の
CDocument* pDoc = GetDocument();
をコメントアウトしても,エラーは出てしまいました.

よろしくお願いします.


返信引用
monkey
 monkey
(@monkey)
ゲスト
結合: 21年前
投稿: 70
 

>> どんな定義
> とは具体的に,何のことでしょうか?

CXXXViewクラスにメンバ関数の追加をしていないかを確認したかったのです.
ビュー上でクリックしたときにエラーが出るということは,クリックしたときに呼ばれ
るビュークラスのメンバ関数の定義に問題があるのではないかと推測しているわけで
す.


返信引用
shogo
 shogo
(@shogo)
ゲスト
結合: 20年前
投稿: 31
Topic starter  

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でした.)

こんなものは,参考になりますでしょうか?
よろしくお願いします.


返信引用
monkey
 monkey
(@monkey)
ゲスト
結合: 21年前
投稿: 70
 

ここでASSERTしているということは,GetParentFrameがNULL以外の値(フレームウィン
ドウを指すポインタ)を返しているということでしょうか...
でも,おかしいですねぇ.
この方法でダイアログボックスに貼り付けたビューには,フレームウィンドウはないは
ずなんですが.


返信引用
shogo
 shogo
(@shogo)
ゲスト
結合: 20年前
投稿: 31
Topic starter  

monkeyさん,レスありがとうございます.

> GetParentFrameがNULL以外の値(フレームウィンドウを指すポインタ)を返している
ということでしょうか

貼り付けるViewの方で,
(CMainFrame*)GetParentFrame();
を呼んでいるのですが,もしかしてこれが原因でしょうか?
(ちなみに呼ぶ理由は,コントロールを動的にCreateするため,
そのIDを同じにならないように取得する目的です.)

よろしくお願いします.


返信引用
shogo
 shogo
(@shogo)
ゲスト
結合: 20年前
投稿: 31
Topic starter  

連続レスで申し訳ありません.

> 貼り付けるViewの方で,
> (CMainFrame*)GetParentFrame();
> を呼んでいるのですが,もしかしてこれが原因でしょうか?
を呼ぶことをやめても,エラーは出てしまいました.


返信引用
mmm
 mmm
(@mmm)
ゲスト
結合: 20年前
投稿: 1
 

>この方法でダイアログボックスに貼り付けたビューには,フレームウィンドウはないは
>ずなんですが.

GetParentFrame() は、トップレベルまで辿ってもフレームウィンドウが
見つからない場合、更にオーナーウィンドウまで探していきます。確か。
#内部で実行される ::GetParent() API 自体がそういう仕様

そうして見つけたフレームウィンドウってのが SDI/MDIアプリのメイン
ウィンドウだったんでしょう。
細かく調べてはいないけど、この手のコードは CView の中にはたくさん
あるんじゃないかな。


返信引用
monkey
 monkey
(@monkey)
ゲスト
結合: 21年前
投稿: 70
 

ごめんなさい,ダイアログベースだと思い込んでいました.
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
 shogo
(@shogo)
ゲスト
結合: 20年前
投稿: 31
Topic starter  

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の中のコントロールの反応がありません.
どうすればよいでしょう?
よろしくお願いいたします.


返信引用
固定ページ 1 / 2

返信する

投稿者名

投稿者メールアドレス

タイトル *

プレビュー 0リビジョン 保存しました
共有:
タイトルとURLをコピーしました