序文
ここ数週間の作業で、私は頭の痛い問題に悩まされてきました。つまり、VB6 で書かれた ActiveX コントロールには、Delphi 環境で多くの奇妙な問題が発生するということです。紆余曲折を経て、最終的にほぼすべてのフォーラムと情報を検索しました。 、Delphi のさまざまなバージョンで発生する問題の解決策が見つかりました。
Delphi5 における説明不能な致命的な例外の 1 つ
まず、Delphi5 で VB で書かれた ActiveX コントロールの奇妙な動作を見てみましょう。
例: VB を使用して、コントロール UserTest (簡単にするために、1 つのクラス、ユーザー コントロールのみをエクスポートします)、プロパティ TestName、およびメソッド TestMethod を作成しました。次に、それを ActiveX コントロールにコンパイルし、登録して Delphi5 開発環境にインポートします (上記の手順について不明な点がある場合は、さまざまな参考資料を確認してください。標準的な回答があるはずです)。これまでのところ、すべてが正常であるようです。
次に、コントロールをフォームにドラッグ アンド ドロップし、サイズを変更し、プロパティ ウィンドウでプロパティに値を割り当てることに慣れています。これはコードでも非常に普通で簡単です。ただし、ここで問題が発生します。この TestMethod を熱心に呼び出すと、奇妙な例外「OleError800a01a9」が発生し、残念ながら、VB でもこの例外を追跡できなくなります。もちろん、アセンブリが得意な場合は、Delphi のデバッグ ウィンドウを段階的に実行できます。
初めてこの問題に遭遇したとき、Microsoft も Borland もエラーの説明がなく、検索できる情報もなかったため、ほとんど怒りを感じました。頻繁に利用するいくつかのフォーラムにアクセスする必要がありましたが、最も重要なのは CSDN で、VB バージョンと Delphi バージョンで同様の質問を検索しましたが、残念なことに、この開発を使用している大口顧客には同様の質問しかありませんでした。ツールを使用して、Windows 上のほぼすべての開発ツールと開発環境 (デスクトップと WEB を含む) をテストした後、Delphi のことを忘れていました。
残りの 2 日間、私はほぼ世界中を駆け回り、友人全員に電話をかけて、Delphi の専門家がこの状況を知っているかどうかを尋ねました。残念ながら、そのリンクの正確な場所は今では忘れてしまいました。 、しかし、私はほぼ魔法のメソッドを手に入れました(発見者はそれをそう呼んでいます):
VBActiveX コントロールのインポート後に Delphi によって生成されたプロキシ タイプ ライブラリ XXX_TLB.PAS (XXX はコントロールのクラス名を指します) ファイルを手動で変更する方法により、この問題を解決できます。例:
VB で記述されたコントロール UserControl1 があり、これを Delphi にインポートすると、2 つのファイルが生成されます。そのうちの 1 つである UserControl1_TLB.PAS が、変更するファイルです。
ファイル内で次のようなものを見つけます
FintF:_UserControl1;
FunctionGetControlInterface:_UserControl1;
そして
PROpertyControlInterface:_UserControl1readGetControlInterface;
GetControlInterface;
同様に
プロシージャTUserControl1.CreateControl;
プロシージャDoCreate;
始める
Finf:=IUnknown(OleObject)as_UserControl1;
終わり;
始める
IfFinf=nilthenDoCreate;
終わり;
FunctionTUserControl1.GetControl1Interface:_UserControl1;
始める
コントロールの作成;
結果:=Finfl;
終わり;
注意: ここで赤でマークされているすべての _UserControl1 を _UserControl1Disp に置き換える必要があります。コンパイルが失敗した場合は、コントロール メソッドを呼び出すときに、コンパイル警告で報告されたすべての _UserControl1 を _UserControl1Disp に置き換えてコンパイルしてください。起こる。
この素晴らしい発見に感謝します。このように説明することしかできません。そうしないと、依然としてこのサークルに閉じ込められるか、別のツールを使用してこのコントロールを再開発する必要があるでしょう (これがどれほどの作業になるか想像できません)または、他の互換性の問題がある可能性があります)。
Delphi5 の不可解な致命的な例外 2
しかし、この制限を回避した後も、Delphi は許可しませんでした。開発環境では、実行時にコントロールを含むフォームが閉じるたびに例外がポップアップするという問題が発生しました。コンパイルされたアプリケーションでは発生しませんが、開発者にとっては大きな問題です。その後、上記の例を使用して試してみましたが、この問題は発生しませんでした。 (その時私は気が狂いました。これはおそらくコード内での互換性のない使用法が原因でした。1 日に数万行のコードが規則的であるかどうかを知るのは非常に怖かったです。) 私は腹を立ててコントロールをブロックしました。ユーザー インターフェイス自体だけを残して、すべてのコードを制御しました。その後、何か奇妙なことが起こりました。私はコードを何も書きませんでしたが、このエラーはコントロールを読み込むときに依然として発生します。これには驚きましたが、幸いなことに、この問題はコードとは関係がないため、問題を見つけるのがはるかに簡単です。 VB でいくつかの標準を削除すると、実際にはこのような恐ろしいエラーが発生する可能性があります。Delphi5 と VB6 の間の競合は実際にはそれほど深刻ではありません。次の 2 時間、私はインターフェイス上のコントロールを削除し続け、この致命的な例外を引き起こしたのは誰かをテストしました。
2 時間後、私は安堵のため息をつき、根本的な問題を発見しました。
VB ユーザー コントロールで Frame や PictureBox などのコンテナ コントロール (内部に他のコントロールを含めることができる) を使用する場合、Label、Line、Image などの windowLess コントロールをこれらのコントロールに追加することはできません (つまり、Window コントロールは追加できません)。これらは実行時に VB によってリアルタイムで描画されます)、そうでない場合は、上記のようなエラー レポートが表示されます。
Delphi6 および 7 の非表示 ActiveX コントロール
Delphi 5 でのひどい経験があったからこそ、同じ問題が Delphi 6 と 7 でも存在するかどうかをテストする必要があることがわかりました(ユーザーが非常に少なく、Delphi 8 は正式にリリースされていないため、以前のバージョンはもう必要ありません)まだ使用できないため、当面は考慮されていません)。結果は次のようになります。 ...何度ロードしても、ActiveX バー上に待望の小さなアイコンが見つかりません。この結果は、もちろん、テストが正常かどうかどころか、ロードすることさえできません。
同様に、さまざまなフォーラムや Web サイトを検索し、CSDN で同様の質問をしている人を見つけましたが、答えは依然としてゼロでした。絶望的に、Delphi6 と 7 のそれぞれでオプションを調整する必要がありました。
3 時間 15 分 54 秒後、私はこのいまいましい問題 (そう呼ぶことをお許しください。耐えられなかっただけです) の原因、つまり解決策を見つけました。それは実際には非常に簡単です。
ここで私に従ってください: [ツール] メニュー -> [環境オプション] -> [タイプライブラリ] ページをクリックすると、項目 IgnorespecialCoClassFlagsWhenImporting が見つかるはずです。それを選択し、次に CanCreate 項目を選択します。それでは、その貧弱な ActiveX コントロールをインポートしてみましょう (一度インポートした場合は、生成された 2 つのファイル (.dcr ファイルと .pas ファイル) を削除してください。削除しないと更新されません)。今回も ActiveX 列でコントロールが見つからない場合は、Microsoft または Borland に電話して、いつ結婚できるかを尋ねる必要があります (笑)。
(また、Delphi5 で発生した上記のエラーは Delphi6 および 7 では見つかりませんでした)
私のテスト環境は次のとおりです。
Win2K
Delphi5Update1
Delphi6Update2
デルフィ7