Delphi でユーザー インターフェイスを作成するための推奨事項。 Delphi でのインターフェイスの操作の機能 Delphi インターフェイスの説明

Viberをダウンロード 23.01.2022
Viberをダウンロード

Delphi プログラミング環境の最大の強みの 1 つは、そのオープン アーキテクチャです。これにより、Delphi では一種のメタプログラミングが可能になり、「プログラミング環境のプログラミング」が可能になります。 このアプローチにより、Delphi はアプリケーション開発システムの質的に新しいレベルに到達し、アプリケーション システム作成のほぼすべての段階をサポートする追加ツールをこの製品に組み込むことができます。 このような幅広い可能性は、IDE (統合開発環境) と外部ツールの間の接続リンクである、Delphi に実装されたいわゆるオープン インターフェイスの概念のおかげで開かれます。

この記事は Delphi のオープン インターフェイスに特化しており、そのオープン インターフェイスが提供する機能の概要を説明します。 Delphi は、ツール インターフェイス、デザイン インターフェイス、エキスパート インターフェイス、ファイル インターフェイス、編集インターフェイス、およびバージョン管理インターフェイスの 6 つのオープン インターフェイスを定義します。 この記事の枠内では、それぞれの機能を詳細に取り上げて説明することはできそうにありません。 Delphi のソース テキストは、検討中の問題をより深く理解するのに役立ちます。幸いなことに、開発者から詳細なコメントが提供されています。 パブリック インターフェイスを表すクラスの宣言は、ディレクトリ...\Delphi\Source\ToolsAPI 内の対応するモジュールに含まれています。 デザイン インターフェイス (モジュール DsgnIntf​​.pas) は、プロパティ エディターとコンポーネント エディターを作成するためのツールを提供します。

プロパティ エディタとコンポーネント エディタについては、個別に説明する価値のあるトピックです。そのため、プロパティ エディタは、対応するプロパティの値を変更しようとするときのオブジェクト インスペクタの動作を制御し、コンポーネント エディタはダブルクリックするとアクティブになることを思い出してください。フォーム上に配置されたコンポーネントの画像上でマウスの左ボタンを押します。 バージョン管理インターフェイス (VCSIntf.pas モジュール) は、バージョン管理システムの作成を目的としています。 Delphi はバージョン 2.0 以降、統合バージョン管理システム Intersolv PVCS をサポートしているため、ほとんどの場合、独自のシステムを開発する必要はありません。 このため、バージョン管理インターフェイスについても考慮を省略します。 ファイル インターフェイス (FileIntf.pas モジュール) を使用すると、IDE の作業ファイル システムをオーバーライドでき、ファイルを保存する独自の方法 (データベース サーバー上のメモ フィールドなど) を選択できるようになります。 編集インターフェイス (モジュール EditIntf.pas) は、ソース テキスト バッファーへのアクセスを提供します。これにより、コードの分析と生成、コード エディター ウィンドウ内のカーソル位置の決定と変更、およびソース テキストの構文の強調表示の制御が可能になります。

特別なクラスは、フォーム上に配置されたコンポーネント (コンポーネントの種類の定義、親コンポーネントと子コンポーネントへの参照の取得、プロパティへのアクセス、フォーカスの移動、削除など)、フォーム自体、およびプロジェクト リソース ファイルへのインターフェイスを提供します。 編集インターフェイスでは、モジュールのソース テキストの変更、フォームの変更、コンポーネントの名前変更、モジュールの保存、名前変更または削除、プロジェクト リソース ファイルの変更、ツール インターフェイス (ToolIntf module.pas) は、開発者が IDE の状態に関する一般的な情報を取得し、プロジェクトや個々のファイルを開いたり、保存したり、閉じたり、モジュールを作成したり、現在のプロジェクトに関する情報を取得したりするための手段を提供します。 (モジュールとフォームの数、それらの名前など)、ファイルシステムの登録、個々のモジュールへのインターフェースの整理など。 モジュール通知機能に加えて、ツール インターフェイスでは、ファイルとプロジェクトの開閉、デスクトップ プロジェクト ファイルの読み込みと保存、プロジェクト モジュールの追加/除外、パッケージのインストール/アンインストール、プロジェクトのコンパイル、およびモジュラー通知機能とは異なり、アドイン通知機能を使用すると、一部のイベントの実行をキャンセルできます。

