トップページ⇒tech
1001コメント291KB

■MFC相談室 mfc11.dll■

レス数が900を超えています。1000を超えると表示できなくなるよ。
0001デフォルトの名無しさんNGNG
Microsoft Foundation Classライブラリ専用スレです。

前スレ
■ VisualC++(MFC限定)相談室 MFC10.dll■
http://pc5.2ch.net/test/read.cgi/tech/1074104008/

関連リンクは >>2-10 の辺り。
0809デフォルトの名無しさんNGNG
>>800
ソフトラインブレーク で調べてみんさい
0810デフォルトの名無しさんNGNG
MFC三日目の初心者です、
いくらでもたたいてくれて結構です
画像を加工して保存がしたいのですが
HDCで保持するのとDIBデータを扱う2つがあるのですが
この2つについての、違いをご教授願いたいのです。
よろしくお願いします
0811デフォルトの名無しさんNGNG
>>810
推奨スレ
http://pc5.2ch.net/test/read.cgi/tech/1092524669/

・・・とは言っても、おそらく API と MFC の境もわからんだろうな。
こっちとあっちで、ちゃんと同じ自己紹介しとくといい。
0812デフォルトの名無しさんNGNG
モードレスダイアログ上にテキストボックスを配置して、
テキストに変更がある度に処理を行いたいのです。

ClassWizard(VisualC++ 6.0)を使用して、
CEdit型の変数、m_EditXをエディットボックスに対応させ、
EN_CHANGEメッセージのハンドラを作成しました。

void CSelectDlg::OnChangeEditbox()
{
  char buffer[5];

  m_EditX.GetLine(0, buffer, 4);

  ・
  ・
}

実行してみると、ダイアログがオープンした途端、
CEdit::GetLine内部でAssertionが発生して止まってしまいます。
どうやらエディットボックスが有効になる前(?)に
EN_CHANGEメッセージが送られてくるようです。

http://www.flounder.com/getdlgitem.htm#Uninitialized%20Controls
これを避けるために、OnInitDialogが実行済みかどうかを
格納しておくBOOL変数を持たせる方法というのがあるそうです。

ただ、こういった処理をしたい場合、これが定番な書き方なのでしょうか?
もうちょっとスマートなやり方がありそうな気がするのですが。。
0813812NGNG
あ、テキストボックスにメッセージが送られるのは、
スピンボックスから自動関連付けしているのが原因っぽいです。
関連付けを外したらダイアログは普通に表示されました。
0814デフォルトの名無しさんNGNG
>>812
スマートかどうかは知らないけど、とりあえずピンポイントその状況だけ避けるなら
if (::IsWindow(m_EditX..m_hWnd)) とかで判定する手もあると思う。
0815812NGNG
>>814
正直、それを考えてましたw
Assertionがその条件で発生してるんですが、
IsWindowの意味自体があやふやで自信がありませんでした。

メンバ変数を増やすよりはマシってことで、それでやらせていただきます。
0816デフォルトの名無しさんNGNG
どなたか795お願いします
0817デフォルトの名無しさんNGNG
>>795>>816
wndfrm.cpp にあるように、メニューの UPDATE_COMMAND_UI を処理するのは CFrameWnd クラス。
( CFrameWnd::OnInitMenuPopup を参照 )
よってダイアログベースの場合自分で似たような処理を書くか、単純に自力でメニューアイテムをSetCheck すること。

あるいは単に SDI で FormView 使うって手もある。たぶんこっちのほうが簡単。
0818デフォルトの名無しさんNGNG
OnInitMenuPopupでチェックするのがFAQ。
0819デフォルトの名無しさんNGNG
>>814
MFC的には if (m_EditX.GetSafeHwnd()) だな。
0820デフォルトの名無しさんNGNG
>>819
GetSafeHwndはポインタ経由で this が 0 のときにもアクセス違反にならないというだけの関数。
(要は return this ? this->m_hWnd : 0 ってな実装)。
ポインタでもないメンバ変数に使うのは無意味。

m_hWnd って直中身見るのは行儀悪くてイヤーンっていう非MFC人なら常時使ってもいいかもね。
0821デフォルトの名無しさんNGNG
operator HWND
ってあまり使ってませんかそうですか
0822795NGNG
>>816
えっと、どなたか存じませんが、ありがとう。

