いつもお世話になっております。
オートメ‐ションを使って別のアプリケーションの関数で描画する処理をしたいと思っています
が、呼び出し元で作成したHDCに呼び出し側で描いてくれません。
下記プログラムで実行したところ、HDCの値(①と②)は同じなので、パラメータの受け渡しに
は問題ないようなのですが、アプリ間を通してのハンドル(HDC)には描画できないものなのでし
ょうか?
よろしくお願いします。(VC++6.0)
//オートメーション出入り口クラス
class CMyAutomation
{
protected:
COleDispatchDriver m_Doc;
public:
BOOL Open()
{
return m_Doc.CreateDispatch( _T(xxxxxx) );
}
BOOL MyDraw( HDC hdc )
{
BOOL rtv;
m_Doc.InvokeHelper( 0x01, DISPATCH_METHOD, VT_BOOL, &rtv,
(BYTE*)VTS_I4, (long)(hdc), );
return rtv;
}
};
//呼び出し側のダイアログ
void CTestDlg::DrawStart()
{
CMyAutomation *pRemote = NULL;
pRemote = new CMyDrawApp;
pRemote->Open();
CClientDC dc(this);
HDC hdc = memdc.GetSafeHdc(); //①
pRemote->MyDraw( hdc ); //描画
if ( pRemote ) pRemote->Close();
}
//呼び出された側の関数
BOOL CMyDrawDoc::MyDraw( long paramHDC )
{
HDC hdc = (HDC)paramHDC; //②
::SetBkMode(hdc,OPAQUE);
::SetTextColor(hdc, RGB(255,0,0));
::SetBkColor(hdc, 0);
::TextOut( hdc, 0,0,abcde, 5 );
return TRUE;
}
※エラー処理と説明に直接関係のなさそうなところは省略しています。
>呼び出し元で作成したHDCに呼び出し側で描いてくれません。
描けていないことはどうやって確かめたのですか?
それから CMyDrawDoc::MyDraw() 側で個々のAPI の呼び出しに成功していることは
確かめましたか?
しまさん、ありがとうございます。
>描けていないことはどうやって確かめたのですか?
呼び出し側がダイアログなので、テストとしてそのダイアログDCの描画させています。
>それから CMyDrawDoc::MyDraw() 側で個々のAPI の呼び出しに成功していることは
確かめましたか?
してなかったです。確認したところ
::TextOut( hdc, 0,0,abcde, 5 );
の戻り値FALSEになっていました。
GDIオブジェクトはプロセスローカルなので、別プロセス
からはアクセスできません。
描画データをDIBやメタファイルなどに出力してやりとりする
必要があると思います。
>>描けていないことはどうやって確かめたのですか?
>呼び出し側がダイアログなので、テストとしてそのダイアログDCの描画させています。
その説明では(あなたがしたかったこと以外には)何も分かりません
例えば
> CClientDC dc(this);
>
> HDC hdc = memdc.GetSafeHdc(); //①
>
> pRemote->MyDraw( hdc ); //描画
というコードですが、 memdc にはどんなビットマップが選択中なんでしょうか?
そして、呼び出し側のダイアログの DC に描画とは何をどう描画したのでしょうか?
そもそもハンドルは基本的にDuplicateHandleでそれぞれのプロセス用に複製し
て使うものじゃないのでしょうか。
とはいえ、なんだかHGLOBALやHWNDなどで複製しないで使ってるケースも良く
あるのでどういったハンドルに有効なのかも良く分かりません。
なので、GDIオブジェクトが複製できるかは分かりません。
まぁ参考までに。
>描画データをDIBやメタファイルなどに出力してやりとりする
場合によってはGlobalAllocで共有メモリを使うという手もあると思います。
ファイルより多少高速化が期待できるかと思います。
> GDIオブジェクトはプロセスローカルなので、別プロセス
> からはアクセスできません。
Yes。
> GDIオブジェクトが複製できるかは分かりません。
できません。
ウィンドウハンドルもグローバルハンドルもできません。
できるのはカーネルオブジェクトハンドルだけです。
ありがとうございます。
ハンドルを使うことはできないということで理解しました。
ファイルや共有メモリなどを使用するような別の方法でプログラミングします。
大変お勉強になりました。ありがとうございました!