Page 8 of 23

Posted: Mon Aug 31, 2009 9:50 pm
by Peyman
i find a way with my tool and hunting classes in PB window and change some lines for compatible with dll and worked with all windows not just PB windows.

COMatePlus.pbi :
http://www.easy-share.com/1907569915/COMatePLUS.pbi

and test it with STrainbow.pb examp in OCX demos folder just everywhere you see COMate_CreateActiveXControl you must add one parameter in the first of its argument (Handle of window)

original :

Code: Select all

rainbowObject1 = COMate_CreateActiveXControl(5, 5, 290, 30, "Project1.STprogressBar")
to:

Code: Select all

rainbowObject1 = COMate_CreateActiveXControl(WindowID(0), 5, 5, 290, 30, "Project1.STprogressBar")
but have one problem please see it my created class not exactly show and have a tiny fix, any idea.

Posted: Mon Aug 31, 2009 10:01 pm
by srod
Sorry but I will not help create a dll from my source code because the resulting code will not be compatible with the original source and I do not want to be dragged in to having to effectively maintain two separate code bases.

I will say that exporting the function COMate_CreateActiveXControl() for use in a dll simply needs the addition of a parent window handle and the use of UseGadgetList() etc. Simple. You do NOT under any circumstances need to be installing any hooks to override PB's container gadget! If that is what you are doing then you are on the completely wrong track there.

Posted: Mon Aug 31, 2009 10:16 pm
by netmaestro
peyman wrote:this is very good if this have a dll version for other programming lang
These boards exist to help PureBasic programmers code in PureBasic. You're welcome to do as srod did and create your dll from the same freeware c sources.

Posted: Mon Aug 31, 2009 10:20 pm
by Peyman
no i just remove some lines (purebasic commands and IDContainer) and create a class like purebasic do then CreateWindowEx_ intead of ContainerGadget (i just create a hook on another program for see members of WNDCLASSEX not in COMatePlus.pbi) all of thing i do this :

Code: Select all

 Container.WNDCLASSEX
 Container\cbSize = SizeOf(WNDCLASSEX)
 Container\lpszClassName = @"PureContainer"
 Container\lpfnWndProc = @ContainerCBS()
 Container\hbrBackground = #COLOR_BTNSHADOW
 Container\cbWndExtra = 4

 RegisterClassEx_(Container)