さらに、ツール インターフェイスは、Delphi IDE のメイン メニューにアクセスする手段を提供し、そこに追加の項目を埋め込むことができます。 エキスパート インターフェイス (ExtIntf.pas モジュール) は、エキスパート (IDE の機能を拡張するために IDE に組み込まれたソフトウェア モジュール) を作成するための基礎です。 エキスパートの例としては、データベース テーブルの内容を表示および変更するためのフォームを生成する Delphi データベース フォーム ウィザードがあります。 エキスパート クラスを定義したら、Delphi がエキスパートについて「学習」するようにする必要があります。 これを行うには、RegisterLibraryExpert プロシージャを呼び出し、エキスパート クラスのインスタンスをパラメータとして渡して登録する必要があります。 実例として、esStandard スタイルで単純なエキスパートを作成してみましょう。このエキスパートは、対応する Delphi メニュー項目を選択すると、実行中であることを示すメッセージを表示します。 上の表からわかるように、esStandard スタイルでは 6 つのメソッドをオーバーライドする必要があります。

エキスパートを「実行」するには、「コンポーネント/コンポーネントのインストール...」メニュー項目を選択し、「参照」ダイアログでエキスパートを含むモジュール (この場合は exmpl_01.pas) を選択し、「OK」をクリックして、 dclusr30.dpk パッケージをコンパイルした後、Delphi のメイン メニューの [ヘルプ] セクションに [Simple Expert 1] 項目が表示され、選択すると、「Standard Expert が開始されました!」という情報メッセージが表示されます。 Delphi がヘルプ セクションにエキスパート メニュー項目を配置する理由は依然として謎のままです。 メニュー項目が、希望する場所ではなく、Delphi の希望する場所に表示されるという事実が気に入らない場合は、次のオプションが考えられます。アドイン スタイルでエキスパートを作成し、メニュー項目の自動作成を排除します。ツール インターフェイスを使用してメニュー項目を「手動で」追加します。 これにより、メイン メニュー内の新しい項目の位置を任意の方法で設定できるようになります。

メニュー項目を追加するには、ツール インターフェイスの基礎である TIToolServices クラスと、IDE メイン メニューとその項目へのインターフェイスを実装する TIMainMenuIntf、TIMenuItemIntf クラスを使用します。 ToolServices クラス TIToolServices のインスタンスは、IDE の初期化時に IDE 自体によって作成されます。 Delphi メイン メニューとその項目へのインターフェイスをリリースする責任は完全に開発者にあることに注意してください。 途中で、エキスパートの機能負荷を少し複雑にしてみましょう。メニュー項目をアクティブ化すると、環境内で現在開いているプロジェクトの名前に関する証明書が発行されます。この例では、中心的な場所は AddIDEMenuItem 関数によって占められています。 、IDE Delphi のメイン メニューにメニュー項目を追加します。 パラメータとして、新しいメニュー項目のテキスト、その識別子、新しい項目が挿入される前の項目の識別子、Ctrl キーと組み合わせて使用​​すると、メニュー項目にすばやくアクセスできるキーのシンボリック表現を受け取ります。新しい項目と、新しい項目の選択に対応するイベント ハンドラー。 「View」セクションの「Watches」項目の前に新しいメニュー項目を追加しました。

次に、通知機能について説明しましょう。 プロジェクトの終了/開始を追跡し、それに応じてアクティブなプロジェクトの名前を格納するフィールドを調整するアドイン通知機能を定義しましょう (簡潔にするために、前の例と比較して変更が加えられていないメソッドの実装は省略します)。ノーティファイアを実装するには、子孫 TIAddInNotifier である TAddInNotifier クラスを定義し、FileNotification メソッドをオーバーライドしました。 IDE は、アドイン通知機能が応答できるイベントが発生するたびに、このメソッドを呼び出します (そのような各イベントは、TFileNotification 型の対応する定数によって示されます)。 TAddInNotifier クラスの Expert フィールドは、エキスパートへのフィードバックに使用されます (TAddInNotifier.FileNotification メソッド)。 エキスパートのデストラクタでは、ノーティファイアの登録が解除され、ノーティファイアが破棄されます。 次に、モジュール式通知機能の使用方法を説明します。 プロジェクト ファイルを保存する各動作に関するメッセージを発行するアドイン エキスパートを作成しましょう (簡潔にするため、すでによく知られているメソッドの実装は示しません)。 この例では、アドイン エキスパートはイベントを監視します。プロジェクトの開始/終了に対応します。

