ページ 1 / 1
コモンダイアログ
Posted: 2009年3月03日(火) 19:10
by ざこ
MFCのVC++6.0を使っています。
ダイアログ1に【リストボックス】と【追加ボタン】があります。
ダイアログ2に【エデットボックス】と【OKボタン】があります。
ダイアログの1の追加ボタンを押すとダイアログ2がでてきます(コモンダイアログ)
それでエデットボックスに何かを入力し、OKボタンを押すとリストボックスに表示されるようにしたいんですが
クラスがそれぞれ別々でアクセスできません。これは継承を使うんでしょうか?それとも他の何かでしょうか?
Re:コモンダイアログ
Posted: 2009年3月03日(火) 19:49
by バグ
publicとprivateの違いを調べてみてください(o^-')b
Re:コモンダイアログ
Posted: 2009年3月04日(水) 09:19
by ざこ
うーん、その可能性も考えには入っていましたがpublicは公開でprivateは非公開。非公開はそののクラスのほかのメンバからしかアクセスできない だったと思います。m_listbox(リストボックスのメンバ変数ですが)はpublicになっており、その可能性は消去したのですが。
Re:コモンダイアログ
Posted: 2009年3月04日(水) 09:32
by バグ
ダイアログ2のエディットボックスはpublicですか?
Re:コモンダイアログ
Posted: 2009年3月04日(水) 09:40
by ざこ
どちらもpublicです
Re:コモンダイアログ
Posted: 2009年3月04日(水) 09:55
by バグ
今、テストプログラムを書いてみたのですが、DoModal関数を抜けた時点でダイアログクラスは破棄されてしまうようです。
ですので、DoModal関数でダイアログ2を表示する前に、文字列保持用の変数へのポインタを、あらかじめダイアログ2へ追加しておいた文字列のポインタ変数へ渡しておき、ダイアログ2が閉じる前(今回の場合ならば、ダイアログ2のOnOK関数内で)にポインタの中身を変更してやればいけると思います。
Re:コモンダイアログ
Posted: 2009年3月04日(水) 10:05
by バグ
サンプルです。ダイアログ1の追加ボタンが押された際と、ダイアログ2のOKボタンが押された際のイベントハンドラをそれぞれ追加するのと、下記のメンバ変数を追加してください。
ダイアログ1
CListBox m_listbox
ダイアログ2
CString* m_pstr
CEdit m_editbox
// 追加ボタンが押された
VOID CDialog1::OnButtonAdd()
{
// ダイアログ2の実体を生成する
CDialog2 dlg;
// 文字列保持用のCStringクラスの実体を生成する
CString str;
// ダイアログ2のCStringへのポインタ変数へstrのアドレスを代入する
dlg.m_pstr = &str;
// ダイアログ2を表示する
dlg.DoModal();
// リストボックスへ文字列を追加する
m_listbox.AddString(str);
}
// ダイアログ2のOKボタンが押された
VOID CDialog2::OnOK()
{
// エディットボックス内の文字列を取り出す
CHAR str[256];
m_editbox.GetWindowText(str, 256);
// CStringクラスへ文字列を代入する
*m_pstr = str;
// ベースクラスのOnOK関数の実行
CDialog::OnOK();
}
Re:コモンダイアログ
Posted: 2009年3月04日(水) 10:06
by バグ
ごめんなさい、preタグを忘れてました…OTL
// 追加ボタンが押された
VOID CDialog1::OnButtonAdd()
{
// ダイアログ2の実体を生成する
CDialog2 dlg;
// 文字列保持用のCStringクラスの実体を生成する
CString str;
// ダイアログ2のCStringへのポインタ変数へstrのアドレスを代入する
dlg.m_pstr = &str;
// ダイアログ2を表示する
dlg.DoModal();
// リストボックスへ文字列を追加する
m_listbox.AddString(str);
}
// ダイアログ2のOKボタンが押された
VOID CDialog2::OnOK()
{
// エディットボックス内の文字列を取り出す
CHAR str[256];
m_editbox.GetWindowText(str, 256);
// CStringクラスへ文字列を代入する
*m_pstr = str;
// ベースクラスのOnOK関数の実行
CDialog::OnOK();
}
Re:コモンダイアログ
Posted: 2009年3月04日(水) 10:24
by ざこ
ご親切にどうもありがとうございます。少し色々いじくってみますね。
Re:コモンダイアログ
Posted: 2009年3月04日(水) 13:31
by ざこ
3箇所いじくりました。
1,リストボックスをリストビューにした
2,ダイアログ2にチェックボタンをとりつけた。
3,ダイアログ2にもう1つエデットボックスを付け加えた
ダイアログ2にチェックボタンを追加します。そのチェックボタンがチェックされていたら
上書きをする機能を追加します。色々考えたんですがまず同じように
ダイアログ1
CListBox m_listbox
ダイアログ2
CString* m_pstr
CEdit m_editbox
int m_chkBOX
CButton m_chk
VOID CDialog1::OnButtonAdd()
{
CDialog2 dlg;
CString str_ed1;
CString str_ed2;
int chk;
dlg.m_pstr=&str_ed1;
dlg.m_qstr=&str_ed2;
dlg.m_chkBOX=chk;
i=m_listC.GetItemCount();
dlg.DoModal();
if(chk==0){
m_listC.InsertItem(i,(LPCTSTR)str_ed1);
m_listC.SetItemText(i,1,(LPCTSTR)str_ed2);
}
if(chk==1){
m_listC.InsertItem(○○);
m_listC.SetItemText(●●);
}
}
VOID CDialog2::OnOK()
{
int chk1=m_chk.GetCheck();
char str_ed1[256];
char str_ed2[256];
if(chk1==1){
m_chkBOX=1;
m_ed1.GetWindowText(str_ed1,256);
m_ed2.GetWindowText(str_ed2,256);
*m_pstr=str_ed1;
*m_qstr=str_ed2;
}
else{
m_chkBOX=0;
char str_ed1[256];
char str_ed2[256];
m_ed1.GetWindowText(str_ed1,256);
m_ed2.GetWindowText(str_ed2,256);
*m_pstr=str_ed1;
*m_qstr=str_ed2;
}
CDialog::OnOK();
}
わからない箇所は今の所2点です。
これを実行するとダイアログ2ではチェックボタンの有無によってm_chkBOXを1と0に。
1だと上書き、2だとそのままです。ダイアログ2内ではきちんとできていますがOKボタンを押して
1に移るとおかしくなります。値がおかしくきちんと渡せていないようです。
上書きの機能はまだ入れておりませんが
例
拡張子 移動先
txt C:\\○
XLS C:\\
ダイアログ1がこの状態(拡張子:EDIT1の内容、場所:EDIT2の内容)で
次にダイアログ2で
EDIT1にtxt EDIT2にC:\\△を入力しOKをおすと
拡張子 移動先
txt C:\\△
XLS C:\\
となるように同じEDIT1内容を探し上書きします。
この同じEDIT1の内容がある行を調べるのに何かよい方法はありますか?
長文失礼しました。
Re:コモンダイアログ
Posted: 2009年3月04日(水) 14:14
by バグ
ダイアログ1のint型のchkをダイアログ2の中で変更したい場合は、アドレスを渡してやらなければいいけません。よって、ダイアログ2のm_chkBOXはポインタにしてやらなければいけません。
ダイアログ2
誤:int m_chkBox;
正:int* m_chkBox;
上記の変更に伴う変更…
誤:dlg.m_chkBOX = chk;
正:dlg.m_chkBOX = &chk;
誤:m_chkBOX = 1;
正:*m_chkBOX = 1;
誤:m_chkBOX = 0;
正:*m_chkBOX = 0;
Re:コモンダイアログ
Posted: 2009年3月04日(水) 14:19
by ざこ
文字じゃなくてもアドレスが必要なのですね、勉強になります。
Re:コモンダイアログ
Posted: 2009年3月04日(水) 14:25
by バグ
ところで、『上書き』というのがイマイチ理解できないのですが、既に入力されている内容と同じ内容が入力された場合のみ、追加ではなく上書きしたいという事でいいのでしょうか?
Re:コモンダイアログ
Posted: 2009年3月04日(水) 14:37
by ざこ
そうですね。
EDIT1の内容がリストビューーの一列目に表示されるわけですが
EDIT1の内容はそのままでEDIT2の内容だけ変更したいときに上書きとなります。
EDIT2の内容が同じでも上書きする必要はありません。
※イメージしズらいと思いますので画像貼り付けて起きます。
Re:コモンダイアログ
Posted: 2009年3月04日(水) 14:42
by ざこ
追加ボタンをおしたときのダイアログ2がこちらになります。
Re:コモンダイアログ
Posted: 2009年3月04日(水) 14:53
by バグ
1:追加ボタンを押す
2:ダイアログ2を表示して、拡張子&パスを入力する
3:チェックボックスにチェックが入っていたら、文字列を更新
4:リストビューの全てのアイテムを取得して、文字列を比較する(CStringクラスなら、==演算子が使用できるので比較が楽です)
5:同じ物があれば、何もしない。違うならば、リストビューを更新する
Re:コモンダイアログ
Posted: 2009年3月04日(水) 15:35
by ざこ
そこまでは考えついたのですが、4がわからないんですよね。FindItemを使おうとしていますがうまくいかずで。
Re:コモンダイアログ
Posted: 2009年3月04日(水) 15:52
by バグ
うまくいかないとは?どういう風にですか?
Re:コモンダイアログ
Posted: 2009年3月04日(水) 16:16
by ざこ
ズバリ、ネットで調べても手ごろなサンプルがないのでまともに組めない→この関数であってるのだろうかと不安
初心者にはありがちかもしれません。
LVLFINDIFNFO find_info;
find_info.flag=LVFI_STRIMG;
int n=(find_info.psz==(char*)&s_ed1);
とまではしてみたんですがきちんと稼動はしません
Re:コモンダイアログ
Posted: 2009年3月04日(水) 16:31
by バグ
なるほど(^_^;)
もし、その方法が不安ならば、全部のアイテムを自力で取り出して、ループで総当り比較しては如何ですか?
こちらの方法ならば、さほど難しくはないと思いますよ(^-^)
Re:コモンダイアログ
Posted: 2009年3月04日(水) 16:41
by ざこ
ふうむ、一番厳しいのはクラスごとのメンバ関数を全然知らないってことかな。どこかに一覧があればいいんですが・・MSDNもメンバ関数の中身は簡単にわかりますが逆が全くダメなんで未知の関数だとそこでつまづきますね