【実務・中級編】【上級プロ向け】Windows APIを活用したCorelDRAWのウィンドウ完全非表示化(Invisible Mode)とバックグラウンド一括変換 – CorelDRAW VBA解析バイブル

スポンサーリンク

【上級】CorelDRAWを完全に隠し、極限の速度で数千ファイルを一括変換する技術

CorelDRAWを使った大量のファイルフォーマット変換(AI、EPS、PDF、SVGなど)において、多くの開発者が直面する最大のボトルネックは「画面描画のオーバーヘッド」と「UIのフリーズ」だ。

`Application.Visible = False`。このプロパティを信じてコードを書いたものの、結局ウィンドウのチラつきが発生したり、タスクバーにアイコンが残り続けたり、最悪の場合はバックグラウンドプロセスがメモリ上に残留してゾンビ化する――。そんな悪夢を見たことはないだろうか。

CorelDRAWのVBAエンジンは、ホストアプリケーションのUIスレッドと密結合している。真に高速かつ堅牢なバックグラウンド処理を実現するためには、VBA単体の機能に頼るのではなく、Windows APIを直接叩いてウィンドウのライフサイクルを完全に制御する必要がある。

今回は、数千件規模のファイルをノーウインドウ(Invisible Mode)で爆速処理し、絶対にメモリリークを起こさないプロダクション・アーキテクチャを伝授する。

—

なぜ標準の `Visible = False` では不十分なのか?

初心者はよく、以下のようなコードを書く。

‘ 【アンチパターン】これでは不完全
App.Visible = False
App.Open “C:\Data\file.cdr”
App.ActiveDocument.Export “C:\Data\file.pdf”, cdrPDF
App.ActiveDocument.Close
App.Visible = True

このアプローチには致命的な欠陥がある。
1. 初期描画のリーク: CorelDRAWの起動瞬間やドキュメント読み込みの初期化フェーズにおいて、一瞬ウィンドウが画面にフラッシュ(描画)される。
2. メッセージポンプの呪縛: UIスレッドが生きたまま処理を行うため、OSからのフォーカス要求や不要なイベントハンドラが走り、処理速度が低下する。
3. 例外時のゾンビ化: 変換中にエラーが発生してコードが中断した場合、CorelDRAWのプロセスがバックグラウンドに残存し、次回起動時にライセンス競合やメモリ圧迫を引き起こす。

これを解決するためには、「起動直後からウィンドウハンドル(hWnd)を隠蔽し、OSレベルで描画メッセージを遮断する」設計が不可欠となる。

—

堅牢なバックグラウンド変換エンジンの設計方針

実務で耐えうるシステムを構築するため、以下の3点をアーキテクチャの軸とする。

1. Windows APIによる完全不可視化: `ShowWindow` および `SetWindowLong` を駆使し、プロセス起動と同時にウィンドウを完全に隠す。
2. 厳格なエラーハンドリング(RAII的アプローチ): 例外が発生しようとも、必ずCorelDRAWのプロセスがクリーンアップされる構造を作る。
3. ガベージコレクションとメモリ管理: 大量ファイルを処理する際、VBAのオブジェクト参照がメモリ上に蓄積するのを防ぐため、明示的なオブジェクトの破棄(`Nothing`代入)と `DoEvents` の適切な制御を行う。

—

プロダクション・コード例

以下のコードは、指定したフォルダ内のCorelDRAWファイルを、一切の画面描画を行わずにPDFへ一括変換するモジュールである。エラーハンドリングとAPIによるウィンドウ制御を完璧に組み込んでいる。

Option Explicit

‘ ==========================================================
‘ Windows API 定義
‘ ==========================================================
Private Declare PtrSafe Function ShowWindow Lib “user32” (ByVal hwnd As LongPtr, ByVal nCmdShow As Long) As Long
Private Declare PtrSafe Function GetActiveWindow Lib “user32” () As LongPtr

Private Const SW_HIDE As Long = 0
Private Const SW_SHOW As Long = 5

Sub ExecuteInvisibleBatchConversion()
Dim sourceDir As String
Dim targetDir As String
Dim fileName As String
Dim fso As Object
Dim fileCount As Long
Dim startTime As Double

startTime = Timer

‘ 入出力パスの設定(実務に合わせて変更してください)
sourceDir = “C:\CorelData\Source\”
targetDir = “C:\CorelData\Output\”

Set fso = CreateObject(“Scripting.FileSystemObject”)
If Not fso.FolderExists(targetDir) Then fso.CreateFolder (targetDir)

‘ ==========================================================
‘ 1. 最重要:CorelDRAW自身のウィンドウを隠蔽
‘ ==========================================================
On Error GoTo ErrorHandler

