diff --git a/lcl/interfaces/win32/win32object.inc b/lcl/interfaces/win32/win32object.inc
index e2feb136ad..00beae79ca 100644
--- a/lcl/interfaces/win32/win32object.inc
+++ b/lcl/interfaces/win32/win32object.inc
@@ -424,7 +424,7 @@ procedure TWin32WidgetSet.AppSetTitle(const ATitle: string);
 begin
   {$ifdef WindowsUnicodeSupport}
   if UnicodeEnabledOS 
-  then Windows.SetWindowTextW(FAppHandle, Utf8ToPWideChar(ATitle))
+  then Windows.SetWindowTextW(FAppHandle, PWideChar(Utf8Decode(ATitle)))
   else Windows.SetWindowText(FAppHandle, PChar(Utf8ToAnsi(ATitle)));
   {$else}
   Windows.SetWindowText(FAppHandle, PChar(ATitle));
@@ -541,7 +541,7 @@ Begin
       hCursor := LoadCursor(0, IDC_ARROW);
       hbrBackground := 0; {GetSysColorBrush(Color_BtnFace);}
       LPSzMenuName := Nil;
-      LPSzClassName := Utf8PCharToPWideChar(@ClsName);
+      LPSzClassName := PWideChar(WideString(ClsName));
     end;
     Result := Windows.RegisterClassW(@WindowClassW) <> 0;
   end
diff --git a/lcl/interfaces/win32/win32proc.pp b/lcl/interfaces/win32/win32proc.pp
index 1af90d76e4..f2d402a2b7 100644
--- a/lcl/interfaces/win32/win32proc.pp
+++ b/lcl/interfaces/win32/win32proc.pp
@@ -107,11 +107,6 @@ procedure RedrawMenus;
 function MeasureText(const AWinControl: TWinControl; Text: string; var Width, Height: integer): boolean;
 function GetControlText(AHandle: HWND): string;
 
-// String functions
-
-function Utf8PCharToPWideChar(param: PChar): PWideChar;
-function Utf8ToPWideChar(param: string): PWideChar;
-
 type
   PDisableWindowsInfo = ^TDisableWindowsInfo;
   TDisableWindowsInfo = record
@@ -1130,20 +1125,35 @@ end;
 function GetControlText(AHandle: HWND): string;
 var
   TextLen: dword;
+{$ifdef WindowsUnicodeSupport}
+  AnsiBuffer: string;
+  WideBuffer: WideString;
+{$endif}  
 begin
+{$ifdef WindowsUnicodeSupport}
+  if UnicodeEnabledOS then
+  begin
+    TextLen := Windows.GetWindowTextLengthW(AHandle);
+    SetLength(WideBuffer, TextLen);
+    TextLen := Windows.GetWindowTextW(AHandle, @WideBuffer[1], TextLen + 1);
+    SetLength(WideBuffer, TextLen);
+    Result := Utf8Encode(WideBuffer);
+  end
+  else
+  begin
+    TextLen := Windows.GetWindowTextLength(AHandle);
+    SetLength(AnsiBuffer, TextLen);
+    TextLen := Windows.GetWindowText(AHandle, @AnsiBuffer[1], TextLen + 1);
+    SetLength(AnsiBuffer, TextLen);
+    Result := AnsiToUtf8(AnsiBuffer);
+  end;
+
+ {$else}
   TextLen := GetWindowTextLength(AHandle);
   SetLength(Result, TextLen);
   GetWindowText(AHandle, PChar(Result), TextLen + 1);
-end;
 
-function Utf8PCharToPWideChar(param: PChar): PWideChar;
-begin
-  Result := PWideChar(Utf8Decode(string(param)));
-end;
-
-function Utf8ToPWideChar(param: string): PWideChar;
-begin
-  Result := PWideChar(Utf8Decode(param));
+ {$endif}
 end;
 
 procedure DoInitialization;
diff --git a/lcl/interfaces/win32/win32winapi.inc b/lcl/interfaces/win32/win32winapi.inc
index 39fdd00241..4ed5cffdd3 100644
--- a/lcl/interfaces/win32/win32winapi.inc
+++ b/lcl/interfaces/win32/win32winapi.inc
@@ -1114,10 +1114,36 @@ End;
 
  ------------------------------------------------------------------------------}
 function TWin32WidgetSet.DrawText(DC: HDC; Str: PChar; Count: Integer; var Rect: TRect; Flags: Cardinal): Integer;
+var
+  s: String;
+  w: WideString;
 begin
   Assert(False, Format('trace:> [TWin32WidgetSet.DrawText] DC:0x%x, Str:''%s'', Count: %d, Rect = %d,%d,%d,%d, Flags:%d',
     [DC, Str, Count, Rect.Left, Rect.Top, Rect.Right, Rect.Bottom, Flags]));
+
+ {$ifdef WindowsUnicodeSupport}
+  // use temp buffer, if count is set, there might be no null terminator
+  if count = -1
+  then s := str
+  else begin
+    SetLength(s, count);
+    move(str^, s[1], count);  
+  end;
+  // the length of utf8 vs Wide/Ansi the strings differ, so recalc.
+  if UnicodeEnabledOS 
+  then begin
+    // TODO: use the real number of chars (and not the lenght)
+    W := Utf8Decode(S);
+    Result := Windows.DrawTextW(DC, PWideChar(W), Length(W), @Rect, Flags);
+  end
+  else begin
+    S := Utf8ToAnsi(S);
+    Result := Windows.DrawText(DC, PChar(S), Length(S), @Rect, Flags);
+  end;
+ {$else}
   Result := Windows.DrawText(DC, Str, Count, @Rect, Flags);
