CorelDRAWでマクロを利用するためのドキュメント「Controlling CorelDRAW or Corel DESIGNER Applications From Other Processes」の和訳です。
CorelDRAWでマクロを利用するためのドキュメント「Controlling CorelDRAW or Corel DESIGNER Applications From Other Processes」の和訳です。
CorelDRAW Graphics Suite(CDGS)X7とCorelDRAW Technical Suite(CDTS)X7アプリケーションは、カスタム・サードパーティ・プラグインとマクロでそれらの機能を拡張するためのたくさんの方法を提供します。
VBAマクロ、VSTAプラグイン、C ++プラグインに基づいたソリューションのすべては、CorelDRAW、Corel PHOTO-PAINT、Corel DESIGNERのような、ホスト・アプリケーションの環境で実行されます。しかしながら、場合によっては、他のスタンドアロン・アプリケーションからCDGS/CDTSアプリケーションに通信する必要があります。このチュートリアルでは、ネイティブC ++アプリケーション、またはC#またはVisual Basicで記述されたマネージ.NETプログラムの可能性がある、外部プロセスからCDGS / CDTSアプリケーションに接続する方法を探ります。
CDGS / CDTSアプリケーションと通信する正確な方法は、サードパーティ・アプリケーションの作成に使用されるソフトウェア・フレームワークとプログラミング言語によって異なります。以下のすべての例は、CorelDRAW X7に接続し、12 ptのArialフォントで単純な芸術的なテキスト・オブジェクト"Hello, world"を作成する、単純なコマンドライン(コンソール)アプリケーションを作成します。これらの例は、次のVBAマクロと同等です。:
Private Sub CreateTextInCorelDRAW(text As String , fontName As String , _
fontSize As Single )
ActiveLayer.CreateArtisticText 0, 0, text, Font:=fontName, Size:=fontSize
End Sub
Sub Main()
CreateTextInCorelDRAW "Hello, world!", "Arial", 24
End Sub
ネイティブC++
Native C++
低レベルのCOMを持つネイティブC++
Native C++ with low-level COM
より高いレベルのフレームワークが利用できない、または望ましくない場合、2つのアプリケーションの間で、最も低レベルのインターフェイスです。あなたは、ネイティブC++アプリケーションを書き込むことができます。そして、純粋なCOM APIを使用して、CDGS / CDTSアプリケーションのインスタンスに接続します。
開始するには、「ファイル」>「新規」>「プロジェクト」を選択し、「Visual C ++」>「Win32」プロジェクト・テンプレート・カテゴリから「Win32コンソールア・プリケーション」を選択して、Visual Studioで、簡単なC ++ Win32コンソールアプリケーションを作成します。
プロジェクト名を入力します。そして、場所を指定して、「OK」をクリックします。デフォルトの設定(あるいは、必要に応じてそれらを微調整します)で、プロジェクトを作成します。
一旦、ソリューションが作成される場合、開いたstdafx.hファイルします。そして、下部に、#include <windows.h>を追加して、このチュートリアルの後半で必要になる、WindowsプラットフォームAPI定義の一部を含めます。
アプリケーションが、CorelDRAWと通信するために、最初に必要とするのは、そのオブジェクトとインターフェイスの説明です。この情報は、CorelDRAWの型ライブラリによって提供されます。それは、システムにインストールされています。CDGS/CDTSが、インストールされるとき、Visual C ++には、アプリケーション型ライブラリ#importから型情報をインポートするための特別な命令が用意されています。
そのため、メインの.cppファイルの先頭に、次のコマンドを追加します。:
#import "libid:95E23C91-BC5A-49F3-8CD1-1FC515597048" version("11.5") \
raw_interfaces_only no_smart_pointers \
rename("GetCommandLine", "VGGetCommandLine") \
rename("CopyFile", "VGCopyFile") \
rename("FindWindow", "VGFindWindow")
ここでは、私たちは、CorelDRAWとCorel DESIGNERで、提供される型を説明するVGCore型ライブラリのID 95E23C91-BC5A-49F3-8CD1-1FC515597048で、型ライブラリをインポートします。あなたが、マシンで、インストールされているCDGSやCDTSの複数のバージョンを持っている場合、バージョン"11.5"は、重要になるインポートする型ライブラリのバージョンを指定します。実際のバージョン文字列は、アプリケーション・バージョンに対応していますが、16進形式です。16進数の11は、10進数の17に等しいため、バージョン"11.5"は、型ライブラリーバージョン17.5を参照します。
デフォルトでは、Visual Studioは、より簡単なCOMオブジェクトを使用して、作成するために、多数のヘルパークラスを生成しますが、この記事の目的は、低レベルのCOMインターフェイスを使用することであるため、私たちは、#importディレクティブに、"raw_interfaces_only"と"no_smart_pointers"オプションを追加します。最後に、GetCommandLineのような、CorelDRAW/Corel DESIGNERオブジェクト・モデルは、メソッドを持っています。マクロと競合するCopyFileとFindWindowは、Win32 APIによって、定義されるため、ここでは、私たちは、名前の競合をなくすために、それらの名前をVBGetCommandLineなどに変更します。
ソリューションをコンパイルするとき、VGCoreタイプライブラリのすべてのCOMインターフェイスが、インポートされ、通常のC ++ヘッダーファイルVGCoreAuto.tlhに変換されます。
現在、CorelDRAW / Corel DESIGNER型ライブラリから、すべての型情報がインポートされました。そして、あなたのC++プログラムが、利用できます。あなたのコンソール・アプリケーションのmain()関数を実装します。:
int wmain(int argc, wchar_t* argv[])
{
HRESULT hr = CoInitializeEx(nullptr, COINIT_APARTMENTTHREADED);
if (SUCCEEDED(hr))
{
hr = CreateTextInCorelDRAW(L"Hello, world", L"Arial", 24.0f);
if (FAILED(hr))
{
wprintf(L"Error occurred: 0x%08X\n", hr);
}
CoUninitialize();
}
return 0;
}
ネイティブ・アプリケーションがCorelDRAW/Corel DESIGNERでコミュニケーションのためにCOMを使用するので、Window COMサブシステムは、最初に初期化されなければなりません。CoInitializeEx() Windows API関数を使用して、続いて、最後に、CoUninitialize()で初期化されていない。
CreateTextInCorelDRAW()は、主機能です。それは、CorelDRAW X7につながります。CorelDRAWのメイン・アプリケーション・オブジェクトのインスタンスを作成することは、CoCreateInstance() Windows APIを利用します。この関数は、CLSIDFromProgID() APIを使用して、"CorelDRAW.Application.17" ProgIDから取得されることができるclass ID (CLSID)を必須です。
(直接、CLSIDを使用して、あるいは、ProgID文字列を変換することで、)実クラスIDを指定することは重要です
VGCoreタイプライブラリは、CDGS/CDTSのすべてのベクトル・グラフィックス・アプリケーションで共有されるため、(CorelDRAW、CorelDRAW Essentials、Corel DESIGNER)そして、それらは、同時に同じコンピュータに、インストールすることができます。そのため、あなたのアプリケーションは、例えば、CorelDRAWやCorel DESIGNERで、それが作業したいかどうか選択することができる必要があります。
この関数は、CorelDRAWのApplicationクラスのインスタンスを作成し、CorelDRAWとの通信に使用できる、IVGApplication COMインターフェイスを取得します。
HRESULT CreateTextInCorelDRAW(const wchar_t* text, const wchar_t* fontName,
float fontSize)
{
CLSID clsid;
HRESULT hr = CLSIDFromProgID(L"CorelDRAW.Application.17", &clsid);
if (FAILED(hr))
return hr;
VGCore::IVGApplication* app = nullptr;
hr = CoCreateInstance(clsid, nullptr, CLSCTX_LOCAL_SERVER,
__uuidof(VGCore::IVGApplication),
reinterpret_cast<void**>(&app));
if (FAILED(hr))
return hr;
hr = CreateText(app, text, fontName, fontSize);
app->Release();
return hr;
}
CorelDRAWが、すでに実行されている場合、CoCreateInstance()は、CorelDRAWの実行中のインスタンスに接続します。そうではない場合、関数が戻る前に、CorelDRAWが、自動的に起動されます。しかしながら、この場合、CorelDRAWは、非表示で開始し、デフォルトでは、UIは表示されません(それは、アプリケーションのメイン・ウィンドウをユーザーに表示せずに、背面で、いくつかのグラフィック処理を実行するために役に立ちます。)。
最後に、CreateText()ヘルパー関数は、作成されるappオブジェクトを使用して、CorelDRAWの文書の芸術的なテキスト・オブジェクトを作成します。
CreateText()が最初に行うことは、Application.VisibleプロパティをTrueに設定することです。CorelDRAWが、実行されていないとき、この事例では重要です。そして、CoCreateInstance()が、呼び出されるとき、Windowで自動的に始まります。この場合、CorelDRAWが非表示になるため、visibilityをTrueに設定すると、アプリケーションのメイン・ウィンドウが、画面に表示されます。
次に、CorelDRAWがちょうど今起動された場合、あるいは、ユーザーが、事前にすべての場合を閉じた場合、私たちは、存在しないかもしれない現在の文書を取得しようとします。Application.ActiveDocumentが、nullptrを返す場合、私たちは、Application.CreateDocument()メソッドを使用して、新しい文書を作成します。
最後に、私たちは、その文書のアクティブ・レイヤー上で、芸術的なテキスト・オブジェクトを作成します。
HRESULT CreateText(VGCore::IVGApplication* app, const wchar_t* text,
const wchar_t* fontName, float fontSize)
{
HRESULT hr = app->put_Visible(VARIANT_TRUE);
if (FAILED(hr))
return hr;
VGCore::IVGDocument* doc = nullptr;
hr = app->get_ActiveDocument(&doc);
if (FAILED(hr))
return hr;
if (doc == nullptr)
{
hr = app->CreateDocument(&doc);
if (FAILED(hr))
return hr;
}
VGCore::IVGLayer* active_layer = nullptr;
hr = doc->get_ActiveLayer(&active_layer);
if (SUCCEEDED(hr))
{
BSTR bstr_text = SysAllocString(text);
BSTR bstr_font = SysAllocString(fontName);
VGCore::IVGShape* shape = nullptr;
hr = active_layer->CreateArtisticText(
0.0, 0.0, bstr_text, VGCore::cdrTextLanguage::cdrLanguageMixed,
VGCore::cdrTextCharSet::cdrCharSetMixed, bstr_font, fontSize,
VGCore::cdrTriState::cdrUndefined, VGCore::cdrTriState::cdrUndefined,
VGCore::cdrFontLine::cdrMixedFontLine,
VGCore::cdrAlignment::cdrLeftAlignment, &shape);
SysFreeString(bstr_font);
SysFreeString(bstr_text);
if (SUCCEEDED(hr))
shape->Release();
}
active_layer->Release();
return hr;
}
ヘルパー・スマート・ポインタを備えたネイティブC ++
Native C++ with helper smart pointers
上記のアプローチは、外部依存関係が最も少ないですが、コードは、あまりに冗長です。すべてのメソッドと呼び出しは、呼び出しごとに検証する必要があるHRESULTを返します。また、返されたインターフェースは、参照カウントされます。そして、それらのIUnknown::Release()メソッドを呼び出すことによって、明示的に解放する必要があります。文字列は、BSTRに変換する必要があります。続いて、使用された後に解放されます。
幸運なことに、Visual Studioの#importディレクティブは、ヘルパークラス、そして、これらの面倒なタスクのほとんどを処理するメソッドを生成できます。また、_bstr_tや_variant_tなどのヘルパークラスを使用して、BSTRとVARINT型のメモリ管理とデータ変換を抽象化します。
最後に、生成されたヘルパークラスは、HRESULTsを使用して、失敗の明示的な確認の代わりに例外を使用します。これにより、プログラムの冗長性が大幅に低下し、作成と保守が容易になります。
開始するには、#importディレクティブのために、raw_interfaces_onlyとno_smart_pointersオプションを省略します。:
これにより、CorelDRAWのすべての型ライブラリ・インターフェイスとオブジェクトの定義を含むヘッダーファイル(VGCoreAuto.tlh)が生成されます。加えて、それは、スマート・ポインタのようなヘルパー・クラスを発生させます。たとえば、トップレベル・アプリケーション・オブジェクトの主なインターフェイスは、VGCore::IVGApplicationです。コンパイラは、自動的に、インスタンスの参照を追跡する、ヘルパー・クラスのVGCore::IVGApplicationPtrも発生させます。そして、基盤となるインターフェイスのデフォルトのメソッドは、生のインターフェイスのポインタの代わりに、スマートポインタを返します。生成された.tlhファイルには、インターフェイスとヘルパークラス、新しいファイル、VGCoreAuto.tliのすべての宣言がありますが、生成もします。そして、すべてのヘルパー・クラスとメソッドの実装が含まれています。このファイルは、自動的にコンパイルされます。そのため、あなたのソリューションのどこかに、言及する必要はありません。
発生させられたヘルパー・クラスを使用するとき、main()関数の本体は、あまり変更されません。CreateTextInCorelDRAW()の戻り値を確認する代わりに、それは、現在、例外処理を使用します。:
int wmain(int argc, wchar_t* argv[])
{
HRESULT hr = CoInitializeEx(nullptr, COINIT_APARTMENTTHREADED);
if (SUCCEEDED(hr))
{
try
{
CreateTextInCorelDRAW(L"Hello, world", L"Arial", 24.0f);
}
catch (_com_error& ex)
{
wprintf(L"Error occurred: 0x%08X (%s)\n", ex.Error(), ex.ErrorMessage());
}
CoUninitialize();
}
return 0;
}
更なるボーナスとして、投げられる例外は、エラーコードだけでなく、エラーメッセージ文字列も返すことができます。オブジェクトのインスタンスを追跡する必要がないため、(それは、スマート・ポインタ・クラスによって、自動的に取り扱われます。)、CreateText()とCreateTextInCorelDRAW()関数は、1つの(はるかに小さい)関数に結合することができます。:
void CreateTextInCorelDRAW(const wchar_t* text, const wchar_t* fontName, float fontSize)
{
VGCore::IVGApplicationPtr app(L"CorelDRAW.Application.17");
app->Visible = VARIANT_TRUE;
VGCore::IVGDocumentPtr doc = app->ActiveDocument;
if (!doc)
doc = app->CreateDocument();
VGCore::IVGShapePtr shape = doc->ActiveLayer->CreateArtisticText(
0.0, 0.0, text, VGCore::cdrTextLanguage::cdrLanguageMixed,
VGCore::cdrTextCharSet::cdrCharSetMixed, fontName, fontSize,
VGCore::cdrTriState::cdrUndefined, VGCore::cdrTriState::cdrUndefined,
VGCore::cdrFontLine::cdrMixedFontLine,
VGCore::cdrAlignment::cdrLeftAlignment);
}
また、CorelDRAWのApplicationオブジェクトが、どのように作成されるかという違いに注意します。VGCore::IVGApplicationPtrのコンストラクタは、作成されるクラスのCLSIDやProgIDを取得できます。そのため、CLSIDFromProgID()とCoCreateInstance()を呼び出す必要はありません。:
void CreateTextInCorelDRAW(const wchar_t* text, const wchar_t* fontName, float fontSize)
{
VGCore::IVGApplicationPtr app(L"CorelDRAW.Application.17");
app->Visible = VARIANT_TRUE;
VGCore::IVGDocumentPtr doc = app->ActiveDocument;
if (!doc)
doc = app->CreateDocument();
VGCore::IVGShapePtr shape = doc->ActiveLayer->CreateArtisticText(
0.0, 0.0, text, VGCore::cdrTextLanguage::cdrLanguageMixed,
VGCore::cdrTextCharSet::cdrCharSetMixed, fontName, fontSize,
VGCore::cdrTriState::cdrUndefined, VGCore::cdrTriState::cdrUndefined,
VGCore::cdrFontLine::cdrMixedFontLine,
VGCore::cdrAlignment::cdrLeftAlignment);
}
他にもいくつか重要な違いがあります。:
- Objectプロパティに値を割り当てることができます。(app-> Visible =…app-> put_Visible(…)ではなく)
- メソッドやプロパティが、他のオブジェクトを返す場合、あなたは、そのオブジェクトのメソッドを、直接、呼び出し続けることができます。(例えば、doc->ActiveLayer->CreateArtisticText)。このプロセスのいずれかのステップが、何らかの理由で失敗した場合、try…catch構文によって、インターセプトすることで簡単にできる例外が、投げられるでしょう。
- COMオブジェクト(app、doc、shape)は、明示的に、解放されていません。関数が終了するか、例外がスローされたとき、これは、自動的に発生します。
管理された.NETアプリケーション
Managed .NET applications
管理されたC++/CLI
Managed C++/CLI
C++/CLIアプリケーションは、管理された.NET アセンブリを使用することができます。まだ、ネイティブで管理されたコードの間で、相互運用する必要ある複雑なソリューションのために、それらと理想プラットフォームを構築する、ネイティブとマネージのC ++コードを混在させることができます。File > New > Project…を選択する事で、Visual Studioで、単純なC++/CLI コンソール・アプリケーションを作成します。そして、「ビジュアルC ++> CLR」プロジェクト・テンプレートのカテゴリから「CLRコンソール・アプリケーション」を選びます:
一旦、プロジェクトが、作成されると、CDGSが、インストールされるとき、あなたは、システムにインストールされている、CorelDRAWの.NET アセンブリに参照を追加する必要があります。
Visual Studioのソリューション・エクスプローラのプロジェクト・ノード上で、右クリックします。そして、Add > References…を追加するか、(メイン・メニューバーから、Project > References…)を選択します:
プロジェクトのプロパティ・ページ・クリックで、Add New Reference…ボタンを追加します:
これにより、「参照を追加」ダイアログが開きます。アセンブリへの切り替え>拡張機能。そして、Corel.Interop.VGCoreアセンブリを選択します:
一旦、これが完了すると、これを読むために、main .cppファイルの内容を変更します。:
#include "stdafx.h"
using namespace System;
using namespace Corel::Interop;
void CreateTextInCorelDRAW(const wchar_t* text, const wchar_t* fontName,
float fontSize)
{
Type^ pia_type = Type::GetTypeFromProgID("CorelDRAW.Application.17");
VGCore::Application^ app =
static_cast<VGCore::Application^>(Activator::CreateInstance(pia_type));
app->Visible = true;
VGCore::Document^ doc = app->ActiveDocument;
if (!doc)
doc = app->CreateDocument();
VGCore::Shape^ shape = doc->ActiveLayer->CreateArtisticText(
0.0, 0.0, gcnew String(text), VGCore::cdrTextLanguage::cdrLanguageMixed,
VGCore::cdrTextCharSet::cdrCharSetMixed, gcnew String(fontName), fontSize,
VGCore::cdrTriState::cdrUndefined, VGCore::cdrTriState::cdrUndefined,
VGCore::cdrFontLine::cdrMixedFontLine,
VGCore::cdrAlignment::cdrLeftAlignment);
}
int main(array<System::String^>^ args)
{
try
{
CreateTextInCorelDRAW(L"Hello, world", L"Arial", 24.0f);
}
catch (Exception^ ex)
{
Console::WriteLine(L"Error occurred: {0}", ex->Message);
}
return 0;
}
上記のコードは、いくつかのC++/CLI マネージド・コード詳細を除いて、スマート・ポインタを備えたC ++のコードと非常に似ています。
再び、ここでProgIDを使用すると、正しいアプリケーション(およびその正しいバージョン)が確実に呼び出されます。
Visual Basic
C ++ / CLIと同様に、Visual Basic > Windows Desktop > Console Applicationのための新しいプロジェクトを作成します。参照を、Corel.Interop.VGCoreアセンブリに追加します。そして、Module1.vbで、アプリケーションのソースコードを提供します。:
Imports Corel.Interop.VGCore
Module Module1
Sub CreateTextInCorelDRAW(text As String, fontName As String, fontSize As Single)
Dim pia_type As Type = Type.GetTypeFromProgID("CorelDRAW.Application.17")
Dim app As Application = Activator.CreateInstance(pia_type)
app.Visible = True
Dim doc As Document = app.ActiveDocument
If doc Is Nothing Then doc = app.CreateDocument()
Dim shape As Shape = doc.ActiveLayer.CreateArtisticText(
0.0, 0.0, text, cdrTextLanguage.cdrLanguageMixed,
cdrTextCharSet.cdrCharSetMixed, fontName, fontSize,
cdrTriState.cdrUndefined, cdrTriState.cdrUndefined,
cdrFontLine.cdrMixedFontLine, cdrAlignment.cdrLeftAlignment)
End Sub
Sub Main()
Try
CreateTextInCorelDRAW("Hello, world", "Arial", 24.0F)
Catch ex As Exception
Console.WriteLine("Error occurred: {0}", ex.Message)
End Try
End Sub
End Module
Visual Basicは、C ++よりも少しレベルの高い言語であるため、機能的には、同じことを行うために必要なコードはさらに少なくなります。
この例は、C++/CLIバージョンと同じです。
C#
Visual C# > Windows Desktop > Console Applicationテンプレートを使用して、新しいプロジェクトを作成します。そして、参照を、Corel.Interop.VGCoreに追加します。
C#とVB.NETの構文の違いは別として、プログラム・コードは、VB.NETとC ++ / CLIのコードと非常によく似ています。:
using System.Text;
using System.Threading.Tasks;
using Corel.Interop.VGCore;
namespace TextCreatorCS
{
class Program
{
static void CreateTextInCorelDRAW(string text, string fontName,
float fontSize)
{
Type pia_type = Type.GetTypeFromProgID("CorelDRAW.Application.17");
Application app = Activator.CreateInstance(pia_type) as Application;
app.Visible = true;
Document doc = app.ActiveDocument;
if (doc == null)
doc = app.CreateDocument();
Shape shape = doc.ActiveLayer.CreateArtisticText(
0.0, 0.0, text, cdrTextLanguage.cdrLanguageMixed,
cdrTextCharSet.cdrCharSetMixed, fontName, fontSize,
cdrTriState.cdrUndefined, cdrTriState.cdrUndefined,
cdrFontLine.cdrMixedFontLine, cdrAlignment.cdrLeftAlignment);
}
static void Main(string[] args)
{
try
{
CreateTextInCorelDRAW("Hello, world", "Arial", 24.0f);
}
catch (Exception ex)
{
Console.WriteLine("Error occurred: {0}", ex.Message);
}
}
}
}
アプリケーションをコンパイルして、実行する
Compiling and running the applications
サンプル・コンソール・アプリケーションのビルドに使用した言語に関係なく、あなたは、問題なく、それをコンパイルすることができるはずです。そして、起動されるとき、現在CorelDRAWで開いている文書内に芸術的なテキストオブジェクト"Hello, world"を作成する必要があります。文書がない場合、新しいものが、作成されます。そして、最後に、CorelDRAWが、すでに実行されていない場合、自動的に起動します。
ダウンロード・ソース:TextCreator.zip