syswin.inc 5.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188
  1. {
  2. This file is part of the Free Pascal run time library.
  3. Copyright (c) 1999-2008 by Florian Klaempfl and Pavel Ozerski
  4. member of the Free Pascal development team.
  5. FPC Pascal system unit part shared by win32/win64.
  6. See the file COPYING.FPC, included in this distribution,
  7. for details about the copyright.
  8. This program is distributed in the hope that it will be useful,
  9. but WITHOUT ANY WARRANTY; without even the implied warranty of
  10. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
  11. **********************************************************************}
  12. {****************************************************************************
  13. Error Message writing using messageboxes
  14. ****************************************************************************}
  15. function MessageBox(w1:longint;l1,l2:pointer;w2:longint):longint;
  16. stdcall;external 'user32' name 'MessageBoxA';
  17. const
  18. ErrorBufferLength = 1024;
  19. var
  20. ErrorBuf : array[0..ErrorBufferLength] of char;
  21. ErrorLen : SizeInt;
  22. Function ErrorWrite(Var F: TextRec): Integer;
  23. {
  24. An error message should always end with #13#10#13#10
  25. }
  26. var
  27. i : SizeInt;
  28. Begin
  29. while F.BufPos>0 do
  30. begin
  31. begin
  32. if F.BufPos+ErrorLen>ErrorBufferLength then
  33. i:=ErrorBufferLength-ErrorLen
  34. else
  35. i:=F.BufPos;
  36. Move(F.BufPtr^,ErrorBuf[ErrorLen],i);
  37. inc(ErrorLen,i);
  38. ErrorBuf[ErrorLen]:=#0;
  39. end;
  40. if ErrorLen=ErrorBufferLength then
  41. begin
  42. MessageBox(0,@ErrorBuf,pchar('Error'),0);
  43. ErrorLen:=0;
  44. end;
  45. Dec(F.BufPos,i);
  46. end;
  47. ErrorWrite:=0;
  48. End;
  49. Function ErrorClose(Var F: TextRec): Integer;
  50. begin
  51. if ErrorLen>0 then
  52. begin
  53. MessageBox(0,@ErrorBuf,pchar('Error'),0);
  54. ErrorLen:=0;
  55. end;
  56. ErrorLen:=0;
  57. ErrorClose:=0;
  58. end;
  59. Function ErrorOpen(Var F: TextRec): Integer;
  60. Begin
  61. TextRec(F).InOutFunc:=@ErrorWrite;
  62. TextRec(F).FlushFunc:=@ErrorWrite;
  63. TextRec(F).CloseFunc:=@ErrorClose;
  64. ErrorLen:=0;
  65. ErrorOpen:=0;
  66. End;
  67. procedure AssignError(Var T: Text);
  68. begin
  69. Assign(T,'');
  70. TextRec(T).OpenFunc:=@ErrorOpen;
  71. Rewrite(T);
  72. end;
  73. procedure SysInitStdIO;
  74. begin
  75. { Setup stdin, stdout and stderr, for GUI apps redirect stderr,stdout to be
  76. displayed in a messagebox }
  77. StdInputHandle:=longint(GetStdHandle(cardinal(STD_INPUT_HANDLE)));
  78. StdOutputHandle:=longint(GetStdHandle(cardinal(STD_OUTPUT_HANDLE)));
  79. StdErrorHandle:=longint(GetStdHandle(cardinal(STD_ERROR_HANDLE)));
  80. if not IsConsole then
  81. begin
  82. AssignError(stderr);
  83. AssignError(StdOut);
  84. Assign(Output,'');
  85. Assign(Input,'');
  86. Assign(ErrOutput,'');
  87. end
  88. else
  89. begin
  90. OpenStdIO(Input,fmInput,StdInputHandle);
  91. OpenStdIO(Output,fmOutput,StdOutputHandle);
  92. OpenStdIO(ErrOutput,fmOutput,StdErrorHandle);
  93. OpenStdIO(StdOut,fmOutput,StdOutputHandle);
  94. OpenStdIO(StdErr,fmOutput,StdErrorHandle);
  95. end;
  96. end;
  97. { ProcessID cached to avoid repeated calls to GetCurrentProcess. }
  98. var
  99. ProcessID: SizeUInt;
  100. function GetProcessID: SizeUInt;
  101. begin
  102. GetProcessID := ProcessID;
  103. end;
  104. {******************************************************************************
  105. Unicode
  106. ******************************************************************************}
  107. procedure Win32Unicode2AnsiMove(source:punicodechar;var dest:ansistring;len:SizeInt);
  108. var
  109. destlen: SizeInt;
  110. begin
  111. // retrieve length including trailing #0
  112. // not anymore, because this must also be usable for single characters
  113. destlen:=WideCharToMultiByte(CP_ACP, WC_NO_BEST_FIT_CHARS, source, len, nil, 0, nil, nil);
  114. // this will null-terminate
  115. setlength(dest, destlen);
  116. WideCharToMultiByte(CP_ACP, WC_NO_BEST_FIT_CHARS, source, len, @dest[1], destlen, nil, nil);
  117. end;
  118. procedure Win32Ansi2UnicodeMove(source:pchar;var dest:UnicodeString;len:SizeInt);
  119. var
  120. destlen: SizeInt;
  121. begin
  122. // retrieve length including trailing #0
  123. // not anymore, because this must also be usable for single characters
  124. destlen:=MultiByteToWideChar(CP_ACP, MB_PRECOMPOSED, source, len, nil, 0);
  125. // this will null-terminate
  126. setlength(dest, destlen);
  127. MultiByteToWideChar(CP_ACP, MB_PRECOMPOSED, source, len, @dest[1], destlen);
  128. end;
  129. function Win32UnicodeUpper(const s : UnicodeString) : UnicodeString;
  130. begin
  131. result:=s;
  132. UniqueString(result);
  133. if length(result)>0 then
  134. CharUpperBuff(LPWSTR(result),length(result));
  135. end;
  136. function Win32UnicodeLower(const s : UnicodeString) : UnicodeString;
  137. begin
  138. result:=s;
  139. UniqueString(result);
  140. if length(result)>0 then
  141. CharLowerBuff(LPWSTR(result),length(result));
  142. end;
  143. { there is a similiar procedure in sysutils which inits the fields which
  144. are only relevant for the sysutils units }
  145. procedure InitWin32Widestrings;
  146. begin
  147. { Widestring }
  148. widestringmanager.Wide2AnsiMoveProc:=@Win32Wide2AnsiMove;
  149. widestringmanager.Ansi2WideMoveProc:=@Win32Ansi2WideMove;
  150. widestringmanager.UpperWideStringProc:=@Win32WideUpper;
  151. widestringmanager.LowerWideStringProc:=@Win32WideLower;
  152. {$ifndef VER2_2}
  153. { Unicode }
  154. widestringmanager.Unicode2AnsiMoveProc:=@Win32Unicode2AnsiMove;
  155. widestringmanager.Ansi2UnicodeMoveProc:=@Win32Ansi2UnicodeMove;
  156. widestringmanager.UpperUnicodeStringProc:=@Win32UnicodeUpper;
  157. widestringmanager.LowerUnicodeStringProc:=@Win32UnicodeLower;
  158. {$endif VER2_2}
  159. end;