Hi Przemek,
It's great. I hope we can nail the watcom tricks and .def file
"chaos" in the future.
I've successfully tested olesrv2 with oletst2.
Then I tried to access olesrv2 from jscript/vbscript. Since
I'm using Win7 x64, first I built olesrv2 with msvc64,
and registered it, which went OK. msvc64 compilation showed
these warnings:
..\hbolesrv.def : warning LNK4104: export of symbol 'DllRegisterServer'
should be PRIVATE
..\hbolesrv.def : warning LNK4104: export of symbol 'DllUnregisterServer'
should be PRIVATE
With these scripts:
--- tst2.jscript
{
var tst2 = new ActiveXObject( "MyOleTimeServer" );
WScript.stdout.WriteLine( tst2.TIME() );
}
--- tst2.vbscript
Dim tst2 : Set tst2 = WScript.CreateObject("MyOleTimeServer")
WScript.stdout.WriteLine tst2.TIME()
---
Both worked when run from 'cscript'. They also worked with
(default) 'wscript' when using GUI output function:
--- tst2.vbs
Dim tst2 : Set tst2 = WScript.CreateObject("MyOleTimeServer")
WScript.CreateObject("Wscript.Shell").Popup tst2.TIME()
---
The only thing I noticed is that "TIME()" is case-sensitive,
so probably a HB_HSETCASEMATCH() call would be needed in sample
server.
Great job!
Viktor
On 2010 May 26, at 00:04, [email protected] wrote:
> Revision: 14593
>
> http://harbour-project.svn.sourceforge.net/harbour-project/?rev=14593&view=rev
> Author: druzus
> Date: 2010-05-25 22:04:04 +0000 (Tue, 25 May 2010)
>
> Log Message:
> -----------
> 2010-05-26 00:03 UTC+0200 Przemyslaw Czerpak (druzus/at/priv.onet.pl)
> * harbour/contrib/hbwin/Makefile
> + harbour/contrib/hbwin/hbolesrv.c
> + added inproc OLE server implementation. It allows to create OLE/ACTIVEX
> COM server in Harbour. Such OLE server allows can be used by programs
> written in any languages supporting OLE automation (also in other
> Harbour applications)
> User ole server code should be linked as DLL which later can be
> register in MS-Windows by regsvr32.exe program, i.e.:
> regsvr32 myolesrv.dll
> The OLE server code should contain DLLMAIN() PRG function which
> is executed just after loading OLE inproc DLL server as server from
> other application and also by regsrv32.exe during registration and
> unregistration procedure. It has to initialize at least OLE server
> ID and name usinf WIN_OleServerInit().
> + added new PRG function which intitialize OLE server:
> WIN_OleServerInit( <cClassID>, <cServerName>, ;
> [ <hAction> | <oAction> | <bAction> | <sAction> ], ;
> [ <lHashClone> | <lAcceptAll> ] ) -> <lServerActive>
> <cClassID> is registered OLE server class GUID
>
> <cServerName> is OLE server class name
>
> <hAction> is optional parameter with hash array containing messages
> and instance variables used by OLE server. The keys in hash array
> are strings with message names and values are actions. Codeblock
> and symbol items means that given message is a method call and
> any other value means that it's variable.
> By default the same hash array is shared between all objects
> created by registered server. It's important when hash array
> contains values which are neither codeblock nor symbol items
> so they are not used as method but rather as instance variables
> because such instance variables are shared between OLE objects.
> Setting 4-th parameter <lHashClone> to .T. causes that each
> objects receives it's own copy of <hAction> item so instance
> variables inside hash array are also local to OLE object.
> Alternatively programmer can use <bAction> or <sAction> to create
> seprate copy of hash array for each object, i.e.:
> bAction := {|| hb_hClone( hValue ) }
> When hash array contains symbol item (@funcName()) then when it's
> executed by OLE object message it's possible to access the hash
> array bound with given OLE object using QSelf() function. It maybe
> useful if hash array contains instance variables and programmer
> wants to access them.
> Please remember that using hash array which was initialized to keep
> original assign order by HB_HKEEPORDER( <hAction>, .T. ) before
> adding its items you can define strict message numbers (DISPIDs), i.e.:
> hAction := {=>}
> HB_HKEEPORDER( hAction, .T. )
> hAction[ "OPEN" ] := @myole_open() // DISPID=1
> hAction[ "CLOSE" ] := @myole_close() // DISPID=2
> hAction[ "SAVE" ] := @myole_save() // DISPID=3
> hAction[ "LOAD" ] := @myole_load() // DISPID=4
> hAction[ "PRINT" ] := @myole_print() // DISPID=5
> (see example in olesrv2.prg)
>
> <oAction> is optional parameter with Harbour object which is used
> as base for all newly created OLE objects. All messages (method and
> instance variables) supported explicitly by <oAction> object (except
> ONERROR message redirecting) are inherited by OLE objects. Each
> newly created OLE object uses the same <oAction> object so its
> instance variables are shared between all of them. If programmer
> wants to create separate Harbour object for each OLE object then
> he should use <bAction> or <sAction>, i.e.:
> bAction := {|| myClass():new() }
>
> <bAction> is optional parameter with codeblock executed when new
> OLE object is created. It should return hash array or Harbour object
> which will be used as base for newly created OLE object.
>
> <sAction> is optional parameter with function symbol. This function
> is executed when new OLE object is created and should return hash
> array or Harbour object which is used as base for newly created
> OLE object.
>
> If the 3-rd parameter is <oAction>, <bAction> or <sAction> then
> it's possible to also set 4-th parameter <lAcceptAll> to .T. and
> in such case <xAction> parameter is used in different way. Newly
> created OLE object accepts any massage names invoking for each
> of them EVAL() message which is sent to <xAction> with OLE message
> name inserted as the 1-st item to OLE object parameters.
> It allows to create OLE server which will accept unknown messages
> redirecting them to some other code, i.e.:
> if netio_connect( cServer,,, cPasswd )
> WIN_OleServerInit( cClassID, cServerName, @netio_funcExec(), .T. )
> endif
> initialize OLE server which redirects all messages to default netio
> connection establish by netio_connect().
>
> If 3-rd parameter is not given then all HVM functions becomes
> OLE methods and HVM memvars (public and private variables) are
> OLE object instance variables so they are shared with all OLE
> objects created by this interface. It works just like xHarbour.com
> OLE server described at
> http://xharbour.com/index.asp?page=add_on_oleserver&show_sub=7&show_i=1
>
> ; TODO: add support for MT RPC servers. Current implementation cannot
> be safely used in MT programs creating OLE objects and executing
> their methods simultaneously in different threads without
> additional user code which will serialize these operations.
> ; TODO: replace message handler API in WIN_AxGetControl()/
> __AxRegisterHandler() which uses only fixed method IDs
> and do not support method names with above one so user
> can easy create activex controls which support message
> names. This modificaiton will force updating user and 3-rd
> party code but IMO should be done. Current interface is
> simply too much limited to keep it.
> ; Possible TODO: add support for user defined fixed message numbers
> (DISPIDs) which are not continuous small numbers so
> users cannot easy use hash arrays with strict order.
> Is such functionality necessary? Can someone with
> ActiveX experience say sth about it?
> Above implementation has undocumented feature:
> it supports hash arrays with keys using numbers only
> which can be used like in __AxRegisterHandler() but
> I haven't decided yet I should keep, extend or remove
> such functionality.
>
> Please make real life test.
> I do not have any practice with MS-Windows and OLE and most of above
> code I wrote using only documentation so I'm very interesting in real
> test results and user opinions about it. If some important functionality
> is missing then please inform me about it.
> BTW There are some 3-rd party activex implementation for [x]Harbour, i.e.
> xharbour.com or FiveWin ones. Maybe someone familiar with them can create
> PRG compatibility layer for Harbour. I cannot do that myself because I
> do not know that products and their PRG API used in OLE/COM/ActiveX
> implementations but if someone can describe it then I can help in such
> implementation.
>
> + harbour/contrib/hbwin/hbolesrv.def
> + harbour/contrib/hbwin/hbolesrv-mgw.def
> + harbour/contrib/hbwin/hbolesrv-ow.def
> + added .DEF link files which are necessary to correctly export
> inproc OLE server DLL functions. It's possible that other compilers
> or even different versions of the same compilers may use different
> a little bit different .DEF files. I tested above with BCC5.5,
> MinGW 3.4.5 and OpenWatcom 1.8.
>
> + harbour/contrib/hbwin/test/olesrv1.prg
> + harbour/contrib/hbwin/test/olesrv1.hbp
> + harbour/contrib/hbwin/test/oletst1.prg
> + harbour/contrib/hbwin/test/oletst1.hbp
> + added example of NETIO-RPC OLE server code with Harbour (PRG) client.
> This server redirects all messages sent to its OLE objects to remote
> HBNETIO server as function calls. It understands the following
> messages:
> CONNECT() - creates connection to the server, parameters like in
> NETIO_CONNECT() and NETIO_GETCONNECTION() functions
> DISCONNECT() - closes current connection
> PROCEXISTS() - works like NETIO_PROCEXISTS()
> PROCEXEC() - works like NETIO_PROCEXEC()
> PROCEXECW() - works like NETIO_PROCEXECW()
> FUNCEXEC() - works like NETIO_FUNCEXEC()
> All other messages are redirected directly to RPS server as function
> calls.
> CONNECT() message should be executed by client to create
> connection to the server. Each NETIO-RPC OLE object uses its own
> connection which should be initialized. If CONNECT() is executed
> more then once the current connection is closed.
> DISCONNECT() is executed automatically when OLE object is destroyed
> so it's not necessary to call it explicitly.
> Please use hbmk2 and olesrv1.hbp to compile OLE server. OLE inproc
> servers have to export some DLL entry functions which are defined
> in .def files which have to be passed to linker.
> Before client code can be tested the server has to be registered.
> The server can be registered in given MS-Windows system using
> regsvr32.exe command. To register the server use:
> regsvr32 olesrv1.dll
> and to unregister:
> regsvr32 /u olesrv1.dll
>
> + harbour/contrib/hbwin/test/olesrv2.prg
> + harbour/contrib/hbwin/test/olesrv2.hbp
> + harbour/contrib/hbwin/test/oletst2.prg
> + harbour/contrib/hbwin/test/oletst2.hbp
> + added very simple example of OLE server using hash array with
> strict item order (associative hash array) to define OLE objects
> with fixed message numbers (DISPIDs)
> Remember about registering the server by 'regsvr32 olesrv2.dll'
>
> + harbour/contrib/hbwin/test/olesrv3.prg
> + harbour/contrib/hbwin/test/olesrv3.hbp
> + harbour/contrib/hbwin/test/oletst3.prg
> + harbour/contrib/hbwin/test/oletst3.hbp
> + harbour/contrib/hbwin/test/oletst3.bas
> + added example of OLE server code with Harbour (PRG)
> and Visual Basic (BAS) clients.
> This server redirects all messages sent to its OLE objects to HVM
> functions and messages to HVM memver (public and private) variables
> This server should work as xHarbour.com OLE servers described at:
> http://xharbour.com/index.asp?page=add_on_oleserver&show_sub=7&show_i=1
> The server and clients code are nearly the same so users can easy
> compare them.
> Remember about registering the server by 'regsvr32 olesrv2.dll'
>
> Modified Paths:
> --------------
> trunk/harbour/ChangeLog
> trunk/harbour/contrib/hbwin/Makefile
>
> Added Paths:
> -----------
> trunk/harbour/contrib/hbwin/hbolesrv-mgw.def
> trunk/harbour/contrib/hbwin/hbolesrv-ow.def
> trunk/harbour/contrib/hbwin/hbolesrv.c
> trunk/harbour/contrib/hbwin/hbolesrv.def
> trunk/harbour/contrib/hbwin/tests/olesrv1.hbp
> trunk/harbour/contrib/hbwin/tests/olesrv1.prg
> trunk/harbour/contrib/hbwin/tests/olesrv2.hbp
> trunk/harbour/contrib/hbwin/tests/olesrv2.prg
> trunk/harbour/contrib/hbwin/tests/olesrv3.hbp
> trunk/harbour/contrib/hbwin/tests/olesrv3.prg
> trunk/harbour/contrib/hbwin/tests/oletst1.hbp
> trunk/harbour/contrib/hbwin/tests/oletst1.prg
> trunk/harbour/contrib/hbwin/tests/oletst2.hbp
> trunk/harbour/contrib/hbwin/tests/oletst2.prg
> trunk/harbour/contrib/hbwin/tests/oletst3.bas
> trunk/harbour/contrib/hbwin/tests/oletst3.hbp
> trunk/harbour/contrib/hbwin/tests/oletst3.prg
>
>
> This was sent by the SourceForge.net collaborative development platform, the
> world's largest Open Source development site.
> _______________________________________________
> Harbour mailing list (attachment size limit: 40KB)
> [email protected]
> http://lists.harbour-project.org/mailman/listinfo/harbour
_______________________________________________
Harbour mailing list (attachment size limit: 40KB)
[email protected]
http://lists.harbour-project.org/mailman/listinfo/harbour