Versions Compared

Key

  • This line was added.
  • This line was removed.
  • Formatting was changed.

Skip to end of metadataGo to start of metadata

When you purchase an ActiveX control, you buy a design-time license for the control. This license is installed on your PC when you install the product and it allows you to use the control in the applications you are developing. The products typically have various design-time licenses for sale. These range from single developer licenses to multiple seat and network licenses.

Usually when you buy a design-time license you also get permission to distribute unlimited copies of the control with your application as compiled object code.

When you distribute your application that uses an ActiveX control, you need to ship also the control in binary format (usually a .dll or an .ocx). Do not distribute the setup file that comes with the design-time license.

Design-time license

If a control has a design-time license it will usually install a license key when its setup program is run. The license key is usually entered into the registry although it can also be installed in a special file.

Having a design-time license allows you to use the control for developing applications.

Run-time license

When you have built and compiled an executable application that uses the control, you need to distribute this control together with the application so a customer can use it. Most of controls also support run-time licensing for this purpose.

At compile time a license key is embedded into the executable file and this key is then inserted into the control when it is created. The control checks this key and if it is valid the control starts up. Because a key is embedded into the executable, no license key is required to be installed on the customer's machine and only the ActiveX control's binary needs to be distributed.

ActiveXのエラー・トラップの考え方を説明する例を以下に示します。コードをコピーして、RDMLXを使用可能にしたフォームに貼り付け、コンパイルして実行してください。

考え方を理解するには、コードのコメントを確認してください。

設定方法

  1. ActiveXのComponentOnFailureプロパティを設定します。
  2. コードでエラーをトラップします。
  3. ActiveXのComponentOnFailureプロパティを「SignalError」に設定します。

ErrorTrappingImage Removed

