トップページ⇒tech
961コメント299KB

■ VisualC++(MFC限定)相談室 ■

■ このスレッドは過去ログ倉庫に格納されています
0001デフォルトの名無しさんNGNG
VisualC++相談室はすでにあるようですが
MFCに限ったお話をしましょう。

ルールを提案。
Qは高度なものからくだらないものまで何でもOK。

Aは「知ってるつもり君」、「えらそうに解説する人」お断りと
いうことで。
0002デフォルトの名無しさんNGNG
えらそうにスレ立てる人もお断りということで。
0003デフォルトの名無しさんNGNG
Q「MFCはなんでこんなにクソですか?」
0004デフォルトの名無しさんNGNG
>>3
教えてあげない。
0005デフォルトの名無しさんNGNG
>> 1
細かいルールとかは別にいらないんじゃない?

といいつつ質問
CStringの文字列の一部を別の文字で置き換えるのってどうやるの?
CString文字列をChar配列にコピーしてからstrncpyして
それをCStringに戻すってのはなんか汚いよね
他にいい方法知ってる人教えてください
0006デフォルトの名無しさんNGNG
>>5
CString::GetBufferでポインタを取得して、中をいじったあとCString::ReleaseBuffer。
0007デフォルトの名無しさんNGNG
「豆知識」
ReleaseBuffer()しないと別のCStringに代入できんし
GetLength()してもsizeは0のままなので要注意だ。
この2つはセットで使うようにしよう。
0008デフォルトの名無しさんNGNG
MFCって便利ですね。クソ面倒くさい登録作業とかやらなくていいし。
0009デフォルトの名無しさんNGNG
CSpinButtonCtrl の SetRange32() ででっかい範囲を設定できるのは
いいんだが、どうやってそこにでっかい値を設定するんだ?
SetPos()だとUD_MAXVAL(0x7FFF)までしか設定できんぞゴラァ!
SetPos32()はどこだゴラァ!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
0010デフォルトの名無しさんNGNG
 ∧∧  