Procedure.i COMate_CreateActiveXControl(Parent, x, y, width, height, progID$, blnInitCOM = #True)
  Protected *this._membersCOMateClass, hResult, id, hWnd, iDisp
CompilerIf Defined(COMATE_NOINCLUDEATL, #PB_Constant)=0
  If progID$
    hWnd = CreateWindowEx_(#Null, @"PureContainer", #Null, #WS_CHILD|#WS_VISIBLE|#WS_CLIPCHILDREN, x, y, width, height, Parent, -1, GetModuleHandle_(0), #Null) 
    If hWnd
      *this = COMate_CreateObject(progID$, hWnd, blnInitCOM) ;This procedure will set any HRESULT codes.
      If *this
        ;SetWindowLongPtr_(hWnd, #GWL_STYLE, GetWindowLongPtr_(hWnd, #GWL_STYLE)|#WS_CLIPCHILDREN)
        *this\hWnd = hWnd
      Else ;Cannot locate an iDispatch interface.
        CloseWindow_(hWnd)
      EndIf
      ProcedureReturn *this
    Else
      hResult = #E_OUTOFMEMORY
    EndIf
  Else
    hresult = #E_INVALIDARG
  EndIf
  CompilerIf Defined(COMATE_NOERRORREPORTING, #PB_Constant)=0
    COMateClass_INTERNAL_SetError(*this, hResult)
  CompilerEndIf
CompilerEndIf
  ProcedureReturn 0
EndProcedure
Anyway thanks.

Posted: Mon Aug 31, 2009 10:24 pm
by srod
You do not need to use CreateWindowEx_().

Something like the following is all you need (untested) :

Code: Select all

Procedure.i COMate_CreateActiveXControl(parenthWnd, x, y, width, height, progID$, blnInitCOM = #True)
  Protected *this._membersCOMateClass, hResult, id, hWnd, iDisp, oldGadList
CompilerIf Defined(COMATE_NOINCLUDEATL, #PB_Constant)=0
  If progID$ And parenthWnd And IsWindow_(parenthWnd)
    oldGadList = UseGadgetList(parenthWnd)
    id = ContainerGadget(#PB_Any, x, y, width, 	height)
    CloseGadgetList()
    UseGadgetList(oldGadList)
    If id
      hWnd = GadgetID(id)
      *this = COMate_CreateObject(progID$, hWnd, blnInitCOM) ;This procedure will set any HRESULT codes.
      If *this
        SetWindowLongPtr_(hWnd, #GWL_STYLE, GetWindowLongPtr_(hWnd, #GWL_STYLE)|#WS_CLIPCHILDREN)
        *this\containerID = ID
        *this\hWnd = hWnd
      Else ;Cannot locate an iDispatch interface.
        FreeGadget(id)
      EndIf
      ProcedureReturn *this
    Else
      hResult = #E_OUTOFMEMORY
    EndIf
  Else
    hresult = #E_INVALIDARG
  EndIf
  CompilerIf Defined(COMATE_NOERRORREPORTING, #PB_Constant)=0
    COMateClass_INTERNAL_SetError(*this, hResult)
  CompilerEndIf
CompilerEndIf
  ProcedureReturn 0
EndProcedure
Note the two uses of UseGadgetList().

Posted: Mon Aug 31, 2009 10:40 pm
by Peyman
wow :shock: :shock:, i cant believe this worked now with other programs, so why u not use this func intead that func ?

Posted: Mon Aug 31, 2009 10:49 pm
by srod
Because I wrote COMate to be used in source code form which, for Purebasic developers, offers a much 'friendlier' interface than would be the case if using a dll version and the adjustment you have made here is but the first of many many such adjustments that you will need to make.

A dll version of COMatePLUS will have to make some serious adjustments in order for the string handling to function correctly without memory leaks and such. The same will be true for some of the functions dealing with variants. The event procedures will have to be reworked quite considerably.

The point is that a lot of COMatePLUS' functions will have to change to such an extent that their parameter lists will need altering (as you have already seen with COMate_CreateActiveXControl()) and the resulting set of functions will not be as easy to use - as is always the case with a dll.

Consider also that COMatePLUS exports an OOP interface to programmers. How many other languages will be able to utilise such an interface? I can think of some which will not be able to make use of such a dll!

My advice, if you really must pursue this, is not to create a dll version of COMatePLUS. Instead, for each target language, create a wrapper dll which exports it's own wrapper functions around the COMatePLUS library. It sounds like more work, but then how many languages are you hoping to target?

Remember that many languages can already do much of what COMatePLUS offers and even where this is not possible, many have already wrapped the DispHelper library upon which the original COMate was based.

I question the need for creating a dll version of COMatePLUS.

Re: COMatePLUS version 1.1

Posted: Thu Sep 17, 2009 3:51 pm
by sverson
Great code! Thanks a lot, srod! :)

Could someone please help me converting this example:

Code: Select all

Set TextPipeApp = CreateObject("TextPipe.Application")
Set Filter = TextPipeApp.newWindow
Filter.openFilter( "C:\MyFilter\MyFilter.fll" )
Filter.execute()
Set Filter = Nothing
Set TextPipeApp = Nothing
I could not find out how to convert these two lines: :?
Filter.openFilter( "C:\MyFilter\MyFilter.fll" )
Filter.execute()

Code: Select all

IncludePath "COMatePLUS\"
XIncludeFile "COMatePLUS.pbi"

Global TextPipeObject.COMateObject, FilterObject.COMateObject

TextPipeObject = COMate_CreateObject("TextPipeEngine.Application")
If TextPipeObject
  FilterObject = TextPipeObject\GetObjectProperty("newWindow")
  If FilterObject
???    FilterObject\Invoke("openFilter('C:\MyFilter\MyFilter.fll')")
    FilterObject\Release()
  EndIf
  TextPipeObject\Release()
EndIf

Re: COMatePLUS version 1.1

Posted: Thu Sep 17, 2009 4:33 pm
by srod
Is the FilterObject\Invoke("openFilter('C:\MyFilter\MyFilter.fll')") line throwing an error?

You haven't added the FilterObject\Invoke("Execute") command!

If you suspect a problem then place a 'Debug' at the beginning of the line FilterObject\Invoke("openFilter('C:\MyFilter\MyFilter.fll')") etc. A non-zero return means an error.

Re: COMatePLUS version 1.1

Posted: Thu Sep 17, 2009 5:54 pm
by sverson
Well - I'm the mule :wink:
srod wrote:You haven't added the FilterObject\Invoke("Execute") command!
Thanks a lot!

It's runnning now!

Re: COMatePLUS version 1.1

Posted: Thu Sep 17, 2009 5:56 pm
by srod
sverson wrote:Well - I'm the mule :wink:
I wasn't going to say it myself, but, now that you've rasied the point... :wink:

Re: COMatePLUS version 1.1

Posted: Sun Sep 20, 2009 8:05 pm
by DoubleDutch
In the pdf example to reference a file called: COMTutorial.pdf

Is there a link somewere to this file? It sounds like a good read....

Re: COMatePLUS version 1.1

Posted: Sun Sep 20, 2009 8:13 pm
by srod
It is the basic tutorial that Freak released ages ago. A search of these forums should locate it.

Re: COMatePLUS version 1.1

Posted: Sun Sep 20, 2009 10:10 pm
by DoubleDutch
Thanks, found it. :)

Re: COMatePLUS version 1.1

Posted: Mon Sep 21, 2009 8:08 pm
by sverson
Is there a way using COMatePLUS inside a thread?

Code: Select all

IncludePath "COMatePLUS\"
XIncludeFile "COMatePLUS.pbi"

Procedure StartFilter(MyFilter$)
  Protected TextPipeObject.COMateObject, FilterObject.COMateObject
  TextPipeObject = COMate_CreateObject("TextPipeEngine.Application")
  If TextPipeObject
    FilterObject = TextPipeObject\GetObjectProperty("newWindow")
    If FilterObject
      FilterObject\Invoke("openFilter('"+MyFilter$+"')")
      FilterObject\Invoke("execute")
      FilterObject\Release()
      MessageRequester("MyFilter:","openFilter('"+MyFilter$+"')")
    Else
      MessageRequester("ERROR","No FilterObject!") 
    EndIf
    TextPipeObject\Release()
  Else 
    MessageRequester("ERROR","No Object!")
  EndIf
EndProcedure

Procedure MyThread(null)
  StartFilter("Y:\MyFilter.fll")
EndProcedure

OpenConsole()
ConsoleTitle("COMatePLUS - textpipeengine.dll")
PrintN("[a] - Call: CreateThread(@MyThread(),0)")
PrintN("[b] - Call: MyThread(0)")
Select Input()
  Case "a"
    CreateThread(@MyThread(),0)
  Case "b"
    MyThread(0)
EndSelect
PrintN("Press return to exit")
Input()
CloseConsole()
Calling MyThread(0) or StartFilter("Y:\MyFilter.fll") everything is OK. :)
BUT when I call CreateThread(@MyThread(),0) there will be a Runtime error 217 on exit. :?

I can call CreateThread(@MyThread(),0) more then once without any error - execution is OK - but there will allways be the Runtime error 217 on exit.