プロジェクトが開かれるたびに、プロジェクト ファイルに対応するモジュラー ノーティファイアが登録されます。 実装の点では、モジュラー通知機能はアドイン通知機能と似ています。TIModuleNotifier の子孫である TModuleNotifier クラスを定義し、その Notify メソッドと ComponentRenamed メソッドをオーバーライドします。 IDE は、このモジュールに関連する特定のイベントが発生すると、Notify メソッドを呼び出します。 このメソッド内で、特定のイベントに対する反応が決定されます。 ComponentRenamed メソッドは、モジュール フォーム上のコンポーネントの名前が変更されるときに呼び出されます。 このメソッドは使用しませんが、オーバーライドする必要があることに注意してください。オーバーライドしないと、コンポーネント名が変更されたときに基本クラスの抽象メソッドが呼び出され、予期しない結果が生じることになります。

モジュラー ノーティファイアの登録は、アドイン ノーティファイアの登録と比較して、少し複雑なプロセスです。まずモジュール インターフェイス (TIModuleInterface) を取得し、次にモジュール インターフェイスを使用してノーティファイアを登録します。 プロジェクトが閉じられると、モジュラー ノーティファイアは登録解除され (やはり TIModuleInterface を使用)、ノーティファイアは破棄されます。 結論として、コード エディター ウィンドウ内のカーソルの位置を決定する方法を示します。 適切なメニュー項目を選択すると、アクティブなファイルの名前とその中のカーソル位置を含むメッセージを表示するエキスパートを作成しましょう (この例に必要なメソッドの実装のみが示されています)。 カーソル位置を決定するには、次のようにします。次の一連のインターフェイスを取得する必要があります。モジュラー インターフェイス (TIModuleInterface)。 コード エディタ インターフェイス (TIEditorInterface)。 エディター ウィンドウ (TIEditView) のモジュール プレゼンテーション インターフェイス。

エキスパート メニュー項目を選択するときにソース テキスト ファイル (*.pas) がアクティブな場合は、アクティブなファイルの名前とそのファイル内の現在のカーソル位置を含むメッセージが表示されます。 アクティブなファイルが PAS ファイルではない場合、メッセージは発行されません。 アクティブなファイルの名前を取得するには、TIToolServices クラスの GetCurrentFile メソッドを使用します。 これで、オープン インターフェイスの使用方法の検討は終了です。 CD-ROM には、示されているすべての例のソース コードが含まれています。 CD-ROM には、ユーザーが Delphi モジュールのソース テキストをブックマークできるようにするアドイン エキスパートを含む、より複雑で詳細なサンプルも含まれています。 Bookmarks Expert のインストールと使用に関する簡単なガイドは、ファイル bkmrks97.htm に含まれています。 したがって、この記事では、オープン インターフェイスの概要とその使用例を示します。 もう一度繰り返しますが、オープン インターフェイスのソース コードが利用できるため、興味のある詳細を簡単に理解できます。 オープン インターフェイスが提供するさまざまな可能性が、大胆で有益なアイデアを複数与えることを願っています。

結果だけのために

期限の厳守

透明性

プロジェクトの実施

技術サポートをギフトとして提供

1Cに関するプログラミング、修正、相談

私たちの働き方

1. 私たちは電話で問題について話し合います。 リモート アクセスがある場合は、コンピュータ画面に表示します。

2. プロジェクトが大規模な場合はルーブル単位で作業を見積もります。そうでない場合はおおよその時間数を見積もります。

3. 私たちは仕事をやり遂げます。

