環境:WinXP,VC++6.0 MFC ダイアログベースです。
こちら↓
http://rararahp.cool.ne.jp/cgi-bin/lng/vc/vclng.cgi?print+200808/08080015.txt
に私と全く同じ質問があるのですが、bunさんが「参考に」と
http://aventech.hp.infoseek.co.jp/Test.zip
とURLの記載をされておられるのですが、なくなっていて取得出来ません・・・。
基本的に行いたいことは上記記載の別質問の方と同じなのですが、参考になるサイトや
サンプルコードがございましたらご教授お願いいたしますm(__)m
追加質問すいません、同じ質問ページ内で仲澤@失業者さんが
「
こういったケースの一般的な方法は、
親DLGのクライアントに「全てのコントロールを持つ、親より大きい子DLG」
を配置して「子DLG」ごとスクロールする
が一般的です。この方法の良いところは
1.実装が簡単。コードが少ない。
2.子DLGの変更が親の仕様に(強く)影響しない(ように実装できる)。
3.縦横スクロール自由自在。
4.親がDLGでなくても良い。
5.スクロールしたくないコントロールは親に配置すればよい。
6.数回程度なら、この仕組みをネストできる。
ではがんばってください。
」
と記載されておられる方法で行ってみようと思うのですが、
リソースは親DLGと子DLGを作成して、
親DLGの表示時に子DLGも表示するのでしょうか?
DLGをDLGに「配置する」というのがよく分からないです・・・。
参考にされているスレッドに実装イメージが説明されていますが、
それでは分からないでしょうか?
> CTestDlg::OnInitDialog()から
> スクロールビュー(CTestScrollView)を作成し、
>
> CTestScrollView::OnCreate()から
> 内部ダイアログ(CInnerDlg)を作成しています。
CTestDlgが土台のダイアログ、その上にCTestScrollViewを生成して
CTestScrollViewのOnCreateでCInnerDlg(コントロールが載った物)を
作成すると書いてあります。
この場合、CInnerDlgはタイトルバーもウインドウ枠も無い物になるでしょう。
わからないのであれば、どの部分が分からないのかを説明した方が
レスもつきやすいと思います。
ご回答ありがとうございます。
分からないのは
>CTestDlgが土台のダイアログ、その上にCTestScrollViewを生成して
>CTestScrollViewのOnCreateでCInnerDlg(コントロールが載った物)を
>作成すると書いてあります。
この具体的な方法が分からないです。
リソースは
・親ダイアログ(CDialog)
・子ダイアログ(CScrollView)
の2つ作成する、という事で正しいでしょうか?
また、親ダイアログのCTestDlg::OnInitDialog()から
どうやって「スクロールビュー(CTestScrollView)を作成」するのでしょうか?
細かい作法などを含め思いっきり初心者なので、サンプルコードが欲しかった
という思いがあります・・・。
あ・・・あと、環境についてなんですが、VC++6.0ではなくてVC++2005でした><
すいません、訂正させていただきます。
あー、そういう状況だとウインドウを自分で起こす所から
勉強しないと駄目ですね。
ウィザード等では出来ないので自分でコードを書かないといけません。
あと、サンプルソースをもらっても一つ一つのコードが何をしているのか、
何の為にそこに記述されているのかと言った事が理解できないと
応用が利かないので結構厳しいです。
ちなみにですが、リソースを作成する必要があるのはダイアログの場合だけです。
スクロールビューはダイアログでは有りません。
ダイアログもビューもウインドウの一種ですが、
使用する場面が全く違います。
親ダイアログの上にスクロールを処理する為のウインドウをのっけて
そのスクロールを処理するウインドウの中に実際のコントロールが
のっかったダイアログがはまり込むイメージです。
単純にダイアログの上にダイアログを載せてもそれだけではスクロールできません。
で、ある程度は試行錯誤するとしてまずはダイアログの上にスクロールビューを
載せると言う部分のコードにチャレンジして見てはどうでしょう。
親ダイアログを親にしてスクロールビューをCreateする流れになります。
基本的なWindowsの知識がある程度あれば良いのですけれど、
いきなりサンプルで何とかしようとするとハマル事が多いので
基本形に関してはちゃんとやって見てからの方がいいカナと思います。
PATIOさん
ありがとうございます。
>あー、そういう状況だとウインドウを自分で起こす所から
>勉強しないと駄目ですね。
重々承知しておりますが、ゆっくり勉強している時間がないもので・・・
サンプルがあれば、細かく何をしているかが分からなくても何とかなるかと
思っているのですが・・・。
>親ダイアログを親にしてスクロールビューをCreateする流れになります。
イメージは大体分かりましたが、いざ実装しようと思うとサッパリな状況です。
とにかく試行錯誤してみます・・・・
> サンプルがあれば、細かく何をしているかが分からなくても何とかなるかと
> 思っているのですが・・・。
サンプルがあっても、そのサンプルの大体の動作が理解できて、どの部分を自分の
アプリケーションに持ってくればよいかを理解する力がなければ、何ともなりません。
つまり、
> あと、サンプルソースをもらっても一つ一つのコードが何をしているのか、
> 何の為にそこに記述されているのかと言った事が理解できないと
> 応用が利かないので結構厳しいです。
という状態に陥るはめになります。
> 細かい作法などを含め思いっきり初心者なので、サンプルコードが欲しかった
> という思いがあります・・・。
という状態では、まずマイクロソフトのサンプルプログラムから勉強した方がよいで
しょう。
http://msdn.microsoft.com/ja-jp/library/hyds2fy1(VS.80).aspx
に色々なサンプルプログラムがあります。
まずはここでWindowsプログラムの基本からかな。
時間が無いのは皆同じだと考えた方が良いかもしれません。
あと、基礎知識だけでも勉強される事をお勧めします。
結果的には勉強したおいた方が最終的に短時間で対応できたと
言う事になるような気がするので。
サンプルコードの継ぎ接ぎでやってしまうと
結局自分でメンテできないコードになりかねません。
結果的に勉強した場合よりもトータルで時間が掛かると言う事にもなりかねません。
ここから先はご自身の判断になると思いますので
強要は出来ないと思いますが、私個人としては多少回り道に見えても
勉強する事をお勧めします。
親を win_Parent 子をwin_Child とすると
1.win_Parent をCreate()
2.win_ParentのOnCreate()でwin_Parentを親にしてwin_Child を作成する
のが、最初です。
win_Child を作るときはWS_CHILDスタイルを指定しなければなりません。
とりあえずここまでできなければ始まりませんね。
親はクライアントエリアを持つものを指定、子は何でも良いですが、
面倒ならばCButtonでも良いですよ。
あとで、最終的な物に差し替えればよいのです。
>サンプルがあれば、細かく何をしているかが分からなくても何とかなるかと
>思っているのですが・・・。
なんか「ググるな危険」のようですね(vv;)。
とりあえず、親をCDialogで、子をFormViewで作成することにしました。
親ダイアログをcreateしました。(これのみで確認しました)
親ダイアログのOnInitDialog内でCFormViewをCreateすると、
「viewform.cpp」の
// dialog template must exist and be invisible with WS_CHILD set
if (!_AfxCheckDialogTemplate(m_lpszTemplateName, TRUE))
{
ASSERT(FALSE); // invalid dialog template name
PostNcDestroy(); // cleanup if Create fails too soon
return FALSE;
}
にひっかかってしまい、ASEERT(FALSE)の箇所で例外にされてしまいます・・・。
ダイアログのテンプレート名というのは、子のリソースIDの事?だと思うのですが、
子をCreateする際には
m_pChildView->Create(NULL,NULL,
WS_VISIBLE|WS_CHILD|WS_EX_CLIENTEDGE|WS_BORDER |
WS_HSCROLL| WS_VSCROLL ,rect,this,nID,&context);
の「nID」にリソースIDが入れています。
(他にも変数がありますが・・・)
何がおかしいのか不明です・・・
自己解決しました。
子のリソースプロパティでstyleを「子」にしていなかったからでした。
とりあえず画面に出るようにはなったのですが、
スクロールバーが出てきません・・・。
この方法は間違っているのでしょうか???
> とりあえず画面に出るようにはなったのですが、
「何が」画面に出るようになったのでしょうか?
親ダイアログの中にFormViewが出るようになったってこと?
> スクロールバーが出てきません・・・。
期待しているのは親ダイアログにスクロールバーを出すことですよね?
この子はCFormViewから作成されていて、CFormViewはCScrollViewから派生しているの
で、CScrollView::SetScrollSizes()を使用して適切な引数を渡せばスクロールバーが
表示されますが、それは子のほうで、親ではありません。
> CTestDlg::OnInitDialog()から
> スクロールビュー(CTestScrollView)を作成し、
>
> CTestScrollView::OnCreate()から
> 内部ダイアログ(CInnerDlg)を作成しています。
をよく読んでください。これは
> ・親ダイアログ(CDialog)
> ・子ダイアログ(CScrollView)
の他に孫ダイアログであるCInnerDlgがあるのです。ここでCTestDlgはスクロールバー
を持つ親として使用しているのでなく、目的とするダイアログボックスのテストドラ
イバになっているのです。どこにスクロールバーがほしいのか、その為にはどのクラ
スを使用するのが良いかを考えないと何をやっているのか分からなくなります。
試行錯誤も良いですが、自分のコードが何をやっているのか理解しないと時間がかか
るだけですよ。
>「何が」画面に出るようになったのでしょうか?
>親ダイアログの中にFormViewが出るようになったってこと?
はい、そうです。
>期待しているのは親ダイアログにスクロールバーを出すことですよね?
>この子はCFormViewから作成されていて、CFormViewはCScrollViewから派生しているの
>で、CScrollView::SetScrollSizes()を使用して適切な引数を渡せばスクロールバーが
>表示されますが、それは子のほうで、親ではありません。
子でも構わないです^^
行いたいのは、スクロール機能を持つ画面に複数(40個くらい)のコントロールを配
置して、縦スクロールで表示させる、といった事です。
子のFormViewを触る(viewの範囲をクリック等)と落ちてしまいます・・・。
VIEWCORE.CPPの249行目↓
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));
// either re-activate the current view, or set this view to
be active
ASSERTの箇所みたいですが、原因が分かりません・・・