Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

We've found an much easier way to create a Unicode message loop in Delphi

134 views
Skip to first unread message

xmlBlueprint Team

unread,
Dec 21, 2005, 1:00:03 PM12/21/05
to
FYI,

To support Unicode in Delphi, you need to replace PeekMessage() and
DispatchMessage() with PeekMessageW() and DispatchMessageW(). In Delphi this
is a bit tricky, because the message loop is hidden within TApplication.
Other solutions replace TAppliction with TApplicationW by copying the
Forms.pas source code and making the necessary changes. And don't forget
make the necessary changes to method TForm.ShowModal, because otherwise your
main window will support Unicode, but your modal dialog boxes won't.

However, we've found a much easier solution that works. A runtime(!)
overwrite PeekMessage() with a relative jump (JMP) to PeekMessageW() and
similar for DispatchMessage(). This is allowed, because the parameters of
the ANSI versions of the functions are exactly the same as the WIDE
versions. The function you need is VirtualProtect (Windows API), this allows
you to make changes in your program at runtime:

procedure Swap(P: Pointer; NewData: Pointer; OldData: Pointer; Size:
Integer);
var
OldProtect: DWORD;
begin
VirtualProtect(P, Size, PAGE_EXECUTE_READWRITE, OldProtect);

Move({Src}P^, {Dst}OldData^, {Count}Size);
Move({Src}NewData^, {Dst}P^, {Count}Size);

VirtualProtect(P, Size, OldProtect, OldProtect);
end;

With function Swap() you can make the actual changes:

type
TCode = packed record
JMP: Byte;
Distance: Integer;
end;
PNewCode = ^TCode;

procedure RedirectCall(OldMethod: Pointer; NewMethod: Pointer; var OldCode:
TCode);
var
NewCode: TCode;
begin
NewCode.JMP := $E9; // jump rel32
NewCode.Distance := Integer(NewMethod) - Integer(OldMethod) -
SizeOf(NewCode);

Swap(OldMethod, @NewCode, @OldCode, SizeOf(TCode));
end;

var
CodeDispatchMessage: TCode;
CodeGetMessage: TCode;
CodePeekMessage: TCode;

initialization
case Win32Platform of
// Windows NT, 2000, XP //
VER_PLATFORM_WIN32_NT: begin
RedirectCall(@DispatchMessage, @DispatchMessageW,
CodeDispatchMessage);
RedirectCall(@GetMessage, @GetMessageW, CodeGetMessage);
RedirectCall(@PeekMessage, @PeekMessageW, CodePeekMessage);
end;
end;
end.

Please remember that you will have to make other changes as well, such as
change CreateWindow() to CreateWindowW(), please see other postings.

If you have questions, you can contact us via our website.

Hope you like it,

- gerben abbink
xmlBlueprint XML Editor
www.xmlblueprint.com


Riki Wiki

unread,
Jan 1, 2006, 5:23:49 PM1/1/06
to
On Wed, 21 Dec 2005 19:00:03 +0100, xmlBlueprint Team wrote:

> To support Unicode in Delphi, you need to replace PeekMessage() and
> DispatchMessage() with PeekMessageW() and DispatchMessageW(). In Delphi this
> is a bit tricky, because the message loop is hidden within TApplication.

Hoi

This newsgroup do not officially exist, that is why there is so few
messages here. Rather use b.p.d.internationalization.win32. Further you
need to repost your message/question on the Borland news server to make
everybody see it.

Take a look here:
<http://tinyurl.com/8m5nw>
which links to
<http://delphi.wikicities.com/wiki/Delphi_Newsgroups>

0 new messages