ActiveXの戻り値 – プログラミング – Home

通知
すべてクリア

[解決済] ActiveXの戻り値


タフガイ
 タフガイ
(@タフガイ)
ゲスト
結合: 19年前
投稿: 30
Topic starter  

VC6.0を使用してActiveXを作成しています。

ActiveXの中のCBitmapオブジェクトを呼び出し元アプリにコピーするという事を行わなけ
ればなりません。

クラスウィザードのオートメーションのメソッドの追加から関数を作っているのですが、
戻り値のタイプの中にCBitmapがない為にどのようにしたら良いのか分かりません。

よろしくお願いします。


引用未解決
トピックタグ
Kerry
 Kerry
(@Kerry)
ゲスト
結合: 20年前
投稿: 192
 

LPPICTUREDISP型を指定してIPictureDispインターフェイスを返せば良いでしょう。

CPictureHolderクラスを使えば比較的楽に実装できると思います。


返信引用
タフガイ
 タフガイ
(@タフガイ)
ゲスト
結合: 19年前
投稿: 30
Topic starter  

早速のアドバイスありがとうございます。

LPPICTUREDISP・IPictureDisp・CPictureHolder
初めて見る言葉ばかりですので、調べてみました。
知識が無いので中々理解できません。

おっしゃっている方法ではLPPICTUREDISPを返す事になるのでしょうか?
呼び出し元のアプリは私が作るのではないのでCBitmap(ポインタでも不可)を返すとい
うのは変更できなのですが
その方法でCBitmapを返すことは可能なのでしょうか?


返信引用
タフガイ
 タフガイ
(@タフガイ)
ゲスト
結合: 19年前
投稿: 30
Topic starter  

色々と調べたのですが、よく分かりませんでした。

とりあえずオートメーションで以下のようなメソッドを作り

LPPICTUREDISP xxx(){
CPictureHolder pictureHolder;

pictureHolder.CreateFromBitmap(tmpBmp); // tmpBmpがリターンしたいCBitmapです

return pictureHolder.GetPictureDispatch();
}

という関数を作り、呼び出し元で

void CTest999Dlg::OnButton1()
{
CBitmap bitmap;

bitmap = m_qr.GetBitmap();
}

としたのですが、エラー('operator '^=' 関数は '<Unknown>' 内では使用できませ
ん。)が出て使えませんでした。

LPPICUTUREDISPという型が何なのか良く分からないのですが、呼び出し元から
GetBitmap()を呼ぶと戻り値はCPictureと表示されていました。

何をどうしたら良いのか分からないのですが、ご教示願えないでしょうか。


返信引用
タフガイ
 タフガイ
(@タフガイ)
ゲスト
結合: 19年前
投稿: 30
Topic starter  

呼び出し元関数をそのまま載せてしまっていました。
これでは分かりませんね。書き直します。

void CTestDlg::OnButton1()
{
CBitmap bitmap;

bitmap = ActiveX.xxx(); // ActiveXのオートメーションで作ったxxxメソッド
}

とても困っていて些細な情報でもいいので、よろしくお願いします。


返信引用
Kerry
 Kerry
(@Kerry)
ゲスト
結合: 20年前
投稿: 192
 

CPictureクラスというのは、タイプライブラリから生成されたクラスですよね?

返されたCPictureクラス(COleDispatchDriver)からIPictureインターフェイスを
取得し、IPicture::Renderメソッドを使ってDCにレンダリングします。
下の例ではクライアントDCに直接描画していますが、メモリDCにレンダリング
すればビットマップとして取り出すことも可能です。

#include <afxole.h>

DEFINE_IPTR(IPicture)

void CTest999Dlg::OnButton1()
{
IPicturePtr pict = ActiveX.xxx();

OLE_XSIZE_HIMETRIC hmW;
OLE_YSIZE_HIMETRIC hmH;
pict->get_Width(&hmW);
pict->get_Height(&hmH);

CClientDC dc(this);

CSize size(hmW, hmH);
dc.HIMETRICtoDP(&size);

CRect rect;
GetClientRect(&rect);

pict->Render(dc, 0, 0, size.cx, size.cy, 0, hmH, hmW, -hmH, &rect);
}


返信引用
タフガイ
 タフガイ
(@タフガイ)
ゲスト
結合: 19年前
投稿: 30
Topic starter  

Kerryさん、お返事ありがとうございます。

なるほど、そういう風にして受け取るのですね。
CPictureがMFCの階層図やヘルプにも載っていなかったので全く何のことか分かりません
でした。
IPicturePtrというので受け取れば良いのですね。

