リソースを使わないでモーダルダイアログを作成する方法 – プログラミング – Home

リソースを使わないでモーダルダイアログ...
 
通知
すべてクリア

[解決済] リソースを使わないでモーダルダイアログを作成する方法

固定ページ 1 / 2

matyam
 matyam
(@matyam)
ゲスト
結合: 15年前
投稿: 7
Topic starter  

初心者です
複数のアプリで共用したいダイアログがあるのでリソースを使わないでプログラムを作成
したいのです。
コントロール類はすべてコードで配置しています。
(OK,CANCELボタンのほかいくつかのコントロールが配置され指定された時間で自動的に閉
じるダイアログです。リソースIDを使った場合には正常に表示されます)
環境は
Windows XP SP3, Visual Studio 2008 MFC
です

http://www.cycleof5th.com/tips/index.php?date=2007-05-16/1
を参考にして記述したのですが
digcore.cppの311行の
hWnd = ::CreateDialogIndirect(hInst, lpDialogTemplate,
pParentWnd->GetSafeHwnd(), AfxDlgProc);
(BOOL CWnd::CreateDlgIndirect内)
でhWndがNULLになり生成に失敗しているようです。

関連する部分のコード

messageBox.h
typedef struct _ty_dtp{
DLGTEMPLATE dtp;
WORD parm[4];
_ty_dtp(){
dtp.x = 0;
dtp.y = 0;
dtp.cx = 200;
dtp.cy = 100;
dtp.cdit = 2;
dtp.style = 2160591040; //リソースで作成したときの値
dtp.dwExtendedStyle = 0;
}
} ty_DLGTEMPLATE;

messageBox.cpp
Cmessagebox::Cmessagebox(CWnd* pParent /*=NULL*/)
//: CDialog(Cmessagebox::IDD, pParent) //リソース使用の場合はコメントアウトしな

{
swo = SW_SHOW;
swc = SW_SHOW;
killtime = 10000;

}

呼び出し部分
ty_DLGTEMPLATE dtp;
memset( dtp.parm, 0, sizeof( WORD ) * 4 );
msg = new Cmessagebox;
msg->setMessage( tmp0, 300, 40, 500000 );
msg->InitModalIndirect( &dtp.dtp, NULL );
stsd = msg->DoModal();
delete msg;
msg = NULL;

初心者かつ質問も初めてですので情報が足りないかもしれませんがよろしくお願いしま
す。


引用未解決
トピックタグ
bun
 bun
(@bun)
ゲスト
結合: 24年前
投稿: 761
 

コントロール類をコードで配置しただけなら、
コントロールが1つも載っていない枠だけのダイアログリソースを作成し、
普通にモーダルダイアログとしてDoModal()すれば良いのでは?

その後、InitDialogで、各コントロールをCreateしていけば良いだけです。


返信引用
matyam
 matyam
(@matyam)
ゲスト
結合: 15年前
投稿: 7
Topic starter  

bunさん
早速の回答ありがとうございます。

確かにそのとおりなのですが,
複数のアプリでダイアログを共用しようとするとIDが重複しないように注意して設定しな
ければならないと思います。
リソース使わなければIDの重複を気にすることなくプログラミングができると思い質問さ
せていただきました。

背景の説明が不足して申し訳ありません。


返信引用
仲澤@失業者
(@uncle_kei)
Prominent Member
結合: 5年前
投稿: 828
 

>複数のアプリでダイアログを共用しようとするとIDが重複しないように注意して
>設定しな>ければならないと思います。
>リソース使わなければIDの重複を気にすることなくプログラミングができると思い
>質問さ>せていただきました。

ん??? 全く意味がわかりませんねぇ。

複数の別々のアプリケーションで共有するDLGなら、
DLLにリソースとコードを分離すれば十分ですよね。
コモンダイアログ(ファイルオープンなど)と同じ仕組みじゃ
だめな理由が聞きたいところです。