>>817
FormView使った方が、早そうですね。
参考になりました。
ありがとうございます。
0823デフォルトの名無しさんNGNG
MFCが無くなっちゃうって本当ですか?
0824デフォルトの名無しさんNGNG
>>823
なくなりません。
MFCがテンプレートになる可能性があるだけでしょう。
その場合、ClassWizardなどのIDE機能の変更があると思います。
0825デフォルトの名無しさんNGNG
いや、すぐにとは言わんがMFCもATLもなくなるだろ。
0826デフォルトの名無しさんNGNG
そりゃタイムスパンのレベルと何をもって「なくなる」とするかによるだろうけど
少なくとも現行OS(winXP以下)が現役で動いているうちは確実に使えるだろ
0827デフォルトの名無しさんNGNG
Longhornでも確実に使えると思うね。
MSがOSを出し続ける限り使えると思う。

それ以前に、MSにとってMFC/ATLをなくすメリットは何かあるの?
0828デフォルトの名無しさんNGNG
新しいライブラリを売る。
0829デフォルトの名無しさんNGNG
>>828
こんどこそ驚きのプゲラ仕様がないライブラリを求む
0830デフォルトの名無しさんNGNG
プゲラですめばいいけどね。大抵真っ青。
0831デフォルトの名無しさんNGNG
リストビューの表示を高速化する方法について教えてください。

大量(最大1万件)のデータをリストビューに表示させるのですが、一番下のアイテムを選択表示させデータの流れる様子を、画面に表示させたいのです。

SetRedrawを用いてInsertItemを行っています。1万件を超えるとDeleteItemを用いて先頭のアイテムを削除しています。現在表示速度が遅いのかデータが溜まっています。さらに画面がちらついてしまいます。

画面のちらつきはOnEraseBkgndを用いて、描画を省いているのですが上手く画面のちらつきがおさまりません。

良い方があれば教えてください。
0832デフォルトの名無しさんNGNG
>>831
リストビューで表示が間に合わないような頻度で書き換わるデータを本当にリストビューで
1万件もためて表示する意味があるのかという疑問が・・・。
0833デフォルトの名無しさんNGNG
>>831
仮想リストビューを使いなさい。
0834デフォルトの名無しさんNGNG
>>831
大量データを扱う場合は仮想リストコントロールを使うというのが定石だけど、
「流れる様子」とか言ってあんまり頻繁に更新する場合は頻度によって多少
のちらつきが出るかも。
0835デフォルトの名無しさんNGNG
仮想リストビューなんて要るの?
コモンのリストコントロールなら必要ないと思うけど。
描画に必要なインデックス情報しか処理要求してこないようにできたはず。
MFCの場合は知らないけど。
0836835NGNG
>>835で書いたヤツだと、自分で能動的にリストを更新したい場合は、
WM_PAINTを送るだけでいいから楽だよ。

LVN_GETDISPINFOとか、LPSTR_TEXTCALLBACKでググって見れば?
MFCでも逝けるはず。試してないけど。
0837835NGNG
修正します。

WM_PAINT送信での更新だと、InvalidateRect()もあらかじめ必要かも。
0838デフォルトの名無しさんNGNG
普通に(仮想でなく)ListCtrlで1万行出してましたが。
尤も、ログ機能なんで更新は最高でも1秒に一回程度。
有り得ない上限として1万行の仕様になり、ランテストした次第。
0839デフォルトの名無しさんNGNG
リストコントロールは、表示よりもむしろアイテムの挿入・削除に時間がかかるので、
あらかじめ上限数のアイテムを作っておいて、無効アイテムに空文字を返せば、
動的にアイテム数が増減しても高速処理できる。
ただし、見た目は件数が数件でもスクロールバーが出てしまうけど。
0840デフォルトの名無しさんNGNG
つーかなぜそこまで泥臭いことをして仮想リストコントロールを避けるのか分からない・・・
0841デフォルトの名無しさんNGNG
>>831
ttp://hpcgi1.nifty.com/MADIA/Vcbbs/wwwlng.cgi?print+200409/04090044.txt
0842デフォルトの名無しさんNGNG
>>835
> 仮想リストビューなんて要るの?
> コモンのリストコントロールなら必要ないと思うけど。

コモンのリストコントロールを使わずに仮想リストビューを使うって、どういうこと?
0843デフォルトの名無しさんNGNG
MFCのダイアログベースのプログラムを作ってみました。
プログラム自体は動くのですが、Enterを押すと勝手に終了してしまいます。
なぜがご存知の方、教えてください<m(__)m>
0844デフォルトの名無しさんNGNG
>>843
ダイアログクラスのOnOk()をオーバーライドし
CDialog::OnOK();
をコメントアウトして下さい
0845デフォルトの名無しさんNGNG
>>843
聞かれる前に追加。
Escキーでも終了してしまうので、
OnCancel()も>844同様に呼び出されないようにすべし。
0846デフォルトの名無しさんNGNG
それは対処法の先回りであり、843の疑問に対する答えにはなっていないな。
0847デフォルトの名無しさんNGNG
しかも終了手段がなくなる罠。
0848デフォルトの名無しさんNGNG
CHtmlViewを利用しているプログラムを作成しております。
Proxyの動的な変更方法が判りません。

