The following program is used to create a single object DLL. At this time, it is not possible to package more than one object/class definition per DLL files with Harbour.
This COM will have its own set of properties for every instance created, which is the most typical type of creating COM objects.
Let's review to code below:
On line 4 we define the Objects Class Name. Once the DLL is registered via, regsvr32, this is the name you will use with CreateObject("Example1.harbourwiki.1") or similar commands in the calling program. In Windows you could actually make up almost any names, the dots (.) are not required, but highly recommended.
On line 5 we must assign a unique UUID. For readability of the code, we are using compiler statements in both lines 4 and 5.
The Harbour.wiki site will automatically create for you a new UUID in this sample code. Simply reloading this page will display a new UUID.
Most of the magic in creating a COM server in Harbour comes from line 12. In this line we use a "Code Block", which is a Clipper (the origins of Harbour) base concept, to have each instantiated object have its one memory space. The example 2, further down this article will have a different way to call Win_oleServerInit. This is also where we link the outside definition of the COM object to a Harbour Class (define in the same PRG). But since a DLL can only host a single object definition, use a single name in place of "MyHarbourClassExample". So the PROCEDURE DllMAin() is the equivalent of a Main() C program for the DLL. It is the way the Objects gets initialized.
What makes your DLL unique will be the definition of the Harbour Class on line 16.
In Harbour, we have to list all the Properties, via VAR for example, and Methods via METHOD, in the code between CLASS and ENDCLASS.
Like VFP the language is case insensitive. I use upper case here just for readability. This feature of the language, case insensitivity, makes it so nice not to deal with some bad coding standards where someone use the same text with different casing to mean different things.
Afterwards, on line 24, we actually define the actual code for the Echo method. Please not hat the word "CLASS" with the name MyHarbourClassExample, is the way to make it clear to the compiler which class this method definition belongs to. In Harbour, you could spread the code for a class in multiple PRGs, as long as the CLASS keyword is used in the METHOD command. So this can help to create some really big classes, but coded in smaller PRGs. There is no concept of "SET PROCEDURE", like in VFP, in Harbour. All functions, procedure and methods are global to an entire EXE of DLL, once linked. To create a routine that should only be know to its PRG file only, the leading word STATIC need to be used. This is the same behavior as in C.
To help debug your program, I added the definition of a routine "SendToDebugView" defined on line 45. This use the Microsoft Windows Sysinternals tool
DebugView. In a future article I will demonstrate how to debug your code using a graphical debugger of a running DLL.
The SendToDebugView function is not an entry point (method) of the COM object. It is a support function that your Harbour Code can call. In turn that function, calls a C routine,OUTPUTDEBUGSTRING, that is also defined in this PRG. One of the other wonderful things is Harbour is that you can mix C code with your Harbour code. This is done using the compiler command from line 87 to line 96.