Delphi-PRAXiS

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Win32/Win64 API (native code) (https://www.delphipraxis.net/17-win32-win64-api-native-code/)
-   -   Delphi Anfängerfrage: InternalGetWindowText verwenden (https://www.delphipraxis.net/25228-anfaengerfrage-internalgetwindowtext-verwenden.html)

flotschie 3. Jul 2004 00:19


Anfängerfrage: InternalGetWindowText verwenden
 
hallo,

also ich bin zwar kein delphi programmierer aber ich ich glaube meine frage kann ich auch hier stellen:

es gibt in der windows API die Funktion

Code:
int InternalGetWindowText(HWND hWnd,
    LPWSTR lpString,
    int nMaxCount
);
die einen Text liefern soll (von mir auch kann man hier auch GetWindowText verwenden :-))

Anfängerfrage: Wie man sehen kann liefert diese Funktion einen integer wert zurück und keinen string! Das versteh ich nicht ganz....

Wenn ich ein Code-Beispiel für vb verwende, nämlich

Code:
Dim textlen As Long ' receives length of text of the window
Dim wintext As String ' receives the text of the window
Dim slength As Long ' receives the length of the returned string

' Find out how many characters are in the window's text.
' Add 1 to compensate for the terminating null.
textlen = GetWindowTextLength(Form1.hWnd) + 1
' Make sufficient room in the buffer.
wintext = Space(textlen)
' Retrieve the text of window Form1.
slength = GetWindowText(Form1.hWnd, wintext, textlen)
' Remove the empty space from the string, if any.
wintext = Left(wintext, slength)
' Display the result.
Debug.Print "The title bar of window Form1 is: "; wintext

funktionierts bei mir nicht weil ich VB.NET programmiere und es da keine Left Anweisung mehr gibt - aber an dem solls nicht scheitern. Überhaupt liefert mir ja fast jede API funktion einen integer oder long wert zurück, auch wenn man strings haben will. Wie bekomme ich denn nun meinen string?

NicoDE 3. Jul 2004 00:28

Re: Anfängerfrage: InternalGetWindowText verwenden
 
Wie ein dem von Dir gezeigten VB-Beispiel zu sehen sit, wird erst ermittelt wie lang der Text ist (GetWindowTextLength) und ein String mit entsprechender Länge angelegt. Dieser String wird GetWindowText übergeben, damit die Funktion ihn füllt. Der Rückgabewert gibt dann an, wieviele Zeichen in den String (der ja als Ausgabepuffer benutzt wurde) geschrieben wurden.

flotschie 3. Jul 2004 01:09

Re: Anfängerfrage: InternalGetWindowText verwenden
 
danke für die schnelle antwort, aber ich glaub schon langsam das ich zu doof bin das zu verstehen...

wie komme ich dann schlussendlich dorthin dass ich schreiben kann

Code:
dim mystring as string
mystring = <string>
??

flotschie 3. Jul 2004 01:15

Re: Anfängerfrage: InternalGetWindowText verwenden
 
aber moment...schon langsam verstehe ich es ....

also, den string im beispiel fülle ich ja zuerst mal mit Leerzeichen, die so lang sind wie der text...und dann wird dieser leere string als parameter einer funktion übergeben....und ist dann ab dieser übergabe mit dem eigetnlichen text befüllt? Dann hat die zuweisung dieser funktion zu der variablen slength nur den zweck (ausser nacher dem abschneiden), das der übergabeparameter wintext befüllt wird...?! *ganzseltsamvorkomm* :?:

flotschie 3. Jul 2004 01:18

Re: Anfängerfrage: InternalGetWindowText verwenden
 
heisst das dann...das diese funktionen eigetnlich keine funktionen sind, so wie ich sie kenne.....sondern dass diese funktionen die übergabeparameter bearbeiten? normalerweise kenn ich ja funktionen in dem sinn:

Code:
function wert_ausrechnen(byval wert1 as int, byval wert2 as int)

Wert_ausrechnen = wert1*wert2

end function

NicoDE 3. Jul 2004 01:39

Re: Anfängerfrage: InternalGetWindowText verwenden
 
Zitat:

Zitat von flotschie
heisst das dann...das diese funktionen eigetnlich keine funktionen sind, so wie ich sie kenne.....sondern dass diese funktionen die übergabeparameter bearbeiten?

So ist es.

Zitat:

Zitat von flotschie
byval wert1 as int

Oben genannter Fall ist nicht byval (by value - es wird der Wert der Variablen übergeben), sondern byref (by reference - es wird eine Referenz auf die Variable übergeben). In letzterem Fall kann/soll sich der Inhalt der Variablen (dessen Referenz übergeben wude) ändern.

Dadurch ist sind API-Funktionen in der Lage Werte in Strukturen (auch mehrere) zurückzugeben. Und der Rückgabewert gibt meist Auskunft darüber, ob der Aufruf erfolgreich war.

dizzy 3. Jul 2004 01:41

Re: Anfängerfrage: InternalGetWindowText verwenden
 
Variable Parameter sind bei Leibe keine Seltenheit ;)
Sehr viele API-Funktionen liefern lediglich einen Errorcode zurück, und die eigentliche Wertzuweisung passiert an einen der Parameter. Im Regelfall bekommst du von einer Fkt. den Wert 0 zurück wenn alles glatt ging, und irgend etwas "nicht 0" wenn's Probleme gab.
Aber die Win32-API ist sich in ihrer Vorgehensweise da sehr uneinig, weswegen sich ein Blick ins MSDN oder PSDK immer lohnt.