そもそも、IDが違うということは、そのコントロールの
意味自体が異なるということです。意味の異なるコントロールを
配置したDLGは意味の異なるDLGであるのであって、
そもそも別に実装しなければいけません。


返信引用
ITO
 ITO
(@ITO)
ゲスト
結合: 22年前
投稿: 1235
 

ん?
> 複数のアプリで共用したいダイアログがあるのでリソースを使わないでプログラムを
> 作成したいのです。
それは無理かな?と思います。
何か方法があるなら僕も知りたいですね。

> コントロール類はすべてコードで配置しています。
> リソース使わなければIDの重複を気にすることなくプログラミングができると思い
> 質問させていただきました。
IDってダイアログ上で使うコントロールIDですよね?
IDの重複を避けるのもリソースを使う目的のひとつだと思います。
コンパイルした時にエラーで知らせてくれます。


返信引用
subaru
 subaru
(@subaru)
ゲスト
結合: 19年前
投稿: 381
 

とりあえず
>dtp.cdit = 2;
コントロールが1つもないのに2を指定しているのはおかしいでしょう。

#ダイアログテンプレートを組み立てるのは面倒なので
#一旦リソースから読み込んでそのバイナリの内容を確認し、
#コード側に静的な配列として保持するというのもありかも。


返信引用
matyam
 matyam
(@matyam)
ゲスト
結合: 15年前
投稿: 7
Topic starter  

中澤@失業者さま

厳しいご指摘ありがとうございます
当方初心者につきDLLについてはよくわからないのでCDialogの派生クラス(Cmessagebox)
を作りそのクラスを共用できないかと考えました。

Cmessagebox.hで
#define IDD_MESSAGEBOX 199
のように設定した場合
それを呼び出す方(メイン側)で同じ番号の空のリソースを作成すればダイアログを作成で
きるのですが,すでに同じ番号のダイアログが作成されていた場合に問題があるように思
われました。(認識が間違っているかも知れません)
そこで,ネットで検索してリソースを使わずにダイアログを作成する方法を見つけたので
試してみたところダイアログが表示できなかったので質問することにしました。


返信引用
matyam
 matyam
(@matyam)
ゲスト
結合: 15年前
投稿: 7
Topic starter  

ITOさま

>> コントロール類はすべてコードで配置しています。
>> リソース使わなければIDの重複を気にすることなくプログラミングができると思い
>> 質問させていただきました。
>IDってダイアログ上で使うコントロールIDですよね?
>IDの重複を避けるのもリソースを使う目的のひとつだと思います。
>コンパイルした時にエラーで知らせてくれます。

ダイアログのID(Resource.hに記述されるもの)です


返信引用
ロマ
 ロマ
(@ロマ)
ゲスト
結合: 18年前
投稿: 170
 

コードを見て思いつくのは、
* cdit=2なのにDLGITEMTEMPLATEがない
* style(0x80c800c0)にDS_SETFONT(0x40)が指定されているのにフォント情報がない
です。

ty_DLGTEMPLATEのメモリーダンプと
正常なリソースをLoadResourceしたdlgtemplateのダンプを比較してみてください。
(VS2008でどうやれば簡単にダンプが出るのかは私には分かりませんが)


返信引用
matyam
 matyam
(@matyam)
ゲスト
結合: 15年前
投稿: 7
Topic starter  

subaruさま

dtp.cdit = 0;

にするとCmessageBoxのOnInitDialog()まで行き着くことができました。
ありがとうございます。

CmessageBoxはDialogの挿入で作ったクラスでリソースはOKとCancelボタンがある状態で
す。そのDLGTEMPLATEをみていたためdtp.cdit = 2 になったものと思います。
OnInitDialog()ではOKボタンCancelボタンを移動しているのでそのところでエラーが出ま
すが一歩進んだと思います。
Dialogの挿入で作成したリソースにはOKとCancelボタンがあるのでそのDLGTEMPLATEを使
えばOKボタンCancelボタンの情報もあると思ったのですが足りないようですね。


