アプリ版:「スタンプのみでお礼する」機能のリリースについて

voidポインタをハンドルへ


今、Form1でlogBoxというTextBoxを作成し、Form1.h以外ののソースからでも、エラーが出た場合そこにLogが吐き出されるようにしようとしています。

//clrres.h
void *LOGBOX;
void OutText(TextBox^ b,String^ s);
extern inline void OUTPUTLOG(String ^s);

//clrres.cpp
#include "stdafx.h"
#include"clrres.h"
void OutText(TextBox^ b,String^ s){
  b->AppendText(s+L"\r\n");
  b->SelectionStart = b->Text->Length;
  b->ScrollToCaret();
}

inline void OUTPUTLOG(String ^s){
  OutText((TextBox^)LOGBOX,s);
}

//Form1.hのForm1コンストラクタ内
System::IntPtr ptr=logBox->Handle;
LOGBOX=ptr.ToPointer();

とすれば、簡単に、Logを書き出せるようになるかと考えたのですが、
error C2440: '型キャスト' : 'void *' から'System::Windows::Forms::TextBox ^' に変換できません。
と出てきます。
どの様にすれば、出来るようになるでしょうか?
宜しくお願いします。

A 回答 (3件)

すいません、変換部分は大嘘ぶっこきました。



Control.FromHandleにIntPtrを渡します。

OutText((TextBox^)Control.FromHandle(IntPtr(LOGBOX)),s);

ただし、いずれにせよ例外は発生するはずですので、#1でも言ったようにデリゲートを使うか前回も言ったように例外発生しないように設定を変えるかしてください。
ログを書き込む部分をForm1のパブリックメンバ関数にしてそこからデリゲートを使うようにすれば記述もそう面倒ではないはずです。
    • good
    • 0
この回答へのお礼

たびたび、どうも有り難うございます。
実は、CUIのC++で使っていたヘッダファイルを.NetでGUIを作った場合でも、OUTPUTLOG周りをちょっと書き換えればどっちでも直ぐに使えるヘッダファイルとしてclrres.hを作りたいなと考えているんです。
そこで、Form1に書き込む部分をForm1の中にstatic関数として作成しました。
ただ、これを呼び出そうとすると、clrres.hにForm1.hをインクルードしなければいけません。しかし、Form1.hで使用する関数をclrres.hとclrres.cppで作成していたので、当然Form1.hにもclrres.hがincludeされています。
そのため、どちらかのファイルからもう片方が読み込まれると、読み込まれたファイルもそのファイル自身を読み込んだファイルを読み込もうとします。
しかし、#pragma onceが入っているので、もう片方のファイルに定義されている定義が読み込めずcompileエラーが出ます。

これは、clrres.hに
hogehoge{
  class Form1;
  void Form1::kakidasi(String^ s);
}
みたいにクラスを前に定義しておくのと同じ感じで書いておけばいけるかなと考えたのですが、このような関数の書き方はだめ、みたいな感じでコンパイラに怒られます。

どの様にすればうまくいくのでしょうか?

お礼日時:2009/06/09 12:14

そこまで行くともはや別の質問って感じですが……


VC++のデザイナ頼りだとついついヘッダに全部書いてしまいますが、C++/CLIも基本はC++ですからヘッダとコードは分離可能です。

シンボル参照の循環が問題ならそれで解消できるかと思いますが、どうですか?
    • good
    • 0
この回答へのお礼

確かにこの方法でうまく書き込めるようになりました
特にコンソールアプリしか作らなかったころは、voidポインタなんて何に使うのかよく分からなかったですが、色んなライブラリを組み合わせてデータの受け渡しするときには物凄く便利ですね

どうも有り難うございました。

お礼日時:2009/06/10 04:33

http://okwave.jp/qa5015628.html
の続きということなのでしょうが、あの例外は「コントロールのオーナー以外がコントロールを操作しようとしている」って事なので、たとえ変換が出来ても結局は同じ例外が発生するだけのはずです。
素直にデリゲートを使ってください。

なお、void *→IntPtrへはIntPtrのコンストラクタを経由して変換可能なので、
OutText((TextBox^)IntPtr(LOGBOX),s);
とすれば文法上の問題はなくなるのではないかと。
    • good
    • 0

お探しのQ&Aが見つからない時は、教えて!gooで質問しましょう!