w32smsg.inc 5.4 KB

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