先週からVCをはじめた初心者です。
開発環境は WinXP SP1 VC++6.0になります。
まずメインのダイアログがあり、そこにエディットボックスなどで数値を入力し加工す
るプログラムを作っています。
入力の種類により個別の項目を設けていたのですが、スペースの関係上タブに分けるこ
とにしました。
メインのダイアログ上の処理をタブの各ページのダイアログに丸々写し、動作させよう
と修正を施します。
結果数値の入力などは上手くいくのですが、数値を加工する処理の部分の実行時に下記
エラーが発生するようになりました。
<エラー部分>
File:winocc.cpp
Line:345
処理としては同じもののはずなのに、何が原因なのか検討もつきません。
理由として考えられるものがありましたら、ご教授頂きたく存じます。
また、メインダイアログ上での処理は上手くいくので、各タブページから数値の加工す
る処理部分のみメインを呼び出す良い方法などありましたら教えてください。
質問の仕方やアプローチに問題があるかもしれませんが、助けていただけると幸いです
せっかく
><エラー部分>
>File:winocc.cpp
>Line:345
という手がかりがあるのに、なんで調べないのでしょうか?
> File:winocc.cpp
> Line:345
その情報では判らないんじゃないの。
ここを読んでいる人が、あなたと同じアプローチをしたり、
あなたと同じバージョンのVCを使っているわけじゃないんだし。
> アプローチに問題があるかもしれませんが、
あなたのアプローチを知らないので問題があるかどうかわからない。
どういうことがしたくて、どういうことをしたら、
どういうエラーになったのかわからないけれど、
俺だったらこうするって方法を示しますね。
各タブのオブジェクト(クラス)に共通オブジェクト(メインダイアログ)への
ポインタを持たせる。
各タブのオブジェクトを作成時にそのポインタを設定するのを忘れずに。
>という手がかりがあるのに、なんで調べないのでしょうか?
すみません。
該当するソース部分から具体的な問題点が判断できず、頓挫してしまいました。
ただ、出ている現象の唯一のエラーメッセージだったため、載せることにした次第で
す。
>あなたのアプローチを知らないので問題があるかどうかわからない。
そうですね。
現在行っているアプローチとしては、メインのダイアログにあったソースをそのままタ
ブのページダイアログにコピーするという方法でした。
移したいオブジェクトに関するソースは、検索などかけて抜けがないようタブページに
移植しているのですが。
一方で元のメインダイアログとのデータのやりとりができるか、また見落としなどがあ
ったりするのではないかという危惧がありました。
出ている現象も関数との引数のやりとり部分で引っかかってる節があるため、そのアプ
ローチ自体遠回りで非効率だったのではないかと。
本当なら中身の処理をメインダイアログに残して、タブページにはオブジェクトのイン
タフェース部分のみというのをやりたかったりしました。
例えばリソースビュー上でボタンをタブにカットアンドペーストで移動させ、実行時タ
ブに移動したボタンを押すことによりメインダイアログに残っている処理を実行するみ
たいに。
ただ、実際どう関連付けるかわからず、仕方なくボタンを押した際の処理ごとタブペー
ジに移動させています。
現状の方法での問題点を解決したいのもありますが、一方でもっと良い手法があれば教
えて頂きたいという希望がありました。
結果として趣旨のよくわからない質問になってしまったのだと反省しきりです。
>各タブのオブジェクト(クラス)に共通オブジェクト(メインダイアログ)へのポイン
タを持たせる。
申し訳ないのですが、その場合どうポインタを持たせるかまで教えて頂けないでしょう
か?
タブオブジェクトのヘッダに何らかの宣言をするという趣旨でしょうか?
>その情報では判らないんじゃないの。
ってのはあなたの書き込みを読んで他人が再現できるように書いてねって話
http://www.hyuki.com/writing/techask.html
ここを読むといいかもしれない
関連するソースの分量が多そうだし、ソースから原因探すよりデバッガで見つけた
ほうが早いと思う。
やり方は主に2パターン。
・VCからデバッグを開始(F5)して、エラーが出た時点でブレークさせる。
・エラーダイアログからデバッガにアタッチさせる。
で、問題の発生したスレッドのコールスタック等を足がかりに調べれば何処で何を
したのが原因かわかるはず。
アタッチは、エラーのダイアログの中のどれかを選択すれば出来たと思いますが。
ライブラリの中でエラーが出ているようですので、大方NULLじゃ駄目な変数が
NULLだったりとかだと思います。
色々レスありがとうございます。
>ってのはあなたの書き込みを読んで他人が再現できるように書いてねって話
ご指摘の通り、再現させるための情報を入れてませんでした。
現在スレを立てた状態から色々検討して“親ダイアログ中の実行したい関数を、タブの
子ダイアログから
public宣言した関数を介して実行する方向”で模索しています。
以下関連する部分のソースをピックアップしてみます。
<メインダイアログ.h>
public:
void Open_Function( short Size, BYTE* Data );
protected:
void Test_Function( short Size, BYTE* Data );
<メインダイアログ.cpp>
// 実行したい処理
void CDlg_Main::Test_Function( short Size, BYTE* Data )
{
***************
}
// 外部からの参照用処理
void CDlg_Main::Open_Function( short Size, BYTE* Data )
{
Test_Function( Size, Data );
}
<タブページ子ダイアログ.cpp>
CDlg_Main cTest;
void(CDlg_Main::*fp)(short Size, BYTE* Data);
fp = cTest.Open_Function;
(cTest.*fp)(size_data, data);
上記のような状態でコンパイルは通ったのですが、子ダイアログの処理を実行しようと
すると
Debug Assertion Failed!のメッセージと共にwinocc.oppの345行目を指摘されてしまい
ます。
またメインダイアログ中で値をとり、Test_Functionを実行すると問題なく動くような状
況です。
十分な情報かどうかわかりませんが、こんな感じです。
やり方は主に2パターン。
・VCからデバッグを開始(F5)して、エラーが出た時点でブレークさせる。
・エラーダイアログからデバッガにアタッチさせる。
で、問題の発生したスレッドのコールスタック等を足がかりに調べれば何処で何を
したのが原因かわかるはず。
アタッチは、エラーのダイアログの中のどれかを選択すれば出来たと思いますが。
ライブラリの中でエラーが出ているようですので、大方NULLじゃ駄目な変数が
NULLだったりとかだと思います。
デバッグライブラリウインドウでエラーを指摘されている状態で処理をブレークしまし
た。
ソースコードが表示されている部分にアセンブラコードが出るようになったのですが、
次のアタッチが
よくわかりませんでした。
デバッグライブラリウインドウの操作をしようとしても、その状態だとデバッグモード
で実行中の
ダイアログがハングアップしているのでやりかたが不味かったのかもしれません。
もうすこし方法を検討してみます。
初めて書き込ませて頂きます。
>開発環境は WinXP SP1 VC++6.0になります。
SDKですか?それともMFC使ってますか?
>public宣言した関数を介して実行する方向”で模索しています。
最初からTest_Functionをpublicにすればいいのでは?
>CDlg_Main cTest;
>void(CDlg_Main::*fp)(short Size, BYTE* Data);
>fp = cTest.Open_Function;
>(cTest.*fp)(size_data, data);
子ダイアログ上で
cTestという親ダイアログと同じクラスのインスタンスを作っているだけであって、
親ダイアログそのものじゃないですよね?
ならば、そのメンバ関数のポインタを取得したところで意味ないのでは?
staticなメンバ関数なら大丈夫かも知れないけど。
#ちなみに私も初心者なので間違っていたらごめんなさい。
rikizoさん、指摘ありがとうございます。
>SDKですか?それともMFC使ってますか?
MFCです。
>cTestという親ダイアログと同じクラスのインスタンスを作っているだけであって、親
ダイアログそのものじゃないですよね?
そうだったのですか。
この書き方でメインダイアログを呼んでいるとばかり思ってました。
逆に、メインダイアログのメンバのポインタを取得するにはどういった書き方をすれば
よいのでしょうか?
>逆に、メインダイアログのメンバのポインタを取得するにはどういった書き方をすれば
よいのでしょうか?
GetParent()を使うとか。
そもそも
>CDlg_Main cTest;
>void(CDlg_Main::*fp)(short Size, BYTE* Data);
>fp = cTest.Open_Function;
>(cTest.*fp)(size_data, data);
これが何をやっているのかご自分で理解されているでしょうか。
ものすごーく意味のない事をしています。
VCを初めて一週間とのことですが、C++の知識はどの程度ありますか?
C++やクラスの概念を理解していない状態で
MFCを使うのは難しいんじゃないかと思います。
自分がそうなので(^^;
VC 6.0
> File:winocc.cpp
> Line:345
>void AFX_CDECL CWnd::InvokeHelper(DISPID dwDispID, WORD wFlags, VARTYPE vtRet,
> void* pvRet, const BYTE* pbParamInfo, ...)
>{
> ASSERT(m_pCtrlSite != NULL); ← ココ 345行 // not an OLE control
(not yet, at least)
> if (m_pCtrlSite == NULL)
> return;
> va_list argList;
> va_start(argList, pbParamInfo);
> m_pCtrlSite->InvokeHelperV(dwDispID, wFlags, vtRet, pvRet,
>pbParamInfo,
> argList);
> va_end(argList);
>}
>// not an OLE control (not yet, at least)
Active X Controlを使っていないですか?
うまく動作していないんじゃない?
修正
> Active X Controlを使っていないですか?
> うまく動作していないんじゃない?
正解
Active X Controlを使っていますか?
うまく動作していないんじゃない?
MFCのソースはこの場所にあります。
VC6.0の場合。
C:\Program Files\Microsoft Visual Studio\VC98\MFC\SRC
winocc.cppもあったよ。
> Active X Controlを使っていますか?
Active X Controlが使われているかの確認方法がわからないのですが、改造する前は同
じ処理で動いていたため、私の方法が間違っているのだと思います。
>これが何をやっているのかご自分で理解されているでしょうか。
>ものすごーく意味のない事をしています。
実はあまり理解できていません。
ネットにあるコードを見て、いろいろと試して確認するという作り方をしているためな
のですが。
>VCを初めて一週間とのことですが、C++の知識はどの程度ありますか?
どう程度を表せばいいかわからないのですが、何年か前に基本は勉強しました。
ただ、長らくCの環境ばかりを扱っていたため、かなり忘れています。
ですので、今は作りながら思い出すという状況にあります。
>MFCを使うのは難しいんじゃないかと思います。
私も同感です。
ただ、改造母体とするプログラムがMFCの環境で作られている関係上、別の選択肢が
取り辛かったりします。
本来なら基本から勉強して臨んだり、また別の方法を模索した方が建設的だとは思いま
すが。
時間と環境の制約があるなか、必要な部分の変更により求める成果物を作成する事を最
優先と考えていました。
しかしそれはこちらの我侭でしかなく、そういった手前勝手な事情につき合わせてしま
って申し訳なく思います。
こちらが質問をするレベルに達していないにも関わらず、結果場を荒らしてしまって本
当に申し訳ありません。
色々ご指導いただきありがとうございました。
そして、本当にすみませんでした。