+ {$endif}
+ 
   Assert(False, Format('trace:> [TWin32WidgetSet.DrawText] DC:0x%x, Str:''%s'', Count: %d, Rect = %d,%d,%d,%d, Flags:%d',
     [DC, Str, Count, Rect.Left, Rect.Top, Rect.Right, Rect.Bottom, Flags]));
 end;
@@ -1251,10 +1277,36 @@ end;
 
   Draws a character string by using the currently selected font.
  ------------------------------------------------------------------------------}
-Function TWin32WidgetSet.ExtTextOut(DC: HDC; X, Y: Integer; Options: Longint; Rect: PRect; Str: PChar; Count: Longint; Dx: PInteger): Boolean;
-Begin
+function TWin32WidgetSet.ExtTextOut(DC: HDC; X, Y: Integer; Options: Longint; Rect: PRect; Str: PChar; Count: Longint; Dx: PInteger): Boolean;
+var
+  s: String;
+  w: WideString;
+begin
   Assert(False, Format('trace:> [TWin32WidgetSet.ExtTextOut] DC:0x%x, X:%d, Y:%d, Options:%d, Str:''%s'', Count: %d', [DC, X, Y, Options, Str, Count]));
-  Result := Boolean(Windows.ExtTextOut(DC, X, Y, Options, LPRECT(Rect), Str, Count, Dx));
+
+{$ifdef WindowsUnicodeSupport}
+  // use temp buffer, if count is set, there might be no null terminator
+  if count = -1
+  then s := str
+  else begin
+    SetLength(s, count);
+    move(str^, s[1], count);  
+  end;
+  // the length of utf8 vs Wide/Ansi the strings differ, so recalc.
+  if UnicodeEnabledOS 
+  then begin
+    // TODO: use the real number of chars (and not the lenght)
+    W := Utf8Decode(S);
+    Result := Windows.ExtTextOutW(DC, X, Y, Options, LPRECT(Rect), PWideChar(W), Length(W), Dx);
+  end                                        
+  else begin
+    S := Utf8ToAnsi(S);
+    Result := Windows.ExtTextOut(DC, X, Y, Options, LPRECT(Rect), PChar(S), Length(S), Dx);
+  end;
+ {$else}
+  Result := Windows.ExtTextOut(DC, X, Y, Options, LPRECT(Rect), Str, Count, Dx);
+ {$endif}
+
   Assert(False, Format('trace:< [TWin32WidgetSet.ExtTextOut] DC:0x%x, X:%d, Y:%d, Options:%d, Str:''%s'', Count: %d', [DC, X, Y, Options, Str, Count]));
 End;
 
@@ -2056,9 +2108,33 @@ End;
   Computes the width and height of the specified string of text.
  ------------------------------------------------------------------------------}
 Function TWin32WidgetSet.GetTextExtentPoint(DC: HDC; Str: PChar; Count: Integer; Var Size: TSize): Boolean;
+var
+  s: String;
+  w: WideString;
 Begin
   Assert(False, 'Trace:[TWin32WidgetSet.GetTextExtentPoint] - Start');
-  Result := Boolean(Windows.GetTextExtentPoint32(DC, Str, Count, @Size));
+{$ifdef WindowsUnicodeSupport}
+  // use temp buffer, if count is set, there might be no null terminator
+  if count = -1
+  then s := str
+  else begin
+    SetLength(s, count);
+    move(str^, s[1], count);  
+  end;
+  // the length of utf8 vs Wide/Ansi the strings differ, so recalc.
+  if UnicodeEnabledOS 
+  then begin
+    // TODO: use the real number of chars (and not the lenght)
+    w := Utf8Decode(S);
+    Result := Windows.GetTextExtentPoint32W(DC, PWideChar(W), Length(W), @Size);
+  end
+  else begin
+    S := Utf8ToAnsi(S);
+    Result := Windows.GetTextExtentPoint32(DC, PChar(S), Length(S), @Size);
+  end;  
+{$else}
+    Result := Windows.GetTextExtentPoint32(DC, Str, Count, @Size);
+{$endif}
   Assert(False, 'Trace:[TWin32WidgetSet.GetTextExtentPoint] - Exit');
 End;
 
diff --git a/lcl/interfaces/win32/win32wscontrols.pp b/lcl/interfaces/win32/win32wscontrols.pp
index 8e206ea1fa..85047af938 100644
--- a/lcl/interfaces/win32/win32wscontrols.pp
+++ b/lcl/interfaces/win32/win32wscontrols.pp
@@ -203,8 +203,8 @@ begin
 
       {$ifdef WindowsUnicodeSupport}
       if UnicodeEnabledOS then
-        Window := CreateWindowExW(FlagsEx, Utf8PCharToPWideChar(pClassName),
-          Utf8PCharToPWideChar(WindowTitle), Flags,
+        Window := CreateWindowExW(FlagsEx, PWideChar(WideString(pClassName)),
+          PWideChar(Utf8Decode(WindowTitle)), Flags,
           Left, Top, Width, Height, Parent, MenuHandle, HInstance, Nil)
       else
         Window := CreateWindowEx(FlagsEx, pClassName, PChar(Utf8ToAnsi(WindowTitle)), Flags,
@@ -429,7 +429,7 @@ Begin
   then Exit;
 {$ifdef WindowsUnicodeSupport}
   if UnicodeEnabledOS 
-  then Windows.SetWindowTextW(AWinControl.Handle, Utf8ToPWideChar(AText))
+  then Windows.SetWindowTextW(AWinControl.Handle, PWideChar(Utf8Decode(AText)))
   else Windows.SetWindowText(AWinControl.Handle, PChar(Utf8ToAnsi(AText)));
 {$else}
   Windows.SetWindowText(AWinControl.Handle, PChar(AText));