*Trap error in code
Function Options(*DIRECT)
Begin_Com Role(*EXTENDS #PRIM_FORM) Clientheight(376) Clientwidth(208) Height(414) Left(295) Top(178) Width(224)
Define_Com Class(#PRIM_PHBN) Name(#StartWord) Caption('Start Word') Displayposition(1) Left(8) Parent(#COM_OWNER) Tabposition(1) Top(8) Width(193)
Define_Com Class(#PRIM_PHBN) Name(#CreateDocument) Caption('Create Document') Displayposition(2) Left(8) Parent(#COM_OWNER) Tabposition(2) Top(40) Width(193)
Define_Com Class(#PRIM_PHBN) Name(#FindBookmark) Caption('Access Bookmark') Displayposition(3) Left(8) Parent(#COM_OWNER) Tabposition(3) Top(72) Width(193)
Define_Com Class(#va_word.Application) Name(#Word) Reference(*dynamic)
Define_Com Class(#va_word.Document) Name(#ActiveDocument) Reference(*dynamic)
Define_Com Class(#va_word.Bookmarks) Name(#Bookmarks) Reference(*dynamic)
Evtroutine Handling(#StartWord.Click)
* Start an instance of word
Set_Ref Com(#Word) To(*Create_as #va_word)
Endroutine
Evtroutine Handling(#CreateDocument.Click)
If (#Word *IsNot *null)
If (#ActiveDocument *Is *null)
* Open a new document
#ActiveDocument <= #Word.Documents.Add
* Get the reference to the Bookmarks of the Active Document
* This is necessary to be able to listen to the activeX errors
#Bookmarks <= #ActiveDocument.Bookmarks
Else
Use Builtin(ov_message_box) With_Args("Document Aleady Exists")
Endif
Else
Use Builtin(ov_message_box) With_Args("Word Has Not Yet been Started")
Endif
Endroutine
Evtroutine Handling(#FindBookmark.Click)
Define_Com Class(#va_word.Bookmark) Name(#Bookmark) Reference(*dynamic)
* Ensure there is an Active Document
If (#ActiveDocument *IsNot *null)
* Try to access a bookmark
* As this is a new document there will be no bookmarks
* This will generate an ActiveX error on Bookmarks ONLY
#Bookmark <= #Bookmarks<1>
Else
Use Builtin(Ov_message_box) With_Args("There Is No Active Document")
Endif
Endroutine
Evtroutine Handling(#Word.ComponentError)
* This routine will never fire.  The bookmark error is specific to the Bookmark instance
Use Builtin(Message_Box_Add) With_Args("Error on Word")
Use Builtin(Message_Box_Add) With_Args(#Com_err_info.ErrorWord)
Use Builtin(Message_Box_Show)
Endroutine
Evtroutine Handling(#Bookmarks.ComponentError)
Use Builtin(Message_Box_Add) With_Args("Error on Bookmarks")
Use Builtin(Message_Box_Add) With_Args(#Com_err_info.ErrorWord)
Use Builtin(Message_Box_Show)
Endroutine
Evtroutine Handling(#Com_Owner.Closing)
* Drop all references and ensure Word quits correctly
#Word.Documents.Close
If (#Word *IsNot *null)
#Word.Quit
Endif
Endroutine
End_Com

背景に関する注意事項

LANSAの実行時エラーを処理するには、LANSAによって生成されたエラーと、ActiveXコントロールによって生成されたエラーの違いを理解する必要があります。

次のコード・サンプルを見てみましょう。

Function Options(*DIRECT)
Begin_Com Role(*EXTENDS #PRIM_FORM) Clientheight(313) Clientwidth(492)
Define_Com Class(#PRIM_STBR) Name(#STBR_1) Displayposition(1) Height(24) Left(0) Messageposition(1) Parent(#COM_OWNER) Tabposition(1) Tabstop(False) Top(278) Width(484)
Define_Com Class(#VA_WORD.Application) Name(#VA_WORD)
Evtroutine Handling(#com_owner.Initialize)
Message Msgtxt("Throwing ActiveX error")
#VA_WORD.ComponentOnFailure := SignalError
If (#VA_WORD.ActiveDocument.Bookmarks.Exists( " ERROR" ))
Endif
Endroutine
Evtroutine Handling(#VA_WORD.ComponentError) Options(*NOCLEARMESSAGES *NOCLEARERRORS)
Message Msgtxt(("Catching ActiveX error").BlankConcat( #COM_ERR_INFO.ErrorCode.AsString ))
#COM_ERR_INFO.Clear
Endroutine
End_Com

上の例では、initializeイベントがWord.ActiveDocument.Bookmarksを参照しています。しかし、ActiveDocumentがない場合(ドキュメントを明示的に作成しても開いてもいない場合)、WordのActiveDocument参照はnullになります。つまり、Visual LANSAランタイムがWordのActiveDocumentプロパティにアクセスを試みた瞬間に、Word.ActiveDocumentがnullであるというエラーがLANSAによって生成されます。

initializeイベントが以下のようになっていれば、エラーは発生していませんでした。

* Add a new (active) document.
#VA_Word.Add
If (#VA_word.ActiveDocument.Bookmarks.Exists("Etc")
etc.

したがって、別のインスタンスを参照する機能にアクセスを試みる前に、適切な防御用コードを含めるようにするのは、開発者の責任です。

If (#Word.ActiveDocument *isnot *null)
If (#VA_word.ActiveDocument.Bookmarks.Exists("Error")
etc.
else
Use OV_message_box ("There is no Active Document")
Endif

このコードで、LANSAによって生成される実行時エラーは回避されるようになりましたが、VA_WORDをリスニングすることで発生するActiveXエラーは依然として検出できません。ブックマークが存在しない場合のActiveXエラーは、Bookmarks機能に属するからです。したがって、コードに特殊な参照を設定する必要があります。

Define_Com Class(#va_word.Application) Name(#Word) Reference(*dynamic)
Define_Com Class(#va_word.Document) Name(#ActiveDocument) Reference(*dynamic)
Define_Com Class(#va_word.Bookmarks) Name(#Bookmarks) Reference(*dynamic)
Evtroutine #Com_owner.CreateInstance
* Start Word
Set_Ref Com(#Word) To(*Create_as #va_word)
* Create a new document and store the reference
#ActiveDocument <= #Word.Documents.Add
#Bookmarks <= #ActiveDocument.Bookmarks
Endroutine

ここで、存在しないブックマークへのアクセスを試みると、Wordによって生成されたエラーを以下のように検出できます。

...