トップページ > プログラム > 2014年06月12日 > GvZA3DBS

書き込み順位&時間帯一覧

3 位/212 ID中時間01234567891011121314151617181920212223Total
書き込み数00000000023250010000000013



使用した名前一覧書き込んだスレッド一覧
デフォルトの名無しさん
MFC相談室 mfc22d.dll

書き込みレス一覧

MFC相談室 mfc22d.dll
478 :デフォルトの名無しさん[]:2014/06/12(木) 09:18:24.66 ID:GvZA3DBS
MFCのソースはスパゲッティーだと思う人いますか?
ちなみに自分は思います。

シンプルなことを複雑に書いてしまっているので、ちょっとした機能向上
のために自前で何かを追加すると、アクティブ化やDocking, Floating関連、
CFrame,CView,CDocument関連の一部で妙な不具合が出てきます。
MFC相談室 mfc22d.dll
479 :デフォルトの名無しさん[]:2014/06/12(木) 09:26:17.26 ID:GvZA3DBS
Document&View Architecture は、一つの CDocumentを複数のCViewで
表示する事が基本理念なのに、VC++6.0のMFCで用意されている関数は、
CFrame,CView,CDocumentを一括で作成する物だけで、既存の
CDocumentを新しいCViewにリンクするような関数は無いようです。

メッセージ・ルーティングも、実装が複雑なせいか、Doc&View
Architecute から離れて、単独の CView や CWnd などを持つと、
当たり前のことが当たり前に出来ないような事態になります。
MFC相談室 mfc22d.dll
482 :デフォルトの名無しさん[]:2014/06/12(木) 10:00:12.19 ID:GvZA3DBS
VC++6.0でMFCのMDIアプリのプロジェクトを作成し、直後にビルド。
アプリに作成されたCViewの継承クラスに OnActivateView() の仮想関数を
追加。その中で:
MyDebugPrintf( "OnActivateView(), bActv = %d, pAct=%08X, pDeact=%08X, this=%08X\n",
        bActivate, pActivateView, pDeactiveView, this );
と書く。この関数は、OutpurDebugString()にvspritnf()を使って、
書式付出力機能をつけた物。

デバッグを開始し、アプリのファイルメニューから新規作成を二度行い、
MDI Child Frame を二個作って、アクティブ化のテストを行う。

別アプリをアクティブ化して、このアプリのタイトルバーをクリックす
ると、pAct==pDeact==this で上記の仮想関数三回呼び出されてくる。
bActvは、1,0,1 の順。で、三回とも、同じ this の値は同じ。つまり、
pAct==pDeact==this は、計9回同じ値が表示され、bActvだけが1,0,1。

別アプリをアクティブ化して、このアプリの中のMDI子ウィンドウをクリック
した場合は、これが、4回となる。
MFC相談室 mfc22d.dll
483 :デフォルトの名無しさん[]:2014/06/12(木) 10:11:18.90 ID:GvZA3DBS
>>481
なるほど。それはすみませんでした。
ちなみに、MSDN Library によれば:

pView = new CMyView;
pView->Create(NULL, NULL, AFX_WS_DEFAULT_VIEW,
rectDefault, this, AFX_IDW_PANE_FIRST + 1, NULL);
//pView->SetDlgCtrlID(AFX_IDW_PANE_FIRST); // ???
pView->ShowWindow(SW_SHOW);
AddView( pView );
SetActiveView(pViewAdd);
RecalcLayout();

とするとのことですが、CViewのCFrameWnd はどうなりますか?
自動作成ですか、自前で用意するのですか?
CViewを追加するだけでこのように大量のコードが必要なのですか?
MFC相談室 mfc22d.dll
484 :デフォルトの名無しさん[]:2014/06/12(木) 10:24:14.20 ID:GvZA3DBS
誤字訂正:
誤:AddView( pView );
正:pDocument->AddView( pView );


ただ、CDocument::AddView(CView *pView) より、
virtual CFrameWnd *CDocTemplate::CreateNewFrame( CDocument* pDoc, CFrameWnd* pOther );
の方が「まだまし」な関数です。なぜなら、後者は、ちゃんとCFrame
を作成してくれるからです。

しかし、これが正しく動作するかは誰にも分かりませんが。
MFC相談室 mfc22d.dll
486 :デフォルトの名無しさん[]:2014/06/12(木) 11:31:25.92 ID:GvZA3DBS
ちなみに、CDocument::AddView(CView *pView) が公開されていることで、
CViewは、どんなCFrameWndに入れても正しく動作するわけではないことは
実験的にはっきりしています。もちろん、一般のCWndに入れたらそれ以上
に駄目です。