4. プログラムに欠陥がある場合は、修正します。

5. 請求書を発行しますので、お支払いいただきます。

作業費

1. すべての作業は、コンサルテーション、標準構成の更新、新しいレポートの開発またはプログラミング、処理、ボタンなどの 3 つのカテゴリに分類されます。

3. 10 時間を超える作業の場合は、作業の説明と費用を記載した技術仕様書を事前に作成する必要があります。 技術仕様がお客様と合意された後に作業が開始されます。

テクニカルサポート

1. 3ヶ月以内に過去に受託した作品に誤りがあった場合には、無償で修正いたします。

2. 定期的にご利用いただいているお客様には、1 年以内に作業上の欠陥を無料で修正します。

ビジネスを管理するためのソフトウェア。

1C:エンタープライズを購入する

当社は1Cの正規代理店ですので、各種ソフトウェア製品やライセンスをご購入いただけます。 「ボックス」の購入に加えて、プログラムのセットアップ、アドバイス、基本的な設定をお手伝いします。

  • 会計
  • ストアオートメーション
  • 卸売
  • インストールと初期設定のサポートがパッケージに含まれています。
  • 顧客のニーズに合わせて構成を微調整し、標準構成に必要な機能が欠けている場合に新しいモジュールを開発します。
1c 会計 1C: 貿易管理 1C: 小売 1C: 給与および人事管理
3300摩擦から。 6700こすれから。 3300摩擦から。 7400摩擦から。

サーバーの提供。

サーバー + 1C のインスタントセットアップ。

サーバーがありませんか? 問題ありません。クラウド内のサーバーを選択してすぐにセットアップします。 少額の料金で、非常に信頼性の高いソリューションが得られます。

  • 空室状況 24/7
  • 独自のシステム管理者を置く必要はありません (節約された分でサーバーのコストがカバーされます)。
  • 1C をサーバーに迅速にセットアップしてインストールすると、3 日以内に完全に動作するシステムが完成します。
  • ソリューションに満足できない場合は、いつでもローカル サーバーに移動できます。

1C からの SMS

顧客にプロモーションや割引について知ってもらいたいですか? 客は戻ってこないのか? 1C から直接 SMS を送信するように設定してください。

当社では、1C から直接顧客に SMS を送信する設定を迅速に行うことができます。 自動化できるイベントの例:

  • ご購入いただきありがとうございます。次回購入後すぐにボーナスが付与されます。
  • 誕生日やその他の大切な日、または祝日のギフトとしてカードにボーナスが付与されます。
  • 倉庫への商品到着のお知らせ。
  • ギフトボーナスの有効期限が切れます。
  • 前払い入金と商品の予約完了のお知らせ。
  • 店舗/オフィスへの道順を含む住所、電話番号。
  • 等々。

1C でのセットアップは、当社の専門家または貴社の従業員が行うことができます。 料金表は SMS 料金ページで確認できます。

  • SMS の配信が保証されており、配信された SMS に対してのみ料金が請求されます。
  • SMS ごとに個別の料金がかかります。
  • さまざまな方法で残高を補充してください。
  • 送信されたすべての SMS の履歴をいつでも確認できます。
  • メッセージ受信者の電話のデジタル番号の代わりに送信者の名前。

C++ コードから Delphi クラスを使用する際に問題が発生します。 delphi dll のデモ。オブジェクトを返す関数をエクスポートします。
私の Delphi DLL コードは次のようになります。

ライブラリ DelphiTest; // パーツを使用します.... type IMyObject = インターフェイス プロシージャ DoThis(n: Integer); 関数 DoThat: PwideChar; 終わり; TMyObject = class(TInterfacedObject,IMyObject) プロシージャ DoThis(n: 整数); 関数 DoThat: PChar; 終わり; // TMyObject 実装はここに移動します ... プロシージャ TMyObject.DoThis(n: Integer); begin showmessage(「"+intToStr(n) +"パラメータ" を使用して DoThis メソッドを呼び出しています」); 終わり; 関数 TMyObject.DoThat: PChar; begin showmessage("DoThat 関数を呼び出しています"); 結果:= Pchar("こんにちは、Dothat"); 終わり;

