tmouse.cpp
上传用户:tigerk9
上传日期:2020-03-10
资源大小:237k
文件大小:6k
源码类别:

Telnet客户端

开发平台:

Visual C++

  1. ///////////////////////////////////////////////////////////////////////////////
  2. //Telnet Win32 : an ANSI telnet client.
  3. //Copyright (C) 1998  Paul Brannan
  4. //Copyright (C) 1998  I.Ioannou
  5. //Copyright (C) 1997  Brad Johnson
  6. //
  7. //This program is free software; you can redistribute it and/or
  8. //modify it under the terms of the GNU General Public License
  9. //as published by the Free Software Foundation; either version 2
  10. //of the License, or (at your option) any later version.
  11. //
  12. //This program is distributed in the hope that it will be useful,
  13. //but WITHOUT ANY WARRANTY; without even the implied warranty of
  14. //MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  15. //GNU General Public License for more details.
  16. //
  17. //You should have received a copy of the GNU General Public License
  18. //along with this program; if not, write to the Free Software
  19. //Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  20. //
  21. //I.Ioannou
  22. //roryt@hol.gr
  23. //
  24. ///////////////////////////////////////////////////////////////////////////
  25. // TMouse.cpp
  26. // A simple class for handling mouse events
  27. // Written by Paul Brannan <pbranna@clemson.edu>
  28. // Last modified August 30, 1998
  29. #include "tmouse.h"
  30. #include "tconsole.h"
  31. TMouse::TMouse(Tnclip &RefClipboard): Clipboard(RefClipboard) {
  32. hConsole = GetStdHandle(STD_INPUT_HANDLE);
  33. hStdout = GetStdHandle(STD_OUTPUT_HANDLE);
  34. }
  35. TMouse::~TMouse() {
  36. }
  37. void TMouse::get_coords(COORD *start_coords, COORD *end_coords,
  38. COORD *first_coords, COORD *last_coords) {
  39. if(end_coords->Y < start_coords->Y ||
  40. (end_coords->Y == start_coords->Y && end_coords->X < start_coords->X))
  41. {
  42. *first_coords = *end_coords;
  43. *last_coords = *start_coords;
  44. } else {
  45. *first_coords = *start_coords;
  46. *last_coords = *end_coords;
  47. }
  48. last_coords->X++;
  49. }
  50. void TMouse::doMouse_init() {
  51. GetConsoleScreenBufferInfo(hStdout, &ConsoleInfo);
  52. chiBuffer = newBuffer();
  53. saveScreen(chiBuffer);
  54. }
  55. void TMouse::doMouse_cleanup() {
  56. restoreScreen(chiBuffer);
  57. delete[] chiBuffer;
  58. }
  59. void TMouse::move_mouse(COORD start_coords, COORD end_coords) {
  60. COORD screen_start = {0, 0};
  61. COORD first_coords, last_coords;
  62. DWORD Result;
  63. FillConsoleOutputAttribute(hStdout, normal,
  64. ConsoleInfo.dwSize.X * ConsoleInfo.dwSize.Y, screen_start, &Result);
  65. get_coords(&start_coords, &end_coords, &first_coords, &last_coords);
  66. FillConsoleOutputAttribute(hStdout, inverse, ConsoleInfo.dwSize.X * 
  67. (last_coords.Y - first_coords.Y) + (last_coords.X - first_coords.X),
  68. first_coords, &Result);
  69. }
  70. void TMouse::doClip(COORD start_coords, COORD end_coords) {
  71. // COORD screen_start = {0, 0};
  72. COORD first_coords, last_coords;
  73. DWORD Result;
  74. get_coords(&start_coords, &end_coords, &first_coords, &last_coords);
  75. // Allocate the minimal size buffer
  76. int data_size = 3 + ConsoleInfo.dwSize.X *
  77. (last_coords.Y - first_coords.Y) + (last_coords.X - first_coords.X);
  78. HGLOBAL clipboard_data = GlobalAlloc(GMEM_MOVEABLE + GMEM_DDESHARE,
  79. data_size);
  80. LPVOID mem_ptr = GlobalLock(clipboard_data);
  81. // Reset data_size so we can count the actual data size
  82. data_size = 0;
  83. // Read the console, put carriage returns at the end of each line if
  84. // reading more than one line (Paul Brannan 9/17/98)
  85. for(int j = first_coords.Y; j <= last_coords.Y; j++) {
  86. // Read line at (0,j)
  87. COORD coords;
  88. coords.X = 0;
  89. coords.Y = j;
  90. int length = ConsoleInfo.dwSize.X;
  91. if(j == first_coords.Y) {
  92. coords.X = first_coords.X;
  93. length = ConsoleInfo.dwSize.X - first_coords.X;
  94. } else {
  95. // Add a carriage return to the end of the previous line
  96. *((char *)mem_ptr + data_size++) = 'r';
  97. *((char *)mem_ptr + data_size++) = 'n';
  98. }
  99. if(j == last_coords.Y) {
  100. length -= (ConsoleInfo.dwSize.X - last_coords.X);
  101. }
  102. // Read the next line
  103. ReadConsoleOutputCharacter(hStdout, (LPTSTR)((char *)mem_ptr +
  104. data_size), length, coords, &Result);
  105. data_size += Result;
  106. // Strip the spaces at the end of the line
  107. if((j != last_coords.Y) && (first_coords.Y != last_coords.Y))
  108. while(*((char *)mem_ptr + data_size - 1) == ' ') data_size--;
  109. }
  110. if(first_coords.Y != last_coords.Y) {
  111. // Add a carriage return to the end of the last line
  112. *((char *)mem_ptr + data_size++) = 'r';
  113. *((char *)mem_ptr + data_size++) = 'n';
  114. }
  115. *((char *)mem_ptr + data_size) = 0;
  116. GlobalUnlock(clipboard_data);
  117. Clipboard.Copy(clipboard_data);
  118. }
  119. void TMouse::doMouse() {
  120. INPUT_RECORD InputRecord;
  121. DWORD Result;
  122. InputRecord.EventType = KEY_EVENT; // just in case
  123. while(InputRecord.EventType != MOUSE_EVENT) {
  124. if (!ReadConsoleInput(hConsole, &InputRecord, 1, &Result))
  125. return; // uh oh!  we don't know the starting coordinates!
  126. }
  127. if(InputRecord.Event.MouseEvent.dwButtonState == 0) return;
  128. if(!(InputRecord.Event.MouseEvent.dwButtonState &
  129. FROM_LEFT_1ST_BUTTON_PRESSED)) {
  130. Clipboard.Paste();
  131. return;
  132. }
  133. COORD screen_start = {0, 0};
  134.     COORD start_coords = InputRecord.Event.MouseEvent.dwMousePosition;
  135. COORD end_coords = start_coords;
  136. BOOL done = FALSE;
  137. // init vars
  138. doMouse_init();
  139. int normal_bg = ini.get_normal_bg();
  140. int normal_fg = ini.get_normal_fg();
  141. if(normal_bg == -1) normal_bg = 0; // FIX ME!!  This is just a hack
  142. if(normal_fg == -1) normal_fg = 7;
  143. normal = (normal_bg << 4) | normal_fg;
  144. inverse = (normal_fg << 4) | normal_bg;
  145. // make screen all one attribute
  146. FillConsoleOutputAttribute(hStdout, normal, ConsoleInfo.dwSize.X *
  147. ConsoleInfo.dwSize.Y, screen_start, &Result);
  148. while(!done) {
  149. switch (InputRecord.EventType) {
  150. case MOUSE_EVENT:
  151. switch(InputRecord.Event.MouseEvent.dwEventFlags) {
  152. case 0: // only copy if the mouse button has been released
  153. if(!InputRecord.Event.MouseEvent.dwButtonState) {
  154. doClip(start_coords, end_coords);
  155. done = TRUE;
  156. }
  157. break;
  158. case MOUSE_MOVED:
  159. end_coords = InputRecord.Event.MouseEvent.dwMousePosition;
  160. move_mouse(start_coords, end_coords);
  161. break;
  162. }
  163. break;
  164. // If we are changing focus, we don't want to highlight anything
  165. // (Paul Brannan 9/2/98)
  166. case FOCUS_EVENT:
  167. return;
  168. }
  169. WaitForSingleObject(hConsole, INFINITE);
  170. if (!ReadConsoleInput(hConsole, &InputRecord, 1, &Result))
  171. done = TRUE;
  172. }
  173. doMouse_cleanup();
  174. }
  175. void TMouse::scrollMouse() {
  176. doMouse();
  177. }