MDIの場合、結露から言うと、CViewは、CMainFrm (<-- CMDIFrameWnd) に
入れるか MDI CLIENT WINDOW の子であるところの CMDIChildWnd に入れ
ないと正しく動作しません。

それ以外のCFrameWndに入れた場合、メッセージルーティングがおかし
くったり、アクティブ化が誤動作します。Docking<--->Floatingでは、
親であるところのCFrameWndの「すげ換え」が置きますが、CControlBar
にCViewを入れたりすると、Floating化後に「二重アクティブCView現象」
が発生し、CMainFrmのメニューが(開こうとすると点滅して)開けなく
なります。
MFC相談室 mfc22d.dll
487 :デフォルトの名無しさん[]:2014/06/12(木) 11:45:23.41 ID:GvZA3DBS
>>485
釈迦に説法。
自分はIPA認定の天才プログラマを超えている。
その上でかなりMFCの経験をつみ、よく調べた上で書いている。

MFCはスパゲッティーで、ドキュメントに書かれている理念でさえ
満たせていない。ほぼデフォルトの状態でしか使えないと見た方がいい。
変えようとするとさまざまな不具合に遭遇し、MFCのソースを解析、
SPY++でメッセージの調査、テストアプリの製作が必要となり、
最終的にはMFCのソースを大量にコピーして修正する必要が有るか、
または、そうした方が楽。
MFC相談室 mfc22d.dll
490 :デフォルトの名無しさん[]:2014/06/12(木) 12:00:25.93 ID:GvZA3DBS
>>488
実際書いてるし、これからもっと書くつもり。
MFC相談室 mfc22d.dll
491 :デフォルトの名無しさん[]:2014/06/12(木) 12:04:03.31 ID:GvZA3DBS
>>488
「使いこなせない」わけじゃない。普通のプログラマなら、デフォルト
状態に毛の生えた状態でしかしようとしない。

自分の場合は、機能拡張を試みるので、機能拡張が全く出来ないよう
ものが困るだけ。
MFC相談室 mfc22d.dll
492 :デフォルトの名無しさん[]:2014/06/12(木) 12:10:17.33 ID:GvZA3DBS
>>486 の誤字訂正:

誤:ちなみに、CDocument::AddView(CView *pView) が公開されていることで、
  CViewは、どんなCFrameWndに入れても正しく動作するわけではないことは

正:ちなみに、CDocument::AddView(CView *pView) が公開されているので
  勘違いしそうですが、CView を、どんなCFrameWndに入れても正しく
  動作するわけではありません。それは、
MFC相談室 mfc22d.dll
493 :デフォルトの名無しさん[]:2014/06/12(木) 12:14:12.78 ID:GvZA3DBS
>>485
その理解もホントは間違い。

なぜなら、オブジェクト指向の理念からすると、公開されている
関数は、どのような使い方をしても正しく動作しなければならない
から。

CView *pView を引数に持つ関数を公開するのなら、ありとあらゆる
方法で作成した CView でも絶対的に正常に動作しなければならない。


この理念の理解の仕方が、天才プログラマのオイラとMFCの設計者や
あなたとの違いだ。
MFC相談室 mfc22d.dll
494 :デフォルトの名無しさん[]:2014/06/12(木) 12:24:41.32 ID:GvZA3DBS
公開さらたメンバ関数に、CView *pView を引数に持つ場合、本来、
次のようなことが守られて無ければならない。

・pView = new CView した pView でも良い。
・CDocTemplate などから間接的に作成したものでも良い。
・既にどこかで使われている既存の CView でも良い。
・CView は、Create() や CreateEx() などでウィンドウオブジェクト
 を作成する前でも後でも良い。
・CView は、クラスの集合で公開されている方法を使ってそうなった
 なら、他のどんな種類のウィンドウの子であっても良い。
 もし、一般の CWnd の子に成り得てしまうのなら、その場合でも
 正常に動作しなければならない。
・CView は、どんなスタイルや属性を持ってCreate()やCreateEx()
 されていても良い。


これが、C++ の基本的な理念。これが一つでも守られていなければ
アウト。ただし、CView は、一般の CWnd ではなく、必ず CFrameWnd
に入れる、程度の制約は、ドキュメント化されているならセーフ。
MFC相談室 mfc22d.dll
499 :デフォルトの名無しさん[]:2014/06/12(木) 15:26:31.26 ID:GvZA3DBS
少なくとも、.Net はもっと使いたくないですけどね。


※このページは、『2ちゃんねる』の書き込みを基に自動生成したものです。オリジナルはリンク先の2ちゃんねるの書き込みです。
※このサイトでオリジナルの書き込みについては対応できません。
※何か問題のある場合はメールをしてください。対応します。