2
0
Эх сурвалжийг харах

* patch by Dmitry Boyarintsev (bug #31023) improving compatibility of unit Crt under Win32 and Win64 to other platforms and original TP/BP - Ctrl-C now treated as ASCII 3 and Ctrl-Break respects CheckBreak setting

git-svn-id: trunk@35051 -
Tomas Hajny 8 жил өмнө
parent
commit
8038b2e64f

+ 53 - 1
packages/rtl-console/src/win/crt.pp

@@ -25,6 +25,9 @@ function WhereY32: DWord;
 
 implementation
 
+{$DEFINE FPC_CRT_CTRLC_TREATED_AS_KEY}
+(* Treatment of Ctrl-C as a regular key ensured during initialization (SetupConsoleInput). *)
+
 uses
   windows;
 
@@ -40,7 +43,7 @@ procedure TurnMouseOff;
 var Mode: DWORD;
 begin
   if GetConsoleMode(GetStdHandle(STD_INPUT_HANDLE), @Mode) then begin { Turn the mouse-cursor off }
-    Mode := Mode AND cardinal(NOT enable_processed_input)
+    Mode := Mode //AND cardinal(NOT enable_processed_input)
       AND cardinal(NOT enable_mouse_input);
 
     SetConsoleMode(GetStdHandle(STD_INPUT_HANDLE), Mode);
@@ -941,8 +944,49 @@ begin
   GetVersionEx(versioninfo);
   Win32Platform:=versionInfo.dwPlatformId;
 end;
+
+procedure SetupConsoleInput(ihnd: THANDLE);
+var
+  Mode : DWORD;
+begin
+  GetConsoleMode(ihnd, Mode);
+  Mode:=Mode and not ENABLE_PROCESSED_INPUT;
+  SetConsoleMode(ihnd, Mode);
+end;
+
+var
+  PrevCtrlBreakHandler: TCtrlBreakHandler;
+
+
+function CrtCtrlBreakHandler (CtrlBreak: boolean): boolean;
+begin
+(* Earlier registered handlers (e.g. FreeVision) have priority. *)
+  if Assigned (PrevCtrlBreakHandler) then
+    if PrevCtrlBreakHandler (CtrlBreak) then
+      begin
+        CrtCtrlBreakHandler := true;
+        Exit;
+      end;
+(* If Ctrl-Break was pressed, either ignore it or allow default processing. *)
+  if CtrlBreak then
+    CrtCtrlBreakHandler := not (CheckBreak)
+  else (* Ctrl-C pressed *)
+{$IFDEF FPC_CRT_CTRLC_TREATED_AS_KEY}
+ (* If Ctrl-C is really treated as a key, the following branch should never *)
+ (* be executed, but let's stay on the safe side and ensure predictability. *)
+   CrtCtrlBreakHandler := false;
+{$ELSE FPC_CRT_CTRLC_TREATED_AS_KEY}
+    begin
+      if not (SpecialKey) and (ScanCode = 0) then
+        ScanCode := 3;
+      CrtCtrlBreakHandler := true;
+    end;
+{$ENDIF FPC_CRT_CTRLC_TREATED_AS_KEY}
+end;
+
 // ts
 
+
 Initialization
   LoadVersionInfo;
 
@@ -983,6 +1027,14 @@ Initialization
   AssignCrt(Input);
   Reset(Input);
   TextRec(Input).Handle:= GetStdHandle(STD_INPUT_HANDLE);
+
+  SetupConsoleInput(TextRec(Input).Handle);
+
+  PrevCtrlBreakHandler := SysSetCtrlBreakHandler (@CrtCtrlBreakHandler);
+  if PrevCtrlBreakHandler = TCtrlBreakHandler (pointer (-1)) then
+   PrevCtrlBreakHandler := nil;
+  CheckBreak := true;
+
 finalization
   if beeperDevice <> INVALID_HANDLE_VALUE then begin
     nosound;