Przemek, Thank you. A new hit in harbour life.
dru...@users.sourceforge.net escribió en mensaje ... >Revision: 14593 > http://harbour-project.svn.sourceforge.net/harbour-project/?rev=14593&view=r ev >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) Harbour@harbour-project.org http://lists.harbour-project.org/mailman/listinfo/harbour