(゜Д゜)<ハァ?
  ||
 ||_
  (________Э
   ||∴
   ||∵
    жж _
0011デフォルトの名無しさんNGNG
>>5
>CStringの文字列の一部を別の文字で置き換えるのってどうやるの?

効率悪いかも知れないけどCString::replace()ってのもあり。
0012デフォルトの名無しさんNGNG
MFCなんか覚えてもプログラマとしての実力はなにも伸びない
VC++をマスターしたつもりでもプログラマとしての実力はなにも変わっていない。
0013デフォルトの名無しさんNGNG
>12
でも楽だからいいじゃん。ね。C++で普通にWINのプログラムする方法知らないとよくわからないわけだし。
0014名無しさんNGNG
MFCはうまく使えばなんてこたないよ。
うまく扱えず落ちこぼれる人もいるようだけど。
現状、MSの仕事やるんなら、覚えておかないとダメだと思うよ。
0015デフォルトの名無しさんNGNG
びるだーを経験した後に MFC を触ると、インターフェースのクソさに
キれたくなる. ラジオボタンをビルダーなみに使いやすくしる!
0016>15NGNG
同意。
でもエディタがクソ。
0017デフォルトの名無しさんNGNG
漏れあんまMFC使わんからわからんのだけど、
std::stringじゃなくてCStringを使うメリットってなに?
やっぱオーバーヘッドを気にしての事?
0018デフォルトの名無しさんNGNG
>17
結合とか容易だからじゃない?
0019デフォルトの名無しさんNGNG
.NETではMFCってどうなるんだろ。
0020デフォルトの名無しさんNGNG
>>17
- MFC では CString を引数に取る関数が多い
- MFC の提供するシリアライズ機能が使える
- BSTR との変換やリソースから文字列を読み込むような Win32 固有の機能
 が実装されているので、便利。
0021デフォルトの名無しさんNGNG
>>20
そうそう。文字列クラスって、単体でどんなにがんばっても、
そのクラスを引数にして、値の受け渡しができないと意味が無いよね。
その点、MFCではWin32ではchar*とバッファサイズで
文字列を受け取る関数をほとんどCStringで受け取れるようにラップ
してあるから便利。
0022デフォルトの名無しさんNGNG
MFCを経験したあとにびるだーを触ると、機能の貧弱さに
キれたくなる。プッシュボタン型チェックボックスをVC++なみに使いやすくしる!
0023デフォルトの名無しさんNGNG
>>1
MFCって自体、ぼろくそに叩かれてこのスレ終了かと思っていたけど
結構順調な滑り出しですな。マターリマターリ
0024デフォルトの名無しさんNGNG
CDockBase(だっけ?)等の非公開クラスについて書いているページありませんか?
0025デフォルトの名無しさんNGNG
MFCで、メインフレームを起動時に最大化しても元に戻ってしまうバグ的仕様が解消されたのはいつですか?
0026デフォルトの名無しさんNGNG
>そうそう。文字列クラスって、単体でどんなにがんばっても、
>そのクラスを引数にして、値の受け渡しができないと意味が無いよね。

同感同感。過去、コアサービスがBSTRとstd::string、
表示用DLLがMFC-DLLでCString使用といったアプリ書く
ことになったんだが値の受け渡しはけっこう苦労したよう
に記憶している。
変換表みたいなの作ってないと、CString<->BSTRだけでも
あれ?これどうやって渡すんだっけかなんてことになる。
その後、_bstr_tなるマクロを知って、だいぶ楽になった。
0027デフォルトの名無しさんNGNG
>>そうそう。文字列クラスって、単体でどんなにがんばっても、
>>そのクラスを引数にして、値の受け渡しができないと意味が無いよね。
>同感同感。過去、コアサービスがBSTRとstd::string、
>表示用DLLがMFC-DLLでCString使用といったアプリ書く
>ことになったんだが値の受け渡しはけっこう苦労したよう

それはクラスライブラリというもののの問題点では。
関数ライブラリであれば複数組み合わせても違和感無いが、
クラスライブラリを複数にすると受け渡し時にコーディングが発生っていう。

MFC/ATL/.NETと増やすのやめて欲しい...と思ったが自分は余り関係無い。
0028デフォルトの名無しさんNGNG
CString に機能追加したくて継承してみたんだけど
=とか<とかオペレータ演算子が使えなくなってしまいました。
機能追加部分以外はCStringとまったく同じ動きにさせたいんだけど
どうやって書けばいいの?
教えてください
0029デフォルトの名無しさんNGNG
>>27
まあそれはわかるんだが現実問題として横たわっている。
ATL/COMで作ったNTサービスをWebインターフェースから
使う場合や、そのサービス自身の制御用プログラムを製造する
ときとか。全部ATLでやると開発工数かかったりPG限定されたりでモゴモゴ・・・
0030デフォルトの名無しさんNGNG
>>29
話が逸れるけど ATL 使えるプログラマって不足してるの?
0031デフォルトの名無しさんNGNG
>>30
NT/2000で常駐型のサービスというだけでATL/COMになるよ。
オレ自身業務系/ネットワーク系問わず監視サービス書いたり
することは少なくない。つーか最近そればっかり。
ただまあ、一般的かというとそうでもないから不足してのか?
と聞かれると判断つかないや。
外注あたってもスキル餅がめったにいないんだもの。
いても人月140+とか。オレの社内単価より高いぞゴラァ。
0032デフォルトの名無しさんNGNG
>6 >7 >11
ありがとー!
0033デフォルトの名無しさんNGNG
マップモードをMM_TEXT以外にしてから
ディスプレイに全角文字を表示させると
例)
pDC->TextOut(0, 0, "文字列");