n8i,
dizzy

\\edit: woosso! war ich wieder laaaangsaaammmm...

NicoDE 3. Jul 2004 01:49

Re: Anfängerfrage: InternalGetWindowText verwenden
 
Zitat:

Zitat von flotschie
den string im beispiel fülle ich ja zuerst mal mit Leerzeichen, die so lang sind wie der text

So lang sind wie der Text + 1 (da die API-Funktion bei ihren 'Strings' keine Längenangabe speichert oder kennt, sondern am Ende eine 0 anhängt und dadurch weiß, wan der String zu Ende ist - deswegen muss genug Platz für den Text und das Null-Byte reserviert werden).

Zitat:

Zitat von flotschie
Dann hat die zuweisung dieser funktion zu der variablen slength nur den zweck (ausser nacher dem abschneiden), das der übergabeparameter wintext befüllt wird...?

Visual Basic hat für sein String-Objekt eine Länge gespeichert. Diese Länge enthält aber auch das abschliessende Null-Byte. Um den String wieder zu kürzen (bzw. um Fehler abzufangen) werden nur die Zeichen kopiert, die die Funktion in den String-Puffer geschrieben hat (ohne Null-Byte).

\\edit@dizzy: keine Sorge, ich hab gerade noch länger gebraucht :)

flotschie 3. Jul 2004 10:06

Re: Anfängerfrage: InternalGetWindowText verwenden
 
so danke für die antworten instweilen, hab versucht mein neues wissen gleich anzuwenden :-)

1. Zuerstmal hab ich die funktion mal so declared:


Code:
Private Declare Function GetWindowText Lib "user32.dll" Alias "GetWindowTextA" (ByVal hWnd As Long, [b]ByRef[/b] lpString As String, ByVal nMaxCount As Long) As Long
--> byref damit die variable überschrieben werden kann - richtig bis jetzt?

2. bekomm ich schon vorher im programm einen fehler, und zwar nach folgendem code:

[code]Dim proz As Process = Process.GetProcessById("572")
Dim Pufferlänge As Long, Puffer As String
Dim find1 As Long
find1 = FindWindow(vbNullString, proz.MainWindowTitle)
Pufferlänge = GetWindowTextLength(find1) + 1
Puffer = Space(CInt(Pufferlänge))[/code]

...also mit find1 bekomme ich einmal den Handle des Fensters.
...mit Pufferlänge und getwindowtextlenght die Puffergrösse des textes + 1
...will ich aber in der nächsten Zeile den Puffer mit Leerzeichen befüllen bekomm ich einen Überlauf...
...kein Wunder wenn die Pufferlänge 18320440699125828 beträgt :roll:

Da kann doch was nicht stimmen oder? Der Text ist niemals so lang....also irgendwas ist da falsch.

P.s.: Wirklich danke für die Antworten obwohl ich euer Delphi-Forum mit Vb zuspamme :stupid:

NicoDE 3. Jul 2004 10:33

Re: Anfängerfrage: InternalGetWindowText verwenden
 
Zitat:

Zitat von flotschie
Zuerstmal hab ich die funktion mal so declared

Versuchs damit: http://www.vbarchiv.net/vbapi/GetWindowTextLength.php

Warum lpString als ByVal definiert ist ist eine lange Geschichte :)
Kurzfassung der Interna:
- bei ByRef generiert der Compiler grundsätzlich Code, in welchem die Adresse der Variablen an die Funktion übergeben wird.
- bei ByVal generiert der Compiler fast immer Code, in welchem der Inhalt der Variablen an die Funktion übergeben wird - aber nicht für alle Typen (zum Beispiel wird bei Strings die Adresse des ersten Zeichens übergeben - die Grundregel ist: von allem was nicht in ein Prozessor-Register passt, wird die Adresse des ersten Bytes übergeben).

