Seite 1 von 1
Wie kann ich Ereignisse eines ActiveX-Controls abfangen
Verfasst: Di, 05. Jun 2007 10:14
von Markus Walter
Hi,
lt. Dokumentation sollten sich doch Mausereignisse, die auf einem ActiveX-Control ausgelöst werden, über die "normalen" Xbase-Callback-Slots abfangen lassen?!
Das funktioniert aber offensichtlich nicht (zumindest nicht beim xbpHtmlViewer).
Hat jemand eine Idee?
Ich habe das Sample aus der Hilfe des HtmlViewers entsprechend verändert...
Code: Alles auswählen
#include "XBP.CH"
#include "AppEvent.CH"
PROCEDURE Main()
LOCAL oDlg
LOCAL oHTML
LOCAL nEvent, mp1, mp2, oXbp
LOCAL oDA
//
// Erzeugen des Hauptfensters der Anwendung
//
oDlg := XbpDialog():new( Appdesktop() )
oDlg:title := "HTMLViewer-Beispiel"
oDlg:taskList := .T.
oDlg:close := {|| PostAppEvent(xbeP_Quit,,, oDlg) }
oDA := oDlg:drawingArea
oDlg:create( ,, {50,50}, {640,480},, .F. )
oDA:resize := {|| ResizeControl(oHTML)}
//
// Erzeugen des XbpHTMLViewer-Objekts
//
oHTML := XbpHTMLViewer():new( oDA )
oHTML:create( ,, {10,10},{450,300} )
// Warum geht`s nicht?????
oHtml:rbclick := {| aPos, uNIL, self | tone(100,3) }
//
// Navigieren zur Seite "www.alaska-software.com"
//
oHTML:navigate( "www.alaska-software.com" )
//
// Anzeigen des Hauptfenster und bearbeiten
// von Ereignissen, bis das Fenster geschlossen
// wird
//
ResizeControl( oHTML )
oDlg:show()
SetAppWindow( oDlg )
SetAppFocus( oHTML )
nEvent := xbeP_Quit
DO WHILE nEvent != xbeP_Close
nEvent := AppEvent( @mp1, @mp2, @oXbp )
oXbp:handleEvent( nEvent, mp1, mp2 )
ENDDO
oDlg:destroy()
RETURN
// Anpassen der Größe des XbpHTMLViewer-Objekts,
// sodass es immer die gesamte Fläche der
// Drawing Area des Dialogs einnimmt
PROCEDURE ResizeControl( oHTML )
LOCAL oParent := oHTML:setParent()
oHTML:setPosAndSize( {0,0}, oParent:currentSize() )
RETURN
// Überladene AppSys()-Prozedur zur Unterdrückung
// der Erzeugung des Standard-XbpCrt-Fensters
PROCEDURE AppSys()
RETURN
Verfasst: Di, 05. Jun 2007 10:49
von Martin Altmann
Hallo Markus,
ich meine, dass man dazu erst mal eine entsprechende Option setzen muss - habe selber noch nicht viel mit ActiveX (abgesehen von RMChart) gemacht, kommt aber noch!
Ich meine aber, dass ähnliches auch bei dem RTF-Control nötig ist...
Viele Grüße,
Martin
Verfasst: Di, 05. Jun 2007 11:03
von Martin Altmann
So,
habe mal gestöbert - ist dafür nicht :subscribeEvent() der ActiveXObject()-Klasse gedacht?
Viele Grüße,
Martin
Verfasst: Di, 05. Jun 2007 11:47
von Markus Walter
Hallo Martin,
da war ich in der Doku auch schon, aber da steht:
Code: Alles auswählen
Hinweis: Die Methode :subscribeEvent() wird intern vom Ereignisbehandlungsmechnismus der Klasse ActiveXObject verwendet. Die Methode wird in einer Xbase++-Anwendung normalerweise nicht direkt verwendet.
Nach meinem Verständnis müsste da auch eher :suspendEvent( ) verwendet werden...
Aber davon ab: beide Methoden verlangen eine <nDISPID> die gibt es für "rechten Mausclick" nicht...
Aber beim XbpActiveXControl() ist ja der
Slot: :rbClick := {| aPos, uNIL, self | ... }
extra "ganz normal beschrieben", so dass mein Code-Beispiel eigentlich funktionieren müsste...
Es sein denn...
Code: Alles auswählen
Hinweis: Nicht alle ActiveX-Steuerelemente unterstützen Mausereignisse. Wird das ActiveX-Ereignis "Click" durch das Steuerelement nicht generiert, wird die Methode :click() nicht ausgeführt.
Benutzt irgendjemand ein anderes ActiveXControl, dass Mausereignisse weitergibt? Falls es der IE wirklich nicht tun sollte...
Verfasst: Di, 05. Jun 2007 11:53
von andreas
Hallo Markus,
das solte die richtige Methode sein:
dynamicCast
Hier ist Ausschnitt aus der Hilfe:
Ähnlich den Callback Slots, die von Xbase Parts zur Verfügung gestellt werden, nutzen COM/ActiveX-Komponenten oftmals Nachrichten, um mit dem Nutzer der Komponente zu kommunizieren. Die zusätzlichen Merkmale, die zur Verarbeitung von COM/ActiveX-Nachrichten erforderlich sind, werden von der Klasse ActiveXObject() zur Verfügung gestellt. Diese Klasse ist von der Klasse AutomationObject abgeleitet.
Um auf COM/ActiveX Ereignisse reagieren zu können, muß ein Codeblock definiert werden, der immer dann ausgewertet wird, wenn das Ereignis ausgelöst wird. Der Codeblock muß einer Instanzvariablen zugewiesen werden, die den selben Namen wie das COM/ActiveX-Ereignis besitzt.
Alternativ kann für die Bearbeitung eines COM/ActiveX-Ereignisses auch eine Ereignisbehandlungsmethode in einer von ActiveXObject abgeleiteten Klasse implementiert werden. Diese Callback-Methode muß den selben Namen haben wie das COM/ActiveX-Ereignis, und wird immer dann ausgeführt, wenn das COM/ActiveX-Ereignis ausgelöst wird.
Erzeugen eines Objektes der Klasse ActiveXObject
Instanzen der Klasse ActiveXObject können auf zwei Arten erzeugt werden. Um ein solches Objekt direkt zu erzeugen, kann die Klassenmethode :create() gerufen werden. Bereits erzeugte Objekte, beispielsweise durch einen Aufruf der Funktionen CreateObject() oder GetObject(), müssen hingegen durch eine Typwandlung (cast) in ein Objekt der Klasse ActiveXObject überführt werden. Hierfür wird die Methode :dynamicCast verwendet. Dieser Methode muß das Klassenobjekt der Zielklasse oder eine Zeichenkette, welche die Zielklasse bezeichnet, als Parameter übergeben werden.
#pragma library( "ascom10.lib" )
PROCEDURE MAIN
LOCAL oWord, cMsg
oWord := GetObject( NIL, "Word.Application" )
IF NIL == oWord
? "Fehler"
? ComLastError()
? ComLastMessage()
ENDIF
oWord:visible := .T.
//
// Typenwandlung des AutomationObject in eine Instanz
// der Klasse ActiveXObject. Ein ActiveXObject wird
// benötigt, um auf COM/ActiveX Ereignisse zu
// reagieren.
//
//
oWord := oWord:dynamicCast( "ActiveXObject" )
//
// Zuweisen eines Codeblockes an den Callback-Slot
// des COM/ActiveX-Ereignisses "quit"
//
oWord:quit := { || MsgBox("In Word ist das Quit-Ereignis aufgetreten") }
cMsg := "Beenden Sie Word, um den Nachrichtendialog zu sehen. "
cMsg += "Drücken Sie eine Taste, um die Anwendung zu beenden."
WAIT cMsg
RETURN
Verfasst: Di, 05. Jun 2007 12:56
von Markus Walter
Hallo Andreas,
XbpHtmlViewer ist ja bereits von ActiveXControl abgeleitet.
:dynamicCast wird verwendet um aus einem AutomationObjekt ein ActiveXObjekt zu machen (so habe ich es zumindest verstanden...)
Verfasst: Di, 05. Jun 2007 17:00
von AUGE_OHR
hi,
Markus Walter hat geschrieben:
Code: Alles auswählen
Hinweis: Die Methode :subscribeEvent() wird intern vom Ereignisbehandlungsmechnismus der Klasse ActiveXObject verwendet. Die Methode wird in einer Xbase++-Anwendung normalerweise nicht direkt verwendet.
richtig.
Markus Walter hat geschrieben:
Aber davon ab: beide Methoden verlangen eine <nDISPID> die gibt es für "rechten Mausclick" nicht...
hm ... versuch mal
Code: Alles auswählen
cEventName := "Click"
xVar := oWmp:isEventPublished( cEventName )
IF xVar <> Nil
lSuccess := oWmp:SubscribeEvent( xVar, { |nButton, nShiftState, fX , fY | ;
IF(nButton=4,PostAppEvent(xbeM_MbClick),NIL) } ) // Wheel = middle
MSGBOX("hat geclickt"+STR(nButton)+" "+STR(nShiftState)+" "+STR(fX)+" "+STR(fY) ) } )
Markus Walter hat geschrieben:
Aber beim XbpActiveXControl() ist ja der
Slot: :rbClick := {| aPos, uNIL, self | ... }
extra "ganz normal beschrieben", so dass mein Code-Beispiel eigentlich funktionieren müsste...
nope, du kannst ein den Slot nicht einfach überschreiben da er
"abgefangen" wird. speziell beim :rbClick wirst du ohne entsprechende
Property diesen nicht "überschreiben" können. Wenn du also z.b. keine
Property :enableContextMenu hast welche du auf .F. setzten kannst so
denke ich, das du aus Xbase++ nicht :rbClick setzten kannst.
Markus Walter hat geschrieben:
Es sein denn...
Code: Alles auswählen
Hinweis: Nicht alle ActiveX-Steuerelemente unterstützen Mausereignisse. Wird das ActiveX-Ereignis "Click" durch das Steuerelement nicht generiert, wird die Methode :click() nicht ausgeführt.
Benutzt irgendjemand ein anderes ActiveXControl, dass Mausereignisse weitergibt? Falls es der IE wirklich nicht tun sollte...
yup, den M$ Mediaplayer ... da gibt es massig solche Events, teilweise
sehr "tricki" ... so gibt es z.b. den Event "keypress", ABER der funktioniert
nur im Fullscreen Modus ... bis ich das raus hatte ...
gruss by OHR
Jimmy
Verfasst: Do, 07. Jun 2007 18:13
von Günter Beyes
Hallo Markus,
Markus hat geschrieben:lt. Dokumentation sollten sich doch Mausereignisse, die auf einem ActiveX-Control ausgelöst werden, über die "normalen" Xbase-Callback-Slots abfangen lassen?!
Das funktioniert aber offensichtlich nicht (zumindest nicht beim xbpHtmlViewer).
beim Webbrowser kommen alle Maus- und Tastaturereignisse im HTML-Dokument an, auf das du über ::BrowserControl:Document zugreifen kannst.
Dahinter steht das HTMLDocument-Objekt aus der mshtml.dll.
Die Aktivierung des Kontextmenüs zum Beispiel kannst du am einfachsten über den "oncontextmenu"-Event abfangen. Hat den Vorteil, dass die Kontextmenü-Taste mit berücksichtigt wird.
Code: Alles auswählen
XbpWebBrowser erweitern:
neue IVAR oDocument (EXPORTED)
neue Methode onContextMenu() (EXPORTED)
#define DISPID_ONCONTEXTMENU 1023
// unterdrückt das Kontextmenü
METHOD XbpWebBrowser:onContextMenu()
IF ::oDocument <> NIL
::oDocument:parentWindow:event:returnValue := FALSE
ENDIF
RETURN TRUE
// folgendes in XbpWebBrowser:DocumentComplete() einbauen:
IF ::oDocument <> NIL
// Ob das wirklich nötig ist, weiss ich nicht...
::oDocument:unsubscribeEvent( DISPID_ONCONTEXTMENU )
::oDocument:destroy()
::oDocument := NIL
ENDIF
// wir brauchen den Event "oncontextmenu"
::oDocument := ::BrowserControl:Document
::oDocument := ::oDocument:dynamicCast( ActiveXObject() )
::oDocument:subscribeEvent( "oncontextmenu", {||::onContextMenu() } )
Falls dynamisch erzeugter HTML-Code angezeigt wird, muss eventuell
ocumentComplete() manuell aufgerufen werden, je nach dem wie man den HTML-Code an den Browser übergibt.
Nachtrag:
Nach einigem Testen muss ich sagen -- Alles gut und schön, funktioniert aber nur nach dem ersten Aufruf einer URL. Navigiert man zu einer anderen URL, hängt der Browser.
Hat jemand eine Idee, was da los ist?
Viele Grüße,
Günter
Verfasst: Fr, 08. Jun 2007 3:28
von AUGE_OHR
hi,
Günter Beyes hat geschrieben:
Code: Alles auswählen
#define DISPID_ONCONTEXTMENU 1023
// wir brauchen den Event "oncontextmenu"
::oDocument := ::BrowserControl:Document
::oDocument := ::oDocument:dynamicCast( ActiveXObject() )
::oDocument:subscribeEvent( "oncontextmenu", {||::onContextMenu() } )
müsste es nicht
Code: Alles auswählen
::oDocument:subscribeEvent( DISPID_ONCONTEXTMENU,;
{||::onContextMenu() } )
also nDISPID heissen ?
ich habe deinen Gedanke aufgenommen und weitere Test gemacht.
Resultat : noch nicht mal "Click", "onClick" oder sonstwas mich click
funktioniert alles nicht d.h. ich bekomme bei o:isEventPublished immer
nur 0 zurück (nicht vorhanden).
Code: Alles auswählen
ALTD()
cEventName := "Click"
nVar := ::isEventPublished( cEventName )
IF nVar > 0
lSuccess := ::SubscribeEvent( nVar, { |nButton, nShiftState, fX , fY | ;
MSGBOX("click"+STR(nButton)+" "+STR(nShiftState)+" "+STR(fX)+" "+STR(fY) ) })
ENDIF
Wenn ich mir das ganze im Debugger ansehe hab ich nur IWebBrowser2
als Interface was ich mit Xbase++ ansprechen kann. Alle anderen Class(en)
kann man zwar mit C++ oder IE benutzen, aber wohl nicht mit Xbase++.
gruss by OHR
Jimmy
Verfasst: Fr, 08. Jun 2007 12:59
von Günter Beyes
Hallo Jimmy,
Jimmy hat geschrieben:Wenn ich mir das ganze im Debugger ansehe hab ich nur IWebBrowser2 als Interface was ich mit Xbase++ ansprechen kann. Alle anderen Class(en) kann man zwar mit C++ oder IE benutzen, aber wohl nicht mit Xbase++.
nach meiner Meinung müsste vieles davon auch mit Xbase++ gehen.
Probier mal, wie ich geschrieben habe,
Der Debugger zeigt:
oDocument:InterfaceName ist "DispHTMLDocument"
und nun:
Code: Alles auswählen
oDocument := oDocument:dynamicCast( ActiveXObject() )
nDispId := oDocument:isEventPublished( "onclick" )
nDispId enthält -600 -- "onclick" wird unterstützt.
In der Helpkit-Dokumentation der mshtml.dll findest du unter "HTMLDocument" die Namen aller unterstützten Ereignisse.
müsste es nicht
Code: Alles auswählen
::oDocument:subscribeEvent( DISPID_ONCONTEXTMENU, {||::onContextMenu() } )
also nDISPID heissen?
Stimmt. Danke! Aber auch wenn ich korrekterweise nDISPID statt des Eventnamens verwende, ändert das leider nichts an der Problemlage...
Der Codeblock wird tatsächlich aufgerufen, wenn das Ereignis eintritt. So weit so gut. Aber nach dem ersten Navigieren funktionieren Hyperlinks nicht mehr, und es kann passieren, dass der Browser regelrecht "hängt" und nur über den Taskmanager beendet werden kann.
Meine Überlegung ist, dass jeder erfolgreiche Navigationsvorgang ein neues HTMLDocument erzeugt. Also muss ich beim vorherigen HTMLDocument :unsubscribeEvent() ausführen, eventuell gefolgt von :destroy(). Für das aktuelle HTMLDocument muss dann :subscribeEvent() aufs Neue aufgerufen werden.
Tue ich dieses, gibt es die beschriebenen Probleme. Tue ich es nicht, sieht es aber auch nicht besser aus.
Viele Grü0e,
Günter
Verfasst: Fr, 08. Jun 2007 19:46
von AUGE_OHR
hi,
Günter Beyes hat geschrieben:
Der Debugger zeigt:
oDocument:InterfaceName ist "DispHTMLDocument"
hm ... soweit bin ich wohl nicht gekommen
Günter Beyes hat geschrieben:
und nun:
Code: Alles auswählen
oDocument := oDocument:dynamicCast( ActiveXObject() )
nDispId := oDocument:isEventPublished( "onclick" )
nDispId enthält -600 -- "onclick" wird unterstützt.
hm ... jetzt muss ich doch noch mal nachfragen: Das HtmlViewer Interface
verwendet IWebBrowser2 welches die ::BrowserControl enthält, richtig ?
Nun verwendest du :dynamicCast( ActiveXObject() ) auf das "aktive"(?)
Interface und fügst eine neues hinzu ??? d.h. man hat dann 2 ?
Günter Beyes hat geschrieben:
In der Helpkit-Dokumentation der mshtml.dll findest du
em, äh ... wo finde ich die ?
auch kann ich mit COMM Assistant nicht die Datei \system32\mshtml.dll
bearbeiten und mir ein help files erstellen lassen ...
dafür gibt es aber ein mshtml.TLB file, wohl für Event Constanten.
Günter Beyes hat geschrieben:
Der Codeblock wird tatsächlich aufgerufen, wenn das Ereignis eintritt. So weit so gut. Aber nach dem ersten Navigieren funktionieren Hyperlinks nicht mehr, und es kann passieren, dass der Browser regelrecht "hängt" und nur über den Taskmanager beendet werden kann.
ich hab mal in der Richtung bei MSDN weiter gesucht :
http://msdn2.microsoft.com/en-us/library/aa741313.aspx
nach der Grundeinführung in die WebControls gibt es dann den Abschnitt
"Providing Extra Control" wo von "MSHTML components" gesprochen wird.
"Hosts of either component can obtain extra control over functionality by implementing the IDocHostUIHandler and IDocHostShowUI interfaces. These interfaces are commonly used to override the context menus that are supplied by default for the browser."
... und woher bekomme ich die IDocHostxxx ?
"The component obtains these interfaces from the host by calling QueryInterface on the IOleClientSite interface implemented by the hosting application"
... und nun auch noch ein IOleClientSite ...
aber zurück zum eigendlichen Problem
"Overriding the Context Menus
The WebBrowser Control's context menus can be overridden entirely by implementing the IDocHostUIHandler::ShowContextMenu method. Returning E_NOTIMPL or S_FALSE from this method indicates to the WebBrowser Control that it should display its own standard context menu. However, returning S_OK causes the WebBrowser Control not to display its menus, and it assumes that the host has performed the appropriate action. "
also sollte man sich mal die :ShowContextMenu Methode ansehen
http://msdn2.microsoft.com/en-us/library/aa753264.aspx
aber auch das bringt mich nicht richtig weiter. geht man aber ein wenig
rauf im Tree an der linken Seite so kommt man nach
http://msdn2.microsoft.com/en-us/library/aa768380.aspx
zumindest kann ich da die angesprochenen Interface "sehen", aber es
sieht völlig anders aus wie die mit COM Assistant erzeugte help Datei ?
meine Frage wäre nun, wie kommt man an die ganzen anderen aktiveX
Interface mit Xbase++ ran oder geht das (wieder mal) nur mit C/C++ ?
gruss by OHR
Jimmy
Verfasst: Fr, 08. Jun 2007 23:09
von Günter Beyes
Hallo Jimmy,
erstmal vorab: Das Problem ist gelöst
Ich hatte geschrieben:
Meine Überlegung ist, dass jeder erfolgreiche Navigationsvorgang ein neues HTMLDocument erzeugt. Also muss ich beim vorherigen HTMLDocument :unsubscribeEvent() ausführen, eventuell gefolgt von :destroy(). Für das aktuelle HTMLDocument muss dann :subscribeEvent() aufs Neue aufgerufen werden.
Voll daneben! Das HTMLDocument bleibt als Objekt offenbar immer dasselbe, nur sein Inhalt ändert sich beim Navigieren. Es reicht also, wenn :subscribeEvent() ein einziges Mal aufgerufen wird. Kein :unsubscribeEvent(), kein :destroy().
Kurz gesagt: Am XbpWebBrowser-Sample sind lediglich folgende minimalen Änderungen nötig, um das Kontextmenü zu unterdrücken.
Code: Alles auswählen
#define DISPID_ONCONTEXTMENU 1023
// zwei neue IVARs
VAR oDocument READONLY
VAR enableContextMenu // in ::init() mit TRUE vorbelegen
// eine neue Methode
INLINE METHOD ContextMenuHandler()
LOCAL oEvent
IF ! ::enableContextMenu
oEvent := ::oDocument:parentWindow:event
oEvent:returnValue := FALSE
ENDIF
RETURN TRUE
// Erweiterung in der Methode :DocumentComplete() :
IF ::BrowserControl:IsBusy() == FALSE
::lIsNavigating := .F.
lAddToHistory := .T.
IF ::oDocument = NIL
::oDocument := ::BrowserControl:Document
::oDocument := ::oDocument:dynamicCast( ActiveXObject() )
::oDocument:subscribeEvent( DISPID_ONCONTEXTMENU, {||::ContextMenuHandler() } )
ENDIF
ENDIF
// und im aufrufenden Code:
XbpWebBrowser:enableContextMenu := FALSE
Jimmy hat geschrieben:Jetzt muss ich doch noch mal nachfragen: Das HtmlViewer Interface verwendet IWebBrowser2 welches die ::BrowserControl enthält, richtig ?
Genau. XbpWebBrowser:BrowserControl enthält ein XbpHtmlViewer-Objekt, und dahinter steht das IWebBrowser2-Interface.
Jimmy hat geschrieben:Nun verwendest du :dynamicCast( ActiveXObject() ) auf das "aktive"(?) Interface und fügst eine neues hinzu ??? d.h. man hat dann 2 ?
Genauer gesagt wende ich :dynamicCast( ActiveXObject() ) auf das AutomationObject an, welches
XbpHtmlViewer:Document mir zurückliefert ! Damit wird das AutomationObject zum ActiveXObject, so dass nun die Methode :subscribeEvent() zur Verfügung steht.
Wie ich das verstehe, ändert :dynamicCast() am zugrundeliegenden COM-Interface gar nichts, und verdoppelt es auch nicht. Es ändert sich lediglich die Verpackung.
Jimmy hat geschrieben:Auch kann ich mit COM Assistant nicht die Datei \system32\mshtml.dll bearbeiten und mir ein help files erstellen lassen...
Hmm... Das funktioniert bei mir zur Zeit auch nicht mehr. Sehr merkwürdig. Mshtml.dll und mshtml.tlb haben völlig unterschiedliches Datum und unterschiedliche Versionsnummern. Wer war das?! Windows-Update???
Bei Bedarf kann ich dir mshtml.chm zur Verfügung stellen (3,2 MB).
IDocHostUIHandler, IDocHostShowUI, IOleClientSite...
Ja, die sind ein Fall für C/C++, oder für Cockpit. Zumindest im vorliegenden Fall aber nicht unbedingt erforderlich.
Viele Grüße,
Günter
Verfasst: Mo, 11. Jun 2007 10:31
von Markus Walter
Hallo Günter,
super, funktioniert wie gewünscht.
Da ich aber unverschämt bin...
Wie kann ich denn jetzt bestimmte Tastatur-Events abfangen (z. B. möchte ich, dass wenn ESC gedrückt wird, der Dialog geschlossen wird, in den der XbpHtmlViewer eingebettet ist)?
Gruß
Markus
Verfasst: Mo, 11. Jun 2007 12:13
von Günter Beyes
Hallo Markus,
da müsstest du den Event "onkeypress" von HTMLDocument abfangen und
im Eventhandler ::oDocument:parentWindow:event darauf untersuchen, ob ESC gedrückt worden ist. Als DISPID probier mal DISPID_ONKEYPRESS (=13).
Habe leider im Moment keine Zeit.. versuch mal in MSDN die Beschreibung von onkeypress und das erwähnte Event-Objekt zu finden.
Viele Grüße,
Günter
Verfasst: Mo, 11. Jun 2007 13:20
von Markus Walter
Hallo Günter,
super, es klappt.
Man muss allerdings
#define DISPID_KEYPRESS -603
verwenden...
Re: Wie kann ich Ereignisse eines ActiveX-Controls abfangen
Verfasst: Di, 04. Aug 2009 17:26
von J.Renseler
Hallo,
ich muss den Thread leider nochmal nach vorne holen.
Ich muss wie Markus auch die ESC Taste abfragen. Wie ich das Event des Tastendrucks an sich abfange habe ich dank euch schon verstanden. Wie aber kann ich dann abfragen ob die ESC Taste gedrückt wurde?
Wäre nett wenn mir jemand das noch etwas näher erklären könnte.
Danke und Gruß Jannik
Re: Wie kann ich Ereignisse eines ActiveX-Controls abfangen
Verfasst: Di, 04. Aug 2009 19:50
von AUGE_OHR
J.Renseler hat geschrieben:ich muss den Thread leider nochmal nach vorne holen.
das ist doch kein Problem
J.Renseler hat geschrieben:Ich muss wie Markus auch die ESC Taste abfragen. Wie ich das Event des Tastendrucks an sich abfange habe ich dank euch schon verstanden. Wie aber kann ich dann abfragen ob die ESC Taste gedrückt wurde?
du solltes nochmal genau sagen was du meinst, den HTMLviewer ?
c:\ALASKA\XPPW32\Source\SYS\axctrls.prg das ist der Source zur HTMLviewer Class.
ganz "allgemein"
Code: Alles auswählen
CASE nEvent == xbeP_Keyboard .AND. mp1 == xbeK_ESC
PostAppEvent( xbeP_Close,,,SetAppWindow() )
oder meinst du es "allgemein" mit activeX ?
:subscribeEvent()
wenn mal "viele" Event hat, wie bei den Codejock ActiveX dann wird man "nicht jeden einzeln" codieren.
Code: Alles auswählen
// alle #define fangen mit "Ev" an
#define EvClick "Click"
#define EvDblClick "DblClick"
#define EvDropDown "DropDown"
#define EvKeyDown "KeyDown"
#define EvKeyPress "KeyPress"
#define EvKeyUp "KeyUp"
#define EvMouseDown "MouseDown"
#define EvMouseMove "MouseMove"
#define EvMouseUp "MouseUp"
ich lege für den Event "click" die #define EvClick an
Code: Alles auswählen
METHOD HX_Combo:DefEvent()
::SubscribeEvent( EvClick , {|| ::_itemSelected() })
::SubscribeEvent( EvDblClick , {|| ::_itemSelected() })
nun wird bei Events oft "Parameter" angegeben ... was mache ich damit ?
Code: Alles auswählen
::SubscribeEvent( EvMouseDown , {|Button,Shift,X,Y|::_MouseDown(Button,Shift,X,Y) })
::SubscribeEvent( EvMouseMove , {|Button,Shift,X,Y|::_MouseMove(Button,Shift,X,Y) })
::SubscribeEvent( EvMouseUp , {|Button,Shift,X,Y|::_MouseUp (Button,Shift,X,Y) })
an diesem Beispiel kann man sehen das man die "Parameter" zwischen die || zu setzt sind und man dann Zugriff darauf hat.
Re: Wie kann ich Ereignisse eines ActiveX-Controls abfangen
Verfasst: Di, 04. Aug 2009 20:38
von J.Renseler
Hallo Jimmy,
danke für deine schnelle Hilfe. Werde es mit deinen Hinweisen direkt nochmal ausprobieren.
Um es nochmal ganz konkret zu formulieren. Ich muss Tasten die im XbpHTMLViewer gedrückt werden auswerten können.
Gruß,
Jannik
Re: Wie kann ich Ereignisse eines ActiveX-Controls abfangen
Verfasst: Mi, 05. Aug 2009 10:22
von J.Renseler
Hallo,
*hmm* funktioniert leider so noch nicht.
Hier mal mein Code
Code: Alles auswählen
CLASS absHTMLViewer FROM XbpHTMLViewer
EXPORTED:
VAR oDocument
METHOD DocumentComplete()
METHOD keyboard()
ENDCLASS
#define DISPID_ONCONTEXTMENU 1023
#define DISPID_ONKEYPRESS 13
#define DISPID_KEYPRESS -603
METHOD absHTMLViewer:DocumentComplete()
IF .NOT. ::IsBusy()
IF Empty( ::oDocument)
IF .NOT. Empty( ::Document)
::oDocument := ::Document:dynamicCast( ActiveXObject() )
::oDocument:subscribeEvent( DISPID_KEYPRESS, {|nKey| ::keyboard(nKey) } )
ENDIF
ENDIF
ENDIF
RETURN(SELF)
METHOD absHTMLViewer:keyboard( nKey)
IF .NOT. Empty( nKey)
MsgBox("nKey:" + CHR( nkey) )
ENDIF
RETURN(SELF)
In der Methode keyboard kommt nie ein Tastendruck an.
(Ich habe auch schon probiert die Methode anders zu benennen, aber dadran liegt es auch nicht)