正しく表示できません。
どうしたらうまくいくんでしょう?
0034デフォルトの名無しさんNGNG
age
0035デフォルトの名無しさんNGNG
ダイアログベースのMFCアプリで、ダイアログに張り付けた水平スクロールバーの位置がOnHScroll(UINT nSBCode, UINT nPos, CScrollBar* pScrollBar)のnPosに入ってるらしいのですが、イマイチその辺の処理がわかりません。ヒントをください。
003635NGNG
あ、質問の意図がはっきりしてない。
スクロールバーにへPosに入ってる位置情報を設定するにはどうすれば良いのかということです・・・。
003735NGNG
あ、検索したらありました。
0038名無しさんNGNG
age
0039名無しさんNGNG
age
0040名無しさんNGNG
age
0041名無しさんNGNG
age
0042名無しさんNGNG
age
004335NGNG
と思って実行しましたが全然だめでした。マイクロソフトのサンプルコードだったのですが、ダメでした。
http://www.microsoft.com/japan/support/kb/articles/J020/6/52.htm
とにかくスクロールバーをマスターしたいです。お願いします。教えてください。
0044デフォルトの名無しさんNGNG
どこらへんがダメでした?
004535NGNG
とりあえず、スクロールバーの親ウインドウにint型の変数myScrollPosを追加して、親ウインドウのOnHScroll(UINT nSBCode, UINT nPos, CScrollBar* pScrollBar)にサンプルコードをコピペしたのですが、ダメでした。
004635NGNG
ダメというのはつまりスクロールしないということです。
004735NGNG
あと、スクロールバーのメンバ変数にint型の変数(DDX?)を設定できるのですが、その変数はどうやって使うものなのでしょう。
004835NGNG
age
0049デフォルトの名無しさんNGNG
スクロールがうまく行っているMFCのサンプルコードでも拾ってこい>35
0050デフォルトの名無しさんNGNG
スクロールバーを離すと戻ってこそMFC(MS)
0051デフォルトの名無しさんNGNG
>>35
どうやって書いたらどのように動かないのか、それを示せって。
005251NGNG
>>35
あぁ、わかったよ
スクロールレンジが決まってないだけだろ。
0053デフォルトの名無しさんNGNG
>>47
DDX = ダイアログデータエクスチェンジ
たとえばint型DDX変数 m_nScroll がある場合
UpdateData(TRUE)を呼ぶことででスクロールバーの値を
m_nScrollに取得できる。
反対に、UpdateData(FALSE)でm_nScrollの値を
スクロールバーに反映できる。
DDX変数には値の上限、下限を設定できるDDVというものもあり
とっても便利&Heart
0054デフォルトの名無しさんNGNG
ハートが出ない・・(鬱
0055デフォルトの名無しさんNGNG
>>36
スクロールレンジをセットしてからWM_HSCROLLのメッセージハンドラを
以下のように記述。
void CTestDlg::OnHScroll(UINT nSBCode, UINT nPos, CScrollBar* pScrollBar)
{
// TODO: この位置にメッセージ ハンドラ用のコードを追加するかまたはデフォルトの処理を呼び出してください
UpdateData(TRUE);
m_str.Format("%d", m_nScroll1);
UpdateData(FALSE);

TRACE("CTestDlg::OnHScroll%d,%x\n", nPos, pScrollBar);
switch(nSBCode){
case SB_THUMBPOSITION:
pScrollBar->SetScrollPos(nPos);
break;
}

CDialog::OnHScroll(nSBCode, nPos, pScrollBar);
}
005655NGNG
あ、ごめん、
TRACE消し忘れた。
消してね
005755NGNG
>>36
余計なもの消してなかった!ごめん!
void CTestDlg::OnHScroll(UINT nSBCode, UINT nPos, CScrollBar* pScrollBar)
{
// TODO: この位置にメッセージ ハンドラ用のコードを追加するかまたはデフォルトの処理を呼び出してください

switch(nSBCode){
case SB_THUMBPOSITION:
pScrollBar->SetScrollPos(nPos);
break;
}

CDialog::OnHScroll(nSBCode, nPos, pScrollBar);
}
005835NGNG
>57
駄目でした。ダイアログに貼り付けられたスクロールバーにレンジが設定できないみたいです。あとSetScrollPosでポジションも指定したのですが、位置が変わりませんでした。
SetScrollRange(IDC_SCROLLBAR1,0,10,TRUE)で、1番目の引数をNULLにするとダイアログの端に自動的にスクロールバーができますよね。
そのときはレンジが設定できました。ポジションも設定できたのですが、動かすと強制終了になってしまいました。
0059デフォルトの名無しさんNGNG
>>58
おいおい。
お前の言ってるSetScrollBarてのは、
1.::SetScrollRange
2.CWnd::SetScrollRange
3.CScrollBar::SetScrollRange
のどれだ?

少なくとも俺は第1引数にコントロールIDを取るようなSetScrollRangeの
オーバーロードを見たことがない。
まずAPIなりクラスメンバの使い方をきっちり調べれ!
ここで訊くのはそれからだ。
006035NGNG
>59
コードエディタでSetScrollRangeと入力し出てきた引数の型を適当に判断したのが間違いでした。
それから気づいてOnHScrollの引数の*pScrollPosでRangeを設定したらちゃんとできました。
本当に馬鹿で申し訳ない。どうもありがとうございました。
0061デフォルトの名無しさんNGNG
すいません。あるクラスから別のクラスのpublic変数にアクセスする方法がわかりません。いかんせんMFCが初めてなもので。MFCじゃなかったらわかるのですが。MFCのクラスの実体がどこにあるかわからないのです。
0062デフォルトの名無しさんNGNG
>>61
MFCでも何でも一緒だと思うが。

# Viewのインスタンスへのポインタの取り方がわからんとかそういうこと?
0063デフォルトの名無しさんNGNG
View?
聞いたことない単語ですが、アクセスしたい変数がるクラスのインスタンスがどこにあるのかわからないということです。
インスタンスの所在が不明なので、その変数を返す関数にもアクセスできないのです。
0064デフォルトの名無しさんNGNG
>View?
>聞いたことない単語ですが、
まじですか
0065デフォルトの名無しさんNGNG
>>63
具体的に、どういうクラスのインスタンスポインタが欲しいか
言ってください。
GetActiveViewとか、GetActiveDocument、AfxGetMainWnd、
GetDocument()、いろいろあるよ。
0066デフォルトの名無しさんNGNG
そういやあ、Afxってどういう意味?
アフロX?
0067デフォルトの名無しさんNGNG
>65
リソースエディタで生成したダイアログクラスです。
0068デフォルトの名無しさんNGNG
CXXXDialog dlg;
dlg.m_EDIT1.SetWindowText("逝ってよし");
dlg.m_EDIT2.SetWindowText("オマエモナー");
こういうことか?
ClassWizardでメンバ変数をCStringとかにしてんのかな。
メンバ変数作成するときに「値」じゃなくて「コントロール」
にすれ。つーかサンプルコードも読め。
006965NGNG
うっ、その場合には自分で作る必要があるでしょう。
CAboutDlg aboutDlg;
aboutDlg.DoModal();
みたいに。
0070デフォルトの名無しさんNGNG
変更が面倒なら
CEdit* ed = GetDigItem(IDC_EDIT1);
ed->SetWindowText("逝ってよし");
でもいいぞ。
0071デフォルトの名無しさんNGNG
65のアプリの画面はリソースエディタで作ったダイアログ
ベースのアプリつーこと?
0072デフォルトの名無しさんNGNG
頭が混乱してきました。すみません。
概ねこんな感じです。長文です。

まず、MFCアプリWizでダイアログベースのスケルトンを生成しました。
生成されたダイアログはCMyDlgです。
次にCMyDlgのメニューを押したら出てくるダイアログを作りました。
CMyDlg2です。
CMyDlg2にはIDC_STATICではないスタティックテキストがあってそれにCString型変数(m_TextCaption)を追加しました。
このm_TextCaptionを違うダイアログで設定した値に書き換えようと思い、CMyDlg3を作りました。
CMyDlg3にはテキストボックスがあり、それに文字を入れてOKボタンを押すとCMyDlg2のm_TextCaptionに値が代入されるようにしようと思いました。
そこでSetTextCaption関数を作りました。引数はCString型(temp)で、テキストボックスの値が入ります。m_TextCaption=temp;というかんじです。
しかしCMyDlg2の関数へのアクセス方法がわからないので駄目でした。
0073デフォルトの名無しさんNGNG
もうMFCは終わるのに熱心だね。
0074デフォルトの名無しさんNGNG
KFC
0075デフォルトの名無しさんNGNG
>>72
CMyDlg2の、どのインスタンスかを指定しないと代入できるわけがない。
CMyDlg3を実体化するときに、テキストを変更したいCMyDlg2のインスタンスを
渡してやればよい。
クラスとインスタンスの違いがわかってないように読める。
007665NGNG
CMyDlg2 md2;
md2.SetTextCaption(CString("AAA"));
md2.DoModal();
とか、こういう感じでいいと思うのだけど・・。
0077デフォルトの名無しさんNGNG
■OKボタンを押したら、CMyDlg3を閉じる場合
※CMyDlg2側に書く
CMyDlg3 dlg;
if(dlg.DoModal()==IDOK)
{
m_TextCaption = dlg.m_EDIT1 //CString型で宣言した場合
m_TextCaption.Update();
}

■OKボタンを押してもCMyDlg3を維持してCMyDlg2のメンバを書き換える場合
※CMyDlg3側に書く
CMyDlg2;;OnOK()
{
CMyDlg2* parent = (CMyDlg2*)GetParent();
if(parent)
parent->SetTextCaption(m_EDIT1);
}
0078デフォルトの名無しさんNGNG
誤:CMyDlg2;;OnOK()
正:CMyDlg2::OnOK()
0079デフォルトの名無しさんNGNG
CStringってstrlenで調べるとちゃんとした値が出るのに、
GetLengthだとたまに変な値が帰ってくるのは何故?
特に400byteとか大きな文字列を入れているとき起こりやすいような。
0080デフォルトの名無しさんNGNG
>>79
GetLength()がNUL文字までの文字長を返すわけではないからです。
文字列バッファの前方に長さ等を保持しているんですが、詳細は
MFCのソースを読んでください。
008172NGNG
>75
その方法で解決できました。どうもありがとうございました。
0082名無しさんNGNG
VC++ってフリーソフトですか?
マイクロソフトのホームページでダウンロードできますか?
0083デフォルトの名無しさんNGNG
age
0084デフォルトの名無しさんNGNG
>83
買え
0085デフォルトの名無しさんNGNG
ダイアログベースアプリで、ENTER押しても終了しないようにするにはどうすればいいのでしょう。
0086デフォルトの名無しさんNGNG
>>85
デフォルトボタンを頃せ。
0087デフォルトの名無しさんNGNG
>86
殺しましたがENTERで終了してしまいます。
0088デフォルトの名無しさんNGNG
自クラスになんも処理しない
virtual void OnOK();を作ればOK。

ついでにID_OKでダイアログを終了するには
CDialog::OnOK()をよぶ。
0089デフォルトの名無しさんNGNG
>88
できました!ありがとうございました。
0090デフォルトの名無しさんNGNG
僕も質問があるのですがよろしいでしょうか???

VCを使ったプログラミングで、
マウスポインタが画面の端に移動したことを
感知するにはどうすればよいのでしょう?
ご存知の方がいましたら宜しくお願いします。
0091デフォルトの名無しさんNGNG
>>90
大麻でもセットしてGetCursorPosで常に監視とか、アイドル時に同様の方法で監視。
それぐらいしか思いつかん。
0092デフォルトの名無しさんNGNG
ウインドウメッセージ拾うんじゃダメ?
0093デフォルトの名無しさんNGNG
画面のマッピングモードをMM_TEXTから変更すると上手く円を描けません。
どうしたら上手く円を描画できるのでしょうか?
MM_TEXTだと普通に
  pDC->Ellipse(0,0,100,100);
で、円がかけるのですが
    pDC->SetMapMode(MM_TWIPS);
を上に挿入すると描けなくなってしまうんです。
0094デフォルトの名無しさんNGNG
>>90
やったことないけど、WM_MOUSEMOVEでWindowFromPoint()するのはどう?
0095デフォルトの名無しさんNGNG
>>93
MM_TWIPSでは下方向はマイナスですよ。
だから
pDC->Ellipse(0, 0, 100, -100);
が正解ですね。
0096デフォルトの名無しさんNGNG
ビュークラスのWM_MOUSEMOVEハンドラでチェックじゃダメ?
void CTestView::OnMouseMove(UINT nFlags, CPoint point)
{
// TODO: この位置にメッセージ ハンドラ用のコードを追加するかまたはデフォルトの処理を呼び出してください
CRect rectWindow;
GetWindowRect(rectWindow);

if(!rectWindow.PtInRect(point)){
TRACE("マウスがウィンドウの外に出ているよ\n");
}
CView::OnMouseMove(nFlags, point);
}
0097デフォルトの名無しさんNGNG
>>96
それちがう
009893NGNG
>>95
どうも有り難うございます。おかげで助かりました。
0099デフォルトの名無しさんNGNG
>>90
「画面の端」ってスクリーンでの端かウィンドウ単位の端かどっちよ?
0100デフォルトの名無しさんNGNG
>>90

GetCapture しといて WM_MOUSEMOVE で座標を確認したらいいよ
0101100NGNG
SetCaptureだったかも? 
■ このスレッドは過去ログ倉庫に格納されています