OCX und das, mit dem Cocreate usw.

Anfängerfragen zum Programmieren mit PureBasic.
Benutzeravatar
mk-soft
Beiträge: 3855
Registriert: 24.11.2004 13:12
Wohnort: Germany

Beitrag von mk-soft »

Ok,

File CreateObject.pb

Code: Alles auswählen

Enumeration
  #CLSCTX_INPROC_SERVER  = 1
  #CLSCTX_INPROC_HANDLER = 2
  #CLSCTX_LOCAL_SERVER   = 4
  #CLSCTX_REMOTE_SERVER  = 16
  #CLSCTX_SERVER = (#CLSCTX_INPROC_SERVER | #CLSCTX_LOCAL_SERVER | #CLSCTX_REMOTE_SERVER)
EndEnumeration

Structure TYPEATTR
  guid.GUID
  lcid.l
  dwReserved.l
  memidConstructor.l
  memidDestructor.l
  lpstrSchema.l
  cbSizeInstance.l
  typekind.l
  cFuncs.w
  cVars.w
  cImplTypes.w
  cbSizeVft.w
  cbAlignment.w
  wTypeFlags.w
  wMajorVerNum.w
  wMinorVerNum.w
  tdescAlias.l
  idldescType.l
EndStructure

Global LastMessage.s
Global LastError.l

