Seite 8 von 12

Verfasst: 24.02.2006 20:12
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

Verfasst: 24.02.2006 20:35
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

Verfasst: 24.02.2006 23:20
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


Verfasst: 24.02.2006 23:44
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.

Verfasst: 25.02.2006 00:21
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.

Verfasst: 25.02.2006 00:24
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:

Verfasst: 25.02.2006 00:27
von mk-soft
Sehe ich auch so.
Solange das Dispinterface nicht öffentlich ist kann man mal andere Programmierer fragen wie das Interface aufgebaut ist.

Verfasst: 25.02.2006 00:52
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:

Verfasst: 25.02.2006 01:04
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?

Verfasst: 25.02.2006 01:17
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: