- 1 名前:デフォルトの名無しさん mailto:sage [2008/04/04(金) 18:37:47 ]
- Microsoft Foundation Classライブラリ専用スレです。
前スレ ■MFC相談室 mfc18d.dll■ pc11.2ch.net/test/read.cgi/tech/1185917008/
- 549 名前:デフォルトの名無しさん mailto:sage [2008/11/11(火) 11:36:26 ]
- >>548
ttp://msdn.microsoft.com/ja-jp/library/18he3sk6(VS.80).aspx のほうには書いてないけど、 その説明は「キャストすれば自分自身を渡せるよ」ということでは無いと思う。 CStringTに書いてないということは昔はそういう制限でもあったのか、 それとも「CString::operator intなどを追加するかもしれないから、 LPCTSTRも明示的にキャストして渡しておけ」という意味じゃないだろうか。
- 550 名前:デフォルトの名無しさん mailto:sage [2008/11/11(火) 12:52:46 ]
- const char*へのキャストは、operatorで内部のバッファ返してるだけ。
Format中に元のバッファが変わったら長さがかわるからバッファ足りなくなる。
- 551 名前:デフォルトの名無しさん mailto:sage [2008/11/11(火) 14:19:28 ]
- >>547>>549>>550
なるほど、ありがとうございました。 ちなみに>>548の文は ttp://msdn.microsoft.com/ja-jp/library/18he3sk6(VS.80).aspx では無くなっちゃってるみたいですが、 VC6付属のMSDNに書かれていた文章です。
- 552 名前:デフォルトの名無しさん mailto:sage [2008/11/11(火) 20:41:35 ]
- C#やった後にこれやると、
GUI画面作成、メッセージ処理、メモリ管理、例外処理とか泣けてくるな… まあでも刺激はあるからいいか…
- 553 名前:デフォルトの名無しさん mailto:sage [2008/11/13(木) 13:07:49 ]
- 質問いいかな?
以下のようなプログラムでスレッド起動してスレッド終了を見ようとしているんだが、 WaitForSingleObject関数で毎回タイムアウト発生…理由分かる人いる? void CMainClass::Start() { g_pThread = AfxBeginThread(Test, GetSafeHwnd(), THREAD_PRIORITY_NORMAL); g_pThread->m_bAutoDelete = FALSE; } UINT Test(LPVOID pParam) { while(!g_Flg){ // ここで処理 // } return 0; } void CMainClass::Stop() { g_Flg = TRUE; ULONG ret = WaitForSingleObject(g_pThread[0]->m_hThread, 10000); delete g_pThread; }
- 554 名前:デフォルトの名無しさん mailto:sage [2008/11/13(木) 13:09:15 ]
- ULONG ret = WaitForSingleObject(g_pThread->m_hThread, 10000);
の間違い。配列はなしね。 なお「g_」をつけているのはグローバル変数
- 555 名前:デフォルトの名無しさん mailto:sage [2008/11/13(木) 14:12:14 ]
- Test関数でちゃんと動いてる?
サスペンド中だったりしない?
- 556 名前:デフォルトの名無しさん mailto:sage [2008/11/13(木) 14:38:07 ]
- >>555
いま調べているんだけど、タイムアウトの10000ms以内には 絶対に終わるはずなんだけどなー。 でもそれが疑わしいか… 回答してくれてありがとん。
- 557 名前:デフォルトの名無しさん mailto:sage [2008/11/13(木) 14:46:42 ]
- とりあえず>>553のまんま動かしてみたけど、WAIT_OBJECT_0でした。
原因はそこ以外にある?
- 558 名前:デフォルトの名無しさん mailto:sage [2008/11/13(木) 14:57:53 ]
- >>557
自分でもやってみたら確かに動いたんだよね。 Test()の処理部分に原因がありそうなのは間違いない。 (ここで10秒かかるってのは考えにくかったからここで質問させてもらったけど) お騒がせさせてすまんかった。 >>557もありがとん
- 559 名前:名無し募集中。。。 mailto:sage [2008/11/13(木) 15:24:33 ]
- threadのreturn 0にブレイクポイントを置いてみるとか
- 560 名前:デフォルトの名無しさん mailto:sage [2008/11/13(木) 16:11:23 ]
- >>553-554だが、新たな発見。
Test()の処理部分に処理回数をカウントアップして、 Editボックスに毎回その値を表示する処理として SetWindowTextを使っているんだけど、 Stop関数をコールした後、どうもそこで固まるらしい。 (SetWindowTextをコメント化したら問題がでなくなった) …意味分からん。なんで最後の1回のSetWindowTextで固まる!?
- 561 名前:デフォルトの名無しさん mailto:sage [2008/11/13(木) 16:17:20 ]
- 具体的には
ULONG num; //処理回数 CString str; str.Format("%d", num); EditBox->SetWindowText(str); とこんな感じ。 もちろん、メインウィンドウのハンドルはもらってきて、 使っている(その部分は省略しているけど)
- 562 名前:デフォルトの名無しさん mailto:sage [2008/11/13(木) 16:50:11 ]
- そりゃあそのSetWindowTextで呼んでるスレッドはもうWaitForしてるからだろ。
- 563 名前:デフォルトの名無しさん mailto:sage [2008/11/13(木) 16:53:40 ]
- SetWindowTextはSendMessageを呼んでる。
メインスレッドのメッセージループでそれを受け取らない以上、SetWindowTextからは返ってこないよ。
- 564 名前:デフォルトの名無しさん mailto:sage [2008/11/13(木) 17:00:11 ]
- あ、そういうことか!言われてみれば激しく納得w
>>562-563ありがとん
- 565 名前:デフォルトの名無しさん [2008/11/14(金) 06:39:27 ]
- SDKを使わないでMFCアプリケーション作る方法を解説してるサイトはないでしょうか?
- 566 名前:デフォルトの名無しさん mailto:sage [2008/11/14(金) 06:41:17 ]
- SDKじゃんくてIDEでした
- 567 名前:デフォルトの名無しさん mailto:sage [2008/11/14(金) 08:09:46 ]
- リソースエディタとコマンドラインからコンパイラを動かすってことかな?
- 568 名前:デフォルトの名無しさん mailto:sage [2008/11/14(金) 08:39:36 ]
- >>567
そうです。 ウィザードの吐き出すコードの解説と、リソースエディタの使い方が解説してあるサイトや本なんかが あればいいなあ、と。
- 569 名前:デフォルトの名無しさん mailto:sage [2008/11/14(金) 08:56:25 ]
- というかMFC詳しい人ってAFX*.Hに宣言されてるクラスを全部覚えてるのか・・・
ウィザードの吐き出すコードの前に、ここを熟読して出直してきます
- 570 名前:デフォルトの名無しさん mailto:sage [2008/11/14(金) 23:08:06 ]
- >>569
覚えてないよ。ただ、よく使うクラスは限られるし、自分で使い勝手の よいMFC派生クラスのライブラリを用意してあるので、それをプロジェ クトに読み込んで使うことの方が多いな。 慣れてくると、ウィザードがどんなコードを吐き出すか判るので、既存の テキトーなクラスの.cpp/.hをコピー&リネーム&文字列置換して、新しい クラスの雛型にして、あとは全部手で書いている。 VC++ 6.0は、クラスウィザードがコード挿入位置を知るために使う特別な 書式のコメントがあるけど、これもクラスウィザードがコード生成したのと 同じように書いている。 その後、一度.clwファイルを消してからクラス ウィザードを起動して.clwを再構築させれば、手で書いたクラスもちゃんと クラスウィザードで認識させられる。
- 571 名前:デフォルトの名無しさん mailto:sage [2008/11/15(土) 12:42:17 ]
- >>561
こういうの見るとSetDlgItemInt使えといいたくなる。
- 572 名前:デフォルトの名無しさん mailto:sage [2008/11/15(土) 14:36:25 ]
- VS2008SP1のFeature Packで機能増えたけど、
新機能使うとレジストリでなくてiniファイルに保存・読み込みできないのだが(´ω`)・・トホー
- 573 名前:デフォルトの名無しさん mailto:sage [2008/11/15(土) 15:56:10 ]
- >>571
素人さんですかw
- 574 名前:デフォルトの名無しさん mailto:sage [2008/11/15(土) 17:45:43 ]
- >>573
玄人がSetDlgItemInt使わない理由とかあるの?
- 575 名前:デフォルトの名無しさん mailto:sage [2008/11/15(土) 19:25:39 ]
- ダイアログを操作したいわけじゃないのに
ダイアログに委託しているところ
- 576 名前:デフォルトの名無しさん mailto:sage [2008/11/15(土) 23:01:11 ]
- 素人・玄人の話ではなくて、
今回の場合、ワーカースレッド側からだとSetDlgItemIntを使いようが無いってだけだな。 コントロール変数とかで持っていても、値をテキストとして設定したい時は、 地味に便利なメソッドだったりする。
- 577 名前:デフォルトの名無しさん mailto:sage [2008/11/16(日) 01:34:50 ]
- また変なのがわいてきたな
ひっこんでろタコ
- 578 名前:デフォルトの名無しさん mailto:sage [2008/11/16(日) 01:59:29 ]
- >>576
素人さんですかw
- 579 名前:576 mailto:sage [2008/11/16(日) 14:52:37 ]
- >>577 タコでさ〜せんwwww
>>578 素人さんですかの人、こんにちはだお
- 580 名前:デフォルトの名無しさん mailto:sage [2008/11/17(月) 02:50:44 ]
- CWnd::SetWindowText()も、CWnd::SetDlgItemText()も、CWnd::SetDlg
ItemInt()も、単純にAPIのラッパだし、ワーカスレッドからでもなんら 問題なく呼べるだろ。 ダイアログのポインタが嫌なら、ハンドルとAPI直接呼び出し使え。 ::SetDlgItemText(this->m_hWnd,IDC_EDIT1,...); ::SetDlgItemInt(this->m_hWnd,IDC_EDIT1,...);
- 581 名前:デフォルトの名無しさん mailto:sage [2008/11/17(月) 22:09:37 ]
- MFCスレでAPI直接呼び出し薦める奴って何なの?
- 582 名前:デフォルトの名無しさん mailto:sage [2008/11/17(月) 22:22:44 ]
- と言われても、割と普通の事だしなあ。
というか、おまいら今回の話はUIスレッドがスレッド終了待機に入った所為で、 UIスレッドへのSendMessageがデッドロックした、っていう事完全に忘れてるだろ。
- 583 名前:デフォルトの名無しさん mailto:sage [2008/11/18(火) 00:00:19 ]
- というより、スレッドとか、ハンドルがクラスで継承されていかないところでは、
Win32APIを直接叩く以外無いよな。 脱線すまん
- 584 名前:デフォルトの名無しさん mailto:sage [2008/11/18(火) 00:09:04 ]
- 隠ぺいしている部分は出来るだけ利用するな
でもGDIだけはベタ書きしてしまう俺 それ自体をクラス化するんだけどな
- 585 名前:デフォルトの名無しさん mailto:sage [2008/11/18(火) 21:59:29 ]
- >>583
MSDNにはHANDLE渡して該当するFromHandleを呼び出す、とあるから オブジェクトは渡せないけどMFCで行けるんじゃない? 個人的にはしないけどね。
- 586 名前:名無し募集中。。。 mailto:sage [2008/11/18(火) 22:07:02 ]
- 都合のいい時だけMFCを使うってスタンスなのでWin32APiは普通に呼ぶ
- 587 名前:デフォルトの名無しさん [2008/11/19(水) 13:37:26 ]
- モーダレスダイアログでボタンを押すと
m_cdlg = new CDlg(this); m_cdlg->ShowWindow(SW_SHOW); みたいな感じで表示するとボタンを押せばいくつでもダイアログが出てしまいます。 1つしか出さないにはどうしたらいいでしょうか? あと、親クラスの関数でモーダレスダイアログを扱うことはできますか? XP+VC.netです。
- 588 名前:デフォルトの名無しさん mailto:sage [2008/11/19(水) 13:53:44 ]
- >>587
その2行を通るたびに new で作ってんだから、そりゃいくつでも出るでしょう。 そのボタン貼ったウィンドウの初期化部分で一回だけ作って、 ボタン押したときに ShowWindow すればいいんじゃね? >親クラスの関数でモーダレスダイアログを扱うことはできますか? ちょっと意味が解らんかった。
- 589 名前:デフォルトの名無しさん [2008/11/19(水) 14:10:21 ]
- delete thisをモーダレス内でしているので、親ウィンドウではモーダレスの終了を検知出来ないですよね?
モーダレスが終了した後なら、もう一度ボタンを押したときはモーダレスを表示したいのですが・・・。 モーダレス上のボタンを押したときに親ウィンドウの変数や関数をいじりたいのですが。
- 590 名前:デフォルトの名無しさん mailto:sage [2008/11/19(水) 14:18:24 ]
- クラスメンバ
private: CUnkoDlg m_dlg; Initidialog m_dlg.Create( CUnkoDlg::IDD , this ) OnButton m_dlg.ShowWindow( SW_SHOW )
- 591 名前:デフォルトの名無しさん mailto:sage [2008/11/19(水) 14:29:49 ]
- モーダレスではなくモードレスですよ。
- 592 名前:デフォルトの名無しさん mailto:sage [2008/11/19(水) 14:30:44 ]
- モーダルに対してなのか、モーダレスと言う人は非常に多い
- 593 名前:デフォルトの名無しさん mailto:sage [2008/11/19(水) 16:14:06 ]
- 青信号に対してなのか、赤信号で渡る人は非常に多い
- 594 名前:デフォルトの名無しさん mailto:sage [2008/11/19(水) 16:40:22 ]
- >>589
自分でWM_NOTIFYして親に通知して、実処理は通知先で
- 595 名前:名無し募集中。。。 mailto:sage [2008/11/19(水) 17:12:27 ]
- >>589
モードレスダイアログに親のthisを渡してpublicな操作をしてもらう事はたまにやる 終了時には 『m_cdlg = new CDlg(this); 』のm_cdlgもNULLにして終わらせる たぶんあんまり行儀が良くないと思う
- 596 名前:デフォルトの名無しさん mailto:sage [2008/11/19(水) 17:23:38 ]
- 子ダイアログで親クラスのヘッダをincludeしてもいいならそれもアリだがそこでしか使えなくなる
俺もやったことあるけど
- 597 名前:デフォルトの名無しさん mailto:sage [2008/11/19(水) 21:07:31 ]
- モードレスダイアログなら、
一旦Createした後は、ShowとHideしかしないという作り方もある。 で、ダイアログ自体はポインタでなくメンバ変数としてそのまま持っておく、と。
- 598 名前:デフォルトの名無しさん mailto:sage [2008/11/19(水) 21:08:33 ]
- って >>590 そのものだった。すまそ。
- 599 名前:デフォルトの名無しさん mailto:sage [2008/11/19(水) 21:37:13 ]
- シングルトンならそれでいいな
- 600 名前:デフォルトの名無しさん mailto:sage [2008/11/20(木) 01:28:13 ]
- >>599
はぁ?何言ってんの?
- 601 名前:デフォルトの名無しさん mailto:sage [2008/11/20(木) 01:32:38 ]
- >>586
アプリケーションフレームワーク使ってないの?
- 602 名前:デフォルトの名無しさん mailto:sage [2008/11/20(木) 01:38:21 ]
- >>589
delete thisってどういう挙動になるのかな?
- 603 名前:デフォルトの名無しさん mailto:sage [2008/11/20(木) 13:47:14 ]
- delete this; // ハラキリ
- 604 名前:デフォルトの名無しさん mailto:sage [2008/11/20(木) 17:42:17 ]
- delete this; // さようなら
なら実際に見たことがある。
- 605 名前:デフォルトの名無しさん mailto:sage [2008/11/20(木) 20:03:19 ]
- >>600
きもw
- 606 名前:デフォルトの名無しさん mailto:sage [2008/11/20(木) 21:05:35 ]
- 俺も >>599 が何を言ってるのか解らん。
親と子ダイアログ、どっちを指してるのかも不明だが、それが シングルトンであるかどうかが今の話にどう関係してくるってんだ。
- 607 名前:デフォルトの名無しさん mailto:sage [2008/11/20(木) 21:44:49 ]
- > モーダレス上のボタンを押したときに親ウィンドウの変数や関数をいじりたいのですが。
ライブラリ化などして、後々まで利用するなら、親ウィンドウなり、 オーナーウィンドウに対して、ユーザー定義メッセージを投げるのが、 一番汎用性があるのでは? WPARAM,LPARAMで、操作したい内容(処理を特定するためのボタンのID等) を渡す。 DWORD値2個で足りなければ、他のメッセージと同様に、構造体 やクラスオブジェクトのポインタを渡す。 処理は、ユーザー定義メッセージを貰う親ウィンドウなり、オーナーウィン ドウ側にON_MESSAGE()のハンドラとして記述することになる。
- 608 名前:デフォルトの名無しさん mailto:sage [2008/11/20(木) 22:08:54 ]
- >>595-596
いいかどうかは別にして、自分もやるし、何度もやったことある。 >>597-598 1回だけCreateして、Show/Hideで使い回す場合、2回目以降表示する際 には、モーダレスダイアログ側のOnInitDialog()が呼ばれないことを ちゃんと理解していれば、それで問題ないと思う。 ダイアログが、親ウィンドウが持つパラメータや状態を表示したり、変更 する機能を持つ場合、同じ実体をリサイクルしてもいいけど、親ウィン ドウ側にはダイアログのポインタをメンバに持たせて、表示時は、newした 後でダイアログのメンバ変数をセットしてCreateを呼び、非表示時は、 DestroyWindow()してdeleteしてしまうのが良いかと。
- 609 名前:デフォルトの名無しさん mailto:sage [2008/11/20(木) 22:14:44 ]
- 要約して書くと、こんなかんじ?
ON_BN_CLICKED(IDC_BUTTONxx,OnShowHideDlg) CxxxxWnd::CxxxxWnd() { m_pDlg=NULL; } CxxxxWnd::~CxxxxWnd() /* virtual */ { if(m_pDlg) // 親が死ぬとき、子も道連れに死ぬ { m_pDlg->DestroyWindow(); // MFCならデストラクタで呼ばれるので省略可 delete m_pDlg; m_pDlg=NULL; // どうせ死ぬので省略可 } } CxxxxWnd::OnShowHideDlg() { if(!m_pDlg) // 非表示→表示 { m_pDlg=new CMyDlg; m_pDlg->m_numParam1=1; m_pDlg->m_strEditParam=_T("テスト"); m_pDlg->Create(this); // 表示時に毎回CMyDlg::OnInitDialog()が呼ばれる m_pDlg->ShowWindow(SW_SHOW); } else // 表示→非表示 { m_pDlg->DestroyWindow(); // MFCならデストラクタで呼ばれるので省略可 delete m_pDlg; m_pDlg=NULL; } }
- 610 名前:デフォルトの名無しさん mailto:sage [2008/11/21(金) 00:21:05 ]
- CWnd::ShowWindow()で表示切替したほうが動作が軽いよ
前回開いてた状態で再表示されたほうが使い勝手も良さそう
- 611 名前:デフォルトの名無しさん mailto:sage [2008/11/21(金) 01:20:56 ]
- まぁ、それも用途次第じゃないか
中身初期化しないならそれがベストだろし
- 612 名前:デフォルトの名無しさん [2008/11/21(金) 15:07:35 ]
- ダイアログベースのMFCアプリです。(VS2005)
親ダイアログにタブコントロールを付けて、タブに更に子ダイアログがくっついている形です。 ダイアログウィンドウでOnSizeが渡されるのが、OnInitDialogより後なのは仕様ですか? CWnd::OnInitDialogが呼び出されるよりも前にOnSizeが来てしまうので、 サイズを一緒に調整したい子ウィンドウ全てに対してGetSafeHwnd()関数でチェックしてから サイズを変更しているのですが、もうちょっと効率的な方法はないですか? それと、なぜかウィンドウでエンターを押すとShowWindow(SW_HIDE)が渡されるのか、 子ダイアログは消えてしまうし、親ダイアログではアプリ自体が終了してしまいます。 何か対処法はありますか?
- 613 名前:名無し募集中。。。 mailto:sage [2008/11/21(金) 15:09:41 ]
- > なぜかウィンドウでエンターを押すと
OnOKに飛んでいる
- 614 名前:デフォルトの名無しさん [2008/11/21(金) 15:25:15 ]
- >>613
OnOKって自分で呼ばなくても勝手に呼び出されちゃうんですか… てっきりIDOKボタンを押した(又はDefault Buttonに設定した上でエンターした)時だけだと思っていました。 これは自分でOnOKを空の関数にオーバーライドして、CDialog::OnOK呼ばないようにせざるを得ないと言うことですか?
- 615 名前:名無し募集中。。。 mailto:sage [2008/11/21(金) 16:40:38 ]
- > OnOKって自分で呼ばなくても勝手に
その通り ESCを押すとOnCancelが呼ばれるのも同じ仕組み
- 616 名前:デフォルトの名無しさん mailto:sage [2008/11/21(金) 17:13:49 ]
- >>599
- 617 名前:デフォルトの名無しさん mailto:sage [2008/11/21(金) 17:28:43 ]
- >>614
>>376
- 618 名前:612 mailto:sage [2008/11/21(金) 17:48:04 ]
- >>617
なるほど。よくわかりました。 っていうか、このスレのレスすらも確認しなくてスンマセン。
- 619 名前:デフォルトの名無しさん mailto:sage [2008/11/21(金) 17:57:18 ]
- >>612
ダイアログ内に子ダイアログを置くのであれば、 子ダイアログの「Control」をTrueにしておいたほうがよいですよ。 子ダイアログだけ消えるということも無くなるはず。
- 620 名前:デフォルトの名無しさん mailto:sage [2008/11/21(金) 19:12:31 ]
- 612を見てなんでCPropertySheet&Pageを使わないのかと思ってしまったが言わない方がいいのか?
- 621 名前:デフォルトの名無しさん mailto:sage [2008/11/21(金) 19:19:05 ]
- うん。言ったら恥かくよ。
- 622 名前:デフォルトの名無しさん mailto:sage [2008/11/21(金) 19:19:28 ]
- と思ったらトップレベルウィンドウがダイアログなのか( ´ω`) ごめんよ
- 623 名前:デフォルトの名無しさん mailto:sage [2008/11/21(金) 21:40:45 ]
- CodeGuruかどっかのサンプルを参考に、トップレベルのダイアログに、
>>620-622 位置決め用にスタティックコントロールを置いて、そのスタティック コントロールに重ねて、動的にプロパティシート(CPropertySheet)を 貼り付けて、そのシートに、さらにCPropertyPageをAddPage()する というコードを実際に書いたことあるけど?
- 624 名前:デフォルトの名無しさん mailto:sage [2008/11/21(金) 21:50:21 ]
- >>612
> ダイアログウィンドウでOnSizeが渡されるのが、OnInitDialogより後 > なのは仕様ですか? DoModal()を呼んだ場合、OnInitDialog()より前、OnCreate()の後に OnSize()が呼ばれていると思うけど? ダイアログリソースに貼り付けたコントロールではなくて、自分でコント ロールを動的にCreate()しているのなら、コントロール作成より前には 呼ばれないでしょ。 そういうことではなくて?
- 625 名前:デフォルトの名無しさん [2008/11/21(金) 22:37:42 ]
- >>624
あ、いや、ダイアログリソースで貼り付けて、DDXで関連づけたコントロールをOnSizeで調整しようとしているので、 DoDataExchangeで関連づけられる前にOnSizeが呼び出されるのが気にくわなかっただけでして… (OnInitDialogはそれよりもあと) あれ、UpdateDataを勝手に呼び出しちゃえば問題なかったですかね? もしかして。
- 626 名前:デフォルトの名無しさん mailto:sage [2008/11/22(土) 03:20:48 ]
- 今日からVC++を使い始めたCプログラマです。
IPAddressクラスからIPv4アドレスをDWORD値で取り出したいのですが どうすればいいのでしょう? CString hostName = Host; String ^strHost = gcnew String(hostName); IPHostEntry^ ipInfo = Dns::GetHostEntry(strHost); IPAddress^ ipAddr; for each (ipAddr in ipInfo->AddressList) { if (ipAddr->AddressFamily == System::Net::Sockets::AddressFamily::InterNetwork) break; } if (!ipAddr) /* この判定は超怪しい */ { /* とれなければLoopBackに強制 */ dwSvAddr = 0x7F000001UL; } else { /* dwSvaddr = *(DWORD *)ipAddr->getAddressBytes(); みたいなキャストがしたい */
- 627 名前:デフォルトの名無しさん mailto:sage [2008/11/22(土) 08:53:01 ]
- .NETスレで聞きなさい
たぶん.NETのデータ型をアンボクシングしてからキャストすればよさそうだが
- 628 名前:624 mailto:sage [2008/11/22(土) 09:32:53 ]
- >>625
やりたいことがイマイチわからんのですが? DoDataExchange()内のDDX_Control()で関連付けせずに、OnInitDialog() 内で、SubclassDlgItem()で動的に関連付け(サブクラス化)することも できますが、コントロールの初期サイズはリソースで指定したサイズに なるので、特定コントロールのみ例外扱い(リソース指定と異なるサイズ にしたい)場合、そのコードはどこかに書く必要があると思います。 そもそも、OnSize()って、ダイアログのスタイルを「ダイアログ枠」で なくて「サイズ変更枠」にすると、ダイアログをドラッグしてサイズ変更 したら、表示中はいつでも何回でも呼ばれる可能性がありますよ? codeguru.comあたりの「CResizeDialog」を参考にしては?
- 629 名前:デフォルトの名無しさん mailto:sage [2008/11/22(土) 19:11:26 ]
- みんなMFCでアプリケーションハンガリアン使うとき、どんな感じにしてるの?
- 630 名前:デフォルトの名無しさん mailto:sage [2008/11/22(土) 22:24:08 ]
- >>628
DoDataExchangeよりも先にOnSizeが先に呼ばれてしまうから、 if (2回目以降のOnSizeだったら) { コントロールのサイズ変更; } のような判定が必要になるのが気にくわないということでは?
- 631 名前:デフォルトの名無しさん mailto:sage [2008/11/23(日) 03:30:09 ]
- >>630
本筋とそれる話で申し訳ない。 "2回目以降"でなくて、コントロールのhWndがIsWindow通るとかでいいんじゃね?
- 632 名前:デフォルトの名無しさん mailto:sage [2008/11/23(日) 07:07:43 ]
- まぁOnSizeはwin32のWM_SIZEのままで、ddxはmfcの後付なんだからしょうがない
- 633 名前:624 mailto:sage [2008/11/23(日) 11:35:19 ]
- >>630
> DoDataExchangeよりも先にOnSizeが先に呼ばれてしまうから、 DoDataExchangeとの順番は関係なく、最小化のタイミング等でもWM_SIZEは 飛んでくるから、何らかの判定は必要だと思うけど? codeguru.comの「CResizeDialog」だと、ダイアログにCRect型のメンバ変数 を追加して、コンストラクタでCRect::Empyt()しといて、一発目のOnSize で、CRect::IsRectEmpty()がTRUEなら、現在のダイアログサイズを変数に 取り込み、FALSEなら、直前のOnSize()時に取り込んだダイアログサイズと、 新しいサイズの差を計算して、子コントロールのダイアログ内での移動や、 サイズ変更をやっていたかと。 OnCreate()⇔OnDestroy()のように、明らかに逆で呼ばれることはないメッ セージを除いて、安易にフレームワークが呼び出す順番に依存するような 造りにはしない方がいいのでは? アイコンやビットマップを貼り付けるスタティックコントロールとか、貼り 付けたイメージのサイズに合わせて、コントロールのみ単独でOnSize()が 呼び出されることもあるし。
- 634 名前:デフォルトの名無しさん mailto:sage [2008/11/23(日) 12:28:51 ]
- >>633
なんかかみ合ってないような。 一発目のOnSizeではDDXメンバがまだ設定されていないということですよ? そのCResizeDialogというのは、派生用のダイアログクラスなんだろうから、 内部で子コントロールのDDXメンバを持ってるわけではないでしょう? 昔のソースを掘り返してみたら、 if (IsWindow(m_buttonOK)) { m_buttonOK.MoveWindow(〜); } と自分もIsWindowを使っていた。
- 635 名前:624 mailto:sage [2008/11/23(日) 12:36:46 ]
- >>634
- 636 名前:624 mailto:sage [2008/11/23(日) 12:41:26 ]
- 間違ってENTER押してもうた。(w
>>634 > なんかかみ合ってないような。 そもそも、なんでサイズ変更に際して、DDX_Control()での関連付けが 必要なのか全く説明がないし、自分が設計するとしても、その必要性を まったく感じないんですが?
- 637 名前:デフォルトの名無しさん mailto:sage [2008/11/23(日) 20:05:24 ]
- IsWindowか 俺はGetSafeHwnd派だ( ´ω`)
- 638 名前:デフォルトの名無しさん mailto:sage [2008/11/23(日) 20:27:16 ]
- ::IsWindow()とCWnd::GetSafeHwnd()なら普通は後者を使うでしょ?
- 639 名前:デフォルトの名無しさん mailto:sage [2008/11/23(日) 20:37:32 ]
- HWNDキャスト派は異端ですか?
- 640 名前:デフォルトの名無しさん mailto:sage [2008/11/23(日) 21:27:30 ]
- それもCWndメンバだからいいんじゃね?
グローバルスコープなのを呼び出すなって話だろ
- 641 名前:デフォルトの名無しさん mailto:sage [2008/11/23(日) 23:00:14 ]
- CWnd::GetSafeHwnd()って、m_hWndを返すだけであって、
そのウィンドウが存在しているかどうかはわからないのでは?
- 642 名前:デフォルトの名無しさん mailto:sage [2008/11/23(日) 23:02:48 ]
- Create()が正常終了してないとm_hWndはNULL
CWndの実体ができる時点でウィンドウが作られてるわけじゃないぞ
- 643 名前:デフォルトの名無しさん mailto:sage [2008/11/23(日) 23:12:18 ]
- >>642
それはどこかで明記されてたっけ? 初期化していないポインタのようにゴミが入っている可能性は常に無い? あとそれが大丈夫だとしても、>>634のようにDDXメンバの実体に対するものには GetSafeHwnd()ではなくm_hWndで十分だと思うけど。
- 644 名前:デフォルトの名無しさん mailto:sage [2008/11/24(月) 00:54:26 ]
- SDKで組んだこと無いのかよ
- 645 名前:デフォルトの名無しさん mailto:sage [2008/11/24(月) 01:32:23 ]
- m_hWndの指すウィンドウが存在しないとか言い出したら、
そのハンドルが、実は他プロセスのウィンドウを指してしまっている状態すら、 考慮しないといけなくなるんじゃないか?
- 646 名前:名無し募集中。。。 mailto:sage [2008/11/24(月) 02:08:50 ]
- 俺はm_hWnd派だったんだけどGetSafeHwnd()の方が安全そうだから乗り換えるわ
でも、たぶんどっちでも良くて気分の問題
- 647 名前:デフォルトの名無しさん mailto:sage [2008/11/24(月) 07:43:46 ]
- >>643
> それはどこかで明記されてたっけ? > 初期化していないポインタのようにゴミが入っている可能性は常に無い? 挙動はMFCのソース見れば判るだろ。 というより、C++やクラスの本質 を理解しているのかと? その理屈なら、CFileクラスのm_hFileメンバ変数や、CGdiObjectクラス (CPen,CBrush等の基底クラス)のm_hObjectメンバ変数の値も信用できん とな?(w > あとそれが大丈夫だとしても... 『大丈夫だとしても』ぢゃなく『大丈夫でなければ』、どんな場面であって も(m_hWndの値を返す)GetSafeHwnd()も、m_hWndの直接参照も使えない。
- 648 名前:デフォルトの名無しさん mailto:sage [2008/11/24(月) 07:44:54 ]
- >>646
> たぶんどっちでも良くて気分の問題 んなことぁない。 直接参照する場合、thisポインタのチェックが入らないのに対して、Get SafeHwnd()は、(CWndを指す)thisポインタが有効かどうかチェックした後 でthisポインタがNULLの時m_hWndの値を参照せずNULLを返し、thisポインタ が有効な時のみメンバ変数m_hWndの値を返す。 クラスメンバとして実体が存在するオブジェクトに対して使う場合は、 >>643 氏の言うとおり。 問題はGetParent()などのようにCWndのポインタとしてNULLを返す可能性が ある場合、戻り値をチェックせず、m_hWndを直接参照すると「0xXXXXXXXXが 無効なポインタを参照うんぬん」というエラーで落ちることになる。 自前のコードでチェックしてm_hWndを参照してもいいけど、どうせなら そういう場合はGetSafeHwnd()を使った方がスマート。 同様に、CGdiObject::m_hObjectも、CGdiObject::GetSafeHandle()を 使った方がいい。
- 649 名前:デフォルトの名無しさん mailto:sage [2008/11/24(月) 10:56:07 ]
- CWndの関数はm_hWndに対してそのままAPIを呼ぶようなものが多いから、
自分もNULLチェックではなくAPIのIsWindowに渡してチェックすることが多いな。
|

|