‘ 画面更新とアラートを完全停止(パフォーマンス最大化の基本)
CorelDRAW.Optimization = True
CorelDRAW.EventsEnabled = False

‘ 自身のウィンドウハンドルを取得して非表示化
Dim hwnd As LongPtr
hwnd = GetActiveWindow()
If hwnd <> 0 Then
Call ShowWindow(hwnd, SW_HIDE)
End If

‘ ファイル列挙とループ処理
fileName = Dir(sourceDir & “.cdr”)
fileCount = 0

Do While fileName <> “”
Dim doc As Document
Dim targetPath As String

targetPath = targetDir & fso.GetBaseName(fileName) & “.pdf”

‘ 2. バックグラウンドでのドキュメント処理
‘ 第2引数(True)でサイレントオープン(可能な限りUIダイアログを出さない)
Set doc = CorelDRAW.OpenDocument(sourceDir & fileName)

‘ パブリッシュオプションの設定(必要に応じてカスタマイズ)
Dim opt As StructPDFExportSettings
Set opt = New StructPDFExportSettings
opt.PublishRange = 1 ‘ 全ページ

‘ PDFエクスポート実行
doc.PublishToPDF targetPath, opt

‘ 3. メモリリーク防止の厳格なオブジェクト解放
doc.Close
Set doc = Nothing
Set opt = Nothing

fileCount = fileCount + 1

‘ OSへのCPU負荷軽減とフリーズ防止(数千件処理のキモ)
If fileCount Mod 10 = 0 Then DoEvents

fileName = Dir()
Loop

CleanUp:
‘ ==========================================================
‘ 4. クリーンアップ処理(例外時も必ず実行される)
‘ ==========================================================
CorelDRAW.EventsEnabled = True
CorelDRAW.Optimization = False

‘ ウィンドウを再表示(必要に応じて)
If hwnd <> 0 Then
Call ShowWindow(hwnd, SW_SHOW)
End If

MsgBox “一括変換が完了しました。” & vbCrLf & _
“処理ファイル数: ” & fileCount & “件” & vbCrLf & _
“処理時間: ” & Format(Timer – startTime, “0.00”) & “秒”, vbInformation, “バッチ処理完了”
Exit Sub

ErrorHandler:
MsgBox “致命的なエラーが発生しました: ” & Err.Description, vbCritical, “エラー”
Resume CleanUp
End Sub

—

現場で絶対に押さべき実務上の注意点

1. サードパーティ製プラグイン・フォント警告の罠

バックグラウンド処理の最大の敵は、ファイルを開いたときに突然現れる「フォントが見つかりません」「埋め込みカラープロファイルがありません」といったモーダルダイアログである。これがポップアップした瞬間、Invisible Modeであってもプロセスは完全に停止し、ユーザーのクリック待ち状態(ハングアップ)に陥る。

  • 対策: 事前に環境側のフォントを完全に一致させておくこと。また、CorelDRAWのオプション設定で「ファイルオープン時の警告を抑制する」レジストリ設定やアプリケーション設定を必ず行っておくこと。

2. `DoEvents` のジレンマと最適化

数千件のファイルをループ処理する場合、OSに制御を戻すために `DoEvents` を挟む必要があるが、毎回挟むとI/Oのオーバーヘッドで逆に処理が遅くなる。上記のコードのように 「10ファイルに1回」 などのバッチ間隔で挟むのが、パフォーマンスと安定性のベストバランスである。

3. マルチプロセス化の検討(更なる高みへ)

もし扱っているCorelDRAWのファイル数が「1万件」を超え、かつマルチコアCPUの恩恵を極限まで受けたい場合は、VBA単体ではなく、VB.NET(C#)でCOM Interopを使い、複数インスタンスを非同期並列起動(Task Parallel Library等)するアーキテクチャへ移行すべきだ。
しかし、社内ツールや限定された環境での確実な自動化であれば、今回紹介した「Windows APIによる非表示化 + VBA」の組み合わせだけで、開発コスト対効果は最大化される。

—

チーフアーキテクトからの総評

プログラミングにおいて「動けばいい」というフェーズは、数件のテストファイルを扱うときで終わりだ。実務で「数千件のデータ」を扱うエンジニアに求められるのは、「OS資源を枯渇させず、エラー時すら美しく自己修復する堅牢性」である。

今回提供したWindows APIを活用した非表示化テクニックをあなたのソリューションに組み込めば、裏でCorelDRAWがどれだけ重い処理をしていようとも、ユーザーは快適に別の作業を並行できる。真のプロフェッショナルな自動化ツールを、ぜひ現場で実装してほしい。

タイトルとURLをコピーしました