■MFC相談室 mfc19d.d ..
577:デフォルトの名無しさん
08/11/16 01:34:50
また変なのがわいてきたな
ひっこんでろタコ
578:デフォルトの名無しさん
08/11/16 01:59:29
>>576
素人さんですかw
579:576
08/11/16 14:52:37
>>577 タコでさ〜せんwwww
>>578 素人さんですかの人、こんにちはだお
580:デフォルトの名無しさん
08/11/17 02:50:44
CWnd::SetWindowText()も、CWnd::SetDlgItemText()も、CWnd::SetDlg
ItemInt()も、単純にAPIのラッパだし、ワーカスレッドからでもなんら
問題なく呼べるだろ。
ダイアログのポインタが嫌なら、ハンドルとAPI直接呼び出し使え。
::SetDlgItemText(this->m_hWnd,IDC_EDIT1,...);
::SetDlgItemInt(this->m_hWnd,IDC_EDIT1,...);
581:デフォルトの名無しさん
08/11/17 22:09:37
MFCスレでAPI直接呼び出し薦める奴って何なの?
582:デフォルトの名無しさん
08/11/17 22:22:44
と言われても、割と普通の事だしなあ。
というか、おまいら今回の話はUIスレッドがスレッド終了待機に入った所為で、
UIスレッドへのSendMessageがデッドロックした、っていう事完全に忘れてるだろ。
583:デフォルトの名無しさん
08/11/18 00:00:19
というより、スレッドとか、ハンドルがクラスで継承されていかないところでは、
Win32APIを直接叩く以外無いよな。
脱線すまん
584:デフォルトの名無しさん
08/11/18 00:09:04
隠ぺいしている部分は出来るだけ利用するな
でもGDIだけはベタ書きしてしまう俺
それ自体をクラス化するんだけどな
585:デフォルトの名無しさん
08/11/18 21:59:29
>>583
MSDNにはHANDLE渡して該当するFromHandleを呼び出す、とあるから
オブジェクトは渡せないけどMFCで行けるんじゃない?
個人的にはしないけどね。
586:名無し募集中。。。
08/11/18 22:07:02
都合のいい時だけMFCを使うってスタンスなのでWin32APiは普通に呼ぶ
587:デフォルトの名無しさん
08/11/19 13:37:26
モーダレスダイアログでボタンを押すと
m_cdlg = new CDlg(this);
m_cdlg->ShowWindow(SW_SHOW);
みたいな感じで表示するとボタンを押せばいくつでもダイアログが出てしまいます。
1つしか出さないにはどうしたらいいでしょうか?
あと、親クラスの関数でモーダレスダイアログを扱うことはできますか?
XP+VC.netです。
588:デフォルトの名無しさん
08/11/19 13:53:44
>>587
その2行を通るたびに new で作ってんだから、そりゃいくつでも出るでしょう。
そのボタン貼ったウィンドウの初期化部分で一回だけ作って、
ボタン押したときに ShowWindow すればいいんじゃね?
>親クラスの関数でモーダレスダイアログを扱うことはできますか?
ちょっと意味が解らんかった。
589:デフォルトの名無しさん
08/11/19 14:10:21
delete thisをモーダレス内でしているので、親ウィンドウではモーダレスの終了を検知出来ないですよね?
モーダレスが終了した後なら、もう一度ボタンを押したときはモーダレスを表示したいのですが・・・。
モーダレス上のボタンを押したときに親ウィンドウの変数や関数をいじりたいのですが。
590:デフォルトの名無しさん
08/11/19 14:18:24
クラスメンバ
private:
CUnkoDlg m_dlg;
Initidialog
m_dlg.Create( CUnkoDlg::IDD , this )
OnButton
m_dlg.ShowWindow( SW_SHOW )
591:デフォルトの名無しさん
08/11/19 14:29:49
モーダレスではなくモードレスですよ。
592:デフォルトの名無しさん
08/11/19 14:30:44
モーダルに対してなのか、モーダレスと言う人は非常に多い
593:デフォルトの名無しさん
08/11/19 16:14:06
青信号に対してなのか、赤信号で渡る人は非常に多い
594:デフォルトの名無しさん
08/11/19 16:40:22
>>589
自分でWM_NOTIFYして親に通知して、実処理は通知先で
595:名無し募集中。。。
08/11/19 17:12:27
>>589
モードレスダイアログに親のthisを渡してpublicな操作をしてもらう事はたまにやる
終了時には 『m_cdlg = new CDlg(this); 』のm_cdlgもNULLにして終わらせる
たぶんあんまり行儀が良くないと思う
596:デフォルトの名無しさん
08/11/19 17:23:38
子ダイアログで親クラスのヘッダをincludeしてもいいならそれもアリだがそこでしか使えなくなる
俺もやったことあるけど
597:デフォルトの名無しさん
08/11/19 21:07:31
モードレスダイアログなら、
一旦Createした後は、ShowとHideしかしないという作り方もある。
で、ダイアログ自体はポインタでなくメンバ変数としてそのまま持っておく、と。
598:デフォルトの名無しさん
08/11/19 21:08:33
って >>590 そのものだった。すまそ。
599:デフォルトの名無しさん
08/11/19 21:37:13
シングルトンならそれでいいな
600:デフォルトの名無しさん
08/11/20 01:28:13
>>599
はぁ?何言ってんの?
601:デフォルトの名無しさん
08/11/20 01:32:38
>>586
アプリケーションフレームワーク使ってないの?
602:デフォルトの名無しさん
08/11/20 01:38:21
>>589
delete thisってどういう挙動になるのかな?
603:デフォルトの名無しさん
08/11/20 13:47:14
delete this; // ハラキリ
604:デフォルトの名無しさん
08/11/20 17:42:17
delete this; // さようなら
なら実際に見たことがある。
605:デフォルトの名無しさん
08/11/20 20:03:19
>>600
きもw
606:デフォルトの名無しさん
08/11/20 21:05:35
俺も >>599 が何を言ってるのか解らん。
親と子ダイアログ、どっちを指してるのかも不明だが、それが
シングルトンであるかどうかが今の話にどう関係してくるってんだ。
607:デフォルトの名無しさん
08/11/20 21:44:49
> モーダレス上のボタンを押したときに親ウィンドウの変数や関数をいじりたいのですが。
ライブラリ化などして、後々まで利用するなら、親ウィンドウなり、
オーナーウィンドウに対して、ユーザー定義メッセージを投げるのが、
一番汎用性があるのでは?
WPARAM,LPARAMで、操作したい内容(処理を特定するためのボタンのID等)
を渡す。 DWORD値2個で足りなければ、他のメッセージと同様に、構造体
やクラスオブジェクトのポインタを渡す。
処理は、ユーザー定義メッセージを貰う親ウィンドウなり、オーナーウィン
ドウ側にON_MESSAGE()のハンドラとして記述することになる。
608:デフォルトの名無しさん
08/11/20 22:08:54
>>595-596
いいかどうかは別にして、自分もやるし、何度もやったことある。
>>597-598
1回だけCreateして、Show/Hideで使い回す場合、2回目以降表示する際
には、モーダレスダイアログ側のOnInitDialog()が呼ばれないことを
ちゃんと理解していれば、それで問題ないと思う。
ダイアログが、親ウィンドウが持つパラメータや状態を表示したり、変更
する機能を持つ場合、同じ実体をリサイクルしてもいいけど、親ウィン
ドウ側にはダイアログのポインタをメンバに持たせて、表示時は、newした
後でダイアログのメンバ変数をセットしてCreateを呼び、非表示時は、
DestroyWindow()してdeleteしてしまうのが良いかと。
609:デフォルトの名無しさん
08/11/20 22:14:44
要約して書くと、こんなかんじ?
ON_BN_CLICKED(IDC_BUTTONxx,OnShowHideDlg)
CxxxxWnd::CxxxxWnd() { m_pDlg=NULL; }
CxxxxWnd::~CxxxxWnd() /* virtual */
{
if(m_pDlg) // 親が死ぬとき、子も道連れに死ぬ
{
m_pDlg->DestroyWindow(); // MFCならデストラクタで呼ばれるので省略可
delete m_pDlg;
m_pDlg=NULL; // どうせ死ぬので省略可
}
}
CxxxxWnd::OnShowHideDlg()
{
if(!m_pDlg) // 非表示→表示
{
m_pDlg=new CMyDlg;
m_pDlg->m_numParam1=1;
m_pDlg->m_strEditParam=_T("テスト");
m_pDlg->Create(this); // 表示時に毎回CMyDlg::OnInitDialog()が呼ばれる
m_pDlg->ShowWindow(SW_SHOW);
}
else // 表示→非表示
{
m_pDlg->DestroyWindow(); // MFCならデストラクタで呼ばれるので省略可
delete m_pDlg;
m_pDlg=NULL;
}
}
610:デフォルトの名無しさん
08/11/21 00:21:05
CWnd::ShowWindow()で表示切替したほうが動作が軽いよ
前回開いてた状態で再表示されたほうが使い勝手も良さそう
611:デフォルトの名無しさん
08/11/21 01:20:56
まぁ、それも用途次第じゃないか
中身初期化しないならそれがベストだろし
612:デフォルトの名無しさん
08/11/21 15:07:35
ダイアログベースのMFCアプリです。(VS2005)
親ダイアログにタブコントロールを付けて、タブに更に子ダイアログがくっついている形です。
ダイアログウィンドウでOnSizeが渡されるのが、OnInitDialogより後なのは仕様ですか?
CWnd::OnInitDialogが呼び出されるよりも前にOnSizeが来てしまうので、
サイズを一緒に調整したい子ウィンドウ全てに対してGetSafeHwnd()関数でチェックしてから
サイズを変更しているのですが、もうちょっと効率的な方法はないですか?
それと、なぜかウィンドウでエンターを押すとShowWindow(SW_HIDE)が渡されるのか、
子ダイアログは消えてしまうし、親ダイアログではアプリ自体が終了してしまいます。
何か対処法はありますか?
613:名無し募集中。。。
08/11/21 15:09:41
> なぜかウィンドウでエンターを押すと
OnOKに飛んでいる
614:デフォルトの名無しさん
08/11/21 15:25:15
>>613
OnOKって自分で呼ばなくても勝手に呼び出されちゃうんですか…
てっきりIDOKボタンを押した(又はDefault Buttonに設定した上でエンターした)時だけだと思っていました。
これは自分でOnOKを空の関数にオーバーライドして、CDialog::OnOK呼ばないようにせざるを得ないと言うことですか?
615:名無し募集中。。。
08/11/21 16:40:38
> OnOKって自分で呼ばなくても勝手に
その通り
ESCを押すとOnCancelが呼ばれるのも同じ仕組み
616:デフォルトの名無しさん
08/11/21 17:13:49
>>599
617:デフォルトの名無しさん
08/11/21 17:28:43
>>614
>>376
618:612
08/11/21 17:48:04
>>617
なるほど。よくわかりました。
っていうか、このスレのレスすらも確認しなくてスンマセン。
619:デフォルトの名無しさん
08/11/21 17:57:18
>>612
ダイアログ内に子ダイアログを置くのであれば、
子ダイアログの「Control」をTrueにしておいたほうがよいですよ。
子ダイアログだけ消えるということも無くなるはず。
620:デフォルトの名無しさん
08/11/21 19:12:31
612を見てなんでCPropertySheet&Pageを使わないのかと思ってしまったが言わない方がいいのか?
621:デフォルトの名無しさん
08/11/21 19:19:05
うん。言ったら恥かくよ。
622:デフォルトの名無しさん
08/11/21 19:19:28
と思ったらトップレベルウィンドウがダイアログなのか( ´ω`) ごめんよ
623:デフォルトの名無しさん
08/11/21 21:40:45
CodeGuruかどっかのサンプルを参考に、トップレベルのダイアログに、
>>620-622
位置決め用にスタティックコントロールを置いて、そのスタティック
コントロールに重ねて、動的にプロパティシート(CPropertySheet)を
貼り付けて、そのシートに、さらにCPropertyPageをAddPage()する
というコードを実際に書いたことあるけど?
624:デフォルトの名無しさん
08/11/21 21:50:21
>>612
> ダイアログウィンドウでOnSizeが渡されるのが、OnInitDialogより後
> なのは仕様ですか?
DoModal()を呼んだ場合、OnInitDialog()より前、OnCreate()の後に
OnSize()が呼ばれていると思うけど?
ダイアログリソースに貼り付けたコントロールではなくて、自分でコント
ロールを動的にCreate()しているのなら、コントロール作成より前には
呼ばれないでしょ。 そういうことではなくて?
625:デフォルトの名無しさん
08/11/21 22:37:42
>>624
あ、いや、ダイアログリソースで貼り付けて、DDXで関連づけたコントロールをOnSizeで調整しようとしているので、
DoDataExchangeで関連づけられる前にOnSizeが呼び出されるのが気にくわなかっただけでして…
(OnInitDialogはそれよりもあと)
あれ、UpdateDataを勝手に呼び出しちゃえば問題なかったですかね? もしかして。
626:デフォルトの名無しさん
08/11/22 03:20:48
今日からVC++を使い始めたCプログラマです。
IPAddressクラスからIPv4アドレスをDWORD値で取り出したいのですが
どうすればいいのでしょう?
CString hostName = Host;
String ^strHost = gcnew String(hostName);
IPHostEntry^ ipInfo = Dns::GetHostEntry(strHost);
IPAddress^ ipAddr;
for each (ipAddr in ipInfo->AddressList)
{
if (ipAddr->AddressFamily == System::Net::Sockets::AddressFamily::InterNetwork) break;
}
if (!ipAddr) /* この判定は超怪しい */
{
/* とれなければLoopBackに強制 */
dwSvAddr = 0x7F000001UL;
}
else
{
/* dwSvaddr = *(DWORD *)ipAddr->getAddressBytes(); みたいなキャストがしたい */
627:デフォルトの名無しさん
08/11/22 08:53:01
.NETスレで聞きなさい
たぶん.NETのデータ型をアンボクシングしてからキャストすればよさそうだが
628:624
08/11/22 09:32:53
>>625
やりたいことがイマイチわからんのですが?
DoDataExchange()内のDDX_Control()で関連付けせずに、OnInitDialog()
内で、SubclassDlgItem()で動的に関連付け(サブクラス化)することも
できますが、コントロールの初期サイズはリソースで指定したサイズに
なるので、特定コントロールのみ例外扱い(リソース指定と異なるサイズ
にしたい)場合、そのコードはどこかに書く必要があると思います。
そもそも、OnSize()って、ダイアログのスタイルを「ダイアログ枠」で
なくて「サイズ変更枠」にすると、ダイアログをドラッグしてサイズ変更
したら、表示中はいつでも何回でも呼ばれる可能性がありますよ?
codeguru.comあたりの「CResizeDialog」を参考にしては?
629:デフォルトの名無しさん
08/11/22 19:11:26
みんなMFCでアプリケーションハンガリアン使うとき、どんな感じにしてるの?
630:デフォルトの名無しさん
08/11/22 22:24:08
>>628
DoDataExchangeよりも先にOnSizeが先に呼ばれてしまうから、
if (2回目以降のOnSizeだったら) {
コントロールのサイズ変更;
}
のような判定が必要になるのが気にくわないということでは?
631:デフォルトの名無しさん
08/11/23 03:30:09
>>630
本筋とそれる話で申し訳ない。
"2回目以降"でなくて、コントロールのhWndがIsWindow通るとかでいいんじゃね?
632:デフォルトの名無しさん
08/11/23 07:07:43
まぁOnSizeはwin32のWM_SIZEのままで、ddxはmfcの後付なんだからしょうがない
633:624
08/11/23 11:35:19
>>630
> DoDataExchangeよりも先にOnSizeが先に呼ばれてしまうから、
DoDataExchangeとの順番は関係なく、最小化のタイミング等でもWM_SIZEは
飛んでくるから、何らかの判定は必要だと思うけど?
codeguru.comの「CResizeDialog」だと、ダイアログにCRect型のメンバ変数
を追加して、コンストラクタでCRect::Empyt()しといて、一発目のOnSize
で、CRect::IsRectEmpty()がTRUEなら、現在のダイアログサイズを変数に
取り込み、FALSEなら、直前のOnSize()時に取り込んだダイアログサイズと、
新しいサイズの差を計算して、子コントロールのダイアログ内での移動や、
サイズ変更をやっていたかと。
OnCreate()⇔OnDestroy()のように、明らかに逆で呼ばれることはないメッ
セージを除いて、安易にフレームワークが呼び出す順番に依存するような
造りにはしない方がいいのでは?
アイコンやビットマップを貼り付けるスタティックコントロールとか、貼り
付けたイメージのサイズに合わせて、コントロールのみ単独でOnSize()が
呼び出されることもあるし。
634:デフォルトの名無しさん
08/11/23 12:28:51
>>633
なんかかみ合ってないような。
一発目のOnSizeではDDXメンバがまだ設定されていないということですよ?
そのCResizeDialogというのは、派生用のダイアログクラスなんだろうから、
内部で子コントロールのDDXメンバを持ってるわけではないでしょう?
昔のソースを掘り返してみたら、
if (IsWindow(m_buttonOK)) {
m_buttonOK.MoveWindow(〜);
}
と自分もIsWindowを使っていた。
635:624
08/11/23 12:36:46
>>634
636:624
08/11/23 12:41:26
間違ってENTER押してもうた。(w
>>634
> なんかかみ合ってないような。
そもそも、なんでサイズ変更に際して、DDX_Control()での関連付けが
必要なのか全く説明がないし、自分が設計するとしても、その必要性を
まったく感じないんですが?
637:デフォルトの名無しさん
08/11/23 20:05:24
IsWindowか 俺はGetSafeHwnd派だ( ´ω`)
638:デフォルトの名無しさん
08/11/23 20:27:16
::IsWindow()とCWnd::GetSafeHwnd()なら普通は後者を使うでしょ?
639:デフォルトの名無しさん
08/11/23 20:37:32
HWNDキャスト派は異端ですか?
640:デフォルトの名無しさん
08/11/23 21:27:30
それもCWndメンバだからいいんじゃね?
グローバルスコープなのを呼び出すなって話だろ
641:デフォルトの名無しさん
08/11/23 23:00:14
CWnd::GetSafeHwnd()って、m_hWndを返すだけであって、
そのウィンドウが存在しているかどうかはわからないのでは?
642:デフォルトの名無しさん
08/11/23 23:02:48
Create()が正常終了してないとm_hWndはNULL
CWndの実体ができる時点でウィンドウが作られてるわけじゃないぞ
643:デフォルトの名無しさん
08/11/23 23:12:18
>>642
それはどこかで明記されてたっけ?
初期化していないポインタのようにゴミが入っている可能性は常に無い?
あとそれが大丈夫だとしても、>>634のようにDDXメンバの実体に対するものには
GetSafeHwnd()ではなくm_hWndで十分だと思うけど。
644:デフォルトの名無しさん
08/11/24 00:54:26
SDKで組んだこと無いのかよ
645:デフォルトの名無しさん
08/11/24 01:32:23
m_hWndの指すウィンドウが存在しないとか言い出したら、
そのハンドルが、実は他プロセスのウィンドウを指してしまっている状態すら、
考慮しないといけなくなるんじゃないか?
646:名無し募集中。。。
08/11/24 02:08:50
俺はm_hWnd派だったんだけどGetSafeHwnd()の方が安全そうだから乗り換えるわ
でも、たぶんどっちでも良くて気分の問題
647:デフォルトの名無しさん
08/11/24 07:43:46
>>643
> それはどこかで明記されてたっけ?
> 初期化していないポインタのようにゴミが入っている可能性は常に無い?
挙動はMFCのソース見れば判るだろ。 というより、C++やクラスの本質
を理解しているのかと?
その理屈なら、CFileクラスのm_hFileメンバ変数や、CGdiObjectクラス
(CPen,CBrush等の基底クラス)のm_hObjectメンバ変数の値も信用できん
とな?(w
> あとそれが大丈夫だとしても...
『大丈夫だとしても』ぢゃなく『大丈夫でなければ』、どんな場面であって
も(m_hWndの値を返す)GetSafeHwnd()も、m_hWndの直接参照も使えない。
648:デフォルトの名無しさん
08/11/24 07:44:54
>>646
> たぶんどっちでも良くて気分の問題
んなことぁない。
直接参照する場合、thisポインタのチェックが入らないのに対して、Get
SafeHwnd()は、(CWndを指す)thisポインタが有効かどうかチェックした後
でthisポインタがNULLの時m_hWndの値を参照せずNULLを返し、thisポインタ
が有効な時のみメンバ変数m_hWndの値を返す。
クラスメンバとして実体が存在するオブジェクトに対して使う場合は、
>>643 氏の言うとおり。
問題はGetParent()などのようにCWndのポインタとしてNULLを返す可能性が
ある場合、戻り値をチェックせず、m_hWndを直接参照すると「0xXXXXXXXXが
無効なポインタを参照うんぬん」というエラーで落ちることになる。
自前のコードでチェックしてm_hWndを参照してもいいけど、どうせなら
そういう場合はGetSafeHwnd()を使った方がスマート。
同様に、CGdiObject::m_hObjectも、CGdiObject::GetSafeHandle()を
使った方がいい。
649:デフォルトの名無しさん
08/11/24 10:56:07
CWndの関数はm_hWndに対してそのままAPIを呼ぶようなものが多いから、
自分もNULLチェックではなくAPIのIsWindowに渡してチェックすることが多いな。
650:デフォルトの名無しさん
08/11/24 11:41:00
もしかして、冷蔵庫内のランプが消えたかどうか、冷蔵庫のドアを何回も
開け閉めして確認しちゃう人?
IsWindow()呼んで戻り値をチェックした後で、APIを呼び出すまでの間に
ウィンドウが消滅しているかもしれないという心配はしないの?(w
651:デフォルトの名無しさん
08/11/24 13:18:36
お取り込み中すみませんが、質問です。
ドキュメントビューアーキテクチャのSDIプログラムを作っているのですが、
メニューのハンドラってxxxDocment.cppに作成するのが良いのでしょうか?
あと、設定データとかファイル入出力のデータの実態もxxxDocment.cppに
作成した方がよいのでしょうか?
652:デフォルトの名無しさん
08/11/24 14:40:44
>>650
それは別問題では?
IsWindow()でチェックしようがm_hWnd!=NULLでチェックしようが、
その後APIを呼び出すまでの間にウィンドウが消滅しているかもしれないのは同じ。
>>651
「表示倍率を拡大」なんていうコマンドならビューやアプリケーションだろうし、
コマンドの内容に依りますよ。
653:デフォルトの名無しさん
08/11/24 16:47:20
質問です、ダイアログのタイトルとかを表示している部分の
高さなどを知る方法ってあるのでしょうか?
┌───────┐
│たいとる .│←この高さが知りたい
├───────┤
654:デフォルトの名無しさん
08/11/24 16:52:38
>>653
::GetSystemMetrics(SM_CYCAPTION);
でいけると思うが、未確認。
655:デフォルトの名無しさん
08/11/24 17:25:35
既存ソフトのバージョンアップ開発で、そういうの生値でやっててキレそうになったことあるわ
上にもあるようにGetSystemMetrics()でOK
というか、GetSystemMetrics()からとれるやつは全部こっからとらないと、ちょっとしたWindowsのデザイン設定の違いでカオスになるからな
656:名無し募集中。。。
08/11/24 17:57:06
>>651
データにまつわる事ならDoc
見せ方(表示)にまつわる事ならView
アプリ全体(データ全体)にまつわる事ならMainFrame
657:デフォルトの名無しさん
08/11/25 03:57:20
本当にMainFrameなの?
658:デフォルトの名無しさん
08/11/25 09:02:09
自分は、アプリケーション全体や、全てのドキュメントに共通の設定は、
CWinApp派生クラスのメンバに登録しているなぁ。 一応、データ本体は、
protectedで、設定をGet/Setするヘルパ関数を用意している。
あと、メッセージハンドラはともかく、ドキュメントの表示方法(例えば
色やスタイルなどの見せ方)に関する設定値は、ViewではなくDocクラスに
持たせているなぁ。
これらの一部をViewに持たせると、ファイルに保存する際にViewクラスに
アクセスしなければならないし、Viewが生成されてドキュメントに関連
付けされる前に、ファイルから初期値を読み込む時等に実装に困る。
CListViewクラスのLVS_REPORT等、ウィンドウが存在する時は、実質的に
Viewもウィンドウ属性という形でそうしたデータを持っているけど、最初
にCreate()する際に、どの初期値でスタイルを指定するという場合に困る。
659:名無し募集中。。。
08/11/25 13:46:17
ドキュメントに保存するパラメータなら見せ方や色にしてもDocが持つべきだろうけど
たとえば表示倍率とかViewごとに変化する(保存する必要のない)データはViewが持って良いだろう
アプリ全体(複数のデータ)は、Appが持つのも良いと思う。
でもCWnd派生のMainFrameだとSetTimerとかPostMessageが使えるから
シーケンシャルな処理が入った時に便利なんで、MainFrameを使ってる
でも>>651の質問ってSDIだよな。1つのDocにViewが複数あるわけじゃないから神経質にならなくてもいいな
660:デフォルトの名無しさん
08/11/25 16:05:52
>>659
SDIはドキュメントが1つであって、ビューが1つではないですよ。
実際、エクスプローラスタイルで作成されたSDIはビューが2つあるし、
標準のスタイルでも任意にビューを増やせる。
661:デフォルトの名無しさん
08/11/25 17:06:39
Doc と View が 1:1 なら、分ける意味も薄いしな。
662:デフォルトの名無しさん
08/11/25 18:36:10
Viewが分割サポートする場合は1:1でもDocは必要だぜ
663:名無し募集中。。。
08/11/25 18:54:48
そっかSDIはDocが1つなだけでViewは1つとは限らないか
664:デフォルトの名無しさん
08/11/25 19:27:45
SDIの単純なエディタでも、CSplitterWndでViewを分割して、離れた場所の
テキストを表示したりできるからね。
665:デフォルトの名無しさん
08/11/26 17:34:11
C**Doc::Serializeを使っているのですが、ファイルの保存や開くときのファイル形式を
する方法はありますか?
666:デフォルトの名無しさん
08/11/26 17:35:42
訂正>>
C**Doc::Serializeを使っているのですが、ファイルの保存や開くときのファイル形式を
指定する方法はありますか?
667:デフォルトの名無しさん
08/11/26 17:52:53
自分でSerializeを書けばいい
668:名無し募集中。。。
08/11/26 18:10:15
拡張子という意味ならリソースのString Tableで"IDR_アプリ名TYPE"の定義で指定
\nで区切られた何番目がどんな意味かはヘルプ参照
"IDR_アプリ名TYPE"は、InitInstance()の中でnewするCMultiDocTemplate()の第1パラメータ
669:デフォルトの名無しさん
08/11/26 18:32:50
助かりました!!
670:デフォルトの名無しさん
08/11/26 23:18:28
Win7では2D描画はDirect2Dがメインになるって聞いたが、旧Windowsをサポートするなら結局GDIの方がいいのかな
671:651
08/11/26 23:35:46
皆さんお返事ありがとうございます。651です。
SDIといってもCFormViewをベースに、複数のダイアログを切り替えて表示するような
プログラムを作っています。データの所在がそれぞれのダイアログに散らばってしまうと
管理が面倒なので今はDocumentクラスにすべて実体を持たせ、メニューのハンドラも
そこにおいています。
みなさんの説明を要約すると基本的なセオリーとしては、
・GUI等の画面表示に関係するデータ、ハンドラ: View(ダイアログ)に持たせる
・ファイル入出力に関するデータ、ハンドラ: Docに持たせる
・アプリ全体に関する設定: CWinAppとかMainFrameに持たせる
と言ったところでしょうか。
データの中にはコンストラクタでデータ設定したりオブジェクト生成したりしていて
その順番が問題になる事もありますので、その辺も考慮して決めたいと思います。
672:デフォルトの名無しさん
08/11/27 01:01:54
ボタンは、BM_SETSTATE で凹ませることができますが、
スピンコントロールの上ボタンや下ボタンを凹ませるには、
どのようなメッセージを送れば良いのでしょうか?
673:名無し募集中。。。
08/11/27 01:15:56
>>670
> Win7では2D描画はDirect2Dがメインになるって聞いたが
VistaではGDI ハードウェアアクセラレーションが効かなかったが
Windows7では有効になる
URLリンク(d.hatena.ne.jp)
674:デフォルトの名無しさん
08/11/27 01:36:16
テクスチャサイズ8K×8Kって結構厳しいな。
家の7600GSじゃ4K×4Kが最大だから対応できないのか。
675:デフォルトの名無しさん
08/11/27 04:56:15
今更MFCの勉強したいんですがどの本読めばいいですか?
ずーっと昔に買ってそのまま放置しておいたプログラミングVisualC++.NET基礎編があるのですが
やっぱり新しい本を購入してやったほうがいいですか?
676:デフォルトの名無しさん
08/11/27 07:23:12
ソースコード読むのが一番遠回りで一番近道な気がしてきた
適当になんか作りたいだけならサンプル眺めてるだけでいいし
677:デフォルトの名無しさん
08/11/27 12:00:03
>>675
基本VS6時代の本でおK
というかあの頃の本が一番詳しく書いてある
VSが.NETになってからだとVC本がしょっぱい現実
678:名無し募集中。。。
08/11/27 13:07:56
MFCの勉強なら「Scribble サンプル : MDI 描画アプリケーション」
のチュートリアルを一通りやるといいよ
VC6の時はSTEP1〜7までていねいに解説してあった
679:デフォルトの名無しさん
08/11/27 22:41:01
それMFCの最初のテーマとしては最悪だよ
何人がそれであきらめてやめたことか
悪いことは言わん
最初は、ダイアログアプリからやるべし
680:デフォルトの名無しさん
08/11/27 22:54:16
慣れてくれば、あのサンプルの意図するところも解るのだけどね。
最初にあれに手を出すと、確実に拒絶反応起こすこと請け合い。
ダイアログアプリ以外だと、Document-Viewを切ったSDIとかも練習には良いな。
681:デフォルトの名無しさん
08/11/27 23:04:43
とりあえずダイアログを使いこなせないとSDIは厳しいだろ
SDIやるなら、適当にGDIの勉強とか、Doc-View-Frameとかの関係を理解するとか・・・良いサンプルないかな
682:デフォルトの名無しさん
08/11/28 02:55:52
MFCサンプル
URLリンク(msdn.microsoft.com)
URLリンク(www.microsoft.com)
683:名無し募集中。。。
08/11/28 12:58:34
薦めておいて何だが、そういえばScribbleは途中で投げ出した記憶があるな
でもリソースエディタの使い方とかVSの操作は役に立ったような・・・
684:デフォルトの名無しさん
08/11/28 19:39:24
ダイアログベースのアプリからモードレスウィンドウを表示しているのですが
ウィンドウを破棄する時に警告がでてしまいます
警告の内容はデストロイウィンドウが呼ばれてないといった内容で
ダイアログを破棄するときに実際にデストロイウィンドウを呼んでみると
例外エラーが発生してアプリケーションが落ちてしまいます
685:デフォルトの名無しさん
08/11/28 19:40:28
質問はどうしたらうまくいくのでしょうか?ということです
686:デフォルトの名無しさん
08/11/28 23:46:39
CWnd::DestroyWindow()のかわりにCWnd::PostMessage()を使ってみては?
687:デフォルトの名無しさん
08/11/29 01:26:55
モードレスウィンドウのインスタンス生成やデータの持たせ方等で方法は
一つではないが、留意しなければいけないのは、モードレスウィンドウの
表示/非表示の繰り返しでメモリリークしないことと、「閉じる」操作など
で親ウィンドウが消滅した際に、モードレスウィンドウが開かれていれば
終了前に閉じれること。
ダイアログベースでメインウィンドウをモードレスに変更したのか、別に
モーダレスウィンドウを開くのか不明だが、後者と仮定しての一例...。
モードレスウィンドウ(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- あたりも参照のこと。
688:デフォルトの名無しさん
08/11/29 01:32:49
ていうか、CDialogを上手く隠ぺいしたら、モーダレスダイアログの抽象クラスくらい作れそうな気がするな
IDDあたりも工夫して・・・
689:デフォルトの名無しさん
08/11/29 01:52:05
抽象クラスって意味判って言ってるのか?
690:デフォルトの名無しさん
08/11/29 01:57:20
何もおかしくないと思うぞ
CDialogのような使い方は出来ないと思うけど
691:デフォルトの名無しさん
08/11/29 02:40:06
>>686-687
レスありがとうございます
このサイトのコードを参考にしていたのですがこれがなんかまずかったみたいです
URLリンク(athomejp.com)
CWaitDlg *pWait = new CWaitDlg();
pWait->Create(this);
//処理
pWait->DestroyWindow();
delete pWait;
で普通に消せました
ご迷惑おかけしました
692:デフォルトの名無しさん
08/11/29 03:03:13
Viewの中でCEditをcreateで生成して用いているのでPreTranslateMessageで
キー入力を認識しているのですが、ctrl+Cなどコピペや複合の入力を検知する方法はありますでしょうか。
XP+VC2005です。
693:デフォルトの名無しさん
08/11/29 03:11:57
>>691
なんでnew使うの?
{
CWaitDlg wait;
wait.Create(this);
// 処理
wait.DestroyWindow();
}
でいいと思うのだけど。
破棄のタイミングに拘らなければブロック化({})すら要らない。
694:デフォルトの名無しさん
08/11/29 03:32:55
>>693
あんまり意味ないです
貼り付けたサンプルがたまたまそうだったからという理由だけですw
695:デフォルトの名無しさん
08/11/29 03:43:50
>>691
CTestDlg::PostNcDestroy()にdelete this;って記述されてるので例外が発生したんじゃないの?
>>692
リソースに記述してCOMMAND_UIあたりで処理するのではなかったっけ?
696:デフォルトの名無しさん
08/11/29 04:13:03
>>695
>CTestDlg::PostNcDestroy()にdelete this;って記述されてるので例外が発生したんじゃないの?
いや、なんかよくわかりませんでした
とりあえず、モードレス側に書く処理はCreate関数だけで
削除は親に全部まかせるのがいい気がします
697:デフォルトの名無しさん
08/11/29 17:15:04
>>693>>694
モードレスの場合はダイアログの作成と破棄のタイミングが違うのでメンバに抱えてnewを使う
698:デフォルトの名無しさん
08/11/29 18:14:42
>>697
モードレスとモーダルを同じダイアログで使いまわす状況なんてないんじゃね?
699:デフォルトの名無しさん
08/11/29 18:30:38
何れにしても、わざわざnew/deleteして使わなくてもいいだろ。
ダイアログが閉じられたからといって、
クラスのインスタンスを即座に破棄しなければならない理由は無い。
別々の派生クラスを時と場合に応じて使い分ける、とかいうなら話は解るけど。
700:デフォルトの名無しさん
08/11/29 20:37:50
>>699
じゃあモードレスの場合にダイアログが作成されてるか破棄されてるかはどうやって判別すんの?
701:デフォルトの名無しさん
08/11/29 21:03:49
画面に線だけを書きたいときは領域を塗りつぶしてから書いたほうがいいですか?それともなんかコントロールを置いてそれに書いたほうがいいですか?
702:デフォルトの名無しさん
08/11/29 21:08:11
領域を塗りつぶしてから書いたほうがいい
703:デフォルトの名無しさん
08/11/29 21:17:29
>>700
用語が曖昧だからなんとも言えないけれど、モードレスダイアログが実際に表示されているのかされていないのか、
そのダイアログ自身以外に一体全体誰が気にしなければいけないというの?
そのダイアログのインスタンスを持っている側にとっては、出ていて欲しいときに出せと要求するだけで充分でしょ。
704:デフォルトの名無しさん
08/11/29 21:17:48
塗りつぶして線を引いた、領域と同じサイズの絵を描画した方がいい
705:デフォルトの名無しさん
08/11/29 21:18:19
>>701
用途と状況と目的によりけりかと。
706:!699
08/11/29 21:22:14
>>700
質問元のモードレスダイアログは、処理中ダイアログみたいだから、
判別する必要ねえんじゃね?
ユーザーによるオペレーションで表示/非表示するようなやつの場合、
俺は(複数表示する必要なかったので)シングルトン的なものにして対応したんで、
作成されている/いないを判別するは必要なかった。
707:706
08/11/29 21:24:28
リロードせずにレスした。 反省した。 次はリロードする。
708:デフォルトの名無しさん
08/11/29 22:06:13
>>706
処理中ダイアログって考えはなかったわ
でも1ハンドラ内に>>691の記述でモードレス中ダイアログを表示できたっけ?
709:デフォルトの名無しさん
08/11/29 22:07:10
>>703
表示/非表示じゃなくダイアログの作成/破棄な CDialog::Create()とCWnd::DestroyWindow()
インスタンスの生成/破棄(new/delete)とも別だよ
710:デフォルトの名無しさん
08/11/29 22:20:51
>>708
PeekMessageでもはさむんじゃね?
711:デフォルトの名無しさん
08/11/29 22:48:54
>>709
事情は変わらんだろ。ダイアログ自身が管理していれば、利用者はそれを意識する必要はない。
712:デフォルトの名無しさん
08/11/29 22:52:27
俺はそもそも
モードレスとモーダルをいっしょのクラスで分岐させる無意味な汎用性と
Createされてる状況でCreate関数を再び呼ぶ必要を考慮してるクラスの仕様のが
気持ち悪くていまの話題についていけないけどね
713:デフォルトの名無しさん
08/11/29 22:56:54
いっそのこと新しいC++向けのMS製フレームワークを提供してほしいわ
.NETは相性悪すぎる
せっかくDirect2DとDirectWriteもC++向けに提供するんだし、アプリケーションハンガリアンでエレガントなクラス群を是非
714:デフォルトの名無しさん
08/11/29 23:01:17
>>711
モードレスダイアログのサンプル書いてみてよ
715:デフォルトの名無しさん
08/11/29 23:03:47
>>714
CWaitDlg wait;
wait.Create(this);
// 処理
wait.DestroyWindow();
716:デフォルトの名無しさん
08/11/29 23:14:20
>>715
処理中ダイアログじゃなくてOKボタン押すまで表示されてるモードレスダイアログのサンプル書いてみてよ
717:デフォルトの名無しさん
08/11/29 23:15:52
>>716
意味がわかんない
718:デフォルトの名無しさん
08/11/29 23:18:19
>>716
CWaitDlg wait;
wait.Create(this);
while(1){
PeekMessage
GetMessage
TranslateMessage
DispatchMessage
if(ボタンが押されたら)break;
//処理
}
wait.DestroyWindow();
719:デフォルトの名無しさん
08/11/29 23:32:06
>>718
モードレスのサンプルになってないよ
その用途ならモーダル使うのが普通じゃん
720:デフォルトの名無しさん
08/11/29 23:36:43
>>719
プログレスバーが表示できるじゃん
質問元が思いっきりそういう意図じゃん
普通だったらモードレスなんてつかわねぇよ
正直いってバグりやすいもん
大部分がこんな感じで済むんだよ
721:706
08/11/29 23:49:45
>>708
1ハンドラでの処理は考えてなかった。 てか忘れてた。
new/deleteの話いらないって話なんだから、1ハンドラだね。
そういうわけで、>>706はなかったことに。
(>>710の通りやればできそうだけど、確認したくないという事情によります)
まったく持ってごめん。 反省した。 次は、、次も、、とり頭だからやってしまうかもしれん。
722:デフォルトの名無しさん
08/11/29 23:58:54
>>718を>>711のようにするにはどうすればいいの?
723:デフォルトの名無しさん
08/11/30 00:00:13
>>722
何がやりたいのか具体的にいいたまへ
724:デフォルトの名無しさん
08/11/30 00:13:23
>>716
どっかのクラス
{
CWaitDlg m_wait;
};
どっかのクラス::モーダレス表示するハンドラ()
{
wait.Create(AfxGetMainWnd());
}
これで、親クラスが消滅するかダイアログの「×」ボタン「OK」または
「Cancel」ボタンがクリックされるまで表示されたままになる。
>>719
モードレスだが?
>>722
スレッドを起こせばいい。
725:デフォルトの名無しさん
08/11/30 00:15:04
>>724
> wait.Create(AfxGetMainWnd()); ... 誤
m_wait.Create(AfxGetMainWnd()); ... 正
726:デフォルトの名無しさん
08/11/30 00:30:19
>>723
ダイアログ自身が管理する形で書かれていないので
CWaitDlgが管理するようにしたいんだけど
727:デフォルトの名無しさん
08/11/30 00:38:36
>>724
m_wait.Create(AfxGetMainWnd());が2回呼ばれたらマズくない?
m_wait.DestroyWindow();は必要ないの?
728:デフォルトの名無しさん
08/11/30 00:39:43
>>726
何を管理する?ちゃんと日本語で書けよバカSEよ。それとも低級な魔法
使い気取りか?
729:デフォルトの名無しさん
08/11/30 00:51:56
>>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()等も同様。
730:デフォルトの名無しさん
08/11/30 01:12:45
>>729
呼ばれなくね?
とりあえず俺の環境では
Warning: calling DestroyWindow in CDialog::~CDialog --
OnDestroy or PostNcDestroy in derived class will not be called.
って警告がでちゃうよ
731:デフォルトの名無しさん
08/11/30 01:27:56
だよね。質問元の>>684にもそう書いてあるし
732:デフォルトの名無しさん
08/11/30 02:18:51
>>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のバグとか、ゲイツ様のせいにすんじゃねぇぞ、ゴルァ!』
ってこった。
733:デフォルトの名無しさん
08/11/30 02:49:47
そんなことは、皆了解済みの上で話していると思うのだがどうか。
わざわざトレース文が入っているようなお情け処理を、
正式な仕様として扱う勇気は俺には無いな。
734:デフォルトの名無しさん
08/11/30 05:34:25
>>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);
}
735:デフォルトの名無しさん
08/11/30 07:02:30
>>733
でもそこなんでトレースいれるんだろうね
少なくとも俺の感覚としちゃそこでDestroyWindowを呼ぶのは当然の処理で
警告なんて出す意味がわからないんだけど
736:デフォルトの名無しさん
08/11/30 07:11:07
CreateとDestroyWindowが対だからじゃね?
コンストラクタでCreateしないからデストラクタでもDestroyWindowしない方針
737:デフォルトの名無しさん
08/11/30 08:00:16
>>736
しろよな
しない方針にすることでなにかいいことあるのか?って感じ
Create関数のヘルプにもそんなこと書いてねーし
DestroyWindow関数のヘルプには
MFC側で呼んだり呼ばなかったりするからユーザー側でうまくやれよマジで
とかかなりむかつく仕様だしで作った奴マジ嫌な感じだな
738:732
08/11/30 10:06:48
>>733
> そんなことは、皆了解済みの上で話していると思うのだがどうか。
理解したり、(実際に呼ばれていることを)知っていたら『呼ばれなくね?』
なんて発言は、マヂでありえなくね。(w
C++の基本を理解し、警告メッセージの意味を正しく理解していれば、
> わざわざトレース文が入っているようなお情け処理を、
> 正式な仕様として扱う勇気は俺には無いな。
なんて発言も出てこないハズ。
739:732
08/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
08/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();
}
ただそれだけのことだ。
741:デフォルトの名無しさん
08/11/30 10:14:42
>>738
俺とそいつは別人だ
ちなみに「よばれてなくね?」は俺
>>739
警告の必要なくね?
742:デフォルトの名無しさん
08/11/30 10:18:33
>>740
でもヘルプでだってどういうときに
DestroyWindowを呼ばなきゃいけないのか書いてないわけだし
当然MFCの中身の都合なんてこっちはしったこっちゃないわけで
もし、自分でこういうもんを作るとしたら解放はフレームワークのほうで自動でやってほしいかな?
743:デフォルトの名無しさん
08/11/30 11:15:41
>>740のコードがまずいというのもわかりにくいしな
744:デフォルトの名無しさん
08/11/30 15:54:00
何この流れ
どうせお互いまったく譲り合わないんだから、これ以上書いても無駄だよ
745:デフォルトの名無しさん
08/11/30 18:51:38
Win7ってペイントとかワードパッドにリボン採用してるよな
今後作るソフトはリボンで作った方が惹きやすいのだろうか・・・2008SP1は持ってるが
次ページ最新レス表示スレッドの検索類似スレ一覧話題のニュースおまかせリスト▼オプションを表示暇つぶし2ch
4357日前に更新/186 KB
担当:undef