教えてください。
SDIのメニューから、ボタンクリックでプロパティシート
を呼び出し、エディットボックス(double型)から取得した
値をFormViewにTextOut表示させるというプログラムを作っています。
が、どうしても取得した値を、画面に表示させることができません。
変数に入れた値は、計算中にE-11等の単位を付加して計算させていますので、
Double型がベストだと思うのですが、同時に取得した値(指数部分より前だけ)
をViewで確認&テキスト形式で保存しなくてはいけません。
プログラム本体は何の問題なく出来上がって走っているのですが、
この部分でハマっています。
もし、こうしたら?っていうのがあれば教えてください。
ちなみに、エディットボックスをCString型にしたら、プログラム本体が
走らなくなってしまいました。
誰かたすけて~!
みかん箱さん、こんにちわ。
なにぶん私も初心者なので、質問をはきちがえているかも
知れませんが、勇気を出して、回答します。
エディットボックスの値を一回CString型に変換したら
だめなんでしょうか?
私は、ダイアログベースでしか作ったことないので、
ぜんぜん自信がないんですが、
UpdateData(TRUE);
CString SSS;
SSS.Format(%f,エディットボックスの値);
UpdateData(FALSE);
これで、CString型のSSSに、
エディットボックスの値が入ると思うんですけれど・・・。
それとも、”エディットボックスの値”のような変数に、
エディットボックスの値を格納することはできないんでしょうか?
(その場合、ちょっとわたしにはわからんないです、すみません)
スーパーマリ子様 みかん箱です。
レスありがとうございます。ちょっとだけ光が見えてきました。
方向的には、Formatで間違っていませんでした。
なるほど、こんなのもあるんですね。
double m;
CString m1;
CString *m1(double m,CString m1);
では、うまくいかなかったのに。
FormViewになんとか数値は表示できたのですが、
中身が空っぽ(doble値は0.091なんですが、表示は0.000000になってしまう)
ひょっとすると%fに違う記号を指定するとできるのかなぁ。
//プロパティシート部分に(mには0.091を最初に#defineで格納してあります。)
double m;
CString m1;
m1.Format(%f,m);
//で値を取得。
//※書きませんがOK戻り・キャンセル戻りも記述してあります。
FormView//で
pDC->TextOut(200,250,m1);
//で表示させようとすると、0.000000となってしまうのです。
FormViewに別のボタンを用意し、それをクリックするとちゃんと計算が
始まるので、mもしくはm1の中に値は入っていると思うのですが..。
あと一歩!あと一歩な気がするぅ~!
こんにちは、スーパーマリ子です。
適当に考えた名前だったけど、改めて書くと
すごい恥ずかしいです。後悔。 (凸o凸)
>ひょっとすると%fに違う記号を指定するとできるのかなぁ。
むむむ・・・。
double m=0.091;
CString m1;
m1.Format(%f,m);
AfxMessageBox(m1,MB_OK);//m1に格納された文字列を、!のメッセージボックスで表示
↑(コレ)
AfxMessageBox関数を使ってメッセージボックスを表示して
確かめたところ、「0.091000」という数字(ホントは文字)が
表示されたところを見ると(ちなみに今回はMDIで作りました)
多分、%fでいいと思うんですけれど・・・。
Format関数呼ぶ直前に、ちょこっと、mに数値を入れても、
やっぱり0.00000000000が出るんでしょうか?
質問に質問で返して、ごめんなさい。
Bunです。
MFC,SDIで作成しているのでしょうか?
m1.Format(%f,m);
はどのクラスのどの関数内に記述されていますか?
pDC->TextOut(200,250,m1);
はどのクラスのどの関数内に記述されていますか?
m1 = 0.091 であればTextOut(200,250,m1)は0.091を表示します。
あと一歩です。がんばってください。
スーパーマリ子様(マリヲより恥ずかしくないと思いますヨ。)ありがとうございます。
Bun様ありがとうございます。
はい、お二人が書いてくださったとおり、全部Viewの中で書くとOKですが、
間にプロパティシートを経由すると、どうもうまく値渡しがいきません。
ちょっと長くなりますが、正確な設定を下に書くと..。
MFC,SDIで作成しています。doule mは、グローバルで宣言しています。
まず、プロパティシートですが、下のような設定です。
void CMainFame::OnParam()
{
CPSheet cps1(プロパティシート);
cps1.m_p1.m_p1e1=m;/*プロパティシート内の1ページ目、1つ目のエディットボックスという意味です。
m_p1e1は、m_p1の中にあります。*/
if(cps1.DoModal()==IDOK)
{
m=cps1.m_p1.m_p1e1;
InvalidateRect(NULL);
}
}
Viewですが、#includeで MainFrm.h/PSheet.hを、メンバ変数にCString m1を記述しています
下の記述場所は、CTTViewの中です。
void CTTView::OnDraw(CDC *pDC)
{
CTTDoc* pDoc=GetDocument();
ASSERT_VALID(pDoc);
CPSheet cps1(プロパティシート);
m1.Format(%f,cps1.m_p1.m_p1e1);
pDC->TextOut(200,250,m1);
}
ちなみに、m_p1e1の変わりにmを直接使用すると、ビルドがとおりません。
「mの宣言を確認してください。」
また、m1.Format(%f,cps1.m_p1.m_p1e1);をOnParamの中で使用すると
値自体が表示できなくなります。
なにか、根本的に違うのでしょうか..。
ちょっと頭を切り替えて、FormViewを使わず値を確認できて、テキスト形式で
保存できる技があったら、それでも良いので教えてください。
ちなみに、値は全部で36個あります。
早く人間になりたぁい!じゃなくて、早く納品したぁい!!
Bunです。おはようございます。
読んだ内容からすると
void CMainFame::OnParam()内のcps1とCTTView::OnDraw()内のcps1は
全く別のインスタンスのようです。おわかりでしょうか?
とするとCTTView::OnDraw()内のcps1.m_p1.m_p1e1の値は不定ではないでしょうか?
まず、mはグローバル変数ということですから、どちらの関数でも参照可能です。
CTTView::OnDraw()内の
m1.Format(%f,cps1.m_p1.m_p1e1); を
m1.Format(%f, m); としてTextOut()可能かどうか調べてください。
あと、「0.091歩」です。がんばってください。
>スーパーマリ子様(マリヲより恥ずかしくないと思いますヨ。)
インパクトがあって、とっても良い名前ですよ。名義変更はしないでくださいね。
Bunです。追記です。
>全部Viewの中で書くとOKですが、
全部Viewに記述できない理由があるのでしょうか?
Bun様 こんにちは。
>void CMainFame::OnParam()内のcps1とCTTView::OnDraw()内のcps1は...
うーん。cps1を.で区切ったときに、自動的にメンバのm_p1を呼びに言った
ので、そのまま使ってしまったんですが、別物なんですね。
>m1.Format(%f, m); としてTextOut()可能かどうか調べてください。
これは、できませんでした。「'm'定義されていない識別子です」というのがエラーです。
グローバル変数なのに、呼び出せない事がそもそもなにか、変なのですが。
(グローバルフォルダに変数が入っているので良いと思うんですけど。)
>全部Viewに記述できない理由があるのでしょうか?
正直なところ、最初に全部をView以外に書いてしまったから。というのが理由です。
今・FormViewの表示につまづいていますが、肝心のプログラム本体
(double mのような変数36個を指数化して計算に使用する、約4000行のプログラムを書いています。)
は、プロパティシートを含めて、すでに完成してしまっているのです。
プロパティシートの値は、正常に本体に反映されていて、テストでも正しい計算結果が出ています。
試しに、Viewに先ほど書き直して見たのですが、どうも・本体を全部を書き直さなくては
ならないような勢いのエラーが大量に出てしまうので、ビギナーの自分は2の足を踏んでいます。
やはり・全部作り直さなくてはいけないのでしょうか...。
Bunです。
>これは、できませんでした。「'm'定義されていない識別子です」というのがエラーです。
>グローバル変数なのに、呼び出せない事がそもそもなにか、変なのですが。
>(グローバルフォルダに変数が入っているので良いと思うんですけど。)
(以前のグローバル変数mの宣言はとりあえず //でコメントにしてください)
どこのファイルでどのように宣言されていましたか?
MainFrm.hの先頭に次のように m をグローバル宣言します。
double m; // <--- ここに宣言
class CMainFrame : public CFrameWnd // <--- ここはもともとある
TTView.hの先頭に次のようにexternで m を宣言します。
extern double m; // <--- ここに宣言 これがないのでエラーが出ると思います
class CTTView : public CFormView // <--- ここはもともとある
このようにすれば上記のエラーはなくなるはずです。
そして
CTTView::OnDraw()内の
m1.Format(%f,cps1.m_p1.m_p1e1); を
m1.Format(%f, m); としてTextOut()可能かどうか調べてください。
追記ですが、
doubleではなく、CStringでFormView⇔PSheet1の値を
出し入れをしていた時には、問題なくできていました。
FormViewへの表示も、ファイル保存も、呼び出しも。
ただ、この時には、肝心の本体へのCString→doubleの値渡しがうまくいきませんでした。
本体が走らず、なんとか走っても、計算結果が違っていました。
もしかすると、教えて頂いたFormat関数でCstringをdoubleにしたら、うまくいくかもしれません。
ちょっとやってみます。
Bun様 レスをありがとうございます。
ちょっとの時間差で、頂いたレスを確認せずに自分のを書いてしまいました。
で、先ほど・教えていただいたのを、やってみました。
結果は、下のようなエラーが出て、ビルド自体が通りません。
TT.obj : error LNK2005: double m (?m@@3NA) はすでに MainFrm.obj で定義されています
TTView.obj : error LNK2005: double m (?m@@3NA) はすでに MainFrm.obj で定義されています
TT.exe : fatal error LNK1169: 1 つ以上の複数回定義されているシンボルが見つかりました
「やり方がマズかったのだろうか。」と思って、何度もBunさんのレスを読み返して、
やり直してみたのですが、同じ。
このエラー、ダブルクリックしてもエラー先にジャンプしないし、m の検索かけると、
プロパティシートの中にしか、この変数をダイレクトに使っている処は無いので、
ここは変更できないし。むむむむ..。
「あと一歩」を踏み出して落とし穴に落ちた気分。
Bunです。
余談ですが
CPSheetとはプロパティシートの派生クラスですか?
本題です。
これはやってもらえましたか?
↓↓↓
(以前のグローバル変数mの宣言はとりあえず //でコメントにしてください)
どこのファイルでどのように宣言されていましたか?
エラーを回避するために、とりあえず mはやめてmmで宣言してみましょう。
MainFrm.hの先頭に次のように mm をグローバル宣言します。
double mm; // <--- ここに宣言
class CMainFrame : public CFrameWnd // <--- ここはもともとある
TTView.hの先頭に次のようにexternで mm を宣言します。
extern double mm; // <--- ここに宣言
class CTTView : public CFormView // <--- ここはもともとある
void CMainFame::OnParam()
{
CPSheet cps1(プロパティシート);
cps1.m_p1.m_p1e1=m;/*プロパティシート内の1ページ目、1つ目のエディットボックスという意味です。
m_p1e1は、m_p1の中にあります。*/
if(cps1.DoModal()==IDOK)
{
mm=cps1.m_p1.m_p1e1; // <--- mをmmに変更
InvalidateRect(NULL);
}
}
このようにすれば上記のエラーはなくなるはずです。
そして
CTTView::OnDraw()内の
m1.Format(%f,cps1.m_p1.m_p1e1); を
m1.Format(%f, mm); // <--- mをmmに変更
としてTextOut()可能かどうか調べてください。
Bun様 レスありがとうございます。
結果は、mの時とまったく同じエラーが表示されました。
>エラーを回避するために、とりあえず mはやめてmmで宣言してみましょう。
やってみました。MainFrm.hの先頭のコメントアウト部分のすぐ下に記述しました。
(以前は、MainFrm.cppの#include、#defineのすぐ下に書いてました。)
>TTView.hの先頭に次のようにexternで mm を宣言します。
>extern double mm; // <--- ここに宣言
しました。TTView.hの先頭のコメントアウト部分のすぐ下に記述しました。
※今回変更したのは、言われたこの2つの手順と、m1.Format(%f,mm)部分のみです。
>CPSheetとはプロパティシートの派生クラスですか?
基本クラスCPropertySheetの派生で、コード記述のみで存在します。
>これはやってもらえましたか?
> ↓↓↓
>(以前のグローバル変数mの宣言はとりあえず //でコメントにしてください)
>どこのファイルでどのように宣言されていましたか?
もちろん、しています。
(これも、今まではMainFrm.cppの#include、#defineのすぐ下に書いてました。)
あの、これって・もしmmがうまくいっても、プロパティシートの値をViewに出し入れできない気がするんですけど..。
どちらにしても、プロパティシートの中に、
void CMainFame::OnParam()
{
CPSheet cps1(プロパティシート);
cps1.m_p1.m_p1e1=mm; //この記述と
if(cps1.DoModal()==IDOK)
{
mm=cps1.m_p1.m_p1e1; //この記述はどうしても必要ですので、#defineの値だけが表示できてもあまり意味が..。
InvalidateRect(NULL);
}
}
せっかく答えていただいたのですが、きっと、私のプログラムの作りが悪いのでしょう。
うまくいかなくて、返って申し訳ありませんでした。