1 :
デフォルトの名無しさん :
2008/12/26(金) 00:43:36
逃げ
3 :
デフォルトの名無しさん :2008/12/26(金) 05:21:39
乙!!! ウィンドウに張り付けたコントロールをスクロールさせてるんですが、 ウィンドウ内のどこへでも行って他の描画を上書きしてしまいます。 このコントロールをウィンドウ領域を制限して移動させるにはどうすればいいんでしょうか? コントロールの一部が見えている状態もあり得るので領域の制限がいいです。 CRgn rgn; rgn.CleageRgn(表示領域); CPaintDC dc(this); dc.SelectObject(&rgn); こうじゃないかと思ったんですが、 コントロールのポジション設定の前に書いても ウィンドウのOnPaintの最初にも書いたのですが、だめでした。お願いします!
コミュニケーション能力不足って、本来こういう時に使うといいのかな?
6 :
デフォルトの名無しさん :2008/12/26(金) 10:40:19
ボタンコントロールをスクロールバーで位置をスクロールさせて使っている時に ウィンドウ内でボタンコントロールを表示させたくない領域か、表示される領域を分けて作りたいんです。
ウィンドウの中に子ウィンドウを作成して、子ウィンドウの中にボタンを配置すればいい。 で、子ウィンドウそのものをスクロールさせる。 ボタンは子ウィンドウの中に存在するから、親ウィンドウの領域を侵すことはない。
8 :
7 :2008/12/26(金) 12:13:54
>で、子ウィンドウそのものをスクロールさせる。 子ウィンドウの中でボタンをスクロールさせる の間違い。
9 :
デフォルトの名無しさん :2008/12/26(金) 23:01:00
なるほど、スタティックコントロールなどを張り付けてその中に置けばいいんですね。 きづかなかった・・・・・ お知恵を頂きありがとう!
>スタティックコントロールなどを張り付けて
ちゃんと
>>7 を読んだ?
スタティックコントロールの上にボタンを置いても、親から見ればどちらも子供だからボタンを動かすと親の領域を侵すぞ。
親の中に子ウィンドウを作って、さらにその中にボタンを置くんだよ。つまり、親から見ればボタンは孫。
「子ウィンドウの中にボタンを配置」とわざわざ書いたのは、そういうことなんだがな。
すごいな
俺は
>>6 の文章で何を言ってるのか意味がわかんねーよ
12 :
デフォルトの名無しさん :2008/12/27(土) 03:12:14
いえ、CStaticがCWnd派生になっているので、 CStaticの上ではなくて派生CStaticの中でボタンをCreateです。 わかってます大丈夫です。ありがとうございます。 まだコンパイルまで行きませんが、はみ出したらCWnd派生を置いてやります。どうもです。
ウィンドウのZオーダーとか親子関係とか、根本的なことを理解していなさ そう。 たぶん次は、『スクロールさせるボタン以外、貼り付けたスタテイック コントロールに重なっているダイアログ内のコントロールが上書きされ たり、欠けてしまう』などと質問してくるに違いない。
すげえ理解力だな、その何言ってるのかわからない質問を予想するとは。
15 :
デフォルトの名無しさん :2008/12/27(土) 09:26:30
すごいです。なんでわかったんですか スタティックコントロールをWS_VSCROLLで張り付けたんですが、スクロールバー操作が全くできません。 SS_NOTIFYを付けたんですがだめです。クリックDownは届いてるんです。 スタティックコントロールではなくリストコントロールを代わりに張り付けたら、リストコントロールは全部操作できるんです。 どういうことですか?
もうわからないのでスクロールバーは孫ではなく子にしました お世話になりました。
>スクロールバーは孫ではなく子にしました ・・・・・・孫にしてどーする。^^;
ソフトバンク社長を馬鹿にするな。
次の質問は、スタティックを親にしてCreateしたボタンのクリックイベ ント通知がダイアログに送られてこないかな?
俺が正義だ!
>ボタンのクリックイベント通知がダイアログに送られてこないかな? そういうコードを子供に書くんだよ。孫から親には通知されないが、子から親には通知されるだろ? 孫から子、子から親に通知すれば、ちゃんと親元に届くじゃないか。(笑)
>>21 そういうメッセージの流れを承知していれば、
> もうわからないのでスクロールバーは孫ではなく子にしました
なんて話も出てこないのでは?
孫を意識しなきゃいけない設計って、結構問題あると思うぞ
24 :
デフォルトの名無しさん :2008/12/27(土) 20:16:07
MDIを終了するときに、子ウィンドウが終了する前にC〜Appで終了する処理をしたいのですが ExitInstanceとかやデコンストラクタでは読み込めないっぽいんです。 どの関数を使ったらいいですか?
>>24 もう少しまともな質問の仕方ができるように、MFCを勉強してこい
>>24 デストラクタくらいはちゃんと覚えようぜ。 会話にならないから。
>MDIを終了するときに、子ウィンドウが終了する前にC〜Appで終了する処理をしたい どんな「処理」をしたいのか、まったく想像できんのだが・・・。
初心者のくせにやりたいことをぼかすからだろ 具体的にこれがしたいって言えよな
COLORREF に 明るさのdouble値をかけるにどうすればいいんですか? どう変化していくのか数値を眺めていたんですが3色同じ割合で変化してないのでどう書けばいいのかわからないです。
面倒臭がるな、でFA
UINT nBrightness; // 0〜255 COLORREF rgbRGB(255,0,0); nBrightness=UINT(dblPercent*255.0/100.0); rgb=RGB(GetRValue(rgb)*nBrightness/255, \ ,GetGValue(rgb)*nBrightness/255, \ ,GetBValue(rgb)*nBrightness/255); とか。
color = RGB(GetRValue(rgb) + (((255.0-(double)GetRValue(rgb))/255.0)*(bufLum/255.0)), GetGValue(rgb) + (((255.0-(double)GetGValue(rgb))/255.0)*(bufLum/255.0)), GetBValue(rgb) + (((255.0-(double)GetBValue(rgb))/255.0)*(bufLum/255.0))); まったくうまくいきません dblPercentはなんですか?
変に悩むくらいなら、shlwapiのColorAdjustLumaでも使っとけ。
あーわかったパーセント、double値を100倍したパーセントを各色に掛けてるのかthx
キーボードの入力でOnKeyDownを入れたんですが、Aを押した時はどう書けばいいんですか? 調べてもVK_Aとしか出てこないんですが、シンボルが無いといわれるんです
>>35 ただ単に 'A' と書けばいい。VK_Aを定義したいなら、 #define VK_A 'A' もしくは #define VK_A 0x41
もう馬鹿にかまうな。 こいつに素養なんか、かけらもない。
俺も最初見たときは迷った口。 昔からそこら辺の説明はまともに書いてないんだよなあ。
ありがとうございます。 VK_Aの情報多すぎますよね。なんでなくなったんだろ トレースで出てきた値入れようか悩んだんですが、あまりにも原始的で・・・Aで良かったんですね。どうもです。 コントロールと同時押しも情報がなさすぎて困ってたんですがすごいのを思いつきました!今日は冴えてます。 BOOL ctrl_A = 0; void OnKeyDown(UINT nChar, UINT nRepCnt, UINT nFlags){ if( ctrl_A == 1 ){ if( (nChar == 'A') || (nChar ==VK_CONTROL) ){ } } if( (nChar == 'A') || (nChar ==VK_CONTROL) ){ ctrl_A = 1; } } void OnKeyUp(UINT nChar, UINT nRepCnt, UINT nFlags){ if( (nChar == 'A') || (nChar ==VK_CONTROL) ){ ctrl_A = 0; } }
「GetKeyState」を調べると幸せになれるかも
感動しました。1行で書けますねwありがとう^^
>>39 どーでもいいことだが、ハンガリアン記法を憶えると、あとからソース見直す時にラクになるぞ。
つうか、こっちがそれに慣れてるからそうじゃないコードを見ると読みにくくてかなわん。(笑)
>BOOL ctrl_A = 0;
BOOL は TRUE か FALSE だろ? みたいな、よ。
>if( ctrl_A == 1 ){
は、if ( ctrl_A ){ でいい。あくまで == を書きたいなら、if ( 1 == ctrl_A){ としたほうがいい。
理由はわかるだろ?
って、ここは C の初心者教室かよ・・・・。
>BOOL は TRUE か FALSE だろ? みたいな、よ。 今更何を…… >は、if ( ctrl_A ){ でいい。あくまで == を書きたいなら、if ( 1 == ctrl_A){ としたほうがいい。 勘弁してくれ。 ここはいつから三田某シンパのロートルが巣食うようになったんだ?
実にどうでもいい
BOOLは1と0と-1 TRUEとFALSEだけではない
C の初心者教室に帰って存分に熱い思いを語れ
47 :
24 :2008/12/28(日) 20:20:46
えっと、MDI終了時に起動しているファイルパスを全て取得したいんですが
ファイルパス情報はDocが持っているんじゃないかな
メニューの最近使ったファイルリストのところを参考にすればよさそうな気がする
終了時に保存するか聞いてくるから 終了時に開いてるやつが編集されたか全部チェックしてるだろ
AfxGetApp()等でアプリケーション派生クラスのポインタを得るか、アプリケーション 派生クラスのメンバ関数内から、 (1) まず、CWinApp::GetFirstDocTemplatePosition()を呼んだ後で、 (2) CWinApp::GetNextDocTemplate()を呼んで、CDocTemplateクラスのポインタを得る。 (3) (2)で取得したCDocTemplateクラスのポインタに対して、まず CDocTemplate::GetFirstDocPosition()を呼んだ後、 (4) CDocTemplate::GetNextDocを呼んで、CDocumentのポインタを得る。 同じテンプレートでオープンされているか複数ドキュメントを全て取得 するには、(4)をNULLが返るまで繰り返す。 という流れ。 アプリケーションに複数のドキュメントテンプレートが存在する場合、(2)が NULLを返すまで、それぞれのテンプレートのポインタに対して(3)〜(4)を繰り 返す。 この方法ならSDI/MDI関係ない。 各ドキュメントのパスは、CDocument::GetPathName()で取得。 ドキュメントが更新されているかどうかは、CDocument::IsModified()で取得。
GetAsyncKeyState のMFC版ってありますかね?
CRectで指定した領域を塗りつぶしではなくカラー補正のようなことをするにはどうすればいいんでしょうか BitBltでパターンを使う2段階描画じゃなくて、直接変更するにはどうすればいいんでしょうか
すいません。マージコピーが用意されてました
55 :
47 :2008/12/30(火) 19:18:07
>51 ありがとうございます! えっと、仕組みは分かったのですが、終了するときExitInstanceやデストラクタでは すでに子ウィンドウが閉じていて取得できません。どこに書けば取得できますでしょうか?
56 :
デフォルトの名無しさん :2008/12/30(火) 23:47:58
MFCはLinuxで使えないから糞ですね。 wxWidgetを使うことにします。
switchの中でswitchを書いたり、ifのtrueとelseで同じcase値をもったswitchを区別させるにはどうすればいいんですか? ずっとバグと闘ってたんですが、どうも同じcase値があるのがいけないような気がするんです。この辺どうなんでしょうか
別の関数にわけたほうがいいと思うが……
ですよね・・・そうします。
誤爆? ここMFCスレですよ
61 :
51 :2008/12/31(水) 13:24:41
WM_CLOSE メッセージハンドラ = CMainFrame::OnClose() あたりで よいのでわ?
でわ?
誰か教えてください VS2008 SP1 で CFormView から派生の SDI の新規プロジェクトを作り、 何も変えずにビルドしたらいきなり CMainFrame::OnCreate が見つからないというエラーに遭遇しました それで、MainFrame.h に CMainFrame::OnCreate の定義を追加したところ、ビルドはできたのですが、 その CMainFrame::OnCreate が呼ばれていないらしくて、ツールバーやドッキングウィンドウ等がまったく表示されません SDI の CFormView でツールバーやドッキングウィンドウはどうやって表示すればいいですか? むしろ VS2008 SP1 を使うのやめといたほうがいいですかね???
>>63 1.アプリケーションの種類でシングルドキュメントを選択
2.生成されたクラスで基本クラスにCFormViewを選択
3.完了ボタンを押す
4.印刷サポートが無いとの警告で「はい」を押す
5.F5でビルド-デバッグ実行
以上の操作で問題なく実行された。
>>64 レスありがとうございます
んー、使っているのが VS2008 Pro の評価版でこいつにSP1あてたせいでしょうかね?
製品版のVS2008 SP1だとこの問題が出ないのでしょうかね
とりあえず、Createのイベントを追加してOnCreateのコードをごっそり移動させたら動きました
>CFormView から派生の SDI の新規プロジェクト これWizard内だけで完結させたのかな? もしそうなら、そんなエラー出ることないと思うけどなあ。
>>63 の件ですが、どうもMFCアプリケーションウィザードの5枚目で
初期ステータスバーのチェックを外すと発生するみたいです
(初期ステータスバーのチェックを外す以外は何も変更しなくても起きました)
>>67 検証してみたが、製品版のVS2008SP1(SE)でも発生した。
【対処法】は以下のとおり。
・MainFrm.cppのメッセージマップに、
ON_WM_CREATE()
の一行を追加する。
・MainFrm.h のメッセージハンドラ関数を宣言しているあたりに、
afx_msg int OnCreate(LPCREATESTRUCT lpCreateStruct);
の一行を追加する。
これでビルドは可能になる。うーん、AppWizerd のバグかな。
69 :
デフォルトの名無しさん :2009/01/03(土) 02:43:18
どなたか教えてください。 VC2005のMFC、SDIを使いラジオボタンを配置しているのですが、選択ができず、チェックがいれられないでいます。 ラジオボタン自体はradiobutton.Create()で引数指定して貼り付けています。 ググってCwnd;;CheckRadioButton等を見つけたのですが、手をつけられず困っています。 もしよろしければどなたか助言の方お願いします。
ID を連続させる必要がある。 あと、「グループ」プロパティのチェックは 一連のラジオボタンの先頭のみにチェックを入れるんだったはず。
radiobutton.SetCheck( int nCheck); 詳細は CButton::SetCheck のヘルプ読めばわかる。
動的に作成したラジオボタンにプロパティなんぞない。 IDを連続させて、ON_CONTROL_RANGE() マクロで処理するんだよ。
ダイアログで右クリックでポップアップメニューを表示するようにしたのですが、 ON_UPDATE_COMMAND_UIを実装してもコールされず、メニューの有効無効やチェックなどが更新されません ダイアログでON_UPDATE_COMMAND_UIの関数でメニューを更新する方法はありますか?
74 :
69 :2009/01/03(土) 12:58:11
>>70-72 様
アドバイスありがとうございます。
IDを連続など調べて頑張ってみます。
>>68 Microsoft Visual Studio 9.0\VC\VCWizards\AppWiz\MFC\Application\templates\1041にある
frame.h内の177行目と、frame.cppの内の47行目の
[!if DOCKING_TOOLBAR || TOOLBAR_STYLE_REBAR || RIBBON_TOOLBAR || STATUS_BAR]
を
[!if DOCKING_TOOLBAR || TOOLBAR_STYLE_REBAR || MENUBAR_TOOLBAR || RIBBON_TOOLBAR || STATUS_BAR]
にしておくと、次からうまくいくようになる。
ついでに、frame.cppの内の935行目の
return CFrameWnd::OnCmdMsg(nID, nCode, pExtra, pHandlerInfo);
を
return [!output MAIN_FRAME_BASE_CLASS]::OnCmdMsg(nID, nCode, pExtra, pHandlerInfo);
にしておくとドキュメントのないSDIのときに、ドッキングウインドウ関係のバグがなくなる。
複数の画像を表示させてドラッグで移動させるプログラムを書いていたのですが 複数選択をさせる時等はどうしたらいいんでしょう?
エクスプローラでも参考にしろ
出来るだけWindowsに近い直感的なUIを提供するのは基本だしな
Docが持ってる変数のみで何らかの処理を行いたい場合って Doc側に関数を実装すればいいんですかね?
OK
>>73 俺は、WM_KICKIDLEが届いたら、
ツールバーにWM_IDLEUPDATECMDUIを送るようにした。
質問失礼します。 LoadImage関数を使いビットマップをマイピクチャから読み込もうとしているのですが、例外が出てしまい上手くいきません。 マイピクチャにあるビットマップを読み込もうとしており、フルパスで指定してみたいと思ったのですがフルパス指定の方法がいまいちわかりません。 どなたかアドバイスお願いします。
あけおめことよろ>all
>>82 どんな例外? ファイルが無くても例外は出ないんじゃないかと。
フルパス指定ができない? \を\\にしていないとかじゃない?
>>82 LoadImageはイメージリソースをロードする関数だろ。
フォルダにあるBMPを読むには、CreateFileなり、fopenなり、CImage::Load なりを使わなきゃ。
ほお、第2引数でパス名を指定できるんだ。ありがと。勉強になったよ。
>>81 ありがとうございます
できないかと思っていましたが、おかげさまで実装できました
88 :
82 :2009/01/04(日) 19:22:05
>>83-85 様
エスケープシーケンスも間違いでしたが、ちょこちょこ手直ししていたらなんとかなりました。
本当に助かりました。ありがとうございます!
何故この流れでいきなり「エスケープシーケンス」が?
newして作ったクラスを切り取りや削除した場合ってdeleteってやったほうがいいんですかね?
切り取りってなんぞ? 特に理由がない限りnewしたものはdeleteと相場が決まっている
MFCの中には、使用者にnewで作らせておいて、 delete thisで自殺するクラスもあるけどね。
>>91 クラス一つ一つに画像がついていて
画像を切り取る時にCRect構造体を用いてるんですよ。
で、このCRect構造体はnewで作っていて切り取りの情報を削除したらDeleteするべきなのかな。とおもいまして
>>93 すまん、何を言っているのか理解できないからソースを出してくれ。
>>93 newで作ったらdeleteしないといけない
でもnew-deleteを使わなくても良い別の方法があるような気がする(ローカル変数を使うとか
>>94 理解できないなら理解しなければいいんじゃね?
ようするに、画像の範囲を切り取る時にCRectでサイズと範囲を指定してるっていう話だろ?
newで作ったならDeleteするのはお約束。
戻り値ある関数でなら戻り値作らなきゃいけないのと一緒。
>削除したらDeleteする 漏れにはここが理解できん。
MFCに触る以前にC++をまったく理解してないって様子がアリアリだな。
>>97 範囲を切り取ったよ!
でも、この範囲の情報をいらなくなったからユーザが削除したよ!
そうしたら、プログラム的にdeleteするべき?ってきいてるんだろ。
deleteと削除を区別して考えてるというか、ユーザ側とプログラムで別って事を自覚してるから正しい。
>>98 顔真っ赤だけど大丈夫?
C++からMFC来るとクラス削除しなくっても勝手に処理してくれたりで戸惑うのは当たり前だと思うのは俺だけか
>>100 顔真っ赤なのは、鏡に映ってる自分のことかぃ?(w
自分のコードで明示的にnewして作ったものを、MFCが内部で勝手に削除
するMFCの標準クラスって、具体的にどのクラスのことなのか1つでいい
から挙げてみてよ。
説明が下手なだけだな。
MFCにもCreateとかReleaseとかいうメンバ関数があんなにいっぱいあるというのにw
>>102 いわゆる、真性のコミュニケーション能力不足ってやつですね。
なんか理系全体のレベルが下がるとともに、年々新人プログラマの質も
下がっているような気がするのは、気のせいか?
>>103 メンバ関数のCreateやReleaseは、麻生読みするとnew/deleteになると
でも言うのかぃ?
予約語以外の関数名なんてコンパイラにとっちゃ、関数を個別に識別する
ための単なる記号でしかないのは、C++どころかCやアセンブラ、BASICでも
変わらん。C++から来たとか騙るな。
自分の世界に浸っているのでしょう。 つまりなにか? このスレは説明もろくにできない質問者と、 自分の世界に浸って周りを見ようともしない回答者と、 一部の傍観者によって構成されているのか? # まぁそんなもんか。
CFrameWndというかCMultiDocTemplateあたり? 説明が下手な人は自分の考えを言葉に表現できないという事だと思うけど コーディングってプログラム言語でプログラムしたい内容を表現するという事だから (上司の、スレ住人の、CPUの、OSの、言語の)理解できる的確な表現をする事は重要な事だぜ
惜しい、そこは「言語」ではなく「コンパイラ」とすべきかと。
>>101 はCFrameWndやCDocTemplateを知らなかったのか?
なぁ、
>>101 は図星だったからこんなに必死なん?
new/deleteや、クラスの生成/消滅でがたがた言ってるヴァカは、ただの屑。 それだけは真実。
MFCと関係ない質問はスルーが基本
親ウィンドウのクライアントエリアにある子ウィンドウがクリックされた時に 親ウィンドウでも処理をしたいんですが、どうしたらいいんでしょう? フォーカスを無理やり親に渡してしまうと子ウィンドウ側での処理ができなくなってしまいますし。。。 と、APIの方に誤爆ってしまいましたがどなたかお知恵をお貸しくださいな
親ウィンドウってCMDIFrameWnd?子ウィンドウってCMDIChildWnd?
フォーカスを渡さないといけない処理ってどんな処理?
>>109 インタプリタもあるじゃない?と思ったけどMFCならコンパイラ限定か(チッ
>>115 子ウィンドウの移動をさせたいんですが、親ウィンドウはViewクラスで子ウィンドウはCEditになってます。
何でフォーカスが関係してくるのか理解不能
とどのつまり親(Viewとか)のPreTranslateMessageで解決する
>>117 キー入力がそっちに行っちゃってCtrl+Vとかも使えなくなったのでフォーカスかなぁと。
MFCのソース見てないけど EditViewでツールバーやメニュー触ったあともフォーカスはeditに残ってるから フォーカス戻す処理が入ってる気がする 仮にそうだったらEditViewじゃない普通のviewの場合はviewへフォーカスが戻るだろうね
リストコントロールで追加したアイテムが常に画面に見えるようにしたいのですが これはどこが問題あるんでしょうか?スクロールバーは常に一番下になるんですが、画面が変わりません m_List.InsertItem(m_List.GetItemCount(), mes); SCROLLINFO si; m_List.GetScrollInfo(SB_VERT, &si, SIF_ALL); si.nPos = si.nMax; m_List.SetScrollInfo(SB_VERT, &si); m_List.RedrawWindow();
SetscrollInfo()ではなく、EnsureVisible()を使うのではないだろうか。
表示されるようになりました。1行で書けてしまいました。ありがとうです!
自前のウィンドウに影(ウィンドウの右と下が黒くなるやつ)を付ける方法を 教えて下され。 CWndクラスの中で下のように書くとタイトルバーもない四角いウィンドウがでるのですが、 これに影を付けたいのです。 CreateEx( WS_EX_TOOLWINDOW, lpszClassName, NULL, WS_POPUP | WS_VSCROLL, 0, 0, 100, 100, NULL, NULL, NULL);
デスクトップに対する相対座標を取得して、そこからデスクトップに対してGDIを使って、ウインドウサイズに合わせて矩形を描画すればいいんじゃね?
フチに自分で色塗るだけ
>>124 GDIを使って描いてもいいけれど、もっと安直にウィンドウを重ねてもできるよ。
もしかしてCS_DROPSHADOWの事か?
MFC Feature Packでアプリ組むと、タイトルバーのフォントが、標準のものより ちょっと小さくて読みにくいんだけど、これって、どこで修正できるん? どこかのタイミングでフォントを設定すれば修正できるような気がするんだけど、 上手くいかない・・・orz どなたか、わかる方、教えてplz
まだそんな名前だっけ 普通にSP1って呼んでるわ
>>128 すんません。いろいろ調べてはいたのですが
灯台下暗しでした。。。
CS_DROPSHADOWでやりたいことができました。
132 :
デフォルトの名無しさん :2009/01/07(水) 13:47:27
MFC(VS2005)からVBAの関数を呼び出す方法を知っている人いませんか? ググってもなかなかみつからないので。。。 よろしくお願いします。
VS2008からDDEを使ってExcelに値を放り込んだり多少の操作をした事はあるけど VBAの関数を呼ぶ方法はわからないな VBAのどんな関数を呼びたいんだ? (または任意のマクロかな)
134 :
デフォルトの名無しさん :2009/01/07(水) 15:05:13
>>133 ExcelのVBEditorで作ったVBAの関数を呼びたいと思っています。
Excelに貼り付けたボタンを押すとその関数が呼び出されるんですが、
これをMFCで処理させたいと思っています。
なかなか難しいですかね?
136 :
デフォルトの名無しさん :2009/01/07(水) 15:22:52
>>135 日本語が。。。
でも、オートメーション使うとなにかできそうですね。
>>129 タイトルバーのフォントが変わるの? XPじゃ変わらんけど。
ちなみに、メニューバーのフォントは変わるのでシステムの設定を
チェックしてそれに合わせているんだが。
CDHTMLDialogのOnInitDialogでCreateExで動的生成したコントロールが、 スクロールバー等をクリックしても無反応です。 CDHTMLDialogで動的に生成したコントロールを有効にする方法は無いでしょうか?
CEditを本体から呼び出してエディットボックスを作成しているのですが、これの色を変更する場合って CEditのHDCを取得して、SetTextColorではだめなんでしょうか?
140 :
デフォルトの名無しさん :2009/01/07(水) 20:19:18
つオンコントロールカラー
古いアプリのメンテのために昨日から初めてMFCに触れることになった者です。 ある比較的シンプルなWindowsアプリで、なぜかCPU使用率が異常に高いので いろいろ試行錯誤しなかがら試してみると、どうもOnPaintのオーバライドで ベースクラスのOnPaint(CframeWnd::OnPaint)を呼んでないことが原因らしいことが わかったのですが(つまりオーバーライドの中でCframeWnd::OnPaintを呼んでやれば CPU使用率の異常な上昇は起こらない)これって普通なんでしょうか? なんかググってもオーバーライドの中でCframeWnd::OnPaint読んでるようなコードって 見かけないような気がするんですが……。
OnPaint で GetDC とかしてないか? OnPaint では CPaintDC でデバイスコンテキストを作る必要がある。 あるいは、OnPaint で何もしていないか・・・。 何もしなくても CPaintDC を作る必要がある。
OnPaint() ではベースクラスの OnPaint() は呼ばない。 ベースクラスでは、Default()、つまりDefWindowProc() を呼んでいるだけだから。
DefWindowProc で BeginPaint と EndPaint をしてるから OnPaint で何もしていないなら 自前で CPaintDC 作るか さもなくばベースクラスの OnPaint を呼ばなければいけない。
CPaintDC(BeginPaintとEndPaint)しないと無効領域がクリアされず 延々とWM_PAINTが生成されるんだっけか
無効領域がある限り永遠にWM_PAINT送り続けるからな。 一応メッセージの優先順位が低いから、それでもそれなりにアプリは動作するけど。
つまり、元のアプリは相当酷い代物ってことだな。
>>142-147 ありがとう。
ソースは会社なんで明日確認してみます。
>元のアプリは相当酷い代物ってことだな。
名前から意味がまったく読み取れない変数名やメソッド名とか、
一つのメソッドが平気で200行とかそれはもうw
子ウィンドウの座標(CPoint)を親ウィンドウの座標(CPoint)に変換したいんですが関数などはあるのでしょうか?
どういう意味だ? デスクトップからの相対座標を、親ウィンドウの相対座標に変換するってことか?
Viewクラス内に派生クラスで作成したCEditクラスがいるんですが このCEdit内をクリックされた時に親ウィンドウ側に座標を渡したいんです
GetCursorPosで取得したならスクリーン座標なので親でScreenToClient
GetCursorPosを行ったのではなく、CEditクラスに来たWM_LBUTTONDOWNのメッセージを処理したいんですよ。
応用力のない奴だな
つ MapWindowPoints
応用力があったらこんなところに来ません。
157 :
デフォルトの名無しさん :2009/01/09(金) 08:02:43
photoshopとかwordみたいにdrawの一部を拡大縮小したくて、SetViewportOrgとか使ってみたのですが どうもキレイに行かなくて困ってます。 イイ解決法ってありますか?
MFCと関係ない質問はスルーの方向で
スクリーン座標をクライアント座標に変換した所、正しく変換された物から右下側に座標がずれてしまうのですが これは、使い方がおかしいのでしょうか?
エスパーさーん
ScreenToClientでスクリーン座標をクライアント座標にしたらずれてるって話だろ? 別に意味がわからなくはないとおもうが・・・。 まぁ、俺には解決策はわからんけどね
・変換元座標がスクリーン座標でない。 ・実はAPIのScreenToClientを使用しており、渡すHWNDが間違っている。 ・"正しく変換された物"のほうがずれている。
非クライアント領域が計算に入ってないんだろうな
GetCurrentDirectoryより簡単な関数はありますか?
166 :
デフォルトの名無しさん :2009/01/13(火) 23:24:58
MFCを使い ダイアログベースのプログラムを作成しています。 例えばダイアログ上にボタンを配置し 毎フレーム位置を変更させるような プログラムを作成したいと考えています。 毎フレーム処理を行うようなコードはどのように実装すればよいのでしょうか?
そもそもフレームってどういう意味で言っているのか分からない 紙芝居でもダイアログ上に表示するのか?
168 :
デフォルトの名無しさん :2009/01/13(火) 23:38:06
>>167 返答ありがとうございます。
>紙芝居でもダイアログ上に表示するのか?
イメージに近いです1フレーム毎に処理を行えればと思っています。
フレームの定義が時間単位とかだと、タイマーイベントでも作ってダイアログのDC上に絵を描画とかか? 関係ない話だけど、今Windows7のペイントいじってみた なんとなくリボンの良さ分かった木はするけど、絵心がないから個人であれ作るのは面倒だな
>>169 Timerを使わず
win32でいうところのメッセージループみたいな
所で独自のイベントを受け取って処理を行いたいんだけど
いまいちわからん。。。
リボンUIは確かに見た目は良いね
GDIにはフレームという概念は無いはず。 タイマーかなんかで一定時間毎に処理するしかないね。
やっぱりフレームがどういうものを想像しているのか分からないな 描画が必要なタイミングの単位と言うならOnDrawとかになるんだろうけど 一定周期じゃないもんな(アクティブになったときとか、リサイズされたときとか色々。。。)
MFCならOnIdleの出番か?
ティアリングの無い綺麗なアニメーションしたければWPF使えってんだ
CRectTrackerを使って画像内にドラッグで大きさ、位置が 変更可能な矩形を描画しようとしてるんですが、 矩形内の色が白になってしまって画像が上書きされた形になります。 枠だけ描画というのはどうやったらできるんでしょうか。 画像はrawで、OpenGLで描画されています。
>>175 コンストラクタでCRectTracker::hatchInsideを指定するとどうなる?
# OpenGLで描画したものってDCの範疇じゃないのかな?
177 :
175 :2009/01/14(水) 18:55:08
>>176 斜線が入るだけで、白く塗りつぶされたままです。
178 :
デフォルトの名無しさん :2009/01/14(水) 19:52:53
エディットボックスでキー入力の入力方法を英語から日本語入力に自動的に切り替える方法を教えてください。
179 :
178 :2009/01/14(水) 19:53:28
↑winXP+VC2005です。すいません
MFCにあったかな? なければスレ違い
>>175 そもそもなんでOpenGLで描画したところにトラッキングしたいのか判らんが、
MFC側の問題じゃなくてOpenGL側の問題っぽいからOpenGLスレで聞いて味噌。
質問させてください。 今MFC VC2005を使いプログラムを組んでいるのですが、あるメソッド内でint型配列array[21]の中身をsetwindowtextでタイトルに表示させたいと思っています。 setwindow(_T(""))で、array[i]をどのように記述すれば表示できるようになるでしょうか。下らないかもしれませんがお願いします。
CString hoge; hoge.format(_T("%d"), array[i]); wnd.SetWindowText(hoge); こんな感じかな
184 :
182 :2009/01/15(木) 02:24:13
>>183 さん
そういう書き方をするんですね、、無事上手くいきました。ありがとうございました!
185 :
175 :2009/01/15(木) 02:48:28
>>181 今使ってるプログラムはもともと1年半くらい前の演習の時に先生から頂いたrawビューアで、
研究に使えそうだってことでその時のプログラムを改造しようとしてるんですが、
OpenGLは全く扱ったことがなくて(演習の時も処理部分しか触ってない)、
時間もないんで、OpenGLを勉強するより1から作り直した方が早いような気がしてきたんですが、
raw画像(320×320の輝度値のみのデータ)をMFCを使って表示させるには
ビットマップに変換するしかないのでしょうか。
輝度データをDIBに変換すれば良い BMPはLoadImageでDIBのハンドルを得られるが 自分で変換する場合はBITMAPINFOにサイズなどをセットしてCreateDIBSectionを使って ハンドルと輝度データを入れる領域を得る(ここまでMFCなし
187 :
175 :2009/01/15(木) 11:33:23
>>186 アドバイスありがとうございます。
それで作ってみたいと思います。
MFC6.0の参考書見ながらこつこつやってるんだけど別に支障はない? 1999〜2001年に出版されたものなんだが
int iLength = m_Edit.LineLength(i)+1; TCHAR *ptBuf = new TCHAR[iLength]; m_Edit.GetLine(i,ptBuf,iLength); ptBuf[iLength]=0; ar.WriteString(str); delete[] ptBuf; 一行一行ファイルの保存させたいのでCEditの内容を取得して保存させるのに 上記の様なソースを書いたところdelete[]の所でエラーをはくのですがなぜでしょうか?
>>189 ptBuf[iLength]=0;
↓
ptBuf[iLength-1]=0;
CWnd::GetWindowTextでCStringに纏めて取って、 CString::Tokenizeで分解したほうが手っ取り早くね?
int i, nLineCount; CString strText; CStringArray bufArray; nLineCount=m_Edit.GetLineCount(); for (i=0;i < nLineCount;i++) { int len = m_Edit.LineLength(m_Edit.LineIndex(i)); m_Edit.GetLine(i, strText.GetBuffer(len), len); strText.ReleaseBuffer(len); bufArray.Add(strText); } CStdioFile file; if(file.Open(..略..)) { for (i=0;i <bufArray.GetSize();i++) { file.WriteString(bufArray.GetAt(i)); file.WriteString(_T("\r\n")); } file.Close(); } とかでよくね?
CEdit::GetLine 戻り値 実際にコピーされたバイト数 戻り値使わないの?
MFCでデバイスコンテキストで使われているフォントの高さを取得する方法ってありますか?
GetTextExtent
GetLineの戻り値、、使わないなあ。 使いどころない。
>>193 は、
>>192 でどう戻り値使うのだろうか?
lineText..GetLine(iLine, strText.GetBuffer(iLength)); っていう風に関数を実行するとstrTextにその行が入る時と入らない時があるんですがなぜなんでしょうか?
ReleaseBuffer してるか?
行ってますし、デバッガでとめて一個一個通すと何故か全部入っていくんです。
>lineText..GetLine(iLine, strText.GetBuffer(iLength)); こんなコード、有り得ないだろ。
CEdit::GetLine(int nIndex, LPTSTR lpszBuffer) だろ?EM_GETLINEのベタ実装なんだよな、これ。 昔から思っていたんだが、わざわざメソッドとして用意しておく必要性あるんだろうか。 普通バッファ長を指定できる方しか使わないと思うのだが。 わざわざこっちでバッファの先頭ワードにバッファ長代入とか暇人過ぎだろ。
2つあるうちの一見楽そうに見える方が実は大変ということか
205 :
デフォルトの名無しさん :2009/01/18(日) 15:22:20
>>199 >>203 が書いているように、引数が2つしかない CEdit::GetLine()を使う
時は、呼び出す前に、第二引数で渡すバッファの先頭に、バッファ長を
書いておく必要があるのに、それをやっていないからだろ?
LPTSTR pBuf;
pBuf=strText.GetBuffer(iLength);
*((LPWORD)pBuf)=iLength; // バッファ長をセット
m_wndEditCtrl.GetLine(iLine,pBuf);
strText.ReleaseBuffer(iLength);
自分でバッファ先頭にバッファ長をセットするのが面倒なら、引数が3つ
あるCEdit::GetLine()を使うことだ。
日付や時間を取得したいけどエラーがでてしまうんです・・・
内容は
Run-Time Check Failure #3 - The variable 'newtime' is being used without being initialized.
afx_msg void CMainWin::OnTime()
{
char str[80];
CTime Curtime = CTime::GetCurrentTime();
struct tm *newtime;
newtime = Curtime.GetLocalTm(newtime); //ここが問題
wsprintf(str,asctime(newtime));
str[strlen(str) - 1] = '\0';
MessageBox(str,"Time and Date");
}
http://msdn.microsoft.com/ja-jp/library/fxy17zta (VS.80).aspx
ここ見る限りじゃ間違いないと思うんだけどなあ・・・
指摘と改善お願いします。。。
207 :
デフォルトの名無しさん :2009/01/18(日) 16:57:35
>>206 突っ込みどころが大杉。釣りか?
C++やMFC以前に、ポインタも理解していないなら、C言語の基礎からやった
方がいいと思う。
MFCのサンプルは間違っているな。
struct tm newtime;
Curtime.GetLocalTm(&newtime);
でうまくいくだろう。
また、ワイド文字版のwsprintf()を使うなら「char str[80]」ではなく
「wchar_t str[80]」とすべき。MessageBoxもワイド版を使う。
> str[strlen(str) - 1] = '\0';
これもprintf()/wprintf()によって文字列末尾にNUL文字('\0')は付与され
ているから意味がないし、ワイド文字なら、strlen()ではなくwcslen()を
使うべき。
str[wcslen(str)-1] = L'\0';
第一、str[]がNUL文字で終端されていないと、strlen()/wcslen()は
文字列長さを判定できない。
>>207 MSのサンプル間違ってるとか悲しいわな
これ、一応参考書のサンプルなんですけど捨てたほうがいいでしょうか
まあ2001年に出版されたものなんですけどね
CTime Curtime = CTime::GetCurrentTime(); tm newtime; Curtime.GetLocalTm(&newtime); wsprintf(str,asctime(&newtime)); でできました! 参考書って年代で仕様も変わるけど図書館にはこれしかなくて・・・^^; なんか疑いにくいんですよね、参考書って どうもありがとうございました
本に誤字脱字があるのは珍しいことじゃない
おかしいと思ったら複数調べるのがいい。
>>210 その参考書が何か知らんが、MSDNのサンプルをコピペしただけの悪書なんじゃないか?
いみじくも参考書を名乗るのなら、ちゃんと検証されたコードを載せるべきだと思うのだが。
>>213 えっと・・・
ハーバート・シルト/フランク・クロケット著 「標準講座 MFC6.0」だそうです
結構分厚いからコピペではないと思います
ver間での使用の違いを疑わなかった自分のミスです
いやこれ仕様の違いじゃなくてもともと間違ってるよ。 でもその本見る限り、コピペじゃなくて同じソースってことみたいね
ってサンプルソースがダウンロードできるから見てみたけど、 struct tm *newtime; newtime = curtime.GetLocalTm(); これなら旧仕様で合法だな。
>>216 を2008でコンパイルするとGetLocalTm()に引数がないことからエラーがでました
昔はよかった
まあそれはMSDNのほうでも、_SECURE_ATLを未定義にすればいいみたいだけどね。
>いいみたい →いいと書いてるみたい
昔は引数にNULL(省略化)を渡すことで、オブジェクト内部のstruct tmの ポインタを返す仕様だったけど、NULLポインタを渡すのを許可しなくなった ってことでは? オブジェクト内部のstruct tmのポインタを取得できると、直接データを 書き換えて隠蔽化の意味がなくなるから。
元のサンプルと全然違ってるし
サンプルコードなんて使い方の雰囲気を感じ取るだけのもんで コピペするもんじゃねぇ。 自分のプログラムに組み込むときは、引数・戻り値の意味と動作を理解し 自分の頭でコードを書くべき。
サンプルコードをいじくりながら学ぶもんなんじゃねえの? いじくる前に1回コピペするだろ
いじくるのは勝手だけど、自分が間違ったのを本のせいにしない。
>>207 wsprintf()ってワイド文字ではなくTCHARだけど。
TCHARは_tsprintfみたいな名前だろ? wprintfはwcharのはず プリプロセッサで切り替わるだけだし
wsprintfはWindowsのAPI wprintfはprintfのワイド文字版
>>210 手元の2004年初版第6刷発行では
>>216 のコードになってるな
>>225-227 wsprintf()は環境によってマルチバイトかUNICODEだよね。
>>206 のコードだとマルチバイト環境のコードならばcharは間違えというわけではない。
それと
str[strlen(str) - 1] = '\0';
ってのはasctime()が改行文字を付加するからそいつを取っ払うため。
まぁ、あんまりよろしくないコードとは思うけどね。
wsprintfとwprintfとswprintfは紛らわしすぎる
230 :
デフォルトの名無しさん :2009/01/19(月) 05:48:07
処理をCPU使用率30%を上限に制限して実行させるにはどうすればいいんでしょうか? そんなことは可能なんですか?
なんでそんなことする必要があるのか疑問。 他のアプリの邪魔をしたくなければ、スレッドの優先順位を低くしとけばいいだけ。
惜しいな、Core2Duo単体なら上限は50%だ。
Core2Duo限定のソフトか!
いえ、Qのほうで
MFCと関係あるか?
誰ですか。勝手に話を進めないでくださいw アプリに重い処理を乗せたくて起動者全員CPU30%とか10%づつシェアするプログラムを組み込みたいんです 制限かけないとずっと自分が使ってなくてもずっと100%で熱暴走が心配なのでCPU10%を提供に制限したいんです。 どうすればいいと思いますか?
MFCにそういうライブラリが存在しなければスレ違い
>>238 熱暴走が心配ってどんな環境だよ。
「起動者全員」とか「シェアする」とかサーバーアプリなの?
どうしても心配ならユーザー数に応じてSleepでもさせたら?
CPU使用率を求める処理でCPUを食うから無意味
熱暴走については、昔の焼き鳥こさえてたAthlonの時代ならともかく、 今のCPUは温度が上がりすぎると勝手にクロックとか落とすので、特に問題ないな。 CPU利用率については、WindowsServerならプロセスがどれだけフル回転していようと、 一定時間毎に容赦なく他のプロセスに明け渡すから、無難なレスポンスが確保できそうかな、と。
優先度でいつでも明け渡せるとしても、気分的に窮屈な感じしませんか? 自分の作ったプログラムはいつも全力で走るんですが、CPU見てると常に20%ぐらいでなんかまわってたりするんですが 、タスクマネージャで確認してるだけなんですが、この%って一定時間内のCPU100%使用率ってことなんですか? そうでないとしたら%制限の方法を教えてください!
>>240 thx!
今ってCPUというかハードの性能がすごくてほとんどの処理がすぐ終わって待機時間がすごくもったいない気がしたので
そういう部分だけの汎用的なCOMとかで自由に独自のソフトに組み込めたらよくないですか?
10%シェアでも100人いればパソコン10台分ですよね。フリーでそういうのあれば教えてください。
Sleepでどうやるかじっくり考えます。
どうもです
無駄。つーか、スレ違いだと。 そもそも>234辺りの理屈は判っているのだろうか。
スレ違いだと何度指摘されても話を続ける奴って何なの? 知的障害者なの?死ぬの?
ム板は初心者にとってスレチが紛らわしいと思うけどこれはわかるだろ、な?
どこで聞けばいいんでしょうか? どうやって実現するかわからないのでターゲットのスレもわからないです。
>>250 >この板はプログラムを作る人のための板です。
>あらゆる質問はまずすれ立てるまでもない質問はここでスレにしてください。
thx
MDIで一つのDocに複数のViewというのはなんとか判る。今回、 そのViewが一つ1枚とその他10枚が別のViewになる構成ってどうやるのがいいのだろう。 CMultiDocTemplateを11個AddDocTemplateすることになるのだろうか。 その場合、クラスを派生して10個にしておかないと10枚の区別がつかない気がするのだが。 ってことで、これから移動するからレスは夜になるが、誰かヒント頼む。
254 :
デフォルトの名無しさん :2009/01/22(木) 09:50:02
Viewクラスだけ異なるDocTemplate作ればよいのではないか? たしか複数のAddDocTemplateをすると新規作成時にテンプレ選択ダイアログが出るようになるな
ドキュメントテンプレートはアイコン、メニュー、ツールバーみたいなリソース関係で ドキュメントごとじゃなくてドキュメントタイプごとに違うリソース使えるようにする
256 :
253 :2009/01/23(金) 00:42:41
今(帰って)きた。レスTHX。つーか、>253は出掛けとは言え酷いなぁw 結局、一つの必ず必要なViewだけドキュメントテンプレートにして、 他の10枚分は全部そのViewから必要に応じて開くようにしてしまった。 考えてみたら、新規作成ならテンプレート選択ダイアログが開くけど ファイルオープンだとどうせ最初のテンプレートでしか開かないしね。 それとも選択する手段があるのかな? # うーむ、今更真面目にMFCの勉強し直すのも面倒だなぁ……
同時に開く1個+10個が、常に同じファイル数でセットなのか、10個は 中身は異なるが同じクラスのオブジェクトなのか、そこらへんで全く 違ってくると思う。 開くファイルとビュー(ウィンドウ)を全てMDIのDoc-View構造に登録して 管理しなければならないかといえば、決してそうではない。 SDIだけど、ペイントブラシのように、開くのは1個の画像ファイルで、 一部を拡大表示するウィンドウを複数同時に表示できるなどというインター フェースだって作れる。 例えばMDIベースでVisual Studio相当のアプリケーションを作成すると して、独立した1個がプロジェクトファイル、残りのN個がプロジェクト を構成するソース/ヘッダファイルだったとして、ソース/ヘッダファイル はプロジェクトの一部としてだけでなく単独でも開ける。 プロジェクトの一部として開いたソース/ヘッダファイルは、プロジェクト に相当するドキュメントクラスで管理することになると思う。ソース/ヘッダ ファイルを単独で開いた場合、インターフェースに統一性を持たせるため、 一時的に無名のプロジェクトを作成し、それに管理させているような形に なるのでは?
CHtmlViewをMDIで使いたいんですが、 このビューを単独でプロジェクトに追加して開くにはどうすればいいですか? ドキュメントテンプレートでAddにすると、使わないのに.Docも作らなければいけないとおもうんですが。
>>258 クラスの追加もできない馬鹿は、MFCの参考書でも読んで勉強し直せ
もとからあるMDIViewにCHtmlViewを張り付けられなくないですか? ビューを切り替えるだけのときオープンドキュしなきゃいけないので.Docもセットなのが嫌なんですが
>>260 Viewクラスの使い方ぐらい調べろ、阿呆が
使わないDocがあってもいいじゃない m_pDocTemplate->OpenDocumentFile(NULL) が楽なんじゃないかなぁ
そんな書き方ができるんですね!ありがとうございます。
>>261 死ね
viewじゃないコントロールもあるよ
CDCクラスからウィンドウハンドル(hWnd)って取得できますかね?
つ CDC::GetWindow
AfxGetMainWnd()->GetSafeHwnd();
Visual Studio 2008 SP1にてMFCアプリケーションを作るんだけど、 ダイアログにも"視覚スタイルと色"を反映させたいのですが、 無理でしょうか? "視覚スタイルと色"を反映させたSDIでも、 ダイアログ(CAboutDlg)だけが浮いたデザインの気がするので、 知ってる方が居られればご教授願いたいです。
269 :
デフォルトの名無しさん :2009/01/31(土) 00:02:52
MFCって今後衰退して、.NETがデファクトスタンダードになるんですか? 今更、MFCをやれなんて上長から言われたんだけど、MFCでガリガリ かけるようになった頃にはVSから姿を消してたら淋しいな
少なくともMSは、数年前まではそのつもりだったんだろうな
MFCが消える頃に、やっとガリガリかける程度なら、 消えて当然のプログラマ。
>>269 触ってみたけど変わんない
俺、ツリーのドラッグアンドドロップが簡単にできるとか
リストの更新関連がうまくできるようになってるとかそういうの期待したけど
結局、全然改善されてないところがアフォだと思った
今ならノウハウや情報がそろってるMFCのがいいよ
.NETは糞面倒臭い上に情報少ない
んでMFCやってから.NET入っても同じところに気を配らないといけないのは
まったく同じなので情報が豊富なMFCから入ったほうがいいと思う
.NETの方が情報は豊富
MFCでやってたらいざとなったら素APIに逃げるからな って.NETでもP/Invokeに逃げたりするか
時代はVB
276 :
デフォルトの名無しさん :2009/01/31(土) 16:18:59
工エエェェ(´д`)ェェエエ工工
というかC++/CLIで.NETは書きにくい 凄く汚くなる C++/CLI単体は悪くないと思ってるけど
278 :
デフォルトの名無しさん :2009/02/01(日) 03:27:28
.NETを使わないならC++/CLIを使う必要があるのか?
CWinAppをCWinAppExに変えただけで、400KBから1800KBにexeファイルのサイズが大きくなった MFCでかくなりすぎワロタ
さらにリソース追加で3Mバ・イ・ト!
スタティックリンクしてんのか? ダイナミックリンクに直せよ
やだよばか
別にサイズなんかどうだっていいような気がするけどね でかいとなんかヤバイの?
284 :
デフォルトの名無しさん :2009/02/01(日) 22:22:36
>>272 ツリーの(略)とかはWPFではできるよ
ただ、C++/CLIじゃWPF使えないからC++のコードはバッサリ捨てなきゃならないけどね…
はじめまして。 MFCのコレクションクラスにて質問があります。 MFCのコレクションクラスにCListとCByteArrayってのがあります。 これを使って、たとえば通信電文の様に可変長データをリストに置きたい場合 CList<CByteArray, &CByteArray>と書けば良いのでしょうか? error C2955: 'CArray' : クラス テンプレート を使用するには テンプレート 引数リストが必要です ってのが出て、どうしていいかわからないです。 有効な宣言の仕方があれば、教えていただきたいですが・・・・
>>287 そもそも&の位置が前後逆だな。
直したところでCByteArrayはoperator=の実装が無いからやっぱり駄目だけど。
MFC的には、CList<CByteArray*>って感じにポインタで持つしかないと思う。
これ以上はSTLの出番か?全然詳しくないから答えられないけど。
C++で扱いやすい新しいフレームワークを作って欲しいのが本音だな .NETと住み分けて
WTLはそれなりに使いやすいだろメッセージハンドラもIDE上で追加できるし。 EEでは古いATLになっちゃうのが難だけどMFCじゃ使えないし。 eGUI++は使ったことないから判らないがstd::stringてのが嫌だな。
>>288 やっぱりSTLで組むしかないのですか・・・
がんばってみたいと思います。
ありがとうございます。
292 :
デフォルトの名無しさん :2009/02/03(火) 10:26:48
>>291 CByteArrayの派生クラスを定義して、そいつでoperator =を実装した上で、
CList<CMyByteArray, const &CMyByteArray>とすればいけると思う。
つーか、STL のコンテナではなく MFC のコレクションを使うメリットって何だろう。
STLをリンクしなくて済む
CObject からの派生していること
MFCベースならMFCに統一したいっていうのはあるな
297 :
デフォルトの名無しさん :2009/02/03(火) 23:03:50
CListCtrlのアイコンモードで ラベルを複数行表示させる方法教えてください
エクスプローラと同じだろ
>>298 ってことは2行までしか表示できないって事?
省略されずに複数行を表示はだめか・・・
>>293 デバッグ実行時にアサート出してくれる、とかMFC例外クラスのスローとか
ただ統一しないとめっちゃ不便
301 :
デフォルトの名無しさん :2009/02/04(水) 09:21:26
>>297 ラベルってヘッダコントロールのテキストのこと?
アイコンモードにヘッダコントロールはない!
アイコンラベルのワードラップかな?
今までEXEで作ってたのを、DLL化しようとしたけど プロジェクト作り直すのに凄い苦労する。 なんかいい方法あるかね?
aaa
>>304 数個なら手で
たくさんあるならPowerShellスクリプトで設定を置換
>>301 >>303 エクスプローラで言うとファイル名が表示されている部分です
そこに複数行の文字を表示したいと思っています
char sz[] = "AAAAAAAAAAA\nBBBBBBBBBBB\nCCCCCC\nDDDD\nEEEEE"
みたいな感じ、実際表示されるのは
AAAAAAAAAAA
BBBBBBBBBBBCCCCCC...
と表示されてしまっています
アイコンを選択するとちゃんと意図した改行位置で表示されるけど
選択していない状態でも全部ちゃんと表示したいです
\nじゃなくて\015\012にして試してみて と思ったけど、エクスプローラーでもファイル名が省略される場合があるから 自分で実装するしかないんじゃないかな
>>307 アイコン間隔を変える事である程度は回避できるかもしれないが、複数行で
無制限に表示すると、左右両側のアイコンのラベルや、下側のアイコンに
テキストがかぶる。
しかも、自動改行せず、1行の文字数(ラベル領域の横幅)や行数(ラベル領域
の高さ)を無制限にすると、ラベル領域が重なるのは隣接するアイコンだけ
では済まなくなる。
表示上はそれでも済むけど、常にそういう状態で表示すると、任意のアイ
コンやラベルをマウスでクリックできなくなるから、非選択時は省略表示
するというユーザインターフェースになっているんだと思う。
CViewやCScrollViewなりから、仕様を満足する派生クラスを自分で作る
しかないね。
2008のSP1入れてる人居たら教えてください。 SP1で初めてプログラム始めたのでSP1関係ないかもしれませんが、 テンプレートで作ったドッキングウィンドウの中にあるツールバーのボタンをコンボボックスに変えた後その中のエディット部分の文字列を 取り出すにはどうすればいいんでしょうか? .h CMFCToolBarComboBoxButton* m_ComboButton; .cpp // OnCreate m_ComboButton = new CMFCToolBarComboBoxButton(ID_EDIT, GetCmdMgr()->GetCmdImage(ID_EDIT), CBS_DROPDOWN); m_ToolBar.ReplaceButton(ID_BTN, *m_ComboButton); // OnButtonClick CString a; a = m_ComboButton->GetText(); ヘルプにある手順と、サンプルも見て書きました。ボタンは置き換わるんですが、aが空なんです。GetEditからGetWindowなどもいろいろやりました どうしても文字列を取得できません。お願いします!
>>310 サンプルのだけど
CMFCToolBarComboBoxButton* pSrcCombo = NULL;
CObList listButtons;
if (CMFCToolBar::GetCommandButtons(ID_DUMMY_SELECT_ACTIVE_CONFIGURATION, listButtons) > 0)
{
for (POSITION posCombo = listButtons.GetHeadPosition(); pSrcCombo == NULL && posCombo != NULL;)
{
CMFCToolBarComboBoxButton* pCombo = DYNAMIC_DOWNCAST(CMFCToolBarComboBoxButton, listButtons.GetNext(posCombo));
if (pCombo != NULL && CMFCToolBar::IsLastCommandFromButton(pCombo))
{
pSrcCombo = pCombo;
}
}
}
if (pSrcCombo != NULL)
{
ASSERT_VALID(pSrcCombo);
LPCTSTR lpszSelItem = pSrcCombo->GetItem();
CString strSelItem = (lpszSelItem == NULL) ? _T("") : lpszSelItem;
AfxMessageBox(strSelItem);
}
else
{
AfxMessageBox(_T("Show \"Set Active Configuration\" dialog...."));
}
}
調べてくれてありがとう。 一度LPCTSTRで取得してからCStringにしてみましたがだめでした。 コンボボックスのポインタのとり方もサンプルのように取得しましたが、だめでした。 CMFCToolBarComboBoxButtonのヘルプでGetTextは編集用のエディットのテキストを返すとあるのに これで返ってこないのがつらいです。 MFCの常識から考えて何か根本的なところのアドバイスをお願いします! 他にツールバーに並んでるボタンはボタンのメンバで無効とかにできるので、ツールバー上のアイテムの取得は出来てると思うんです。
>>312 アドバイスでいいのか。
ちゃんとドキュメントを読んで勉強しろ。
理解力があれば解決できるだろ。
GetWindowTextを使えば?
それもやったんですが、空でした。
>>311 のやり方でポインタを取得したら
GetEditCtrl()->GetWindowText
で取得できる。
だめです。 pSrcCombo != NULL のelseの方に飛びます。 もうべた貼りしましたがだめでした。 キーでボックスに入力したあとそれを更新してメンバ変数に入れなくてはいけないんでしょうか? GetText()の戻値がプロテクト変数を返すだけになっていたのですが、どこで入るのかがたどれません
CMFCToolBar::IsLastCommandFromButton(pCombo) を抜いたらいけるだろ?
みんなSP1も結構すらすら分かってるんだな 俺は来月から久々にMFCの仕事やりそうだから、VC6レベルでさえかなり不安だ
だめでした。 ID_DUMMY_SELECT_ACTIVE_CONFIGURATION をID_EDITにすると TRUEには飛びますが、 lpszSelItemが無効なポインタになります。 置き換えたボタンのポインタを取得するだけならGetButton(index)を使って CMFCToolBarComboboxButton* m_box = (CMFCToolBarComboboxButton*)m_toolbar.GetButton(index); CString str = m_box.GetItem(); これはどこが問題あるんでしょうか? あと頻繁に出るんですが、ブレークポイントで、現在の設定ではヒットしません。このドキュメントのシンボルが読み込まれていません。 と出て、右クリで場所の許可で対応してるんですが、これなんですか?関係ありますか?
もしかしてリリースビルドじゃないのか?それだとデバッグの変数モニタは出鱈目になるぞ
リリースじゃないです。ncb消しとかクリーンも頻繁にやってるんですが、 なんどもここ挫折して後回しにして2か月ぐらいチャレンジしてるんですが、今だにTextが取得できません 取得できると教えてもらえただけでもありがとうです。なにか設定か、全然違うところが原因な気がしてきました。
ちょっと説明が悪かったかもしれないけど、
>>311 はドロップダウンリストの場合に、リストを変更した時に取得する方法。
任意のタイミングで取得する場合は、
任意なので「CMFCToolBar::IsLastCommandFromButton(pCombo)」は要らない。
よって、TRUEに飛んだら
pSrcCombo->GetEditCtrl()->GetWindowText
で取得する。
>>308 >>309 ありがとう
時間的に厳しそうなのであきらめます
無制限に全部教示でなくても指定した行数だけは表示してくれるようになってると良かったなぁ
改行位置が結構重要なので省略された行は改行が無視されるのが痛いかった
>>323 おーできました!ありがとうございました。感動しました。
調べてもらってすいませんでした。じっくり解析します
ありがとうございました!!!
>>326 確かにそのページの主張には同意しかねるね。
CMutexについてはタイムアウトを特別視する用途以外(所有権が取得できたかどうかだけを知りたい場合)なら問題なさそうだし。
CSingleLockの再帰呼び出しはそもそも想定外の使い方だと思う。
CreateMutexの記述には待機関数を同じスレッドで繰り返し呼び出してもいいけど、
待機条件を満たす毎にReleaseMutexを呼べと書いてある。
再帰でデッドロックするのは当たり前だろうと
329 :
326 :2009/02/07(土) 23:58:47
>327-328 ありがとうございます。 やはり欠陥と言うほどではないようですね。
330 :
デフォルトの名無しさん :2009/02/08(日) 10:00:58
MDIでファイルを起動時に読み込むとき、pDocTemplate->OpenDocumentFileみたいな ことをしますが、initInstance意外の場所でするときにpDocTemplate->OpenDocumentFile を使うとき、newとかあたりをどうやってコーディングすればいいか分からないのですが 教えてください。
素直に CxxxApp::OpenDocumentFile() を使え
DrawTextで文字の背景を塗りつぶすのってどうやるんですか? DT_NOCLIPだけで出来てるところもあるのでDT_NOCLIPを付けたんですが白で塗りつぶされてしまいます。 色を指定しなくてもいいんですが、文字ボックスが出来ないようにしたいんです
CDC::SetBkMode() で OPAQUE 指定かな? 色はCDC::SetTextColor() 文字ボックスってなんだっけ。
// CDC::DrawText // このメンバ関数は、テキストを描画するために、デバイス コンテキストに現在選択されているフォント、テキストの色、背景色を使います。 ちゃんとマニュアル読めよ。 CDC::SetBkColor CDC::SetBkMode
ああ、背景の色だったな、すまん
そうだったBKだった思い出した Brushだと思い込んでた thx
ウィンドウの関係がわかりません。 CStaticのなかにCStaticを作った時 中のCStaticにクリックメッセージを送るには,Zオーダーをどうしようが外から中にメッセージを素通りさせるコードを書かない限り 届かないんでしょうか? 塗りつぶしの順序とか考えてたらわけわからなくなって来たんですが、 どうすれば整理できて自由に子、孫などにメッセージが届くようになりますか?
SS_NOTIFY
スタティックは特別だったんですね。なんで他のと出来たりできなかったりとわけわかんなかったんです ありがとうございました
特別というか「スタティック」なんだから、本来はそういう動的な目的では使わない。 スタティック=静的。
CWndだとパラメータとかが複雑じゃないですか だからなんか作る時はCStaticを基本にしてるんですが、もっといいのあるんですか?
状況がよくわからない。 パラメータが複雑で嫌気がさすほど、メインウィンドウにいくつものウィンドウがあるのか?
スタティックコントロールもウインドウには変わりないだろ いらないメッセージが発生しないようにデフォルトで殺してるだけで、 デフォルト以外がアブノーマルな使い方とは思わないな
カスタムコントロールとかは?
スタティックコントロールにIDを振れば良いじゃない
346 :
デフォルトの名無しさん :2009/02/08(日) 22:52:27
MFCってなんで、.NETみたいにポトペタ環境にしないの? コントロールも.NETの1/10位しかないし・・・
>コントロールも.NETの1/10位しかないし・・・ kwsk
>>346 .netってツリーのドラッグアンドドロップとか
リストコントロールのウィンドウ枠の固定機能とかって楽にできるようになってる?
結構、客から要望くる機能で毎回作らないといけないんだけど・・・
ウィンドウ枠の固定ってなんだ? コンテナに貼り付けてDock指定するやつのことかな?
SS_NOTIFYでCStaticの子どもにメッセージが届くようになりましたが 今度は子がある部分をクリックしたとき親のクリックが実行されなくなりました。 クリックした場所にある特定の全ウィンドウにクリックを送るにはどうすればいいんでしょうか
MFCはAPIをラップしたようなコントロールしかないんだよな
まぁそこから派生クラス作るわけだね 自作コントロール作るにはもってこいだ
>子がある部分をクリックしたとき親のクリックが実行されなくなりました 親は「クリックされていない」からな。 クリックされた座標を含むウィンドウを列挙して、それらのウィンドウすべてにメッセージを送る関数を 自前で作るしかあるまい。
CMFCMenuBar を使うと、例えば ファイル(F) とかの F の下にラインが引かれないんだけど、 これはどうすれば直る? TBSTYLE_NOPREFIX はつけていないんだけど・・・。
>>355 当然、文字列は「ファイル(&F) 」ってやってるんだよな?
ところで、プルダウンメニューはCMenuだと思うけど、CMenuBarを使ってる
ということは、ツールバーのボタンのキャプションでアンダーバーが表示
されないってこと?
そもそもツールバーやダイアログバーに、そんな機能あったっけ?
>>355 MFC内部で&を消して描画してるから無理。
&&Fとか&&&Fって書けば表示はされるけどAlt+Fに反応しなくなるからやはり無理。
フューチャーパックは問題だらけだから諦めろ。
>当然、文字列は「ファイル(&F) 」ってやってるんだよな? もちろん。 たとえば IE7 のメニューバー。あれもツールバーじゃん。そこにはアンダーバーがついてる。 他のアプリケーションでも同じ。 だけどCMFCMenuBar を使うと付かない。 Visual C++ 2008 Feature Pack のサンプル見ても付いてないんで仕様なのかなという気もするんだが、 何か見落としているよーな気もしてしっくりこないんだわ・・・。
おっと、書いているうちに書き込みが。
>>357 やっぱ仕様ということね。ふむ。
Feature Packなんてあるの初めて知ったわ まだベータ版なのか でもおれのVSは2005(´・ω・`)
と思ったら今はリリースverなのね、スマソ
いやもうSP1に組み込まれてる。
C++0x よりも 2008 SP1 のバグフィックスに力を入れて欲しいよな バグがあるうちは業務で使えない
Feature PackでCDialogBarって表示される? 俺だけなんかな?
CPaneDialogを使えば CMFCxxxBar と連携できるのでは?
366 :
364 :2009/02/10(火) 19:31:47
>>365 CPaneDialogのCreateメンバで、IDを指定するのね。
おぉぉーできたwww
サンクスコ
367 :
デフォルトの名無しさん :2009/02/11(水) 20:44:07
MDIでexeのアイコンにドラッグ&ドロップをするとファイルが開けるようにしたいのですが、 CString drag_file(m_lpCmdLine); if (drag_file != _T("")) { pDocTemplate->OpenDocumentFile(drag_file); } ではファイルが見つからないというメッセージボックスが出てうまくいきません。 MessageBox(drag_file);として見ても、ちゃんとドラッグしたファイルパスが拾えてるのですが・・・ どうすればイイですか?
ちゃんと引数飛んできてるか?
369 :
デフォルトの名無しさん :2009/02/11(水) 21:03:37
MessageBox(drag_file);で見えるのできてるハズですが・・・。
370 :
デフォルトの名無しさん :2009/02/11(水) 21:21:37
デバッグのパラメータにパスを入れたら起動してますます理解に苦しんでいるのですが、 Unicodeで開発しているのですが、文字コードのせいとかありますか?
MessageBoxじゃなくてデバッガでデバッグしろ
>>367 CString drag_file;
drag_file.Format( _T("\"%s\""), m_lpCmdLine);
// To Do...
すんません質問です。 VC2005で、CRichEditCtrlをもったダイアログベースのアプリを作っております。 CRichEditCtrlにShift_JISにないような文字(「もげる」を変換したらでる漢字とか)を 入れて、GetWindowTextWでその文字をCStringに取り込むと、その文字が?になって しまいます。これを回避する方法はありませんでしょうか?
CStringが実はCStringAでした、ってオチは嫌だなあ。 昔と違って、今は簡単にMBCS/Unicode変換しちゃうからなあ。
375 :
373 :2009/02/16(月) 22:47:35
リソーススクリプト上だと、常に"RichEdit20A"で固定なのが大元の原因か。 なるほどなあ。
377 :
デフォルトの名無しさん :2009/02/17(火) 21:49:00
う〜ん、serialize中にファイルが壊れている事に気づき、 子ウィンドウを開くのをやめたい場合ってどうしてます?
気づいたのなら開かなきゃ良い。 子ウィンドウとは何物?
MDIのことか?
メインウィンドウから起動するダイアログにラジオボタンを設置しました。 起動時に選択されているラジオボタンを(動的に)変更したいのですが、やり方がわかりません。 ダイアログのコンストラクタ中でSetCheckをしても、 コンパイルは通るのですが、デバック中に「Debug Assertion Failed!」 と落ちます。(まだ実体ができてない?)
つ oninitdialog() 最近MFCやってないからあやふやだ・・・ 来週からまた使うことになりそうだからリハビリせねば
>>382 既に見ていないかもしれないが ...
ダイアログ派生クラスに、ラジオボタンに対応するint型のメンバ変数を
割り当てて、DoDataExchange()内でDDX_Radio(pDX,...)でコントロール
に関連付けておけば、ダイアログウィンドウが生成されていないタイミ
ングでも、クラスのオブジェクトが生成された時点で、メンバ変数には
アクセスできるので、メンバ変数の初期値を変更してDoModal()すれば、
ラジオボタンの初期値を変更できるよ。
クラスウィザードでメンバ変数を割り当てると、コンストラクタで「-1」に
初期化されるコードが自動生成されるので、これを0〜の値にすればいい。
>クラスウィザードでメンバ変数を割り当てると、コンストラクタで「-1」に >初期化されるコードが自動生成されるので、これを0〜の値にすればいい。 VS2008 だと初期値は 0。修正されたのかな。 ちなみに、変数のカテゴリには Value を選ぶこと。
MSDNのScribbleサンプルなんかを見ると、 リスト(m_strokeList)や配列(m_pointArray)などのメンバは堂々とpublicで、 描画時などは外から直接参照したり操作してるけど、 これってやはり手を抜いているだけでしょうか? それとも、この程度のものはいちいちカプセル化しないものなのでしょうか?
Scribbleサンプルって15年くらい前からあるよな・・・
>>385 クラスウィザードでメンバ変数を作ると、意識して設定しない限り public になる。
MSのサンプルは「動けばまだマシな方」くらいに思っとかないと。
CPaneDialog型って、リサイズをさせたくない場合どうすればいいんでしょ? 知っておられる方、情報をお願いします。
CBasePane::CanBeResized をオーバーライドして FALSE を返す
「このメソッドは現在実装されていません。」だった。すまん
実装すればいんだから、それでいい
393 :
389 :2009/03/03(火) 09:10:56
>>390-392 Visual Studio 2008のIDEでは、
派生元へのオーバーライドができないのね・・・手書きなのか・・・
できました!
ありがとうございます!
むみません。 ダイアログ上でレイアウトされたグループボックスにて、 文字色をで変更しようとSetTextColorを使ったのですが、 反映されませんでした。 何かコツみたいなものがあるのでしょうか? ちなみに環境はVS2008でMFC Feature Packを使っています。
むみません。
VC++ 6 でプログラミングしています。 ポップアップメニューを表示しています。 各行で文字位置を合わせたいので固定ピッチのフォント を利用したいのですが、ポップアップメニューのフォント はどのようにすれば変更できますか? ポップアップメニュー作成は、TrackPopupMenuを使っています。
ちと古いけど
>>129 の件、おれも悩んでたんで調べた結果を貼っとく。
afxGlobalData.SetMenuFontで設定するといいらしい。
他にもafxGlobalDataをいじるといろいろできるけど、
これ直接いじっていいんかな?
それをいじる関数として、CMFCMenuBar::SetMenuFont() が用意されているんだが。
あれ、CMFCMenuBarのヘルプを見てもFont関係が見あたらなかったから MFCのソースを追っかけたのに・・・・ 思いっきり見落としたらしい。
ついでに言っておくと、WM_SETTINGCHANGE が飛んでくると CMFCMenuBar::SetMenuFont() した内容はクリアされるから、再度設定しなおすこと。:-)
403 :
◆8x8z91r9YM :2009/03/09(月) 21:08:28
質問です。 VS2005 MFCでCrystalReport(PUSH型)を扱ってる 参考になりそうなサイトをご存知の方おられましたら 教えていただけませんでしょうか? C#やVBなどは表示したいデータをDataSetでまとめて Crystalreportに渡して表示できますが、 それをMFCでどのように実装すればいいのか悩んでおります。。 よろしくお願い致します。
VS2008SP1のCMFCToolbarで、初期状態からアイコンの右側にテキストラベルを表示する方法は無いでしょうか。 ToolbarResetを発行してやると、文字は表示されるにはされるんですが、 カスタマイズ設定も消えてしまうので・・・
横に表示できたっけ? CMFCToolBar::EnableTextLabels() だと下に表示だよな。 CMFCToolBar::GetButton( nIndex)->m_bText = TRUE; あたりで試してみ。
VS2005 WinInet で http Postを使ってファイルアップロードをするプログラムを書いているのですが うまくいきません。 ソース 80行程度をアップしてアドバイスを頂いてもよろしいでしょうか? 1週間ぐらい頑張りましたが分からなかったもので・・・。
それのどこがMFC?
質問部分にCInternetSession等のMFCクラスを使ってれば質問は可 ただ「うまくいきません」としか説明できないんじゃ答えるつもりはない。
406です。スレ汚し失礼します。 状態としてはデバッガ出力ではエラーは帰ってきていませんが スニファツールで見ると サーバから501エラーが帰ってきています。 サーバ側のPHPテストプログラムの方は $_FILES["upfile"]["tmp_name"] にも $_FILES['userfile']['error']にも 値が入ってきません。 多分ヘッダの送り方、設定の仕方がおかしいと思うのですが。。。 ソースは以下になります。
80行貼るのかよ ろだ使っては
#define APP_NAME "PostTool" #define BOUNDARY "hogehoge" #define POST_FILE "C:\\TEST.DAT" #define BUF_SIZE 2048 bool PostData(TCHAR* uri){ bool bRtn = false; try { DWORD dwServiceType = 0, statusCode; CString strServer, strObject, strBuf, strBoundary = TEXT(BOUNDARY); INTERNET_PORT nPort; char szBuf[BUF_SIZE + 1]; if (AfxParseURL(uri, dwServiceType, strServer, strObject, nPort) == false) {OutputDebugString(TEXT("PostData() AfxParseURL失敗\n")); goto pd_End;} CInternetSession session(TEXT(APP_NAME)); CHttpConnection* conn = session.GetHttpConnection(strServer, CHttpConnection::HTTP_VERB_POST, nPort, NULL, NULL); CHttpFile* file = conn->OpenRequest(CHttpConnection::HTTP_VERB_POST, strObject, NULL, 1, NULL, NULL, INTERNET_FLAG_RELOAD | INTERNET_FLAG_DONT_CACHE);
http://support.microsoft.com/kb/811262/ja エラー メッセージ : エラー 501/505 - 未実装または未サポート
[HTTP 1.1 を使用する] チェック ボックスをクリックしてオフにし、[OK] をクリックします。
テストして問題が解決したかどうかを調べます。
2002 年 12 月現在、HTTP 1.1 は新しい Internet プロトコルです。
一部の Web サイトでは HTTP 1.0 が使用されているため、HTTP 1.1 を使用した場合、
接続の問題が発生することがあります。
こういう場合 プログラムに問題がある 設定が間違ってる 使い方が間違ってる ネット上にトラブルがある メールを送った相手に問題がある みたいにありとあらゆる原因が考えられるわけだけど いきなりプログラムのソース見ろと言われても 設定が間違ってる 使い方が間違ってる ネット上にトラブルがある メールを送った相手に問題がある だったら見るだけ無駄だろ
サーバ側のhttpdのログ見たらわかると思うよ
こういった感じでソース書いている人って多いのか? ・グローバル関数だし、 ・コメントないし、 ・goto ラベル使い放題だし、 ・for(;;)だし・・・ (while() 使えよ)
別に習作なんだし そういう関係ないところつっこむからソース出したがらない質問者が増える
Httpは手順が多くてネストが深くなるしエラー処理も多いからどうやっても汚くなる 手抜きしないできれいに書いてあるサンプルあったら見てみたい
>>416 > ・グローバル関数だし、
> ・コメントないし、
コミュニケーション能力重視とか、ヒューマンスキル重視の現場では、
ありがちだ。 業務で引き継ぐと悲惨なパターン。
しかも極端な場合、グローバル変数の名前が「i」なんて場合もある。
> ・for(;;)だし・・・ (while() 使えよ)
個人的には「while(1)」の方が好みだけど、「for(;;)」の方が推奨
されているらしい。
しかし、「for(;;)」を使いながら、forループ内で「if(...) break;」
はやめてほしい。
>>419 >しかし、「for(;;)」を使いながら、forループ内で「if(...) break;」
そりゃ無茶や。
全く脱出しないループで外部から殺してもらうってことなら兎も角、
ループ内の何かの事象で脱出したくなることくらいあるだろよ。
>>416 while(1)はMS-C V6がwarning吐いてたから、おれはfor(;;)使うよ。
>>420 そういう場合forに脱出条件を入れろという説がある。
おれは基本的に嫌いだけどね。
for (;;) { ...; someStatus = someFunction(); if (someStatus) break; ...; ...; } -- よくありがちなこんなコードを否定するのかな?
someStatus が いつか必ず TRUE になるという保証があるなら、かまわんのでは。 無限ループの可能性を残すコードを、おれ個人は書かないけど。
for (;;)の正しい使い方が良くわからないからMFCのソースの中探してみたけど やっぱfor (;;)とbreakはセットで使ってるね 以下VC6のMFC SRC\AFXMEM.CPP(322): for (;;) SRC\AFXMEM.CPP(371): for (;;) SRC\APPUI1.CPP(172): for (;;) SRC\ARCCORE.CPP(816): for (;;)
下らない疑問かもしれませんが質問させてください。 MFCでコントローラに追加した文字列のメモリ管理ってどうなってるんでしょうか? 例えば、以下のような場合、FuncA()関数を抜けたときに strのアドレス先のメモリが解放されて、コンボボックスで strの文字列が参照できなくならないのでしょうか? 試したところ問題ないようですが、不思議です。 void FuncA() { CString str; m_pCmbBox->AddString(str); //メンバ変数であるコンボボックスに文字列追加 }
コントロールが別のところでメモリを割り当ててるのさ。メモリの割り当てに失敗したら CBN_ERRSPACE が通知されてくる。 これはMFCの質問じゃないな。
>>426 すみません、もう一歩だけお願いします。
調べるなら、C++のメモリ管理で調べればいいでしょうか?
フォントなんかが参照不能になるのは 描画のタイミングが関数抜けた後だから 文字列は渡し終わってるから問題なし
>>426 , 428
まとめるとこうでしょうか。
・コントローラに文字列を渡すと、コントローラが新たにメモリを割り当てる。
・この場合、関数を抜けた後も、描画タイミングで割り当てられたメモリが参照されるので問題なし
ただしフォントの場合は、メモリ割り当てが行われない(?)ので、関数を抜けると参照不能
コントローラのメモリ管理について調べてみます。
ありがとうございました。
どうでもいいけど「コントローラ」ってなんだよ。 controllerじゃなくてcontrolだぞ。
>ただしフォントの場合は、メモリ割り当てが行われない(?)ので、関数を抜けると参照不能 これは単にスコープの問題
スコープの問題じゃなくて、寿命の問題。 スコープが外れても寿命が続くのなら大丈夫。 だから例えば、staticでも(一代限りは)使える。
フォントって、CFontクラスやCBrushクラス等のGDIオブジェクトをローカル 変数で作成したなら、関数を抜けた時点で変数の寿命が尽き、DeleteObject() を呼んでいなくてもデストラクタから(メンバ変数のm_hObjectを使って)強制 的にDeleteObject()が呼び出され、(GDIオブジェクトとそのハンドルが)破棄 される。 CFont *pFont=new CFont; などとやった場合、ポインタ変数の寿命が尽きても、newしたオブジェクト 自体はdeleteはされないので、プロセス終了まで、紐が切れた凧のように メモリ空間に残る。 95系だとプロセス終了でも解放されず、リソースリークになるんだっけか? static で宣言したオブジェクトでも、 if(s_FontStatic.GetSafeHandle()) s_FontStatic.DeleteObject(); s_FontStatic.CreateFontIndirect(...); と破棄する手順を踏めば、何回でもリサイクルできる。
CMFCToolbar上にStatic Textを作成できないですかねぇ・・・
>>435 CMFCToolbar って、CDialogBar よりも美味しいの?
スタティックテキスト相当な機能なら、わざわざウィンドウを置かなくても
CString型のメンバ変数を追加して、ツールバーの描画処理を自前でやれば
いいだけのような肝。
438 :
デフォルトの名無しさん :2009/03/22(日) 15:54:16
ダイアログ上のコントロールのタブオーダーが一つ前のコントロールIDを調べるにはどうしたらいいんですか? 例えばCEditが10個並んでいるとして、5番目のタブオーダーのCEditにフォーカスがある時に、 4番目のタブオーダーのコントロールIDを調べたいんですが。 "タブオーダー MFC"でググってもタブオーダーを変更する方法しか見つからなくて。 タブオーダーがらみのAPIって無いんですかね?
CWnd* pWnd = wndEdit.GetWindow( GW_HWNDPREV): if ( pWnd->GetStyle() & WS_TABSTOP) UINT nID = pWnd->GetDlgCtrlID(); // こいつがそう。 else pWnd = pWnd->GetWindow( GW_HWNDPREV); 以下繰り返しってな感じで取得できないかな。 実際には while ループするほうがお得だろうが。
>>439 どうもありがとうございます。
GW_HWNDPREVというのはウインドウのZオーダー順であるだけでなく、
Window上のコントロールのタブオーダー順でもあるんですね。
441 :
デフォルトの名無しさん :2009/03/22(日) 21:59:09
C初心者スレで相手にされなかったので、質問させてください MFCでアプリを作っているのですが、 動作確認のため、コンソールも起動しております。 _cprintf_sや_cscanf_s関数を使っているのですが、 _cscanf_s関数でバックスペースのキーを入力すると、 プログラムが無限ループで暴走してしまいます。 普通のscanf()関数のようにバックスペースで一つ前の文字を削除するには どうすればよいでしょうか?
暴走するようなもの使うな
MFCも使っているのかもしれないけど_cscanf_s関数ってMFCじゃないし コンソールならダイアログにEditコントロールを置いて表示・入力するって感じになりそうだけど デバッグ表示だけならTRACEマクロが便利 値の入力は・・・ちょっと試すだけならブレイクポイントで値の代入とか
444 :
デフォルトの名無しさん :2009/03/23(月) 21:24:49
いまさらながら、mfcおもしろいお。 詳しい説明書ないかお?
SP1以降の解説か、まだないかもな。
>>444 SP1非対応でよければMicrosoft Pressの「プログラミングVisual C++.NET Vol.1/2」
Vol.2の最後にちょろっと.NETの説明があるけど、それ以外はMFCの説明になってる
後はmfcのソース読んどけ、ってところだな。 ドキュメント化されていない情報が山ほどあるし。 別に全部目を通さなくても、疑問に思った箇所だけで十分。
448 :
デフォルトの名無しさん :2009/03/27(金) 13:56:06
ちょっと質問よろしいですか? CDialogを継承したCxxxDialogというクラスを作って、 そこにWM_UNINITMENUPOPUPというメッセージが来たときのハンドラを作成したいのですが、 VC++の開発環境から追加しようと思っても、CxxxDialogクラスのプロパティのメッセージのリストには出てきません。 クラスのプロパティのメッセージの一覧には、限られたメッセージしか扱ってないようです。 ここにないメッセージのハンドラを追加したい場合はどうしたらいいのでしょうか?
↑開発環境はVC++2005です。
メッセージマップに、 ON_MESSAGE( WM_UNINITMENUPOPUP, &OnUnInitMenuPopup) xxxDialog.h に afx_msg LRESULT OnUnInitMenuPopup( WPARAM wParam, LPARAM lParam); xxxDialog.cpp に LRESULT CxxxDialog::OnUnInitMenuPopup( WPARAM wParam, LPARAM lParam) { // ToDo... return 0L; }
しばらくBCBを使ってたんで今どうなってるか知らないけど BCBのTDrawGridみたいなものないでしょうか 条件はwin+exeのみで実行出来てCListView(だったかな)以外です
>>452 TDrawGirdとやらに充分近づいたと納得できるまで、CListCtrlを拡張する。
TypeがPICTYPE_ICONであるCPictureHolderオブジェクトからHICONオブジェクトを作成するにはどうすればいいでしょう?
>>454 作成というか、ハンドルを取得するなら、
m_pPictメンバにIPictureインターフェースのポインタが入っているから、
ここからget_Handleで取り出すのが一番早いかな。
>>455 thx
@get_Handleでハンドル取得
AHICONでキャスト
BCopyIconで複製
でいけた
457 :
デフォルトの名無しさん :2009/03/31(火) 20:43:19
MFCは一人せっくすより面白いな。
それは「たいして面白くない」という意味の例えだね
やり方によるだろ
ActiveXでIPictuDisp*型で画像ファイル読み込んでんだけど ここからファイルパスってとれないかな?
ミス、IPictureDisp*型です
>>460 IPictureDispって、デバイスコンテキストみたいな感じで
データソースがファイルとは限らないんじゃない?
ファイルパスの保持はこのオブジェクトの役目ではないような気がする。
ですよね、あきらめます
ウィザードを使わないMFCの入門サイトってありませんか? ウィザード使うと訳が分からなくなるので、手動で最低限必要なところだけ書いてMFCを使いたいのですが
入門を卒業してから、ウィザードを使うのをやめればいいと思います。
書籍の標準講座MFCのソースが落とせるからそれで勉強
>>466 ありがとうございます!
標準講座MFCという本を買ってみようと思います。
CRichEditCtrl::GetSelTextで複数行にわたるテキストをCStringに取り込み、 そのテキストにある改行を Find(_T('\n', 0) と書いて検索したのですが-1しか 返ってきません。文字セットはUnicodeを使っていますが、マルチバイトでも 結果は同じでした。 地味にwcsstrとかを使わないと駄目でしょうか?
CStringに取り込んだデータの内容確認してないのか?
ちゃんと返ってくるよ。 CStringの中身を確認してみ。
Unicodeだと\nじゃなくて\rでした。お騒がして申し訳ありません。
>Unicodeだと\nじゃなくて\rでした。 \nと\rの違い、解ってる?
ワロタwwwwww
判りませんが、何か? CStringをメモリダンプしたら0dだけだったので\rにしただけです。
それはよかった
ダメだこりゃ。
>>474 その問題解決で合ってる。
煽ってる人はおかしいね。
Unicodeは\rでそれ以外は\nと言ってるように見える
思い込みまたは深読み
文字セットもエンコードも関係ないのに、
>>471 で
>Unicodeだと
と明示しているわけだが。
>>477 >煽ってる人はおかしいね。
あまり親切ではないが、教えてくれてるんだろう。
Unicodeなんかより先にWindowsの勉強した方がいいんじゃね?w
VC++6.0で、人の作った既存のMFCのプログラムを改修しています。 以下の手順で、ダイアログと関連付けられているはずのクラスが ClassWizard上からは参照できなくて困っています。 1.リソースのダイアログ上で右クリックしてClassWizardを選択 2.新規クラス名を求められるので、「既存のクラスの選択」を選ぶ 3.「クラスに関連付けられていません」と表示される上、クラスを選ぶ リストにクラス名がひとつも表示されないので、選択できない。 (今、手元にVC++がないので、多少手順がちがうかもしません。) プログラムを実行すると問題なく動きます。 また、ダイアログに関連付けられているはずのクラスのヘッダファイルを見ると、 ClassWizardで生成したと思われる関数("//{{AFX_MSG"コメント内にOnXXX関数がある) が書かれています。 原因や対処法などわかりましたらよろしくお願いします。
>>482 とてつもなく昔の話なのでうろ覚えだが、VC6ではクラスウィザードはしょっちゅう破損するから
いつも何かのファイルを消して対応してたような気がする。
なんだっけなぁ、拡張子がclwみたいやつだったかなぁ・・・
>>483 ありがとうございます。
clwファイルは、問題のダイアログの箇所が、Class=?になってました。
(普通は関連したクラス名が書かれているような)
試しに手でクラス名を書いたら、reloadのエラーメッセージが半永久的に…
clwを削除して、ビルドすれば再作成されるのでしょうか?
やってみりゃいいだろ。 バカが。
>>484 やってごらんよ。必要ならバックアップをとった上で
どうもです。明日やってみます
488 :
483 :2009/04/07(火) 22:44:44
VC6使ってた人、ここにはあんまいないのかな? 当時は、周りの人たちはみんな知ってたしMLやWeb上でもFAQ扱いだったから 正確な情報知ってる人が颯爽と現れてくれないかなと思ってたんだけど。
VC6使ってたけど、クラスウィザードは使ってなかったな
>488 そこまでヒントでてたら自分で調べるもんだろ しかも職業プログラマに手取り足取り無料サポートする必要あるのか?
ははは
ひひひ
ふぉーっ
MFCじゃなくてVisualStudioのネタになるけど 昔からncbを消したりclwを消さないと変な挙動になる事はあるよね
少なくともプロジェクトorソリューションをアーカイブするときは必ず消しているなぁ
496 :
482 :2009/04/08(水) 23:13:46
皆さん、ありがとうございます!
clwを削除してリビルドしたところ、ClassWizardが直りました。
VC++自体に不慣れで、ファイルを消すということは盲点でした。
>>495 次からそうします。
MFCのSDIで、ChildView(クライアント)のサイズが640x480なウィンドウを作りたいのですが CChildView::PreCreateWindowの cx.cx を変えてもサイズが変わらず CMainFrame::PreCreateWindowの cx.cx を変えても外枠のサイズが変わり、クライアント部分が小さくなり、 CRect rect = CRect( 0,0,640,480 ); AdjustWindowRectEx( rect , cs.style , TRUE , cs.dwExStyle ); cs.cx = rect.Width(); cs.cy = rect.Height(); と、書いてみたのですが、 ステータスバーやツールバーの部分が計算に入れられてないので やや狭いという感じになるのです。 なにか、いい方法はありませんか?
void CFrameWnd::RecalcLayout() をオーバーライド
クライアント領域のサイズ調べて差分だけ外側のサイズ変更みたいな単純な話じゃないのか?
500 :
デフォルトの名無しさん :2009/04/09(木) 19:18:22
MFCおもしれえお( ^ω^) でも、むずかしめなサンプルが載ってる本がすくないんだお( ^ω^) VC++6のころの本をあさるしかないんだお( ^ω^)おまけにネットワークをカバーしてる本もすくないんだお( ^ω^) Impressの赤い分厚い本のシリーズでMFCの本があればよかったとおもうんだお( ^ω^) ハーバーと汁とのMFCの本はあまりおもしろくないお( ^ω^)
いまさらMFCの本を出しても売れなさそう
ドトネト本なら売れるのか?
馬鹿なSEが 何も分からず.NET.NETうるさいから そういう人に売れてるんじゃね
リボンを付けたい人にMFCが大人気! という事実はない。
そのうち、.NETを超える何かが出て中途半端な存在になるのさ
こ
WPFに触れた後だと、MFC(というかWin32コントロール)を使ったUI構築がものすごく面倒に感じる。
510 :
デフォルトの名無しさん :2009/04/11(土) 00:38:18
MFCも.NETもWPFもどれでもけっこうだが、Javaだけはくそ。あんな糞言語二度とやりたくない。 ただより高いものなし。12万打して、VSPRo買ったほうがはるかに有益。
CRichEditCtrl::FindTextで日本語のテキストを検索しようとしても-1しか返ってきません。 文字セットはUnicodeで、第一引数にFR_DOWN、第二引数にはFINDTEXTEXWを使っています。 chrg.cpMinに0、chrg.cpMaxに-1、lpstrTextにCString::GetBufferの戻り値を入れてます。 何か足りないものがあるんでしょうか?
>>511 脳みそ、知識、技術、考える力。
好きな物を選べ。
全部足りないんでご教示ねがいます。
lpstrTextの中身が空だったなんてオチはなしにしろよ
CStringには文字列が入っていて、デバッグでFindTextの呼び出し時にも空に なっていないことは確認できています。
VS2008だと普通に機能するなあ、とか色々試しているうちに思い出したのだが、 VS2005だと、リッチエディットコントロールは 常にクラス名が"RichEdit20A"に固定されていた気がする。 で、VS2008のMFCだと、FindTextはEM_FINDTEXTEX呼び出しに変換されていたので それ以前のVer.でも同じなんじゃないかなあ。 で、何が言いたいかと言うと、クラスとメッセージに妙な関係があるわけで。 x64Vista SP1/VS2008 SP1 でテストしてみた結果は下記の通り。 Unicode-ANSI変換時に化けちゃってるのかねえ。 ちなみにANSI/Unicode、x86/x64で違いは無かったので省略。 ・RichEdit20A OK : SendMessageA/EM_FINDTEXTEX NG : SendMessageA/EM_FINDTEXTEXW NG : SendMessageW/EM_FINDTEXTEX (VS2005?) OK : SendMessageW/EM_FINDTEXTEXW ・RichEdit20W NG : SendMessageA/EM_FINDTEXTEX NG : SendMessageA/EM_FINDTEXTEXW OK : SendMessageW/EM_FINDTEXTEX (VS2008) OK : SendMessageW/EM_FINDTEXTEXW 今時ANSIビルドも無いだろうし、EM_FINDTEXTEXWを直接呼んだほうが早いか。 クラス名弄るよりよっぽど楽だし。
すみません、VCのバージョンかいてませんでした。XP SP3/2005 SP2です。 指摘の通り、SendMessageWでEM_FINDTEXTEXWで呼び出してみましたが、やはり-1しか返って きませんでした。 あと、CRichEditCtrl::FindTextの宣言を調べてみたら、#ifdef UNICODEでFindTextWになっていました。
>>517 ダメだ。
おまえは、いろいろ分かってなさ過ぎる。
AfxInitRichEdit2してないというオチだったりして
AfxInitRichEdit2はしています。 何がわかっていないのか、ご教示願えれば幸いです。
CStringW strFind(_T("探す文字列")); FINDTEXTEXW ft; ZeroMemory(&ft, sizeof(ft)); ft.chrg.cpMin = 0; ft.chrg.cpMax = -1; ft.lpstrText = strFind; long pos = richEditCtrl.SendMessage(EM_FINDTEXTEXW, FR_DOWN, (LPARAM)&ft); richEditCtrlはCRichEditCtrlクラスの変数。 これで動作しないなら現ソースを全てupするしかないな。 俺が調べた限りでは、EM_FINDTEXTEXWが最強っぽいのだけどなあ。
richEditCtrl.SendMessageのところ、::SendMessageにしていてました。 期待通りの動きが確認できました。ありがとう御座いました。
CRichEditCtrl::FindTextもrichEditCtrl.SendMessageも 中の人が::SendMessageしてるだけだから、どれ使ってもできない方がおかしい。
送り先間違ってたんじゃないの
Visual Studio 2008からMFCアプリケーションを開発するとき、 スプラッシュスクリーンをどうしています? 自作ですか? それともCSplashWndに代わるクラスがありますでしょうか?
必要性がないからつけていない。
MFC開発の初心者ですが、質問させてください。 MFCアプリケーションにて、 ダイアログ操作による選択を行う場合、 CDocument派生クラスのポインタを 対象のダイアログの引数で参照させることは一般的でしょうか? それとも、AfxGetApp()の様なグローバルな関数があるのでしょうか?
view以外では参照しない
529 :
527 :2009/04/13(月) 19:55:27
>>528 ではCViewから派生したクラスを参照させるのですか?
まず、MFCの想定しているダイアログの使われ方としては、 1.ダイアログのインスタンスを作成 2.必要に応じてインスタンスに現在の設定内容を渡す 3.表示 4.インスタンスから変更された設定内容を取り出す こんな感じ。 UIとメンバ変数の内容交換はDDX/DDVでやれ、と。 そこらへんは、コントロールに対して「変数の追加」とかやれば勝手にやってくれる。
531 :
527 :2009/04/13(月) 20:25:03
>>530 やはりそうか・・・
引数などで参照させて
ダイアログ内でCDocument派生系を操作するのではなく、
ダイアログによる操作後、手前でCDocumentを操作するのですね?
プログレスダイアログ風な事を考えるのは邪道だと、、、
>>531 俺なら、こんな風にやっちゃったりするけど。
class CMyDlialog : public CDialog
{
...
private:
MyData& mydata;
public:
CMyDlialog(MyData& mydata, CWnd* pParent = NULL)
: CDialog(CMyDlialog::IDD, pParent), mydata(mydata)
{}
...
};
あとアプリケーション共通データは、CDocumentに無理に持たせず
シングルトンクラスにしてどっからでも参照できるようにしたりもする。
これは賛否分かれるかもしれんが、意外とその方がメンテナンス性よかったりする。
アプリケーション共通のデータは CxxxApp に持たせる。 theApp そのものがグローバルなのだから。
534 :
527 :2009/04/13(月) 23:21:37
>>532 >>533 あぁーなるほど。
システム共通なものはCWinAppに持たせるのも手ですね。
考えて見ます。
なぁーーーーーるほど
>>アプリケーション共通のデータは CxxxApp に持たせる。 一理ある。でも他アプリでも使う可能性が0.1%でもあるなら CxxxAppではなくCxxxAppが保持する独立したobjectの方が 良いと思う今日この頃。532に一票。
あとはデータの性質によりけりだったりする。 変更後に必ずUpdateAllViewsしたくなるようなデータだったらCDocumentに持たせるのが妥当だし。
>CxxxAppではなくCxxxAppが保持する独立したobjectの方が >良い それも CxxxApp のデータであることに変わりはあるまいw
いや、MFCプログラムではCxxxAppに保持させておいて MFC以外に移植するときはそのオブジェクトを使いまわせるように、って意味でしょ
いや、MFC以外って意味じゃないか。 まあとにかくCxxxAppのメンバには変わりないが、まるごと切り取れるように、ってこと
プログレスダイアログ風な事の意味がわからないけど ファイルの読み書きをするプログレスバーのようなものをイメージすればいいのかな
ねーよw
おそ
松
質問です。 VisualStudio2005でVC++のプログラムを書いていて、 GUI操作可能なプログレスダイアログを作ろうと思ってます。 そこでVisualStudioヘルプのGetImageサンプルコードに含まれる ProgressDlgを参考にしようと思ってるんですが、この実装方法だと 独自に派生したコモンコントロールのクラス(例えばCButtonから 派生したCMyButtonのような)をプログレスダイアログ上に配置する にはどうすればいいんでしょうか。 ダイアログプロシージャ内でDDXを呼び出すのかと思ったのですが どのメッセージをどう受ければいいのかがわかりません。 あるいはもっと使いやすくて安全なサンプルコードがあれば、 それを紹介していただくだけでも構いません。 よろしくお願いします。
あぁーなるほど。
そんなサンプルあるのか
CButtonが使える所なら派生したCMyButtonも使えるはずだけど 何か使えないような特殊な事情でもあるんだろうか? それとも単純に派生したクラスの使い方がよくわからないということ?
549 :
545 :2009/04/16(木) 23:19:46
>>548 いつも自分がやってる方法は下記のとおり。
(1) リソースエディタでダイアログの外観を適当に編集した後、
右クリック→クラスの追加でそのダイアログに相当するクラス
(CDialogの派生クラス)を作る。
(2) リソースエディタ上に戻ってダイアログ上のボタンを右クリック→
メンバ変数の追加を選び、CButtonクラスの変数として(1)のクラスの
メンバに追加する。
(3) (1)のクラスのヘッダにCMyButtonの宣言を含むヘッダを#include
した上で、(2)の型宣言をCButtonからCMyButtonに書き換える。
こうすることで、DoDataExchange関数の中のDDXがリソース上の
ボタンのIDとCMyButton型のメンバ変数を結び付けてくれるから、
後は何もしないでもCMyButtonの挙動になります。
550 :
545 :2009/04/16(木) 23:22:28
でも、
>>545 で挙げたサンプルコードの場合、CProgressDlgが
そもそもCDialogの派生クラスじゃないんですよ。
HWND型のメンバ変数を持っておいて、クラスが作られるとき
リソースIDを指定してダイアログを作成し、そのメンバ変数に
結びつけるという、いわばダイアログの簡易実装みたいなこと
をやってて、ボタンの挙動なんかはそのクラス内で走らせてる
プロシージャでIDCANCELとかのメッセージを直接受け取って
処理してるんです。
こういう場合、ボタンのリソースIDとCMyButtonクラスとを
どうやって結びつければいいのかわからない、というのが
質問の中身です。
551 :
545 :2009/04/16(木) 23:40:24
まあ操作可能なプログレスダイアログが作れれば それでいいので、もっと使いやすくて安全なコードが あるなら、このサンプルには取り立ててこだわらない んですけど。
CMyButton::SubclassWindow( ::GetDlgItem( hDlg, nIDResource));
おたずねします。 CDialogBarを使っていて、メインウィンドウの左右どちらかにドックできるようにしています。 そために、そのダイアログバーのリソースは縦長でデザインしました。 上下にもドックできるようにしたいのですが、上下にドックしたときには横長になるようにしたいのです。 ドックする位置によってリソースを使い分ける方法ってあるのでしょうか。
動的にレイアウトし直す
タブでダイアログの中味切り替えたりできるんだからできないはずがない。
そういうえばダイアログバーはコントロールの派生しても使えなかったな
CodeGuruのソースを参考にしてCDialogBarでDDXを使えるようにしたっけ あんまり関係ないけど
558 :
545 :2009/04/18(土) 01:59:06
>>552 ありがとうございます。
WM_INITDIALOGのメッセージを処理する箇所で
その関数を呼び出すことで、結びつけることが
できました。
諸先輩方、すみませんがお知恵を拝借させてください。 ・CSplitterWndで静的分割ウィンドウが複数分けられていて、 あるペインではCTreeViewが貼り付けられている。 ・別のペインで何らかのUI操作中に、このCTreeViewの表示を 排他をかけずに更新させたい。 ・CTreeViewのオブジェクトをスレッド化?しなければならないと思うけど どのようにすればよいのでしょうか? AfxBeginThreadとかRUNTIME_CLASSとか使用するものと思っていますが、 実装のしかたがよくわかりません(;_;)
>別のペインで何らかのUI操作中に、このCTreeViewの表示を >排他をかけずに更新させたい。 すまんが解りやすく言ってくれ。「排他をかけずに」とはどういう意味か
>>560 日本語下手ですみません。
今の処理は、CTreeViewのペインと別ペインはシーケンシャルに動作しています。
というか、CTreeViewのペインの処理とその結果表示が終わるまで、画面全体が
グレイ表示になってしまい何も操作できないようになっています。
これを「排他している」と表現しました。
今回任された対応は、CTreeViewの処理&結果表示を実行している最中でも、
他ペインの操作をできるようしたいため、「排他をかけずに」と表現しました。
対応としてCTreeViewのオブジェクトをどうにかしてスレッド化して、
非同期で処理しなければならないのでは?と推測していますが、
なにぶんMFCのスレッド化がよく理解できていません。
(AfxBeginThreadとかRUNTIME_CLASSとか使用する?)
>>562 ご指導感謝いたします。
ご提示のURL拝読いたしました。
AfxBeginThreadで、クラスのスレッドではなく、関数のワーカースレッドを
作成して、また、その関数にCTreeViewのオブジェクトを渡して処理させてみます。
なんだが、光明が差した気分です。
貴重なご意見ありがとうございました。
>>564 アドバイス感謝いたします。
>別スレッドにMFCオブジェクトは渡さない方が良いです。
>ハンドルで渡してスレッドの中で作成したCTreeViewオブジェクトにアタッチするか、
>ハンドルを渡しといてPostMessageなどでメインスレッドに処理させて下さい。
現在の実装は、CTreeViewをメインフレーム内に作成していますので、
後者のCTreeViewのハンドル(m_hWnd?)をワーカースレッドに渡しておいて、
そのワーカースレッド内でPostMessage/PostThreadMessageなどを使用して、
メインフレームへ処理させるようにしてみます。
ありがとうございました。
質問です MFCアプリケーションにて、自作でメッセージを定義し、 メッセージハンドルによる関数呼び出しを考えています。 呼び出される関数のハンドラに向けてメッセージを送信する場合で、 WPARAM, LPARAMにGlobalAlloc関数で生成したHGLOBALをキャストして送る事は 一般的にありえるんですかね? それともタブー?
HGLOBALをWPARAM,あるいはLPARAMにキャストするということは一般的。 ただ、自身にGlobalAllocして送るというのは設計的にどうだろう。 解放のタイミングを考えると、送った先でGlobalAllocすることも視野にいれるべきかと。
568 :
566 :2009/04/23(木) 14:57:53
>>567 返答ありがとうございます。
ご意見をもとに検討してみます。
569 :
デフォルトの名無しさん :2009/04/23(木) 15:51:04
すみません。もしあれば、VC++スタンダード版を買おうと思ってるんですが、 MfcでC#とかにあるDataGridViewコントロールはありますか?FlexGridは使いにくくていやです。
MFCにはない
>>569 そう思っている奴は世界中に居るだろうから、
CodeGuruを探せば似たようなのがいくつか見つかるはず。
572 :
566 :2009/04/23(木) 20:01:08
>>567 結局、vectorコンテナを基とするHGLOBALを管理するクラスを作成し、
CWinApp系クラスのメンバとしました。
間接的にGlobalAlloc/GlobalFreeを行い、
同時にハンドルをvectorに登録したので、
最悪開放し忘れても、対処できるようにしました。
この構成で、しばらく実験してみようと思います。
ご意見、ありがとうございました。
質問です ActiveXのMicrosoft ImageList ControlからHIMAGELISTに登録した複数のアイコンの情報を渡したいと思っています 環境はVS2005です。どなたかご教授よろしくお願いします 尚、以下のことを試してみましたが、できませんでした ImageList_GetImageCountでイメージの数を調べた所0となっていました // HIMAGELISTに変換(m_imagelistはMicrosoft ImageList Controlの変数) HIMAGELIST hImage = (HIMAGELIST)m_imagelist.get_hImageList(); // INDEXを指定してアイコンを取得 m_hIcon = ::ImageList_GetIcon(hImage, 2, ILD_TRANSPARENT);
574 :
573 :2009/04/25(土) 01:47:35
・MFCアプリケーションをダイアログベースで作成 ・「ActiveXコントロールを挿入」→「Microsoft ImageList Control 6.0」でコントロール追加 ・16*16、24bitの適当なアイコンを3つ挿入 ・「変数の追加」で変数名m_imagelistにしてラッパークラス作成
>・16*16、24bitの適当なアイコンを3つ挿入 どこに挿入したのかさっぱり判らない。
>ActiveXのMicrosoft ImageList ControlからHIMAGELISTに登録した複数のアイコンの情報を渡したい 「誰が」「なぜ」「いつ」「どこで」「何を」「どのようにして」
577 :
573 :2009/04/25(土) 16:17:25
>>575 以下のようにして挿入しています
1. デザイナ上で「ActiveXコントロールを挿入」→イメージリストコントロール追加
2. コントロールを選択→プロパティページを開→プロパティページダイアログボックスが表示
3. 「イメージ」タブを選択→「ピクチャの挿入」ボタンクリック→図の選択ファイルダイアログから画像を指定
>>576 説明不足で申し訳ありません。以下になります。
私が
ボタンコントロールに表示しているアイコンを変更するため
ボタンクリック時に
Microsoft ImageList Controlから
「ピクチャの挿入」で挿入した複数のアイコン情報を
(どのようにして)←今模索中です
ボタンコントロールに渡したい
最近MFC使ってないから忘れたけど MFCのイメージリストじゃなくてActiveXのイメージリスト使うと何かいいことあるんだっけ? MFCの画像つきのボタンクラスじゃなくて、そういう方法だと何か意味があるんだっけ?
>ボタンコントロールに表示しているアイコンを変更する その最初のアイコンはどうやって表示したんだ?
>MFCのイメージリストじゃなくてActiveXのイメージリスト使うと何かいいことあるんだっけ? コードをいじらずに画像の追加やマスクの設定ができるからです 利用者の負担を減らしたいと思いまして >MFCの画像つきのボタンクラスじゃなくて、そういう方法だと何か意味があるんだっけ? 自作のボタンコントロールにアイコンを表示する機能をつけようというのが前提なので・・
>>579 最初のアイコンはイメージリストとは別にファイルから読み込んで表示しています
PowerDVD 9 体験版を入れると、VC2005ランタイム入れさせられた・・・
>>573 で挙げたコードはVS2008のMicrosoft ImageList Controlでは動くことを確認しました
環境によって動かないというのも困りますので
利便性は落ちますがMFCのイメージリストを使って実装することにします
ありがとうございました
>>583 「Microsoft ImageList Control」って
MSCOMCTL.OCXに含まれているやつを指しているんだよな。
これはVB6.0用だから、VC6.0ならともかくそれ以降で使用される事は一切考慮されていない。
あくまでVB6.0の互換目的でOSに付属しているだけだから、当てにしないほうが良い。
585 :
おれ :2009/04/26(日) 15:14:33
ちょいと質問 CDialog を継承したクラスを Create() すると、以降の処理が重くなるってあり得る? class CMyDialog : public CDialog { ... } を、 CMyClass::func() { ... CMyDialog *dialog = new CMyDialog(); dialog->Create(); // *1 *1の行をコメントアウトする/しないで、処理が重いんだ。でもCPU使用率とかI/Oに差はない。 なんでだろう。。。
>>585 *1の行をコメントアウトする/しないで、何がどう変わるか理解しているか?
587 :
デフォルトの名無しさん :2009/04/27(月) 00:31:38
質問です。 あるコントロールのウインドウハンドルが分かっていて、 それがエディットコントロールかどうかを知るにはどうしたらいいんでしょうか?
GetClassName()
それはハンドルじゃない気もするがMFCだからいいか
ウインドウハンドルだが? しかもMFCじゃなくてwin32apiだが? int GetClassName( HWND hWnd, // handle of window LPTSTR lpClassName, // address of buffer for class name int nMaxCount // size of buffer, in characters );
>>588 , 590
ありがとうございました。うまくいきました。
592 :
おれ :2009/04/30(木) 20:45:06
>>586 Dialogを表示する/しない
の差だと思っているが間違ってる?
表示してもイベント待ちになるだけで、処理が重くなるってことはないかと思ってたんだが。。。
>>592 間違っている。ダイアログ(ウィンドウ)を作成する/しないの違い。
CMyDialog *dialog = new CMyDialog();
はオブジェクトを生成するだけでウィンドウは作成しない。
CFileDialog dlg(FALSE, _T("jpg"), NULL, OFN_HIDEREADONLY | OFN_OVERWRITEPROMPT, _T("JPEG (*.jpg)|*.jpg|BMP (*.bmp)|*.bmp||"), this); if (dlg.DoModal() == IDOK) { AfxMessageBox(dlg.GetPathName()); } というテストルーチンを実行し、 「BMP (*.bmp)」を選択した状態で拡張子を付けないで「保存」を押すと、 「bmp」の拡張子が付加されたファイルパス名が表示されます。 CFileDialogのコンストラクタをMSDNで読む限りは、 lpszDefExtに入れてある文字列「jpg」が付加されるのではと思ったのですが、 この引数はなんのためにあるのでしょうか? もちろん、この動きのほうが、 「BMP (*.bmp)」を選択してるのに拡張子に「jpg」が付いてしまう というような動きにならずに便利だとは思うのですが、 lpszDefExtがなんのためにあるのかわからず、 上記のような選択式の場合には何を入れておけばよいのか わからなくなったため、質問させていただきました。 よろしくお願いいたします。
すべてのファイル(*.*)|*.*| を追加してみ
VC2003のリソースエディタで Toolbarを編集するとき セパレータを追加するにはどうすればいいでしょうか?
マウスでボタンを右にずらす
>>595 「すべてのファイル (*.*)|*.*|」を選択した状態で
「保存」を押してみたところ、「jpg」が自動で付きました。
ここで使われるものだったのですか。
ということは、「*.*」を入れないときには、
lpszDefExtには何を入れても無意味ということになるのですね。
>「*.*」を入れないときには、 >lpszDefExtには何を入れても無意味 そうではなく、君がフィルタでlpszDefExtとは別に「*.bmp」と「*.jpg」の拡張子を指定しているから。 フィルタを指定する場合は、lpszDefExtは NULL で足りる。
Default Extension(拡張子初期値)
タブコントロールで三つのダイアログをタブ操作可能なようにしたのですが タブAについてるボタンを押された時と同じ処理をタブCでもしたい場合は タブCにつけたボタンで同じ処理をかかなければいけないのでしょうか?
そんなレベルのやつでもMFC使えるんだ
そんなレベルのやつでもMFC使えるんだ (プゲラ
ああ、いやプログラムスレはどこも一緒だなぁと思っただけだ あふぉな質問したらどう返すんだろうなぁと思っただけでw
誰?
イベントを自動で追加したときにできる END_MESSAGE_MAP() の後ろの urn 0; ってどういう意味ですか?
>urn 0; ウチでは見たことがない。 消し忘れた return 0; のゴミじゃないのか?
めちゃくちゃはずかしい><
ダイアログベースのプログラムにてダイアログバーを表示するプログラムを作ってます。 このダイアログバーの右上にある×(閉じる)ボタンを押した時のイベントはどうやって検知すればいいのでしょうか? WM_CLOSEやらWM_DESTROYやらWM_KILLFOCUSやらありえそうな大体のイベントに対応した プログラムを書いてTRACE文で出力させるようにして試しましたが、 検知出来ませんでした。(最初の数回のみシステムの挙動によってイベント発生しているようですが、 その後自分で閉じたり出したり何回しても検知してません。) ダイアログバーを×ボタンで消して再表示すると前回移動させた位置に表示してくれるってことは 非表示にしているだけなのでしょうか? なんにせよ検知方法が分かりません。 誰か教えてくださいお願いします。
まずソース読んで見ようとか思いつかないんだろうか
Spy++ してみようとも思わんのだろう
614 :
611 :2009/05/03(日) 23:59:08
>>612 すいません。初心者なものでよく分からないのですがどこのソースを見ればいいんでしょうか?
>>613 Spy++使うと、自分のPCが固まってしまってctrl+alt+delも効かなくなり、
パソコン強制リセットボタンするしかなくなることが多々あるので怖くて使ってません。
>どこのソースを見れば MFCのソース。HDDにインストールされているからそれを読め。
616 :
デフォルトの名無しさん :2009/05/04(月) 16:01:28
ドキュメントビューアーキテクチャで、リストビューを利用したプログラムなんですが、 デスクトップPC3台では問題なく動くのに、 ノートpc(EeePC701)だと、起動時ウインドウが表示される前にエラー終了します。 エラー報告のウインドウをみると、エラー著名のmodnameにcomctrl32.dllと表示されてます。 debugビルドのプログラムだとエラーになりません。 vs2005で、OSはすべてXPproSP3です。 ノートはメモリ2GでHDDも要領あまってます。 どんなところに問題ありそうですか?
dllのバージョンの違いとか つーかcomctrl32.dllを使わないMFCアプリではどうなの?
618 :
616 :2009/05/04(月) 16:06:55
>>617 レスありがとうございます。
昨日その辺でいろいろ調べたんですが、
debugビルドのexeファイルだと動きますし。
XPsp3が入っているのでそれはないかと。
で、ListViewを使わないRelease版のやつは動くのか?
>どんなところに問題ありそうですか ノートPCとデスクトップPCでの相違点(ハードウェア・ソフトウェア環境双方)をピックアップしてみる。 どちらか一方にインストールされているソフトがあるとかね。 デバッグ版で動くなら、最適化なしでビルドしてみるという手もある。
621 :
616 :2009/05/04(月) 16:21:33
リストビューを使ってるプログラムを3つ作っているのですが、 他の2つは動きます。 動かないプログラムも、改良途中の今はソースがないバージョンのやつは起動します。
バグっててたまたま問題起きないで動く場合もあるだけだろ
623 :
616 :2009/05/04(月) 16:49:19
>>622 そうですよね。もっと大きくて複雑な市販のソフトは通常に動作するわけですから。
やっぱりバグってたまたま動くのって、ポインタの初期化してないとか、その他、どんなところ見るのが普通でしょうか。
ウィンドウも出ないんだろ? どこまで実行できたか確認しようぜ。 あとイベントビューアは当然チェックしてるんだろうな
あー同じやつでも動くのと動かないのとあるのか。
なら
>>620 の言うとおり、最適化はずしてみ。
626 :
616 :2009/05/04(月) 17:30:20
レスありがとうございます。 どこまで動くかコード削りながら探してます。 イベントビューアのエラー内容は、エラー報告に書いてあるのと同様でした。comctl32.dllのバージョンとエラー発生アドレス が書いてあって、ググっても調査すすまなかったです。 ビルドの最適化設定は、動くプログラムと同じ設定なんですよ。バグをやっぱり見つけたい感じです。
MFCライブラリをスタティックリンクすれば解決しそうな気がする
>>623 >やっぱりバグってたまたま動くのって、ポインタの初期化してないとか、その他、どんなところ見るのが普通でしょうか。
ポインタだけでなく変数の初期化もチェック
リストビューなら構造体も色々使ってるだろうし。
>>626 そうじゃねーだろ、切り分けのためにやってみろって言ってるんだよ。
何でも試してみて違いから何かを得られないなら何日デバッグしても見つからんだろうよ
630 :
616 :2009/05/04(月) 17:53:00
切り分けですよね。原因特定うまくいきました。 リストビューのソートで、三角形のソートマークを上下に切り替えているんですけど、 ソートマークの部分をすべて削ったら、動きました。 コードの内容をすぐに思いだせないので、とりあえず、内容は後で検証してみます。 前バージョンのやつは、ソートマーク付いているのに、なんでエラーにならないのか、ちょっと不思議なんですが。 ソートマークの部分なんて最近は点でいじっていなかったのに・・・
631 :
616 :2009/05/04(月) 17:53:30
//////////////////ソートマーク m_pHdrCtrl = ListCtrl.GetHeaderCtrl(); m_pHdrCtrl->SetImageList(&m_imageH); for(int i=0;i<5;i++) { m_pHdrCtrl->GetItem(i, &curItem); curItem.mask= HDI_IMAGE | HDI_FORMAT; curItem.fmt= HDF_STRING; m_pHdrCtrl->SetItem(i, &curItem); } for(int i=5;i<8;i++) { m_pHdrCtrl->GetItem(i, &curItem); curItem.mask= HDI_IMAGE | HDI_FORMAT; curItem.fmt= LVCFMT_RIGHT | HDF_STRING; m_pHdrCtrl->SetItem(i, &curItem); }
632 :
デフォルトの名無しさん :2009/05/04(月) 17:53:38
if((SORT_ITEM_DATA.iSubItem)<5) { m_pHdrCtrl->GetItem(SORT_ITEM_DATA.iSubItem, &curItem); curItem.mask= HDI_IMAGE | HDI_FORMAT; curItem.iImage= SORT_ITEM_DATA.blSortFlag; curItem.fmt= HDF_BITMAP_ON_RIGHT | HDF_IMAGE | HDF_STRING; m_pHdrCtrl->SetItem(SORT_ITEM_DATA.iSubItem, &curItem); } else { m_pHdrCtrl->GetItem(SORT_ITEM_DATA.iSubItem, &curItem); curItem.mask= HDI_IMAGE | HDI_FORMAT; curItem.iImage= SORT_ITEM_DATA.blSortFlag; curItem.fmt= LVCFMT_RIGHT | HDF_IMAGE | HDF_STRING; m_pHdrCtrl->SetItem(SORT_ITEM_DATA.iSubItem, &curItem); }
>>631-632 細かく見てないので、ぱっと見で。
curItem はどこで宣言して、初期化はどうなってる?
あと、GetItem()する前にmaskにフラグ設定していないのは拙いんでは?
634 :
616 :2009/05/04(月) 18:06:14
m_pHdrCtrl = ListCtrl.GetHeaderCtrl(); int i=0; m_pHdrCtrl->GetItem(i, &curItem); これだけでノートPCだけエラーになります。 なんなんだ。
635 :
616 :2009/05/04(月) 18:11:58
public: CImageList m_imageH;//ヘッダー用 HDITEM curItem; curItemは、リストビューのメンバ変数として、ヘッダーファイルで、上のように書いてあるだけで初期化してないです。 勉強してきます。
636 :
616 :2009/05/04(月) 18:28:03
中途半端な理解ですが、とりあえず、 curItem.pszText が無効値になっていたので、 = NULL;をいれたら、ノートPCでも動くようになりました。 ありがとうございました。 for(int i=0;i<5;i++) { curItem.pszText = NULL; m_pHdrCtrl->GetItem(i, &curItem); curItem.mask= HDI_IMAGE | HDI_FORMAT; curItem.fmt= HDF_STRING; m_pHdrCtrl->SetItem(i, &curItem); } for(int i=5;i<8;i++) { curItem.pszText = NULL; m_pHdrCtrl->GetItem(i, &curItem); curItem.mask= HDI_IMAGE | HDI_FORMAT; curItem.fmt= LVCFMT_RIGHT | HDF_STRING; m_pHdrCtrl->SetItem(i, &curItem); }
637 :
616 :2009/05/04(月) 22:29:51
curItemをゼロメモリで初期化して、 Getitemなんかせずに、変えたいところだけをmaskで選択して、setitemすればよかったんですね。 かなりいい加減なことしていたな・・・
基本ができていない証拠
シングルドキュメントで((CMainFrame*)AfxGetMainWnd())でメインフレームを取得して子インスンタンスにアクセスしていきたいんですが IsWindowでアクセス違反アサートで止まってしまいます。 マルチドキュメントのときはうまくいっていたんですが、シングルのときは違いがあるんでしょうか?他に違いがわからないんです
シングルドキュメントが何を意味してるか知らないけど、 SDIのことだったら当然メインフレームは存在する。 子インスンタンス〜IsWindowでアクセス違反アサートの部分は 何について語ってるのか理解不能。
>子インスンタンスにアクセス って何?
具体的に該当行書いてみりゃすぐわかるんだが
位置関係はこれです。 class CMainFrame : public CFrameWndEx { CFileView m_wndFileView; } class CFileView : public CDockablePane { CThumbnailStatic m_ThumbnailStatic; } class CThumbnailStatic : public CStatic { void OnCreate{ASSERT(((CMainFrame*)AfxGetMainWnd())->m_wndFileView != NULL}; } ((CMainFrame*)AfxGetMainWnd())だけでもエラーになるんです。
CThumbnailStatic のクラス定義で OnCreate() しているのか? ならば、(CMainFrame*)AfxGetMainWnd() するとエラーになるのは当然。 なぜか? AfxGetMainWnd() の実体がまだ存在していないからだ。
宣言の中というかON_WM_CREATE()に対応したところの.cppに書いてます OnCreateつながりで一通りの子が全てCreateされてからトップのMainFrameの実体ができるってことですか? ということは、子のOnSizeとかOnPaintはMainFrameが出来る前に一度呼び出されているってことなんでしょうか? フラグを立てて初回は実行しないようにしたんですが、同じエラーでます。MainFrameが出来上がるまでに 何回スルーしなきゃいけないんでしょうか
>ON_WM_CREATE()に対応したところの.cppに書いてます なぜちゃんとしたコードを示さない? 二度手間だろーが。 >MainFrameが出来る前に 親がいないのに子が生まれるわけないだろ。 ちゃんとしたコードを示せ
コード適当だなあ・・・ このm_ThumbnailStaticはどこでCreateしているの?
ThumbnailStaticはCFileViewのOnCreateで作ってます。 どこがいけないのか見当もつかないので 最小コードで再現しました。 MFCのSDIウィザードのひな形に3行追加しました。 //MainFrm.h class CMainFrame : public CFrameWndEx { CString path; } //MainFrm.cpp CMainFrame::CMainFrame() { path = _T("aaaaaa"); } void CClassView::AdjustLayout() { CString aaa = ((CMainFrame*)AfxGetMainWnd())->path; } これはIsWindowで引っかかるんじゃないんですがじゃないんですがエラーでます CStringData* GetData() const throw() { return( reinterpret_cast< CStringData* >( m_pszData )-1 ); } ここに飛んで止まります 何がいけないんですか?
それで他人に何が伝わる?
CString aaa = ((CMainFrame*)AfxGetMainWnd())->path; の次はmfc90ud.dllの //cstringt.h // Copy constructor CStringT( const CStringT& strSrc ) : CThisSimpleString( strSrc ) { } //atlsimpstr.h CSimpleStringT( _In_ const CSimpleStringT<BaseType, !t_bMFCDLL>& strSrc ) { CStringData* pSrcData = strSrc.GetData(); CStringData* pNewData = CloneData( pSrcData ); Attach( pNewData ); } //atlsimpstr.h CStringData* GetData() const throw() { return( reinterpret_cast< CStringData* >( m_pszData )-1 ); } ここで最後止まるんです。これはどういうエラーですか? mfc90ud.dllでハンドルされていない例外 0xC0000005場所0x000003f4読み込み中アクセス違反 とでます。
そもそも 他人には CClassView が何の派生であるのかも CMainFrame と どういう関係にあるのかもわからんのだよ。
VC++9からひな形に追加されたCDockablePane派生のCClassViewです。
Paneの派生にViewとかつけるな、アホが。
すいませんそれはMSに言ってください
MFCのソース見るとこういう風に AfxGetMainWndでNULL帰ってくる可能性を考慮して作ってあるから 真似しとけば問題ない CWnd* pMainWnd = AfxGetMainWnd(); if (pMainWnd != NULL &&
結論から言えば、AfxGetMainWnd() が NULL を返しているのがエラーの原因。 なぜなら、CWinApp::m_pMainWnd に値が代入される前にも CClassView::AdjustLayout() が呼ばれるから。 if ( AfxGetMainWnd() != NULL) CString aaa = ((CMainFrame*)AfxGetMainWnd())->path; とすればエラーは生じないはずだ。
うおーーーーーできました!ありがとう!!! いつもフラグで初回実行回避とかやってました 勉強になりましたどうもです!
MFCの仕組みが詳しくわかる本ってありますか? 最初、林本で動くけど意味はわからない状態で、次に標準MFC本で大まかな流れはわかるが細かい挙動がわかるようにはなりませんでした もっと徹底的な本はありますか?
MFCつかわないでWinAPIのみでプログラム組んでみれば?
すでに君は徹底的なものを手に入れている。HDDにインストールされているMFCのソースだ。 細かい挙動は、ソースを遡ればわかるようになる。これは冗談ではない。
林本読んでるような相手にソース嫁って厳しすぎないか?
665 :
デフォルトの名無しさん :2009/05/06(水) 01:26:38
CRichEditCtrl::GetLineのMFCコードってどこにインストールされているんですかあ
Program Files\Microsoft Visual Studio 9.0\VC\atlmfc\include\afxcmn.inl(650): Program Files\Microsoft Visual Studio 9.0\VC\atlmfc\src\mfc\winctrl4.cpp(77): Program Files\Microsoft Visual Studio 9.0\VC\atlmfc\src\mfc\winctrl4.cpp(132): VS2008での話だがな
667 :
デフォルトの名無しさん :2009/05/06(水) 16:11:24
MFCのウインドウプロシージャってどういう過程でAfxWndProcBase()に登録されるの? AfxEndDeferRegisterClass()の中からRegisterClass()で登録している関数は wndcls.lpfnWndProc = DefWindowProc; こんな風になっているんですが? #こんな関数を登録しているのも謎なんが・・・ #DefWindowProcを登録したらWM_*をうけれなくなるんじゃないの?
ウィンドウハンドルと CWnd(あるいはその派生)オブジェクトとの関連付けがなされる際に サブクラス化され、メッセージはサブクラスプロシージャによって処理されている。 だから、クラス登録時のプロシージャは DefWindowProcでもいっこうにかまわない。 MFCだけでなく、独自のクラスライブラリを作る際にもよくあるパターン。
669 :
デフォルトの名無しさん :2009/05/06(水) 16:41:10
ってことはRegisterClassしてからCreateWindowするまでにサブクラス化している? あれ?CreateWindowして初めてサブクラス化する時に使うHWNDが取得出来るんじゃないの? それにCreateWindowした時に発生するWM_CREATEはなんでサブクラス化したプロシージャにくるんだろ?
ソース読め
あんまり関係はないが、CreateWindow() した時に発生する最初のメッセージは WM_CREATE ではない
>>669 SetWindowsHookExのWH_CBTで受け取るコールバックに、
HCBT_CREATEWNDというのがある。
拡縮が必要で一度CDCに描画した元画像のBMPをサムネイル画像としてクラスに保持するためにCBitmapに入れ直そうと思ったのですが これどうやればいいんでしょうか
>一度CDCに描画した元画像 この元画像は、もともとCBitmapで読み込んでいるんじゃないのか?
メモリDCにビットマップを選択した後にそこへ描画すれば、 そのビットマップの内容は更新される。
そうだったんですか! CBitmapを保持するだけで次にそのままDCに送れば拡縮された状態ってことですね ありがとうございました
677 :
667,669 :2009/05/07(木) 00:52:26
あぁ!フックってこういうものなのか。単語は聞いた事あったけどどういうものか知らなかった。 なるほどね。イベントに引っ掛けるから"フック"ね。 確かに、_AfxCbtFilterHook中にウインドウプロシージャをセットするコードがあった。 勉強になった。ありがとう
StretchBltで縮小した後もCBitmapのインスタンスにロードされている画像のサイズが変わりません SRCCOPYの指定がおかしいんでしょうか?
StretchBltは「元の画像」を描画先に拡縮して表示する関数であって「元の画像」そのものを拡縮する関数ではない
CDC.StretchBltから CImage.StretchBltに変えてCImageに書き込まれるように書き換えたんですがエラーがでます。 この考え方はおかしいですか?コンパイルは通るんです あとSelectOblectの戻り値が現在のオブジェクトとなってるので違う方法も試したんですが詰まりました これもコンパイル通るんですがAttachで止まります。元画像を縮小したサムネイルだけを画像系のインスタンスで保持しておきたいんです CImage imgSave; void CStaticBox::OnPaint() { if(imgSave.IsNull){ CPaintDC dc(this); CDC m_memDCMain; CBitmap m_bmpMain; m_memDCMain.CreateCompatibleDC(&dc); m_bmpMain.CreateCompatibleBitmap(&dc, rect.Width(), rect.Height()); m_memDCMain.SelectObject(&m_bmpMain); m_memDCMain.SetStretchBltMode(HALFTONE); CDC myDC; myDC.CreateCompatibleDC( &m_memDCMain ); CImage img; img.Load(activeFullPath + fileName); myDC.SelectObject( img ); m_memDCMain.StretchBlt( left+10, top+10, width-20, height-20, &myDC, 0, 0, img.GetWidth(), img.GetHeight(), SRCCOPY ); HBITMAP* imgBMP = ( HBITMAP* )m_memDCMain.SelectObject( CImage() ); imgSave.Attach( *imgBMP ); } }
すいませんめちゃくちゃ頭悪いことしてました忘れてください bmpMainを外に書くだけでした
>bmpMainを外に書くだけ オブジェクト指向プログラミングするなら、グローバル変数はあまり使わないほうがいい。
683 :
611 :2009/05/07(木) 22:28:50
ようやく解決しました。MFC閉じるボタンで検知とかのキーワードでググると
このスレが真っ先に出てくるので後続の人の為に残しときます。
×ボタンを押すとダイアログバーでWM_WINDOWPOSCHANGINGイベントが発生し、
void ダイアログバーのクラス::OnWindowPosChanging(WINDOWPOS* lpwndpos)
の追加した関数に渡される変数を判定し
if(lpwndpos->flags & SWP_HIDEWINDOW)
{
この部分に閉じるボタン押下時処理を書きます。
}
これはShowControlBarをフレームウィンドウで使用して閉じた時にも発生しますが、
アプリケーション終了時は発生しません。
>>612 >>613 親切丁寧なアドバイスありがとうございました!!
684 :
デフォルトの名無しさん :2009/05/07(木) 23:52:42
いやさ〜。前の人に文句言うわけじゃないけど、MFCなんてJavaかC#やったことあるひとなら、 C++ならこう書くのか〜って辞書引きながらやれば、一挙に2つ覚えちゃうよね。ついでにC++も余分なページよんだりしながらさ。
JavaやC#が先な辺りに時代を感じる。 俺がMFC始めた頃なんて、Javaは生首が回り始めた頃だったからな。
CImage folderImg; folderImg.LoadFromResource(AfxGetInstanceHandle(), _T("folder.png")); これ実行したらExpression:hBitmap != 0; とかいうエラーが出ました リソースファイルに.pngファイル入れるだけじゃだめなんですか?
>>686 そもそも本当に"folder.png"というリソースIDなのか?
CImage::LoadFromResourceは::LoadImageを呼び出すので、
結局PNG画像の読み出しには対応できないのだけどね。
IStream経由で読み込ませるようにお膳立てしてやる必要がある。
あと、リソースハンドルの取得用にAfxGetResourceHandleというのがある。
pngリソース 読み込み あたりでググれば、いくらでもでてくるだろーに。
できません CImage img; img.LoadFromResource(GetModuleHandle(NULL), IDB_PNG1); GetModuleHandle(NULL)でも AfxGetApp()->m_hInstanceでも AfxGetInstanceHandle()でも AfxGetResourceHandle()でも この行でエラーになります どいういうことですか? IDB_PNG1はリソースビューでPNGフォルダの中に入ってるんです ソリューションエクスプローラの中のリソースファイルフォルダの中にもfolder.pngが入ってます
>>689 VSのバージョンとかOSとかは何なん?
PNGイメージは LoadFromResource() できない。VS、OSの種類とは無関係。
ぐぐればでてきたぞ 1. FindResource関数でリソースハンドルを取得 2. SizeofResource関数でサイズを取得 3. LoadResource関数でリソースを読み出しLockResource関数でをロック 4. GlobalAlloc関数でメモリを確保 5. GlobalLock関数でメモリをロック 6. CopyMemory関数でリソースを確保したメモリにコピー 7. CreateStreamOnHGlobal関数でストリームを作成 8. Bitmap(またはImageクラス)のFromStreamメソッドでBitmapオブジェクトを作成
695 :
デフォルトの名無しさん :2009/05/11(月) 00:24:26
チンポの先の我慢汁をとるプログラムを作成してください><;
696 :
デフォルトの名無しさん :2009/05/11(月) 10:05:03
;' ':;,, ,;'':;, ;' ':;,.,.,.,.,.,,,;' ';, ,:' : :、 ,:' / ,,. 、.\ ノ( ::::::::', :' ∩ ∩ ⌒ :::::i. i ''' (_人_) '''' * :::::i : {+ + +} :::::i `:,、  ̄ ̄ ::::::::: / ,:' : ::::::::::::`:、 ,:' : : ::::::::::`:、
MFCをやる人はMVC構造とかを意識しない人が多いですね。 Document/Viewでもイヤな感じなのに、 ダイアログクラス上で全部やってるソースとか見ると発狂しそうになる。
MVCはよくてDocument/Viewがイヤ? それはあれか、FireWireはよくてi-Linkはイヤとかいう類か? ともかく最後の一行だけは共感できる。 MFCあんま関係ないけど。
>>699 Control と View を分離しる!という御意見なんじゃね?
知らんけど。
[MVCの場合] M-C-V1 |-V2 |-V3 [Document/Viewの場合] M--VC1 |-VC2 |-VC3 Controllerの処理は、Viewがちゃんと抽象化されていれば一つにまとめることができるはずなのに、 Document/Viewの場合は同じようなControllerの処理をViewごとに重複して書くので無駄。
> 同じようなControllerの処理をViewごとに重複して書く 抽象化したViewを作って派生させれば良いんじゃないの
ダイアログベースのプログラムを作っています。 環境はVC++.NETです。 ダイアログ上に配置したピクチャーボックスの中でLBUTTONDOWNを検知した時に、 setCaptureして、カーソルをドラッグすることで別ウィンドウの内容を変化させ、 LBUTTONUPを検知したときにReleaseCaptureするプログラムを作ろうとしているのですが、 イベントハンドラを追加しようとしてもピクチャーボックスにはマウスクリックイベントしか追加できません。 ピクチャーボックス内のマウスダウンイベントを検知するのは不可能なのでしょうか? 可能であれば出来るだけそれを使いたいと思ってますが不可能であれば、ダイアログにたいするマウスダウンイベントを 検知して、マウス座標をGetMessagePosやScreenToClientなどを使って、該当ピクチャーボックス範囲内かどうかを 判定して代用するしかないのでしょうか? よろしくお願いします。
SS_NOTIFY スタイルつけているか?
[クラスで使用可能なメッセージ用フィルタ] ボックスでは、 特定の種類のクラスまたはウィンドウだけに適用されるメッセージを指定するためのフィルタを変更できます。 でできなかったっけ?
706 :
703 :2009/05/15(金) 20:48:30
>>704 リソースエディタから該当ダイアログ(厳密にはダイアログバー)上のピクチャーボックスのプロパティを開き、
表示カテゴリの「Notify」をTrueに設定しましたが状況は変わりません。
これとは別物でしょうか?
該当ダイアログを生成しているCreate文にSS_NOTIFY スタイルを付けて見ましたが、
やはりイベントハンドラの追加で指定できるメッセージは
STN_CLICKED
STN_DBLCLK
STN_ENABLE
STN_DISABLE
NM_THEMECHANGED
のみです。
>ピクチャーボックス内のマウスダウンイベントを検知するのは不可能なのでしょうか? CStaticの派生にして、そこにマウスイベントのメッセージハンドラを追加すれば?
708 :
703 :2009/05/15(金) 21:11:35
>>707 いまいちCstaticの派生にするという意味が分からないのですが、
ダイアログ上のピクチャーボックスのみの為に新たにクラス作成するという事でしょうか?
その場合、新たに作ったクラスはそのままでは機能しないかと思いますが、
(サブダイアログクラスであれば、Createメソッドで実体を作りますが、コントロールのクラスは良く分かりません)
上記認識が正しいのであれば、簡単な説明のあるURLか検索キーワードを教えていただけないでしょうか?
1. CStaticの派生クラスを作成する ex.「CMyStatic」 2. リソースエディタで、当該ピクチャーボックスを「CMyStatic」のメンバ変数として追加する。
日本語としてわかりにくいかもしれないので修正 >「CMyStatic」のメンバ変数として追加する。 「CMyStatic」型のメンバ変数として追加する。
>>709-710 と俺も思ったのだが、VS2008だと派生クラスが選択肢に出なかった。
とりあえずCStaticで追加しておいて、
クラス名だけ派生クラスのものに直接書き換えておけばOKだと思う。
>>711 選択肢はでないけど、「変数の種類(V)」のコンボボックスに直接書き込めるだろ。
このコントロールはドロップダウンコンボであって、ドロップダウンリストじゃないんだから。
713 :
703 :2009/05/15(金) 21:58:11
いまいちよく分からないのですが、 ピクチャーボックスをDDX変数にするということでしょうか?
そうだよ。 念のため言っておくが、そのピクチャーボックスのIDは、もちろん IDC_STATIC 以外だろうな。
715 :
703 :2009/05/15(金) 22:08:44
>>714 IDは一応全部オリジナルに設定しています。
まだプログラム歴浅くて、DDX変数などを使い慣れてません。
(リソースエディタで右クリックから変数追加してもコントロール変数とか
チェック出来なくなってる・・・)
とりあえず色々あがいて見ます。
ありがとうございました。
716 :
703 :2009/05/15(金) 23:40:59
結局ピクチャーボックスの所属するダイアログのマウスダウンイベント時に CRect myrec; this->GetDlgItem(IDC_PICT_1)->GetWindowRect(myrec); ScreenToClient(myrec); 後はpoint.x point.yがmyrec.left right top bottomの中に所属するか判断して コード記述することにしました。
>後はpoint.x point.yがmyrec.left right top bottomの中に所属するか判断 myrec.PtInRect( point);
718 :
703 :2009/05/15(金) 23:49:37
if( myrec.PtInRect(point) ) これでいけた。
719 :
703 :2009/05/20(水) 20:57:53
703です。またですすいません。 もう一歩ごとに躓いてます。 ダイアログバー(ツールバー)でのドラッグなどのアクションを検知して、 ビュークラスでの表示内容をリアルタイムに変化させたいのですが、 ダイアログバーからビュークラスの関数を起動する方法が分かりません。 ・最初に考えた案 ダイアログバークラスにメンバとしてビュークラスオブジェクトのポインタを持たせる。 ↓ コンパイル時にヘッダファイルなどが循環参照してしまう。色々調べて見ても、 仮に無理やりやれたとしても、あまりプログラムとして美しくない作りなんではないか? ・次に考えた案 どうしても無理だったらsendmessageみたいなものを調べて使って、メッセージをやりとりする プログラムにすべきなのか? ↓ なんとなく、有り得ないんじゃないかと却下。 ・現在の最終有力候補 よく見たらアプリケーションクラスの変数参照できてる(theApp)。 アプリケーションクラスで関数作ってダイアログバーからアクションしてビューに反映したい場合は、 アプリケーションクラスを中継すればいいのではないか? ↓ これが、MFCのプログラミングにおいて正しい方法、定石的な方法なのかアドバイスお願いします。
>コンパイル時にヘッダファイルなどが循環参照してしまう 記述法がまずいんだと思う。 >メッセージをやりとりする ダイアログバーとビューで直接メッセージをやりとりするなら、 どちらかのポインタがどちらかに必要になる。つまり、「最初に考えた案」に戻ることになる。 >現在の最終有力候補 最も簡単ではあるが、バーの挙動をCWinAppクラスが知っている必要はない。 中継方法でやるとすれば、バーとビュー双方のポインタを取得できるフレームウィンドウクラスあたりか。 僕なら最初の案でやるか、フレームウィンドウを中継するか、かな。
ツールバーと同じ動きが定石だろ
722 :
703 :2009/05/20(水) 23:28:04
>>720 すばやい回答ありがとうございます。
たしかにAppクラスが行うべき処理というよりはフレームウィンドウクラスがやるべきかと思います。
また、Viewクラスのポインタを持つのはオブジェクト志向なプログラムという点では好ましくないかとも思いました。
で、問題はダイアログバーからフレームウィンドウクラスのメンバ関数を実行する手段で、
フレームウィンドウクラスのヘッダファイルをダイアログバーのクラスでインクルードすると色々エラーがでてコンパイルできず、
かといってフレームウィンドウクラスをインクルードしなければメンバ関数なんて実行出来ない・・・。
関数ポインタを使うのか・・とか言う以前に、Viewクラスのポインタ持つのとやってることが同じ・・・。
やはり諦めてアプリケーションクラスにViewコントロール用の新規オブジェクトを持たせるほうがよいか・・・。
いやそれならフレームウィンドウクラスに持たせるべきか・・。
足掻いて試行錯誤してみます。
723 :
703 :2009/05/20(水) 23:33:25
>>721 ググって見てもツールバーは大抵イベントハンドラを追加して、
フレームウィンドウでクリックイベントを受けているのですが、
自分の場合マウスムーブイベントを取りたいのにそれの追加方法が調べてもイマイチ分かりませんでした。
ためしにフレームウィンドウにマウスムーブメッセージ取得する内容を入れてみてもどうも検知してる様子が無い。
マウスムーブはビュークラスかサブダイアログクラスじゃないと取れないんじゃないかと自分は勝手に結論付けています。
// ダイアログバークラスにて CFrameWnd* pFrame = (CFrameWnd*)AfxGetMainWnd(); // フレームウィンドウオブジェクトのポインタを取得 CMyView* pView = (CMyView*)pFrame->GetActiveView(); // ビューオブジェクトのポインタを取得 >フレームウィンドウクラスのヘッダファイルをダイアログバーのクラスでインクルードすると色々エラーがでてコンパイルできず、 ヘッダにインクルードする必要は生じない。やはり記述法がおかしい。
725 :
703 :2009/05/20(水) 23:53:01
>>724 記載の方法であっさりいけました。
ただ自分がダイアログバーのクラスのヘッダにインクルードするのにこだわってたのは、
一度取得したポインタを一度読んだ後はずっと保持したかったからですが、
マウスムーブイベントだと瞬間的に無数にポインタの設定と破棄が何千何万と繰り返される事になると思いますが、
心配するほど影響は無いのでしょうか?
>一度取得したポインタを一度読んだ後はずっと保持したかったから 保持するのは「ポインタ」なんだから、ヘッダにインクルードする必要はないんだ。 クラスの前方宣言、あるいは先送り宣言と呼ばれるものについて一度調べてみ。
727 :
703 :2009/05/21(木) 00:22:33
グローバル変数としてやってみます。 ありがとうございました。
728 :
703 :2009/05/21(木) 00:23:33
>>726 ありがとうございます。
調べて見ます。
ヘッダのクラス定義前に class hoge;としておいて クラス内にhoge *m_pHogeというメンバ変数を記述するのはエラーにならない cppのほうでclass hogeのヘッダをインクルードして、m_pHogeを使えばいい
ポインタの保持はプログラム設計的には大罪だから なるべく使わない方法を心がけるほうがいいぞ
もっとも、MFCは山ほど保持しているけどな(笑)
MFCはしょうがねぇんだよな この継承して作っていく方式がどうしてもポインタ保持をしなければいけない仕組みにしてしまう そうでなかったらなかなかやらないんだけどね
>>730 >ポインタの保持はプログラム設計的には大罪だから
お前は何を言っているんだ
>>733 インスタンス消えても気づかないで爆死確定だぜ
保持はしないで引数で渡すのが正しいプログラム
>インスタンス消えても気づかないで爆死確定 それはプログラマの個人的な大罪
>>735 でもこれスマートポインタとか使って逃げると今度は構造的な不具合が酷い
死なないだけで値やステータスが知らずに変わってることで起きる不具合に
悩まされる
俺的結論としては保持しないのが一番
ただし、MFCは構造的に仕方がないとしている もう保持しまくり
>>736 >でもこれスマートポインタとか使って逃げると
逃げるなよ。立ち向かえよ。
>俺的結論としては
ヘタレめ。
>>736 それはおまえの頭の欠陥だよ。
どんな仕様で実装しようが、問題なく組むのがプログラマの仕事だ。
結論として、おまえにはポインタさえ使いこなせないということだ w
スマートポインタを使えば「問題なく組む」ことになるのか?
手を抜きたいだけでしょ
>>740 スマポ使っても落ちないだけ
知らない間に値が変わってるバグは放置状態になる
DeepCopyが基本 って結構前に誰か書いていた記憶がある。 .NET出た頃か、もしかするとそれより前かもしれない。
…これ以上突っ込んだらスレ違いだから黙っとく。
>>13 ・・・ やべぇ この人 コナンみたいな推理力だ・・・ 世の中には、こんな鉄人がおるのか!!!
>>740 スマートポインタ使ったところで結局参照数の管理しなきゃいけないからな
通常のポインタ使いこなせずリーク起こすような奴は
スマートポインタでも問題起こすだろ
>>743 そんな基本はねえよ
どう考えてもケースバイケースだ
>>746 「参照数の管理しなきゃいけない」って意味がよく分からないのだけど。
shared_ptr/weak_ptr/intrusive_ptrでググってくれ
>>747 そいつは真性のヴァカだ。スマポ自体理解してないと思われ。ほっとけ。
そもそも、気にくわないなら、スマポを自分で実装するなんて発想もないに違いない。
750 :
747 :2009/06/02(火) 16:04:33
いや、boost::shared_ptrとかが内部で参照数をカウントしてるのは知ってるよ。
いまの話って、そういうスマートポインタを使用する側の話じゃないの?
>>749 が言ってるのはよく意味が分からん。普通は自分で実装しないだろ。
>>747 に
>>746 はほっとけって言ってるんでしょ。
自分で実装した場合どんなふうにするか、を考えるのも内部を理解する一つの手だと思うけどね。
あ、理解した。 まあ、俺もshared_ptrの中身を覗いてみたことはあるよ。自分で完璧に作るのは大変そうだなとは思ったが。
shared_ptrとweak_ptrを正しく使い分けることを 参照数を管理する、・・・とは言わんか
スレタイ読めないやつ
755 :
744 :2009/06/03(水) 03:23:03
MFCのCTreeCtrlについて質問があります。 CTreeCtrlを継承して自作のチェックボックス付きツリーを作成しようとしています。 特定アイテムのみにチェックボックスを付けたいのですが、スタイルを指定するとすべてのアイテムに対して チェックボックスが付きます。 1階層目はチェックボックスなし、2階層目は有りなど、個別にチェックボックスを付けることは可能でしょうか?
自分で描画すれば可能
759 :
757 :2009/06/09(火) 21:47:30
>>758 返信ありがとうございます。
自分でチェックボックスのイメージを作成して、アイテムに付けるということですよね。
すべての階層のアイテムにチェックボックスとは別にイメージをつける必要があります。
2個のイメージを並べて表示させることは可能ですか?
イメージとしては、エクスプローラー風のディレクトリツリー(絵付き)で特定アイテムのみにチェックボックスを付ける
ことをやりたいと思っています。
自分で描画すれば可能
MFCを捨ててWPFでやる
762 :
デフォルトの名無しさん :2009/06/11(木) 12:06:54
ちょっとしたことなのですが、 ダイアログアプリで、タブコントロールを使ってます。 なので、タブ指定時に子ダイアログの作成、操作を行います。 子ダイアログの操作(ボタン選択)をした時に、 親のダイアログのオブジェクト操作 (例えば、親ダイアログのボタンのグレーアウトなど)を行うときは、 1,子から親のウィンド(GetParent())を取得して、直接操作を行う。 2,子から親にSendMessege()でメッセージを送り、親側で操作を行う。 1,2のどちらが定石なのでしょうか? それともどちらでも問題ないとか?
どっちでもいいのでは? 手間を省こうとすれば、子ダイアログオブジェクトの作成時に親ダイアログのthisポインタを渡すので、 GetParent() せずに、それをそのまま使うかな。
>>763 以前、先輩から、子ダイアログから親を操作するのは、あまり良くないという
話を聞いたので、一般的な定石はどちらなのかな??と思い質問しました。
例えばメニューを選択したりツールバーのボタンを押したときに ダイアログのボタンをグレーアウトしたいと思ったら グレーアウトする処理をどこに書くか考えればわかるだろ
親ダイアログと子ダイアログを分けて考えるのが変
ボタンを Enable/Disable する関数(コード)そのものはそのボタンをもつダイアログクラスに書く。 「子ダイアログの操作(ボタン選択)をした時に」とあるので、その関数のトリガーを引くのは子ダイアログ。
>>766 クラスの巨大化とSRP違反を避けるために
分けるのは普通だろ
Oberverパターンで子からの呼び出し受けとるのが最も標準的だな
769 :
762 :2009/06/11(木) 19:16:47
レスありがとうございますm(_ _)m
>>766 , 767
タブコントロールを使用した場合、
タブの切り替えを、現状のダイアログの上に子ダイアログ(枠なし)を新たに作成して、
表示、非表示で切り替えています。 ↓これを参考に作成しました。
ttp://www.g-ishihara.com/mfc_ta_01.htm 例えば、タブ内のダイアログ(子) の"実行"ボタンを押した場合、
親ダイアログの一部のオブジェクト(ボタンやエデットボックスなど)を使用不可にしたいと思っています。
767さんの言われるとおりなら、親のボタンは親の関数で実行する。
子から親の関数を直接的に呼ぶのではなく、メッセージを送信して間接的に処理依頼をする方法の方が
良いとのことですよね?
親ダイアログに「オブジェクト操作」関数を用意して、子ダイアログから親の関数を呼ぶくらいは良いんじゃないかな メッセージが適切な場合もあるが、煩雑になって見難いソースになるほうがイヤだが 親のボタンのグレーアウトまで子ダイアログクラスに記述するのは美しくない、かな。
771 :
767 :2009/06/11(木) 20:59:31
>メッセージを送信して間接的に処理依頼をする方法の方が
>良いとのことですよね?
パブリックな親オブジェクトの関数を子オブジェクトから呼ぶ、という意味。
>>770 氏の書いてるのと同じだね。
メッセージ送信は「ウィンドウ」に対しておこなうわけだから、今回のようにオブジェクトを確定的に取得できる
場合は迂遠な方法になってしまうよな。
複数のチェックボックスのBool型メンバ変数の値を読み込み、そのパターンから値を一つ返す関数を作りたいと考えています。 例えばチェックボックスが3つなら、8パターンあり、返す値としては8個になります。4つなら、16個です。 こういう関数を実現するにあたり便利な関数などあれば教えていただければ幸いです。
とりあえずmfcの関数にはないからmfc以外で探せ ということで以下終了
シフト演算でいいんじゃ?
どのビットがどのチェックボックスなのかの紐付けがエグいことになりそうだ。
わざわざ返り値でやる意味あんのかね?
まぁ、俺の感知するところではないから、
>>773 が正しいでやっぱ終了だな。
? 簡単にできると思うがね。
UpdateData(); value = ( m_Check1 ? 1 : 0 ) + ( m_Check2 ? 2 : 0 ) + ( m_Check3 ? 4 : 0 ) ;
汎用的な関数の話じゃなかったのか?
普通の整数使ったフラグの処理 普通過ぎて、そういう「便利な関数」があるかと言われれば無い て事でしょ
MFCで可変配列を使いたいときって、 CArray , vector(STL) , その他 どれを使うのが普通ですか? 特にシリアル化は必要ないです。
使い方が容易なので C*Array をよく使うが、「どれを使うのが普通」がというものはない。 用途に応じて使い分ければいいだけ。
各クラスには、それぞれ長所・短所。自分の用途に合わせて使い分けろ。 それが分からんなら、動くことを優先して、どれでもいいから使え。 あと、くだらん質問しに来るな、ドアホゥ
とまぁ、STLを使う常識に馴染めないMFC使いも多いので、職場なら空気を読みましょう。
プログラマってのは、いろいろ使うことを経験して、自分で考えるもんだ。
何を使うのか教えてもらえなきゃ組めないなら、設計通りに組むただのオペレーター。
おまえ、プログラマには向いてないよ
>>780
VS2005でMFCのダイアログで開発しています。 このダイアログにClass Nameを設定したいのですが、グレーアウトしていて出来ません。 どうすればよいのでしょうか? ヒントだけでも下さい。お願いします。
MFCメインフレームのひ孫で作ったマルチスレッド内で if( (CMainFrame*)AfxGetMainWnd() != NULL ) をしてもずっとTRUEにならないんですが、どうすればメインフレームを取得できるんですか?
theApp.m_pMainWnd
出来ました。違いがわかりませんがありがとうございました
>違いがわかりませんが ・・・orz
あるダイアログクラスからCClientDCをnewし 別のダイアログクラスからnewしたCClientDCを使用し 表示などを行っても問題はないのでしょうか? 教えてください。
問題はないか、だって? それぞれのデバイスコンテキストがどのウィンドウのものであるか、把握できているのかね?
795 :
793 :2009/06/24(水) 19:02:32
newしたダイアログクラスのみで使用するものだと思いますが 別のダイアログクラスで使用しても正しく表示できているので 問題がないのならば使用したいと思っています。
その君の思考はオブジェクト指向ではない。 そこがおおいに問題。
797 :
793 :2009/06/24(水) 19:10:46
その問題以外は問題がないんですね?それならば問題ありません。
よ〜し、パパCSingleLockをnewしちゃうぞ〜。
799 :
793 :2009/06/24(水) 19:50:08
教えていただきありがとうございました。
それが自分のものか親から受け継いだものかはともかく、自分の資産に関してアクセスするのは構わないが 人のものに対して勝手にアクセスするのはよろしくない。 人からいじられる事を想定した切り口(関数とか)を用意してあげるとか、方法はいくつかある。
>それならば問題ありません。 こういう考え方だと、いつまでたってもスパゲティ的なプログラムしか組めなくなるから注意されたし。
>スパゲティ的なプログラム フェットチーネにすると、クリーム系じゃないソースは絡み難くなるよ。
簡単な確認ダイアログを作成して、数秒後に自動クローズをするモーダル・ダイアログを作成したのですが、 ダイアログを終了するところで落ちます。 以下の、コードはダメなのでしょうか? OnInitDialog()時にワークスレッドを作成して、そこでダイアログの描写処理、 処理後にスレッド側でOnOk()などでダイアログを終了します。 //簡単な例(大分省いています・・) class CTestDlg : public CDialog { public: virtual BOOL OnInitDialog(){ //初期化時にワークスレッド作成 AfxBeginThread( CTestDlg::BeginTread, this ); } //ワークスレッド bool TreadFunc() { //ここでダイアログの描写処理() //例えば30秒間タイマーを表示するなど・・ //ダイアログを閉じる OnOk(); //<-うまくモーダル・ダイアログを閉じることができない・・・・ } static UINT AFX_CDECL BeginTread(LPVOID pParam) { CTestDlg* pObj = (CTestDlg*)pParam; pObj->TreadFunc(); } }; //呼び側 CTestDlg cDlg; cDlg.DoModal
>>803 ・なぜ別スレッドにしているの?
・なぜOnInitDialog()内で処理しようとするの?
・何もせず、単に数秒後に閉じるだけのダイアログをサンプルとして作ってみた?
この程度の内容を自分で解決できないなら、真剣にプログラムをやめることを検討すべき
プログラムを止める必要はないけど、プログラマは辞めて欲しいな。 趣味のプログラミングなら勝手にしてくれ。
スレッドの中からOnOkを呼ばずに、自分にWM_CLOSEをpostしてみては?
>>803 それはメインスレッドで閉じないとだめだ。
ダイアログが表示されたぞ→メインスレッドでワーカーの終了を待つ→メインスレッドでOnOK()
ところで、「ダイアログが表示された」って、いつわかるんだっけ・・・
CWinThread* thread;
BOOL CTestDlg::OnInitDialog() {
thread = AfxBeginThread(.・・・);
}
void CTestDlg::ダイアログが表示されたあとにメインスレッドで実行される何か()
{
//スレッドの終了までブロック
::WaitForSingleObject(thread->m_hThread, INFINITE);
//ダイアログを閉じる
OnOK();
}
809 :
803 :2009/06/26(金) 14:35:50
>>804 >・なぜ別スレッドにしているの?
>・何もせず、単に数秒後に閉じるだけのダイアログをサンプルとして作ってみた?
本当は、数秒かかる処理(複数回)を確認するために、プログレスバーを使用して
状態確認を行い、処理終了後に自動でダイアログが閉じることが目的です。
ダイアログクラスに処理を埋め込むのも微妙だと思いますが・・
>・なぜOnInitDialog()内で処理しようとするの?
DoDoModal()時に確実に呼ばれるみたいなので、とりあえずここに入れてみました。
他に適切なイベントハンドラがありますか?
一応、趣味で作成しています。MFCは初心者です。
>>807 WM_CLOSEでうまくダイアログが閉じましたありがとうございます
>処理終了後に自動でダイアログが閉じることが目的です。 処理のみを別スレッドとし、処理が終了したらダイアログに「終わったよ」と教えてやる。 それを受けて、ダイアログは自身で閉じるようにする。 別スレッドでダイアログを閉じてはダメ。
>>809 途中経過のプログレスバー表示もPostMessageを使ったほうがいいよ。
ワーカースレッドから進行状況をWindowにPostMessageして、
メインスレッドでは、ポストされた進行状況に従ってプログレスバーを更新するようにする。
ワーカースレッドでプログレスバーを更新するとはまるよ。
メインスレッドはワーカースレッド終了を待っているのに、 ワーカースレッドはメインスレッドがメッセージを処理してくれない為に SendMessageから帰って来れなくてデッドロックとか、良くあるパターン。
そこでPostMessageだぜ
>ワーカースレッドはメインスレッドがメッセージを処理してくれない これを称して自業自得という。
普通はワーカースレッドではpostmessage以外は一切ダイアログをいじらないもんだろ ダイアログを閉じる以外の操作でも必ずといっていいほど何らかの不具合がおきる
ワーカーっていうぐらいだからな
おまえら、スレッドの使い方を1から勉強し直せ
GUIスレッドについて知ることが先ではないか そうすれば自ずと分かる
GUYについても知ってほしい。
もちろん、GAYについてもな
CStringを引数で渡すとき CString$ sz ってやる人いるけど CString* sz じゃだめなの?
CString& でした
どっちでもいいんですね
Windowsのサービス作りたいんだけど、MFC使ってサービスって作れる? リソースキットについてるサービス化ツールを使えばいいのかな?
>>821 ポインタ渡し → 受け取った関数でnullチェックが必要
参照渡し → nullはこない
>>827 void Hoge(CString& rStr)
{
if (&rStr == NULL) {
TRACE("NULL\n");
}
else {
TRACE("%s\n", rStr);
}
}
CString* pStr = NULL;
Hoge(*pStr);
>>828 NULLをデリファレンスしようとした時点で花から悪魔。
何とかの一つ覚え
参照渡しを &でアドレスとってNULLチェックなんて 誰もしないよね
代わりって……実体がくるんじゃん
もうヴァカにかまうなよ。 かまって欲しいだけだろ。 スルー推奨。
GetWindowTextとかでしょっちゅう使うだろ いちいちgetbufferしなくていいから便利だよな CWnd::GetWindowText int GetWindowText( LPTSTR lpszStringBuf, int nMaxCount ) const; void GetWindowText( CString& rString ) const;
素直にCStringを返しても良かったんじゃないかとは思うけどね。 CStringが参照カウント管理されていなかった時代の名残かな。
余計なコンストラクタを実行させないためだろ。
>>833 いや、nullの場合だってあるじゃん
unko=NULL;
hoge(unko);
こんなん?
>>840 おまえの書きたいのはこうだろ
Foo* unko=NULL;
hoge(*unko);
>>838 じゃポインタ渡しだ
全然会話の流れに乗れてない
void GetWindowText( CString& rString ) void GetWindowText( CString* rString ) 違いわからん
>>843 // GetWindowText( CString* rString ) の悪例
int n;
CString* p = (CString*)&n;
GetWindowText( p); // コンパイルエラーにならない
>>844 結局、チェック必要になるんと違うのん?
チェックしようがしまいが0アドレスを参照した時点で大抵落ちるんじゃないかな
>>846 チェックが必要なのは
*演算子をやる前
他のスレでも話題になってたが Foo* unko=NULL; hoge(*unko); というコードは、hogeとは無関係に、このコード自体が不正。 なので「これで正しく動くかどうか」等は、hoge関数が責任を持つことではない。
850 :
849 :2009/07/02(木) 07:46:51
ごめん。他のスレだと思ってたがこのスレ自体で既に出てたみたいだ。 ずっと同じ話題だったのか。
>>838 そのものは
NULLで初期化した実体を渡してるだけ
あほすぎる
>>849 そうかなぁ?
仮にその関数100回呼び出すとしたら
必ず100回同じチェックすることになるでしょ?
非効率じゃない?
必ず同じチェックがてめーで必要になるならてめーの中でやれよ
ってのが俺流
ポインタがあふれているなら、ポインタでわたせばいいじゃん。 CString や std::string のように、普通はポインタを使わないようなオブジェクトを渡すときに、 foo(CString*)のような、ポインタ渡しの関数を書くのはヘタクソ。
でもそれだと面倒なんでしょ? 実用的じゃねぇもの使ってもしょーがねーじゃん
CArrayとvectorってどっちを使えばいいんですか? 動的配列の違いがわからないんですが
SDIでCViewをCHtmlViewと切り替えて使いたいんですが どういう構造で組めばいいんでしょうか?
双方とも動的に作成して切り替えるか、静的に作成して一方を非表示にしておく。
>>587 MSDNのkb99562にサンプル載ってるよ
860 :
294 :2009/07/05(日) 20:43:28
587じゃなくて857だった orz
MFCでツールを作っています。 ダイアログバーを使用してツールバーのような物を作り、そのダイアログバーにツリーコントロールを配置したのですが、 ダイアログバーゆえになのか、通常のダイアログに配置したコントロールのように自動でDDX変数を追加する事が出来ません。 その為、CTreeCtrlクラスオブジェクトのメンバ変数を作ってもそのコントロールと関連付け出来ず、アクセス出来ません。 色々悩んで調べた後に辿り着いたのが (ツリーコントロールのメンバ変数).Attach( this->GetDlgItem(IDC_TREECONTROL1)->GetSafeHwnd() ); を実行後にメンバ変数から操作し、最後に (ツリーコントロールのメンバ変数).Detach(); とすることで一応動かせたのですが、これがベストなのでしょうか? もしくは偶然動いただけで想定外動作を起こしかねない方法なのでしょうか? ダイアログバーに配置したツリーコントロールが表示されているということは MFCプログラムのどこかの段階でそのコントロールをCreateしているはずで、 どこかにその時のオブジェクトがあるんじゃないかとは思ったのですが未熟な自分には どこなのかまったく分かりませんでした。 どなたかアドバイスお願いします。
ダイアログバーでDDXを有効のコードはcodeguruを参考にして作ったけど MS謹製の方法もあるんだな
865 :
862 :2009/07/08(水) 20:52:03
>>863 ありがとうございます。
教えて頂いたURLを参考にした結果、アタッチやデタッチ無しで無事成功しました。
2008で作ったアプリって 再頒布可能パッケージをインスコしないと 他のPCで実行できないのですか?
/MTにしたうえでスタティックリンクにすればredistなしでいけるかもね
870 :
デフォルトの名無しさん :2009/07/14(火) 01:33:45
リストボックスで複数列を表示したいのですが、 そのような事は可能でしょうか?
絶対無理
オーナードローとか 昔NT3.5対応させなきゃならなかったから ListViewとTreeViewをListBoxサブクラス化して作ったなあ・・・
リストコントロールならできる
独自に作ったダイアログ(CDialogから派生)を 複数のプロジェクトで使い回したいのですが、 リソースが絡んでいるため、ソースとヘッダだけのときのように、 共通の場所に置いたものを各プロジェクトに追加するような使いかたができません。 このような場合、どのような方法があるのでしょうか。 おとなしくプロジェクトごとのrcファイルに ダイアログ部分を毎回記述していくことになるのでしょうか。
>>875 .rc2ファイルにしておいて、インクルードすれば?
.rcファイルの終わり近くに、
#include "res\\***.rc2" // Microsoft Visual C++ 以外で編集されたリソース
とあるでしょ?
リソースファイルは個別に設定できるようにしてほしかった もしかしてできる? なんでプロジェクトで1枚なんだ? ほかの人と被ったときにやたらと編集が面倒くせぇよ
dllにリソース入ってたりする。
>>877 リソースは個別にリソースエディタ(外部ツール)で編集し、>876のように.rcでインクルードすればいいよ。
ソースファイルと似たような扱いでいいだろ 名前の衝突さえ起こらなければ いくらでも追加できるんだから リソースエディタも複数リソース対応してるぞ
>>879 その場合、ダイアログ自体や各コントロールのIDはどこに記述するのですか?
通常ならresource.hに勝手に入ってしまうのですが。
外部のリソースエディタが作ってくれるべさ。 あ、番号が競合しないように、そこだけは要注意ね。
>>883 根本的な質問で申し訳ありませんが、
外部のリソースエディタというのはそもそも何ですか?
>>884 リソースエディタがなんなのか、よく考えていろいろググって、それから氏ね
ダイアログ生成時にコントロールの大きさや位置を指定するにはどうしたらいいでしょうか?
>>887 CDialog::OnInitDialog() をオーバーライドして、そこに必要なコードを書く。
ありがとうございますコントロールの変更はできました でもダイアログの変更ができません、OnInitDialog()内でコントロールと同様に MoveWindow()で変更しようと思ったのですが 動作させるとエラーが出てしまいます
T.exe の 0x004058f5 でハンドルされていない例外が発生しました: 0xC0000005: 場所 0x00000050 を読み込み中にアクセス違反が発生しました。 winocc.cppのここで止まります if (m_pCtrlSite == NULL) ::MoveWindow(m_hWnd, x, y, nWidth, nHeight, bRepaint);
アクセス違反か。実体が存在しないオブジェクトのメソッドを実行している可能性ありだな。 CWnd* pWnd = NULL; pWnd->MoveWindow( 0, 0, 0, 0); // アクセス違反
// TODO: ここに初期化を追加してください CWnd* ttdlga = GetDlgItem(IDD_TTDLG); ttdlga->MoveWindow(0,0,PictWidth,PictHeight+80,1); IDは間違ってないと思うんですけど
>>893 >IDは間違ってないと思うんですけど
CWnd* ttdlga != NULL をチェックしてみ。
それと、IDD_TTDLGが自身のダイアログなら、このコード自体不要。
MoveWindow(0,0,PictWidth,PictHeight+80,1); // これだけでいい。= this->MoveWindow(0,0,PictWidth,PictHeight+80,1);
それとも、別のウィンドウでこのコードを実行しているのか?
>MoveWindow(0,0,PictWidth,PictHeight+80,1); // これだけでいい。= this->MoveWindow(0,0,PictWidth,PictHeight+80,1); これでできましたありがとうございます。よく考えたらそうですよね・・・助かりました
先輩方に質問させて下さい。 ダイアログ上に配置したスクロールバーの場合はできるのですが、 WS_HSCROLL | WS_VSCROLLを追加して作ったビューにくっついてるスクロールバーのハンドラ(?)の取得方法が分かりません。 CScrollbar *pCScrollbar = ************; ***********←ここの部分はどうやって書けばよいのでしょうか。 よろしくお願いします。
>>896 独立したスクロールバーではないので、バー単体でのハンドルは存在しない。
GetScrollPos / SetScrollPos 等の、CWnd のスクロール関数を使って操作されたし。
>>897 迅速なご回答本当にありがとうございます。
エラーエラーで困っていたので万感の思いです。
この程度で万感とは、随分安い思いだな。
CHeaderCtrlでオーナードローをしようとしています。 itemにHDF_OWNERDRAWをつけて、DrawItemをオーバーライドしたところ、 item自体は描画できるんですが、item枠や、item間の区切りが、 DrawItem抜けた後で勝手に上書きで描画されてしまうようです。 これをやめさせる方法ってないでしょうか? 別案で、OnPaintオーバーライドして全部自前描画、ってのもやってみました。 こちらだと区切りまで含めて自分で描けるんですが、 OwnerDrawの時は引数として渡されてくる、Itemのhoverやpushの状態等 を取得する方法がわからず、詰まってしまいました。 どなたか、助言をお願いします。
MFCのダイアログベースで作成しています。 初歩的なことで申し訳ありませんが、ダイアログがサイズ変更可能な状態で、 指定以下のサイズに縮小できないようにするには、どのようにすればよいでしょうか? ご教授お願いいたします。
WM_GETMINMAXINFOを適当に処理する
905 :
903 :2009/07/28(火) 13:59:58
>>904 ありがとうございます。
解決しました(^^
VisualStudio2008、ダイアログベースでプログラムを書いてます。 ダイアログAとダイアログBを準備しておいて、 ・アプリケーションを起動するとダイアログAが開く ・ダイアログA内の『次へ』というボタンをクリックするとダイアログBが開く ・ダイアログBが開くとダイアログAは非表示になる というセットアップウィザードのようなプログラムを作成したいです。 ボタンを押した際の処理に、 m_pDlgB = new CダイアログB; m_pDlgB->Create(IDD_ダイアログB, this); m_pDlgB->ShowWindow(SW_SHOW); ShowWindow(SW_HIDE); と書いているのですが、これだとタスクバーからアイコンが消えてしまいます。 タスクバーにアイコンを残す方法は何かありますか? それとも、セットアップウィザードのように画面が切り替わるプログラムの場合 は何か他に方法があるのでしょうか。
>>906 >タスクバーにアイコンを残す方法
CダイアログBのOnInitDialog() で SetIcon( hIcon, FALSE) する。
>何か他に方法があるのでしょうか。
ウィザード形式のプロパティシートを利用する。
908 :
906 :2009/08/02(日) 11:40:28
>>907 >CダイアログBのOnInitDialog() で SetIcon( hIcon, FALSE) する。
やってみたのですが、この方法でもタスクバーからアイコンは消えてしまうようでした。
>ウィザード形式のプロパティシートを利用する。
これでできました!ありがとうございます。
それと、単純にリソースのプロパティのApplicationWindowの項目を
Trueにすればよかったみたいです。
ありがとうございました!
Visual Studio 2008 + MFC Feature Packの環境にて、 アプリケーションの種類:SDI,プロジェクト形式:MFC標準のフレームワークで、 ツールバーのアイコンを大きい/小さいを入れ替えたいと思っています。 ※大きいアイコンと小さいアイコンは別々にリソースを用意するつもりです。 また、この時メニューバーの [表示(V)]→[ツールバーとドッキングウィンドウ(T)]→[カスタマイズ...] で表示される「カスタマイズ」ダイアログ内、「オプション」タブにある、 「大きいアイコン」チェックボックスに対応させて入れ替えたいと思いますが、 そんな事可能なんでしょうか? もし、可能であれば、オブジェクト名とそのメンバ。 もしくはサンプルを教えていただけませんか?
MFC Feature Packのソースを読んで、適切なタイミングでリソースを入れ替えれば? 今、ソースを読んでる時間ないから思いつきだけど。:-) あるいは、大きいアイコンのツールバーと小さいアイコンのツールバーを別個に用意して 表示/非表示で切りかえるとか。
>>909 やりたいことだけ考えて、あとは教えてもらおうとか、プログラマとしては屑だな。
普通は試行錯誤して自分で組むもんだ。
氏んだ方がいいんじゃないか。つか、氏ね。
912 :
909 :2009/08/04(火) 13:34:01
>>911 おいおいwww
俺がプログラマって言ったか?
残念wwww
>>910 すり替えの方法で、
サンプルのIEDemoとかで調べてみます。
>>911 そうですね。
くれくれではなく、少しは精進します。
プログラマ:プログラムを組む人。プロの職人という意味にあらず。
それは冤罪
他人を装ってレスするのはム板では日常茶飯事
質問です。 サーバー側からクライアント側にCSocketを使用してCString配列のデータを送信しているのですが、 送信途中でPunpMessage関数に入ってしまい、送信速度が遅くなってしまいます。 一つ配列を送信するごとにSleep(1);をはさめばうまくいくこともあるのですが、 やはり不安定ですし、送信速度も遅くなってしまいます。 どうやったらPunpMessage関数に入らず、すばやく送信できるのか教えてください。 また、そのような問題を解決するサンプルプラグラム等ありましたら教えていただけると助かります。
920 :
919 :2009/08/06(木) 10:28:22
>一つ配列を送信するごとに ↑は一つCString配列を送信するごとにの誤りでした。すみません。
>>919 >PunpMessage関数
そもそもこういった関数は存在しない。スペルミスであることはわかるが、
CSocket::PumpMessages() なのか CWinThread::PumpMessage() なのか不明。
ま、いずれにしろメンバ関数なので、無効化だけを狙うならオーバーライドしてしまえばよい。
922 :
919 :2009/08/06(木) 10:58:12
923 :
デフォルトの名無しさん :2009/08/06(木) 13:39:58
CResourceException が発生するのですが、原因は何? 解決するにはどうしたらいいの?
Windows が要求されたリソースを見つけられないか、割り当てられないときに発生
解決するにはその例外で止まった時点で、その場所を見るとか呼び出し履歴を見るなりなんなりして 直接の原因を調べることだろうな
926 :
デフォルトの名無しさん :2009/08/06(木) 22:24:26
24文字のテキストを百万回連結して最後にテキストボックスに表示する操作をやろうとしているのですが、 どうやったら一番早いでしょうか? 毎回CStringで連結してたらあまりに遅かったので、 char配列のバッファAに16kBまで書き込んで、次にCStringのバッファBで16回連結し、 それを16回分たまるごとにCStringのバッファCで連結して最後にテキストボックスに出すようにしたら 少しは早くなりましたが…
なんでバッファ分けるんだ 小分けにする理由はあるの?
928 :
デフォルトの名無しさん :2009/08/06(木) 23:58:14
はなくそとMFCは同じくらいうまい。
929 :
926 :2009/08/07(金) 00:43:38
>>927 やはり大きい領域で連結操作すると重いみたい。
CString一段から二段に増やしたら時間短縮した。
それ以上増やしてもあんまり変わらなかったけど。
10000文字あったとして連結して10001文字にしたら多分 10001文字の領域を確保して10000文字の領域からコピーして 10000文字の領域を破棄してるから遅くなると考えてなるべく小分けするって 手法をとったんだろ? javaでも似たような動作したな 毎回こういう文字列オナニークラスみるたびに思うけど 汎用設計下手糞すぎる奴がなんでこんなもの手をだすんだろね
>>929 なんかズレてるな
>char配列のバッファAに16kBまで書き込んで
これを24MBのchar配列にして
CStringの連結を一回も行わずに
テキストボックスに渡すのは駄目なのか?
CStringも中の人はchar配列だし、 最初から大きめに領域取っておけば、 不足するたびに何度も領域増やすような頭の悪い状況は避けられる。
連結してテキストボックスに出力する程度のことでわざわざ CString 使わなくても char 配列で十分だろーに。 使いたいなら CFixedStringT というのもある。
タスクバーに表示されない常駐プログラムを作成しています。 いろいろとサイトを拝見してたところ簡単な方法で、 OnSysCommand()内で、最小化時に ShowWindow(SW_HIDE)で本体を隠し、CDialog::OnSysCommand()が呼ばれる前に 終了する方法を見つけましたが、この方法で特に動作的に問題は無いでしょうか? サンプルを作成してみたところ、正常に動作しているように見えます。 void CTest::OnSysCommand(UINT nID, LPARAM lParam) { if ((nID & 0xFFF0) == IDM_ABOUTBOX) { CAboutDlg dlgAbout; dlgAbout.DoModal(); } else { switch(nID){ case SC_MINIMIZE: //ここで終了 ShowWindow(SW_HIDE); return; } CDialog::OnSysCommand(nID, lParam); } }
>>934 CDialog::OnSysCommand() が何をしているのか調べるとわかる。
>>935 アプリ主なシステムコマンド(最小化、最大化、クローズなど)のデフォルト処理を行っているんですよね。
それを飛ばして、勝手にウインドを隠すこと自体、問題ないのか少し不安になり質問しました。
クローズボタンの無効化などで、OnSysCommand()を呼ばずに終了する方法は見たことはあるのですか・・・・
>>936 難しく考えなくていい。
CDialog::OnSysCommand() は メッセージを DefWindowProc() に渡しているに過ぎない。
DefWindowProc() は処理されないメッセージを処理する関数。
原則として、処理をしたメッセージをこの関数に渡す必要はない。
>>937 ありがとうございます。参考になりました。
メッセージ処理を行っているだけで、特に必要なければ、
飛ばしてもよいのですね。
939 :
926 :2009/08/09(日) 01:36:51
>>931-933 いや、十分な大きさの配列宣言したら実行時エラーが出てしまって…
(その後、malloc系の関数で別途メモリを確保したら一応できましたが)
240万文字を保持するにはCStringとかにするしかないのかなと思ってしまっていました。
それに、毎回240万文字出さなくちゃいけないわけではなくて、
そのプログラムをある特定の目的で使ったときのみその必要があるだけで、
通常は24文字が数十からせいぜい数百くらいしか生成されないんです。
そして正確な必要量は、確率で決まるので実行するまで不明という仕様。
で、926の書き込みの後さらに試行錯誤した結果、文字列の生成・連結の実行時間は既にかなり短縮できていて、
現状では実行時間のほとんどがCEditのSetWindowTextに費やされていたことがわかりました。
ちょっと私の実力ではCEditに代わるものをなんとかするとか無理なので、あきらめることにします。
お騒がせしました。
>十分な大きさの配列宣言したら実行時エラーが出てしまって >そして正確な必要量は、確率で決まるので実行するまで不明 char* lpString = new char[必要量]; // to do ... delete [] lpString;
>そして正確な必要量は、確率で決まるので実行するまで不明 これはおかしい 上限は仕様で決めなければならない だってランダムで明らかにPCのスペックを上回る量だったらどーすんだよ HDDに一時的に保存しておく必要だってでてくるし 本当は上限はあるにはあるんだけど概算を出すのが面倒だからやってないだけだろ 嘘をつくな 嘘をつくと後で大変なことになるぞ 自分にとってもよくない
・・・お前、そこだけ読んでるだろ。
>>939 そもそも数メガのテキストを渡すとか
まともなパフォーマンスにならなかった気がする
テキスト渡すだけでフリーズしかけ、
スクロールする度にフリーズしかけ・・・
1MB越えると処理しきれないよね 一文字増えるだけで大変なことになる
946 :
926 :2009/08/10(月) 02:33:26
947 :
926 :2009/08/10(月) 04:08:59
失礼。ちょっと勘違いしてました。
仕様上の上限は
>>926 にある通り2400万字。
24文字のテキストが生成されるルーチンは、理論上は果てしなく続く可能性があるけれど、
100万回で強制的に打ち切る仕様です。
24文字のデータを生成するルーチンだけに関して言えば、「必要量」は不明です。
その「打ち切る」処理まで含めて言えば24MBが必要量の上限となりますが、
それってむしろ必要量というよりは十分量のような気が。
>>947 MFCからはほど遠い内容になってきているから、もうそのくらいにしとけ。
C++相談室でこちらを紹介されたので、移動しました。 VS2008のVC++MFCで ボタンクリックでピクチャーコントロールにjpgファイルの画像をサイズを変えて表示しています。 以下ソース CImage img; CImage img2; HDC hdc; img2.Create(80,60,24); img.Load("jpgファイルのフルパス"); hdc = img2.GetDC(); SetStretchBltMode(hdc, HALFTONE); img.Draw(hdc, 0, 0, 80, 60); img2.ReleaseDC(); m_xcPic01.SetBitmap( (HBITMAP)img2 ); img.Destroy(); img2.Detach(); img2.Destroy(); jpgファイルが変わる毎に、画面上の画像も切り替えたいので 上の処理を呼び出して、画面を切り替えてます。 しばらく動かしていたところで気付いたのですが、 メモリの使用量がかなり多くなっていました・・・ ファイルロード側のDestroyやリサイズ後側のDetach、Destroyだけでは解放してくれないのでしょうか? わかる方、または参考になるサイトやスレをご存知の方、よろしくお願いします。
>>949 メモリの使用状況との関連は不明だが
>img2.Detach();
>img2.Destroy();
この場合、img2.Detach() によってオブジェクトに関連付けられている HBITMAP が切り離されてしまうので、
img2.Destroy() は何も機能しない。
したがって、m_xcPic01 に関連付けた HBITMAP をどこかで DeleteObject() してやる必要がある。
>>950 レスありがとうございます。
つまりは以下の様にすれば・・・とのことでしょうか?
CImage img;
CImage img2;
HDC hdc;
img2.Create(80,60,24);
img.Load("jpgファイルのフルパス");
hdc = img2.GetDC();
SetStretchBltMode(hdc, HALFTONE);
img.Draw(hdc, 0, 0, 80, 60);
img2.ReleaseDC();
m_xcPic01.SetBitmap( (HBITMAP)img2 );
img.Destroy();
img2.Detach();
//img2.Destroy(); //コメントアウト
::DeleteObject(img2); //追加
まずは、コレで動作を確かめてみます。
ありがとうございます。
>::DeleteObject(img2); //追加 すでに Detach() されているのだからこれも無意味。 m_Bitmap = img2.Detach(); // m_Bitmap は HBITMAP 型のメンバ変数として宣言する m_xcPic01.SetBitmap( m_Bitmap); // 不要になった時点で ::DeleteObject( m_Bitmap);
>>952 ありがとうございます。
さっそく動作を確かめてみます。
ダイアログバーにスクロールバーのコントロールを貼り付けて、 ダイアログバーのOnVScrollなどでスクロールイベントを拾ってます。 動かして見るとスクロールバーをいくらスライドさせてもドラッグしているボタンを 離すと元の初期位置に戻ってしまいます。 スクロールイベント検知時にはSetScrollPosでnPosの値をちゃんと設定しています。 念のために直後にGetScrollPosで値をTRACE出力して確認しましたが、ちゃんと設定されています。 このGetScrollPosで取得した値をTRACEで出しながら確認したのですが、ドラッグ中は正しい値がちゃんと取れています。 でもドラッグを中断してボタンを離した瞬間に、何故かスクロールイベントがnPosが0で発生し、 その0によって上書いてしまします。 苦肉の策でnPosが0の時は上書き処理をしない条件式を入れると期待通り動きます。 初期処理としてSetScrollRangeで最大値500を入れたのに、GetScrollLimitでみると勝手に501にしてくれています。 これはnPosが0が来たら無視するプログラムを作れというマイクロソフトの意図なのでしょうか? それとも自分が何か間違っているのでしょうか?
955 :
954 :2009/08/12(水) 14:18:08
他にもスライダーコントロールのレンジをー300〜100に設定し、 初期値をSetposで0にすると、最初に描画された画面では意図した場所にスライダーが 設定されてません。 でも初期値を50にするとちゃんと意図した位置にスライダーが設定されて描画されてます。 MSDNの説明には1からスタートで0は無効ともマイナスを設定しては駄目ともありませんし、 プログラム中はマイナスになっても機能してます。 マイクロソフトのプログラマーがsetposの引数が0だったら処理しないみたいな バグを仕込んでいるのではないかと邪推してしまいます。
957 :
954 :2009/08/12(水) 16:33:29
>>956 ページ移動や左右クリックによって細かい処理変更を行う意図はなく、
純粋に値だけ正しければいいと思ったので、nPosの値のみみて
nSBcCodeは意識していません。
これが関係しているのでしょうか?
>>957 いらないnSBcCodeは無視するようにしないとnPos=0で何回も飛んでくるだろ
該当部分のコード貼れよ TBM_SETRANGE に当たるもんな TBM_SETRANGE wParam = (WPARAM) (BOOL) fRedraw; lParam = (LPARAM) MAKELONG(lMinimum, lMaximum); ちなみに設定時のMAKELONGってWORD指定じゃね? WORD指定って 16ビット符号なし整数(unsigned short型/2バイト) ってことはマイナスなしじゃね? っていい加減なこと言ってたらスマンコ
960 :
954 :2009/08/12(水) 20:53:17
void CMyDialogBar::OnHScroll(UINT nSBCode, UINT nPos, CScrollBar* pScrollBar) this->UpdateData(TRUE); if( *pScrollBar == m_ddxHScroll && nPos != 0) { m_ddxHScroll.SetScrollPos(nPos); } this->UpdateData(FALSE); CDialogBar::OnHScroll(nSBCode, nPos, pScrollBar); } 今はこんな感じになってます。 スクロールバーの矢印クリックだろうが直接指定だろうが、左右の隙間クリックだろうが、 ショートカットキーだろうがnPosにはその時の実際の値が入っているという理解は間違いでしょうか?
>>955 >他にもスライダーコントロールのレンジをー300〜100に設定し、
>初期値をSetposで0にすると、最初に描画された画面では意図した場所にスライダーが
>設定されてません。
>でも初期値を50にするとちゃんと意図した位置にスライダーが設定されて描画されてます。
ウチでは問題なく設定される。
おそらく君は、スライダの再描画フラグをTRUEにしていない。
m_wndSlider.SetRange( -300, 100, TRUE); // 再描画フラグはTRUE。
m_wndSlider.SetPos( 0);
スライダーコントロールの、そもそものスライダの初期値は 0。
再描画フラグをFALSEにしたまま範囲を変更して、その後初期値を 0 に設定しても、
スライダの値そのものは変化していないのだから、再描画されないのは当然と言えば当然。
よって「意図した場所にスライダーが設定されてません」なとど言わなきゃいけないハメになる。
初期値を 50 にすれば、もともとの値から変化しているのだから、再描画フラグが FALSE でも
スライダの位置は再描画されるので
「でも初期値を50にするとちゃんと意図した位置にスライダーが設定されて描画されてます」
などとのたまうコトになる。
バグを仕込んでいるのではないかと邪推する前に、道理を考えるべし。
963 :
954 :2009/08/13(木) 01:05:11
ご指摘の通りでした。 修正すると全て上手く動きました。 この問題だけに一日悩みました・・・。 ありがとうございました。
独自のコマンドライン引数に対応する実行コードを記述する場合、 CWinApp::ProcessShellCommand をオーバーロードすればいいんでしょうか?
>>964 CCommandLineInfo::ParseParam() を「オーバーライド」する。
msdnを読む限り、デフォルトの動作では、CCommandLineInfo::ParseParamは CCommandLineInfoオブジェクトのデータメンバに値をセットしてるだけで 実際の動作はCWinApp::ProcessShellCommandの方で行われてるようなんですが (設定はCCommandLineInfoクラスで、実行はCWinAppクラスで、という形になっている) CCommandLineInfoクラスの中で処理コードを書いちゃってもいいものなんでしょうか…。 というよりも、CWinAppオブジェクトを参照できないから theAppのパラメータ等に依存するコードはかけないような・・・。
>>966 独自のコマンドライン引数の処理をするには CCommandLineInfo::ParseParam() をオーバーライド
して CCommandLineInfo::m_nShellCommand に独自の値をセットし、その値の時には独自の処理をおこなうように
CxxxApp でコーディングする。言いかえると、CCommandLineInfo::m_nShellCommand が既定の値のときだけ
CWinApp::ProcessShellCommand() が実行されるようにする。
>msdnを読む限り
CCommandLineInfo::ParseParam() の解説に
「ほかのフラグやパラメータ値を処理するには、派生クラスでこの関数をオーバーライドします。」と書いてある。
面倒くさければ、CWinApp::ProcessShellCommand() 相当の関数を自作して、コマンドライン引数に対する
すべての処理を自分で書けばよい。
>というよりも、CWinAppオブジェクトを参照できないから
>theAppのパラメータ等に依存するコードはかけないような・・・。
意味不明。
蛇足ながら、CWinApp::ProcessShellCommand() は仮想関数ではないから
オーバーライドは成立しない。( だから
>>964 は不可)
__argc と __argvのが好きだ
Win7RCで自作MFC GUIアプリ動かしたらどうもtheApp::OnIdleが呼び出されないっぽい どうやって解決したものか、自分で直接呼び出してもいいけど正式リリース版待ったほうがいいか
ウチでは呼び出されているが?
>>969 すげぇ、ヴァカすぎるwww
こんなヴァカでもプログラム組んでるのか。
もう少し勉強して出直してこい。少なくともOSのせいでOnIdleが呼ばれないとか、
そんな発想してるうちはダメだろw
>>970 少し突っ込んで調べたらちゃんと呼ばれてたわ
どうもOnIdle内で起こすイベント待機スレッドが起きてなかっただけだった これはこれで問題だが
>>971 今OSごとの動作チェックしてて7以外はまともに動いてたんだよ(・ω・)゙許せハゲ
MFCのSDIアプリケーションで、起動後最初の一回のみ自作のモーダルダイアログを表示したいのですが、 上手くいきません。 リソースエディタでFormViewのダイアログを作成編集し、それを右クリックして、 CDialogを基本クラスとしてクラス作成(仮:CMyDialog)をしています。 そしてCMainFormのヘッダにてCMyDialog MyDialog;と宣言し、 同OnCreate関数最後にて MyDialog.Create(該当ダイアログID,this); MyDialog.DoModal(); すると「Debug Assertion Failed!」という内容のダイアログが出て File:dlgcore.cpp Line:450 という内容が表示されます。Createを省略するとエラーダイアログは出ませんが、 何事も無かったかのようにDIALOGがまったく表示されません。 モードレスとして表示すろと(CreateしてShowWindow)SDIのフォーム内部に ドッキングした感じで表示されますがダイアログとして機能していません。 ただ単にアプリケーション開始直後にモーダルダイアログを出したいだけなのですが、 どうすれば良いのでしょうか? またダイアログ表示を仕込む箇所(OnCreate)は適切なのでしょうか? ネットで調べてもいまいち解決に繋がるものが見つかりませんでした。 また書いてある通りいやっても上手くいきませんでした。 どなたか教えてくださいよろしくお願いします。
974 :
973 :2009/08/20(木) 14:54:32
もう少し調べて見ました。 dlgcore.cppの450行目はすでにモードレスとして作られた物をモーダルとして 動かそうとしているという感じの内容っぽいです。やはりCreateは要らないのだと思います。 そして戻り値を見るとどうもIDOKがこっちが一切ダイアログ触ってないのに 返されてスルーされているみたいです。
>>973 ,974
>ただ単にアプリケーション開始直後にモーダルダイアログを出したい
>MyDialog.Create(該当ダイアログID,this);
>MyDialog.DoModal();
MyDialog.DoModal() が要らない。
MyDialog.Create() して、MyDialog.ShowWindow( SW_SHOW);
976 :
975 :2009/08/20(木) 15:05:55
>>975 あ、モーダルか。スマン。
MyDialog.Create(該当ダイアログID,this); が要らない。
977 :
975 :2009/08/20(木) 15:10:37
>>973 斜め読みしてたから、書き忘れた。
>起動後最初の一回のみ自作のモーダルダイアログを表示したいのですが、
メインウィンドウが表示される前に、メインウィンドウとの関連性がないものであれば、
CxxxApp::InitInstance() 内で表示すればいい。
978 :
973 :2009/08/20(木) 15:19:43
すばやい回答ありがとうございます。 しかし、ためしにAppクラスのInitinstanceの最後でDoModalでやってみましたが、 起動後本の一瞬だけやはりフォームの左上にドッキングしてはりついた感じでチラっと見えた後、 すぐに見えなくなりました。 しかしその後フォームをマウスクリックなどしようとするとモーダルダイアログが出ているときに 下の画面を触ろうとする時の「ポンッ」という音だけが聞こえるが一切操作できず、 相変わらずダイアログは見えていない状態になります。
979 :
973 :2009/08/20(木) 15:45:00
自己解決しました。 表示しようとするダイアログのプロパティのスタイルを「子」から「ポップアップ」 にすれば意図通りに動きました。 果たしてこれが正解は分かりませんが、こんな秘密コマンドみたいな仕様普通分かりません・・・。 ただ単にダイアログ表示したいだけなのに・・・。物凄い基本機能なのに・・・。
普通に説明見ながら作れば何の問題もないのに それさえもすっ飛ばして勘でやるからそういうことになる。 そんな基本中の基本もわからないで秘密コマンドとか笑われるぞ。
>ただ単にダイアログ表示したいだけなのに・・・。物凄い基本機能なのに・・・。 MFCというのは文字通り Foundation Class だから、WindowsAPIの上に分厚い化粧(=Foundation)を 塗りたくったものにすぎない。だから、MFCの基本はWindowsAPIにあって、 WindowsAPIによるWindowsプログラミングの基礎ができていないと使いこなすのは難しいかもな。 逆に言うと、WindowsAPIによるWindowsプログラミングの基礎をマスターしていると、MFCを解するのは すごく楽になる。
>表示しようとするダイアログのプロパティのスタイルを「子」から「ポップアップ」 >にすれば意図通りに動きました。 スタイルプロパティを「子」にして使うほうが用途的には少ないんだけど、なんで こんなところで躓くのかな? 不思議。
えーと、foundationて化粧じゃなくて基礎って意味。 化粧品におけるファンデーションてのは化粧の下地って意味だから、 MFC=化粧じゃなくて、MFC=基礎クラス。 まぁ、MFCは慣れれば強力だけど敷居は高いから、始めたばっかのヤシが ダイアログ表示するだけで「秘密コマンド」とか言い出すのも無理ないな。
MFCなんてカスみたいに簡単じゃん^^
>化粧品におけるファンデーションてのは化粧の下地って意味 ちょっと違う。ファンデーションのつきをよくするためにその下に塗るのが化粧下地。
ボタンのOnCtrlColorでブラシ指定してんのに再描画が遅い 色々悩んだ結果 UpdateWindow(); Invalidate(); とかやらないとすぐに再描画されないらしい と半日かかったw なんか俺、こういうのばっかだ
987 :
デフォルトの名無しさん :2009/08/20(木) 22:32:10
そのカスみたいなMFCについて質問です。 CMFCToolBar上のボタンをコンボに置き換えたいということで以下の様にコードを追加しました。 CMainFrame::OnCreate()にて if( !m_wndToolBarReplace.CreateEx( this, TBSTYLE_FLAT, WS_CHILD | WS_VISIBLE | CBRS_TOP | CBRS_GRIPPER | CBRS_TOOLTIPS | CBRS_FLYBY | CBRS_SIZE_DYNAMIC ) || !m_wndToolBarReplace.LoadToolBar( IDR_TOOLBAR_TEST ) ) { TRACE0( "ツールバーの作成に失敗しました。\n" ); return -1; } ・・・ m_wndToolBarReplace.EnableDocking( CBRS_ALIGN_TOP ); EnableDocking(CBRS_ALIGN_ANY); DockPane( &m_wndToolBarReplace ); ・・・ CMainFrame::OnToolbarResetにて UINT nToolBarID = ( UINT )wp; if( nToolBarID == IDR_TOOLBAR_TEST ) { m_wndToolBarReplace.ReplaceButton( ID_BTN_1, //先頭のボタンのID これを置き換えたい CMFCToolBarComboBoxButton( ID_BTN_1, GetCmdMgr()->GetCmdImage( ID_BTN_1 ), CBS_DROPDOWNLIST ) ); } とやってもボタンが置き換わらないのですが、他に何が必要なのでしょうか。 「ツールバー上のボタンを置き換える」についてのヘルプとMFCFeaturePackのサンプルについても見てみたのですが、 ボタンの置き換えについての手順はこれ以外に見当たらず、足止め状態です。 識者の方何とぞご指導くださりませ。
俺にはむつかしすぎる!
>>987 コード変更後にレジストリはクリアした?
してないなら一度すべて削除する。
>>987 おそらく
>>989 が正解。
CWinAppExをベースにしていると、LoadState / SaveState のおかげで
レジストリを削除しないとその後に変更した部分が反映されない。
>>989-990 レジストリですか。。クリアしてませんでした。
確かにツールバーの位置については最初から保持してるなぁとは思っていましたが。。
ありがとうございます。感謝!
>>991 ちなみに、CMainFrame::OnViewCustomize内でも置き換え処理してる?
ここでも置き換え処理しておけば、カスタマイズダイアログ上でもコンボボックスになるよ。
993 :
987 :2009/08/21(金) 00:29:45
>>992 OnViewCustomizeについては操作できないようにするつもりなので何もしていなかったのですが、
ついさっきテストプロジェクトで試してみたところツールバーもカスタマイズダイアログ上でも置き換えできました。
置き換えたコンボがDisableだったけど・・・ようやく一歩進めました。
感謝です!
MFCのツールバーはCControlBar派生でちょっと他とちがうんだよね CControlBarは独自のドッキングバー作るのに散々格闘したわ CDockBarとCDockContextのドキュメントをなぜ出さなかったMSめ( ´ω`)