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 WM_GETTEXT + Unicode (https://www.delphipraxis.net/32357-wm_gettext-unicode.html)

toms 22. Okt 2004 08:47


WM_GETTEXT + Unicode
 
Hi,

Wie muss diese Funktion aussehen, wenn sie Unicode Strings zurückgeben sollte?

..SendMessage durch SendMessageW ersetzen und dann?

Delphi-Quellcode:
function GetWindowText(wnd: HWND): string;
var
  TextLength: Integer;
  Text: PChar;
begin
  Result := '';
  if wnd = 0 then
    Exit;
  TextLength := SendMessage(wnd, WM_GETTEXTLENGTH, 0, 0);
  if TextLength <> 0 then
  begin
    GetMem(Text, TextLength + 1);
    SendMessage(wnd, WM_GETTEXT, TextLength + 1, Integer(Text));
    Result := Text;
    FreeMem(Text);
  end;
end;

Luckie 22. Okt 2004 08:51

Re: WM_GETTEXT + Unicode
 
Musst du nicht die doppelte Länge an Speicher reservieren? WM_GETTEXTLENGTH gibt dochnur die Anzahl der Zeichen zurück:
Zitat:

Under certain conditions, the DefWindowProc function returns a value that is larger than the actual length of the text. This occurs with certain mixtures of ANSI and Unicode, and is due to the system allowing for the possible existence of double-byte character set (DBCS) characters within the text. The return value, however, will always be at least as large as the actual length of the text;
Aber Unicode verwendet doch 2 Byte pro Zeichen.

toms 22. Okt 2004 08:57

Re: WM_GETTEXT + Unicode
 
So, habe mal ein wenig herumprobiert.
Wenn ich TextLength * 4 funktioniert's.
Stimmt's etwa so oder gibt's noch was anderes zu beachten?

Delphi-Quellcode:
function GetWindowText(wnd: HWND): WideString;
var
  TextLength: Integer;
  Text: PWideChar;
begin
  Result := '';
  if wnd = 0 then
    Exit;
  TextLength := SendMessageW(wnd, WM_GETTEXTLENGTH, 0, 0);
  if TextLength <> 0 then
  begin
    GetMem(Text, TextLength * 2  + 1);
    SendMessageW(wnd, WM_GETTEXT, TextLength + 1, Integer(Text));
    Result := Text;
    FreeMem(Text);
  end;
end;

Luckie 22. Okt 2004 09:03

Re: WM_GETTEXT + Unicode
 
Warum denn mal vier? :gruebel: Mal zwei sollte reichen.

toms 22. Okt 2004 09:08

Re: WM_GETTEXT + Unicode
 
Zitat:

Warum denn mal vier? Mal zwei sollte reichen.
Hab es auch zuerst mit mal 2 ausprobiert aber hat dann den Text abgeschnitten.
Funktioniert jetzt aber seltsamerweise mit Mal 2 (hatte wohl etwas anderes noch geändert)

Luckie 22. Okt 2004 09:10

Re: WM_GETTEXT + Unicode
 
Zitat:

Zitat von toms
Funktioniert jetzt aber seltsamerweise mit Mal 2 (hatte wohl etwas anderes noch geändert)

Hätte auch sonst mein Weltbild vom Unicode-Zeichensatz zerstört. ;)

Bernhard Geyer 22. Okt 2004 10:28

Re: WM_GETTEXT + Unicode
 
Zitat:

Zitat von Luckie
Zitat:

Zitat von toms
Funktioniert jetzt aber seltsamerweise mit Mal 2 (hatte wohl etwas anderes noch geändert)

Hätte auch sonst mein Weltbild vom Unicode-Zeichensatz zerstört. ;)

Wieso? Unicode-Zeichen sind doch mit 4 Byte definiert (ist ja mittlerweile bis #$10FFFD definiert)? Windows verwendet jedoch bis NT nur die 2-Byte-Version von Unicode 2.0. Ab 2000 werden die Strings UTF-16-Codiert definiert. :-)
Aber alles > #$FFFD ist eh noch nicht relevant.

Assarbad 27. Okt 2004 21:36

Re: WM_GETTEXT + Unicode
 
Zitat:

Zitat von Luckie
Zitat:

Zitat von toms
Funktioniert jetzt aber seltsamerweise mit Mal 2 (hatte wohl etwas anderes noch geändert)

Hätte auch sonst mein Weltbild vom Unicode-Zeichensatz zerstört. ;)

Zitat:

Zitat von Bernhard Geyer
Wieso? Unicode-Zeichen sind doch mit 4 Byte definiert (ist ja mittlerweile bis #$10FFFD definiert)?

Ihr habt beide recht und unrecht. Das Problem ist, daß es verschiedene Bereiche von Unicode gibt und auch verschiedene Kodierungsmöglichkeiten - inklusive derer die mit 8bit pro Zeichen auskommen und dennoch ÜBER 64k Zeichen darstellen können (UTF8 nämlich). Entscheidend ist *hier* aber wie Windows das kodiert und das hat Barnhard schon erläutert. Daß sie mit 4 Byte definiert sind kann ich genauso verneinen, denn in 10 Jahren sind es vielleicht bereits 8 Byte (Minimum!) - und Minimum ist hier die wichtige Angabe.

Statt es mal 2 zu nehmen sollte man IMMER sizeof(WideChar) benutzen (denn die Definition von WideChar kann sich ändern). Außerdem sollte man zur Textlänge 1 addieren für die schließende #0.


Alle Zeitangaben in WEZ +1. Es ist jetzt 05:10 Uhr.

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