// DLL 関数のエクスポート:

関数 CreateMyObject: IMyObject; 標準呼び出し;エクスポート; var txt: テキストファイル; begin AssignFile(txt,"C:\log.log"); リセット(txt); Writeln(txt,"こんにちは"); 結果:= TMyObject.Create; 終わり; CreateMyObject をエクスポートします。

私の C++ プロジェクトでは、次のように IMyObject インターフェイスを宣言しました。

Class IMyObject ( public: IMyObject(); virtual ~IMyObject(); virtual void DoThis(int n) = 0; virtual char* DoThat() = 0; );

そして私の主な機能は次のようなものです:

Typedef IMyObject* (__stdcall *CreateFn)(); int main() ( HMODULE hLib; hLib = LoadLibrary(L"DelphiTest.dll");assert(hLib != NULL); // 合格 !! CreateFn pfnCreate; pfnCreate = (CreateFn)GetProcAddress((HINSTANCE)hLib, "CreateMyObject "); if (pfnCreate == NULL) ( DWORD errc = GetLastError(); printf("%u\n", errc); // エラー 127 が発生します ) else( printf("successload\n"); ) IMyObject* objptr = pfnCreate(); objptr->DoThis(5); int_s("%i", &in);

この例では、エクスポートされた関数にアクセスしようとするとランタイム エラーが発生しました。 次の行のエラー:
IMyObject* objptr = pfnCreate();

私の例のどこが間違っているのか教えていただけますか。
可能であれば、C++ コードから Delphi クラス (DLL 内) にアクセスするための実際の例。

解決

最初の問題は、メソッド規約の呼び出しです。 Delphi インターフェイスは、Delphi 固有の呼び出し規則である register を使用します。 stdcall の使用 たとえば、インターフェイス メソッドの場合。

次の問題は C++ です。 C++ インターフェイスは IUnknown から派生する必要があります。さらに、コンストラクターまたはデストラクターを宣言してはなりません。

これとは別に、Delphi コードは PwideChar によってエクスポートされますが、これは char* にマップされず、 wchar_t* にマップされます。

さらに詳しく見てみると、実装ではリテラルが返されるため、ここでは PChar を返すと問題なく動作します。 しかし、より本格的なコードでは、動的に割り当てられた文字列を使用する必要がある可能性があり、その時点で設計に欠陥があります。

システム ドライブのルートにファイルを作成するには、昇格された管理者である必要があることに注意してください。 したがって、これも潜在的な障害点となります。

他にもバグはあると思いますが、今のところ見つかっているのはこれだけです。

これは、フォーラムでの質問に基づいた記事です。「DLL から文字列を返すにはどうすればよいですか?」、「レコードの配列を渡して返すにはどうすればよいですか?」、「DLL にフォームを渡すにはどうすればよいですか?」。

それを理解するのに人生の半分を費やさないように、この記事ではすべてを大皿に盛り付けて説明します。

この記事のトピックは、このブログで程度の差こそあれ何度か触れられていますが、この記事ではそれらをまとめて正当化します。 つまり、DLL を開発している人にこの記事へのリンクを投げることができます。

重要な注意点: 記事は読まなければなりません 順次。 コード例は次のようにのみ提供されています 、記事の各ステップ (ポイント) で、サンプル コードに新しい詳細が追加されます。 たとえば、記事の冒頭ではエラー処理が行われておらず、「古典的な」メソッド ( GetLastError や sdtcall 規約の使用など) が示されていますが、記事が進むにつれてより適切なメソッドに置き換えられます。 これは、「新しい」(「珍しい」)デザインに疑問が生じないようにするためです。 それ以外の場合は、例ごとに「これは下の段落で説明されていますが、あれはこの段落で説明されています」というような注記を挿入する必要があります。 いずれにせよ、記事の最後には、記事で述べられたすべてを考慮して書かれた既製のコードへのリンクがあります。 そのまま手に取って使用することができます。 そして記事ではその理由と理由が説明されています。 「なぜ、なぜ」に興味がない場合は、最後までスクロールして結論と例をダウンロードするリンクを参照してください。



読むことをお勧めします