w32smsg.inc 4.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179
  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. procedure InitSystemMsg;
  53. var
  54. mode : dword;
  55. ConsoleScreenBufferInfo : Console_screen_buffer_info;
  56. begin
  57. if SystemEventActive then
  58. exit;
  59. // enable Window events
  60. GetConsoleMode(TextRec(Input).Handle,@mode);
  61. mode:=mode or ENABLE_WINDOW_INPUT;
  62. SetConsoleMode(TextRec(Input).Handle,mode);
  63. GetConsoleScreenBufferInfo(GetStdHandle(STD_OUTPUT_HANDLE),
  64. @ConsoleScreenBufferInfo);
  65. XSize:=ConsoleScreenBufferInfo.srWindow.right-ConsoleScreenBufferInfo.srWindow.left+1;
  66. YSize:=ConsoleScreenBufferInfo.srWindow.bottom-ConsoleScreenBufferInfo.srWindow.top+1;
  67. PendingSystemHead:=@PendingSystemEvent;
  68. PendingSystemTail:=@PendingSystemEvent;
  69. PendingSystemEvents:=0;
  70. FillChar(LastSystemEvent,sizeof(TSystemEvent),0);
  71. InitializeCriticalSection(ChangeSystemEvents);
  72. SetResizeEventHandler(@SystemEventHandler);
  73. SetFocusEventHandler(@SystemEventHandler);
  74. SystemEventActive:=true;
  75. end;
  76. procedure DoneSystemMsg;
  77. var
  78. mode : dword;
  79. begin
  80. if not SystemEventActive then
  81. exit;
  82. // disable System events
  83. GetConsoleMode(TextRec(Input).Handle,@mode);
  84. mode:=mode and (not ENABLE_WINDOW_INPUT);
  85. SetConsoleMode(TextRec(Input).Handle,mode);
  86. SetResizeEventHandler(nil);
  87. SetFocusEventHandler(nil);
  88. DeleteCriticalSection(ChangeSystemEvents);
  89. SystemEventActive:=false;
  90. end;
  91. procedure GetSystemEvent(var SystemEvent: TSystemEvent);
  92. var
  93. b : byte;
  94. begin
  95. repeat
  96. EnterCriticalSection(ChangeSystemEvents);
  97. b:=PendingSystemEvents;
  98. LeaveCriticalSection(ChangeSystemEvents);
  99. if b>0 then
  100. break
  101. else
  102. sleep(50);
  103. until false;
  104. EnterCriticalSection(ChangeSystemEvents);
  105. SystemEvent:=PendingSystemHead^;
  106. inc(PendingSystemHead);
  107. if longint(PendingSystemHead)=longint(@PendingSystemEvent)+sizeof(PendingSystemEvent) then
  108. PendingSystemHead:=@PendingSystemEvent;
  109. dec(PendingSystemEvents);
  110. LastSystemEvent:=SystemEvent;
  111. LeaveCriticalSection(ChangeSystemEvents);
  112. end;
  113. function PollSystemEvent(var SystemEvent: TSystemEvent):boolean;
  114. var
  115. ConsoleScreenBufferInfo : Console_screen_buffer_info;
  116. NewXSize, NewYSize : longint;
  117. begin
  118. EnterCriticalSection(ChangeSystemEvents);
  119. if PendingSystemEvents>0 then
  120. begin
  121. SystemEvent:=PendingSystemHead^;
  122. PollSystemEvent:=true;
  123. end
  124. else
  125. begin
  126. GetConsoleScreenBufferInfo(GetStdHandle(STD_OUTPUT_HANDLE),
  127. @ConsoleScreenBufferInfo);
  128. NewXSize:=ConsoleScreenBufferInfo.srWindow.right-ConsoleScreenBufferInfo.srWindow.left+1;
  129. NewYSize:=ConsoleScreenBufferInfo.srWindow.bottom-ConsoleScreenBufferInfo.srWindow.top+1;
  130. if (XSize<>NewXSize) or (YSize<>NewYSize) then
  131. begin
  132. SystemEvent.typ:=SysResize;
  133. SystemEvent.x:=NewXSize;
  134. SystemEvent.y:=NewYSize;
  135. PutSystemEvent(SystemEvent);
  136. XSize:=NewXSize;
  137. YSize:=NewYSize;
  138. PollSystemEvent:=true;
  139. end
  140. else
  141. PollSystemEvent:=false;
  142. end;
  143. LeaveCriticalSection(ChangeSystemEvents);
  144. end;
  145. {
  146. $Log$
  147. Revision 1.2 2002-06-06 20:32:34 pierre
  148. * check console window size changes
  149. Revision 1.1 2002/05/21 11:59:57 pierre
  150. + system messages unit added
  151. }