CorelDRAWでマクロを利用するためのドキュメント「3.4 - How is automation coding structured?」の和訳です。
あなたのプログラミングの知識は、Microsoft Visual Basic for Applications (VBA)やMicrosoft Visual Studio Tools for Applications(VSTA)に接したあなたの経験のレベルに関係なく、ソフトウェアの自動化の学習に役立つはずです。
このトピックの内容:
- 変数を宣言する
- 関数とサブルーチンを使用する
- 終了行
- コメントを含める
- メモリの割り当て
- スコープの定義
- Boolean比較と代入を使用する
- ローカルとビット演算子を使用する
- メッセージ・ボックスと入力ボックスを提供する
- オブジェクトを参照する
- コレクションを参照する
- オブジェクト・ショートカットを使用する
- イベント・ハンドラを提供する
Script Editorは、あなたのためのすべてのVBAコーディングをフォーマットします。(コードの自動フォーマット設定を参照)。
書式設定をカスタマイズする唯一の方法は、インデントのサイズを変更することです。
VBAは、オブジェクト指向クラスを作成するために、使用できます。しかしながら、この関数は、プログラミング言語の機能であるため、この文書では詳しく説明しません。
変数を宣言する
Declaring variables
VBAでは、変数を宣言するための構造は、次のようになります。:
Dim foobar As Integer
組み込みデータ型は、Byte、Boolean、Integer、Long、Single、Double、String、Variant、およびDate、Decimal、Objectを含むその他の使用頻度の低い型です。
変数は、関数の本体内、または、現在のモジュールの一番上で、宣言することができます。しかしながら、使用される前に、変数を宣言することは、通常、良い考えです。;それ以外の場合には、コンパイラは、それをVariantと判断し、非効率性が実行されたときに、生じます。
Booleanは、Falseを0に、Booleanから、Longに変換することは、-1の値を変換をTrueに変換する結果を与えますが、Trueを他の値を取ります。
組み込みデータ型の1つに関する情報については、Macro EditorのCodeウィンドウに、それを入力し、それを選択し、続いて、F1を押します。
以下のVBA構文を使用することにより、データ構造を構築することができます。:
Public Type fooType
item1 As Integer
item2 As String
End Type
Dim myTypedItem as fooType
myTypedItem.item1 = 5
文字列を宣言する
Declaring strings
文字列の使用は、CよりもVBAの方がはるかに簡単です。VBAでは、文字列を一緒に追加したり、切り捨てたり、前後に検索することができます。そして、関数に、単純な引数として渡されます。
VBAで、2つの文字列を一緒に追加するために、単純に、連結演算子(&)や加算演算子(+)を使用します。:
Dim string1 As String, string2 As String
string2 = string1 & " more text" + " even more text"
VBAでは、InStr()、Left()、Mid()、Right()、Len()とTrim()を含む、文字列を操作するための多くの関数があります。
列挙体を宣言する
Declaring enumerations
VBAで列挙体を宣言するために、以下の構造を使用します。:
Public Enum fooEnum
ItemOne
ItemTwo
ItemThree
End Enum
デフォルトでは、列挙型の最初の項目は、0の値が、割り当てられます。
配列を宣言する
Declaring arrays
VBAで配列を宣言するために、括弧を使用します。-つまり、(と)記号:
Dim barArray (4) As Integer
この値は、配列の最後の項目のインデックスを定義します。配列の添字が、デフォルトでゼロから始まるため、上記のサンプル配列には、(要素0から4まで)5つの要素があります。
配列は、ReDimを使用して、大きさを変更することができます。たとえば、次のVBAコードは、barArrayに追加の要素を追加しますが、元の5つの要素の既存の内容を保持します。:
ReDim Preserve barArray (6)
配列の上限と下限は、実行時に決定できます。関数UBound()とLBound()を使用して、
以下のVBAの例のように、コンマで、ディメンジョン・インデックスを区切ることによって、多次元配列を、宣言することができます。:
関数とサブルーチンを使用する
Using functions and subroutines
VBAは、関数とサブルーチン(あるいは、"subs")を使用します。関数を使用して、値を返すことができますが、subsには、できません。
VBAでは、関数とサブは、使用する前も、定義する前も、宣言する必要がありません。実際には、関数とサブは、外部システムDLLに、実際に存在する場合のみ、宣言する必要があります。
JavaやC++のような、言語の代表的な関数は、次のように、構築できます。:
void foo(string stringItem) {
// 関数の本体は、ここに記述します
}
double bar(int numItem) { return 23.2; }
VBAでは、しかしながら、関数は、次の例のように構成されます。:
Public Sub foo (stringItem as String)
' サブルーチンの本体は、ここに記述します
End Sub
Public Function bar (numItem as Integer) as Double bar = 23.2
End Function
関数やサブルーチンをすぐに強制終了するために、あなたは、(それぞれ)Exit FunctionやExit Subを使用することができます。
終了行
Ending lines
VBAでは、それぞれの文は、それ自身の行に存在する必要がありますが、それぞれの行の終わりを示すための特別な文字は必要ありません。(対照的に、他の多くのプログラミング言語では、セミコロンを使用して、個々のステートメントを区切ります。)
長いVBAステートメントを2行以上に分割するには、(最終行以外の)各々の行、少なくとも1つの空白が前に付いたアンダースコア(_)で終了する必要があります。
newString = fooFunction ("This is a string", _
5, 10, 2)
あなたは、コロン:で区切ることによって、いくつかのステートメントを、一つのVBA行に結合することができます。
a = 1 : b = 2 : c = a + b
VBA行は、コロンで終わることができません。コロンで終わるVBA行は、Goto文によって使用するラベルです。
コメントを含める
Including comments
ANSI、C++、Javaと同様に、VBAのコメントは、行の最後でのみ作成できます。コメントは、アポストロフィ( ' )で始まり、行末で終了します。
複数行コメントのそれぞれの行は、VBAでは、それ自身のアポストロフィーから始まる必要があります。:
a = b ' これは、本当に面白いコードです。
' それは、多くの説明が必要です。
' コメントを複数行に分割する必要がありました。
VBAコードの大きな範囲をコメントアウトするために、(CやC ++と同様)次の構文を使用します。:
#If 0 Then ' これはゼロであり、文字「oh」ではありません。
' このコードはすべて、
' 実行時にコンパイラによって無視されます!
#End If
メモリの割り当て
Allocating memory
VBAは、Cスタイルのメモリ・ポインタをサポートしていません。メモリ・アロケーションとガーベージ・コレクションは、JavaやJavaScript(そして、いくつかのC ++コード)のように、自動で、わかりやすいです。
引数を渡す
Passing arguments
C ++やJavaを含むほとんどの言語は、元のコピーとして、プロシージャに引数を渡します。オリジナルを渡す必要がある場合、続いて、次の2つのいずれかが発生する可能性があります。:
- メモリ・ポインタは、メモリ内のオリジナルの引数にプロシージャを指示して渡されます。
- 元の引数への参照が渡されます。
Microsoft Visual Basic(VB)には、引数を渡すための同じ要件があります。VBでは、元の引数のコピーを渡すことは、「値渡し」と呼ばれています。そして、元の参照を渡すことを「参照渡し」と呼びます。
デフォルトでは、関数とサブルーチンのパラメーターは、参照で渡されます。元の変数への参照は、プロシージャの引数で渡されます。;その引数の値を変更すること、実際には、同様に、最初の変数値の値を変更します。この方法では、関数やサブルーチンから、1つ以上の値を返すことができます。明示的に、引数が、参照で渡されているコードに注釈をつけるために、あなたは、引数の接頭辞ByRefを付けることができます。
あなたが、プロシージャが元の値の値を変更するのを防ぎたい場合、あなたは、引数のコピーを強制できます。これをVBAで行うために、次の例に示すように、引数に、ByValで接頭辞を付けます。変数のコピーを渡すために、あるいは、ポインタを元の変数に渡すためのByRefとByValの機能は、CとC++の能力と似ています。
Private Sub fooFunc (ByVal int1 As Integer, _
ByRef long1n AS Long, _
long2 As Long) ' Passed ByRef by default
前述のVBAの例では、引数long1とlong2は、デフォルトでは両方とも参照で渡されます。関数の本体内のいずれかの引数を変更すると、元の変数が変更されます。;しかしながら、int1を変更しても、元のコピーであるため、元のファイルは変更されません。
スコープの定義
Defining scope
あなたは、データ型やプロシージャ(あるいは、オブジェクト)のスコープを定義することができます。privateとして、宣言するデータ型、関数とサブルーチン(そして、クラスのメンバー)は、そのモジュール(やファイル)内でのみで、表示されます。対照的に、publicとして宣言される関数は、すべてのモジュールから見えます。;しかしながら、モジュールが、ほとんどスコープ外である場合、たとえば、あなたが、いろいろなプロジェクトで、functionを参照している場合、あなたは、完全修飾に参照を使用する必要がある場合があります。
Cとは異なり、VBAは、ローカル範囲を定義するために、中括弧{と}記号を使用しません。VBAのローカル範囲は、opening関数によって定義されます。あるいは、サブルーチン定義ステートメント(つまり、FunctionやSub)そして、一致するEndステートメント(つまり、End FunctionやEnd Sub)。関数内で、関数自体の範囲内で、宣言された変数は、すべて利用可能です。
Boolean比較と代入を使用する
Using Boolean comparison and assignment
Microsoft Visual Basic(VB)では、Boolean比較とBoolean代入の両方は、一つの等号 ( = )を使用して実行されます。:
If a = b Then c = d
対照的に、多くの他の言語では、Boolean比較のために、二重の等号を使用します。そして、Boolean代入のために、1つの等号:
if( a == b ) c = d;
C、C ++、Java、およびJavaScriptで有効な次のコードは、VBAでは無効です。:
if( ( result = fooBar( ) ) == true )
前述の例は、以下のようにVBAに書き込まれることになります。:
result = fooBar( )
If result = True Then
他のBoolean比較については、VBAは、他の言語と同じ演算子を使用します。("is equal to"と"is not equal to"の演算子を除いて)。すべてのBoolean比較演算子は、次の表で提供されます。
比較 | VBA演算子 | Cスタイル演算子 |
---|---|---|
等しい | = | == |
等しくない | <> | != |
より大きい | > | > |
より小さい | < | < |
より大きいか等しい | >= | >= |
より小さいか等しい | <= | <= |
Boolean演算子を使用した結果は、常に、TrueやFalseです。
ローカルとビット演算子を使用する
Using local and bitwise operators
VBAでは、論理演算は、論理演算AND、NOT、OR、排他的ORを実行する、キーワードAnd、Not、Or、Xor、Imp、Eqv、論理的な意味、そして、論理的等価(それぞれ)を使用して、実行されます。これらの演算子は、Boolean比較も実行します。
次のコードは、Cや類似した言語で記述された比較を示します。:
if( ( a && b ) || ( c && d ) )
この例は、VBAで以下のように、書き込まれます。:
If ( a And b ) Or ( c And d ) Then
別の方法では、前述のVBAコードは、次の完全な省略しない書き方で記述できます。:
次の表は、4つの一般的なVBA論理演算子とビット単位演算子、および、C、C++、JavaとJavaScriptによって使用する、Cスタイルの論理演算子とビット単位演算子の比較を示しています。
VBA演算子 | Cスタイルのビット演算子 | Cスタイルのブール演算子 |
---|---|---|
And | & | && |
Not | ~ | ! |
Or | | | || |
Xor | ^ |
メッセージ・ボックスと入力ボックスを提供する
Providing message boxes and input boxes
VBAでは、あなたは、MsgBox関数を使用することで、単純なメッセージをユーザーに提示することができます。:
Dim retval As Long
retval = MsgBox("Click OK if you agree.", _
vbOKCancel, "Easy Message")
If retval = vbOK Then
MsgBox "You clicked OK.", vbOK, "Affirmative"
End If
あなたは、ユーザーから、InputBox関数を使用することで、文字列を取得することもできます。:
Dim inText As String
inText = InputBox("Input some text:", "type here")
If Len(inText) > 0 Then
MsgBox "You typed the following: " & inText & "."
End If
ユーザーが、Cancelをクリックする場合、inTextで返される文字列の長さは、ゼロです。
より複雑なユーザー・インターフェイスの作成については、「マクロをユーザー・フレンドリーにする」を参照してください。
オブジェクトを参照する
Referencing objects
あなたが、その参照を変数のように扱うことができるために、オブジェクトへの参照を作成する場合、次のCorel DESIGNERとCorelDRAWのVBAの例で、sh)、あなたは、Setキーワードを使用することができます。
Dim sh As Shape
Set sh = ActiveSelection.Shapes.Item(1)
あなたが、この参照を作成したあと、あなたは、まるで、オブジェクトそのものであるかのように、扱うことができます。
sh.Outline.Color.GrayAssign 35
shが、まだ、スコープ内にある間に選択が変更された場合、shは、古い選択からの元の形状を参照し、新しい選択に、影響を受けないです。次の例のように、あなたは、オブジェクトを、単純に、変数に割り当てることができません。:
Dim sh As Shape
sh = ActiveSelection.Shapes.Item(1)
オブジェクトを解放するために、あなたは、その参照値をNothingに設定する必要があります。
Set sh = Nothing
あなたは、Nothingキーワードを使用することで、変数が、有効なオブジェクトを参照しているかどうかもテストできます。
If sh Is Nothing Then MsgBox "sh is de-referenced."
オブジェクトは、明示的に解放される必要はありません。ほとんどの場合、あなたが、関数やサブルーチンを終了するとき、VBは、変数の破棄時に、オブジェクトを解放します。
コレクションを参照する
Referencing collections
多くのオブジェクトは、コレクションのメンバーです。コレクションは、値ではなく、オブジェクトが含まれていますが、配列に似ています。しかしながら、コレクションのメンバーは、配列と同じ方法でアクセスすることができます。たとえば、Corel DESIGNERとCorelDRAWで頻繁に使用されるコレクションは、レイヤーの上のshapesコレクションです:ActiveLayerオブジェクトは、現在のレイヤーやオブジェクト・マネージャーのドッキング・ウィンドウで選択されているレイヤーを参照します。
Corel DESIGNERとCorelDRAWには、多くのコレクションが含まれています。:documentには、pageが含まれています。pageには、layerが含まれています。layerには、shapeが含まれています。curveには、subpathが含まれています。subpathには、segmentとnodeが含まれています。テキスト範囲には、lineとword、shapeが含まれているクループが含まれています。
applicationには、windowが含まれています。これらのコレクションは、すべて、同じ方法でVBAによって処理されます。
コレクション・アイテムを参照する
Referencing collection items
layer上のshapeを参照するために、そのlayerのためのshapesコレクションが、使用されます。:ActiveLayer.Shapes.コレクション内のそれぞれのshapeを参照するために、Item()プロパティが、使用されます。ここに、Corel DESIGNERとCorelDRAWのためのVBAの例があります。:
Dim sh As Shape
Set sh = ActiveLayer.Shapes.Item(1)
コレクションのほとんどの要素は、1から始まり、増加します。コレクションActiveLayer.Shapesの場合、Item(1)は、layerの"top"あるいは、"front"にあるアイテムです。-言い換えると、他の全てのshapeの前にあるアイテムです。さらにまた、ActiveLayerコレクションのそれぞれのアイテムが、Shape型のオブジェクトであるため、あなたは、純粋に、適切なドット表記のメンバーを追加することによって、VBAで、どんなアイテムでも参照することができます。:
ActiveLayer.Shapes.Item(1).Outline.ConvertToObject
時々、それぞれのアイテムには、名前があります。あなたが、探しているアイテムが関連する名前を持っているそして、あなたは、名前が何であるか、そして、アイテムがどのコレクションにあるかわかっている)場合、あなたは、次のCorel DESIGNERとCorelDRAWのVBAの例のように、直接、アイテムを参照する名前を使用できます。
Dim sh1 As Shape, sh2 As Shape
Set sh1 = ActiveLayer.CreateRectangle(0, 5, 7, 0)
sh1.Name = "myShape"
Set sh2 = ActiveLayer.Shapes.Item("myShape")
また、通常、アイテムは、コレクションの暗黙的、あるいは、デフォルトのメンバーであるため、厳密には、必須ではありません。この理由のために、上記のVBAコードの最後の行は、次のように書き換えることができます。:
Set sh2 = ActiveLayer.Shapes("myShape")
コレクション・アイテムを数える
Counting collection items
すべてのコレクションは、Countというプロパティを持っています。この読取り専用プロパティは、次のCorel DESIGNERとCorelDRAWのVBAの例のように、コレクションでメンバーの数を与えます。
Dim count As Long
count = ActiveLayer.Shapes.Count
戻り値は、コレクション内のアイテムの数だけではありません。:コレクションは、1から始まるため、最後のアイテムのインデックスでもあります。
コレクション・アイテムの解析
Parsing collection items
多くの場合、コレクションのメンバーを解析して、それぞれのアイテムのプロパティを確認、あるいは、変更する必要があります。
Item()とCountメンバーを使用して、アイテムのコレクション中に、踏み出すことは、簡単です。それぞれの繰返しで、現在のアイテムのプロパティをテストすること、あるいは、そのメソッドを呼び出すことが可能です。Corel DESIGNERとCorelDRAW用の次のVBAコードは、レイヤー上のすべてのシェイプを10ユニット以下に制限します。:
Dim I As Long, count As Long
count = ActiveLayer.Shapes.Count
For I = 1 to count
If ActiveLayer.Shapes.Item(i).SizeWidth > 10 Then
ActiveLayer.Shapes.Item(i).SizeWidth = 10
End If
Next I
しかしながら、VBAで、コレクションを解析するより便利な方法があります。CountプロパティとFor-Nextループを使用する代わりに、の技術は、For-Each-Inループを使用します。:
Dim I As Long, count As Long
count = ActiveLayer.Shapes.Count
For I = 1 to count
If ActiveLayer.Shapes.Item(i).SizeWidth > 10 Then
ActiveLayer.Shapes.Item(i).SizeWidth = 10
End If
Next I
あなたが、選択をコピーしたい場合、続いて、後で、それを解析します。それが、もはや選択されないとき、選択をShapeRangeオブジェクトにコピーします。:
Dim sr As ShapeRange
Dim sh As Shape
Set sr = ActiveSelectionRange
For Each sh In sr
' Do something with each shape
Next sh
オブジェクト・ショートカットを使用する
Using object shortcuts
ショートカットは、いくつかの頻繁にアクセスされたオブジェクトのために提供されます。ショートカットを使用すると、入力が少なくて済むため、ショートカットは、省略しない書き方のバージョンよりも使いやすいです。(また、コンパイラが、長いドットで区切られた参照で、すべてのオブジェクトを決定する必要がないため、ショートカットを使用すると、実行時のパフォーマンスを改善できます。)
Corel DESIGNERとCorelDRAWのために、ショートカットは、Applicationオブジェクトのプロパティとして、単独で使用することができます。次の表は、これらのショートカットとその長い形式を示します。(アイテムの説明については、Corel DESIGNERとCorelDRAWのためのAPIの部分を参照してください。)
ショートカット | ロング形式 |
---|---|
ActiveLayer | ActivePage.ActiveLayer |
ActivePage | ActiveDocument.ActivePage |
ActiveSelection | ActiveDocument.Selection |
ActiveSelectionRange | ActiveDocument.SelectionRange |
ActiveShape | ActiveDocument.Selection.Shapes(1) |
ActiveView | ActiveWindow.ActiveView |
ActiveWindow | ActiveDocument.ActiveWindow |
Corel PHOTO-PAINTのために、ショートカットは、Corel PHOTO-PAINTのApplicationオブジェクトのプロパティとして、単独で使用することができます。次の表は、これらのショートカットとその長い形式を示します。(アイテムの説明については、APIセクションを参照してください。)
ショートカット | ロング形式 |
---|---|
ActiveLayer | ActivePage.ActiveLayer |
ActiveWindow | ActiveDocument.ActiveWindow |
Corel DESIGNERとCorelDRAWの場合、次のショートカットは、特定のDocumentオブジェクトのメンバーとして使用できます。:
- ActiveLayer
- ActivePage
- ActiveShape
- ActiveWindow
Corel PHOTO-PAINTのために、次のショートカットは、特定のDocumentオブジェクトのメンバーとして使用できます。:
- ActiveLayer
- ActiveWindow
Corel DESIGNERとCorelDRAWの場合、Documentオブジェクトも、あなたが、そのドキュメントがアクティブかどうかに関係なく、指定されたドキュメントから、(それぞれ)選択や選択範囲を取得できる、SelectionとSelectionRangeプロパティもあります。
イベント・ハンドラを提供する
Providing event handlers
実行中に、Corel DESIGNER、CorelDRAW、Corel PHOTO-PAINTは、イベント・ハンドラを使用して、マクロが、応答できるさまざまなイベントを発生させます。-特定の定義された名前を持つサブルーチン。それぞれのマクロ・プロジェクトは、次のコード・モジュールのいずれかでイベント・ハンドラーを定義します。:
- ThisMacroStorage - マクロ・プロジェクトのために、それは、Global Macro Storage (GMS)ファイルに保存されています。
- ThisDocument - マクロ・プロジェクトでは、文書に格納されています。
GlobalMacroStorageオブジェクトは、すべての文書を開き、各々を表示するバーチャル・オブジェクトです。GlobalMacroStorageオブジェクトは、いくつかのイベントを持っています。それは、イベントの発生時に発生します。文書を開く、印刷する、保存する、閉じるような、(それぞれが、"before" と"after"イベントを持っているため、イベントの範囲は実際にはこれよりも大きくなります。)。
イベントに反応するために、あなたは、検索するために、事前にプログラムしたアプリケーションのために、特定の名前を持つThisMacroStorageモジュールのサブルーチンのイベント・ハンドラを提供する必要があります。しかしながら、アプリケーションは、インストールされているすべてのプロジェクトのThisMacroStorageモジュールをすべてチェックします。;このために、他のソリューションを提供するのと同じように、イベント駆動型のソリューションを作成し、それを単一のプロジェクト・ファイルとして配布できます。それぞれのプロジェクトは、ThisMacroStorageモジュールを1つだけ持つことができます。そして、それは、プロジェクトが、最初に作成されるとき、自動的に作成されます。
VBAでは、あなたは、Macro Editorを使用することで、ThisMacroStorageモジュールにイベント・ハンドラを追加することができます。たとえば、Corel DESIGNERやCorelDRAWのマクロ・ソリューションは、ワークフロー管理システムの一部として、ファイルにクロージャーを記録して、ドキュメントの終了に応答する必要がある場合があります。ドキュメントのオープンに応答するために、ソリューションは、GlobalMacroStorageクラスのOpenDocumentイベントに応答する必要があります。VBAで、このイベント・ハンドラを作成するために、以下のことを行います。:
- Macro Editorで、編集のためにThisMacroStorageモジュールを開きます。
- 次に、Codeウィンドウの最上位で、Objectリスト・ボックスから、GlobalMacroStorageを選択します。続いて、DocumentOpenをProcedureリスト・ボックスから選択します。
Macro Editorは、空のサブルーチンは、GlobalMacroStorage_DocumentOpen()を呼び出す新しいものを作成します。-あるいは、そのサブルーチンが、すでに存在する場合、Macro Editorは、それにカーソルを配置します。開いたファイルの名前をログに追加するために、あなたは、いくつかのコードを書き込む必要があるだけす。ThisMacroStorageモジュールの寸法を小さくするために、あなたは、他のモジュールで、パブリック・サブルーチンに、このイベント・ロギングの作業を割り当てることができます。この技術は、インタプリタの実行時に、より簡単に、イベントが発生するたびに、すべてのThisMacroStorageモジュールを解析できます。次のVBAコードは、Corel DESIGNERとCorelDRAWのために、この例を示します。:
Private Sub GlobalMacroStorage_OpenDocument(ByVal Doc As Document, _
ByVal FileName As String)
Call LogFileOpen(FileName)
End Sub
ここに、Corel DESIGNERとCorelDRAWで利用できるイベントの小さなサンプルがあります。:
イベント | 説明 |
---|---|
Start | ユーザーが、アプリケーションを起動するとき、発生します。 |
DocumentNew | 文書が、作成されるとき、発生します。;文書に参照を渡します。 |
DocumentOpen | 文書が、開かれるとき、発生します。;文書に参照を渡します。 |
DocumentBeforeSave | 文書が、保存される前に、発生します。パラメータとして、文書のファイル名を渡します。 |
DocumentAfterSave | 文書が、保存された後に、発生します。パラメータとして、文書のファイル名を渡します。 |
DocumentBeforePrint | 印刷ダイアログ・ボックスが表示される前に、発生します。 |
DocumentAfterPrint | 文書が印刷された後に、発生します。 |
SelectionChange | 選択が変更されたとき、発生します。 |
DocumentClose | 文書が閉じられる前に、発生します。 |
Quit | ユーザーが、アプリケーションを終了するとき、発生します。 |
Shapeクラスに関連したイベントのような、頻繁に発生するイベントのためのイベント・ハンドラは、アプリケーションをできるだけ早く実行し続けるために、可能な限り効率的である必要があります。