| ||||||
| COM (short for Component Object Model) is a specific convention for allowing objects to interact with one another in an orderly, predictable way. Due to the number of programming languages and operating systems, some standard has to be set for the various objects created by these languages and systems if they want to work together. COM is one such standard. | ||||||
|
ActiveX© is based on COM. It allows Visual Basic programmers to create code libraries for repetitive code or instancing of whole server objects. ActiveX DLL's will provide same code thread execution while EXE's provide a separate code thread. Although it is possible to make an ActiveX standalone EXE program, the intent is to create these as code libraries that your (standard EXE) program may access.
In Visual Basic, ActiveX components are programmed as classes. Class, Client and Server are object-oriented programming terms. A client normally creates an instance of a server class and then sends information and requests to that instance. The server then processes the information and usually returns some information to the client. Generally the ActiveX object is the server and your standard EXE is the client. When Microsoft implemented ActiveX for its Windows© operating system, to comply with the COM standard they set up a system whereby any and all ActiveX components (libraries generally - but just might be a standalone program) must be registered with the operating system before they can be used. Among the advantages, such registration enables Windows to ensure beforehand that a component is ActiveX compliant - thus not tying up the system with repetitive system overhead checks (speeding execution of your library requests). | ||||||
| Visual Basic automatically registers your ActiveX components for you each time you compile an ActiveX project. Included in the system registration information is the path and file name of the DLL or EXE you have just compiled. (So you only need to specify the name of the desired component and Windows knows where to find it.) For your Visual Basic projects you may be creating and registering this DLL or EXE in a directory where your source code is located. | ||||||
|
Similiarly when your program is installed on another computer, it will not run unless your DLL (and a lot of other VB DLL's) is first copied to that computer and then registered. (You must run the application setup wizard to produce the installation file with all these required dependent files.)
If a program has already been installed on another computer, then the rules of COM should allow reregistration of a reprogrammed component with no recompile of the standard EXE client if the signature (anything public about the component) of the ActiveX component has not changed. ActiveX and VB take it one step further and require recompile of your standard EXE any time the ActiveX component has been reregistered. The registered location is important. If you move the DLL or EXE to another directory, Windows can't find it and your (compiled) program won't run. Note that Microsoft did not initiate this process to be an added security feature, but to assist in ensuring compatibility with the COM standard of which ActiveX is a subset. The path is a DOS environmental variable where the system will search for files automatically if you have not included the full path in your filespec. c:\windows, c:\windows\system, and c:\windows\system32 are usually set as the path. Normally you will find ActiveX files in the path (in c:\windows\system or c:\windows\system32). They are copied there when applications are installed on a computer. For your own personal use it is fine to keep your ActiveX components registered in the source code directory where you compiled them. But if you wish to move them to c:\windows\system, you must register them again. (I like to unregister the old location first.) | ||||||
The windows program named c:\windows\regsvr32.exe is used to register and unregister ActiveX DLL's and OCX's. (An OCX file is merely a renamed DLL file.) You RUN regsvr32 as follows:
Register: regsvr32 dllFileName.dll
UnRegister: regsvr32 /u dllFileName.dll
The above example assumes that the target "dllFileName.dll" is in your computer's path. (Regsvr32 is also assumed in the path.)
| ||||||
| ||||||
If your component is not in the path and the path to your component contains a space in it, you will need to enclose the filespec in quotes when you issue the command like this.
Register: regsvr32 "c:\program files\vb\dllFileName.dll"
UnRegister: regsvr32 /u "c:\program files\vb\dllFileName.dll"
| ||||||
ActiveX EXE's have a slightly different process. You do not use Regsvr32.exe to register them. Instead they basically register and unregister themselves, and you accomplish this by running them with the proper command line parameter.
Register: ActivexFileName.exe /regserver
UnRegister: ActivexFileName.exe /unregserver
or
Register: "c:\program files\vb\ActivexFileName.exe" /regserver
UnRegister: "c:\program files\vb\ActivexFileName.exe" /unregserver
Generally you can easily browse for your EXE file in Start->Run and then just add the /regserver part before clicking OK.
| ||||||
| The following RegX Project is a program I wrote for my own personal use to more easily browse for my ActiveX components and then choose to either register or unregister them. | ||||||
| ||||||
| ||||||
| When you run the program, click on the Browse button to bring up the common dialog window. You will then be able to choose an ActiveX file. Click the Register button to register it or the Unregister button to unregister it. | ||||||
'========================================================
' RegX
' by: Rick Meyer date: July 2001
'========================================================
' File Name: regx.frm
' Object Name: Form1
' Description: Interface and code for registering and
' unregistering ActiveX DLL OCX, & EXE
'========================================================
Option Explicit
Private Enum regxEnum
REGISTER
UNREGISTER
End Enum
Private Enum resultEnum
INVALID
NOTFOUND
NOTACTX
NOTHREAD
SUCCESS
FAILURE
End Enum
' The API's to be used
Private Declare Function ShellExecute _
Lib "shell32.dll" Alias "ShellExecuteA" ( _
ByVal hwnd As Long, _
ByVal lpOperation As String, _
ByVal lpFile As String, _
ByVal lpParameters As String, _
ByVal lpDirectory As String, _
ByVal nShowCmd As Long) As Long
Private Declare Function LoadLibraryRegister _
Lib "KERNEL32" Alias "LoadLibraryA" ( _
ByVal lpLibfName As String) As Long
Private Declare Function FreeLibraryRegister _
Lib "KERNEL32" Alias "FreeLibrary" ( _
ByVal hLibModule As Long) As Long
Private Declare Function GetProcAddressRegister _
Lib "KERNEL32" Alias "GetProcAddress" ( _
ByVal hModule As Long, _
ByVal lpProcName As String) As Long
Private Declare Function CreateThreadForRegister _
Lib "KERNEL32" Alias "CreateThread" ( _
lpThreadAttributes As Any, _
ByVal dwStackSize As Long, _
ByVal lpStartAddress As Long, _
ByVal lpparameter As Long, _
ByVal dwCreationFlags As Long, _
lpThreadID As Long) As Long
Private Declare Function GetExitCodeThread _
Lib "KERNEL32" ( _
ByVal hThread As Long, _
lpExitCode As Long) As Long
Private Declare Sub ExitThread _
Lib "KERNEL32" ( _
ByVal xc As Long)
Private Declare Function CloseHandle _
Lib "KERNEL32" ( _
ByVal hObject As Long) As Long
Private Declare Function WaitForSingleObject _
Lib "KERNEL32" ( _
ByVal hHandle As Long, _
ByVal dwMilliseconds As Long) As Long
' The Main Function to do the work
Private Function RegX(fName$, func As regxEnum) _
As resultEnum
Dim regLib&, process&, succeed&
Dim h1&, xc&, id&
Dim p$
Select Case func
Case REGISTER: p = "DllRegisterServer"
Case UNREGISTER: p = "DllUnregisterServer"
Case Else: RegX = INVALID: Exit Function
End Select
regLib = LoadLibraryRegister(fName)
If regLib = 0 Then
RegX = NOTFOUND
Exit Function
End If
process = GetProcAddressRegister(regLib, p)
If process = 0 Then
RegX = NOTACTX
Else
h1 = CreateThreadForRegister(ByVal 0&, 0&, _
ByVal process, ByVal 0&, 0&, id)
If h1 = 0 Then
RegX = NOTHREAD
Else
succeed = _
(WaitForSingleObject(h1, 10000) = 0)
If succeed Then
CloseHandle h1
RegX = SUCCESS
Else
GetExitCodeThread h1, xc
ExitThread xc
RegX = FAILURE
End If
End If
End If
FreeLibraryRegister regLib
End Function
'Handle differently if it is an EXE
Private Function ItIsNotEXE(func As regxEnum) As Boolean
ItIsNotEXE = False
Text1.Text = Trim$(Text1.Text)
If Len(Text1.Text) < 5 Then Exit Function
If LCase$(Right$(Text1.Text, 3)) <> "exe" Then
ItIsNotEXE = True
Exit Function
End If
Dim sWorkDir$, sFile$, sCommand$
sFile = Text1.Text
sWorkDir = vbNullString
sCommand = IIf(func = REGISTER, _
"/regserver", "/unregserver")
Label1.Caption = Str$(ShellExecute(Me.hwnd, _
"open", sFile, sCommand, sWorkDir, 1))
End Function
'The Register Button
Private Sub Command1_Click()
If ItIsNotEXE(REGISTER) Then
showLabel RegX(Text1, REGISTER), ""
End If
End Sub
'The Unregister Button
Private Sub Command2_Click()
If ItIsNotEXE(UNREGISTER) Then
showLabel RegX(Text1, UNREGISTER), "Un"
End If
End Sub
Private Sub showLabel(x As resultEnum, u$)
Dim s$
Select Case x
Case INVALID: s = "Invalid function"
Case NOTFOUND: s = "Could not find file"
Case NOTACTX: s = "File is not ActiveX"
Case NOTHREAD: s = "Could not create thread"
Case SUCCESS: s = u & "Register Successful"
Case FAILURE: s = u & "Register Failed"
End Select
Label1.Caption = s
End Sub
'The Browse Button
Private Sub Command3_Click()
Static InitDir$
If InitDir = "" Then
InitDir = "C:\Windows\System"
End If
With CommonDialog1
.InitDir = InitDir
.FileName = ""
.Filter = "ActiveX Files|*.ocx;*.dll*;*.exe"
.ShowOpen
Text1.Text = .FileName
InitDir = .FileName
End With
End Sub
Private Sub Form_Activate()
Command3.SetFocus
End Sub
Private Sub Form_Load()
Const UNIT = 375
Dim tp!, lt!, rt!, tw!, lt2!
tp = UNIT
lt = 200
rt = ScaleWidth - lt
tw = (rt - lt - UNIT) / 2
lt2 = (ScaleWidth + UNIT) / 2
Caption = "RegX - ActiveX Register and Unregister"
With Text1
.Text = ""
.Move lt, tp, rt - lt, UNIT
End With
tp = tp + UNIT * 2
With Command1
.Caption = "Register"
.Move lt, tp, tw, UNIT
End With
With Command2
.Caption = "Unregister"
.Move lt2, tp, tw, UNIT
End With
tp = tp + UNIT * 2
lt2 = (ScaleWidth - tw) / 2
With Label1
.Caption = ""
.Move lt2 - UNIT, tp, tw + UNIT * 2, UNIT
End With
tp = tp + UNIT * 2
With Command3
.Caption = "Browse"
.Move lt2, tp, tw, UNIT
End With
End Sub
| ||||||