Sleipnirの様にプログラム中から変更を行いたいと思っております。
参考になる文献などでも良いのでご存じの方ご教授お願い致します。
0849デフォルトの名無しさんNGNG
>>843
ttp://www.athomejp.com/goldfish/mfc/dialog/nonesc.asp
0850デフォルトの名無しさんNGNG
>>847
なんで? いつでも EndDialog できるやん。
0851デフォルトの名無しさんNGNG
何も知らない奴に>>844-855を教えただけじゃ終了できなくなるって意味だろ
0852デフォルトの名無しさんNGNG
>>844-845を教えただけじゃ、だ
0853デフォルトの名無しさんNGNG
>>852
844は終了できなくならんだろ。
0854デフォルトの名無しさんNGNG
>>851
そんなん言い出すなら、タスクリストがあるやん
0855デフォルトの名無しさんNGNG
>>853
だから>>844-845の二つともやらせたら、だってば。
0856デフォルトの名無しさんNGNG
>>854
で、「タスクリストからしか終了できません。どうすればいいですか。」って質問が来そうだなって話だ
0857デフォルトの名無しさんNGNG
>>856
そんなら来てからでええやん
来ないかも知れないし
0858デフォルトの名無しさんNGNG
タスクリストってなんんですか?
0859デフォルトの名無しさんNGNG
いや、そんなくだらない質問来て欲しくないから
予防線として>>845は同時にEndDialogも書いた方がいいという主張をしたかったんだろう。>>847は。
0860デフォルトの名無しさんNGNG
で、>>843の質問には誰が答えるんですか?
0861デフォルトの名無しさんNGNG
直後に答え出てますやん
0862なぜが?NGNG
なぜがご存知の方、教えてください
なぜがご存知の方、教えてください
なぜがご存知の方、教えてください

 
0863デフォルトの名無しさんNGNG
Q. ダイアログがEnterキーで終了してしまうんです。なぜですか?
A. OnOK()をコメントアウトで終了しなくなります。

すごい回答だ。つーか、こんな回答でWindowsのダイアログの作法を無視しまくる
変なアプリが増えないことを祈る。
0864デフォルトの名無しさんNGNG
>>860
>>849
0865デフォルトの名無しさんNGNG
>>863
模範回答よろしく
0866デフォルトの名無しさんNGNG
863じゃないけど、ここにやり方書いてあったと思ったけど、サイトが壊れてるのか開けない。
ダイアログボックスをリターンキーやエスケープキーで閉じないようにするには?
http://web.archive.org/web/20030415014307/techtips.belution.com/ja/vc/
0867デフォルトの名無しさんNGNG
エスケープキーでキャンセルできないダイアログボックスは 【 う ざ い 】
0868デフォルトの名無しさんNGNG
OKで閉じないダイアログもうざいけどね。
0869デフォルトの名無しさんNGNG
OKじゃないや、enterだ。
0870デフォルトの名無しさんNGNG
いろいろやり方あるけど、MFCならこの辺じゃないか?
void CxxxDlg::OnOK()
void CxxxDlg::OnCancel()
void CxxxDlg::OnClose()
0871デフォルトの名無しさんNGNG
頼むから話の流れを読んでから書き込んでくれ。
0872デフォルトの名無しさんNGNG
しかも終了手段がなくなる罠。
0873デフォルトの名無しさんNGNG
キャンセルを押してもこの話題が終わらないのですが、どうすればいいでしょうか。
0874デフォルトの名無しさんNGNG
>>873
なんで? いつでも EndDialog できるやん。
0875デフォルトの名無しさんNGNG
thisThread->EndDialog('終了');
0876デフォルトの名無しさんNGNG
error(875) : no matching EndDialog(const char*) in CthisThread
0877デフォルトの名無しさんNGNG
そんなエラーが出るわけねえだろうがクソ野郎
0878デフォルトの名無しさんNGNG
843です。ご回答いただきありがとうございます<m(__)m>
私の理解では、
ESCやENTERでプログラムが終了するのはダイアログベースの仕様であり、
終了させるためには、OnCancel()、OnOK()をオーバーライドすればよい。