後の流れは大体理解できました。

ただ、仕様とは異なってしまうので、今回は使えないのが残念ですが。
受け取り元アプリはC#ですので、何か違う方法があるのかも知れないのでC#掲示板で
も聞いてみます。

今回は誠にありがとうございました。


返信引用
Kerry
 Kerry
(@Kerry)
ゲスト
結合: 20年前
投稿: 192
 

C#でActiveXコントロールインポータを使えば、LPPICTUREDISP型のメソッドは、
System.Drawing.Image型としてインポートされます。

よって、C#では以下のように使えると思います。

Bitmap bmp = new Bitmap(ActiveX.xxx());


返信引用
タフガイ
 タフガイ
(@タフガイ)
ゲスト
結合: 19年前
投稿: 30
Topic starter  

Kerryさん、勝手に解決してしまったのにありがとうございます。

早速おっしゃる方法でやってみました。
ビルドは通ったので早速動かしたんですが、エラーが出て止まってしまいました。

'System.Runtime.InteropServices.ExternalException' のハンドルされていない例外が
System.Drawing.dll で発生しました。

追加情報: GDI+ で汎用エラーが発生しました。

というエラーダイアログが表示されました。

VC側は以前と同じままです。

LPPICTUREDISP xxx(){
CPictureHolder pictureHolder;

pictureHolder.CreateFromBitmap(tmpBmp); // tmpBmpがリターンしたいCBitmapです

return pictureHolder.GetPictureDispatch();
}

C#のアプリ側、VCのActiveX側のどちらが悪いのでしょうか?


返信引用
Kerry
 Kerry
(@Kerry)
ゲスト
結合: 20年前
投稿: 192
 

ActiveX側のコードは見たところ問題なさそうですが…

tmpBmpはメンバ変数ですか?ローカル変数であれば、関数を抜ける
ときにデストラクタで破棄されてしまうので問題が起こるでしょう。


返信引用
タフガイ
 タフガイ
(@タフガイ)
ゲスト
結合: 19年前
投稿: 30
Topic starter  

ありがとうございます。

問題なさそうですか。。。

tmpBmpはPublicなメンバ変数です。
Privateでしたが、念のためPublicに移動しました。

更に念の為に
CPictureHolder pictureHolder
もメンバ変数にしてみましたが、同じエラーメッセージが出ます。

もう少しだと思うのですが、エラーの意味が分からず。。。


返信引用
Kerry
 Kerry
(@Kerry)
ゲスト
結合: 20年前
投稿: 192
 

ローカル変数の場合でも以下のようにすればokなのですが…

LPPICTUREDISP ActiveX::xxx()
{
CBitmap tmpBmp;
tmpBmp.LoadBitmap(IDB_BITMAP1);

CPictureHolder pict;
pict.CreateFromBitmap(&tmpBmp, NULL, TRUE); // ピクチャオブジェクトが
// ビットマップの所有権を持つ

return pict.GetPictureDispatch();
}

私の環境では上のようなコードで問題なく動いてますが。
ビットマップの作成方法が問題なのかなぁ…


返信引用
タフガイ
 タフガイ
(@タフガイ)
ゲスト
結合: 19年前
投稿: 30
Topic starter  

Kerryさん、重ね重ねありがとうございます。

Kerryさんの例のように、リソースのビットマップを返してみるとC#側アプリで受け取る
ことができました。
しかし、私の返したいCBitmapを返すとエラーメッセージが表示されます。

CBitmapに何か問題があるのかと思い、CDCから取る方法に変えました。
表示に使っているCDCからGetCurrentBitmap()を使いそれを返すようにもしたのですが、
同じエラーメッセージでした。

また、
CDC *pDC
pDC = this->GetDC();
tmpBmp = GetCurrentBitmap();

とするとエラーは起こらなかったのですが
画面全体のハードコピーが取れてしまいました。
プリントスクリーンと同じようにWindows全体(タスクバー等も含む)が取れました。

アクティブXで表示されている部分だけが取りたいのですが・・・

ちょっと話が脱線してきてしまいました。別スレ立てた方が良いかも知れませんね。
ここまでこれただけでも非常に感謝しております。恐らく私一人ではいつまでかかってい
たか。。。
本当にありがとうございます。


返信引用

返信する

投稿者名

投稿者メールアドレス

タイトル *

プレビュー 0リビジョン 保存しました
共有:
タイトルとURLをコピーしました