DrGraph图形博士

导航

CB2010的一个BUG:在Win2K SP4之前的系统上会出问题

Delphi2010/CB2010的一个BUG.在Win2K SP4之前的系统上会出问题.

解决代码是:

 

 1 unit D2009Win2kFix; 
 2 
 3 {
 4   Inno Setup
 5   Copyright (C) 1997-2010 Jordan Russell
 6   Portions by Martijn Laan
 7   For conditions of distribution and use, see LICENSE.TXT. 
 8 
 9   When Windows 2000 with SP<4 is detected, this unit reverts the change in
10   Delphi 2009 Update 3 that causes VCL apps (even new, empty projects) to
11   crash on startup when run on Windows 2000 with no SP/SP1/SP2/sometimes SP3. 
12 
13   This should be at the top of the .dpr's "uses" clause to ensure it runs
14   before any VCL code. 
15 
16   $jrsoftware: issrc/Projects/D2009Win2kFix.pas,v 1.1 2010/03/03 18:50:21 jr Exp $
17 } 
18 
19 interface 
20 
21 implementation 
22 
23 {$IFDEF VER200}
24   {$DEFINE Delphi2009Or2010}
25 {$ENDIF}
26 {$IFDEF VER210}
27   {$DEFINE Delphi2009Or2010}
28 {$ENDIF} 
29 
30 {$IFDEF Delphi2009Or2010}   { Only Delphi 2009/2010 }
31 uses
32   Windows, SysUtils; 
33 
34 {
35   Details:
36   In Delphi 2009 Update 3 (or possibly one of the previous updates),
37   TUTF8Encoding.Create in SysUtils was changed to set the
38   MB_ERR_INVALID_CHARS flag: 
39 
40          original: inherited Create(CP_UTF8);
41     with Update 3: inherited Create(CP_UTF8, MB_ERR_INVALID_CHARS, 0); 
42 
43   It appears that when used with CP_UTF8, the MB_ERR_INVALID_CHARS flag is
44   only supported beginning with Windows 2000 SP4 and Windows XP. On Windows
45   2000 with no SP, MultiByteToWideChar() fails with ERROR_INVALID_FLAGS. 
46 
47   In Delphi 2010 Update 1 this change is still present. 
48 
49   This code changes TEncoding.UTF8's private FMBToWCharFlags field from
50   MB_ERR_INVALID_CHARS back to 0 when Windows 2000 (5.0) with SP<4 is
51   detected. 
52 
53   Note: This won't fix any other instances of TUTF8Encoding, but there
54   shouldn't be more than just the one. (Inside the Delphi RTL/VCL,
55   TEncoding.GetUTF8 is the only place where TUTF8Encoding.Create is called.)
56 } 
57 
58 function NeedWin2kFix: Boolean;
59 var
60   Info: TOSVersionInfoEx;
61 begin
62   Result := False;
63   Info.dwOSVersionInfoSize := SizeOf(Info);
64   if GetVersionEx(Info) then
65     if (Info.dwMajorVersion = 5) and (Info.dwMinorVersion = 0) and
66        (Info.wServicePackMajor < 4) then
67       Result := True;
68 end; 
69 
70 procedure ApplyWin2kFix;
71 type
72   PLongWordArray = ^TLongWordArray;
73   TLongWordArray = array[0..6] of LongWord;  { 28 bytes }
74 var
75   U: SysUtils.TEncoding;
76 begin
77   U := SysUtils.TEncoding.UTF8;
78   if (U.ClassType = SysUtils.TUTF8Encoding) and
79      (U.InstanceSize = 28) and
80      (U is SysUtils.TMBCSEncoding) and
81      (SysUtils.TMBCSEncoding.InstanceSize = 28) then begin
82      if (PLongWordArray(U)[3] = 65001) and  { verify that FCodePage = CP_UTF8 }
83         (PLongWordArray(U)[4] = 8) and      { verify that FMBToWCharFlags = MB_ERR_INVALID_CHARS }
84         (PLongWordArray(U)[5] = 0) then     { verify that FWCharToMBFlags = 0 }
85        PLongWordArray(U)[4] := 0;          { change FMBToWCharFlags to 0 }
86   end;
87 end; 
88 
89 initialization
90   if NeedWin2kFix then
91     ApplyWin2kFix;
92 {$ENDIF}
93 end.

 

 


转成C代码 

 1 void ApplyWin2kFix()
 2 {
 3  OSVERSIONINFOEX osvi;
 4  osvi.dwOSVersionInfoSize = sizeof(OSVERSIONINFOEX);
 5  GetVersionEx((LPOSVERSIONINFO) & osvi); 
 6 
 7  //Win2000 -- Win2KSP3
 8  if (osvi.dwMajorVersion == 5 && osvi.dwMinorVersion == 0 && osvi.wServicePackMajor < 4)
 9  {
10   TEncoding * u = Sysutils::TEncoding::UTF8;
11   if (u->ClassName() == "TUTF8Encoding" && u->InstanceSize() == 28)
12   {
13    DWORD *p = (DWORD*)u;
14    if (p[3] == CP_UTF8 && p[4] == MB_ERR_INVALID_CHARS && p[5] == 0)
15     p[4] = 0;
16   }
17  }
18 }
19 //在工程中, 把 ApplyWin2kFix(); 加在 Application->Initialize();之前  

 

 

 

posted on 2013-04-16 14:28  drgraph  阅读(373)  评论(0编辑  收藏  举报