Author Topic: COM  (Read 2732 times)

0 Members and 1 Guest are viewing this topic.

John

  • Hero Member
  • *****
  • Posts: 3830
Re: COM
« Reply #45 on: November 15, 2020, 05:35:05 PM »
I was able to get the Speak_String function to return an error.

Code: Script BASIC
  1. ' DLLC SAPI5
  2.  
  3. IMPORT dllc.sbi
  4.  
  5. sapi = dllfile("tts.dll")
  6.  
  7. Begin_Speech = dllproc(sapi, "Begin_Speech i = (i bufsz)")
  8. Speak_String = dllproc(sapi, "Speak_String i = (i usetxt, c *vtxt, i clrbuf, i vidx, i nttsa, i udv, i vol, i udp, i pitch, i uds, i speed)")
  9. End_Speech   = dllproc(sapi, "End_Speech ()")
  10.  
  11.  
  12. rtn = dllcall(Begin_Speech, 5000)
  13. PRINT "Begin_Speech = ", rtn,"\n"
  14.  
  15. rtn = dllcall(Speak_String,0,"Hello World",1,0,1,0,0,0,0,0,0)
  16. PRINT "Speak_String = ", rtn, "\n"
  17.  
  18. dllcall(End_Speech)
  19.  
  20. dllfile
  21.  


C:\ScriptBASIC\examples>sbc dllc_com.sb
Begin_Speech = 1
Speak_String = 0

C:\ScriptBASIC\examples>


I can't believe Theo would post a library reference and not even test if it works on current OS versions.  :-[
« Last Edit: November 17, 2020, 07:51:51 PM by John »

Charles Pegge

  • Admin Support Member
  • *****
  • Posts: 4427
    • Oxygen Basic
Re: COM
« Reply #46 on: November 16, 2020, 02:38:18 PM »
Hi John,

speak will run in a thread. I do this in ProjectsA\speech\speech2.o2bas. I expect most COM interface methods will tolerate being in a thread

But speak is also capable of running asynchronously without requiring a thread. This is done by adding an extra arg '1'. voice.speak "hello ...",1

But I was unable to go asynchronous using iDispatch. I don't have a typelib browser and can't find the properties or methods  for automation ispVoice, to check for alternatives.

John

  • Hero Member
  • *****
  • Posts: 3830
Re: COM
« Reply #47 on: November 16, 2020, 09:18:44 PM »
Have you tried Jose Roca's typelib viewer?

I'm not a member of the JRS forum so I can't download attachments. Please post the latest here so I can update my version.

« Last Edit: November 17, 2020, 10:29:14 AM by John »

John

  • Hero Member
  • *****
  • Posts: 3830
Re: COM
« Reply #48 on: November 17, 2020, 12:25:08 PM »
If you have VB6 it comes with a typelib viewer.

John

  • Hero Member
  • *****
  • Posts: 3830
Re: COM
« Reply #49 on: November 17, 2020, 05:34:23 PM »
This works in VB6 as a button click event.

Code: Visual Basic
  1. Private Sub Command1_Click()
  2.   Dim Voice As SpVoice
  3.   Set Voice = New SpVoice
  4.   Voice.Speak "Hello World"
  5. End Sub
  6.  

I exported from OLEview to an .idl file with the SAPI COM object info. This file is readable in a text editor.
« Last Edit: November 17, 2020, 07:48:36 PM by John »

Charles Pegge

  • Admin Support Member
  • *****
  • Posts: 4427
    • Oxygen Basic
Re: COM
« Reply #50 on: November 20, 2020, 02:42:08 AM »
Thanks John,

JosÚs TypeLib Browser is an excellent tool. It provides all the interfacing details you need. The virtual table offsets can be used to access the required functions generically without a header.

CallByOffset
Code: [Select]
  uses  COM/COMutil
  CoInitialize null
  CreateGuid clsid "96749377-3391-11D2-9EE3-00C04F797396" 'SAPI
  CreateGuid iid   "6C44DF74-72B9-4992-A1EC-EF996E0422D4" 'IspVoice
  VirtualInterface *voice
  err=CoCreateInstance clsid, null, context, iid, @voice
  CallByOffset voice(80) (L"Hello World",1,0) 'speak async
  print "ok" 'pause required before ending
  CallByOffset voice(8) () 'release
  CoUninitialize

John

  • Hero Member
  • *****
  • Posts: 3830
Re: COM
« Reply #51 on: November 20, 2020, 02:54:33 AM »
Sweet!

I hope you're having as much fun as I did playing with OLE automation.

VirtualInterface seems to answer my question about pasing iUnknown (object) pointers as arguments.

In the Sage accounting software ole automation interface it has a CreateObject call which often uses a previously created object as an argument to provide inherent use.

Take another peek at my example I posted to show this in use. Mike saved the day and added this feature (along with couple other improvements) that wasn't functional where Dave left off. Without this ability I can't access the Sage software which I personally do a lot of work with. My current project is using this feature in ScriptBasic.
« Last Edit: November 20, 2020, 08:48:44 PM by John »

John

  • Hero Member
  • *****
  • Posts: 3830
Re: COM
« Reply #52 on: November 21, 2020, 01:48:01 PM »
Charles,

Is using i for integer with DLLC to define a DWORD argument correct? Windows uses a lot of DWORD references. I was thinking p for pointer would be a better choice.
« Last Edit: November 22, 2020, 11:15:37 AM by John »

John

  • Hero Member
  • *****
  • Posts: 3830
Re: COM
« Reply #53 on: November 25, 2020, 12:03:41 PM »
Charles,

Basically I need to pass returned LONG object pointers as VT_DISPATCH type for the Sage CreateOject method. That's why Mike used SET.