doubleの値をCStringで受け取るには?

[戻る]
みかん箱 2001/04/14(土) 17:09:25
教えてください。
SDIのメニューから、ボタンクリックでプロパティシート
を呼び出し、エディットボックス(double型)から取得した
値をFormViewにTextOut表示させるというプログラムを作っています。
が、どうしても取得した値を、画面に表示させることができません。

変数に入れた値は、計算中にE-11等の単位を付加して計算させていますので、
Double型がベストだと思うのですが、同時に取得した値(指数部分より前だけ)
をViewで確認&テキスト形式で保存しなくてはいけません。

プログラム本体は何の問題なく出来上がって走っているのですが、
この部分でハマっています。

もし、こうしたら?っていうのがあれば教えてください。
ちなみに、エディットボックスをCString型にしたら、プログラム本体が
走らなくなってしまいました。
誰かたすけて〜!

スーパーマリ子 2001/04/16(月) 10:42:47
みかん箱さん、こんにちわ。

なにぶん私も初心者なので、質問をはきちがえているかも
知れませんが、勇気を出して、回答します。

エディットボックスの値を一回CString型に変換したら
だめなんでしょうか?

私は、ダイアログベースでしか作ったことないので、
ぜんぜん自信がないんですが、

  UpdateData(TRUE);
  CString SSS;
  SSS.Format("%f",エディットボックスの値); 
  UpdateData(FALSE);

これで、CString型のSSSに、
エディットボックスの値が入ると思うんですけれど・・・。

それとも、”エディットボックスの値”のような変数に、
エディットボックスの値を格納することはできないんでしょうか?
(その場合、ちょっとわたしにはわからんないです、すみません)

みかん箱 2001/04/18(水) 12:41:38
スーパーマリ子様 みかん箱です。
レスありがとうございます。ちょっとだけ光が見えてきました。

方向的には、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の中に値は入っていると思うのですが..。

あと一歩!あと一歩な気がするぅ〜!

スーパーマリ子 2001/04/18(水) 13:25:08
こんにちは、スーパーマリ子です。
適当に考えた名前だったけど、改めて書くと
すごい恥ずかしいです。後悔。 (凸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 2001/04/18(水) 13:33:00
Bunです。

MFC,SDIで作成しているのでしょうか?

m1.Format("%f",m);
はどのクラスのどの関数内に記述されていますか?

pDC->TextOut(200,250,m1);
はどのクラスのどの関数内に記述されていますか?

m1 = "0.091" であればTextOut(200,250,m1)は0.091を表示します。

あと一歩です。がんばってください。

みかん箱 2001/04/19(木) 09:24:48
スーパーマリ子様(マリヲより恥ずかしくないと思いますヨ。)ありがとうございます。
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 2001/04/19(木) 09:52:04
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 2001/04/19(木) 10:05:34
Bunです。追記です。

>全部Viewの中で書くとOKですが、

全部Viewに記述できない理由があるのでしょうか?

みかん箱 2001/04/19(木) 13:31:53
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 2001/04/19(木) 14:53:24
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()可能かどうか調べてください。

みかん箱(追記) 2001/04/19(木) 14:55:22
追記ですが、
doubleではなく、CStringでFormView⇔PSheet1の値を
出し入れをしていた時には、問題なくできていました。
FormViewへの表示も、ファイル保存も、呼び出しも。
ただ、この時には、肝心の本体へのCString→doubleの値渡しがうまくいきませんでした。
本体が走らず、なんとか走っても、計算結果が違っていました。

もしかすると、教えて頂いたFormat関数でCstringをdoubleにしたら、うまくいくかもしれません。
ちょっとやってみます。

みかん箱 2001/04/19(木) 18:31:33
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 2001/04/19(木) 18:43:55
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()可能かどうか調べてください。

みかん箱 2001/04/19(木) 21:01:05
[[解決]]
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);
 }
}

せっかく答えていただいたのですが、きっと、私のプログラムの作りが悪いのでしょう。
うまくいかなくて、返って申し訳ありませんでした。

古いスレッドには追加発言できません。