Tapi3 ... Mal wieder ärger mit Events

  • VB.NET

Es gibt 9 Antworten in diesem Thema. Der letzte Beitrag () ist von SlashMcKagen.

    Tapi3 ... Mal wieder ärger mit Events

    Hallo,
    ich habe nun schon zum zweiten Mal ärger mit Events. Sollte ich genau das selbe wieder falsch machen, so verzeiht es mir bitte, habe dann wohl einfach noch nicht genug aus meinem Fehler gelernt.
    Das Problem, bei dem mir schon geholfen wurde, ist dieses: [VB 2008] Problem mit COM Komponente in Zusammenhang mit mehren Handles (HRESULT: 0x80040202)
    Jetzt aber zu meinem neuen Problem. Es geht um eine Anruferkennung mittels Tapi3 in VB2008.
    Ich habe mir schon einige Beispiele dazu angeschaut (ich behaupte einfach mal alle, die sich über google finden lassen) aber laufen tut es bei mir immernoch nicht.
    Aus den vielen Beispielen habe ich mir einen Code zurechtgebastelt, um einfach zu sehen, wie das alles funktioniert.
    Dabei habe ich folgendes Problem: Das Event: TE_CALLSTATE funktioniert, soweit ich das beurteilen kann, problemlos.
    Alle anderen Events werden nicht ausgelöst.
    Doch hier nun erstmal mein Test-Code:

    VB.NET-Quellcode

    1. Imports TAPI3Lib
    2. Public Class Form1
    3. Public Const MediaAudio As Integer = 8
    4. Public Const MediaModem As Integer = 16
    5. Public Const MediaFax As Integer = 32
    6. Public Const MediaVideo As Integer = 32768
    7. Public WithEvents oTAPI As TAPI3Lib.TAPI
    8. Public oAddress As ITAddress ' will hold our selected address (you can hold many address in an array)
    9. Public RegCookie As Integer
    10. Private Sub Form1_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
    11. Dim m_TAPI As New TAPIClass ' creating a new instance to first initialize TAPI befor attaching the events
    12. Dim MediaTypes As Integer ' a variable to hold supported media types for the address
    13. m_TAPI.Initialize() ' initializing TAPI
    14. oTAPI = m_TAPI ' attaching event sink
    15. m_TAPI = Nothing
    16. Dim AddressCollection As ITCollection = oTAPI.Addresses()
    17. For Each Address As ITAddress In AddressCollection ' looping through address collection
    18. If Address.State = ADDRESS_STATE.AS_INSERVICE Then ' checking if address is working
    19. Dim MediaSupport As ITMediaSupport = Address ' extracting meida support interface from the address
    20. MediaTypes = MediaSupport.MediaTypes ' extracting media types supporting
    21. MediaSupport = Nothing ' dispose of the object
    22. If MediaTypes And MediaModem = MediaModem Then ' the address is a data Modem
    23. If MediaTypes And MediaAudio = MediaAudio Then 'the address supports Audio
    24. oAddress = Address ' select this address
    25. MsgBox("we have selected this address: " + oAddress.AddressName) ' show the selected address name
    26. Exit For
    27. End If
    28. End If
    29. End If
    30. Next Address
    31. If Not oAddress Is Nothing Then
    32. ' registering notifications for the selected address
    33. RegCookie = oTAPI.RegisterCallNotifications(oAddress, True, False, MediaTypes, 1)
    34. oTAPI.EventFilter = TAPI_EVENT.TE_CALLNOTIFICATION Or TAPI_EVENT.TE_CALLSTATE Or TAPI_EVENT.TE_CALLINFOCHANGE 'Gibt an auf welche Events Tapi reagieren soll
    35. Else
    36. MsgBox("no address selected")
    37. End If
    38. End Sub
    39. Private Sub oTAPI_Event(ByVal TapiEvent As TAPI3Lib.TAPI_EVENT, ByVal pEvent As Object) Handles oTAPI.Event
    40. Select Case TapiEvent
    41. Case TAPI_EVENT.TE_CALLNOTIFICATION 'Call Notification Arrived
    42. MsgBox("oTAPI_Event+ Callnotification")
    43. Case TAPI_EVENT.TE_CALLSTATE 'Funktioniert, wird ausgelöst, wenn Verbunden oder die Verbindung getrennt wird
    44. MsgBox("oTAPI_Event + Callstate")
    45. Case TAPI_EVENT.TE_CALLINFOCHANGE 'Call Info Changes
    46. MsgBox("oTAPI_Event + Callinfochange")
    47. End Select
    48. End Sub
    49. Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click
    50. Dim PhoneNumber As String = "01577??????"
    51. Dim lAddressType As Long = TAPI3Lib.TapiConstants.LINEADDRESSTYPE_PHONENUMBER
    52. Dim newcall As TAPI3Lib.ITBasicCallControl
    53. newcall = oAddress.CreateCall(PhoneNumber, TAPI3Lib.TapiConstants.LINEADDRESSTYPE_PHONENUMBER, TAPI3Lib.TapiConstants.TAPIMEDIATYPE_AUDIO)
    54. newcall.Connect(False)
    55. End Sub
    56. End Class


    Der Klick auf den Button1 startet einen Anruf, wenn ich mein Handy abhebe, wird TE_CALLSTATE ausgelöst (Connect), wenn ich wegdrücke auch (Disconnect) aber wenn ich von meinem Handy aus anrufe, wird kein Event angezeigt. Das brauche ich allerdings, um eine Anruferkennung zu machen.
    Ich habe schon gelesen, dass das hier was damit zu tun haben soll: support.microsoft.com/kb/841712
    Allerdings bin ich noch immer Anfänger und verstehe nicht wirklich, was mir das sagen soll.

    Über eure Hilfe wäre ich wirklich dankbar, und sollte mein Problem auf die selbe Art zu lösen sein, wie das alte, so wäre ich auch froh über eine Nachricht, sodass ich zumindest eine Richtung habe, in der ich weitermachen kann.

    Liebe Grüße

    Slash
    Because of the complexity of the TAPI 3.x Component Object Model (COM) interface, the managed wrapper that is created by Microsoft Visual Studio .NET does not work.
    Therefore, you cannot call TAPI functionality from managed code.

    You can call TAPI 3.x (Tapi3.dll) functionality from unmanaged code.
    Create an unmanaged DLL that calls TAPI 3.x functionality, and then call the unmanaged DLL from managed code.

    Das heißt auf deutsch soviel wie: Mach dir eine .dll in (zB) C++ und benutze diese für dein VB Projekt..


    Allerdings scheint es ja teilweise in VB zu funktionieren... nur einige Events nicht..
    Vll kannst du ja mal folgende Sachen testen..
    1. m_TAPI kannst du im Grunde komplett weglassen..
    Du hast doch oTAPI global schon deklariert, also instanziere es einfach und ruf die initialize methode auf

    VB.NET-Quellcode

    1. oTAPI = New TAPIClass
    2. oTAPI.Initialize() ' initializing TAPI


    Nun kannst du mal alle möglichen Sachen testen, und sehen, ob im Event irgendwas ankommt.

    VB.NET-Quellcode

    1. 'Lass dir doch mal im Event ausgeben, was so drin steckt
    2. Private Sub oTAPI_Event(ByVal TapiEvent As TAPI3Lib.TAPI_EVENT, ByVal pEvent As Object) Handles oTAPI.Event
    3. 'zB mit debug.print
    4. If TapiEvent is nothing then
    5. debug.print("Kein TAPI3Lib.TAPI_EVENT")
    6. Else
    7. Debug.print "TAPIEVENT: " & TapiEvent.tostring ' oder eventuell anderes konvierten zu string
    8. End if
    9. If pEvent is nothing Then
    10. Debug.print("Kein pEvent")
    11. Else
    12. Debug.print "pEvent : " & pEvent .tostring ' oder eventuell anderes konvierten zu string
    13. End if
    14. Select Case TapiEvent
    15. Case TAPI_EVENT.TE_CALLNOTIFICATION 'Call Notification Arrived
    16. MsgBox("oTAPI_Event+ Callnotification")
    17. Case TAPI_EVENT.TE_CALLSTATE 'Funktioniert, wird ausgelöst, wenn Verbunden oder die Verbindung getrennt wird
    18. MsgBox("oTAPI_Event + Callstate")
    19. Case TAPI_EVENT.TE_CALLINFOCHANGE 'Call Info Changes
    20. MsgBox("oTAPI_Event + Callinfochange")
    21. End Select
    22. End Sub

    Dies ist nur EIN Ansatz, die Objekte zu prüfen, ich kenn die dll nicht.
    Aber so würde ich da ran gehen, um zu schauen, ob WIRKLICH kein event gefeuert wird...

    //EDIT: guck mal hier : http://www.codeproject.com/script/Articles/ViewDownloads.aspx?aid=10994&display=Mobile&zep=tapi3_dev%2fForm1.cs&rzp=%2fkb%2fip%2fdevangpro%2ftapi3_dev.zip

    Gruss Mono
    Das ist meine Signatur und sie wird wunderbar sein!

    Dieser Beitrag wurde bereits 1 mal editiert, zuletzt von „Mono“ ()

    Danke, aber lieder hilft das nicht weiter

    Hallo mono,

    vielen Dank schonmal für deine Hilfe, leider bringt das nichts.
    Es wird tatsächlich kein Event gefeuert, oder besser gesagt nur das eine, TE_CALLSTATE.

    Eine DLL in C++ ist für mich leider auch keine Lösung, schon alleine aus dem Grund, dass ich kein C++ kann (ich kann ja nichtmal richtig VB ;) )
    Außerdem will ich irgendwie nicht einsehen, dass es in VB keine Möglichkeit gibt, da es ja teilweise funktioniert. Blödes Tapi :cursing:
    Ich hab auch schon mal ein bisschen mit julmar.com/tapi/ rumgespielt, allerdings komme ich da auch nicht weiter und ich würde lieber mit der "offiziellen" Variante arbeiten.
    Wie gesagt, danke für deine Hilfe, aber leider hats nix gebracht ;(

    LG

    Slash


    Edit: oO, da war ich wohl zu spät, da kam ja noch was nach^^

    Tja, ich hab mir den Code mal angeschaut, aber wenn ich ehrlich bin nur überflogen. Erstes Problem C#, aber die Grundgedanken verstehe ich denke ich. Allerdings will mir nicht so recht auffallen, was daran anders ist. Und wie gesagt, es gibt ja einige Code-Beispiele, daraus habe ich ja auch meine kleine Testanwendung geschrieben, nur funktioniert das halt irgendwie nicht. Und wenn es in C# klappt ist mir damit nicht direkt geholfen.
    Ich hoffe es gibt noch n anderen Ansatz, ich glaube wenn ich anfange in C# Sachen zu schreiben und die dann in mein VB-Projekt einzubinden, dann wird das Forum mit Fragen überflutet.

    Edit2: Hab ich ja ganz vergssen: Ich habe mich ursprünglich auch gefragt, warum dieser Umweg über m_Tapi genommen wird. Macht ja eigentlich keinen großen Sinn. ABER: Wenn man es weglässt, dann gibts Fehlermeldungen.

    Dieser Beitrag wurde bereits 2 mal editiert, zuletzt von „SlashMcKagen“ ()

    Nunja, hast du das Projekt mit C# mal probiert ?
    Funktioniert es ?
    Werden alle Events behandelt ?

    WENN JA!, dann geht es auch in VB.NET.
    Du musst nur den Code aus C# in VB.NET übersetzen.
    Das ist Mithilfe von CodeConvertern nicht allzu schwierig.
    Für dich entscheidend in dem Code dürften folgende Sachen sein:

    Sub:
    void initializetapi3()

    Class:
    callnotification

    Ich kann es halt hier nicht testen
    Das ist meine Signatur und sie wird wunderbar sein!

    Danke, aber lieder hilft das nicht weiter

    Also komme ich nicht drum rum, den Code mal zu testen;-)
    Nunja, habe kein C# installiert, aber dann werde ich das wohl mal tun müssen.
    Wie gesagt, dank dir erstmal

    Edit: Also, ich habe mir mal das fertige Projekt von Ihm runtergeladen, geht erstmal schneller, als C# zu installieren usw.
    Es funktioniert. Ich kann zwar keinen Anruf absetzen (was bei mir funktioniert) aber das ist ja erstmal nicht das entscheidende. Entscheidend ist, dass bei Ihm ein eingehender Anruf ein Event feuert.
    Und das bedeutet dann, dass es definitiv auch mit Vb funktioniert? Das wäre ja schonmal was, dann wüsste ich zumindest, dass ich nicht umsonst suche^^

    Dieser Beitrag wurde bereits 1 mal editiert, zuletzt von „SlashMcKagen“ ()

    C# brauchst du nicht installieren, wenn du sowieso schon mit Visual Studio und VB.NET entwickelst.

    C# ist quasi (mit einigen Außnahmen) identisch zu VB.NET. Zumindest was die verwendeten Bibliotheken und Möglichkeiten angeht.
    (Ich weiss, einige werden sagen, mit C# geht aber das, was in VB nicht geht .. bla, bla)

    Fakt ist, C# Code, welcher keinen "unsafe" Code enthält, ist nahezu 1 zu 1 umsetzbar in VB.NET.

    Ich habe über den Code hier kurz drüber geschaut und bin mir sehr sicher, dass dieser auch in VB umzusetzen ist.
    An welchen Stellen hast du denn Probleme den Code zu verstehen ?
    Das ist meine Signatur und sie wird wunderbar sein!
    Sagen wir es mal so, ich habe schon mit vb so meine Probleme, wenn ich dann auch noch eine andere Syntax sehe, kann ich mich noch weniger drauf konzentrieren.
    Ich werde mich mal durchbeißen, wird sicher eine Zeit dauern, aber wenn ich dann wirklich konkrete Fragen habe, melde ich mich wieder.
    Ich habe den Code mal durch einen Konverter laufen lassen, funktioniert auch wunderbar bis auf 2 Fehlermeldungen.
    Diese beiden Fehler sind aber wohl entscheident, denn bis jetzt bekomme ich mit dem konvertierten Code gar keine Events.
    Fehler:

    VB.NET-Quellcode

    1. tobj.ITTAPIEventNotification_Event_Event += New TAPI3Lib.ITTAPIEventNotification_EventEventHandler(AddressOf cn.[Event])

    Fehlermeldung: Fehler 1 "Public Event ITTAPIEventNotification_Event_Event(TapiEvent As TAPI3Lib.TAPI_EVENT, pEvent As Object)" ist ein Ereignis und kann nicht direkt aufgerufen werden. Verwenden Sie eine RaiseEvent-Anweisung, um ein Ereignis aufzurufen.

    und

    VB.NET-Quellcode

    1. Implements TAPI3Lib.ITTAPIEventNotification


    Fehlermeldung: Fehler 4 Class "callnotification" muss "Sub Event(TapiEvent As TAPI_EVENT, pEvent As Object)" für die TAPI3Lib.ITTAPIEventNotification-Schnittstelle implementieren.

    Ich habe aber noch keinerlei Anstrengungen unternommen, zu verstehen was da schief läuft, wie gesagt, bin Anfänger und brauche da auf jeden Fall länger um mich durchzuarbeiten.
    Auf jeden Fall hast du mir schonmal einen Denkanstoß in die richitge Richtung gegeben, dafür bin ich dir sehr dankbar. :thumbsup:
    Wenn ich zu neuen Erkenntnissen komme, oder ähnliches werde ich mich selbstverständlich wieder melden.

    Vielleicht findet sich ja auch noch jemand, der selbst mal eine Anruferkennung mit VB2008 gemacht hat (in VB6 hat alles noch sooo schön funktioniert) und der vielleicht die selben Probleme schon gelöst hat.

    LG

    Slash
    Hallo mal wieder,

    also die erste Fehlermeldung habe ich wegbekommen, war ja gar nicht so schwer.
    Bei der Zweiten stehe ich allerdings auf dem Schlauch, was will er da bloß von mir?

    VB.NET-Quellcode

    1. Public Class callnotification
    2. Implements TAPI3Lib.ITTAPIEventNotification ' Bei dieser Zeile ist der Eigentliche Fehler, TAPI3Lib.ITTAPIEventNotification ist blau unterstrichen
    3. Public Delegate Sub listshow(ByVal str As String)
    4. Public addtolist As listshow
    5. Public Sub [Event](ByVal te As TAPI3Lib.TAPI_EVENT, ByVal eobj As Object)
    6. ...
    7. End Sub
    8. End Class


    Dabei kommt diese Fehlermeldung:

    Class "callnotification" muss "Sub Event(TapiEvent As TAPI_EVENT, pEvent As Object)" für die TAPI3Lib.ITTAPIEventNotification-Schnittstelle implementieren.

    Hast du irgendeinen Tipp, mit dem ich rauskriege, was er von mir will, oder wo ich mit der Suche nach Infos anfangen kann?

    Danke

    Slash
    Hi...

    Auf Anfrage hole ich den Thread mal wieder hoch. Du sollst doch nicht einfach drauflosprogrammieren - das geht fast immer in die Hose.

    Zunächst: Worum geht es genau? --> Um die MS-Telephone-API, v3, klar. Dazu finde ich folgendes:
    msdn.microsoft.com/en-us/library/ms734214.aspx
    msdn.microsoft.com/en-us/library/ms734236.aspx

    Du möchtest Call-Notifications empfangen. Um generell ein TAPI-Event zu registrieren, musst du diese Schritte befolgen: msdn.microsoft.com/en-us/libra…s726986%28v=vs.85%29.aspx. Die Frage ist, wo du das Objekt herbekommst, bei dem du das Ereignis registrieren musst. Hier steht, dass du es einfach mit CoCreateInstance erzeugen kannst.

    Da der generierte RCW offenbar nicht funktioniert, musst du ihn eben selbst schreiben. So gehts:
    - Suche dir im MSDN die benötigten Interfaces raus. Das habe ich schonmal erledigt:
    msdn.microsoft.com/en-us/libra…s732485%28v=vs.85%29.aspx
    msdn.microsoft.com/en-us/libra…s732506%28v=vs.85%29.aspx

    - Suche dir alle Headerdateien dieser Interfaces (am Ende jeder MSDN-Seite). Die Header gibts im Windows SDK, falls du es nicht installiert hast.

    - Deklariere die Interfaces manuell (ComImportAttribute), indem du die Headerdateien quasi übersetzt. Dabei fallen weitere Interfaces (z.B. als Parameter in Funktionen) an, die du ebenfalls deklarieren musst, sofern sie verwendet werden. Also wieder Googeln --> MSDN --> Header --> übersetzen. Einfacher: Lasse dir einen RCW generieren und öffne die DLL dann im Reflector / ILSpy. Kopiere die benötigten Deklarationen in dein Projekt und, ganz wichtig, überprüfe sie auf Richtigkeit, denn wir wissen nicht, wo der Fehler im generierten RCW liegt. Übrigens: IConnectionPointContainer und IConnectionPoint sind bereits vorhanden (in InteropServices.ComTypes).

    --> Wenn du bis hierher gekommen bist, hast du gerade einen RCW (oder Teile davon) selbst geschrieben.

    - Importiere die API-Funktion CoCreateInstance().

    Der Rest ist nur das Befolgen der Anweisungen im MSDN:
    - Initialize TAPI
    - Select an Address
    - Register Events

    Hier sind noch die TAPI Event-Interfaces: msdn.microsoft.com/en-us/libra…s734880%28v=vs.85%29.aspx

    Zusammengefasst: Das Ganze ist _sehr_ aufwändig. Der Fehler irgendwo im generierten RCW produziert ne Menge Zusatzarbeit. Die C++-Beispielcodes allein sind schon lang genug, zudem wird dort nur das Wesentliche zusammengefasst. Außerdem sind in C++ keine Import-Deklarationen erforderlich, die in .NET mühsam und fehleranfällig sind.

    Das Projekt ist interessant, keine Frage. Leider fehlt mir die Zeit, sowas zu verwirklichen. Eine Funktionsgarantie gibt es natürlich auch nicht - dieser Post ist nur der Ansatz einer Lösung und ist im schlechtesten Fall Zeitverschwendung :) .
    Gruß
    hal2000

    Dieser Beitrag wurde bereits 1 mal editiert, zuletzt von „hal2000“ ()

    Mal wieder danke^^

    Hallo Hal,

    ich danke dir mal wieder für diese super ausführliche Antwort.
    Allerdings war das leider doch etwas ernüchternd, denn das, was du schreibst, übersteigt meine Fähigkeiten eindeutig.
    Sicher, du hast dir jetzt so eine Mühe gemacht, ich werde mich also Schritt für Schritt damit befassen, dass bin ich dir immerhin schuldig (zusätzlich zu meinem Dank ;) ) aber ich werde wahrscheinlich schon gleich beim ersten Schritt stecken bleiben.
    Vielleicht sollte ich einfach aufhören, das Rad neu erfinden zu wollen und einfach eine fertige Komponente benutzen.
    Schade eigentlich...
    Aber wie gesagt, anschauen werde ich mir das auf jeden Fall nochmal und wenn ich eine Lösung gefunden habe, werde ich sie hier auf jeden Fall public machen, Tapi ist ja doch ein Thema, das viele andere auch interessiert.

    Liebe Grüße

    Slash