実際にやってみたところ、ESCやEnterでは終了せず、右上のバツでは終了できました。
ありがとうございました!!

しかしながらEnterでプログラムが終了する仕様は問題ありですね、、、
0879デフォルトの名無しさんNGNG
>>しかしながらEnterでプログラムが終了する仕様は問題ありですね、、、

んなこたあない。
ダイアログがどうゆうものか、もちっと勉強してくれ。
0880デフォルトの名無しさんNGNG
ところが世の中にはenterでダイアログが終わるとバグ扱いになる所も。。
0881デフォルトの名無しさんNGNG
うちは「仕様です」で押し切るな。
0882デフォルトの名無しさんNGNG
ダイアログクラスをベースにして、ダイアログではないプログラムを作る。
ダイアログクラスを使わないで、ダイアログを作る。
0883デフォルトの名無しさんNGNG
ダイアログクラスをベースにして、ダイアログではないプログラムを作る。
→Enterでプログラムが終了するのは好ましくない。
ダイアログクラスを使わないで、ダイアログを作る。
→Enterでプログラムが終了しないのは好ましくない。
0884デフォルトの名無しさんNGNG
OKボタンに相当するものがあってボタンがそれだけならEnterでOnOKを受けて
終了するのは自然な動作だが、ダイアログ・ベースでもそんな簡単なものばかり
じゃないからね。ものに合わせて変えるのは当然だろ。
0885デフォルトの名無しさんNGNG
ダイアログが閉じた後、さらに別のGUI操作が続く場合は、Enterクローズは便利だけど、
ダイアログが閉じて、アプリ終了した場合やGUI操作がない場合は、Enterクローズは不安感に襲われる。
0886デフォルトの名無しさんNGNG
>>863
ダイアログの作法?
ダイアログを作ってるんじゃなく、
ダイアログを"ベース"にアプリを作っています。
0887デフォルトの名無しさんNGNG
質問させてください。
CSocketで通信するプログラムを作ってるのですが、Connectで止まってしまいます。
動作試験中なのでサーバ、クライアントともに同じマシンであり、
"127.0.0.1"にコネクトするようにしています。

サーバ:Create(1500) → Listen() → Accept(socket) ここで止まる
クライアント:Create() → Connect("127.0.0.1", 1500) ここで止まる
各CreateとListenが成功しているのは戻り値で確認しています。

不可思議なのは、別のマシンではちゃんと動くことです。
自分のマシン:Win XP Pro(SP2当ててない),
       ファイアウォール・アンチウィルス停止中
別のマシン:Win 2000 Pro

どんな原因が考えられるでしょうか。(ポート番号が良くないとか?)
0888デフォルトの名無しさんNGNG
>>887
127.0.0.1がちゃんと解決されているか確認。
netstat /an でポート番号が重複してないか確認。
0889デフォルトの名無しさんNGNG
ダイアログアプリケーションでAfxMessageBox()などのモーダルダイアログが表示されているときに
別のアプリケーションからPostMessage()されると、そのメッセージは破棄されてしまうのですか?

どうも拾えないメッセージがあってそれが原因かなと考えているのですが・・・
0890デフォルトの名無しさんNGNG
XP自信もファイヤーウォール持ってるけど関係あるかね?
0891デフォルトの名無しさんNGNG
>>887
どうでも良いけどテストで使うにしろ1500ってポートはあんまり使わないところ
とりあえず5000オーバーの空いてるところとか使っとけよ
0892デフォルトの名無しさんNGNG
みなさんありがとうございます。

>>888
127.0.0.1が解決できているかどうかの確認ですが、
とりあえずpingは返ってくるようです(他に確認方法ってありますか?)。
またnetstat /anで確認したのですが、特にかぶっているポートはありませんでした。

>>890
OSのファイヤーウォールの項目もチェックしてみましたが、
どの接続にもファイヤーウォールのチェックは入っていませんでした。

>>891
そうします。Winがどのあたりのポートを使っているか
よく知らなかったもので。
0893デフォルトの名無しさんNGNG
telnet 127.0.0.1 1500
0894デフォルトの名無しさんNGNG
>>893
接続中: 127.0.0.1...ホストへ接続できませんでした。 ポート番号 1500: 接続に失敗し
ました

となりました。これは解決ができていないのでしょうか?
ためしにnetstat /anで出てきたLISTENING中のポートに
telnetしてみても同じ結果になりました。
0895デフォルトの名無しさんNGNG
>>894
そのリスニング・ポートはちゃんと0.0.0.0か127.0.0.1にバインドされてるの?