Eigentlich musst Du das nicht alles Wissen, da gerade die VB-Leute ware API-Import-Freaks sind (Visual Basic war nicht dafür konzipiert Funktionen der Win32-API direkt aufzurufen...).


Google ist Dein Freund :)

flotschie 3. Jul 2004 11:11

Re: Anfängerfrage: InternalGetWindowText verwenden
 
thx NicoDE,

google war und ist noch immer mein freund, aber gestern nach stundenlangem suchen konnte ich einfach nicht mehr :zwinker:

Gute Nachricht: Bei mir klappts jetzt. Ich bin draufgekommen dass ich einfach alle Parameterwerte in den funktionen, die Long sind, auf Integer geändert habe, und auch die Rückgabewerte der Funktionen auf Integer.

Also vorher hats so ausgesehn:

Code:
Declare Function GetWindowText Lib "user32.dll" Alias "GetWindowTextA" (ByVal hWnd As Long, ByVal lpString As String, ByVal nMaxCount As Long) As Long
und jetzt bei mir siehts so aus:

Code:
Declare Function GetWindowText Lib "user32" Alias "GetWindowTextA" (ByVal hwnd As Integer, ByVal lpString As String, ByVal cch As Integer) As Integer
und siehe da, es funktioniert. Ich hoffe das hat keine schwerwiegenden Auswirkungen auf das System...

w3seek 3. Jul 2004 12:42

Re: Anfängerfrage: InternalGetWindowText verwenden
 
Nur zur Information:

InternalGetWindowText() sendet im Gegensatz zu GetWindowText() keine WM_GETTEXT bzw WM_GETTEXTLENGTH messages, wenn das Fenster zum eigenen Prozess gehoert. Wenn man InternalGetWindowText() verwenden moechte sollte man aber konsequenterweise auch auf GetWindowTextLength() verzichten, da man die Laenge des Strings (in Zeichen!) auch mit InternalGetWindowText() bekommt, indem man die letzten beiden Parameter auf NULL/nil bzw 0 setzt. Bedenkt auch, dass InternalGetWindowText() nur als Unicode-Funktion implementiert ist! Die Laenge wie viele Bytes kopiert wurden oder wie lang der String ist, ist immer in Zeichen (Characters) angegeben, nicht in Bytes. Ein Zeichen in unicode hat 2 bytes, d.h. man muss also doppelt so viel Speicher reservieren. Ich bezweifle mal sehr, dass VB mit Unicode vernuenftig umgehen kann, deshalb ist GetWindowText()/GetWindowTextLength() in VB wohl die bessere Wahl.

flotschie 3. Jul 2004 16:32

Re: Anfängerfrage: InternalGetWindowText verwenden
 
danke w3seek....habe InternalGetWindowText schon probier aber es funkt net - fehlermeldung "Objektverweis wurde nicht auf eine Objektinstanz festgelegt" ....ist der grund das was du beschrieben hast?

flotschie 3. Jul 2004 20:12

Re: Anfängerfrage: InternalGetWindowText verwenden
 
ups....mit grosser verwunderung stell ich fest das man mit GetWindowText ja eigentlich nur die Titelleiste des Fenster auslesen kann! Sch* :wall: das brauch ich ja gar nicht!

... :wiejetzt: ...

Was ich wollte ist grundsätzlich mal den Inhalt eines Fensters (konkret: den eines Internet Explorers) auslesen, und zwar nicht den HTML-Quellcode sondern den effektiv angezeigten Text! jemand eine Ahnung wie ich das sonst machen könnte ausser mit GetWindowText oder überhaupt der Windows API? Bin auch bereit auf Delphi umzusteigen :coder:

Christian Seehase 3. Jul 2004 20:19

Re: Anfängerfrage: InternalGetWindowText verwenden
 
Moin Flotschie,

zum Thema Seiten auslesen, und Hier im Forum suchenHTML parsen (sonst kommst Du nicht an den Text) wirst Du hier einiges finden, allerdings natürlich in Delphi ;-)

So gesehen ist das

Zitat:

Zitat von flotschie
Bin auch bereit auf Delphi umzusteigen

eine gute Idee, wenn Du die Antworten hier finden willst...


Alle Zeitangaben in WEZ +1. Es ist jetzt 16:21 Uhr.

Powered by vBulletin® Copyright ©2000 - 2025, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024-2025 by Thomas Breitkreuz