Various Windows unicode fixes.

git-svn-id: trunk@14146 -
This commit is contained in:
sekelsenmat 2008-02-15 20:23:58 +00:00
parent 108da51c02
commit 8023d99e58
5 changed files with 115 additions and 16 deletions

View File

@ -124,6 +124,8 @@ procedure BlendRect(ADC: HDC; const ARect: TRect; Color: ColorRef);
function GetLastErrorText(AErrorCode: Cardinal): String;
function BitmapToRegion(hBmp: HBITMAP; cTransparentColor: COLORREF = 0; cTolerance: COLORREF = $101010): HRGN;
function WideStrLCopy(dest, source: PWideChar; maxlen: SizeInt): PWideChar;
type
PDisableWindowsInfo = ^TDisableWindowsInfo;
TDisableWindowsInfo = record
@ -1771,6 +1773,25 @@ begin
FreeMem(Data);
end;
{ Exactly equal to StrLCopy but for PWideChars
Copyes a widestring up to a maximal length, in WideChars }
function WideStrLCopy(dest, source: PWideChar; maxlen: SizeInt): PWideChar;
var
counter: SizeInt;
begin
counter := 0;
while (Source[counter] <> #0) and (counter < MaxLen) do
begin
Dest[counter] := Source[counter];
Inc(counter);
end;
{ terminate the string }
Dest[counter] := #0;
Result := Dest;
end;
procedure DoInitialization;
begin

View File

@ -139,8 +139,10 @@ end;
*******************************************************************}
class function TWin32WSCustomTrayIcon.Show(const ATrayIcon: TCustomTrayIcon): Boolean;
var
tnid: TNotifyIconData;
buffer: PChar;
tnida: TNotifyIconDataA;
tnidw: TNotifyIconDataW;
AnsiBuffer: ansistring;
WideBuffer: widestring;
Window: Windows.TWndClassEx;
begin
vwsTrayIcon := ATrayIcon;
@ -175,20 +177,57 @@ begin
hInstance, //* handle to application instance */
nil); //* pointer to window-creation data */
// Fill TNotifyIconData
FillChar(tnid, SizeOf(tnid), 0);
tnid.cbSize := SizeOf(TNotifyIconData);
tnid.hWnd := ATrayIcon.Handle;
tnid.uID := uIDTrayIcon;
tnid.uFlags := NIF_MESSAGE or NIF_ICON;
if (ATrayIcon.Hint <> '') then tnid.uFlags := tnid.uFlags or NIF_TIP;
tnid.uCallbackMessage := WM_USER + uIDTrayIcon;
tnid.hIcon := ATrayIcon.Icon.Handle;
buffer := PChar(ATrayIcon.Hint);
StrCopy(@tnid.szTip, buffer);
{$ifdef WindowsUnicodeSupport}
if UnicodeEnabledOS then
begin
// Fill TNotifyIconDataW
FillChar(tnidw, SizeOf(tnidw), 0);
tnidw.cbSize := SizeOf(TNotifyIconDataW);
tnidw.hWnd := ATrayIcon.Handle;
tnidw.uID := uIDTrayIcon;
tnidw.uFlags := NIF_MESSAGE or NIF_ICON;
if (ATrayIcon.Hint <> '') then tnidw.uFlags := tnidw.uFlags or NIF_TIP;
tnidw.uCallbackMessage := WM_USER + uIDTrayIcon;
tnidw.hIcon := ATrayIcon.Icon.Handle;
// Create Taskbar icon
Result := Shell_NotifyIconA(NIM_ADD, @tnid);
WideBuffer := UTF8Decode(ATrayIcon.Hint);
WideStrLCopy(@tnidw.szTip, PWideChar(WideBuffer), 127);
Result := Shell_NotifyIconW(NIM_ADD, @tnidw)
end
else
begin
// Fill TNotifyIconDataA
FillChar(tnida, SizeOf(tnida), 0);
tnida.cbSize := SizeOf(TNotifyIconDataA);
tnida.hWnd := ATrayIcon.Handle;
tnida.uID := uIDTrayIcon;
tnida.uFlags := NIF_MESSAGE or NIF_ICON;
if (ATrayIcon.Hint <> '') then tnida.uFlags := tnida.uFlags or NIF_TIP;
tnida.uCallbackMessage := WM_USER + uIDTrayIcon;
tnida.hIcon := ATrayIcon.Icon.Handle;
AnsiBuffer := UTF8ToAnsi(ATrayIcon.Hint);
StrLCopy(@tnida.szTip, PChar(AnsiBuffer), 127);
Result := Shell_NotifyIconA(NIM_ADD, @tnida);
end;
{$else}
// Fill TNotifyIconDataA
FillChar(tnida, SizeOf(tnida), 0);
tnida.cbSize := SizeOf(TNotifyIconDataA);
tnida.hWnd := ATrayIcon.Handle;
tnida.uID := uIDTrayIcon;
tnida.uFlags := NIF_MESSAGE or NIF_ICON;
if (ATrayIcon.Hint <> '') then tnida.uFlags := tnida.uFlags or NIF_TIP;
tnida.uCallbackMessage := WM_USER + uIDTrayIcon;
tnida.hIcon := ATrayIcon.Icon.Handle;
StrLCopy(@tnida.szTip, PChar(ATrayIcon.Hint), 127);
// Create Taskbar icon
Result := Shell_NotifyIconA(NIM_ADD, @tnida);
{$endif}
end;
{*******************************************************************

View File

@ -1850,6 +1850,9 @@ begin
Result := Windows.GetTextExtentPoint32W(DC, PWideChar(W), Length(W), @Size);
end else
begin
// Important: Althougth the MSDN Docs point that GetTextExtentPoint32W
// works under Windows 9x, tests showed that this function produces
// a wrong output
s := Utf8ToAnsi(s);
Result := Windows.GetTextExtentPoint32(DC, pchar(s), length(s), @Size);
end;
@ -2196,8 +2199,20 @@ end;
and includes buttons.
------------------------------------------------------------------------------}
function TWin32WidgetSet.MessageBox(HWnd: HWND; LPText, LPCaption: PChar; UType: Cardinal): Integer;
{$ifdef WindowsUnicodeSupport}
var
WideLPText, WideLPCaption: widestring;
{$endif}
begin
{$ifdef WindowsUnicodeSupport}
WideLPText := UTF8Decode(string(LPText));
WideLPCaption := UTF8Decode(string(LPCaption));
Result := Windows.MessageBoxW(HWnd, PWideChar(WideLPText),
PWideChar(WideLPCaption), UType);
{$else}
Result := Windows.MessageBox(HWnd, LPText, LPCaption, UType);
{$endif}
end;
{------------------------------------------------------------------------------

View File

@ -435,7 +435,8 @@ begin
Move(FilterBuffer[1], lpStrFilter^, Length(FilterBuffer) * 2 + 2);
TitleBuffer := Utf8Decode(AOpenDialog.Title);
{$note AllocMem is used a workaround for a possible bug in Utf8Decode, it doesn't seem to null terminate the widestring}
{$note AllocMem is used a workaround for a possible bug in Utf8Decode,
it doesn't seem to null terminate the widestring}
lpStrTitle := AllocMem(Length(TitleBuffer) * 2 + 2);
Move(TitleBuffer[1], lpStrTitle^, Length(TitleBuffer) * 2);
end

View File

@ -899,13 +899,36 @@ end;
class procedure TWin32WSCustomComboBox.SetText(const AWinControl: TWinControl; const AText: string);
var
Handle: HWND;
AnsiBuffer: ansistring;
WideBuffer: widestring;
begin
Assert(False, Format('Trace:TWin32WSCustomComboBox.SetText --> %S', [AText]));
Handle := AWinControl.Handle;
{$ifdef WindowsUnicodeSupport}
if UnicodeEnabledOS then
begin
WideBuffer := UTF8Decode(AText);
if TCustomComboBox(AWinControl).ReadOnly then
Windows.SendMessageW(Handle, CB_SELECTSTRING, -1, LPARAM(PWideChar(WideBuffer)))
else
Windows.SendMessageW(Handle, WM_SETTEXT, 0, LPARAM(PWideChar(WideBuffer)));
end
else
begin
AnsiBuffer := UTF8ToAnsi(AText);
if TCustomComboBox(AWinControl).ReadOnly then
Windows.SendMessage(Handle, CB_SELECTSTRING, -1, LPARAM(PChar(AnsiBuffer)))
else
Windows.SendMessage(Handle, WM_SETTEXT, 0, LPARAM(PChar(AnsiBuffer)));
end;
{$else}
if TCustomComboBox(AWinControl).ReadOnly then
Windows.SendMessage(Handle, CB_SELECTSTRING, -1, LPARAM(PChar(AText)))
else
Windows.SendMessage(Handle, WM_SETTEXT, 0, LPARAM(PChar(AText)));
{$endif}
end;
class function TWin32WSCustomComboBox.GetItems(const ACustomComboBox: TCustomComboBox): TStrings;