Deutsch
C ++ Forum

Return Wert stimmt nicht

 

Georg
Hovenbitzer
Hallo Sebastian,

ich habe mal wieder ein größeres Problem.
Der geniale folgende Code stammt vom Pascal, soetwas könnte ich mir nicht ausdenken.
Er ermittelt den Quellcode aus einem geöffneten IE Fenster, wie z.B. www.google.de.
Zum Test bitte keine große Seite nehmen, da die Zuweisung zum Edit Feld im Beispielt noch per SetText geht.

Im Interpreter und als Profan Exe läuft er super, übersezt kommt immer eine Schutzverletzung.
Die Zeile die den Fehler verursacht ist die:
Error& = CallMethod(IHTMLElement&,62,@Addr(Text&))

Der Grund ist dafür, dass der Aufruf davor von:
Error& = CallMethod(IHTMLDocument2&,9,@Addr(IHTMLElement&))

Eine Error& Nummer <> 0 zurückt gibt und IHTMLElement&, gleich 0 ist.

Könnte dieses Problem des Übersetzen sein ?
KompilierenMarkierenSeparieren
 $H D:PrivatProfanXProfan9INCLUDEWindows.ph
---------------Umwandlung String > globally unique identifier

Proc StringToGUID

    Parameters GUID$,GUID&
    Declare Temp$
    Temp$ = @Space$(80)
    ~MultiByteToWideChar(1,1,@Addr(GUID$),-1,@Addr(Temp$),80)
    @External("ole32","CLSIDFromString",@Addr(Temp$),GUID&)

EndProc

-----------------------------------------------------------------------
--------------------------Methode eines COM-Interfaces aufrufen

Proc CallMethod

    Parameters IFace&,Method&
    Declare VTable&
    VTable& = @Long(IFace&,0)
    Method& = @Long(VTable&,(Method& * 4))
    Case %PCount = 2 : Return @Call(Method&,IFace&)
    Case %PCount = 3 : Return @Call(Method&,IFace&,@&(3))
    Case %PCount = 4 : Return @Call(Method&,IFace&,@&(3),@$(4))
    Case %PCount = 5 : Return @Call(Method&,IFace&,@&(3),@&(4),@&(5))

EndProc

-----------------------------------------------------------------------
----------WideChar (UniCode) zu MultiByte (Ansi) [nur OLE!]