ProcedureDLL.s Uni2Ansi(unicodestr.l) ; Converts Unicode to normal (Ansi) string
  lenA = WideCharToMultiByte_(#CP_ACP, 0, unicodestr, -1, 0, 0, 0, 0);
  ansistr.s = Space(lenA)
  If (lenA > 0)
    WideCharToMultiByte_(#CP_ACP, 0, unicodestr, -1, @ansistr, lenA, 0, 0);
  EndIf
  ProcedureReturn ansistr
EndProcedure

ProcedureDLL.l Ansi2Uni(ansistr.s) ; Converts normal (Ansi) string to Unicode
  lenA.l = Len(ansistr)
  lenW = MultiByteToWideChar_(#CP_ACP, 0, ansistr, lenA, 0, 0)
  If (lenW > 0) ; Check whether conversion was successful
    unicodestr = SysAllocStringLen_(0, lenW)
    MultiByteToWideChar_(#CP_ACP, 0, ansistr, lenA, unicodestr, lenW)
    result = unicodestr
    ProcedureReturn result
  Else
    ProcedureReturn 0
  EndIf
EndProcedure

ProcedureDLL.l CreateObject(ProgID.s) ; Creates COM object from ProgID

  err.l = CLSIDFromProgID_(Ansi2Uni(ProgID), @CLSID.GUID)
  If err <> #S_OK
    LastMessage = "Error: CLSIDFromProgID. Errorcode: " + Hex(err)
    LastError = err
    ProcedureReturn 0
  EndIf

  err.l = CoCreateInstance_(CLSID,0,#CLSCTX_SERVER,?IID_IDispatch,@oDispatch.IDispatch)
  If err <> #S_OK
    LastMessage = "Error: CoCreateInstance. Errorcode: " + Hex(err)
    LastError = err
    ProcedureReturn 0
  EndIf

  If oDispatch\GetTypeInfo(0,lcid,@oDispTypeInfo.ITypeInfo) = #S_OK
    If oDispTypeInfo\GetTypeAttr(@aTypeAttributes.l) = #S_OK
      *oTypeAttributes.TYPEATTR=aTypeAttributes
      IID_OBJECT = *oTypeAttributes\guid
      oDispTypeInfo\ReleaseTypeAttr(aTypeAttributes)
    EndIf
    oDispTypeInfo\Release()
  EndIf

  err.l = oDispatch\QueryInterface(IID_OBJECT,@object.l)
  If err <> #S_OK
    oDispatch\Release()
    LastMessage = "Error: QueryInterface. Errorcode: " + Hex(err)
    LastError = err
    ProcedureReturn 0
  EndIf
  oDispatch\Release()
  
  LastMessage = "CreateObject:" + ProgID
  LastError = err
  ProcedureReturn object
EndProcedure

ProcedureDLL ReleaseObject(object.l) ; Releases Object from memory
  *object.IUnknown = object
  *object\Release()
EndProcedure

ProcedureDLL COMLIB_Init()
  CoInitialize_(#Null)
EndProcedure

ProcedureDLL COMLIB_End()
  CoUninitialize_() 
EndProcedure

DataSection
  IID_IDispatch:
  Data.l $00020400
  Data.w $0000, $0000
  Data.b $C0,$00,$00,$00,$00,$00,$00,$46
EndDataSection
 
DataSection
  IID_IUnknown:
  Data.l $00000000
  Data.w $0000, $0000
  Data.b $C0,$00,$00,$00,$00,$00,$00,$46
EndDataSection 
File ADUSB.pb

Code: Alles auswählen


IncludeFile "CreateObject.pb"


Interface AD_USB2XX Extends IDispatch
  Scan(DeviceNr.w); boolean (Long)
  AnalogVoltage(DeviceNr.w, Channel.w); Double
  AnalogVoltage2(DeviceNr.w, Channel.w, rhs.double); Void
  DigIO(DeviceNr.w); short
  DigIO2(DeviceNr.w, rhs.w); void
  GetAnalogDiffVoltage(DeviceNr.w,Channel.w); Double
  GetDeviceType(DeviceNr.w); short
  GetError(DeviceNr.w); short
  GetSerialNr(DeviceNr.w); short
  AnalogIO(DeviceNr.w, Channel.w); long
  AnalogIO2(DeviceNr.w, Channel.w, rhs.l); void
  EnableCalibration(*Password); BSTR Unicode ; 
  Calibration(DeviceNr.w, IO.w, Level.w, Channel.w); long
  Calibration2(DeviceNr.w, IO.w, Level.w, Channel.w, rhs.l); void
  SerialNr(DeviceNr.w); short
  SerialNr2(DeviceNr.w, rhs.w); void
  ReadAnalogVoltage(DeviceNr.w, Channel.w); double
  WriteAnalogVoltage(DeviceNr.w, Channel.w, Voltage.double); void
  ReadDigIn(DeviceNr.w); short
  WriteDigOut(DeviceNr.w, Value.w); void
  DataIO(DeviceNr.w); void
  Close(); void
EndInterface

COMLIB_Init()

*Object.AD_USB2XX = CreateObject("ADUSB2XX.ADUSB2XXCtrl.1")

r1 = *Object\Scan(0)

ReleaseObject(*Object)

COMLIB_End()

Bei mir Funktioniert er auch nicht. Invalid memory access
Alles ist möglich, fragt sich nur wie...
Projekte ThreadToGUI / EventDesigner V3 / OOP-BaseClass-Modul
Downloads auf MyWebspace / OneDrive
Benutzeravatar
Falko
Admin
Beiträge: 3535
Registriert: 29.08.2004 11:27
Computerausstattung: PC: MSI-Z590-GC; 32GB-DDR4, ICore9; 2TB M2 + 2x3TB-SATA2 HDD; Intel ICore9 @ 3600MHZ (Win11 Pro. 64-Bit),
Acer Aspire E15 (Win11 Home X64). Purebasic LTS 6.11b1
HP255G8 Notebook @AMD Ryzen 5 5500U with Radeon Graphics 2.10 GHz 3.4GHz, 32GB_RAM, 3TB_SSD (Win11 Pro 64-Bit)
Kontaktdaten:

Beitrag von Falko »

Danke, ich habe die Variants_inc.pb auch per Include hinzugefügt. Vorher aber die Structure DOUBLE aber auskommentiert und in PB4 probiert.
Aber ich bleibe leider auch trotz angeschlossener Hardware beim IMA hängen und zwar genau beim
Funktionsaufruf r1 = *Object\Scan(0).
Das die OCX richtig aufgerufen wird, hatte mir DarkDragon schon per ICQ angezeigt, weil bei ihm die OCX sowie der USB-Treiber nicht installiert war.

Siehe folgende Error-Message:
---------------------------
AD_USB~1
---------------------------
Error: Can't Load Ftd2xx.dll
---------------------------
OK
---------------------------
Das ist der eigendliche Treiber um per USB auf das Modul zugreifen zu
können, welches über die OCX geschieht.


MfG Falko
Bild
Win11 Pro 64-Bit, PB_6.11b1
Benutzeravatar
mk-soft
Beiträge: 3855
Registriert: 24.11.2004 13:12
Wohnort: Germany

Beitrag von mk-soft »

Ok,
Der Fehler liegt im aufbau des Interfaces. Da das Dispinterface als "hidden" declariert ist kann diese nicht mit Interface-Generator exportiert werden.
Also ist das vobn Hand geschiebene Interface nicht Ok. Die Anzahl der zu übergebende Parameter kann unterschiedlich sein zu der angegebenden anzahl von ein Parameter.

Code: Alles auswählen


IncludeFile "CreateObject.pb"

Interface AD_USB2XX Extends IDispatch
  Scan(DeviceNr.w); boolean (Long)
  AnalogVoltage(DeviceNr.w, Channel.w); Double
  AnalogVoltage2(DeviceNr.w, Channel.w, rhs.double); Void
  DigIO(DeviceNr.w); short
  DigIO2(DeviceNr.w, rhs.w); void
  GetAnalogDiffVoltage(DeviceNr.w,Channel.w); Double
  GetDeviceType(DeviceNr.w); short
  GetError(DeviceNr.w); short
  GetSerialNr(DeviceNr.w); short
  AnalogIO(DeviceNr.w, Channel.w); long
  AnalogIO2(DeviceNr.w, Channel.w, rhs.l); void
  EnableCalibration(*Password); BSTR Unicode ; 
  Calibration(DeviceNr.w, IO.w, Level.w, Channel.w); long
  Calibration2(DeviceNr.w, IO.w, Level.w, Channel.w, rhs.l); void
  SerialNr(DeviceNr.w); short
  SerialNr2(DeviceNr.w, rhs.w); void
  ReadAnalogVoltage(DeviceNr.w, Channel.w); double
  WriteAnalogVoltage(DeviceNr.w, Channel.w, Voltage.double); void
  ReadDigIn(DeviceNr.w); short
  WriteDigOut(DeviceNr.w, Value.w); void
  DataIO(DeviceNr.w); void
  Close(); void
EndInterface


COMLIB_Init()

*Object.IDispatch = CreateObject("ADUSB2XX.ADUSB2XXCtrl.1")

Debug LastMessage

r1 = *Object\QueryInterface(?IID__DAD_USB2XX, @*MyEvent.IDispatch)
If r1 <> #S_OK
  End
EndIf
  
r1 = *Object\QueryInterface(?IID__DAD_USB2XX, @*MyObject.AD_USB2XX)
If r1 <> #S_OK
  End
EndIf
  
r1 = *MyObject\Scan(0)

ReleaseObject(*Object)

COMLIB_End()

DataSection
  IID__DAD_USB2XX: ; BFD9E61F-75C4-4B33-8949-73A64F014514
  Data.l $BFD9E61F
  Data.w $75C4,$4B33
  Data.b $89,$49,$73,$A6,$4F,$01,$45,$14
  IID__DAD_USB2XXEvents: ; 9A894BB7-0F68-429D-A30A-FCE4F6379D78
  Data.l $BFD9E61F
  Data.w $75C4,$4B33
  Data.b $89,$49,$73,$A6,$4F,$01,$45,$14
EndDataSection

Alles ist möglich, fragt sich nur wie...
Projekte ThreadToGUI / EventDesigner V3 / OOP-BaseClass-Modul
Downloads auf MyWebspace / OneDrive
Benutzeravatar
Falko
Admin
Beiträge: 3535
Registriert: 29.08.2004 11:27
Computerausstattung: PC: MSI-Z590-GC; 32GB-DDR4, ICore9; 2TB M2 + 2x3TB-SATA2 HDD; Intel ICore9 @ 3600MHZ (Win11 Pro. 64-Bit),
Acer Aspire E15 (Win11 Home X64). Purebasic LTS 6.11b1
HP255G8 Notebook @AMD Ryzen 5 5500U with Radeon Graphics 2.10 GHz 3.4GHz, 32GB_RAM, 3TB_SSD (Win11 Pro 64-Bit)
Kontaktdaten:

Beitrag von Falko »

Aber lt. der Readme AD-USB.txt vom Programmierer Friedrich Lorenz
der Fa. Lorenz GmbH sind doch die Anzahl und der Aufruf der Objekte
insoweit richtig vorhanden. Wenn die stimmen, sollte es doch egal sein,
ob die hidden sind. Oder verstehe ich das etwa falsch?
Wenn es in VB funktioniert, dann müsste es doch auch in PB gehen. Es sei
denn, PB4 unterstützt keine hidden Dispinterfaces oder ähnliches.
Dann habe ich natürlich keine Chance was darüber zu steuern.
Eigendlich Schade drum. Aber ich möchte mich trotzdem für den Einsatz
hier im forum bei allen bedanken, die versucht haben hierzu eine Lösung
zu finden.

Es ist eben doch schwieriger in PB4 sowas anzustellen, als ich gedacht hatte. :roll:

Hier noch der Originalauszug aus der Readme.
Beschreibung des Steuerelementes AD_USB.OCX
===========================================

Bei der Installation von Monitor wird auf Ihrem System
automatisch ein ActiveX-Steuerelement installiert und registriert,
mit dem Sie mit selbst entwickelter Software auf des Gerät zugreifen
können.
Dieses Steuerlement beinhaltet auch den Windows-Treiber, der WDM-
konform für die Betriebssysteme Win98 und Win2000 realisiert ist.

Dieses Steuerelement kann in Ihren eigenen Programmen benutzt werden.
Das Steuelement wurde in VC++ Version 6 entwickelt, und kann in allen
Entwicklungsumgebungen eingesetzt werden, die Steuerelemente
unterstützen.

Beschreibung der Methoden und Eigenschaften
===========================================

1. BOOL Scan (short Adr)
Mit der Methode Scan kann ermittelt werden, ob ein AD-USB am
PC angeschlossen ist. Es wird nach dem Gerät mit der überge-
benen Adresse gesucht. Der zulässige Bereich für Adr liegt
zwischen 0 und 126. Wird ein Gerät unter dieser Adr gefunden
liefert die Methode TRUE. Mit Scan können auch mehrere AD-USBs
am PC lokalisiert werden. Diese Methode muß immer zuerst benutzt
werden, bevor mit einem Gerät kommuniziert werden kann.
Bei allen nachfolgenden Methoden und Eigenschaften muß die Adresse
des Gerätes als 1. Parameter übergeben werden.

2. short GetSerialNr (short Adr)
Mit dieser Methode können Geräte identifiziert werden, falls
mehrere Geräte gleichzeitig am PC betrieben werden. Die Geräte
müssen vorher mit Scan gefunden worden sein.

3. short GetDeviceType (short Adr)
Mit dieser Methode kann unterschieden werden, welcher Gerätetyp
unter übergebener Adr gefunden wurde. Rückgaben 1 oder 2.

4. BOOL GetError (short Adr)
Nach jeder Kommunikation mit dem AD-USB kann überprüft werden,
ob die Kommunikation erfolgreich war. Liefert diese Methode die
Rückgabe TRUE, so liegt eine Kommunikationsstörung zwischen Gerät
und PC vor.

5. short DigIO (short Adr, short NewValue)
Übermittelt die Signalzustände der digitalen Ein-/Ausgänge als
short zwischen PC und AD-USB.

6. long AnalogIO (short Adr, short Cha, long NewValue)
Übermittelt die Signalzustände der analogen Ein-/Ausgänge als
long zwischen PC und AD-USB. Cha ist die Kanalnummer und muß bei
den analogen Eingängen zwischen 0 und 7 liegen, bei den analogen
Ausgängen 0 oder 1.

Meßwert Ergebnis AD-USB 3
10V ca. 4000
0V 2048
-10V ca. 100


7. double AnalogVoltage (short Adr, short Cha, double NewValue)
Um sich die Unterscheidung der Gerätevarianten zu erleichtern und den
Spannungswert der Ein- und Ausgänge direkt in Volt bearbeiten kann diese
Eigenschaft benutzt werden. Sie arbeitet identisch zu AnalogIO, aber die
Ein-/Ausgangswerte werden als double-Wert direkt in Volt ausgetauscht.

8. double ReadAnalogVoltage(short DeviceNr, short Channel)
Liest den Eingangskanal aus dem Steuerelement (nicht aus dem AD-USB),
ohne einen Datenaustausch mit dem AD-USB durchzuführen. Diese Methode
empfielt sich um nach dem Aufruf von DataIO (siehe unten) die Werte
möglichst schnell einzulesen.

9. short ReadDigIn(short DeviceNr)
Liest die digitalen Eingangskanäle aus dem Steuerelement (nicht aus dem AD-USB),
ohne einen Datenaustausch mit dem AD-USB durchzuführen. Diese Methode
empfielt sich um nach dem Aufruf von DataIO (siehe unten) die Werte
möglichst schnell einzulesen.

10. void WriteAnalogVoltage(short DeviceNr, short Channel, double Voltage)
Schreibt einen Ausgangswert in das Steuerelement. Der Wert wird nur im
Steuerelement gespeichert, nicht an das AD-USB übertragen. Beim nächsten
Aufruf von DataIO wird der Wert am Analogausgang des Gerätes sichtbar.

11. void WriteDigOut(short DeviceNr, short Value)
Schreibt die digitalen Ausgangswerte in das Steuerelement. Der Wert wird nur im
Steuerelement gespeichert, nicht an das AD-USB übertragen. Beim nächsten
Aufruf von DataIO wird der Wert an den digitalen Ausgängen des Gerätes sichtbar.

12. void DataIO(short DeviceNr)
Es wird ein kompletter Datenaustausch zwischen dem PC und dem AD-USB
durchgeführt. Die Daten, die mit den Methoden 10 und 11 vorher in dem
Steuerelement gespeichert wurden, werden zum Gerät übermittelt. Gleichzeitig
erhält der PC mit dem Datenaustausch alle Eingangswerte des Gerätes. Diese
Werte sind dann mit den Methoden 8 und 9 aus dem Steuerlement entnehmbar, ohne
einen weiteren Austausch durchzuführen.
Um möglichst hohe Datendurchsätze zu erzielen, empfielt es sich die Methoden
8 bis 10 zu verwenden.

13. void Close (void)
Die Verbindung zu allen geöffneten Geräten wird geschlossen.
Bild
Win11 Pro 64-Bit, PB_6.11b1
Benutzeravatar
mk-soft
Beiträge: 3855
Registriert: 24.11.2004 13:12
Wohnort: Germany

Beitrag von mk-soft »

Nach VB Schon.

Sonst:

HRESULT = Object\Scan([IN] Adr, [OUT] Result)

Hatte eine Beschreibung für eine Funktion mit 2 Parameter.
Interface-Generator hatte 5 Parameter im Interface erzeugt.
Alles ist möglich, fragt sich nur wie...
Projekte ThreadToGUI / EventDesigner V3 / OOP-BaseClass-Modul
Downloads auf MyWebspace / OneDrive
Benutzeravatar
ts-soft
Beiträge: 22292
Registriert: 08.09.2004 00:57
Computerausstattung: Mainboard: MSI 970A-G43
CPU: AMD FX-6300 Six-Core Processor
GraKa: GeForce GTX 750 Ti, 2 GB
Memory: 16 GB DDR3-1600 - Dual Channel
Wohnort: Berlin

Beitrag von ts-soft »

>> und kann in allen Entwicklungsumgebungen eingesetzt werden, die Steuerelemente unterstützen.

Also kannst Du es nur mit der ActiveXLib probieren. Das ocx muß in einen
"Container" gepackt werden, damit es funzt. Da kann man ja lange probieren
:mrgreen:
PureBasic 5.73 LTS | SpiderBasic 2.30 | Windows 10 Pro (x64) | Linux Mint 20.1 (x64)
Nutella hat nur sehr wenig Vitamine. Deswegen muss man davon relativ viel essen.
Bild
Benutzeravatar
mk-soft
Beiträge: 3855
Registriert: 24.11.2004 13:12
Wohnort: Germany

Beitrag von mk-soft »

Sehe ich auch so.
Solange das Dispinterface nicht öffentlich ist kann man mal andere Programmierer fragen wie das Interface aufgebaut ist.
Alles ist möglich, fragt sich nur wie...
Projekte ThreadToGUI / EventDesigner V3 / OOP-BaseClass-Modul
Downloads auf MyWebspace / OneDrive
Benutzeravatar
Falko
Admin
Beiträge: 3535
Registriert: 29.08.2004 11:27
Computerausstattung: PC: MSI-Z590-GC; 32GB-DDR4, ICore9; 2TB M2 + 2x3TB-SATA2 HDD; Intel ICore9 @ 3600MHZ (Win11 Pro. 64-Bit),
Acer Aspire E15 (Win11 Home X64). Purebasic LTS 6.11b1
HP255G8 Notebook @AMD Ryzen 5 5500U with Radeon Graphics 2.10 GHz 3.4GHz, 32GB_RAM, 3TB_SSD (Win11 Pro 64-Bit)
Kontaktdaten:

Beitrag von Falko »

ts-soft hat geschrieben:>> und kann in allen Entwicklungsumgebungen eingesetzt werden, die Steuerelemente unterstützen.

Also kannst Du es nur mit der ActiveXLib probieren. Das ocx muß in einen
"Container" gepackt werden, damit es funzt. Da kann man ja lange probieren
:mrgreen:
Ich hab damit gerechnet, daß du diese Antwort schreibst. :mrgreen:
Bild
Win11 Pro 64-Bit, PB_6.11b1
Benutzeravatar
ts-soft
Beiträge: 22292
Registriert: 08.09.2004 00:57
Computerausstattung: Mainboard: MSI 970A-G43
CPU: AMD FX-6300 Six-Core Processor
GraKa: GeForce GTX 750 Ti, 2 GB
Memory: 16 GB DDR3-1600 - Dual Channel
Wohnort: Berlin

Beitrag von ts-soft »

Dann sag doch gleich, das es ein Steuerelement ist, also etwas sichtbares,
dann hätte man sich die Tests mit ComLib sparen können :mrgreen:

Und schon getestet mit der ActiveXLib?
PureBasic 5.73 LTS | SpiderBasic 2.30 | Windows 10 Pro (x64) | Linux Mint 20.1 (x64)
Nutella hat nur sehr wenig Vitamine. Deswegen muss man davon relativ viel essen.
Bild
Benutzeravatar
Falko
Admin
Beiträge: 3535
Registriert: 29.08.2004 11:27
Computerausstattung: PC: MSI-Z590-GC; 32GB-DDR4, ICore9; 2TB M2 + 2x3TB-SATA2 HDD; Intel ICore9 @ 3600MHZ (Win11 Pro. 64-Bit),
Acer Aspire E15 (Win11 Home X64). Purebasic LTS 6.11b1
HP255G8 Notebook @AMD Ryzen 5 5500U with Radeon Graphics 2.10 GHz 3.4GHz, 32GB_RAM, 3TB_SSD (Win11 Pro 64-Bit)
Kontaktdaten:

Beitrag von Falko »

ts-soft hat geschrieben:Dann sag doch gleich, das es ein Steuerelement ist, also etwas sichtbares,
dann hätte man sich die Tests mit ComLib sparen können :mrgreen:

Und schon getestet mit der ActiveXLib?
Ich hatte das schon mal versucht. Wie fängt man deiner Meinung nach das mit den Scripts an? Vielmehr verstehe ich aus den Beispielen nicht. Leider :oops:


Das mit den Steuerelementen, wenn du das auf der obigen Readme beziehst hatte ich jemanden schon gepostet. Du wolltest OCX-Kram ja nicht haben :mrgreen: . Also gesagt, bzw. in der geschriebenen Version hatte ich es schon verschickt. :mrgreen:
Zuletzt geändert von Falko am 25.02.2006 02:23, insgesamt 1-mal geändert.
Bild
Win11 Pro 64-Bit, PB_6.11b1
Antworten