返信引用
matyam
 matyam
(@matyam)
ゲスト
結合: 15年前
投稿: 7
Topic starter  

みなさま

質問の仕方が悪くて申し訳ありませんでした。

dtp.cdit = 0;

として

CmessageBoxのOnInitDialog()内にボタンコントロール(OKボタンCancelボタン相当)をコ
ードで書く

ことにより目的(リソースを使うことなくダイアログ作成する)が達成できました。

どうもありがとうございました。


返信引用
仲澤@失業者
(@uncle_kei)
Prominent Member
結合: 5年前
投稿: 828
 

>Cmessagebox.hで
>#define IDD_MESSAGEBOX 199
>のように設定した場合
>それを呼び出す方(メイン側)で同じ番号の空のリソースを作成すればダイアログを
>作成できるのですが,すでに同じ番号のダイアログが作成されていた場合に問題が
>あるように思われました。(認識が間違っているかも知れません)

 残念ならがら間違っていると思います。
この問題が起きるのは、DLGのリソース dlg.rcを複数のexeの*.rcで
#includeして「*.rc」単位で共用しようとしているの場合などです。
この方法は、もはや誰もやらなくなった危険な賭けであると言っておきましょう。

いまは、共用のDLGは共用のDLLに収めるのがごく普通の方法です。
きれいにカプセル化されたDLL上のDLGは、そのIDがいくつであるかなど、
知る必要さえありません。

 多くのプログラマが、おそらく一生使うことのないであろう、
CreateDialogIndirect()を勉強するより、DLLの活用方法を学ぶのを優先
させたほうが自分のためだと考えます。
まぁ、外野席の人はおもしろいかもしれませんが(vv;)。


返信引用
matyam
 matyam
(@matyam)
ゲスト
結合: 15年前
投稿: 7
Topic starter  

中澤@失業者さま

今後DLLについて勉強していきたいと思います。
どうもありがとうございました


返信引用
subaru
 subaru
(@subaru)
ゲスト
結合: 19年前
投稿: 381
 

自作MessageBox程度のものみたいなのでリソースなしで作るのもありかとは思うけど
多言語対応が必要になったらDLLに分離せざるを得ないでしょうね。


返信引用
maru
 maru
(@maru)
ゲスト
結合: 17年前
投稿: 358
 

>  多くのプログラマが、おそらく一生使うことのないであろう、
> CreateDialogIndirect()を勉強するより、DLLの活用方法を学ぶのを優先
> させたほうが自分のためだと考えます。
これには同意いたしますが、

> この問題が起きるのは、DLGのリソース dlg.rcを複数のexeの*.rcで
> #includeして「*.rc」単位で共用しようとしているの場合などです。
> この方法は、もはや誰もやらなくなった危険な賭けであると言っておきましょう。
残念ながら正しい記述とは言えないでしょう。マイクロソフトがやっています。
Visual Studioが作成したリソースの一部を抜粋。
#if !defined(AFX_RESOURCE_DLL) || defined(AFX_TARG_JPN)
LANGUAGE 17, 1
#pragma code_page(932)
#include res\\MFC_MDI.rc2 // Microsoft Visual C++ 以外で編集されたリソース
#include l.JPN\\afxres.rc // 標準コンポーネント
#include l.JPN\\afxprint.rc // 印刷/印刷プレビュー リソース
#if !defined(_AFXDLL)
#include l.JPN\\afxribbon.rc // MFC のリボン リソースとコントロ
ール バー リソース
#endif
#endif

既存のアプリケーションにリソースを追加するならいざ知らず、新規にアプリケーショ
ンを作成するのであれば、そのIDを避けて使用すればいいだけの話。要は使い方次第。
複数のそういうリソースがあってそのIDが衝突している場合は問題ですが。


返信引用
固定ページ 1 / 2

返信する

投稿者名

投稿者メールアドレス

タイトル *

プレビュー 0リビジョン 保存しました
共有:
タイトルとURLをコピーしました