Proc OLE_WideToMulti

    Parameters Text&
    Declare Text$,Size&,Text#
    Size& = @External("oleaut32","SysStringLen",Text&)
    Dim Text#,Size&
    Clear Text#
    ~WideCharToMultiByte(0,0,Text&,-1,Text#,Size&,0,0)
    @External("oleaut32","SysFreeString",Text&)
    Text$ = @String$(Text#,0)
    Dispose Text#
    Return Text$

EndProc

-----------------------------------------------------------------------
------------------------------EnumChildProc---------------------------

Proc EnumChildProc

    Parameters wnd&
    Declare Name#
    Dim Name#,255
    ~GetClassName(wnd&,Name#,255)
    Case @String$(Name#,0)="Internet Explorer_Server" : IEServerWnd& = wnd&
    Dispose Name#
    Return 1

EndProc

---------------------------------------------------------------------------------
--------------------------RunningIE_GetText-----------------------

Proc RunningIE_GetText

    Parameters IEHwnd&
    Declare Error&,IID#,Msg&,Result&,oleacc&,IHTMLDocument2&,IHTMLElement&,Text&,Text$,Url&,Url$
    Dim IID#,16
    Declare IEServerWnd&
    ~EnumChildWindows(IEHwnd&,@ProcAddr(EnumChildProc,2),0)
    @ProcAddr(EnumChildProc,-2)--ProcAddr freigeben
    Print "IEServerwnd&",IEServerWnd&
    Print
    Msg& = ~RegisterWindowMessage("WM_HTML_GETOBJECT")
    Print "msg",Msg&
    Print
    Error& = ~SendMessageTimeout(IEServerWnd&,Msg&,0,0,~SMTO_ABORTIFHUNG,1000,@Addr(Result&))
    Print "Error SendMessageTimeout",Error&
    Print "Result SendMessageTimeout",Result&
    @External("ole32","CoInitialize",0)
    oleacc& = @UseDLL("oleacc.dll")
    Print "oleacc",oleacc&
    Print
    StringToGUID("{332c4425-26cb-11d0-b483-00c04fd90119}",IID#)--IID_IHTMLDocument2
    Error& = @External("oleacc","ObjectFromLresult",Result&,IID#,0,@Addr(IHTMLDocument2&))
    Print "Error ObjectFromLresult",Error&
    Print "IHTMLDocument2",IHTMLDocument2&
    FreeDLL oleacc&
    Error& = CallMethod(IHTMLDocument2&,9,@Addr(IHTMLElement&))--IHTMLDocument2::get_body
    Print "Error IHTMLDocument2::get_body",Error&
    Print "IHTMLElement",IHTMLElement&
    Print
    ----------------------------------------------Quelltext ermitteln
    Error& = CallMethod(IHTMLElement&,62,@Addr(Text&))--IHTMLElement::get_outerHTML
    Print "Error IHTMLElement::get_outerHTML",Error&
    Print "Result get_outerHTML",Text&
    Print
    Text$ = OLE_WideToMulti(Text&)
    -------------------------------------------------------URL ermitteln
    Error& = CallMethod(IHTMLDocument2&,40,@Addr(Url&))--IHTMLElement::get_URL
    Print "Error IHTMLElement::get_URL",Error&
    Print "Result get_URL",URL&
    Print
    Url$ = OLE_WideToMulti(Url&)
    Print "URL = ";Url$
    Dispose IID#
    @External("ole32","CoUninitialize")
    Return Text$
    EndProc---------------------------------------------------------------------------------
    Window 0,0-800,600
    Declare Fenster&
    Declare Edit&
    Declare Quell$
    Declare IEServerWnd&
    Fenster& = ~FindWindow("IEFrame",0)--Hier könnte man auch andere Möglichkeiten nehmen,

    IfNot Fenster&---------------------z.B. Suche nach Fenstertitel.

        Print "Bitte IE starten!!"------Benötigt wird das gewünschte Hauptfenster des IE!
        WaitInput
        End

    EndIf

    Quell$ = RunningIE_GetText(Fenster&)

    If @Len(Quell$)

        Edit& = @Create("multiedit",%hwnd,"",300,20,450,500)----Text anzeigen
        SetText Edit&,Quell$

    EndIf

    WaitKey
    End
 
Viele Grüsse, Georg Hovenbitzer(Windows XP Pro, XProfan 11.2, Profan2Cpp 1.6a)
17.05.2006  
 




Sebastian
König
Hallo Georg,

danke für den Hinweis - das Problem tritt auch bei mir auf - leider konnte ich die Ursache noch nicht feststellen ...

Wie Du schon geschrieben hast, schlägt der Aufruf

Error& = CallMethod(IHTMLDocument2&,9,@Addr(IHTMLElement&))

fehl, sodass IHTMLElement& keinen gültigen Schnittstellenzeiger enthält und der Versuch, eine Methode damit aufzurufen, zum Abstruz führt.

Nur was genau da schiefläuft, ist mir noch ein Rätsel... Das CallMethod selbst ist ja noch in Ordnung, es wird nur ein Fehler-Cdoe zurückgegeben... Ich werde mal versuchen, dessen Bedeutung herauszufinden und melde mich nochmal, wenn ich etwas neues weiß...

MfG

Sebastian
 
Windows XP, XProfan/Profan² 4.5 bis 11
Profan2Cpp-Homepage:  [...] 
Alte Profan²-Seite:  [...] 
17.05.2006  
 




Sebastian
König
Hallo Georg,

Der Code steht für RPC_E_CANTCALLOUT_ININPUTSYNCCALL. Die Beschreibung dafür lautet:

Ein ausgehender Aufruf kann nicht ausgeführt werden, da die Anwendung einen Eingabe-synchronisierten Aufruf weiterleitet.

Sehr komisch...

Da mir sonst nichts einfiel, hatte ich irgendwie das MultiThread-Konzept im Verdacht (der Gedanke kam mir, weil da ja angeblich irgendwas gleichzeitig stattfindet ...

Jedenfalls habe ich dann folgendes probiert: Call() und External() werden in den übersetzen Programmen ja grundsätzlich im Kontext des Haupt-Threads ausgeführt, weil man ja nie wissen kann, ob irgendwie Fenster oder Controls erstellt/bearbeitet werden... Es gibt jedoch eine Möglichkeit, dies zu ändern: Wenn ich den Code zunächst nur übersetze, also make.bat nicht automatisch starte, und in die erzeugte [Projektname].cpp-Datei (Achtung: nicht die PrfMain.cpp) nach den ganzen #include-Anweisungen die beiden Zeilen

#define External External_ST
#define Call Call_ST

einfüge, funktioniert es auf einmal...

Kannst Du das bestätigen?

MfG

Sebastian

P.S.: Das ganze scheint ein bekannter Windows-Bug zu sein... Gut möglich, dass es sich genau um das [...]  beschriebene Problem handelt. Der Abschnitt Symptoms beschreibt nämlich genau das aktuelle Problem
 
Windows XP, XProfan/Profan² 4.5 bis 11
Profan2Cpp-Homepage:  [...] 
Alte Profan²-Seite:  [...] 
17.05.2006  
 




Georg
Hovenbitzer
Hallo Sebastian,

deine Lösung funktioniert mit dem Demo sehr gut

Ich werde sie im laufe des Tages im Programm testen um zu sehen ob dort Schwierigkeiten auftreten.

Melde mich dann hier.
 
Viele Grüsse, Georg Hovenbitzer(Windows XP Pro, XProfan 11.2, Profan2Cpp 1.6a)
18.05.2006  
 




Sebastian
König
Hallo Georg,

leider ist es sehr wahrscheinlich, dass das pauschale Umstellen auf die *_ST-Versionen in Deinem Programm zu Problemen führt . In der Regel ist es ja wie schon erwähnt sogar notwendig, dass API-Funktion im Kontext des Haupt-Threads ausgeführt werden, da dort die ganze Fensterverwaltung stattfindet...

Ich habe inzwischen auch mal den unter dem Link (siehe PS in meinem Posting oben) gegebenen Vorschlag Use PostMessage instead of an inter-process/inter-thread SendMessage. ausprobiert - auch damit ist der Fehler behoben.

Das blöde ist nur: Die Alternative kommt eigentlich nicht in Frage. Ursprünglich hatte ich für External() und Call() tatsächlich PostThreadMessage() benutzt, bis irgendwann (ich glaube es war noch in der Beta-Phase vor der Veröffentlichung von Profan2Cpp) auffiel, dass es damit in Extremsituationen (sehr viele Aufrufe in sehr kurzer Zeit) zu Problemen kommen konnte . Mit dem Umstieg auf SendMessage() war dann alles in Ordnung und obendrein noch die Performance etwas besser, da ja der Umweg über die Nachrichtenschleife entfiel ...

So, jetzt nach dem ganzen Erklären, was nicht geht, mal ein Vorschlag zur Lösung des Problems :

Dass es in der Demo mit den _ST()-Funktionen auch bei Dir funktioniert, ist ja schonmal super! Meine Idee wäre jetzt, Profan2Cpp so zu erweitern, dass mit einer speziellen Anweisung im Profan-Code automatisch für einen bestimmten Abschnitt auf die _ST-Varianten umgeschaltet werden kann. Damit sich XProfan selbst nicht über unbekannte Befehle beschwert, würden sich spezielle Kommentare anbieten. In Deinem Code könnte es dann in etwa so aussehen:
KompilierenMarkierenSeparieren
Proc Runningie_gettext

    P2CPP: <USE_EXTERNAL_ST>
    Parameters Iehwnd&
    ...
    @External("ole32","CoUninitialize")
    Return Text$
    P2CPP: </USE_EXTERNAL_ST>

EndProc


Was hältst Du von dem Vorschlag?

MfG

Sebastian
 
Windows XP, XProfan/Profan² 4.5 bis 11
Profan2Cpp-Homepage:  [...] 
Alte Profan²-Seite:  [...] 
18.05.2006  
 




Georg
Hovenbitzer
Hallo Sebastian,

ich kann dich beruhigen

Mein Programm läuft nun ohne Fehler, es gab zwar ein paar seltsame Effekte wie z.B. dass ich alle DLLs mit UseDLL Laden musste, was ohne Übersetzen nicht nötig war.
Anderseits mach das Programm auch nicht viel, es ließt den Quelltext der Seite aus und sucht dort nach Links, speichert Bilder und Text Dateien.
Für die Zukunft wäre deine angedacht Lösung sehr vom Vorteil, da sie sehr leicht in den Profan Code einzubauen ist und man sich dadurch auch nicht die Möglichkeit nimmt deine Plugins zu benutzen (da ich noch nicht herausgefunden habe wie ich mit dem ResHacker Versions Informationen in eine Datei bekomme).
 
Viele Grüsse, Georg Hovenbitzer(Windows XP Pro, XProfan 11.2, Profan2Cpp 1.6a)
19.05.2006  
 




Sebastian
König
Hallo Georg,

wenn es sogar so schon funktioniert, ist das natürlich erst recht super!

Die vorgeschlagen Kommentar-Schalter werde ich dann in die nächste Version einbauen - für größtmögliche Flexibilität sogar getrennte Schalter für Call() und External(), die aber in einer einzigen Zeile gesetzt werden können, z.B.

P2CPP: <USE_EXTERNAL_ST,USE_CALL_ST>

MfG

Sebastian
 
Windows XP, XProfan/Profan² 4.5 bis 11
Profan2Cpp-Homepage:  [...] 
Alte Profan²-Seite:  [...] 
19.05.2006  
 




Georg
Hovenbitzer
Hallo Sebastian,

ich habe mich etwas zu früh gefreut

Ich habe dir mal ein Codebeispiel geschrieben der leider nach dem manuellen Einfügen von:
#define External External_ST
#define Call Call_ST
nicht funktioniert.
Das Problem liegt daran, dass &UwParam keinen Wert mehr erhält
KompilierenMarkierenSeparieren
Def RegisterHotKey(4) !"USER32.DLL","RegisterHotKey"
Def UnregisterHotKey(2) !"USER32.DLL","UnregisterHotKey"
Declare Edit&
Window 100,100-400,400
Edit& = @Create("Edit",%hWnd,"",100,100,150,20)
UserMessages $312
RegisterHotKey(%hWnd,11111,3,80) Strg + Alt + P

WhileNot %Key = 2

    WaitInput
    SetText Edit&,""
    DrawText 20,30,@Space$(30)
    DrawText 20,20,"&UwParam = " + @Str$(&UwParam)

    If ((&UwParam = 11111) And (%GetFocus = Edit&))

        SetText Edit&,"TREFFER !"

    EndIf

EndWhile

UnRegisterHotKey(%hWnd,11111)
UserMessages 0
End
 
Viele Grüsse, Georg Hovenbitzer(Windows XP Pro, XProfan 11.2, Profan2Cpp 1.6a)
23.05.2006  
 



Mir viel da auch noch was ein!

P2CPP: <USE_EXTERNAL_ST,USE_CALL_ST>

Ist denkbar schlecht als Indikator - Rems sollten immer wegoptimierbar sein.

XProfan selbst hat schon solch tollen Befehl SET 

Warum also nicht
KompilierenMarkierenSeparieren
set("P2CPP:...",1)

Ich glaub das wäre eleganter.
 
23.05.2006  
 




Sebastian
König
Hallo iF,

[quote:26d3b84306]XProfan selbst hat schon solch tollen Befehl SET

Warum also nicht

Set(P2CPP:...,1)

Ich glaub das wäre eleganter. [/quote:26d3b84306]
das geht leider aus 2 Gründen nicht:

1. Die Information muss schon zum Zeitpunkt der Übersetzung zur Verfügung stehen - bei Set() ist das leider nicht so, weil man ja auch eine Stringvariable benutzen könnte... (dehalb ließ sich zum Beispiel das @Set(ESCAPE, n%) von XProfan 9 nicht richtig umsetzen ).

2. XProfan würde eine solche Anweisung mit Unbekannter Schalter: P2PP... quittieren...

Oh, gerade fällt mir noch ein:

3. Abwärtskompatibilität! Ältere Profan²-Versionen kennen gar kein Set()...

Kannst Du dem XPSE nicht einfach beibringen, bei bestimmten Kommentaren ein bischen Zurückhaltung zu üben?

MfG

Sebastian
 
Windows XP, XProfan/Profan² 4.5 bis 11
Profan2Cpp-Homepage:  [...] 
Alte Profan²-Seite:  [...] 
24.05.2006  
 



[quote:a8da9240c6=Sebastian König]Hallo iF,

[quote:a8da9240c6]XProfan selbst hat schon solch tollen Befehl SET

Warum also nicht

Set(P2CPP:...,1)

Ich glaub das wäre eleganter. [/quote:a8da9240c6]
das geht leider aus 2 Gründen nicht...

...Kannst Du dem XPSE nicht einfach beibringen, bei bestimmten Kommentaren ein bischen Zurückhaltung zu üben?

[/quote:a8da9240c6]
Ohhhh mein Gott.

Ok, noch ne Idee: p2cppcompiler$=blub
 
24.05.2006  
 




Sebastian
König
[quote:f983247403]Ohhhh mein Gott.

Ok, noch ne Idee: p2cppcompiler$=blub [/quote:f983247403]
Ich weiß jetzt nicht so ganz, was Du meinst...

Die Lösung mit diesen Kommentar-Befehlen gefällt mir eigentlich auch ziemlich gut, weil sie sehr flexibel ist (man könnte sogar für einzelne Aufrufe das Verhalten ändern), den XProfan-Interpreter bzw. Compiler überhaupt nicht stört und auch gar keinen unnötigen Overhead erzeugt...
 
Windows XP, XProfan/Profan² 4.5 bis 11
Profan2Cpp-Homepage:  [...] 
Alte Profan²-Seite:  [...] 
24.05.2006  
 




Antworten


Thementitel, max. 100 Zeichen.
 

Systemprofile:

Kein Systemprofil angelegt. [anlegen]

XProfan:

 Beitrag  Schrift  Smilies  ▼ 

Bitte anmelden um einen Beitrag zu verfassen.
 

Themenoptionen

5.968 Betrachtungen

Unbenanntvor 0 min.
Normann Strübli05.02.2023

Themeninformationen



Admins  |  AGB  |  Anwendungen  |  Autoren  |  Chat  |  Datenschutz  |  Download  |  Eingangshalle  |  Hilfe  |  Händlerportal  |  Impressum  |  Mart  |  Schnittstellen  |  SDK  |  Services  |  Spiele  |  Suche  |  Support

Ein Projekt aller XProfaner, die es gibt!


Mein XProfan
Private Nachrichten
Eigenes Ablageforum
Themen-Merkliste
Eigene Beiträge
Eigene Themen
Zwischenablage
Abmelden
 Deutsch English Français Español Italia
Übersetzungen

Datenschutz


Wir verwenden Cookies nur als Session-Cookies wegen der technischen Notwendigkeit und bei uns gibt es keine Cookies von Drittanbietern.

Wenn du hier auf unsere Webseite klickst oder navigierst, stimmst du unserer Erfassung von Informationen in unseren Cookies auf XProfan.Net zu.

Weitere Informationen zu unseren Cookies und dazu, wie du die Kontrolle darüber behältst, findest du in unserer nachfolgenden Datenschutzerklärung.


einverstandenDatenschutzerklärung
Ich möchte keinen Cookie