BOOL OnInitDialog(void)
{
GetDC(m_hWnd)->DrawText("
>>1 乙", m_rect, 0);
}
nice _beginthreadex
リソースビューでダイアログにボタンを配置した場合、プログラム中でボタンの初期設定をするのはどこで行えば宜しいのでしょうか。 リソースビュー上で初期設定はできますが、マクロや使用者のスペックに合わせて内容を変更したい時に対応できず困っています。 ダイアログはクラス化され、初期窓クラスにメンバとして保有しています。 そのため自動的にダイアログが生成されるのですが、ダイアログのコンストラクタでボタンのテキストを変えようとするとエラーが出ます。
ダイアログ ボックスを初期化するときに特別な処理が必要な場合は、この関数をオーバーライドします。
>>5 ダイアログアイテム(ウィンドウハンドルを持つデータ)の初期化はコンストラクタではなくOnInitDialogでやるようにする。
コンストラクタの時点ではまだm_hWndが生成されていない。
8 :
5 :2008/04/05(土) 19:38:53
ありがとうございます。 いつもダイアログを生成した後に自前で初期化関数を呼んでいたのでソースがすっきりしそうです。
CSliderCtrlのSetSelectionで範囲を選択すると小さな点のようなものが表示されるだけで分かりにくいのですがもっと大きくならないのでしょうか。 プロパティを触っていると何故か中心の棒は太くなったのですが選択マークは目盛りに埋まって視認し難いままどうにもなりませんでした。 VC8を使っています。
>>9 亀レスだが
msdn2より
>作成時に TBS_ENABLESELRANGE スタイルを指定した場合にだけ、スライダ コントロールに選択範囲を表示できます。
>スライダ コントロールにこのスタイルが設定されていると、選択範囲の開始位置と終了位置の目盛りが
>垂直のダッシュではなく三角形で表示され、選択範囲が強調表示されます。
TBS_ENABLESELRANGEを設定するとスライダーバーは広がるのはVC8では何の意味もない。
以前はそこが強調表示されたがVC8では上記の通り三角形が強調表示。
VC8でも出来たらいいんだけど、俺も色々試したが無理だった。
質問しに来たら真上に答えがある幸せ。 しかしMSは何を考えて仕様を変えたのかさっぱりわからん。
12 :
デフォルトの名無しさん :2008/04/14(月) 23:00:47
Visual C++ 2008 Feature Pack Releaseが出たのに全然話題になってないねー まだ英語版だけだし・・・でも誰か感想よろ
13 :
hori :2008/04/16(水) 10:09:39
画像を表示するプログラムを作成していますが、、、。 ダイアログにピクチャーBOXを入れ APPWizardでメンバー変数追加しょうとしましたが 一覧にPICT1 が無いのです。( プロパテイではIDC_PICT1は入っているのですが) 。なぜなのでせうか?。。。m(__)m
よくわかんないけど ダイアログエディタの当該コントロール上で右クリックしてからメンバ変数として追加じゃダメなん?
15 :
hori :2008/04/17(木) 06:00:03
>プロパテイではIDC_PICT1は入っているのですが 見間違いしていました、、、、(-_-;) デフオルテでIDC_STATICをIDC_PICT1と見間違いしていました。。。m(__)m
16 :
hori :2008/04/17(木) 06:13:11
問題解決。。。ヨーソロー。。。^^
char str[100]="ABC"; CString cstr=(CString)str; テンパってるときに書いたコードなんだけど エラーにならないのはなんで?一時のCStringインスタンスが生成されて cstrにコピーされたっていう解釈でいいの?
>>17 ん。型変換コンストラクタ (CString::CString(LPCTSTR)) が呼ばれてる。
コピーコンストラクタだねぇ
20 :
デフォルトの名無しさん :2008/04/19(土) 01:11:25
VB6から移ってきたんだけどさ、MFCアプリのメモリ使用量ってバカでかくね? 一行もコード書かずにコンパイルしたプログラムが、6.3MBもメモリ食ってるし。 VBより酷い。なんかいきなり嫌になってきた。 MFC使わずにしこしこCreateWindowとかやった方がいいのか?
リリースビルドして出来た.exeを走らせてみればいい
>>21 リリースビルドしてもexeファイルサイズが小さくなるだけで、メモリ使用量はほとんど変わらないよ。
debug newじゃなくなる分多少はましにならないかな?
デバッグ版はメモリの前後にバッファオーバーフロー検出用の領域仕込んだりするが、 まあ微量っちゃ微量だな。 どうせ動的に確保できるメモリってあるブロック単位になっちゃうし。 スタック使用量は明らかに増えるが、 どうせスタックサイズはリリースかどうかで変える訳でもないし。
MFCは作成時点で既にいくつも機能を取り込むからなあ。 実装していくうちに、VB6もMFCも殆ど変わらなくなるんじゃね? てか、.NETでなくてわざわざMFCに来たんだか。 既存のC/C++のライブラリでどうこうしたいなら非常にお勧めだが、 逆に、そうでないなら全くやる理由がない。
>>25 .netは金取る製品を作るための開発環境じゃないから。
あれはサンデープログラマのお勉強用。
作るのは楽だけど、起動が遅くて動作もモッサリしてるのでダメ。
それは作り方が悪いだけだと思います
よく知らないけど起動ごとに機械語解釈通してしまう可能性があるから遅い、らしいけど どうにかなりそうなのにね ダメなんかな
x86のMFCをWOW64上で動かすときと、 CPU対象がAnyでJITコンパイル済みの.NET(WinFormあるいはWPF) どっちが速いんだろ。 もっとも構造や機能がまるで違うものを単純比較しても意味ないけど。
30 :
hori :2008/04/21(月) 14:05:54
OS XPに”Visual C++ 6.0 Professional”をインストールしたら まずい、、、でしょうか? ^^;
^^;
32 :
hori :2008/04/22(火) 00:55:35
ぐぐって見ました。 、、、、やはり、、。。^^;
はいはい
34 :
デフォルトの名無しさん :2008/05/04(日) 21:57:35
ダイアログベースのアプリを作成しています。 リソースエディタにて複数のダイアログの画面を作成し、 任意のタイミングで表示されるダイアログを切り替える機能を実装したいです。 具体的には、IDD_DIALOG1とIDD_DIALOG2という画面を作成し、 アプリ起動時はIDD_DIALOG1が表示されるのですが 指定したチェックボックスの状態を有効にすると 画面がIDD_DIALOG1からIDD_DIALOG2に切り替わる、 といった動作を想定しています。 何か方法はありませんでしょうか。 ちなみに開発環境はVC++6.0@Win2kです。
チェックボックスイベントでDialog1を通常終了させて呼び出し元(WinApp派生のやつあたり)がDialog2を呼び出せばよいのでは。 Dialog1の状態パラメータ等を取りたいならDoModalオーバーライドの引数として&参照で構造体バッファ渡すなり 単純な数値だけ欲しいならDoModalの返値としてIDOK等ではないものを返せばいいし。 とりあえずフレーム+ビューにしろダイアログにしろWinApp派生から呼ばれてるから そいつに管理させればカンタンである
>>35 レスありがとうございます。
つまり、イメージ的にはDialog1とDialog2それぞれ別のプログラムを作って、
プログラム終了時にお互いを呼び出す、というイメージでしょうか。
お互い、だと
お互い、だとDialog1と2が相互に呼び出し合うみたいに聞こえるけど Dialogオブジェクトを生成してDoModalするのはあくまでAppのメインさんね
タブコントロールを使ってページを切り替えるようにした方が良いんじゃないかなあ。 チェックボックスでダイアログ自体が入れ替わるUIは、一寸前衛的すぎる気がする。
しょちゅう切り替えるんならタブが便利かもしれないけど 初心者モード、エキスパートモードみたいに たまにしか切り替えない場合はタブは邪魔なだけ
>>39 自分もチェックボックスで画面が変わるというのは標準的ではないと思う。
やりたいことがよく分からないけど、チェックボックスの代わりにボタンじゃあかんの?
その方が標準的と思う。
42 :
41 :2008/05/05(月) 09:54:03
あっ、もちろんタブで問題なければタブの方がいいと思うけど。
>>36 別のプログラムではないよ。
35、38は1つのプログラム内でWinApp(アプリ管理クラス)が切り替えをする案。
43 :
41 :2008/05/05(月) 10:15:22
ちょっと訂正 ×WinApp(アプリ管理クラス)が ○CWinAppクラスの派生クラス(C+プロジェクト名+Appクラス) C+プロジェクト名+App.cppの下のほうにあるDoModalの辺りで処理するという話っす
コントロールの無い親ダイアログ(DoModal)に、 子ダイアログDialog1,Dialog2(Create)を貼り付ける
タブコントロール部分無しプロパティシート(&リソース定義済みページ複数)という荒技もある
AfxBeginThreadで作成したワーカースレッドから別のプログラムを呼び出しています。 このプログラムにはハンドルリークが有ることが分かっていますが、その場合呼び出し 元のプログラム(スレッドを作成したプログラム)でハンドルが増加し続けたりするのでしょうか。
>>46 いいえ、それだけなら「別のプログラム」のハンドルがリークするだけで「元のプログラム」のハンドルはリークしません。
勿論、適切なプログラムであるとの前提ですが。
# ありがちなのは、スレッドハンドルをクローズし忘れているケースですが……
## そもそもなんでCreateProcessを使わないのかとか、TaskManagerでハンドルの数を観測しろとか。
複数のダイアログを作成し、お互いのクラスが保持しているメンバ変数や関数を 使いたい場合は「〜App」のメンバ変数にクラスのオブジェクトを作成するのが普通ですか? 例えば、CDialog1、CDialog2と言うダイアログとクラスを作成し、 CDialog2からCDialog1のメンバ変数と関数を使いたいのですが。
Appのメンバ変数としてDialog派生クラスのオブジェクト、あるいは動的にnewしたものを保持するためのポインタを持っておいて Appのインラインメンバ関数として「Dialog派生クラスのポインタ(あるいは参照)だけくれる関数」を作ればよいのでは。
publicじゃだめなの?
そもそも自分ならそういう設計は避ける。
MFCでMDIアプリを作っております。 そこで困ったことがあり質問させていただきました。 あるアクティブな一つのウィンドウをViewクラスに属しているメニューコマンドで メニューを選択したらアクティブMDIの子ウィンドウを最大化したいのです。 メニューコマンドを選択したら自動的にアクティブなウィンドウに対してコマンドが 実行されると思っています。 コマンドを追加した関数から「ShowWindow( SW_SHOWMAXIMIZED );」を 呼んだのですが最大化しそうな動きが一瞬するのですが、子ウィンドウが最大化表示しません。 最大化の方法が間違っているのでしょうか? 実現方法をよろしくお願いいたします。
つ CMDIChildWnd::MDIMaximize
54 :
52 :2008/05/11(日) 03:37:32
>>53 ありがとうございます。解決しました。
CMDIChildWndをヘルプを見ましたらクラスメンバでvoid MDIMaximize();を見付けました。
ヘルプでのMDI子ウィンドウフレーム派生クラスの親クラスを見ていませんでした。
今回の件で解決方法を調べるのにネットの方ばかり探していました。
「MDIMaximize」でググると検索で欲しかった情報が出てきました。
Viewクラスからの呼び出しているコマンド内では、以下の通りでMDIMaximize()を呼びました。
CChildFrame *pChildFrameWnd = (CChildFrame *)GetParentFrame();
pChildFrameWnd->MDIMaximize();
この処理を追加しましたらMDI子ウィンドウのタイトルバーの最大化ボタンをクリックしないで
MDI子ウィンドウを最大化する事ができました。
重ねてありがとうございます。
リソースビューでタブを作った場合、その中に表示するコントロールは自分で用意(Create等)しなければならないのでしょうか。 全てリソースビューでやろうとすると、全てのタブに表示されるべきコントロールが同じ場所に表示されてしますので扱い辛く・・
プロパティシートかな
リソースビュー使わずに直接.rcファイルいじるとか、 リソースビュー上はバラバラだけどプログラム上の初期処理で位置変えるとかもある
別ウィンドウに作っておいてタブを切り替えたときにウィンドウごと張り替える。 # それやるくらいならプロパティシートかな。
59 :
55 :2008/05/11(日) 19:35:03
レスありがとうございます。 色々なアプローチの仕方があるのですね。
60 :
デフォルトの名無しさん :2008/05/14(水) 16:46:33
VC6で印刷処理を作っています。 印刷ダイアログを表示せずにデフォルトのプリンタで印刷するときの前後処理は こんな感じのやり方でよろしいのでしょうか CPrintDialog dlgPrint(FALSE); VERIFY(dlgPrint.GetDefaults()); CDC dc; VERIFY(dc.Attach(dlgPrint.CreatePrinterDC())); (印刷処理) dc.DeleteDC(); GlobalFree(dlgPrint.m_pd.hDevMode); GlobalFree(dlgPrint.m_pd.hDevNames);
実行出来たらそれていんじゃね?
62 :
デフォルトの名無しさん :2008/05/15(木) 13:48:03
>>61 メモリを解放しないといけないかと思いまして
63 :
デフォルトの名無しさん :2008/05/15(木) 16:22:21
別にどっちでもいいんですが。。 当方、6年位前に貧乏でして、VisualC++スタンダード版を何とか買いました。 その後、JavaやPHPで食いつないできたんですが、今になって当時買った本とか読んで WindowsAPIやらMFCやら勉強したら面白くてだいぶ身についたんですが、 今は.NETFrameWorkで動くCLRというのがもっぱららしいんですが、私はぜんぜん知らないし 大体環境をもってません。まあ無料でダウンロードできるらしいんですが。 私みたいのでも就職口ありますかね?別にJavaやPHPでくっていけるんでいいんですが 一度仕事でもVC++やってみたいですし。 よろしくお願いしますm(_ _)m
>>63 --
別にどっちでもいい
んですが。。
当方、6年位前に貧乏でして、VisualC++スタンダード版を何とか買いました。
その後、JavaやPHPで食いつないできた
んですが、
今になって当時買った本とか読んで
WindowsAPIやらMFCやら勉強したら面白くてだいぶ身についた
んですが、
今は.NETFrameWorkで動くCLRというのがもっぱららしい
んですが、
私はぜんぜん知らないし
大体環境をもってません。まあ無料でダウンロードできるらしい
んですが。
私みたいのでも就職口ありますかね?別にJavaやPHPでくっていけるんでいい
んですが
一度仕事でもVC++やってみたいですし。
よろしくお願いしますm(_ _)m
--
そもそも鼬害だし、望み薄だと思う
んですがw
>>63 結局、訊きたいのは
>私みたいのでも就職口ありますかね?
これか?
ここ、そゆこと訊くスレに見える?
>>65 どうでもいいそうだから、質問にさえなってないと思われ。
67 :
デフォルトの名無しさん :2008/05/15(木) 18:25:12
うんこ♥
シングルウィンドウの×ボタン(閉じる)を押したとき『終了しますか?』といったダイアログを出したいのですが、どこに記述すれば宜しいのでしょうか。 〜ViewのOnDestroyやメッセージでWM_Destroyを関知したときにwhile(1)で無限ループさせても終了してしまいます。 OnDestroyを通った後にOnCloseは通らず、×ボタンを押したときウィンドウを閉じさせないという選択肢をどこで作ればいいのか・・。
OnClose
ありがとうございます。 なるほど、Viewで無限ループさせてもFrameが閉じられるのでアプリケーション自体が終了していたのですね。
73 :
あは〜ん :2008/05/19(月) 18:54:12
あは〜ん
MFCでアプリケーションを作っています。 質問なのですが、 エクセルなんかのカラー選択のコンボボックスの動きを実現させたいのですが、 コンボボックスの内容をオーナードローで描画するのは出来るのですが、 あの色サンプル(コンボボックス押すと出てくるリスト)はどのように作るべきでしょうか。 CColorDialogとかではなく、あの30色ぐらいのパレットがほしいのですが。
>>74 このへん?
CMFCColorButton
>>75 レスありがとうございます。MFCと書いてあるということはVS2008版ですよね。
残念ながら、当方VS2003なのです。
エクセルのパレットがそのままの形ででもあれば・・・。
78 :
77 :2008/05/25(日) 08:36:46
>>76 MFC→VS2008じゃないよ。2008EEにはついてないし。
逆にVS2003には必ずついていると思われ。
「CColorDialogとかではなく」ってことは77はNGか orz
>>77 >>78 レスありがとうございます。
MFCと書いたのはCMFCColorButtonのことでした。略して分かりにくしてすいません。
http://up.cgi.jp/mek3 ↑作りたいのはコレなんです。これをチョコチョコ改変して作りたいのです。
やはりダイアログを作成して、CBitmapButtonでサンプル色ボタンを作って貼り付けて、
テキストリンクのところはCButtonの枠線なしとかで対応するのでしょうか。
80 :
77 :2008/05/25(日) 14:22:21
失礼。CMFCColorButton は2008にしかないってことでしたか。 う〜ん。やっぱり79のような感じなんですかね。
エクセルのはただのツールバーだろ
82 :
74 :2008/05/25(日) 19:22:25
>>77 レスありがとうございます。
形状的にはそうするのが一番形になるような気がします。
>>81 レスありがとうございます。
えっ?!コンボボックスの中身をツールバーにするのですか?
ちょっとイメージがつきません…。
>>82 ツールバーの中にコンボボックスがあるんだろ。
85 :
74 :2008/05/25(日) 20:22:12
>>83 レスありがとうございます。
おお、これです。コレがしたかったんです。ありがとうございます。
英語ばかりですが、サンプルコード読みながら何とか紐解いてみます。
サンプルプロジェクトコンパイルしたらエラーしますがorz...
このサイト、Japanizeでちゃんと自動翻訳してくれるんだな・・・メニューくらいだけだけど
JapanizeじゃなくJapaneseだろ! …って書き込もうと思ったんだが、ググったらそういうソフトがあるのな。自動翻訳の。
デバッグモードだと _DEBUGが定義されてるように MFCだと 定義されてるやつってありますか?
_MFC_VER
VC6、MFC、ダイアログベース ダイアログ上にCStaticを配置して、そこにJPG画像を表示しています。 JPG表示領域に別のWindowが重なったりした場合に、それをどかしても 重なっていた部分だけ表示が消えた状態となってしまいます。 自分自身が最上位に来たときに再描画するようにすれば良いと思うのですが 何のMessageを捕まえればよいのでしょう?
画像を設定した後、さっさとハンドルを破棄してしまっている予感。
ダイアログベースならデフォルトで再描画あるじゃないか
OnPaint を理解してないと思われ
2008SP1が出たら購入を考えているのですが、 タブMDIやリボンバーを実現するクラスの仕様や構成をご存じの方いますか?
Dialog::WindowProcがダイアログが非アクティブだと呼ばれないのですが、 非アクティブ時も処理したい場合、どのように書けばよいですか?
メッセージが来てないだけだろ
メッセージが来るようにしたい場合、どのように書けばよいですか?
そもそもどんなイベントが欲しいんだ?
DIJOYSTATE2.rgbButtons[]の状態を常に監視して、 ボタンが押されたら任意に設定したキーイベントを発生させたいんです。
普通は非アクティブウインドウにキーイベントは来ない できないこともないけどMFCとは関係ない
MFCやWin32APIに関して初心者なんだけど、だれか助けてくれたりしないかな。 MFCでSDIアプリを作っている。CMainFrameのメンバにCDialog m_toolDlgを保持して、 モードレスで実体化させている。 やりたいことは、モードレスダイアログ m_toolDlg のあるボタンが押されたときに、CHogeViewの向けて メッセージ(?)を飛ばしたいのだけど、どういう枠組みを用意してやって、どういうメソッドを使ってやればいいのか わからない。 どうも体系的に知識が不十分なのは分かっているのだけど、今時MFCの資料が無くて困っている。 だれかアドバイスをくれないだろうか。
CFrameWnd * pFrame = (CFrameWnd *)(AfxGetApp()->m_pMainWnd); CView * pView = pFrame->GetActiveView(); あとはSendMessageするなりキャストして直接関数呼ぶなり好きにしろ。
>>103 早速ありがとう。示してもらったとおりに SendMessage(WM_COMMAND, ID_XXX, 0) としたら、
Viewがうまく反応した。
感謝
メッセージの受け方は、自動生成される他の関数を参考にしてみろ WM_PAINTならOnPaint()みたいな感じで
ユーザー定義メッセージ あたりでググるとよい。
afx_msg LRESULT OnXXXXX(WPARAM wParam, LPARAM lParam); ON_MESSAGE(WM_APP+n,OnXXXXX) とかだね OnCommandとか直に呼ぶと、まずい場合もあるから↑書き方も覚えておくと良いかも
アクションゲームの様な物を想定して、毎秒30フレームの画面更新を行いたいのだけど、MFCで書くにはどうすればいいのだろう? もちろん、一番手軽なのはWM_TIMERで処理することだと思うけど、精度が低いので保留。 OnIdleをハンドリングして、中でtimeGetTime()を使って適切な時間をカウントしてやる方法も試してみたんだけど、こちらは常にCPUを100%使い切ってしまうのが厳しい。 実行している処理内容は大した負荷ではないはずなのに、CPUを使い切ってしまうとユーザがいやがるし、美しくない。 できれば、この両者の間ぐらいが方法が欲しい。つまり、まずまず精度が高くて、CPU使用率がむやみに100%に振り切らない方法。 自分はMFCやWin32APIの初心者なんだけど、何かいい企てや情報はないだろうか?
別スレッドでSleepやWaitableTimerで1/30毎にSendMessageするとか。
111 :
デフォルトの名無しさん :2008/06/04(水) 22:21:07
質問だけど、MSDNにはCFileのwriteはバッファリングしないって 書いてあったんですけどCFileのwriteとfwriteってどちらが速いですか? また、それ以外にも速いファイルライト関数ってありますか?
自分で試して違いがわからなかったら気にする必要ないだろ
速度程度なら、ループさせてGetTickCount()あたりでも計測すればいい
114 :
デフォルトの名無しさん :2008/06/04(水) 23:41:51
質問です。 WindowsXPでVS2005なんですけど、CFileDialog等のコモンダイアログって リソース上の文字列(“開く”とか)は実行環境に合わせ勝手にローカライズ されませんよね? 環境に応じて表示言語を変えたい(少なくとも日本語←→英語の切り替え)を やりたいんですけど、リソースIDとかがわからず、どこをどう触ればいいのか 途方に暮れてしまってるんですが、何かセオリーってありますか?
ローカライズの切り替えは知らないけど、リソースIDはふられていたはず ダイアログ自体書き換えれるし
数年ぶりにMFCに戻ってきたんだけど いつのまにか、テンプレート クラス用のメッセージ マップなんて 作られたんだね。結構使われてるのかな?
117 :
114 :2008/06/05(木) 00:17:00
>115 レスありがとうございます。 ちなみにコモンダイアログのリソースIDはどこで確認すればいいのでしょうか? 目ぼしいドキュメントが見つからなくて、てっきりリソースIDは無いものだとばかり・・・
>>112 ,113
わかりました。結局あなた達も知らないのですね。
>速度程度なら、ループさせてGetTickCount()あたりでも計測すればいい
そんなしょぼい精度の計測はせず、QueryPerformanceCounter()で計測します。
なんという恥ずかしいレス
MFCは一定間隔の更新に弱く、MFCの表示周りの更新を行うと内部で勝手にウエイトが入るんだよな。 別スレとか方法としてはいくつもあるけど正確な更新をするのであればMFCベースでやらないほうがいい。
動画再生ぐらい余裕でできるだろ
>>117 Dlgs.h の中の edt1 とかの値が使われている。
>>118 fpsの調節をするためにビジーループでQueryPerformanceCounterを呼び出していると、
環境によっては数秒に一度関数からしばらく戻って来ないでフリーズする現象が発生します。
動画の再生なんて、アバウトでいいのよ 30 fps をきっちり正確に表示する必要は全くない 人間の目なんて、数コマ落ちしようと時間間隔が多少 ずれてもわからんのよ よって、秒単位に適当に切り捨てればよい
125 :
デフォルトの名無しさん :2008/06/05(木) 20:54:18
MFCの中でオーバーライドされてる関数の元の関数を使いたいんですが、どうやるんでしょうか? LRESULT SendMessage( HWND, WPARAM , WPARAM, LPARAM ); これを使いたいんですが、HWNDがない方になっちゃいます。 ::つけるようだった気がするんですが違うみたいでした。
あってると思うけどな。
>>125 それはオーバーライドとは言わない ただのAPIをCWndオブジェクトに対してのみ便利メンバ関数として用意してるだけ
頭に::をつけるというのは、グローバルな関数や変数を指定してるだけだからな 頭にクラス名がついていない代わりだ ていうか、自動補完が動いてないだけで、書けばコンパイルはとおるだろ?
とおらないんじゃないだろうか。
SDI(ドキュメント無し)のMFCアプリで、Viewウィンドウサイズを指定(800*600)して起動させたいのだけど、やり方がさっぱり分からん。 やりたいことは、指定の画像(800*600)をビューでピッタリ描写すること。 いや、CMainFrame::PreCreateWindow()でcs.cx, cs.cyを設定すればいいのは分かるんだけど、ここに800, 600と入れるとウィンドウサイズが800,600になって、Viewの描写領域のサイズはメニューやツールバーに削られた小さな領域になってしまう。 メニューやツールバーの領域をあらかじめ計算して大きめのウィンドウサイズを指定する方法があるけど、それはあまりにスマートじゃないので、何かベンツのやり方はないだろうか?
GetMatrixHogehoge(名前忘れた)で、タイトルバーのサイズとかをあらかじめ取得しておいて、 そいつらの高さや幅をあらかじめ加算しておけば? メニューやステータスバーのサイズはあらかじめわかるだろうし
メニューが二段とかの例外を気にしないならAdjustWindowRect
>>131 , 132
情報ありがとう。教えてもらった情報を試してからまた報告に来ます。
そのテのはネットで結構あった気がする
AdjustWindowRectを試してみたけど、ツールバーとステータスバーの領域は考慮してくれなくて、 その部分は自前で算出してやらなきゃいけないみたい。
MFCの勉強をしようと思ったら何からはじめたらいいの? WinAPIではガリガリ組めるレベルだ。
Win32がそのくらいのレベルあるなら、かなり楽かもなー 逆に隠ぺいされすぎて、ムカつくかもしれないけどw とりあえず、MSが配布してるサンプル読んで理解して、あとは適当に自力で作ってみたらいいんじゃないかな
まずはダイアログアプリから始めて、基本的な GUI の 実装を一通り経験すべし その後にドキュメント/ビュー に進むがよい
>>137 隠蔽されすぎてるのかw
わかった取りあえず、サンプル読みまくるよ。
ところで、MFC自体のソースって公開されてるの?
関数名がそのままだけど、第1引数のハンドルとかが、クラスに隠蔽されていて、なかったりする たしかに、先にダイアログから手をつけるべきだな サンプルは公式にあったと思う
個々のクラスで見ると、素直にクラスで包んでるだけだよ。 後はそれにアプリケーションレベルの仕組み(Doc/Viewとか)があるくらい。 コマンドメッセージとかはちょっと複雑なルート辿るけどね。
みんなありがとう。 ダイアログから読んでいろいろやってみるよ。
確かに、目の前にハンドルがあるとついついクラスのメンバ関数じゃなくてAPI呼びたくなるよな。 ハンドルを意識する必要が全くなければいいんだけどね。
VS2005のMFCで作ったexeファイルが 別のPCで起動させた際に不正なファイルとでて起動できませんでした プログラムを組んだPCではきちんと起動するのですが原因がわかりません 原因についてわかる方、教えていただけませんか PCのOSは両方ともWinXP Pro SP2です VS2005は片方にしか入っていません よろしくお願いいたします
インストーラ作れよ
ヘルプを見よ
>>149 ありがとうございます。
そこに書いてあるように「マルチスレッド MT」に変えると
ビルドする際に
c:\program files\microsoft visual studio 8\vc\atlmfc\include\afxver_.h(77) :
fatal error C1189: #error : Please use the /MD switch for _AFXDLL builds
といったエラーがでるようになってしまいました
解決方法がわかれば教えていただけませんか
>>150 >解決方法がわかれば教えていただけませんか
>Please use the /MD switch for _AFXDLL builds
152 :
デフォルトの名無しさん :2008/06/12(木) 00:11:07
VS2005でStdioFile::ReadString()関数を引数をCString参照で使っているんだけど、 何行かread(大体1000行ぐらい)していると、stringのバッファサイズが何とかという 実行時エラーが出てしまいます。何か対策はありませんでしょうか。
何とかって何?
改行文字で止まるのに1000行とはなんぞや
155 :
152 :2008/06/12(木) 07:05:45
>>153 154
今ソース、環境が手元に無いので詳細は今日帰宅したらまた書きます。
CStringの上限は2GBぐらいだろ
m_timerID = SetTimer; ↓ OnTimerでInvalidate(FALSE); ↓ アニメが終わったらKillTimer(m_timerID); ピクチャーコントロールにビットマップを表示してるダイアログで これでアニメーションをしてると、 タイマー開始するたびに4Kずつ使用メモリが増えていきます なぜでしょうか
知るかよ お前んとこのバグに決まってるだろ
>>157 m_timerIDって解放しなくてよかったっけ。
時計の電池を抜いて止めても時計の本体は残っている状態のような。
>159はキチガイだから無視で
161 :
デフォルトの名無しさん :2008/06/12(木) 22:29:14
CStaticにCBitmapの画像を貼り付けたいのですが、リソースからは上手くいっても メモリ上からは失敗(何も描画されない)します。 どうするのが適切なのか、教えてください。 //// リソース読み込み CBitmap m_bmp; // メンバ変数 m_bmp.LoadBitmap(IDB_BITMAP); CStatic *pPicture = (CStatic *)GetDlgItem(IDC_STATIC_IMAGE); pPicture->SetBitmap((HBITMAP)m_bmp); //// メモリ読み込み CBitmap m_bmp; // メンバ変数 BYTE m_buf[300]; // メンバ変数 bmpの各ピクセルの色データ配列 m_bmp.CreateBitmap(10, 10, 1, 24, m_buf); CStatic *pPicture = (CStatic *)GetDlgItem(IDC_STATIC_IMAGE); pPicture->SetBitmap((HBITMAP)m_bmp);
水平方向のバイト数が4の倍数じゃないから? m_buf[(10*24/8+7)&~3*10];
>>162 元のは横240*縦240*3バイトだったのを編集したときに4バイトアライメントを失念してました。
すみません。
CreateBitmapでいけることはいけるんでしょうか?
m_bmpのデストラクタで破棄されたらそれまで。描画されなくて当然。 Windowsのハンドルは参照カウンタで管理されているわけではないので注意しる。
その辺まともに理解してないと、メモリリークとかもやらかしそうだな
166 :
161 :2008/06/13(金) 19:45:30
自己解決。 リソース読みのm_bmpを使い回して、32bppに変換したデータをSetBitmapBitsすることで表示されるようになった。
どのへんが自己?w
あえてWin16時代の名残りであるSetBitmapBitsを使うところが渋いな。 まあ、直接イメージを弄るなら普通はCreateDIBSectionを使う。 MFCならCImageだな。
MFC に CImage なんかあるかよ
あるある
VC++6.0で時間が止まってる人なんだろうな
MFC じゃなくて ATL だろが
CImage の中身は GDI+
GDI の BitBlt はハードウェアを使うので早い GDI+ の BitBlt はソフトウェアのみで処理するので遅い
Vistaではどちらもソフトウェアになるけどな
そういえばGDI専用のスレってないんだな この手の話するならここかWin32になるのか?
FTP転送経過情報(転送サイズ)がわかるFTPクライアントを作成したいです。 FTP転送状況を取得するにはOnStatusCallbackをオーバーライド する、とのことだったのでマニュアルを見たのですが、 ▼▼▼ OnStatusCallback (DWORD dwContext, DWORD dwInternetStatus, LPVOID lpvStatusInformation, DWORD dwStatusInformationLength) dwInternetStatus コールバックの理由を示すステータス コード。指定できる値については、後の「解説」を参照してください。 lpvStatusInformation このコールバックに関する情報を格納しているバッファへのポインタ。 ▲▲▲ 上記の引数によりファイルの転送済みサイズとかが取得できるように なるのかなと思ったのですが、マニュアルにはそれらしき記述はありません でした。 OnStatusCallbackの中でどのような処理をすれば転送済みファイルサイズとか 取得できるのでしょうか。 ご教示のほど、よろしくお願いします。
>上記の引数によりファイルの転送済みサイズとかが取得できるように >なるのかなと思ったのですが なんでそんなこと思ったの?
FTP転送状況を取得するには、 OnStatusCallbackをオーバーライドして、FTP転送状況を提供 してやるってことじゃねえの? でなきゃ、オーバーライドする意味ないし。
転送状況を取得したいのは判る。MSDNにも取得できると書いてある。 しかし、転送済みサイズが取得できるとはどこにも書いてないし、そもそもなんでそんな発想できるのかと。 # 要は、私もOnStatusCallbackで転送済みサイズが取得*できない*とは確認していないのだけどね。
転送状況のステータスはとれても転送済みサイズは取れないってことですかね。 FTPコマンドとかフリーのFTPソフトで転送経過(%)が表示されているのってどうやってるんでしょうね。
適当なバイト単位で読む
>>181 そりゃぁあんた、FTPクライアントがMFCを使う義理なんてないからねぇ。
ダイアログについて質問です。 ダイアログの中のstatic textを変更したいのですが、SetDlgItemTextを呼ぶとassertで止まります。 assertはm_hWnd=NULLが原因です。 しかしCDialogの中のCWnd周りは勝手にやっているので、nullは仕様かと思われます。 m_hWndを必要としない、static text変更の命令はどれに当たるのでしょうか? またはMFCはそういうことが出来ない仕様なのでしょうか?
いつもは GetDlgItem(hoge)->SetWindowText() でやってるな ちなみに、それを呼び出しているタイミングは? OnInitDialog()とか?
とりあえずメンバ変数に入れておき、OnInitDialogかDoDataExchange辺りで 生成されたウィンドウに対して設定するというのが一般的なやり方。
VC7のプログレスバーでマーキースタイルを実装する方法は有りませんか? VC8と9は重すぎて使用に耐えません。。。
VC2008SP1ってリリース予定っていつくらいになるか発表してましたっけ? 夏くらいとも聞いた気もするけど自信がない
>>187 CProgressCtrl::Createで直接スタイル指定して作れないか?
リソーススクリプトを直接編集してもいいけど、IDEで弄ったらたぶん消える。
190 :
デフォルトの名無しさん :2008/06/19(木) 02:41:15
ダイアログベースで終了時の処理を行いたいのですが、 OnDestroy()が自動生成されないのですが、これって自分で作らないとだめなんですか? ためしに自分で virtural void OnDestroy()でオーバーライドしてみたんですが、 OnDestory()内にコード書いても動作してくれません。
OnDestoryはちゃんと呼ばれる
192 :
184 :2008/06/19(木) 15:45:20
>>185 試してみたのですが、GetDlgItemも内部でm_hWndがnullだとassertにヒットするので出来ませんでした。
呼び出すタイミングはOnInitDialogでやっています。
もうちょっとしたら別のとこでもやる予定ですが、今は初期値を入れているだけです。
>>186 設定をしようとすると、m_hWndがnullのため設定出来なくて困っています。
自前でダイアログを呼んで返り値のハンドルを保存しているならいいのですが、MFC側で隠蔽され何故か保存されていないため、どうしたらm_hWndに値を入れられるかというのが一番悩んでいるところです。
GetDlgItemで存在しないものを呼んでるんだろ
>>192 普通はちゃんと入っているよ
そもそもWM_INITDIALOGメッセージを送るのにもウィンドウハンドルは必要だろ?
土地を買う → 家を立てる → 家具を買う いきなり家具を買われても困るだろ
>>192 >呼び出すタイミングはOnInitDialogでやっています。
が、CDialog::OnInitDialog を呼ぶ前でした、というオチを想像した。
たしかにそのタイミングだと、コントロールにメンバ変数を割り当ててあっても、 CDialog::OnInitDialog → UpdateData → DoDataExchange が呼ばれる前だから、まだNULLの状態になるな。
OnInitDialog()でWM_APP_XXXメッセージを自分にポストして遅延処理する。
199 :
192 :2008/06/19(木) 20:24:32
CDialog::OnInitDialogを呼ぶ前でした>< 皆さんありがとうございます。
あほ
大体そんなことだろうとは思ってたw
>>190 message_mapにon_wm_destroy定義してある?
自分で記述しないで、どのバージョンか知らんがVSにまかせたら?
ドキュメント・ビューアーキテクチャを利用して常駐型アプリを作成したいと考えています。 内容を簡単に説明すると、一つのデータベース(自作)を参照する複数のビューがあり、 それらは同時に表示可能であるといったものです。 ただ、常駐型なのでタスクバーに表示されないようにしたいのと、外見上メインフレームの みを非常時にしていのですが、メインフレームを非表示にすると、それのビューまでが非表 示になってしまいます。 メインフレームとビューの表示・非表示を個別で制御することはできないでしょうか?
>>203 メインフレーム以外のフレームつくればいいんでねえの?
子ウインドウは親にひっついてるから 独立したウインドウにして切り離すしかない
206 :
デフォルトの名無しさん :2008/06/22(日) 18:30:31
複数のダイアログで同じ内容のコントロールを使うときはどうすればいいんでしょうか?
>>206 複数のダイアログに同じ内容のコントロールを使うことで、何が問題となるのかわからん。
>>207 ダイアログを作るたびにコントロールの初期設定とかで同じ処理を何度もコピペして書いて、
修正するときは同じ部分を全部書き直すのが無駄な気がして、もっと楽にできる方法がないかと思って。
コモンダイアログ
>>208 "同じ内容のコントロール"を持ったダイアログを基底クラスとしてつくって、
そっから派生させたらどうだ?
VC8でマウスの右ボタンを押しながらツールバーのボタンを左クリックすると落ちるのですが解決方法はあるのでしょうか。 プロジェクトを作った直後にビルドし、ツールバーにある印刷ボタンなどを押すと落ちました。 自分で置いたツールバー(CToolBar)も同じ状態です。 今までのバージョンでは確認出来ないのですが、VC8では何か処理を噛まさないといけないのでしょうか。
プログラムに問題があったのに今まで偶然に動いてただけかもしれないけど VC側のバグを疑ってるならサポートに聞くしかない
>>210 その場合MESSAGE_MAP・DoDataExchangeのリソースIDはどうすれば良いでしょうか?
> 205 ということはCMDIFrameWndをそのまま使用して実現することは出来ないということでしょうか?
みんな結構SP1Beta入れてるのか 正式版待った方がいいと思って粘ってるんだけど、なんか羨ましいな
Picture Controlで Type四角形にした時の プログラムでの 色の変更ってどうすればいいですか?
四角形のまま色変えるにはサブクラス化するしかないんじゃないかな。 オーナードローにするか、テキストのスタティックにしてOnCtlColor使うかするといいかも。
ってもしかして白黒灰の範囲内の話?
直接描画したほうが早い予感
MFCでアプリケーションハンガリアン記法使うときって、どんな感じにしてますか? APIがシステムハンガリアン記法なんで、色々書きづらいと思うけど
224 :
デフォルトの名無しさん :2008/06/27(金) 18:24:55
コンボボックスからユーザーが入力した値を取得するにはどうしたらいいでしょうか? m_Combo.GetLBText(m_Combo.GetCurSel(),str); だと取得できませんでした。
コンボボックスのスタイルにもよるんだけど、通常のエディットコントロールが乗ってる ドロップダウンスタイルのエディットコントロール部分が欲しいの? もしそれなら、GetWindowtext()で。
sp1 にある MFC FeaturePack はなかなかのもんだ 大幅なバージョンアップだな
んで、sp1 はいつよ?
βはもうでてる
むしろSP1入れて始めて2008の意味があるだろう VCにとっては
シングルウィンドウについて、親を指定せずに作ったウィンドウやダイアログからCMainFrmは取得できるのですが、 C〜Viewは取得できないのでしょうか。 CMainFrmのメンバクラスかと思ってたのですがそうではないですよね。
ViewはChildFrmの子供じゃなかったっけ
viewを取得するメンバ関数があるだろ
234 :
デフォルトの名無しさん :2008/06/28(土) 20:54:22
MFCのソースを読んでみようと思ったんだが、 どれから手をつけていいのかわからん。 どれがいい?
必要になった部分だけ拾い読みするから愛読してる部分はない
236 :
デフォルトの名無しさん :2008/07/01(火) 14:16:59
MFCのリッチエディット2.0について質問させていただきます。 MFCのダイアログベースでプロジェクトを作成 ↓ プロジェクトのプロパティで「マルチバイト文字セットを使用する」を「Unicode文字セットを使用する」に変更 ↓ エディットボックスとリッチエディット2.0を適当に配置 ↓ エディットボックスとリッチエディット2.0それぞれにコントロール変数を追加 ↓ InitInstance()内に AfxInitRichEdit2(); を追加 ↓ あとは適当なところでエディットボックスとリッチエディット2.0それぞれにGetWindowText関数を使って、記入内容を取得します。 すると、エディットボックスではUnicodeの文字を入れても文字化けしないのに対し、リッチエディット2.0では文字化けしてしまいます。 例えば“ÄÅÆ”を入力すると、エディットボックスではそのまま“ÄÅÆ”なのに、リッチエディット2.0では“AAA”になります。 ※入力している段階では“ÄÅÆ”と表示されています。GetWindowText関数で取得すると“AAA”になってしまいます。 リッチエディット2.0からUnicode文字を正常に受け取れる方法はありませんでしょうか。
237 :
236 :2008/07/01(火) 14:48:29
書き忘れてました 環境は Visual Studio .NET 2003 です。
設定フォントはUnicode表示できるの?
>>238 できます。
それも含め、エディットボックスでならすべてうまくいっています。
ただ、リッチエディットだとうまくいかないんです・・・
>>236 の通りにやってみたが、すべて問題なく動作した。
VS2008だけど。2003もあるんでちょっとやってみる。
ご苦労
243 :
236 :2008/07/01(火) 17:06:44
>>242 回答ありがとうございます。
やっぱり2003のリッチエディットはUnicodeに対応してないんですかねぇ・・・
あ、その添付のURLは私が上げた質問ですw
OKWaveで質問しても回答が得られなかったのでこっちに来た次第です。
よくやった
246 :
236 :2008/07/01(火) 18:20:59
>>244 ありがとうございます、さっそく試してみます。
>>244 さんの紹介ページの通りやってみたらうまくいきました。
・・・とはいっても、>ex と書くべきところを >ex と書いてあったり、TCHAR*型のポインタを渡すべきところにCString型変数を渡してたりと、なかなか誤字の多いページでしたけど。
そこは const のTCHAR*渡すようにすれば CString のまま渡せるんだけどね。 オレはそこはLPCTSTRにした。 結局、コードページ1200にしてEM_GETTEXTEXが必要ってことみたいだな。
249 :
247 :2008/07/01(火) 18:57:17
あ、誤字ってる・・・ > とはいっても、>ex と書くべきところを >ex と書いてあったり 「&gtex」を半角で打つと「>ex」になってしまうようですね。前者の「>ex」は「&gtex」のつもりで書きました。
MFCはマルチコアなど気にする必要は無いのでしょうか。 現在P4 2.8Gを使っているのですが、処理によってはCPU使用率が80%を超える場合があります。 もしC2Dなどのマルチコアで実行した場合、 何も気にせず組むと1つしか使っていない(=現状より処理が重い)という状況になるかと思ったのですがどうなのでしょうか。
MFCじゃなくてスレッドの話だろ
内容次第としか言いようがないな 今でもまともにマルチコアを使いこなしてるソフトなんて、エンコーダくらいしかないし
コンパイルそのものは速くなるよ 複数のファイル平行してコンパイルするからね
あと、C2Dの1コアだけで同クロックのPen4より かなり速いぞ クロックだけで判断しないほうがいい
マルチコアって響きはプログラマとしてトキメクものがあるが 現状1つのアプリ内で有効に活用できる機会はあまり無いわな。
というか複数アプリ起動時にパフォーマンスが高いから、もう十分
257 :
250 :2008/07/01(火) 20:39:43
レスありがとうございます。 特殊なことをしない限りMFCでマルチコア云々を特に考える必要は無いのですね。
258 :
デフォルトの名無しさん :2008/07/02(水) 16:19:51
いま、EXEにあるクラスのヘッダーをincludeしてDLLを作ろうとしてます。 構造体ならうまくいくのですが、クラスだと fatal error LNK1120: 外部参照 1 が未解決です。 になってしまいます。解決方法ご存じでしょうか?
何言ってるのかわかりにくいが、、、 その外部参照1の名前から推測できないの?
__declspecをつけてないとか
261 :
デフォルトの名無しさん :2008/07/02(水) 17:42:14
__declspecも付けてみましたがうまくいきません。 error LNK2019: 未解決の外部シンボル "public: class ATL::CStringT<wchar_t,class StrTraitMFC_DLL<wchar_t,class ATL::ChTraitsCRT<wchar_t> > > __thiscall CNode::getAll(void)" (?getAll@CNode@@QAE?AV?$CStringT@_WV?$StrTraitMFC_DLL@_WV?$ChTraitsCRT@_W@ATL@@@@@ATL@@XZ) が関数 "public: virtual void __thiscall CMindPlug::LoadProperty(struct DataObj,class ATL::CStringT<wchar_t,class StrTraitMFC_DLL<wchar_t,class ATL::ChTraitsCRT<wchar_t> > >)" (?LoadProperty@CMindPlug@@UAEXUDataObj@@V?$CStringT@_WV?$StrTraitMFC_DLL@_WV?$ChTraitsCRT@_W@ATL@@@@@ATL@@@Z) で参照されました。 というエラーが弊出します
unicodeとか、シングルスレッド/マルチスレッドとかの設定は合ってるか? 最初に競合してるとかのエラーは出てない?
そのクラスがDLLの外から呼び出せるようになってるか確認した? あと、構造体ならうまくいくって、どううまくいくんだ?
264 :
デフォルトの名無しさん :2008/07/05(土) 04:47:27
いつも使っているUpdateData(FALSE);を マルチスレッドで作った別スレッドの中で実行するとエラーが出るんですが、どういう問題が考えられますか?
別スレッドの中で実行してるという問題が考えられる
266 :
デフォルトの名無しさん :2008/07/05(土) 13:28:30
やはりそうですか、別スレッドの中で実行するにはどうすればいいですか?
だから別スレッドの中で実行したらだめ
MFCやってて、マルチスレッドなんてプログレスバー処理やるときくらいだな
↑あほ確定
うむ
マルチスレッドって何ですか?
親子関係を持たないシングルウィンドウとダイアログについての質問です。 メインフレームをクリックするとダイアログも並び順はそのままで他のアプリケーションの上にウィンドウが来るように組もうとしています。 例えば以下のようにウィンドウが並んでいる場合 デスクトップ) ダイアログ1 ダイアログ2 メインフレーム 他のアプリケーション (最前面 このメインフレームをクリックすると デスクトップ) 他のアプリケーション ダイアログ1 ダイアログ2 メインフレーム (最前面 このように重なりを替えたいです。 しかしダイアログ1と2の前後関係が分からないため デスクトップ) 他のアプリケーション ダイアログ2 ダイアログ1 メインフレーム (最前面 このようになってしまいます。 メインフレームを親にしてダイアログを生成するとダイアログの前面にメインフレームが持ってこれず躓きました。 重なり順をそのままに他のアプリケーションの前面に移動させるのは無理なのでしょうか。
CPenで点を打つとき座標が必要ですが、コントロール上の座標を調べる方法はないんですか? 適当に座標を入れて、もう少し上だ、とかでずらしてコンパイルするしかないんですか?
もう少し上、てのは何を基準に? その基準を利用してみては。 見た目でなんとなく、というのならキミがやるしかないでしょ。
マウス持ってけばわかるけど ダイアログ上の座標は実行環境で可変だから 計算じゃなくて見た目で決めると実行時にずれる
解決しました。付属のspyツールでマウスイベントのX,Y座標がとれました。
座標関連のことやってるなら、PC用語ではないが黄金比くらいは知っておいた方がいい 役に立つかどうかは別だが
ダメな方法を教えてやったのに
280 :
デフォルトの名無しさん :2008/07/13(日) 18:29:59
ビットマップをピクチャコントロールの大きさに合わせて表示したり、 ボタンの横幅を文字数にあわせたりするのはどうしたら良いでしょうか?
ピクチャコントロールの大きさを調べて合わせる 文字数から横幅を計算して合わせる
文字数はDrawTextでパラメータにCALCっぽいやつつけろ
283 :
デフォルトの名無しさん :2008/07/13(日) 23:32:56
素人質問ですいません。 MFCでダイアログを表示させる時に作成したボタンを クリックしている状態にするのにはどうすれば良いでしょうか?
見た目だけでよかったらへこんだ状態にすればいい
チェックボックスのボタンスタイルか?
ダイアログエディタなら、チェックボックスを貼ってPushLikeをtrueに。 それ以外なら、、3ステートボタンとか2ステートボタンで探してみて
ON_BN_CLICKED で ピクチャーコントロールの上をクリックされたときによばれるコールバックを設定したんだけど、 このとき、クリックされた座標が知りたい。どうすればいい?
>>287 CPoint pt = GetMessagePos();
GetCursorPos使えばいいよ
STNじゃないの? CLICKEDはボタンを押して離した後に来るからマウス座標の概念は無いかもな。 サブクラス化してLBUTTONDOWNやUPを見たほうがいいかも?
GetCursorPos や GetMessagePos にはタイムラグあるんじゃない? CLICKEDが最後のメッセージであると決まってればGetMessagePosでいいのかもしれん
>>292 GetMessagePosも、
イベント発生時の座標=クリックされた座標では無いのが曲者だな
クリックされた座標を拾えるAPIは、もしかして無いんじゃね?
実際にやってみて、ずれなきゃそれでいいしずれるなら自前で取るのがいいかもね。
287 です。 みなさん、回答ありがとう。GetMessagePos() を使用して要望がかないました。 実際、実装したかったモノはCStaticにカラーグラデーションを配置して、簡易なカラーピッカを実現することでした。 実装してみるとクリック時よりもリリース時の座標の方が使い勝手がいいことが分かりましたが、 助言をヒントにこれも実現できそうです。
296 :
デフォルトの名無しさん :2008/07/16(水) 13:01:17
VC.netでUnicode環境の場合に、 char a[10]; CString s; strcpy(a,s); _tcscpy(a, s); _tcscpy_s(a, s); とか、CStringからcharへのコピーがうまくいきません。 誰かご教授くださいm(_._)m
いったい何がやりたいのか理解できない
>>296 char a[10]; CString s;
strcpy(a, CT2A(s));
とか
USES_CONVERSION;
char a[10]; CString s;
strcpy(a, T2A(s));
とやれば動くだろうけど、そもそもaがchar配列なのは何故?
CStringA
コピーじゃなくて変換なのか?
Visual Studio 2005で、WindowsMobile6用のダイアログベースアプリを作っています。
ダイアログにメニューをつけたいのですが、やり方がわかりません。
下記URLのやり方をやってみようと思ったのですが、2箇所やり方がわからず、詰まってしまいました。
http://www.g-ishihara.com/mfc_me_01.htm 1.メニューのIDが設定できない
リソースの追加でMenuを作成したときに、リソースビューには「IDR_MENU1」というのができるのですが、
メニューのプロパティでは「IDの編集ができません」と書かれて、IDが編集できません(サブメニューは編集できました)。
でも、とりあえず、メニューリソースの作成方法はわかったつもりです。
また、下記2.で使うのは「IDR_MENU1」という名前だと考えたので、
ここでIDの編集ができないことは、メニューをつけられないこととは関係ないと思っています。
2.ダイアログにメニューを関連付けられない
>> ダイアログのプロパティで、「Menu」に作成したメニューのIDを指定
という手順で、ダイアログのプロパティに、「Menu」という項目がありませんでした。。。。
もしMenuという項目があれば、「IDR_MENU1」を記入すればよいと思っています。
ダイアログにメニューをつける方法を教えていただけませんでしょうか。
足りない情報があれば、ご指摘ください。
よろしくお願いいたします。
>>301 1.リソースビューの「IDR_MENU1」をシングルクリック
2.リソースビューの該当ダイアログIDをダブルクリック
(※VS2003だけど)
>>301 1. メニューの編集閉じてから、リソースビューからメニュー右クリックでプロパティ出してみ
2. でも、モバイルでダイアログにメニュー持たせられたっけ
304 :
301 :2008/07/16(水) 18:35:44
レスありがとうございます。
>>302 その通りにやってみましたが、ダイアログの編集が開くだけでした。
また、実行してみても、画面的に変化はありませんでした。
>>303 >> 1. メニューの編集閉じてから、リソースビューからメニュー右クリックでプロパティ出してみ
これはできました!リソースのプロパティでのIDの編集なのですね。
>> 2. でも、モバイルでダイアログにメニュー持たせられたっけ
ガーン。
もし無理ならばSDIで作り直して、メニューを編集することにします。
モバイルで可能かどうかって、何を調べればわかりますでしょうか?
どうだろ、そういうアプリ見たこと無いしなぁ やっぱMSDN探すしかないか?
306 :
301 :2008/07/16(水) 18:54:25
書き忘れました。。。
>>302 1.については、リソースのプロパティが表示され、IDが編集できました。
(303さんと同じ結果でした)
307 :
301 :2008/07/16(水) 19:05:41
>>305 MSDNでの探し方ってよくわからないんです。
モバイルで可能かどうかっていうのの情報が、どう書いてあるのかわからなくて。。。
.NET Compact Frameworkのどのバージョンに対応とか
そういうのは書いてある気がするんですけど、これはまた別の話ですよね?
# 当方MFCとかCompactFrameworkとかが何を指しているのかわかっていません。
言葉の意味はわかるのですが、具体的に何を指しているのかわからないのです。。。
たとえばCStringってクラスはMFCっぽい?とかそんなくらいの認識です。。。
308 :
デフォルトの名無しさん :2008/07/16(水) 22:42:12
309 :
301 :2008/07/17(木) 13:07:04
WindowsMobile用のスレを見つけたので、そっちで聞いてみます。 お邪魔しました。
VC6、VC7.1ともにダイアログベースのスケルトンにボタン貼り付けて、 クリックしたらMessageBox表示するだけのアプリで、 何回かボタンクリックしてるとメモリ使用量が4K増えるんですけど、こういうもんなんですか?
一応、そのボタンクリック時の関数の中身貼ってみて
>>310 そんなもんだろう。
ページングがおこって4kが確保されたんだろうが、それ以上その動作で確保されることはない(とは断定できないが)。
CFileDialogのファイル選択ダイアログのことなんですが JPEG Files (*.jpg;*.jpeg)|*.jpg; *.jpeg|All Files (*.*)|*.*|| と設定していて最初はJPEG Filesの拡張子が表示されるんですがJPEG FilesからAll Filesに変えると何も表示されなくなります(JPEG Filesに戻しても表示されない) あとXPですが左側にあるマイコンピュータを押してもCドライブなどが表示されず真っ白の状態(上と同じ)になります これをちゃんと表示させる方法ありませんか?
ほかのアプリで同様の現象が起きるなら、MFCは関係ないな。 再インストールでもした方が良い。
VS2005でピクチャーボックスのサイズが知りたくてGetWindowRectを使おうと思ったんだけど void C・・・Dlg::OnBnClickedButton1(){} こんな形の場所だとhwndの指定がうまくできないんですがどうすればいいんですか?
欲しいのはこれかね? つGetDlgItem
>>316 それ使いたいんですがGetWindowRectの引数が1個しか指定できなくて使えないんです
RECT rc; GetDlgItem(IDC_XX)->GetWindowRect(&rc); こういう事?
そんなやり方があったんですか ずっとGetWindowRect(GetDlgItem(hwnd,IDC_XX),&rc);こんな感じでしかできないものと思ってました どうもです
>>319 GetWindowRect()は、this->GetWindowRect()
のthisが省略された書き方だと言う事を意識した方が良い
Win32と入り混じってそうだな
GetDlgItem(IDC_XX)-> これ一番最初の方で習うだろ 別のやり方もあるけど、MFCでその方法教えない本はないと思う
>>322 MFCなら変数化して使うのが一般的じゃないかな。
IDを変数に置きなおして直感的に触れるようにするのがMFCの特徴の1つでもあるし。
324 :
310 :2008/07/19(土) 14:11:23
>>311 亀で申し訳ないです。
void CmessageboxDlg::OnBnClickedButton1()
{
// TODO : ここにコントロール通知ハンドラ コードを追加します。
MessageBox("Message", "Title", MB_OK | MB_ICONWARNING);
}
で、張り付けたボタン→メッセージボックスのボタン
の順にクリックし続けると何回かに1回4K増えます。
ボタンにフォーカス当ててエンター押しっぱなしだとより
顕著に増加します。
それ以外の部分はダイアログベースのスケルトンです。
CWnd一時オブジェクトが増えるのが原因じゃないかなあ。 放っておけば適当な間隔で解放されるから、あまり気にしなくても良いと思うけど。
だろうな 環境によって違うけど、ある程度時間を待てば解放されると思う
まあ、多分聞きたいことはみなさんの環境でも同じことやって同じ現象おきませんか? ってことだと思うけど俺は腰が重くてとても動く気になれないなw
>>327 もしそうなら、同じOS・同じMFCバージョンでやらないと意味無いかもな。
さすがにメッセージボックス表示させるだけのコードなら大丈夫だと思うぜ。
MFCのバグの可能性を疑うのなら別だけど、それを言い出したらキリが無い。
MFCもapi呼んでるだけだし、 呼んだ人のハンドル渡すぐらいのことしかやってないから 特にメモリ使ってるようには見えないな メモリ使ってるとしたらapiだろ
所詮CWnd::MessageBox()がAfxMessageBoxを呼んで、そいつがAPIのMessageBox呼んでるだけだよなw
ちょいとスレ違いだけど EmeditorってMFC使ってないらしいけど どうやって作ってるんですか
MFCを使わずに作ればいい
MFCの仕組み分かってないのか・・・
ウィンドウが作られる前はPreCreateWindowっぽいのですが、 ウィンドウが作られた後のイベントは何でしょうか?
OnCreate の話?
CHogeWnd::OnCreate() { CWnd::OnCreate(); // ここに書け }
CHogeDialog::OnInitDialog() { CDialog::OnInitDialog(); // TODO: ダイアログならこれの方がいい // TODO: でもなんでダイアログだとこれの方がいいんだろう??? }
子コントロールも初期化終わってるからじゃない?
339 :
デフォルトの名無しさん :2008/07/23(水) 21:46:18
リストコントロールの行の高さを変えるにはどうすりゃいいでしょうか?
リソースで書き換えとけ
MFC初心者です ダイアログ内の状態に応じて、×ボタンなのでダイアログを閉じさせたくないのですが どのイベントを拾ってどういう処理をすればいいのでしょうか?
×ボタン→WM_SYSCOMMAND(SC_CLOSE)→WM_CLOSE どっか(OnSyscommand等)で捕まえるのがいいかと。 ×ボタン自体はSYSMENUのSC_CLOSEを消すと消える。
即レスどうもです! ためしにOnCloseをオーバーライドしてみたんですが、終了時に呼ばれない。 ためしにOnOkとOnCancelも作ってみたけど・・・呼ばれないorz 何が悪いんでしょうか
×ボタンのキャンセルじゃないの? void Cmfc005Dlg::OnSysCommand(UINT nID, LPARAM lParam) { if ((nID & 0xFFF0) == SC_CLOSE) { // ×ボタン } } とか
いろいろやってみてるんですがやっぱり継承したOn〜が全然呼ばれていないようです メッセージマップの設定もしているはずなんですが… 唯一呼ばれるのはOnInitDialogくらいです エスパー助けて >o<
virtual になって無いとか・・・
メッセージマップの設定もなにも、、、 クラス選択してプロパティ出して、上のイベントボタン押して そこから追加してる?手でやってるならどれとどれ書いた?
イベントじゃないや、メッセージね
>>346 「On〜が全然呼ばれていないようです」
「メッセージマップの設定もしているはずなんですが」
どちらかが嘘だと思う。
OnCancel が呼ばれるんだよ ID は IDCANCEL
>>351 クローズボックスで閉じたときの話をしてるんだが。
>ID は IDCANCEL
そう。OnCancel が呼ばれるのは、IDがIDCANCELのダイアログの子ボタンが
NOTIFY投げてきたとき&ダイアログがESCキー検出したとき。
けど今それ関係ないから。
>>346 >継承したOn〜が全然呼ばれていないようです
仮想関数でもない OnClose に継承とか関係ない。
メッセージマップに ON_WM_CLOSE があれば、ディスパッチされるハズ。
そういえばエスケープで閉じない処理を入れると 閉じるボタンでも閉じなくなってしまうから 閉じるボタンだったら閉じる処理を入れたのを思い出した
エスケープはOnCancel()でいいべ。
たぶん閉じるボタンでOnCancelが呼ばれて そこでEndDialogしてるんだろ void CDialog::OnCancel() { EndDialog(IDCANCEL); }
357 :
デフォルトの名無しさん :2008/07/29(火) 21:34:16
>>341 ありがとうございます。
その方法で行の高さはかえれるようになりましたが、ヘッダの高さが変えられません。
どうすればいいでしょうか?
358 :
337 :2008/08/02(土) 00:30:06
>>338 OnCreate内でも子コントロールを操作して問題無いからどちらも子コントロール初期化終わってる希ガス
>>357 ヘッダは別コントロールだから、そっちで何とかするしかないかも
361 :
337 :2008/08/03(日) 23:56:56
>>360 DDXと言うとコントロールとコントロール変数を関連付けるアレかな?
あっちは初期化終わってなかったのか
CDialog::OnInitDialog -> UpdateData -> DoDataExchange こんな感じになってるからね。 大体、WM_CREATEの時点だと子ウィンドウはまだ存在しないと思うし。
質問お願いします。 edit controlを2個 OKボタンを1個 作成しました。edit controlが共に値が入っていないと OKボタンが非表示になるようにしたのですが 非表示の場合でも、Enterキーを入力するとOKが適用されてしまいます。 非表示の場合、Enterキーの無効化または常に無効化する方法を ご存じの方はご教示ください。
>>363 OnOkをオーバーライドしてそこにエディットコントロールの中身を調べるプログラムを書く。
もし空白など適切なものではない場合はreturnでそのまま返してやるだけ。
で、SP1まだ?w
>>363 同時にDisableにしておけばよいかと。
Disableにしても消しても無理
OnOkはシステム定義のメッセージだろ OKボタンじゃなくて自分で作ったボタンにすればいい
>>368 >OnOkはシステム定義のメッセージだろ
何を言っているのか解らんが、
1. IDがIDOKである、ダイアログの子ボタンからのBN_CLICKED を受け取ったとき
2. ダイアログ自身がキー入力を見て Enter だったとき
に、ダイアログから呼び出される仮想メンバ関数。
win32で定義してるのを知らんのか WINUSER.H(7537): #define IDOK 1 /* * Dialog Box Command IDs */ #define IDOK 1 #define IDCANCEL 2 #define IDABORT 3 #define IDRETRY 4 #define IDIGNORE 5 #define IDYES 6 #define IDNO 7 #if(WINVER >= 0x0400) #define IDCLOSE 8 #define IDHELP 9 #endif /* WINVER >= 0x0400 */
また意味不明なことを言ってるよ。 話をどこにもっていきたいのかわからん。
>OKボタンじゃなくて自分で作ったボタンにすればいい リターンキーでIDOKを回避するにはこれだけじゃだめで、 その自分で作ったボタンをデフォルトボタンにする必要がある。 まあOnOK()捕まえたほうが確実だね。
>>367 なんでDisableが無理?
Disableにすればエディットボックス上でEnter押しても効かなくなるけど。
>>369 > 2. ダイアログ自身がキー入力を見て Enter だったとき
> に、ダイアログから呼び出される仮想メンバ関数。
これは違う。
Enterキーはデフォルトボタンを押す操作。
キャンセルボタン上でEnterキーを押せばOnCancelがコールされるし、
自分で用意したボタン上ならそのハンドラがコールされる。
OKボタン削除してもOnOK呼ばれる
MFCやってるんなら、始めにぶつかって覚えてそうなことなのになw
>>374 OKボタンを削除してもOnOKが呼ばれるのは、IsDialogMessage()が、
デフォルトボタンが存在しないときにIDOKを発行しているからであって、
直接OnOKが呼ばれているのではないのでは?
OKボタン削除だけしておいて代わりのデフォルトボタンを用意しなかったり、
DM_GETDEFIDメッセージを処理しなかったりしているからそうなるだけ。
シングルウィンドウでexeのアイコンにファイルをドロップしたり、その実行ファイルに関連付けされているファイルを開いた場合 どの部分でドロップしたファイルや開いたファイルのパスを取得するのでしょうか。
>>377 取得しなくとも__argv or __wargvに保持されています。
DialogベースのアプリでないならCYourApp::InitInstanceのParseCommandLineでコマンドラインの解析が行われます。
argvなんて単語初めて聞いた!!という場合はParseCommandLineの利用をお勧めします。
VisualStudio2005で、WindowsMobile6用にSDIで作っています。 リストボックスのフォントを等幅フォントにしたいと思って、次のように書いたのですけど、反映されません。 CFont nfont; nfont.CreateFont( 0, // nHeight 0, // nWidth 0, // nEscapement 0, // nOrientation FW_BOLD, // nWeight FALSE, // bItalic FALSE, // bUnderline 0, // cStrikeOut SHIFTJIS_CHARSET, // nCharSet OUT_DEFAULT_PRECIS, // nOutPrecision CLIP_DEFAULT_PRECIS, // nClipPrecision DEFAULT_QUALITY, // nQuality FIXED_PITCH | FF_DONTCARE, // nPitchAndFamily _T("MS ゴシック") // lpszFacename ); GetDlgItem(IDC_LIST1)->SetFont(&nfont); ちなみにHeightの設定だけ微妙に反映される状態です。 リストの1行の高さだけが変化し、フォントの大きさは変わらないという微妙さ加減です。 BOLD指定しても太字にならないし、何がなにやらよくわからないです・・・。 リストボックスの文字を等幅フォントに設定する方法を教えてください〜
そのフォントがスコープ抜けて無効になってるというオチじゃなかろうね?
381 :
379 :2008/08/12(火) 15:55:41
>>380 スコープ!?
あわわわわ。まさにそのオチでしたorz
ありがとうございました(泣)
sp1出てたのか いろんなニュースに紛れてて気付かなかった
あれ? ファイルのフルパスからファイル名を省いたフォルダパスを取得するのってどうするんでしたっけ?
>>383 PathRemoveFileSpec()
385 :
383 :2008/08/19(火) 14:41:34
_tsplitpath でしたね。。。 すまそ。
386 :
383 :2008/08/19(火) 14:43:06
>>384 そんなのあったんですね!!
ありがとうございます!!!
Path系はIE5のライブラリのAPIだっけか
shlwapiの4.71以降だからIE4.0かな splitpathなんてDOSの頃使ったっきりで、すっかり忘れてたよ
389 :
デフォルトの名無しさん :2008/08/22(金) 00:07:23
エディットボックスにctrl+vで文字を貼り付けたときに 10文字以上になった場合にメッセージボックスを表示させるにはどうしたら良いでしょうか?
DDV_MaxChars
MFCスレって、いつの間にか過疎ってるのな。 皆どこ行っちゃったんだろう?
ATL/WTL, .NETなどなど
残業でカンヅメ状態だから書き込めない
SP1でいろいろ追加されたが、なかなか触る暇が無い
MFCで印刷関係のサンプルコード検索しようとすると、 ブラザーのレーザープリンタが、ちょいちょいヒットするの なんとかしてくれませんか?
印刷といえば、.NET Framework 3.0 で Microsoft XPS Document Writer が インストールされるようになったけど、あれはいいな。手軽に試せて。
つPrimoPDF
SP1のタブMDI(呼び方あってる?)って、デフォルトでマウスイベントとかなさ気だな・・・ まだちゃんと仕様見てないが・・・ていうかテーマで挙動かわりやがる
すみません、ひとつ質問というか相談させてください 現在、VC6でMFCを用いて開発しています。 昨日、取引先から、過去に弊社が納品したソフトを、 「Google Chrome」みたいなマルチタスク方式を組み込んで バージョンアップして欲しいという要求が来ました。 過去に納品したソフトにはタブで画面を切り替える部分がありますが、シングルタスクです。 この部分をマルチタスクにして欲しいという内容でした。 要求の理由は目新しさや安定性が売りになるからとのです。 まず、実現可能性の調査をすることが決定し、 私がその調査をすることになったのですが、 いろいろ検索したりして情報を探しても、 なかなか適した情報がヒットしない状況です。 で、質問なのですが、VC6で実現できるのでしょうか? 場合によっては最新の開発環境(VS2008だったかな)へ移行することも考えています。 よろしくお願いします
できます。 たぶん、きっと
マルチタスク、マルチスレッド、マルチタブを混同してないか? まずはその違いを理解してから質問しろよ
ちなみに「Google Chrome」は VS2005 でビルドします。 MFC は使用されていないみたいです。 VC6, VS2003, VS2008 を持っているおいらは負け組み? orz
2005をskipするのはありがちだと思う VISTAで開発するなら2008になるよなぁ
chromeはvs2008でもビルドできたよ
VC6でchromeをビルドできるようにして納品しちゃえば?
まじ?>405 釣りじゃないよね? 今から試してみよう
ソリューションを変換してビルド中だけど warning C4396 が山のように出てるぞ (Chome をビルド・改造するってスレはある?あれば移動します)
CListCtrl上にデータを表示し入ってくるデータで更新しているのですが、一定時間がたつと画面表示がおかしくなります。 フォントキャッシュが壊れた時のようにコンボボックスの右側の▽ボタンに6と表示されたり、画面全体(Windows含)が残像を残すようになったり。 データの受信を中止してもそのままで、またメモリ使用量を調べても特に増えてはいません。 InValidate関数等も試しましたが同じ現象が起こります。 最小化する、別の画面を最前面に表示する等で他の画面は正常に戻るのですが、再度リストを表示するとその瞬間に同じ症状が出ます。 どのような対策方法があるか教えていただけないでしょうか。
そうなんだ
どのような対策って、バグをつぶすしかねーだろ
>>409 の訳:「ソース出さないけど誰かデバッグして下さい」
よくあるケースみたいだから対策方法教えてくれと言ってるのかもしれんが、 普通無いケースだからなあ
「入ってくるデータで更新」がちょっと気になるな。 別スレッドでなんかやってるとか、 逆にシングルスレッドで表示の更新が止まってるとか。
リソース食いつぶしてるようにも見えるなあ
MFCと関係ないだろ
417 :
デフォルトの名無しさん :2008/09/10(水) 19:20:41
スタッティク領域に書かれたテキスト文字だけ拡大できる のか
ひとりごとです
>>409 メモリーじゃないとすればGDIオブジェクトの数確認してみ。
タスクマネージャで表示メニューいじれば確認できる。
ひとつのアプリで使用できるGDIオブジェには上限があり
開放し忘れ関数が何度も呼ばれると409のような状態になる。
>>419 タスクマネージャにそんな機能があるとは、知らなかった
これは便利
421 :
409 :2008/09/11(木) 11:12:54
ソースも出さず失礼しました。 単純なプログラムでも同じ状態になるので、何か単純な回避方法があるのではないかと思ったのです。 とりあえずGDIオブジェクトを調べてみようと思います。 ありがとうございました。
423 :
デフォルトの名無しさん :2008/09/15(月) 23:52:27
質問です。 現在VS2008でダイアログベースのプログラムを作成しています。 多重起動を禁止するため、以下の手順でウィンドウクラス名を変更しました。 1.ダイアログのClassNameをAAAAに変更 2.C***App::InitInstanceでClassNameをAAAAに設定 BOOL C***App::InitInstance(){ /* MFCによる処理 */ WNDCLASS wc; HINSTANCE hInst = ::AfxGetInstanceHandle(); if(!::GetClassInfo(hInst, CLASS_NAME, &wc)) { ASSERT(::GetClassInfo(hInst, "#32770", &wc)); wc.lpszClassName = CLASS_NAME; wc.hIcon = ::LoadIcon(hInst, MAKEINTRESOURCE(IDR_MAINFRAME)); ASSERT(::AfxRegisterClass(&wc)); } ASSERT(CWinApp::InitInstance()); /* 残りの処理 */ C***Dlg dlg; dlg.DoModal return FALSE; } Debug版ではDoModalでちゃんとウィンドウが表示されるのですが、Release版ではDoModalが-1を返し異常終了してしまいます。 Release版でやらなければいけない処理などがあるでしょうか? また、間違ってる処理などがあれば教えてください。
ASSERTがいかんのじゃね? 誤解してんじゃね? よくみてねーけどさ。
うん、俺もちゃんと見てないがInitInstance()なんてものをASSERTの中で呼んでることが怖い
426 :
423 :2008/09/16(火) 00:55:56
>>424-425 ありがとうございます!解決しました!
ASSERTを誤解してました。これからは変数値の評価だけに使うことにします。
多重起動防止はCreateMutexを使うのが普通だぜ m_hMutex = ::CreateMutex( NULL, 0, "__HogeAppMutex__" ) ; if ( ::GetLastError() == ERROR_ALREADY_EXISTS ) { ::CloseHandle( m_hMutex ) ; m_hMutex = NULL ; return( FALSE ) ; }
>>426 Releaseビルド時にも式の評価だけはしてくれるVERIFYマクロがあるよ
429 :
デフォルトの名無しさん :2008/09/16(火) 20:16:49
>>427 共有メモリでもいいかも知れない。
共有メモリに最初に起動したウィンドウの
ハンドルを格納しておいて、
多重起動された時に最初に起動したウィンドウ
を最前面に表示させるとか・・・
>>429 >最初に起動したウィンドウの
>ハンドルを格納
する前に、二番目に起動したプロセスのウィンドウハンドルが
格納されてしまうかも知れないわけよ。
432 :
423 :2008/09/17(水) 11:52:16
返信遅くなってすいません。
>>427 これからはこれを多重起動の確認に使ってみようと思います。
ありがとうございます!
>>428 こんなマクロもあったんですね。
これからはASSERTの代わりに使ってみます。
>>429 >多重起動された時に最初に起動したウィンドウ
>を最前面に表示させるとか・・・
>>427 のreturn前にコレだな
CString strWndTitle ;
strWndTitle.LoadString( IDR_MAINFRAME ) ;
::SetForegroundWindow( ::FindWindow( NULL, (LPCTSTR)strWndTitle )) ;
MFCをマクラって略してんの俺だけ?
ファンデーションはどこに行ったんだ
どっかにふっとんだ。
ファウンデーションでしょ
はげしく、どっちでもいいw
どっちでもいいぐらいだからどっか行ったんじゃね?w マクラいいなw
440 :
デフォルトの名無しさん :2008/09/21(日) 19:24:06
ダイアログコントロールの種類(ボタンかエディットかなど) を判別する関数とかありますか?
IsKindOfかなぁ
関数は知らないけどapiならある
質問です。 タスクトレイにアイコンを格納しようと思っているんですが、タスクトレイに表示されるアイコンが32ピクセルのアイコンになってしまいます。 タスクトレイに表示されるアイコンを16ピクセルのアイコンにするにはどうすればいいんでしょうか? //SetIcon(m_hIcon, TRUE); ← タスクバーのアイコンが16ピクセル、タスクトレイのアイコンが32ピクセルになる //SetIcon(m_hIcon, FALSE); ← タスクバーのアイコンが32ピクセル、タスクトレイのアイコンが32ピクセルになる m_iconData.cbSize = sizeof(NOTIFYICONDATA); m_iconData.uID = TRY_ID; m_iconData.hWnd = m_hWnd; m_iconData.uFlags = NIF_ICON | NIF_MESSAGE | NIF_TIP; m_iconData.hIcon = m_hIcon; m_iconData.uCallbackMessage = TRY_MESSAGE; lstrcpy( m_iconData.szTip, "***" ); ::Shell_NotifyIcon( NIM_ADD, &m_iconData );
いまいちよく判らんけど、LoadImageで取り出す大きさを明示的に指定すれば良いんじゃね?
445 :
443 :2008/09/30(火) 03:00:33
>444 LoadIconで2種類のサイズのアイコンを取得していると思っていたんですが、LoadImageで取得する必要があるのでしょうか? 今はこうやってアイコンを取得しています。 m_hIcon = AfxGetApp()->LoadIcon(IDR_MAINFRAME);
あまり関係ないかもしれないけどLoadIcon()って非推奨じゃなかったっけ
LoadIcon()は昔からある固定サイズの1種類しかとれないよ。
MFCのウィザードが吐き出すコードで SetIcon(m_hIcon, FALSE) ってあるけど、32x32のアイコンを16x16に縮小して表示するだけで、 16x16のアイコンを読み出して表示しているわけでは無かったりする。 DestoryIcon呼ぶの('A`)マンドクセ、ってのが理由だろうな。
LoadIcon非推奨ってことは16×16のビットマップで描画したほうがよかったりするんだろうか? アイコン使うメリットってなんだろ?
メンバのCArrayを戻り値として返したいんですけど CArray<〜*, 〜*>& GetData() { return( m_arrData ); } だと、コンパイル時にprivateにアクセスしています。みたいなメッセージが表示されます。 (他のクラスからアクセスしてる) どのように書くのが正しいのでしょうか…
自己解決しました…
452 :
443 :2008/10/03(金) 00:29:16
返信が遅くなってすみません。 >446-449 ということは16x16と32x32のアイコンをそれぞれロードする必要があるということでしょうか? また、16,32,48ピクセルのアイコンをそれぞれ出力するにはどうすればいいんでしょうか?
自分でLoadImage使うって書いてるじゃない
>m_hIcon = AfxGetApp()->LoadIcon(IDR_MAINFRAME); これと同じように、 m_hSmallIcon = (HICON)::LoadImage(AfxGetInstanceHandle(), MAKEINTRESOURCE(IDR_MAINFRAME),IMAGE_ICON,16,16,LR_DEFAULTCOLOR); とかやればよし。
456 :
デフォルトの名無しさん :2008/10/05(日) 12:31:57
age
457 :
443 :2008/10/05(日) 14:32:49
>453-454 無事アイコンの使い分けが出来るようになりました。 ありがとうございました!
iniファイルをexeのところに作ろうとしてますがうまくいきません。なぜ。。。 App::InitInstance() { WCHAR dir[MAX_PATH]; ::GetModuleFileName(NULL, dir, MAX_PATH); wchar_t* pdest = wcsrchr(dir, _T('\\')); pdest[1] = '\0'; ::SetCurrentDirectory((LPCTSTR )dir); wcscat_s(dir, _T("XXX.ini")); free((void*)m_pszProfileName); m_pszProfileName = _tcsdup(dir); }
何がうまく行ってないか不明だし、 そこまでできてたらデバッガで調べるだろ
CWinApp::SetRegistryKeyを後で呼び出していたら笑う。 デバッガでステップ実行すれば、正しいパスが渡せているかどうかは一発だな。
ところで、これはMFCになんか関係あるのか?
m_pszProfileName m_pszProfileName がMFC
463 :
デフォルトの名無しさん :2008/10/11(土) 21:59:13
CStringって普通のStringじゃだめなのか?
CStringを使うのが普通
デバッガ上では dir にexeまでのパスが入っておりxxx.iniもセットされてますが 実際、ファイルは出来上がっていない。しかし、GetProfileStringでデータは取れるという状態
レジストリ使ってるわけじゃなくて?
簡単に変更でききるようにiniついたかったんですが
>>466 コードに書いてるのは、GetProfileStringなのか?
ぐぐり直したほうがいんじゃねーのか?
469 :
468 :2008/10/11(土) 22:57:47
Win32APIの同名APIを呼んでいる可能性があるかも。 WriteProfileStringなんか引数が全く同じだし。
471 :
463 :2008/10/11(土) 23:34:38
>>464 ありがとう><;まだ、MFCはじめたばかりなので、習ってCString使っていこうと思います><;
ただ単に慣習的なもののような気がしますが。
>470 愛してる そのまま使うとレジストリ保存だった。 正しくはWritePrivateProfileString() で最後に保存先指定でいけた
473 :
472 :2008/10/12(日) 00:36:16
>468 も愛してるよ〜
>>472 愛は要らんから、CWinApp側のメソッドを使ってやろうぜ。
MFCだと、普通はCWinApp派生クラスがtheAppとしてグローバルで宣言されているはず。
ダイアログの中のCStaticコントロール上のOnMouseMoveイベントを取得したいのだけど、どうすればいいのだろうか? だれか教えてください。
そのCStaticをクラス化して、その中で受け取るか ダイアログ側のクラスで、CStaticのハンドルを指定してOnMouseMoveを受け取ればいい どっちが綺麗かと言われると、ときと場合によるけど、前者の方がいいかな
たぶんコントロールがIDC_STATICのままなんだろ
なるほどIDC_STATICじゃ出来ないな 固有の名前をつけないと
>ダイアログ側のクラスで、CStaticのハンドルを指定してOnMouseMoveを受け取ればいい こちらの方法をもう少し詳しく教えてもらえないだろうか。 ON_WM_MOUSEMOVE() と void CFooDlg::OnMouseMove(UINT nFlags, CPoint point) のセットで間に合うモノなんだろうか? コントロールのIDはもちろんユニークなモノを付けている。
PreTranslateMessageかなぁ
479です。 ごめんなさい。問題解決しました。 今までクリックを検出するためにnotifyをtrueにしていたため、OnMouseMoveでは コントロール領域のMouseMoveが取得できなかっただけでした。
ID_FILE_OPENなどが選択された際、 それがメニューからか、ツールバーからか、アクセラレータからか などをコマンドハンドラ内で調べられませんか? MFC内の隠し関数とかでも構わないのですけど。 コマンドハンドラまで来てしまったら絶対に区別できないですか?
区別する必要があったら区別できるように作ればいい。
ID_FILE_OPEN_1とかID_FILE_OPEN_2とか作って、ラッパー経由とか?w
>>482 WM_COMMANDにそういうパラメータあったはずだから調べてみなさい。
>>483-485 CWnd::GetCurrentMessage()を使って
WM_COMMANDの付加情報からコマンド発生元を取れました。
ありがとうございます。
CListCtrlレポート形式で たくさん表示させると重いです 何か回避方法はありますか?
仮想リストビューとか
>>490 更新すべき場所だけ更新すればOK
普通のリストだと表示部分全てに更新がかかるから重いだけ。
ダイアログAに ラジオボタン1 ラジオボタン2 が設置されていて、この二つのラジオボタンがグループで、 2を押したら1のチェックが外れるとします(逆もあり)。 今、2を押して、1のチェックが外れました。 ダイアログAのWindowProcにはラジオボタン1のコントロールIDで何かしらのメッセージが 飛んでくるのでしょうか? ちなみに自分で試してみたところだとどうも飛んでこないようなのです。 ではラジオボタン1のチェックが外れた!というイベントをダイアログA上でキャッチすることはできないのでしょうか?
(コントロール変数).GetCheck(); で調べればよろし。 チェックのON/OFFを手動にすれば、チェックをつけなおす前に以前の状態を調べればチェックが外れたかどうか調べれる。
>>492 「ラジオボタン2が押された」→「ラジオボタン1のチェックが外れた」
でいいじゃん。
メッセージは飛んでるよ WindowProc使った方法は知らん
>>493 >>494 説明が足りませんでしたが事情によりチェックが外れた瞬間のイベント駆動の処理が必要なんです
まだチェックオンの瞬間は、オンクリックで拾うことはできますが、
ラジオボタンの場合、他のボタンを押したときに勝手に外れるので、オンクリックでは拾えず
また、SetCheck関数などで変更されたときもオンクリックでは拾えませんし悩んでます。
クリックから、関数から、などの入力方法に関わらず、とにかく「チェックが切り替わったとき」の
イベントが欲しいのです…
例えばエディットボックスなら内容を変更されたときのイベントを取れるとおもうんですが、
考えてるのは「今変わった!」というのがわかる、そんなイメージです…
>>495 どういったメッセージか、もしわかればヒントだけでも教えてください><
できるだけ自分で調べるつもりですので
オンクリック→正確にはBN_CLICKEDです
>>496 >ラジオボタンの場合、他のボタンを押したときに勝手に外れるので
ラジオボタンのプロパティでそういう風に設定しているからだろ。
リソースでラジオボタンをダブルクリックしたときに作られる関数で、
SetCheckする前にチェックの状態が変わったかどうか自分で調べれば解決。
>>494 と似た考え方だが
とりあえずそのグループのラジオボタンのイベントを一箇所で捕まえて
今回選択されたラジオボタンと前回で選択されたラジオボタンが異なっていたら、
「前回選択されたラジオボタンのチェックが外れた」
と考えればいいと思う。
なんとなく
>>496 はWindowProcとか言ってるからMFCじゃない気もするが、
MFCならON_COMMAND_RANGE使って10行も必要ないから
とりあえずダメ元で試してみたら?
話それるけどON_COMMAND_RANGEで扱うために リソースIDを連続させるためにresource.hを編集しちゃう俺はヘタレですか?
いいんじゃない? ID指定するとき、=つけて数値指定できるけど、面倒だもんね。
ON_COMMAND_EXを使えば、IDを引数にとるハンドラを作れるから、 リソースIDが飛び飛びでも一つのハンドラにまとめられるけど、 こっちはあまり使われないのかな。
MFCを使う標準DLLを作成すると CWinAppを派生したアプリケーションクラスが用意されますが、 これはDLL内の単独のスレッドというわけではないのでしょうか? OnIdle()をオーバーライドしてもコールされないのですが。
んー、そのままだと自分のメッセージループは使わないからな。
506 :
デフォルトの名無しさん :2008/10/21(火) 19:20:58
すみません。他で聞いても返事が無いのでここできかせてください。 VC6で本の通りにブラウザとかつくりました。VC6の生成するブラウザだから いまどきのWebページは開けないだろうと思っていたんですが、普通にうまくひらけました。Flushとかもです。 これは、VC6とはいえ、ブラウザエンジン?はいまどきのPCの最新のを(要するにIE7のを) 作成してくれるのでしょうか? よろしく教えてください。
507 :
506 :2008/10/21(火) 19:34:59
元のスレを今見たら、今日の夕方に返答がきてました。
解決したので、
>>506 はスルーしてください。
SDIでグラフ描画するソフトを作ろうとしてるんですが ViewのOnDrawで縦軸横軸を引いて その上にグラフを描画する方法がわかりません。 どなたか、わかる人教えてください。
どこまでわかっててどこからわからないの?
510 :
デフォルトの名無しさん :2008/10/23(木) 15:16:36
VC6で、_MBCSを使い、日本語と英語のプログラムを作っています。 一つのEXEで問題なく、 日本語Win上では、日本語のダイアログ、 英語Win上では、追加した英語のダイアログが表示されたのですが、 現在選択しているリソースが日本語か英語か知りたいのですが、 プログラム実行時、 英語日本語のリソース切り替え選択はどの値を見て読み替えてるのでしょうか? GetSystemDefaultLangID() 辺りは、コントロールパネルによって変化しているのは確認したのですが、 リソース読み替えとは関係ない様でした。 GetACP() , GetVersionEx()でも取得はできませんでした。 ご存知の方、ヒントだけでも御教授下さい。 よろしくお願いします。
GetSystemDefaultUILanguageとかGetUserDefaultUILanguageあたりかね? でも自分でFindResourceExする必要はある気がする。
って動的に切り替えるのが目的じゃないのか
ありがとうございます。 GetSystemDefaultUILanguage も調べていたのですが、これはVC7以降のAPIの様です。 多分ですが、 GetSystemDefaultLangIDと同様、コントロールパネルのロケールIDを返すのではないかと思います。 コントロールパネルからロケールIDは変更できるのですが、 実行時に使用されるリソースは変化ありませんでした。 現在の状態が知りたいだけですので、動的に読み替える必要は今のところありません。 どうしても・・・となれば、リソースに番号振って、プログラム中から判定するという方法もあるのですが、 Kernel32あたりで、どう判断しているのかが知れればと思った次第です。
winnls.h インクルードして使えないか?
そもそもAPIなのにVC7以降、とか関係ないでしょ。 インポートライブラリにもヘッダーにもないのなら作ればいいし。
516 :
513 :2008/10/23(木) 18:13:02
>>515 karnel32.libに無いので、呼べないのかと思ってました。
karnel32.dll をLoadLibraryして呼び出すことができました。
結果、
・日本語Win
GetSystemDefaultUILanguage() = 1041
GetUserDefaultUILanguage() = 1041
・英語Win (XP-Pro SPなし)
GetSystemDefaultUILanguage() = 2011628553
GetUserDefaultUILanguage() = 1033
と、
コントロールパネルに影響されないGetSystemDefaultLangID()と同じ値が取得できました。
ただ、リソース読み替えに使われているのかは不明なのと、
英語Winで、GetSystemDefaultUILanguageが不思議な値を返してくるのですが、
とりあえずは目的を果たせそうです。
助かりました。ありがとうございました。
その不思議な値、16進で0x77E70409だね。 下16ビット、0x0409は10進で1033だから上と下で別々に意味もってるのかも。
GDI系のAPIの基本の話か?w
519 :
513 :2008/10/23(木) 19:27:20
>>517 LANGIDFROMLCIDマクロを使ったところ、下位だけ抜けました。
言われるとおりのHEXで見るべきでした。
WINNT.H には、上位16bitは、Reserved、SortIDとコメントがありましたから、
Reservedは不明ですが、何か意味はありそうですね。
CMyDialog mydlg; if ( dlg.doModal() ){
DoModal()じゃねぇのか? 返り値はIDOKじゃないのか? そもそもmydlgじゃないdlgって何者?
CheckBoxの表示手法について教えて下さい。 通常はプロパティのCaptionで設定されている文字を表示させておいて 途中で文字の代わりにアイコンを表示させたいと思ってます。 最初からCheckBoxにアイコンを表示させる事はできてるのですが、途中で テキストからアイコンへの変更ができません。 途中から変える事は無理なのでしょうか? HINSTANCE hInst = AfxGetInstanceHandle(); HICON h_Icon1 = (HICON)LoadImage(hInst,MAKEINTRESOURCE(IDI_ICON1),IMAGE_ICON,128,128,LR_DEFAULTCOLOR); m_Check1.SetButtonStyle(m_Check1.GetButtonStyle() | BS_ICON); m_Check1.SetIcon(h_Icon1);
ボタンスタイルは | でつなげても意味ないぞ。 m_Check1.SetButtonStyle(BS_ICON); でもウィンドウサイズも変えないとアイコンの大きさにはならないかもな。
つーか、チェックボックスでかつアイコンというのが無いのか
ボタンみたいに動くものじゃないんだから 絵や文字と一体化してる必要ないし、 隣に自分で絵や文字書いても何の問題もない。
そんなにチェックボックスにアイコン使いたいなら擬似的に実現したクラス作ればいいじゃん
子ウィンドウとしてダイアログを利用しているのですが、 起動時、非表示にしたいのです。 CDialog dlg; dlg.Create( IDD , this ); dlg.ShowWindow( SW_HIDE ); とやっているのですが、 一瞬表示されるのです。 OnInitdialogで ShowWindow( SW_HIDE ); と記入しても。 回避できませんでした。 他に方法はありますか?
子ウィンドウってメインじゃないってこと? ダイアログエディタでVisibleの初期値をfalseにしてもだめかな?
MFC 9.0って、どこでダウンロードできますか?
できません。 standard以上を買ってください。
>>531 ありがとうございました。
しつこい質問で申し訳ないですが、今少し困っていることがあります。
当方
Visual C++ Express 2008
OS XP SP2
を使用していて、C++によってSQL Serverへの接続を試みています。
しかし、CDatabase db; のところで躓いてしまっています。
よく調べたところ、#include "afxdb.h" を使用する必要など
があるようで、更に調べたところ、MFCが関係していると知りました。
そこで、このスレの本質に従う質問をしたいと思います。
MFC9.0が使用できないことは分かりました。
MFCのシリーズで無料で(違法ではなく、公式な方法で)使用が可能な
方法はありませんか?
また、MFCがない場合
#include "afxdb.h" や CDatabase db;
などは、自分で1から記述しなければならないのでしょうか?
(初心者のため、バカなことかもしれませんが、ライブラリ
にはないため、自分で定義しなくてはならないのでしょうか?)
長文の上、稚拙な文になってしまいましたが、躓いてしまっている
ので、ご助力を加えて下されば幸いです。
よろしくお願いします。
CDatabaseを使用しないでDBにアクセスしなきゃなんないよ。 CDatabaseは C++ からODBCを介してSQL-Serverにアクセスするもので、 CDatabaseはMFCのクラスで、あなたは利用できないから、 ほかの手段を探すことになる。 ODBCの代わりにOLE-DBを使うこともできるし、 今からDBの勉強はじめるならこちらをお勧めする人が多いと思う。 "C++ OLE-DB SQL-SERVER アクセス"あたりのキーワードでぐぐればいいんじゃないかな。 というわけで、さようなら。
>>533 ご教授ありがとうございました。
貴重なお時間を割いていただき、申し訳ございませんでした。
質問しつれいします。 vc 2005 MFCを使ってGETやPOSTでデータを送信するプログラムを作成しようと思います。 勉強になるサイトなどありませんか? 検索のヒントでもいいので宜しくお願いしまっす
つWinInet
538 :
535 :2008/11/02(日) 18:19:43
>>536 ありがとうございます
そのキーワードを頼りに自分なりに調べてやってみます
>>537 すいません板違いでしたかー
検索のヒントを提示しただけ。鼬害かどうかは白根。
MFCのクラスを使うんなら、使えそうなクラスぐらいすぐ見つかると思うが MFCのクラスを使わずにやるんならスレ違い
>>540 いやぁMFCのクラスを使いたいのですが・・・
んー検討つかないんです
検索ワードだけでもヒントをぉぉぉぉぉ・・・orz
>>542 ありがとうございます!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
>>544 本当にありがとうございます・・・
階層図・・・目から鱗です・・・
xp sp2 VS2005 CString GetString(void) { CString strTemp; strTemp = "1234"; return strTemp; } void Main(void) { CString strHoge; CString strValue; strValue = GetString(); strHoge.Format("%08s", (LPCTSTR)strValue); strValue = GetString(); strHoge.Format("%s%08s", (LPCTSTR)strHoge, (LPCTSTR)strValue); // 以下略 } という感じの処理をするとFormatで落ちてしまうのですが、 何故なのでしょうか? あと CString でイメージ検索するとエr
>>546 CStringT::Format
--------
文字列オブジェクト自体をパラメータとして Format に渡すと、呼び出しは失敗します。たとえば、次のコードの結果は保証されません。
CAtlString str = "Some Data";
str.Format("%s%d", str, 123);
--------
>>547 その下に
----------
オプションの引数として文字列を渡すときは、LPCTSTR に明示的にキャストしてください。
書式は、printf 関数の書式引数と同じ機能を持っています。(書式や引数の説明は、
『ランタイム ライブラリ リファレンス』の「printf」を参照してください)。
書き込まれる文字列の終わりには NULL 文字が追加されます。
----------
とあったのですが、これはそもそも
>>546 の中でいう strValue のことであって、
自身を引数に指定するのはキャストしようが何しようがダメってことなんですよね?
const char*へのキャストは、operatorで内部のバッファ返してるだけ。 Format中に元のバッファが変わったら長さがかわるからバッファ足りなくなる。
C#やった後にこれやると、 GUI画面作成、メッセージ処理、メモリ管理、例外処理とか泣けてくるな… まあでも刺激はあるからいいか…
質問いいかな? 以下のようなプログラムでスレッド起動してスレッド終了を見ようとしているんだが、 WaitForSingleObject関数で毎回タイムアウト発生…理由分かる人いる? void CMainClass::Start() { g_pThread = AfxBeginThread(Test, GetSafeHwnd(), THREAD_PRIORITY_NORMAL); g_pThread->m_bAutoDelete = FALSE; } UINT Test(LPVOID pParam) { while(!g_Flg){ // ここで処理 // } return 0; } void CMainClass::Stop() { g_Flg = TRUE; ULONG ret = WaitForSingleObject(g_pThread[0]->m_hThread, 10000); delete g_pThread; }
ULONG ret = WaitForSingleObject(g_pThread->m_hThread, 10000); の間違い。配列はなしね。 なお「g_」をつけているのはグローバル変数
Test関数でちゃんと動いてる? サスペンド中だったりしない?
>>555 いま調べているんだけど、タイムアウトの10000ms以内には
絶対に終わるはずなんだけどなー。
でもそれが疑わしいか…
回答してくれてありがとん。
とりあえず
>>553 のまんま動かしてみたけど、WAIT_OBJECT_0でした。
原因はそこ以外にある?
>>557 自分でもやってみたら確かに動いたんだよね。
Test()の処理部分に原因がありそうなのは間違いない。
(ここで10秒かかるってのは考えにくかったからここで質問させてもらったけど)
お騒がせさせてすまんかった。
>>557 もありがとん
threadのreturn 0にブレイクポイントを置いてみるとか
>>553-554 だが、新たな発見。
Test()の処理部分に処理回数をカウントアップして、
Editボックスに毎回その値を表示する処理として
SetWindowTextを使っているんだけど、
Stop関数をコールした後、どうもそこで固まるらしい。
(SetWindowTextをコメント化したら問題がでなくなった)
…意味分からん。なんで最後の1回のSetWindowTextで固まる!?
具体的には ULONG num; //処理回数 CString str; str.Format("%d", num); EditBox->SetWindowText(str); とこんな感じ。 もちろん、メインウィンドウのハンドルはもらってきて、 使っている(その部分は省略しているけど)
そりゃあそのSetWindowTextで呼んでるスレッドはもうWaitForしてるからだろ。
SetWindowTextはSendMessageを呼んでる。 メインスレッドのメッセージループでそれを受け取らない以上、SetWindowTextからは返ってこないよ。
565 :
デフォルトの名無しさん :2008/11/14(金) 06:39:27
SDKを使わないでMFCアプリケーション作る方法を解説してるサイトはないでしょうか?
SDKじゃんくてIDEでした
リソースエディタとコマンドラインからコンパイラを動かすってことかな?
>>567 そうです。
ウィザードの吐き出すコードの解説と、リソースエディタの使い方が解説してあるサイトや本なんかが
あればいいなあ、と。
というかMFC詳しい人ってAFX*.Hに宣言されてるクラスを全部覚えてるのか・・・ ウィザードの吐き出すコードの前に、ここを熟読して出直してきます
>>569 覚えてないよ。ただ、よく使うクラスは限られるし、自分で使い勝手の
よいMFC派生クラスのライブラリを用意してあるので、それをプロジェ
クトに読み込んで使うことの方が多いな。
慣れてくると、ウィザードがどんなコードを吐き出すか判るので、既存の
テキトーなクラスの.cpp/.hをコピー&リネーム&文字列置換して、新しい
クラスの雛型にして、あとは全部手で書いている。
VC++ 6.0は、クラスウィザードがコード挿入位置を知るために使う特別な
書式のコメントがあるけど、これもクラスウィザードがコード生成したのと
同じように書いている。 その後、一度.clwファイルを消してからクラス
ウィザードを起動して.clwを再構築させれば、手で書いたクラスもちゃんと
クラスウィザードで認識させられる。
>>561 こういうの見るとSetDlgItemInt使えといいたくなる。
VS2008SP1のFeature Packで機能増えたけど、 新機能使うとレジストリでなくてiniファイルに保存・読み込みできないのだが(´ω`)・・トホー
>>573 玄人がSetDlgItemInt使わない理由とかあるの?
ダイアログを操作したいわけじゃないのに ダイアログに委託しているところ
素人・玄人の話ではなくて、 今回の場合、ワーカースレッド側からだとSetDlgItemIntを使いようが無いってだけだな。 コントロール変数とかで持っていても、値をテキストとして設定したい時は、 地味に便利なメソッドだったりする。
また変なのがわいてきたな ひっこんでろタコ
579 :
576 :2008/11/16(日) 14:52:37
CWnd::SetWindowText()も、CWnd::SetDlgItemText()も、CWnd::SetDlg ItemInt()も、単純にAPIのラッパだし、ワーカスレッドからでもなんら 問題なく呼べるだろ。 ダイアログのポインタが嫌なら、ハンドルとAPI直接呼び出し使え。 ::SetDlgItemText(this->m_hWnd,IDC_EDIT1,...); ::SetDlgItemInt(this->m_hWnd,IDC_EDIT1,...);
MFCスレでAPI直接呼び出し薦める奴って何なの?
と言われても、割と普通の事だしなあ。 というか、おまいら今回の話はUIスレッドがスレッド終了待機に入った所為で、 UIスレッドへのSendMessageがデッドロックした、っていう事完全に忘れてるだろ。
というより、スレッドとか、ハンドルがクラスで継承されていかないところでは、 Win32APIを直接叩く以外無いよな。 脱線すまん
隠ぺいしている部分は出来るだけ利用するな でもGDIだけはベタ書きしてしまう俺 それ自体をクラス化するんだけどな
>>583 MSDNにはHANDLE渡して該当するFromHandleを呼び出す、とあるから
オブジェクトは渡せないけどMFCで行けるんじゃない?
個人的にはしないけどね。
都合のいい時だけMFCを使うってスタンスなのでWin32APiは普通に呼ぶ
587 :
デフォルトの名無しさん :2008/11/19(水) 13:37:26
モーダレスダイアログでボタンを押すと m_cdlg = new CDlg(this); m_cdlg->ShowWindow(SW_SHOW); みたいな感じで表示するとボタンを押せばいくつでもダイアログが出てしまいます。 1つしか出さないにはどうしたらいいでしょうか? あと、親クラスの関数でモーダレスダイアログを扱うことはできますか? XP+VC.netです。
>>587 その2行を通るたびに new で作ってんだから、そりゃいくつでも出るでしょう。
そのボタン貼ったウィンドウの初期化部分で一回だけ作って、
ボタン押したときに ShowWindow すればいいんじゃね?
>親クラスの関数でモーダレスダイアログを扱うことはできますか?
ちょっと意味が解らんかった。
589 :
デフォルトの名無しさん :2008/11/19(水) 14:10:21
delete thisをモーダレス内でしているので、親ウィンドウではモーダレスの終了を検知出来ないですよね? モーダレスが終了した後なら、もう一度ボタンを押したときはモーダレスを表示したいのですが・・・。 モーダレス上のボタンを押したときに親ウィンドウの変数や関数をいじりたいのですが。
クラスメンバ private: CUnkoDlg m_dlg; Initidialog m_dlg.Create( CUnkoDlg::IDD , this ) OnButton m_dlg.ShowWindow( SW_SHOW )
モーダレスではなくモードレスですよ。
モーダルに対してなのか、モーダレスと言う人は非常に多い
青信号に対してなのか、赤信号で渡る人は非常に多い
>>589 自分でWM_NOTIFYして親に通知して、実処理は通知先で
>>589 モードレスダイアログに親のthisを渡してpublicな操作をしてもらう事はたまにやる
終了時には 『m_cdlg = new CDlg(this); 』のm_cdlgもNULLにして終わらせる
たぶんあんまり行儀が良くないと思う
子ダイアログで親クラスのヘッダをincludeしてもいいならそれもアリだがそこでしか使えなくなる 俺もやったことあるけど
モードレスダイアログなら、 一旦Createした後は、ShowとHideしかしないという作り方もある。 で、ダイアログ自体はポインタでなくメンバ変数としてそのまま持っておく、と。
シングルトンならそれでいいな
>>586 アプリケーションフレームワーク使ってないの?
>>589 delete thisってどういう挙動になるのかな?
delete this; // ハラキリ
delete this; // さようなら なら実際に見たことがある。
俺も
>>599 が何を言ってるのか解らん。
親と子ダイアログ、どっちを指してるのかも不明だが、それが
シングルトンであるかどうかが今の話にどう関係してくるってんだ。
> モーダレス上のボタンを押したときに親ウィンドウの変数や関数をいじりたいのですが。 ライブラリ化などして、後々まで利用するなら、親ウィンドウなり、 オーナーウィンドウに対して、ユーザー定義メッセージを投げるのが、 一番汎用性があるのでは? WPARAM,LPARAMで、操作したい内容(処理を特定するためのボタンのID等) を渡す。 DWORD値2個で足りなければ、他のメッセージと同様に、構造体 やクラスオブジェクトのポインタを渡す。 処理は、ユーザー定義メッセージを貰う親ウィンドウなり、オーナーウィン ドウ側にON_MESSAGE()のハンドラとして記述することになる。
>>595-596 いいかどうかは別にして、自分もやるし、何度もやったことある。
>>597-598 1回だけCreateして、Show/Hideで使い回す場合、2回目以降表示する際
には、モーダレスダイアログ側のOnInitDialog()が呼ばれないことを
ちゃんと理解していれば、それで問題ないと思う。
ダイアログが、親ウィンドウが持つパラメータや状態を表示したり、変更
する機能を持つ場合、同じ実体をリサイクルしてもいいけど、親ウィン
ドウ側にはダイアログのポインタをメンバに持たせて、表示時は、newした
後でダイアログのメンバ変数をセットしてCreateを呼び、非表示時は、
DestroyWindow()してdeleteしてしまうのが良いかと。
要約して書くと、こんなかんじ? ON_BN_CLICKED(IDC_BUTTONxx,OnShowHideDlg) CxxxxWnd::CxxxxWnd() { m_pDlg=NULL; } CxxxxWnd::~CxxxxWnd() /* virtual */ { if(m_pDlg) // 親が死ぬとき、子も道連れに死ぬ { m_pDlg->DestroyWindow(); // MFCならデストラクタで呼ばれるので省略可 delete m_pDlg; m_pDlg=NULL; // どうせ死ぬので省略可 } } CxxxxWnd::OnShowHideDlg() { if(!m_pDlg) // 非表示→表示 { m_pDlg=new CMyDlg; m_pDlg->m_numParam1=1; m_pDlg->m_strEditParam=_T("テスト"); m_pDlg->Create(this); // 表示時に毎回CMyDlg::OnInitDialog()が呼ばれる m_pDlg->ShowWindow(SW_SHOW); } else // 表示→非表示 { m_pDlg->DestroyWindow(); // MFCならデストラクタで呼ばれるので省略可 delete m_pDlg; m_pDlg=NULL; } }
CWnd::ShowWindow()で表示切替したほうが動作が軽いよ 前回開いてた状態で再表示されたほうが使い勝手も良さそう
まぁ、それも用途次第じゃないか 中身初期化しないならそれがベストだろし
612 :
デフォルトの名無しさん :2008/11/21(金) 15:07:35
ダイアログベースのMFCアプリです。(VS2005) 親ダイアログにタブコントロールを付けて、タブに更に子ダイアログがくっついている形です。 ダイアログウィンドウでOnSizeが渡されるのが、OnInitDialogより後なのは仕様ですか? CWnd::OnInitDialogが呼び出されるよりも前にOnSizeが来てしまうので、 サイズを一緒に調整したい子ウィンドウ全てに対してGetSafeHwnd()関数でチェックしてから サイズを変更しているのですが、もうちょっと効率的な方法はないですか? それと、なぜかウィンドウでエンターを押すとShowWindow(SW_HIDE)が渡されるのか、 子ダイアログは消えてしまうし、親ダイアログではアプリ自体が終了してしまいます。 何か対処法はありますか?
> なぜかウィンドウでエンターを押すと OnOKに飛んでいる
614 :
デフォルトの名無しさん :2008/11/21(金) 15:25:15
>>613 OnOKって自分で呼ばなくても勝手に呼び出されちゃうんですか…
てっきりIDOKボタンを押した(又はDefault Buttonに設定した上でエンターした)時だけだと思っていました。
これは自分でOnOKを空の関数にオーバーライドして、CDialog::OnOK呼ばないようにせざるを得ないと言うことですか?
> OnOKって自分で呼ばなくても勝手に その通り ESCを押すとOnCancelが呼ばれるのも同じ仕組み
618 :
612 :2008/11/21(金) 17:48:04
>>617 なるほど。よくわかりました。
っていうか、このスレのレスすらも確認しなくてスンマセン。
>>612 ダイアログ内に子ダイアログを置くのであれば、
子ダイアログの「Control」をTrueにしておいたほうがよいですよ。
子ダイアログだけ消えるということも無くなるはず。
612を見てなんでCPropertySheet&Pageを使わないのかと思ってしまったが言わない方がいいのか?
うん。言ったら恥かくよ。
と思ったらトップレベルウィンドウがダイアログなのか( ´ω`) ごめんよ
CodeGuruかどっかのサンプルを参考に、トップレベルのダイアログに、
>>620-622 位置決め用にスタティックコントロールを置いて、そのスタティック
コントロールに重ねて、動的にプロパティシート(CPropertySheet)を
貼り付けて、そのシートに、さらにCPropertyPageをAddPage()する
というコードを実際に書いたことあるけど?
>>612 > ダイアログウィンドウでOnSizeが渡されるのが、OnInitDialogより後
> なのは仕様ですか?
DoModal()を呼んだ場合、OnInitDialog()より前、OnCreate()の後に
OnSize()が呼ばれていると思うけど?
ダイアログリソースに貼り付けたコントロールではなくて、自分でコント
ロールを動的にCreate()しているのなら、コントロール作成より前には
呼ばれないでしょ。 そういうことではなくて?
625 :
デフォルトの名無しさん :2008/11/21(金) 22:37:42
>>624 あ、いや、ダイアログリソースで貼り付けて、DDXで関連づけたコントロールをOnSizeで調整しようとしているので、
DoDataExchangeで関連づけられる前にOnSizeが呼び出されるのが気にくわなかっただけでして…
(OnInitDialogはそれよりもあと)
あれ、UpdateDataを勝手に呼び出しちゃえば問題なかったですかね? もしかして。
今日からVC++を使い始めたCプログラマです。 IPAddressクラスからIPv4アドレスをDWORD値で取り出したいのですが どうすればいいのでしょう? CString hostName = Host; String ^strHost = gcnew String(hostName); IPHostEntry^ ipInfo = Dns::GetHostEntry(strHost); IPAddress^ ipAddr; for each (ipAddr in ipInfo->AddressList) { if (ipAddr->AddressFamily == System::Net::Sockets::AddressFamily::InterNetwork) break; } if (!ipAddr) /* この判定は超怪しい */ { /* とれなければLoopBackに強制 */ dwSvAddr = 0x7F000001UL; } else { /* dwSvaddr = *(DWORD *)ipAddr->getAddressBytes(); みたいなキャストがしたい */
.NETスレで聞きなさい たぶん.NETのデータ型をアンボクシングしてからキャストすればよさそうだが
628 :
624 :2008/11/22(土) 09:32:53
>>625 やりたいことがイマイチわからんのですが?
DoDataExchange()内のDDX_Control()で関連付けせずに、OnInitDialog()
内で、SubclassDlgItem()で動的に関連付け(サブクラス化)することも
できますが、コントロールの初期サイズはリソースで指定したサイズに
なるので、特定コントロールのみ例外扱い(リソース指定と異なるサイズ
にしたい)場合、そのコードはどこかに書く必要があると思います。
そもそも、OnSize()って、ダイアログのスタイルを「ダイアログ枠」で
なくて「サイズ変更枠」にすると、ダイアログをドラッグしてサイズ変更
したら、表示中はいつでも何回でも呼ばれる可能性がありますよ?
codeguru.comあたりの「CResizeDialog」を参考にしては?
みんなMFCでアプリケーションハンガリアン使うとき、どんな感じにしてるの?
>>628 DoDataExchangeよりも先にOnSizeが先に呼ばれてしまうから、
if (2回目以降のOnSizeだったら) {
コントロールのサイズ変更;
}
のような判定が必要になるのが気にくわないということでは?
>>630 本筋とそれる話で申し訳ない。
"2回目以降"でなくて、コントロールのhWndがIsWindow通るとかでいいんじゃね?
まぁOnSizeはwin32のWM_SIZEのままで、ddxはmfcの後付なんだからしょうがない
633 :
624 :2008/11/23(日) 11:35:19
>>630 > DoDataExchangeよりも先にOnSizeが先に呼ばれてしまうから、
DoDataExchangeとの順番は関係なく、最小化のタイミング等でもWM_SIZEは
飛んでくるから、何らかの判定は必要だと思うけど?
codeguru.comの「CResizeDialog」だと、ダイアログにCRect型のメンバ変数
を追加して、コンストラクタでCRect::Empyt()しといて、一発目のOnSize
で、CRect::IsRectEmpty()がTRUEなら、現在のダイアログサイズを変数に
取り込み、FALSEなら、直前のOnSize()時に取り込んだダイアログサイズと、
新しいサイズの差を計算して、子コントロールのダイアログ内での移動や、
サイズ変更をやっていたかと。
OnCreate()⇔OnDestroy()のように、明らかに逆で呼ばれることはないメッ
セージを除いて、安易にフレームワークが呼び出す順番に依存するような
造りにはしない方がいいのでは?
アイコンやビットマップを貼り付けるスタティックコントロールとか、貼り
付けたイメージのサイズに合わせて、コントロールのみ単独でOnSize()が
呼び出されることもあるし。
>>633 なんかかみ合ってないような。
一発目のOnSizeではDDXメンバがまだ設定されていないということですよ?
そのCResizeDialogというのは、派生用のダイアログクラスなんだろうから、
内部で子コントロールのDDXメンバを持ってるわけではないでしょう?
昔のソースを掘り返してみたら、
if (IsWindow(m_buttonOK)) {
m_buttonOK.MoveWindow(〜);
}
と自分もIsWindowを使っていた。
635 :
624 :2008/11/23(日) 12:36:46
636 :
624 :2008/11/23(日) 12:41:26
間違ってENTER押してもうた。(w
>>634 > なんかかみ合ってないような。
そもそも、なんでサイズ変更に際して、DDX_Control()での関連付けが
必要なのか全く説明がないし、自分が設計するとしても、その必要性を
まったく感じないんですが?
IsWindowか 俺はGetSafeHwnd派だ( ´ω`)
::IsWindow()とCWnd::GetSafeHwnd()なら普通は後者を使うでしょ?
HWNDキャスト派は異端ですか?
それもCWndメンバだからいいんじゃね? グローバルスコープなのを呼び出すなって話だろ
CWnd::GetSafeHwnd()って、m_hWndを返すだけであって、 そのウィンドウが存在しているかどうかはわからないのでは?
Create()が正常終了してないとm_hWndはNULL CWndの実体ができる時点でウィンドウが作られてるわけじゃないぞ
>>642 それはどこかで明記されてたっけ?
初期化していないポインタのようにゴミが入っている可能性は常に無い?
あとそれが大丈夫だとしても、
>>634 のようにDDXメンバの実体に対するものには
GetSafeHwnd()ではなくm_hWndで十分だと思うけど。
SDKで組んだこと無いのかよ
m_hWndの指すウィンドウが存在しないとか言い出したら、 そのハンドルが、実は他プロセスのウィンドウを指してしまっている状態すら、 考慮しないといけなくなるんじゃないか?
俺はm_hWnd派だったんだけどGetSafeHwnd()の方が安全そうだから乗り換えるわ でも、たぶんどっちでも良くて気分の問題
>>643 > それはどこかで明記されてたっけ?
> 初期化していないポインタのようにゴミが入っている可能性は常に無い?
挙動はMFCのソース見れば判るだろ。 というより、C++やクラスの本質
を理解しているのかと?
その理屈なら、CFileクラスのm_hFileメンバ変数や、CGdiObjectクラス
(CPen,CBrush等の基底クラス)のm_hObjectメンバ変数の値も信用できん
とな?(w
> あとそれが大丈夫だとしても...
『大丈夫だとしても』ぢゃなく『大丈夫でなければ』、どんな場面であって
も(m_hWndの値を返す)GetSafeHwnd()も、m_hWndの直接参照も使えない。
>>646 > たぶんどっちでも良くて気分の問題
んなことぁない。
直接参照する場合、thisポインタのチェックが入らないのに対して、Get
SafeHwnd()は、(CWndを指す)thisポインタが有効かどうかチェックした後
でthisポインタがNULLの時m_hWndの値を参照せずNULLを返し、thisポインタ
が有効な時のみメンバ変数m_hWndの値を返す。
クラスメンバとして実体が存在するオブジェクトに対して使う場合は、
>>643 氏の言うとおり。
問題はGetParent()などのようにCWndのポインタとしてNULLを返す可能性が
ある場合、戻り値をチェックせず、m_hWndを直接参照すると「0xXXXXXXXXが
無効なポインタを参照うんぬん」というエラーで落ちることになる。
自前のコードでチェックしてm_hWndを参照してもいいけど、どうせなら
そういう場合はGetSafeHwnd()を使った方がスマート。
同様に、CGdiObject::m_hObjectも、CGdiObject::GetSafeHandle()を
使った方がいい。
CWndの関数はm_hWndに対してそのままAPIを呼ぶようなものが多いから、 自分もNULLチェックではなくAPIのIsWindowに渡してチェックすることが多いな。
650 :
デフォルトの名無しさん :2008/11/24(月) 11:41:00
もしかして、冷蔵庫内のランプが消えたかどうか、冷蔵庫のドアを何回も 開け閉めして確認しちゃう人? IsWindow()呼んで戻り値をチェックした後で、APIを呼び出すまでの間に ウィンドウが消滅しているかもしれないという心配はしないの?(w
651 :
デフォルトの名無しさん :2008/11/24(月) 13:18:36
お取り込み中すみませんが、質問です。 ドキュメントビューアーキテクチャのSDIプログラムを作っているのですが、 メニューのハンドラってxxxDocment.cppに作成するのが良いのでしょうか? あと、設定データとかファイル入出力のデータの実態もxxxDocment.cppに 作成した方がよいのでしょうか?
>>650 それは別問題では?
IsWindow()でチェックしようがm_hWnd!=NULLでチェックしようが、
その後APIを呼び出すまでの間にウィンドウが消滅しているかもしれないのは同じ。
>>651 「表示倍率を拡大」なんていうコマンドならビューやアプリケーションだろうし、
コマンドの内容に依りますよ。
653 :
デフォルトの名無しさん :2008/11/24(月) 16:47:20
質問です、ダイアログのタイトルとかを表示している部分の 高さなどを知る方法ってあるのでしょうか? ┌──────────────┐ │たいとる .│←この高さが知りたい ├──────────────┤
654 :
デフォルトの名無しさん :2008/11/24(月) 16:52:38
>>653 ::GetSystemMetrics(SM_CYCAPTION);
でいけると思うが、未確認。
既存ソフトのバージョンアップ開発で、そういうの生値でやっててキレそうになったことあるわ 上にもあるようにGetSystemMetrics()でOK というか、GetSystemMetrics()からとれるやつは全部こっからとらないと、ちょっとしたWindowsのデザイン設定の違いでカオスになるからな
>>651 データにまつわる事ならDoc
見せ方(表示)にまつわる事ならView
アプリ全体(データ全体)にまつわる事ならMainFrame
本当にMainFrameなの?
自分は、アプリケーション全体や、全てのドキュメントに共通の設定は、 CWinApp派生クラスのメンバに登録しているなぁ。 一応、データ本体は、 protectedで、設定をGet/Setするヘルパ関数を用意している。 あと、メッセージハンドラはともかく、ドキュメントの表示方法(例えば 色やスタイルなどの見せ方)に関する設定値は、ViewではなくDocクラスに 持たせているなぁ。 これらの一部をViewに持たせると、ファイルに保存する際にViewクラスに アクセスしなければならないし、Viewが生成されてドキュメントに関連 付けされる前に、ファイルから初期値を読み込む時等に実装に困る。 CListViewクラスのLVS_REPORT等、ウィンドウが存在する時は、実質的に Viewもウィンドウ属性という形でそうしたデータを持っているけど、最初 にCreate()する際に、どの初期値でスタイルを指定するという場合に困る。
ドキュメントに保存するパラメータなら見せ方や色にしてもDocが持つべきだろうけど
たとえば表示倍率とかViewごとに変化する(保存する必要のない)データはViewが持って良いだろう
アプリ全体(複数のデータ)は、Appが持つのも良いと思う。
でもCWnd派生のMainFrameだとSetTimerとかPostMessageが使えるから
シーケンシャルな処理が入った時に便利なんで、MainFrameを使ってる
でも
>>651 の質問ってSDIだよな。1つのDocにViewが複数あるわけじゃないから神経質にならなくてもいいな
>>659 SDIはドキュメントが1つであって、ビューが1つではないですよ。
実際、エクスプローラスタイルで作成されたSDIはビューが2つあるし、
標準のスタイルでも任意にビューを増やせる。
Doc と View が 1:1 なら、分ける意味も薄いしな。
Viewが分割サポートする場合は1:1でもDocは必要だぜ
そっかSDIはDocが1つなだけでViewは1つとは限らないか
SDIの単純なエディタでも、CSplitterWndでViewを分割して、離れた場所の テキストを表示したりできるからね。
665 :
デフォルトの名無しさん :2008/11/26(水) 17:34:11
C**Doc::Serializeを使っているのですが、ファイルの保存や開くときのファイル形式を する方法はありますか?
666 :
デフォルトの名無しさん :2008/11/26(水) 17:35:42
訂正>> C**Doc::Serializeを使っているのですが、ファイルの保存や開くときのファイル形式を 指定する方法はありますか?
自分でSerializeを書けばいい
拡張子という意味ならリソースのString Tableで"IDR_アプリ名TYPE"の定義で指定 \nで区切られた何番目がどんな意味かはヘルプ参照 "IDR_アプリ名TYPE"は、InitInstance()の中でnewするCMultiDocTemplate()の第1パラメータ
669 :
デフォルトの名無しさん :2008/11/26(水) 18:32:50
助かりました!!
Win7では2D描画はDirect2Dがメインになるって聞いたが、旧Windowsをサポートするなら結局GDIの方がいいのかな
671 :
651 :2008/11/26(水) 23:35:46
皆さんお返事ありがとうございます。651です。 SDIといってもCFormViewをベースに、複数のダイアログを切り替えて表示するような プログラムを作っています。データの所在がそれぞれのダイアログに散らばってしまうと 管理が面倒なので今はDocumentクラスにすべて実体を持たせ、メニューのハンドラも そこにおいています。 みなさんの説明を要約すると基本的なセオリーとしては、 ・GUI等の画面表示に関係するデータ、ハンドラ: View(ダイアログ)に持たせる ・ファイル入出力に関するデータ、ハンドラ: Docに持たせる ・アプリ全体に関する設定: CWinAppとかMainFrameに持たせる と言ったところでしょうか。 データの中にはコンストラクタでデータ設定したりオブジェクト生成したりしていて その順番が問題になる事もありますので、その辺も考慮して決めたいと思います。
672 :
デフォルトの名無しさん :2008/11/27(木) 01:01:54
ボタンは、BM_SETSTATE で凹ませることができますが、 スピンコントロールの上ボタンや下ボタンを凹ませるには、 どのようなメッセージを送れば良いのでしょうか?
テクスチャサイズ8K×8Kって結構厳しいな。 家の7600GSじゃ4K×4Kが最大だから対応できないのか。
今更MFCの勉強したいんですがどの本読めばいいですか? ずーっと昔に買ってそのまま放置しておいたプログラミングVisualC++.NET基礎編があるのですが やっぱり新しい本を購入してやったほうがいいですか?
ソースコード読むのが一番遠回りで一番近道な気がしてきた 適当になんか作りたいだけならサンプル眺めてるだけでいいし
>>675 基本VS6時代の本でおK
というかあの頃の本が一番詳しく書いてある
VSが.NETになってからだとVC本がしょっぱい現実
MFCの勉強なら「Scribble サンプル : MDI 描画アプリケーション」 のチュートリアルを一通りやるといいよ VC6の時はSTEP1〜7までていねいに解説してあった
それMFCの最初のテーマとしては最悪だよ 何人がそれであきらめてやめたことか 悪いことは言わん 最初は、ダイアログアプリからやるべし
慣れてくれば、あのサンプルの意図するところも解るのだけどね。 最初にあれに手を出すと、確実に拒絶反応起こすこと請け合い。 ダイアログアプリ以外だと、Document-Viewを切ったSDIとかも練習には良いな。
とりあえずダイアログを使いこなせないとSDIは厳しいだろ SDIやるなら、適当にGDIの勉強とか、Doc-View-Frameとかの関係を理解するとか・・・良いサンプルないかな
薦めておいて何だが、そういえばScribbleは途中で投げ出した記憶があるな でもリソースエディタの使い方とかVSの操作は役に立ったような・・・
684 :
デフォルトの名無しさん :2008/11/28(金) 19:39:24
ダイアログベースのアプリからモードレスウィンドウを表示しているのですが ウィンドウを破棄する時に警告がでてしまいます 警告の内容はデストロイウィンドウが呼ばれてないといった内容で ダイアログを破棄するときに実際にデストロイウィンドウを呼んでみると 例外エラーが発生してアプリケーションが落ちてしまいます
685 :
デフォルトの名無しさん :2008/11/28(金) 19:40:28
質問はどうしたらうまくいくのでしょうか?ということです
CWnd::DestroyWindow()のかわりにCWnd::PostMessage()を使ってみては?
モードレスウィンドウのインスタンス生成やデータの持たせ方等で方法は
一つではないが、留意しなければいけないのは、モードレスウィンドウの
表示/非表示の繰り返しでメモリリークしないことと、「閉じる」操作など
で親ウィンドウが消滅した際に、モードレスウィンドウが開かれていれば
終了前に閉じれること。
ダイアログベースでメインウィンドウをモードレスに変更したのか、別に
モーダレスウィンドウを開くのか不明だが、後者と仮定しての一例...。
モードレスウィンドウ(Exp:CMyModalessDlg)を、ベースダイアログ(Exp:
CMyMainDlg)のメンバ変数(Exp:m_wndModalessDlg)にする。
App終了時にモーダレスを自動で閉じるため、CMyMainDlg::OnDestroy()に、
if(m_wndModalessDlg.m_hWnd)
m_wndModalessDlg.DestroyWindow();
を追加。 モーダレスの表示/非表示のハンドラは...
void CMyMainDlg::OnShowHideModaless() /* afx_msg */
{
if(m_wndModalessDlg.m_hWnd==NULL)
m_wndModalessDlg.Create(this);
m_wndModalessDlg.ShowWindow(m_wndModalessDlg.IsWindowVisible() ? SW_HIDE:SW_SHOW);
}
モードレスウィンドウのインスタンスをnewで生成していないので、
CMyModalessDlg::PostNcDestroy()で「delete this」やっていたら
削除。
>>587 - あたりも参照のこと。
ていうか、CDialogを上手く隠ぺいしたら、モーダレスダイアログの抽象クラスくらい作れそうな気がするな IDDあたりも工夫して・・・
抽象クラスって意味判って言ってるのか?
何もおかしくないと思うぞ CDialogのような使い方は出来ないと思うけど
692 :
デフォルトの名無しさん :2008/11/29(土) 03:03:13
Viewの中でCEditをcreateで生成して用いているのでPreTranslateMessageで キー入力を認識しているのですが、ctrl+Cなどコピペや複合の入力を検知する方法はありますでしょうか。 XP+VC2005です。
>>691 なんでnew使うの?
{
CWaitDlg wait;
wait.Create(this);
// 処理
wait.DestroyWindow();
}
でいいと思うのだけど。
破棄のタイミングに拘らなければブロック化({})すら要らない。
>>693 あんまり意味ないです
貼り付けたサンプルがたまたまそうだったからという理由だけですw
>>691 CTestDlg::PostNcDestroy()にdelete this;って記述されてるので例外が発生したんじゃないの?
>>692 リソースに記述してCOMMAND_UIあたりで処理するのではなかったっけ?
>>695 >CTestDlg::PostNcDestroy()にdelete this;って記述されてるので例外が発生したんじゃないの?
いや、なんかよくわかりませんでした
とりあえず、モードレス側に書く処理はCreate関数だけで
削除は親に全部まかせるのがいい気がします
>>693 >>694 モードレスの場合はダイアログの作成と破棄のタイミングが違うのでメンバに抱えてnewを使う
>>697 モードレスとモーダルを同じダイアログで使いまわす状況なんてないんじゃね?
何れにしても、わざわざnew/deleteして使わなくてもいいだろ。 ダイアログが閉じられたからといって、 クラスのインスタンスを即座に破棄しなければならない理由は無い。 別々の派生クラスを時と場合に応じて使い分ける、とかいうなら話は解るけど。
>>699 じゃあモードレスの場合にダイアログが作成されてるか破棄されてるかはどうやって判別すんの?
画面に線だけを書きたいときは領域を塗りつぶしてから書いたほうがいいですか?それともなんかコントロールを置いてそれに書いたほうがいいですか?
領域を塗りつぶしてから書いたほうがいい
>>700 用語が曖昧だからなんとも言えないけれど、モードレスダイアログが実際に表示されているのかされていないのか、
そのダイアログ自身以外に一体全体誰が気にしなければいけないというの?
そのダイアログのインスタンスを持っている側にとっては、出ていて欲しいときに出せと要求するだけで充分でしょ。
塗りつぶして線を引いた、領域と同じサイズの絵を描画した方がいい
>>700 質問元のモードレスダイアログは、処理中ダイアログみたいだから、
判別する必要ねえんじゃね?
ユーザーによるオペレーションで表示/非表示するようなやつの場合、
俺は(複数表示する必要なかったので)シングルトン的なものにして対応したんで、
作成されている/いないを判別するは必要なかった。
707 :
706 :2008/11/29(土) 21:24:28
リロードせずにレスした。 反省した。 次はリロードする。
>>706 処理中ダイアログって考えはなかったわ
でも1ハンドラ内に
>>691 の記述でモードレス中ダイアログを表示できたっけ?
>>703 表示/非表示じゃなくダイアログの作成/破棄な CDialog::Create()とCWnd::DestroyWindow()
インスタンスの生成/破棄(new/delete)とも別だよ
>>708 PeekMessageでもはさむんじゃね?
>>709 事情は変わらんだろ。ダイアログ自身が管理していれば、利用者はそれを意識する必要はない。
俺はそもそも モードレスとモーダルをいっしょのクラスで分岐させる無意味な汎用性と Createされてる状況でCreate関数を再び呼ぶ必要を考慮してるクラスの仕様のが 気持ち悪くていまの話題についていけないけどね
いっそのこと新しいC++向けのMS製フレームワークを提供してほしいわ .NETは相性悪すぎる せっかくDirect2DとDirectWriteもC++向けに提供するんだし、アプリケーションハンガリアンでエレガントなクラス群を是非
>>711 モードレスダイアログのサンプル書いてみてよ
>>714 CWaitDlg wait;
wait.Create(this);
// 処理
wait.DestroyWindow();
>>715 処理中ダイアログじゃなくてOKボタン押すまで表示されてるモードレスダイアログのサンプル書いてみてよ
>>716 CWaitDlg wait;
wait.Create(this);
while(1){
PeekMessage
GetMessage
TranslateMessage
DispatchMessage
if(ボタンが押されたら)break;
//処理
}
wait.DestroyWindow();
>>718 モードレスのサンプルになってないよ
その用途ならモーダル使うのが普通じゃん
>>719 プログレスバーが表示できるじゃん
質問元が思いっきりそういう意図じゃん
普通だったらモードレスなんてつかわねぇよ
正直いってバグりやすいもん
大部分がこんな感じで済むんだよ
721 :
706 :2008/11/29(土) 23:49:45
>>708 1ハンドラでの処理は考えてなかった。 てか忘れてた。
new/deleteの話いらないって話なんだから、1ハンドラだね。
そういうわけで、
>>706 はなかったことに。
(
>>710 の通りやればできそうだけど、確認したくないという事情によります)
まったく持ってごめん。 反省した。 次は、、次も、、とり頭だからやってしまうかもしれん。
>>716 どっかのクラス
{
CWaitDlg m_wait;
};
どっかのクラス::モーダレス表示するハンドラ()
{
wait.Create(AfxGetMainWnd());
}
これで、親クラスが消滅するかダイアログの「×」ボタン「OK」または
「Cancel」ボタンがクリックされるまで表示されたままになる。
>>719 モードレスだが?
>>722 スレッドを起こせばいい。
>>724 > wait.Create(AfxGetMainWnd()); ... 誤
m_wait.Create(AfxGetMainWnd()); ... 正
>>723 ダイアログ自身が管理する形で書かれていないので
CWaitDlgが管理するようにしたいんだけど
>>724 m_wait.Create(AfxGetMainWnd());が2回呼ばれたらマズくない?
m_wait.DestroyWindow();は必要ないの?
>>726 何を管理する?ちゃんと日本語で書けよバカSEよ。それとも低級な魔法
使い気取りか?
>>727 > m_wait.Create(AfxGetMainWnd());が2回呼ばれたらマズくない?
概念の説明だけでなく、エラー処理まで手取り足取り見なきゃならん
のか?
if(m_wait.m_hWnd=NULL)
m_wait.Create(AfxGetMainWnd());
とでもしておけばいい。
> m_wait.DestroyWindow();は必要ないの?
MFCの場合、明示的に呼ばなくても、m_waitのデストラクタ内で
DestroyWindow()が呼び出される仕様。
CFile::Close()等も同様。
>>729 呼ばれなくね?
とりあえず俺の環境では
Warning: calling DestroyWindow in CDialog::~CDialog --
OnDestroy or PostNcDestroy in derived class will not be called.
って警告がでちゃうよ
>>730-731 MFCのソースも読めないし、トレースの仕方も知らんと恥を晒している
ようだな。 まさに宝の持ち腐れ。 豚に真珠ってヤツだ。
その警告メッセージは、MFC(デバッグ版ライブラリ)が出している。
CDialog::~CDialog()
{
if (m_hWnd != NULL)
{
TRACE0("Warning: calling DestroyWindow in CDialog::~CDialog --\n");
TRACE0("\tOnDestroy or PostNcDestroy in derived class will not be called.\n");
DestroyWindow(); // ← ここで呼んでるだろうが、ボケ!!!
}
}
ついでに、英語も理解できないおまえらに、低学歴の漏れが警告メッ
セージの意味を解説してやると、
『テメェが忘れてるから、デストラクタ内(CDialog::~CDialog())で
ケツ拭きでDestroyWindow()呼んでやるが、今からじゃ手遅れで派生
クラスのOnDestroy()やPostNcDestroy()は呼ばれねぇけど、間違っても
Windowsのバグとか、ゲイツ様のせいにすんじゃねぇぞ、ゴルァ!』
ってこった。
そんなことは、皆了解済みの上で話していると思うのだがどうか。 わざわざトレース文が入っているようなお情け処理を、 正式な仕様として扱う勇気は俺には無いな。
>>688 >>716 今までの話を整理したらこうなった
void CPropertyDialogSampleView::OnEditProperty()
{
m_propertyDlg.Show();
}
CModelessDialogBase::~CModelessDialogBase()
{
if (CWnd::GetSafeHwnd() != NULL)
CWnd::DestroyWindow();
}
void CModelessDialogBase::Show(CWnd* pParentWnd = NULL)
{
if (CWnd::GetSafeHwnd() == NULL)
CDialog::Create(GetTemplateID(), pParentWnd);
CWnd::ShowWindow(SW_SHOW);
CWnd::BringWindowToTop();
}
void CModelessDialogBase::OnOK()
{
CWnd::ShowWindow(SW_HIDE);
}
void CModelessDialogBase::OnCancel()
{
CWnd::ShowWindow(SW_HIDE);
}
>>733 でもそこなんでトレースいれるんだろうね
少なくとも俺の感覚としちゃそこでDestroyWindowを呼ぶのは当然の処理で
警告なんて出す意味がわからないんだけど
CreateとDestroyWindowが対だからじゃね? コンストラクタでCreateしないからデストラクタでもDestroyWindowしない方針
>>736 しろよな
しない方針にすることでなにかいいことあるのか?って感じ
Create関数のヘルプにもそんなこと書いてねーし
DestroyWindow関数のヘルプには
MFC側で呼んだり呼ばなかったりするからユーザー側でうまくやれよマジで
とかかなりむかつく仕様だしで作った奴マジ嫌な感じだな
738 :
732 :2008/11/30(日) 10:06:48
>>733 > そんなことは、皆了解済みの上で話していると思うのだがどうか。
理解したり、(実際に呼ばれていることを)知っていたら『呼ばれなくね?』
なんて発言は、マヂでありえなくね。(w
C++の基本を理解し、警告メッセージの意味を正しく理解していれば、
> わざわざトレース文が入っているようなお情け処理を、
> 正式な仕様として扱う勇気は俺には無いな。
なんて発言も出てこないハズ。
739 :
732 :2008/11/30(日) 10:08:09
>>735 CDialogクラスのデストラクタで呼び出しているので、(この時点では
派生クラスのメッセージマップや仮想関数テーブルを参照できない、
もしくは存在自体を知りえないため)派生クラスのOnDestroy()やPost
NcDestroy()は呼ばれないだけ。 当然ながら、CDialog::OnDestroy()
やCDialog::PostNcDestroy()の呼び出しは行われる。
派生クラスのOnDestroy()やPostNcDestroy()で独自の実装(例:閉じた
時のウィンドウサイズを取得してレジストリやINIファイルに保存する
等)を呼び出していなければ、デストラクタに処理を任せてもなんら
問題ない。
だからこそ「Error:」じゃなく、あくまで「Warning:」ってなってる。
CFileクラスのデストラクタや、CGdiObjectクラス(CPen,CBrush等の基本
クラス)のデストラクタでも同様のことをやっているけど、これらはメッセ
ージループを廻す必要がないので、TRACE記述はない。
740 :
732 :2008/11/30(日) 10:13:43
>>736-737 こういう文句を言う連中は、MFCはおろかC++の基本的な仕様(派生クラスと
基本クラスのコンストラクタ/デストラクタが呼び出される順序や、仮想
関数など)さえロクに理解していないんだろうナァ。
方針なんて関係ない。強いて言えばデザインパターンってやつか?
コンストラクタでデフォルト値を代入してメンバ変数の初期化忘れを防ぐ
とか、デストラクタでメモリやハンドルの解放忘れを防ぐというのは、
基本中の基本。
インスタンスの消滅で確実にウィンドウを破棄し、なおかつ派生クラス
のOnDestroy()やPostNcDestroy()も呼び出されるようにしたければ、MFC
内部の実装に関係なく、派生クラスのオブジェクトが消滅するタイミング
でDestroyWindow()を呼び出せばいいだけ。
すなわち、自分が作るCDialog派生クラスで、デストラクタ関数を定義し、
m_hWndが有効ならDestroyWindow()を呼び出してやればいい。
class CMyDialog : public CDialog
{
virtual ~CMyDialog();
};
CMyDialog::~CMyDialog()
{
if(m_hWnd!=NULL)
DestroyWindow();
}
ただそれだけのことだ。
>>740 でもヘルプでだってどういうときに
DestroyWindowを呼ばなきゃいけないのか書いてないわけだし
当然MFCの中身の都合なんてこっちはしったこっちゃないわけで
もし、自分でこういうもんを作るとしたら解放はフレームワークのほうで自動でやってほしいかな?
>>740 のコードがまずいというのもわかりにくいしな
何この流れ どうせお互いまったく譲り合わないんだから、これ以上書いても無駄だよ
Win7ってペイントとかワードパッドにリボン採用してるよな 今後作るソフトはリボンで作った方が惹きやすいのだろうか・・・2008SP1は持ってるが
746 :
732 :2008/11/30(日) 20:41:12
>>743 何を言いたいのかな? 根拠があるなら問題点を明示すればいい。 でき
ないなら、黙っておくことだ。
GetSafeHwnd()を使わずm_hWndを直接参照していることが問題だとでも
言いたいのかな? だとすれば、C++の仕様を理解していないと自白して
いるようなもの。
C++の仕様ではNULLに対してdeleteを呼び出しても何も行われないことが
保証されている。「delete (CWnd *)NULL;」では何も起こらない。
つまり、デストラクタ関数のアドレスを関数ポインタに取得して明示的に
デストラクタを呼び出すなんて使い方をしない限り、deleteからデスト
ラクタが呼ばれた時点で、thisポインタの値はNULLではない。
だから、この場合this->m_hWndで直接参照してもなんら問題ない。
SAFE_DELETE(x)
>>746 自動削除の仕組みと相性悪いよそれ。
自分だけで使うのにとどめといたほうがいい
> 416 :デフォルトの名無しさん:2008/03/06(木) 00:50:58 > SAFE_DELETEを使ってるのを見ると > ああ10年前に学ぶのを止めてしまったんだなと分かる > 自分自身がSAFE_DELETEされてしまったんだ
750 :
733 :2008/11/30(日) 21:40:07
>>745 メニュー項目が多い場合はリボンも良いけど、
基本はメニュー非表示でツールバーだけ、って感じで良いんじゃないかなあ。
あと、進む・戻るボタンがこっそり標準UIになりつつある気がする。
>>746 とりあえず落ち着け。誰もそれが駄目だなんて書いてないぞ?
>>739 「派生クラスのOnDestroy()やPostNcDestroy()は呼ばれない」ってのが
期待している挙動と異なるので「デストラクタに処理を任せてもなんら問題ない」とは思えない
>>751 はなしがむずかしくて、りかいできないんだね。
>>751 「問題ない」しか読んでないのか?その段落ちゃんと嫁。
つか、書いてないコードが呼び出されるのを「期待している」のは莫迦すぐる。
756 :
754 :2008/12/01(月) 21:09:29
VC++ 2008 SP1(Feature Pack)でレジストリじゃなくてiniファイル(またはXMLファイル)に設定書き込むクラスってどこかに無い? レジストリ汚すソフトは嫌われるのだがな・・・
iniファイルなら直API XMLならMSXMLを使うのが一般的じゃないかな MFCでラッピングしているクラスは知らない
>>759 レスd
あー具体的には、CWinAppEx クラスでウィンドウ情報が勝手(?)にレジストリ登録されるので、ファイルへの書き込みに変えたいのです
VC++2008 SP1が出たばかりで情報がないみたいです。あと半年ROMることにします
APIだとWritePrivateProfileStringかな
>>761 >760はINIファイルへの書き込み手段を探しているのではなく、レジストリ書き込みをさせない手段を探しているようだよ。
>>760 勝手にレジストリに登録する迷惑なやろうって
SetRegistryKey だったりする?
一時、BoostのRegexでテキストファイルのパーサーを自作していた時期があったな。。。 INIのAPIって、レジストリ用のAPIと共有しているんだっけ あの辺あんまり使わないから、よく分からんw
どこかのサイトでレジストリでなくiniに飛ばさせる方法を見たような しかしMS自身がXML勧める時代に、勝手にレジストリに書きにいくなんて…
>>763 うん
CWinApp::SetRegistryKey()を呼び出さないよう変更したらINIファイルに登録されたハズ
SetRegistryKey呼ばなけりゃ、iniに書きに行くけど、OS側の設定で iniファイルに書こうとするとレジストリに書くiniファイルマッピングというのもある どちらもすり抜ければiniファイルに書くが、その場所がexeと同じディレクトリで Program Filesだったりすると今度はVistaではまる。
>>767 >>768 CWinAppExはレジストリ前提だからSetRegistryKey()を呼ばないと動作しなくなる。(落ちる)
だから
>>765 が正解。
CWinAppは?
MFC勉強するのにいいホンってあります?
ちょっと調べたらCWinAppExクラスには、アプリケーションの既定のレジ ストリパスを取得/設定する、GetRegistryBase()/SetRegistryBase()って メンバ関数があるね。 例によってあまり役に立たないヘルプには、SetRegistryBase()のデフォ ルト引数「NULL」を指定した時の挙動が説明されていないけど、おそらく 下請けでCWinApp::SetRegistryKey()が呼び出されているだろう。 あとは、MFCのソースをトレースするしかないな。 XMLは、自分はC++のオーバーロードを使って指定のデータ型とXMLデータを やりとりしたり、ノード名を指定してXMLツリーを検索するとか、Read_XML() /Write_XML()という仮想関数を持つ、CObject派生のCXML_Objectクラスとか、 MSXMLを呼び出す汎用関数やライブラリを作ったなぁ。 ところで、SOAPの扱いってどうなったんだろ?
SOAP Toolkit の最終版である3.0は、 2008/05/31をもってサポートが完全に打ち切られている。 SOAPやるなら.NETで、って方針だったようだ。
お、これMFC9.0のクラスか MFC本スレでありながら、この認知度は問題ないか?w
>>776 おぉっ、なるほど。
これで.iniに保存するようにして
CWinAppEx::SaveState()で
CDockState::SaveState()が呼ばれ更に
CWinApp::WriteProfileInt()が呼ばれて勝手にレジストリに保存されるという
中途半端な実装を目の当たりにするわけですね?
>>778 うちのプログラムも CSettingsStoreSP クラスでINIファイルに保存するようにしたが、
レジストリに ControlBars-Summary のキーができていた
ダメすぎオワタ
CComboBox::ResetContent
782 :
780 :2008/12/05(金) 16:09:09
>>781 THX!
--
>コンボ ボックスのリスト ボックスとエディット コントロールからすべての項目を削除します。
--
あー、「文字列」じゃなくて「項目」を削除か。MSDNは思い込みを持たずに読まなければならないのを忘れてた。
これで納得。MSDNのサンプルの馬鹿さ加減は兎も角。
>ComboBoxに関しては、すべてのアイテムを1発で消すことができる便利関数が用意されていない。
--
うーん、3年前にこれって……
カーソル位置か、座標上にあるクライアント領域のウィンドウかコントロールのハンドルを取得する関数ってなんですか?
ドロップダウンリストのコンボボックスに文字列を入力したいのですが SetDlgItemTextでは値が表示されません 何かいい方法ないでしょうか?
代わりにSetDlgItemTextを使う
>>786 代わってねぇ〜
SetWindowTextだよな?
>>787 駄目です
SetWindowTextでも
かわりませんでした
「変わらない」のか「使い方が間違ってる」のかは別問題だよな
表示だけだったら複数のコントロールで構成されてるのを考慮するまでもなかったと思う。
>>785 ダイアログの(オブジェクトではなく)ウィンドウが存在する状態で、
ちゃんと正しいコントロールIDと文字列を指定していれば、SetDlg
ItemText()でいけると思うが?
まさか、
CMyDlg wndDlg;
wndDlg.SetDlgItemText(IDC_COMBO1,_T("テスト"));
wndDlg.DoModal();
とか、
CMyDlg wndDlg;
wndDlg.m_wndComboBox.SetWindowText(_T("テスト"));
wndDlg.DoModal();
なんて書いていないだろうな? DoModal()やCreate()を呼ぶ前は、ウィン
ドウが生成されていないので、SetWindowText()やSetDlgItemText()は
使えない。
DoModal()でコンボボックスに表示される初期文字列を指定したいなら、
ダイアログクラスにCString型のメンバ変数を追加して、DoDataExchange()
内で、DDX_CBString()を使ってコンボボックスに関連付けておき、DoModal()
を呼ぶ前に、CString型のメンバ変数に文字列をセットする。
wndDlg.m_strComboBoxText=_T("テスト");
wndDlg.DoModal();
>>791 ちゃんとOnInitDialogでやってるのですが
どうもドロップダウンリストだと駄目っぽいです
ちなみにドロップダウンだといけます
>>792 そりゃ、ドロップダウンリストは、リストボックスの項目内からしか
選択させない仕様だから、ダメに決まってる。
あらかじめ文字列のインデックスが判っていればSetCurSel()で直接指定
して文字列を選べるが、そうでなければFindString(-1,"文字列")でリスト
ボックス全体から文字列を探して、なければAddString()して、SetCurSel()
するしかない。
いずれにしろ、「ドロップダウンリスト」スタイルではリストに追加されて
いない文字列は表示できない。
>>793 いえ、リストにないものを表示したいわけではなくてですね
SelectStringという関数で文字列を指定するといけるということがわかったので
今度はコントロールを判別(エディットかコンボか?)しようとしてます(笑)
何がやりたいかというと
大量のIDリストからループで文字列をセットしてるわけです
そのIDリストにコンボボックスのドロップダウンとドロップダウンリストとエディットボックスが
混じってしまっているのでなんとか全部に突っ込めないものだろうか?
と考えていたわけです
>>794 何がヤリたいのか今ひとつ判らんが、一番お手軽な方法は、resource.h
を直接編集して、コントロールの種類毎に、コントロールIDに割り当てる
値の範囲を分けてしまうことだな。 関数を分けた方がいいと思うけどな。(w
#define IDC_EDIT1 1000
#define IDC_EDIT2 1001
#define IDC_EDIT3 1002
…
#define IDC_COMBO1 2000
#define IDC_COMBO2 2001
#define IDC_COMBO3 2002
…
ムリヤリデッチ上げてみた。 void CMyDialog::PresetString(UINT nCtrlID,LPCTSTR lpszDefaultString=NULL,const CStringArray *pListBoxText=NULL) { if(IDC_EDIT1<=nCtrlID && nCtrlID<=IDC_EDITxx) // エディットコントロール { CEdit *pEdit=(CEdit *)GetDlgItem(nCtrliD); ASSERT(pEdit); pEdit->SetWindowText(lpszDefaultString): } else if(IDC_COMBO1<=nCtrlID && nCtrlID<=IDC_COMBOxx) // コンボボックス { CComboBox *pComboBox=(CComboBox *)GetDlgItem(nCtrliD); ASSERT(pComboBox); if(pListBoxText) { for(int n=0;n<pListBoxText->GetSize();n++) (pComboBox->AddString(pListBoxText->GetAt(n)): if(lpszDefaultString && lstrlen(lpszDefaultString)) SelectString(lpszDefaultString); } } } ※ resource.hを編集したら、リビルドしなおすこと。
>>795-796 おお、そういう方法もありましたか
ありがとうございます
私の方は
ウィンドウクラス名を取得する方法をみつけてきました
char temp[256];
memset(temp,0,sizeof(temp));
GetClassName(cmb->m_hWnd,temp,sizeof(temp));
if(0 == strcmp(temp,"ComboBox")){
((CComboBox*)cmb)->SelectString(-1,"あいうえお");
}
リソースはみんなでつつきまくって編集不能(笑)な状態になっているので
とりあえずこっちのが楽そうなんでこっちでいきます
ありがとうございました
>>797 クラス判定にはCObject::IsKindOf()を使うのが一般的だお
if (pCtrl->IsKindOf(RUNTIME_CLASS(CComboBox)))
((CComboBox*)pCtrl)->SelectString(-1, "あいうえお");
今回の場合、CComboBoxに関連付けられていない可能性があるから、 その方法は無理っぽいかな。
サブクラス化ってもしかして ウィンドウに張り付けたボタンのメッセージを拾うためにボタンの派生クラスを作らなくてもサブクラス化すればウィンドウに全部メッセージ来るってこと?
>>800 C++のクラスとサブクラスのクラスは違うんだよ
あんまり関係ない
ダイアログエディタで「Use System Font」をTRUEにすると 「...」などの表記がすごく幅を取るブサイクなフォントになるのですが、 これってユーザの環境が反映されるものなのですよね? どこで設定されているものなのでしょうか?
CChildViewでスクロールバーを使いたいのですが、 やはり自力で、 void CChildView::OnHScroll(UINT nSBCode, UINT nPos, CScrollBar* pScrollBar) 等のイベントで、スクロールバーいじるしかないのでしょうか?
CScrollViewから派生すれば
805 :
デフォルトの名無しさん :2008/12/09(火) 21:01:23
MDIでViewにeditboxをおいているのですが、ウィンドウ全体を最小化とか した後に再びフォーカスが当たったときにeditboxがアクティブになりません。 いい方法はありますでしょうか?
メモリの使用可能容量、現在の使用量って数値で取得することは可能なのでしょうか。 MFCの枠から外れそうな気もしますが。 メモリが不足したときにメッセージが返ってきたり、メモリ確保している部分にtry catch文を仕掛けてもいいのですが、 そうなる前に余裕を持たせたい+リアルタイムで監視したい等の理由があります。
自前でメモリを監視できる関数を作ってそれを使うとか?
PROCESS_MEMORY_COUNTERS MemInfo ; HANDLE hProcess ; hProcess = OpenProcess( PROCESS_QUERY_INFORMATION|PROCESS_VM_READ, FALSE, GetCurrentProcessId() ); GetProcessMemoryInfo( hProcess, &MemInfo, sizeof( MemInfo )) ; LOG4CXX097_INFO( Logger::getLogger( "ProcessMemoryInfo" ), "WorkingSetSize="<<int(MemInfo.WorkingSetSize)<<", PageFileUsage="<<int(MemInfo.PagefileUsage)<<", hProcess="<<std::hex<<hProcess ) ; CloseHandle( hProcess ); パクリ改造だからほぼそのまま晒す
#include <psapi.h> #pragma comment(lib, "psapi.lib") あと、これが必要だな
>>806 使用可能とか使用量とは、システム全体での値? それとも実行中の自
プロセスに割り当てられた分? あるいはスレッド単位や別のプロセス?
システム全体なら、Win32 APIのGlobalMemoryStatus()または改良版の
GlobalMemoryStatusEx()かな。 前者は95系のOSでもサポートされている
けど2GB以上は正しい値を返さない。 後者は2000以降でのみ使えるけど、
2GB以上のメモリにも対応。
プロセス単位で詳しく知りたい場合は、Inside Windowsあたりで解説され
ている。パフォーマンスメータ関係のAPIだったかな。
ただ、リアルタイムで監視といっても、常時切れ目なくメモリ状態変化を
監視はできない(定期的にメモリ状態取得しても、直後に別プロセスで大
きなメモリ領域を確保されてしまう可能性がある)し、スラッシングで
空きメモリがあっても要求した連続メモリが確保できず、malloc()に失敗
する場合もあるので、戻り値のチェックを省略することはできない。
>>805 MDIのViewは、CViewやCScrollViewからの派生クラス? それとも
CFormViewからの派生クラス?
前者なら、コードを書いてCEditを動的に配置しているんだろうけど、
CEdit::Create()時にEditコントロールの親にViewを指定していない
のでは?
後者なら、ダイアログエディタでEditコントロールを配置するだけで、
あとは勝手にプログラムがリソースから読み込んだフォームで親子
関係を設定してくれるから、プログラムで余計なことをしない限り
質問のような結果にはならないはず。
812 :
デフォルトの名無しさん :2008/12/10(水) 01:16:49
>811 createEx時にthisを指定しているのですが・・・うまくいかないです ウィンドウがアクティブになったときにC〜Viewに通知されるイベントがわかると setFocusで何とかするのですが、イベント分かりませんか?
CView::OnActivateView()かも
>>812 > createEx時にthisを指定しているのですが・・・
CreateEx()を呼んでいる場所は、ビュークラスのメンバ関数内ですよね?
また、メンバ関数は、OnInitialUpdate()など、ビューのウィンドウが
生成されてた状態で呼ばれるメンバ関数ですよね?
thisが指すウィンドウが生成されていない(m_hWndが無効)なビューの
コンストラクタや、thisがビューを指していない他のクラス等では、
親子関係が正しく設定されません。
そもそも、MFCのCEditクラスのメンバにCreateEx()はなかったかと。
CreateExを使っているのは拡張スタイルを指定したいからだと思い
ますが、これはどの関数でしょう? また、スタイルの指定には
WS_CHILD と WS_TABSTOP が含まれていますか?
あとクラス名の指定とかどうなってます?
面倒でもCEdit::Create()でウィンドウを生成した後で、GetExStyle()と
ModifyStyleEx()で拡張スタイルを変更してみては?
815 :
814 :2008/12/10(水) 09:41:30
こんなページがありました。
ttp://m--takahashi.com/bbs/pastlog/a1700/A1618.html 上記のページを見るまで、CEditの場合、Create()でウィンドウを生成した
後でGetExStyle()とModifyStyleEx()で拡張スタイルは変更できないって、
すっかり忘れてました。(w
アクティブにならないと言うのが、ビューがアクティブになった際に、
エディットにフォーカス移動しない(カレットが表示されない)ということ
であれば、ダイアログと違って、ビューのデフォルトハンドラにはそういう
処理が含まれていないので、フォーカス移動の位置を記憶するメンバ変数を
ビュークラスに追加してCView::OnActivateView()などで自前で実装する
ほかないと思います。
816 :
デフォルトの名無しさん :2008/12/11(木) 16:36:50
MFCのダイアログアプリで質問です。 画面上のボタンを押すとWindowsForm画面を開いています。 こんな感じです ボタンの処理 Form1 ^ fm = gcnew Form1; fm->Show(); 画面は普通に開きますが 別プロセスみたいにメイン画面の下に隠れます 親ハンドルを指定すればいいのかな?と思い 下のようにしても裏に隠れます Form1 ^ fm = gcnew Form1; fm->Show(fm->FromHandle(GetSafeHwnd())); 親子関係にするにはどうやればいいのかわからないです。 fm->Parentやfm->Ownerを設定してもダメでした MFCダイアログとWindowsForm画面の親子関係は無理なんでしょうか? やりたいことはMFC画面上に.NETコンポーネントである グラフコントロールを表示したいだけです。 素ではダイアログに組み込めないのでWindowsForm画面に組み込み 子画面として特定の位置に固定させようとしています。 画面は表示できたのに位置合わせだけがダメです。
>>816 FromHandleだと.NET以外で作ったウィンドウはダメだと思う。
多分fm->FromHandle(GetSafeHwnd())がnull参照返してると思う。
自分でIWin32Window実装してやらないとダメなんじゃないかな。ヘルパークラスがあるような気もするが。
詳しく知りたかったら.NETスレ行った方がいいと思う。
スライダーを変更したとき、 変更前の値と、変更後の値を取得したいのですが、 どのイベントでとればいいのでしょうか? OnHScrollだと、変更後しか見れまえん
>>818 1つ前のCWnd::OnHScroll()の値を覚えとく
820 :
812 :2008/12/11(木) 23:44:02
なるほど!ありがとうございました!
>>817 ありがとうございました
.NETの方で聞いてみます
MFCで拡張ペンを使いたいんですが、まずはCPenクラスを宣言して作成後 ExtCreatePenで作ったハンドルをm_hObjectに入れてやればいいんですかね?
引数が多いほうのコンストラクタがExtCreatePenを呼んでいるので、 わざわざAttachする必要は無し。 というか、ソースが提供されているのだから疑問に思ったら読もうぜ。
824 :
デフォルトの名無しさん :2008/12/14(日) 23:40:03
MFCアプリって画面に1つコントロール(C****View)しかおけないのですか?
よくわからんけどXXXVIewなら MDIにすればいいんじゃね?
SDIでもエクスプローラのような2ペインとかタブ作ってに置くことは可能。 スプリッタウィンドウやタブを親ウィンドウにして作れる。 MDIはドキュメントが複数作れるだけで関係ない。
827 :
デフォルトの名無しさん :2008/12/15(月) 16:16:08
メモ帳の検索ダイアログみたいな感じで、C**viewから呼び出したモードレス上のてきすとを ボタンを押してC***Viewの関数で処理することってできますか?
winで他のソフトができることならできないわけがない。
829 :
デフォルトの名無しさん :2008/12/15(月) 17:47:53
つまりどうすれば?
通常はメッセージでやりとりする。
831 :
デフォルトの名無しさん :2008/12/15(月) 17:59:52
メッセージで文字列はおくれないですよね?
832 :
デフォルトの名無しさん :2008/12/15(月) 18:24:34
>>831 同じプロセスならできないこともないが、、、
コモンダイアログの検索を試しに使ってみては?
これでもデータのやり取りやってるぞ。
共有メモリ使えばよくね?
モードレスウィンドウをわざわざ別プロセスで作るって、どんだけ物好きやねん。
自分の子供であるモードレスにthisを渡してあげなよ
まぁ方法なんていくらでもあると思うけど、SDIならわざわざthisとか渡さ なくても、流れ的にはこんなやり方でいけると思う。 #define UM_SEARCH_EXEC (WM_APP+1) class CMySearchDlg; class CMainFrame : public CFrameWnd { CMySearchDlg m_wndSearchDlg; }; void CMainFrame::OnSearchExec(WPARAM,LPARAM) { CString strSearchText; m_wndSearchDlg.GetDlgItem(IDC_EDIT1,strSearchText); if(!strSearchText.IsEmpty()) SearchText(strSearchText); } void CMySearchDlg::OnSearchBtnPressed() { CWnd *pWnd; pWnd=AfxGetMainWnd(); if(pWnd) pWnd->PostMessage(UM_SEARCH_EXEC); } 厳密にはPostMessageした後、メッセージが処理されるまでの間にダイア ログ側のテキストが変更される可能性があるので、ダイアログ側でnewした CStringにGetDlgItem()でテキストを取り込んで、CStringのポインタを LPARAM等で渡し、メインウィンドウ側で使い終わった後deleteした方が いいかな。
C***View側にモードレス上のてきすとを読むメンバ関数を作る。 モードレスでボタン押したらそのメンバ関数を呼ぶ そんだけでいいんじゃないか?
839 :
デフォルトの名無しさん :2008/12/16(火) 13:47:22
MFCはいつまで続きますか? .NETで作りなおした方がいいですか? また別の技術とかできたら困る
MFCのSDIで、ウィンドウにドラッグドロップして ファイルを読み込みたいのですが、 普通にOnDropFilesを使うしかないのでしょうか? その後、CDocument::OnOpenDocumentを通してファイルの読み取りを行いたいのですが、 何を呼べばよろしいのでしょうか? (OnOpenDocumentのままだと、タイトルバーが変わらない)
>>839 MFCは、C/C++
.NETは、C++/CLI
C/C++ユーザーがいる限りMFCは続くはず。
SDIでeditviewだったら特に何もしなくても ドラッグドロップしたら新しいファイル開くと思うけど まず呼ばれるのはonfilenewだろ
スタティックライブラリ でMFCを使うと、 ファイル系メッセージや 印刷プレビューの文字列が英語になるのですが 日本語にする方法ってありますか? ちなみに、共有DLL だと日本語になります。 環境はVS2003 sp1です
STLやboostと親和性高くて、C++0xの仕様取り入れたナウいGUIライブラリ 誰か作らねぇかな。
よろしく
ついでにDirect2Dのサポートもよろしく
調べていたらMSFlexGridに辿りついたんですが、 これライセンスと、他のPCにVBランタイムが入ってないとダメみたいなんです。 数行表示できればいいんですが、他に似たようなコントロールは今でもないんですか?ランタイムなしで動くやつがいいです。
いくらでもある。
鮭のたまごは筋子とも呼ばれるが、いくらでもある。
たとえばどれですか?
あれ⇒
CWinAppEx::GetStringってエントリがなかったとき、ちゃんとデフォルト値が返ってくる? 常に""が返ってくるんだけど。
うちじゃならんけどな、、 試しにそうなるコード書いてみてよ。
ってレジストリのほうか・・・ ソースおっかければわかるが、常に空文字列になる。
だよね? CSettingsStore::Readのところで、strValue.Empty();になってるよね? 完全にバグだよね?
バグ報告したいんだったらMSの掲示板
バグじゃねーだろーよ CString GetString( LPCTSTR lpszEntry, LPCTSTR lpzDefault= _T("") ); デフォルトは自分で設定するんだよ
>>848 CListCtrlでは事が足りないのかね。
861 :
デフォルトの名無しさん :2008/12/18(木) 01:35:18
困りました。 ポップアップダイアログの中にタブコントロールを作って、 そのタブの中にダイアログを張り付けたのですが、中のボタンが押せません ダイアログではなくエディットコントロールを張り付けたらメッセージが届くのですがどうすればいいんでしょうか
>>861 ダイアログの中にダイアログをどう貼り付けたか知らんけど、ボタンの
メッセージ(BN_CLICKED)が届くのは、中のダイアログの人になるだけで、
フツーに押せると思うが?
863 :
デフォルトの名無しさん :2008/12/18(木) 02:59:19
>>858 M$はバグを仕様と言い張るからな〜
困ったもんだw
>>848 結局見た目が同じようなコントロールを自分で作った
きっと需要あるだろうなーと思うが請負った仕事で書いたものだから公開は出来ないのー
私もCListCtrlに編集機能つけたし、みんな通る道じゃねぇのw
結局、CWinAppEx::GetString使うと空文字なのかエントリーが無いのかの区別はつかないってことだな
>>862 thx解決した。ダイアログ.Create(IDD..., this);
のthisをタブコントロールにしたらメッセージが届いたよ!
>>867 つくだろう
CString str = GetString("entry","ないよ");
entry がなければ、
str = "ないよ"
だろが
要するに、
>>778-779 のように、勝手にキーが作成されるから、
それ以降にGetStringするとエントリーがあることになって空文字が返ってくるんだろ?
だから、ダイアログベースとかでレジストリを使わないようにするときちんと動作する。
ってことじゃないの?
872 :
869 :2008/12/18(木) 17:37:30
>>870 大変失礼しました。
MS に文句言って帰ります。
コントロールがアクティブで無くなった時を検出するのはOnActivateAppでいいんですか? ボタンのクラスウィザード見てもないんですけど、CWndの派生だから手動で追加しても大丈夫ですかね
>>873 WM_ACTIVATEメッセージハンドラ(CWnd::OnActivate())。
関数の引数と戻り値の型さえ間違わなければ手で追加しても問題ない。
メッセージマップの追加も忘れずに。
クラスウィザードで出ないって、ちゃんとボタンの派生クラス作ってる?
ボタンを配置したダイアログにOnActvate()ハンドラ追加しても、そこで
取れるのはダイアログのウインドウがアクティブ/非アクティブになった
タイミングのイベントだけだぞ。
>>873 使えるハンドラだけウィザードで表示される
RedrawWindowをマウスの動きにあわせて実行すると画面がちらつくんですが、 これ回避できませんか?メモリ上のDCに書いて入れ替えてるんですが描画が終わる前に次の描画が来ることってあるんでしょうか?
>>876 WM_ERASEBKGND メッセージハンドラ CWnd::OnEraseBkgnd() はどうしてる?
感動しました。ちらつきが激減しました。 自力で絶対解決できないことを教えてもらいありがとうございました。 BOOL CView::OnEraseBkgnd(CDC* pDC) { return 0; return CScrollView::OnEraseBkgnd(pDC); } pDCの範囲がでかすぎる場合、RedrawWindowではなくInvalidataRect(rect)にしたんですが、解決できなくて困ってました ありがとうございました。
CDC::DrawTextってどうやって呼び出せばいいの? CDCじゃないほうがどうしてもよびだせないんです。
>>879 おれも
>>880 とまったく同じ意見なんだ。
とりあえず、"CDCじゃないほう"ってのを説明してみてくれ。
その前に >CDC::DrawTextってどうやって呼び出せばいいの? ってのもよくわかんね よんでんじゃんw
GDIのAPIのこと言ってるんじゃね?w
::DrawTextのこと?
そもそもWindowsアプリの基本が分かってないような気がする VBとかCLIとかしか経験してないのかもしれないが そもそもどんなアプリを作ろうとしていて、どこに文字列を描画しようとしているんだよ・・・
すいませんやっとわかりました。 DrawText(hDC.,.....とインテリセンス続きますが、 hDCが意味不明なので CDC::DrawText(str...の書式の方で書きたかったのですが、 hDC->DrawText(str....としたらCDCのDrawTextのインテリセンス出てきました。 結局hDCが理解できてしまい、どっちでもいい感じになってしまいました。 すいません。
たぶんほとんどわかってない気もするが、、、まあ似たような質問を繰り返さないならいいかw
つうか、ここMFCの相談室だよな?
Docクラスを、別なクラス内で使いたいんだけどDoc.hをインクルードさせると大量のエラーをはいてしまいます。 で、型を定義できないのでポインタを渡す事も出来ません。 Docクラスを別なクラス内で使いたい時ってどうすればいいんですかね?
別のクラス ってのはどんなん? 別プロジェクトだったりしないね? エラーってのはコンパイルエラーだね? 最初の一個張ってみて。 もしかしたら、前方宣言ってググるだけでことたりるのかもしれない、と、おもった。
>>889 そのエラーを全部なくせよ。ヴァカか、おまえは。
ああ、ヴァカなのかw
別class.hでは、class ChogeDoc とだけ定義しておけば、docへのポインタ変数を定義できる 別class.cppで hogedoc.h をインクルードさせればエラーは出ない(事が多い
>>890 別クラスを定義したヘッダーに型の定義をする為にhogeDoc.hをインクルードさせると
別クラスを定義していないっていうエラーが大量にでます
ボタンにSetIcon()やSetBitmap()を適用すると XP上でもクラシックスタイルになってしまうのですが、 通常のテキストボタンと同じように環境に合わせて描画してくれるような 拡張クラスとかどこかにありませんか? CodeGuruとかCodeProjectとか見ても、そのものズバリなものが見つからないです。
マニフェストでもどうにもならんなら難しいな
>>895 CMFCButton
ただし、VS 2008 sp1限定だけど。
>>895 CodeguruかCodeprojectか忘れたけど、XPStyleButtonってのがあった。
けど、結局は自分でボタン派生クラスを作ったよ。
ボタンを押したら新しいボタンを自動で作ってどんどん表示させるようにしたいのですが、 CButton* m_btn; OnButtonDown { m_btn = new CButton(); m_btn->Create(・・・・); } これで、Createの行を削除したらエラー止まるので、ここだと思うのですが、 CObjectのPrivateメンバにアクセスできませんと出てしまいます。どう書けばいいんでしょうか
>>900 まずは、C++自体をちゃんと勉強してから出直して来い。
ヒントをください。これ以上本で勉強しても実際に使わないと理解できないぐらいC++むずいです。おねがいします
だめですわかりません。 CButtonのCreateは純粋仮想関数にもなってないし、privateにもなってません。 ねんをおして((CButton*)m_btn)->Createとキャストしましたが、変わりません、 CObjectはどこからあらわれたのでしょうか
引数間違ってんじゃねーの?
再度確認しましたが間違ってなかったです。 OnButtonDownを外部のクラスから呼んで実行させてるんですが、ここは問題ありますか?
>>905 virtual BOOL Create(
LPCTSTR lpszCaption,
DWORD dwStyle,
const RECT& rect,
CWnd* pParentWnd,
UINT nID
);
こんなんだぞ?
ちょっと該当箇所晒してみ?
>>905 "間違ってない"って判断が怪しい。 多分、間違ってる。
"OnButtonDownを外部のクラス〜"は、その文章だけでは判断できない。
とりあえず情報は先に出せ。 聞き出すのがだるいから。
だってとくに気をつけることもなく普通に動くしな できないのがよくわからないし
>>905 ,907
>OnButtonDownを外部のクラスから呼んで実行させてる
クラスの宣言で、
private:
void OnButtonDown();
になってるから外部からアクセスできない。ただそれだけ。エラーメッセージの通りだよ。
しかし、new で確保したメモリはいったいどこで解放してるんだろーな。
そのコードじゃ、OnButtonDown() 呼ぶたびに以前のアドレスは忘却の彼方に飛んでいくし、
最後に作ったボタンにしかアクセスできなくなんだがな。
>>910 >これで、Createの行を削除したらエラー止まるので、ここだと思うのですが、
そしたらこの意味がわかんねー
やっぱり初心者はコードを晒すべきだな
多分、はじめに質問した時点と後で確かめた時点でのソースがかわってそうだしね
結局
>>901 でFAってことか。
幾らなんでもC++を知らなさ過ぎて話にならん。
すいません。省略せずに行数限界まで張ります。助けてください。 class CCopyStaticButton: public CStatic { public: CCopyStaticButton(int Num = 0){historyNum = Num;} int historyNum; afx_msg void OnPaint(); DECLARE_MESSAGE_MAP() }; vector<CCopyStaticBox> vCopyBox; int boxNum; CCopyStaticButton* pm_CSB; void CCopy::ActiveCopy() { boxNum++; CRect rectBox; rectBox.SetRectEmpty(); pm_CSB = new CCopyStaticButton(boxNum); vCopyBox.push_back(*pm_CSB); (vCopyBox.end()-1)->Create(_T("CopyBox")+boxNum, WS_CHILD | WS_VISIBLE, rectBox, this, boxNum); RedrawWindow(); }
>class CCopyStaticButton: public CStatic ?
すいません、そこ短く書くときにわかりやすくと思って CButtonで書いてしまいました。 正確にはStaticを派生させた独自作成のボタンです。 コンパイルエラー悪化してました。 vector<CCopyStaticBox> vCopyBox は vector<CCopyStaticButton> vCopyBox です。
メモリリークわろたw
CCopyクラスがダイアログクラスじゃないから引数に渡したthisがエラってんじゃないの?
CWnd派生のCDockablePaneです。 new初めて使うのでメモリ関連は勘弁してくださいすいません
> (vCopyBox.end()-1)->Create(_T("CopyBox")+boxNum この"+boxNum"っておかしくないのか?
こっちで似たようなサンプル書いてみたけど普通に動くけどねぇ 矩形が空だから表示はされないけどw
そうでした。 CString strNum; strNum.Format(_T("%d"),boxNum); (vCopyBox.end()-1)->Create(_T("CopyBox")+strNum, WS_CHILD | WS_VISIBLE, rectBox, this, boxNum); に変更しました。ありがとうございます。なんでエラーにならなかったんだろう・・・ しかしエラー内容は変わりません。 依然、CObjectのPrivateメンバにアクセスできませんです。
pm_CSB->Create( 仮にこうしてみても結果は同じ?
エラーおなじでした・・・
CButtonでもCStaticでもいいけど、同じ引数でCreateしてエラー出る?
んじゃ後はリビルドしか残ってないなw
後はプロジェクトにCCopy(同名の別クラスとかw)がもう一つあるとかそんなオチのような気がするな
CCopyStaticButtonクラスは使わずに CButtonで書き換えました vector<CButton> vCopyBox; CButton* pm_CSB; pm_CSB = new CButton(boxNum); この3か所書き換えましたがだめです。 .ncb消し、クリーン。VS再帰。ダメでした。 CCopyクラス重複してませんでした。
vector<CButton> vCopyBox; を vector<CButton*> vCopyBox; じゃね?
(vCopyBox.end()-1)->Create("CopyBox", WS_CHILD | WS_VISIBLE, rectBox, this); こんなんにしてもエラーそのまま? あと、unicode/マルチバイトはどっち?
もうちょっと丁寧に書け。 >pm_CSB = new CButton(boxNum); CButton に CButton( CButton& hoge) はあっても、CButton( int hoge) なんつうコンストラクタはないぞ。
第一引数_T("CopyBox")のみにしました。だめでした。 ゆにコードです
そーなんだよねぇ テキトーに貼ってるのも怖いんだよねぇ はじめはCButtonとか言ってたわけだし 一度最小のプロジェクトを作って同じことを一番シンプルな形でやってみたほうがいいよね
>>934 this以降(this含む)の引数削ってみてくんない? さすがにエラー内容変わるよね?
それちょっとコンパイル通らなすぎてちょっと待ってください。
vector<CButton*> vCopyBox; int boxNum; CButton* pm_CSB; { boxNum++; CRect rectBox; rectBox.SetRectEmpty(); pm_CSB = new CButton(); vCopyBox.push_back(pm_CSB); CString str; str.Format(_T("%d"),boxNum); (vCopyBox.end()-1).Create(_T("CopyBox")/*+str*/, WS_CHILD | WS_VISIBLE, rectBox, this/*, boxNum*/); RedrawWindow(); } 現状これなんですが、Createをコンパイルどうかけば通せますか
>>940 >(vCopyBox.end()-1).Create
?
(*(vCopyBox.end()-1))->Create( このレベルじゃ他でもどうせdelete忘れたりするから諦めろ。
っていうか貼るたびに言ってること違うし ここ貼ってるコードとソースも状況が違うな? RECT rect; SetRect(&rect,0,0,50,50); CStatic *m_pBut = new CStatic; m_pBut->Create(_T("Button 2"),WS_VISIBLE | WS_CHILD ,rect, this, 50); もうこれそのまま貼ってみろw
できました!!! 起動しました。
何ができたんだ?
vector<CButton*> vCopyBox; int boxNum; CButton* pm_CSB; boxNum++; CRect rectBox; rectBox.SetRectEmpty(); pm_CSB = new CButton(); vCopyBox.push_back(pm_CSB); CString str; str.Format(_T("%d"),boxNum); (*(vCopyBox.end()-1))->Create(_T("CopyBox")/*+str*/, WS_CHILD | WS_VISIBLE, rectBox, this, boxNum); RedrawWindow(); これで起動できました。 ありがとうございます!!!まじありがとうございます! vector<CButton> vCopyBox; はでなんでだめなんですか?
>>946 >vector<CButton> vCopyBox;
>はでなんでだめなんですか?
ポインタじゃないから
おまえが馬鹿だからだよ
確かに。 死刑だなwww
なるほどw
徹底的に解析に入ります。ありがとうございました。
出来ればnewど素人に開放の場所のアドバイスをくださいお願いします。
>>949 すいませんそこ直したんですが関連どこを直せばいいかわからなくなって忘れてました。
そこだったんですね!すいません
もっというと
>>900 は自分の状況を何も表現できてなかったってことだなw
いや思い出しました。 pm_CSB->Create( 直した時もCObjectのPrivateメンバにアクセスできません。でなにもエラー内容変わらなかったんです
じゃあ、これが↓嘘で CCopyStaticButton* pm_CSB; CCopyStaticButton pm_CSB; ってなってたってことぐらいしか考えられないな
>>951 >出来ればnewど素人に開放の場所のアドバイスをくださいお願いします。
仕様による
最後でいいならボタン貼ってるウィンドウのデストラクタでもおk
Create();したからDestroyWindow();を忘れずに・・・
あれ?コントロールはいらないっけ?DestroyWindow();
vectorに実体をpush_backしようとした時点で コピーコンストラクタとかでおかしくなりそうだけど
>>956 いらんよ。親が破棄する。
しかしまあ、
>>946 も雑なコーディングだな。
>int boxNum;
int boxNum = 0; // 初期化しないでインクリメントするな。これだと warning C4700 がでてるはずなんだがな。
>str.Format(_T("%d"),boxNum);
>(*(vCopyBox.end()-1))->Create((_T("CopyBox")/*+str*/, WS_CHILD
str.Format( _T("CopyBox %s"), boxNum); // こうすりゃ一度で終わるだろ。
(*(vCopyBox.end()-1))->Create( str, WS_CHILD
いけね。 str.Format( _T("CopyBox %s"), boxNum); → str.Format( _T("CopyBox %d"), boxNum);
960 :
デフォルトの名無しさん :2008/12/24(水) 03:38:02
ソフトでデータを編集するとファイル名に*がついて、終了するときに勝手に保存するか問い合わせてくる、 アレってどうやるんすか?
>>960 どうやるもこうやるも、ファイル名の脇に'*'を出力するのと確認ダイアログを出すだけなんだが。
まさか、コードが天から降ってくると思っているわけじゃないだろ?
Docクラスあたりにmodifyなんちゃらっていうフラグが立つから、それが立ってる場合にフレームタイトル描画する関数で*追加するだけだな やったことあるわ
他のアプリケーションを起動させるのは出来るんですが そのアプリケーションをダイアログみたいにウインドウに張り付けて起動させることはできないんでしょうか?
できる
まじですか。完璧じゃないですかそれ
で、やり方は?
起動される側のアプリが対応して無いと無理だろ。 無理やりやればできなくは無いだろうが、まともに動くとは思えない。
CreateProcessで起動して
インスタンスとってそのインスタンスのメインウィンドウを
取得してやれば何とかできるかもしれないけど
全部が対応できるわけねえよ
>>964 てきとうに「できる」とか言うなボケ
できるかできないか、だけなら「できる」でいいだろ。 そこまでする必要が普通はないだけで。 # 少なくともリモートデスクトップにはできるのだから。
うれしくて.NET勉強してたんですが、難しいんですか? 移行してみようかな的な、.NETのアプリを作って組み込んで切り替えて使えるようにしようかと思ったんですが。 最悪WebBrawserコントロール貼り付けてSilverlightでUI全部すませたら面白いかなーと 今後、MFCのドッキングウィンドウは絶対はずしたくない機能なんで、どうすればいいとこどりできるかを考えてたんです。 CreateProcessで他のウィンドウを操作するところから始めてみます。ありがとうです。
971 :
デフォルトの名無しさん :2008/12/24(水) 22:51:23
.NETってUI作るの簡単なんていうけど実際にお金を貰うアプリを作る場合はほとんどの 標準コントロールはつかえないから自前で用意することになるから MFCとなんらかわりない
WPFの広告とかみてたら簡単にUI作れるみたいな印象を受けたんですが、甘いですか? 自由度なくて調整するのにMFC以上に時間かかるなら意味ないですけどそんな予感はたしかにしますw
ツリーコントロールのドラッグアンドドロップとか リストコントロールの着色とか ダイアログにダイアログを貼り付けたときのフォーカスの移動とか リストコントロールのセルチェンジ時のコントロールの切替とか ふつーにやらなきゃならんけどMFCだとかなり困難な部分って楽になってないの?
>>972 WPFは自由度高い。
リストコントロールの各項目に別のコントロール入れたり
ボタンの中にボタン入れられたり(意味無いけど)
それらを任意の拡大率・角度に調整できたり。
MFCとWPF比べるとか、月とすっぽんもいいところ。 WPFやったらもう、MFC使ってるやつはマゾとしか思えなくなるレベル。 まあ、C++使わざるを得ないとMFCしか選択肢なくなるんだが・・・
>>974 それってほとんど実用性ないじゃん。(w
>>973 が指摘している件は、具体的にWPFでカイゼンされているの?
> C++使わざるを得ないとMFCしか選択肢なくなるんだが・・・
MFCは文字通りマイクロソフト謹製のクラスライブラリでしかない
んだが? 対してC++は汎用言語なんで、MFCを一切使わず、自前の
クラスライブラリを作ってもいいんだよ。
もっとも、それができればの話だが、MFCさえ使いこなせないヤツに、
ムリな注文だよなぁ。
>>971 >ほとんどの
>標準コントロールはつかえないから
何を言っているんだ君は。
>C++使わざるを得ないとMFCしか選択肢なくなるんだが・・・
C++/CLI はあかんの?俺使ったことないけど。
C++で.NET使うならC++/CLIだな C++0xスレだと、C++0xで標準化しようとしている記法を馬鹿にするほどC++/CLIの記法は評判良かったりする そこは俺も同感だが、正直.NETとC++の相性なのか結構使いにくい印象 C++の長所も捨ててるしな
C++/CLI使ってみた俺がちょっとだけ書く [長所] ・GUIが細かい設定ができる ・GC [短所] ・文字列変換がめんどくさい C++/CLIオンリーならいいけど、 WindowsAPIとか、自分のC/C++なライブラリ使うんだったらこれ必要 他にも色々あるけど 結構C/C++の楽な部分ができなくなるお。 MFCは、GUIのタブ系と画面サイズ変更時の子コントロール変更がめんどくさいけど、 それ管理周りを自作したら、あと10年は戦える。 という結果になった。 俺は。
ついでに言うなら、.NETするならC#がもっと楽
数値入力専用のエディットコントロールを置いたのですが、その入力できる数値を制限したいのです。 どのようにすればいいでしょうか?
CEditとCSpinButtonを合体させたらレンジ指定出来なかったっけ? C++0xの記述が長ったらしいのは柵のせいなんだろうな・・・ 拡張性はあるだろうけど、正直勘弁
>>981 どう制限したいの?
−や少数点が無しならエディットのコントロールに番号ってのがあるからそれにチェックをいれれば
数字以外入力できない
あとはキルフォーカスの瞬間にエラーメッセージを出すとか
OKボタンを押した瞬間にチェックが走ってエラーメッセージが表示されるとか
そもそも入力させないってのもあるけどこれは使う側が面倒だな
どの瞬間にどう制限したいのか?ってところでもやり方変わるけど・・・
>>983 そもそも入力させないようにしたいのです。
出来たら制限範囲よりも大きい数字が入力されたら、補正して範囲内の最大値にするといった風にしたいのです。
>>984 だからどのタイミングで?
キルフォーカス?
アップデート?
キルフォーカスでお願いします。
じゃ、やれよ!
すいません 色々と試行錯誤したところ上手くいきそうです。 くだらない質問に答えて頂いてありがとうございました。
>>988 嘘だな
SetLimitTextとか他の制限は頭に入ってなさそう
流れにワロタw ていうかWinのマウスキャプチャーの仕様考えたの誰だよ この辺でいつも悩んでしまう
>>984 ,988
CDialog::::OnChangeFileName のハンドラをEditコントロールの親ウィンドウに
追加して、そこで入力された数値を監視すればいい。
で、範囲外の数値が入力されたら CEdit::SetWindowText() を使って書き直す。
ただそれだけだ。難しく考えるな。
992 :
991 :2008/12/26(金) 00:04:52
ちょいミス。CDialog::::OnChangeFileName()はウチで使ってる関数プロトタイプだった。 要はこれね。ON_EN_CHANGE( <id>, <memberFxn> ) afx_msg void memberFxn( );
CRect rect; rect.Width(); こう書いた方がいい? それとも極力 rect.right; の方がいいと思う?
どっちでも内容が同じでどっちでも書ける場合なんですけど GetClientRect(&rect)の時とかで、 Width()は関数なので.rightの方がいいのではと考えながらやってたらごっちゃ混ぜで統一できてなくてひどくなってきました。 いいかげんどっちがいいのか決着をつけたいです!
>>996 rect.right と rect.Width() の値は違うぞ。
GetWindowRect( rect)してみ。
int CRect::Width() { return rect.right - rect.left; }
関数といってもやってることはこれだけだから、rect.Width() を使うクセをつけておいたほうが、
>>997 のような時にバグらなくていい。
関数の中身見れたんですね。 引き算しかしてないということで、.rightに統一しようと思います。 もっと複雑なことをしていて、.rightで大丈夫なのかと不安だったんです GetWindow、toScreenを全てGetClientに統一したので大丈夫です。ありがとうざいました。
1000 :
デフォルトの名無しさん :2008/12/26(金) 07:48:33
意味不明なほど余裕の1000 (・∀・)ヨユーヨユー
1001 :
1001 :
Over 1000 Thread このスレッドは1000を超えました。 もう書けないので、新しいスレッドを立ててくださいです。。。