w32smsg.inc 5.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190
  1. {
  2. System independent system interface for win32
  3. Copyright (c) 2000 by Pierre Muller
  4. This library is free software; you can redistribute it and/or
  5. modify it under the terms of the GNU Library General Public
  6. License as published by the Free Software Foundation; either
  7. version 2 of the License, or (at your option) any later version.
  8. This library 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. See the GNU
  11. Library General Public License for more details.
  12. You should have received a copy of the GNU Library General Public
  13. License along with this library; if not, write to the Free
  14. Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  15. }
  16. uses
  17. windows,dos,winevent;
  18. var
  19. ChangeSystemEvents : TCriticalSection;
  20. Const
  21. SystemEventActive : Boolean = false;
  22. procedure SystemEventHandler(var ir:INPUT_RECORD);
  23. var
  24. e : TSystemEvent;
  25. begin
  26. { WINDOW_BUFFER_SIZE_EVENT is triggered by buffer size changes
  27. but we are interested in console size changes, thus its handled below
  28. in PollSystemEvent }
  29. if (ir.EventType in [FOCUS_EVENT{,WINDOW_BUFFER_SIZE_EVENT}]) then
  30. begin
  31. EnterCriticalSection(ChangeSystemEvents);
  32. if (ir.EventType=FOCUS_EVENT) then
  33. begin
  34. if ir.Event.FocusEvent.bSetFocus then
  35. e.typ:=SysSetFocus
  36. else
  37. e.typ:=SysReleaseFocus;
  38. end
  39. else
  40. begin
  41. e.typ:=SysResize;
  42. e.x:=ir.Event.WindowBufferSizeEvent.dwSize.x;
  43. e.y:=ir.Event.WindowBufferSizeEvent.dwSize.y;
  44. end;
  45. PutSystemEvent(e);
  46. LeaveCriticalSection(ChangeSystemEvents);
  47. end;
  48. end;
  49. var
  50. Xsize, YSize : longint;
  51. function HandleConsoleCtrl(typ : dword) : BOOL; stdcall;
  52. var
  53. SE : TSystemEvent;
  54. begin
  55. HandleConsoleCtrl:=false;
  56. case typ of
  57. CTRL_CLOSE_EVENT,
  58. CTRL_LOGOFF_EVENT,
  59. CTRL_SHUTDOWN_EVENT :
  60. begin
  61. SE.typ:=SysClose;
  62. SE.CloseTyp:=typ;
  63. PutSystemEvent(SE);
  64. HandleConsoleCtrl:=true;
  65. end;
  66. end;
  67. end;
  68. procedure InitSystemMsg;
  69. var
  70. mode : dword;
  71. ConsoleScreenBufferInfo : Console_screen_buffer_info;
  72. begin
  73. if SystemEventActive then
  74. exit;
  75. // enable Window events
  76. GetConsoleMode(TextRec(Input).Handle,@mode);
  77. mode:=mode or ENABLE_WINDOW_INPUT;
  78. SetConsoleMode(TextRec(Input).Handle,mode);
  79. GetConsoleScreenBufferInfo(GetStdHandle(STD_OUTPUT_HANDLE),
  80. @ConsoleScreenBufferInfo);
  81. XSize:=ConsoleScreenBufferInfo.srWindow.right-ConsoleScreenBufferInfo.srWindow.left+1;
  82. YSize:=ConsoleScreenBufferInfo.srWindow.bottom-ConsoleScreenBufferInfo.srWindow.top+1;
  83. PendingSystemHead:=@PendingSystemEvent;
  84. PendingSystemTail:=@PendingSystemEvent;
  85. PendingSystemEvents:=0;
  86. FillChar(LastSystemEvent,sizeof(TSystemEvent),0);
  87. InitializeCriticalSection(ChangeSystemEvents);
  88. SetResizeEventHandler(@SystemEventHandler);
  89. SetFocusEventHandler(@SystemEventHandler);
  90. SetConsoleCtrlHandler(@HandleConsoleCtrl,true);
  91. SystemEventActive:=true;
  92. end;
  93. procedure DoneSystemMsg;
  94. var
  95. mode : dword;
  96. begin
  97. if not SystemEventActive then
  98. exit;
  99. // disable System events
  100. GetConsoleMode(TextRec(Input).Handle,@mode);
  101. mode:=mode and (not ENABLE_WINDOW_INPUT);
  102. SetConsoleMode(TextRec(Input).Handle,mode);
  103. SetResizeEventHandler(nil);
  104. SetFocusEventHandler(nil);
  105. DeleteCriticalSection(ChangeSystemEvents);
  106. SetConsoleCtrlHandler(@HandleConsoleCtrl,false);
  107. SystemEventActive:=false;
  108. end;
  109. procedure GetSystemEvent(var SystemEvent: TSystemEvent);
  110. var
  111. b : byte;
  112. begin
  113. repeat
  114. EnterCriticalSection(ChangeSystemEvents);
  115. b:=PendingSystemEvents;
  116. LeaveCriticalSection(ChangeSystemEvents);
  117. if b>0 then
  118. break
  119. else
  120. sleep(50);
  121. until false;
  122. EnterCriticalSection(ChangeSystemEvents);
  123. SystemEvent:=PendingSystemHead^;
  124. inc(PendingSystemHead);
  125. if longint(PendingSystemHead)=longint(@PendingSystemEvent)+sizeof(PendingSystemEvent) then
  126. PendingSystemHead:=@PendingSystemEvent;
  127. dec(PendingSystemEvents);
  128. LastSystemEvent:=SystemEvent;
  129. LeaveCriticalSection(ChangeSystemEvents);
  130. end;
  131. function PollSystemEvent(var SystemEvent: TSystemEvent):boolean;
  132. var
  133. ConsoleScreenBufferInfo : Console_screen_buffer_info;
  134. NewXSize, NewYSize : longint;
  135. begin
  136. EnterCriticalSection(ChangeSystemEvents);
  137. if PendingSystemEvents>0 then
  138. begin
  139. SystemEvent:=PendingSystemHead^;
  140. PollSystemEvent:=true;
  141. end
  142. else
  143. begin
  144. GetConsoleScreenBufferInfo(GetStdHandle(STD_OUTPUT_HANDLE),
  145. @ConsoleScreenBufferInfo);
  146. NewXSize:=ConsoleScreenBufferInfo.srWindow.right-ConsoleScreenBufferInfo.srWindow.left+1;
  147. NewYSize:=ConsoleScreenBufferInfo.srWindow.bottom-ConsoleScreenBufferInfo.srWindow.top+1;
  148. if (XSize<>NewXSize) or (YSize<>NewYSize) then
  149. begin
  150. SystemEvent.typ:=SysResize;
  151. SystemEvent.x:=NewXSize;
  152. SystemEvent.y:=NewYSize;
  153. PutSystemEvent(SystemEvent);
  154. XSize:=NewXSize;
  155. YSize:=NewYSize;
  156. PollSystemEvent:=true;
  157. end
  158. else
  159. PollSystemEvent:=false;
  160. end;
  161. LeaveCriticalSection(ChangeSystemEvents);
  162. end;