システム・サービスの場合、リストに出てても接続を受けないものもあるから
ちゃんと動く何かの簡易サーバ-クライアント・ソフトを持ってきて実験して
みたら?

それでもダメなら接続をブロックするファイアウォールか何かが動いてる
そのシステム固有の問題ってはっきりするから。
0896デフォルトの名無しさんNGNG
何故、1500?
もし他のポートで試せるのなら試すべき。
0897デフォルトの名無しさんNGNG
XPならファイアーウォールの設定をしないとダメなのでは?
>>892を見るとテストするポートの設定をしてないように思える。
0898デフォルトの名無しさんNGNG
>>889
破棄されない。
MessageBox APIの中でメッセージループが回ってるから。
0899デフォルトの名無しさんNGNG
>>895-897
ご回答ありがとうございます。
>>895さんのおっしゃる通り、アンインストールしたと思っていた
ファイヤーウォール(Zone Alarm)が残っていたようです。
アンインストールしたら正常に接続できました。
言い訳をさせていただくと、以前はフィルタ状況のモニターがポップアップで
表示されており、現在は出現しないのでアンインストールしたと思い込んでいました。
(思い込みは良くない・・・)

休日にみなさんの貴重な時間を割いていただいてありがとうございます。
問題の特定の仕方や、問題になりそうな部分の勉強になりました。
今後も精進します。
0900デフォルトの名無しさんNGNG
ドッキングツールバーという仕組みは、ReBarのようなものを自前で実装しているという理解でいいですか?
0901デフォルトの名無しさんNGNG
良く分からん表現だな
0902デフォルトの名無しさんNGNG
特に問題の無かったアプリのダイアログにボタンを追加したんですが、
そのボタンにクラスウィザードを使おうとしたところ、

 ソースファイル(C:\〜\TestDlg.h, C:\〜\TestDlg.cpp)の
 クラス"CTestDlg"は重複する挿入ブロックが存在します。

というメッセージが出てクラスウィザードが使えなくなってしまったのですが
どうやったら直りますか?環境はXP(SP1)、VC6SP6です。

いったんVCを終了してncb, opt, clw ファイルを削除した後にもう一度
試してみたんですがやはり同じ症状です。
0903902NGNG
すんません。解決しますた。

ダイアログベースでデストラクタが無いので手動で追加したんですが
それを消してから上記の3ファイルを削除・再構築したところ直りました。
0904デフォルトの名無しさんNGNG
宿題に困っています。
お分かりの方、いらっしゃいましたら、よろしくお願いします。

1.iniファイルで指定されたフォルダにあるファイル名(例:abbccc)を取得
2.ファイル名を分解(例:a bb ccc)
3.msdnの行にadoを使ってインサートする(例:a bb cccとフィールドを分けて)

0905デフォルトの名無しさんNGNG
>>904
スレ治外。
0906デフォルトの名無しさんNGNG
まあ、もしかしたらスレ違いじゃ無いのかもしれないけど、
msdnにadoでインサートするのはMFCじゃ無くても無理だろうなあと。
0907デフォルトの名無しさんNGNG
ClassViewで右クリックを使ってクラスにメンバ関数を追加するとき、
デフォルトの引数を設定して、一番最後の引数の型をLPCTSTRにして
デフォルト値=NULL にすると宣言と定義が違うという旨のダイアログが
出て実際に定義の部分の引数部分が削られてしまうのですが、これって
どういうことなんでしょうか?

手動で直すとClassViewの該当関数をダブルクリックしても、ソースの
該当関数部分にジャンプしなくなって「インプリメンテーションが見つからない」
なんて警告されます。

class CTest{
  CTest();
  ~CTest();
  
  BOOL SetData(DWORD dwData=0, LPCTSTR pStrName=NULL);  ←コレ
protected:
  DWORD m_dwData;
  CString m_strName;
};

BOOL CTest::SetData(DWORD dwData)      ←宣言と異なる
{
  m_dwData=dwData;
  if(pStrName==NULL)
    m_strName="";
  else
    m_strName=pStrName;
  return TRUE;
}
0908デフォルトの名無しさんNGNG
>>907
バージョンくらい書こうや。
0909デフォルトの名無しさんNGNG
>>908
すみません。VCのですよね。
VisualC++Ver6、サービスパックもVer6です。

ちなみにconst char * に置き換えると直るには直るのですが
これ(宣言と定義で違うようにすること)は一体どういう意図なのかがわからないです
レス数が900を超えています。1000を超えると表示できなくなるよ。