XplatUIWin32.cs 25 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811
  1. // Permission is hereby granted, free of charge, to any person obtaining
  2. // a copy of this software and associated documentation files (the
  3. // "Software"), to deal in the Software without restriction, including
  4. // without limitation the rights to use, copy, modify, merge, publish,
  5. // distribute, sublicense, and/or sell copies of the Software, and to
  6. // permit persons to whom the Software is furnished to do so, subject to
  7. // the following conditions:
  8. //
  9. // The above copyright notice and this permission notice shall be
  10. // included in all copies or substantial portions of the Software.
  11. //
  12. // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
  13. // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
  14. // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
  15. // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
  16. // LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
  17. // OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
  18. // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
  19. //
  20. // Copyright (c) 2004 Novell, Inc.
  21. //
  22. // Authors:
  23. // Peter Bartok [email protected]
  24. //
  25. //
  26. // $Revision: 1.17 $
  27. // $Modtime: $
  28. // $Log: XplatUIWin32.cs,v $
  29. // Revision 1.17 2004/08/13 21:42:15 pbartok
  30. // - Changed signature for GetCursorPos
  31. //
  32. // Revision 1.16 2004/08/13 19:00:15 jordi
  33. // implements PointToClient (ScreenToClient)
  34. //
  35. // Revision 1.15 2004/08/13 18:53:57 pbartok
  36. // - Changed GetWindowPos to also provide client area size
  37. // - Fixed broken prototypes for several win32 functions
  38. //
  39. // Revision 1.14 2004/08/12 22:59:03 pbartok
  40. // - Implemented method to get current mouse position
  41. //
  42. // Revision 1.13 2004/08/11 22:20:59 pbartok
  43. // - Signature fixes
  44. //
  45. // Revision 1.12 2004/08/11 19:41:38 jordi
  46. // Fixes ClientRect
  47. //
  48. // Revision 1.11 2004/08/11 19:19:44 pbartok
  49. // - We had SetWindowPos and MoveWindow to set window positions and size,
  50. // removed MoveWindow. We have GetWindowPos, so it made sense to keep
  51. // SetWindowPos as matching counterpart
  52. // - Added some X11 sanity checking
  53. //
  54. // Revision 1.10 2004/08/11 18:55:46 pbartok
  55. // - Added method to calculate difference between decorated window and raw
  56. // client area
  57. //
  58. // Revision 1.9 2004/08/10 18:47:16 jordi
  59. // Calls InvalidateRect before UpdateWindow
  60. //
  61. // Revision 1.8 2004/08/10 17:36:17 pbartok
  62. // - Implemented several methods
  63. //
  64. // Revision 1.7 2004/08/09 20:55:59 pbartok
  65. // - Removed Run method, was only required for initial development
  66. //
  67. // Revision 1.6 2004/08/09 20:51:25 pbartok
  68. // - Implemented GrabWindow/ReleaseWindow methods to allow pointer capture
  69. //
  70. // Revision 1.5 2004/08/09 16:05:16 jackson
  71. // These properties are handled by the theme now.
  72. //
  73. // Revision 1.4 2004/08/06 15:53:39 jordi
  74. // X11 keyboard navigation
  75. //
  76. // Revision 1.3 2004/08/04 20:11:24 pbartok
  77. // - Added Invalidate handling
  78. //
  79. // Revision 1.2 2004/07/21 16:19:17 jordi
  80. // LinkLabel control implementation
  81. //
  82. // Revision 1.1 2004/07/09 05:21:25 pbartok
  83. // - Initial check-in
  84. //
  85. //
  86. // NOT COMPLETE
  87. using System;
  88. using System.Drawing;
  89. using System.ComponentModel;
  90. using System.Collections;
  91. using System.Diagnostics;
  92. using System.Runtime.InteropServices;
  93. /// Win32 Version
  94. namespace System.Windows.Forms {
  95. internal class XplatUIWin32 : XplatUIDriver {
  96. #region Local Variables
  97. private static XplatUIWin32 instance;
  98. private static int ref_count;
  99. private static IntPtr FosterParent;
  100. internal static Keys key_state;
  101. internal static MouseButtons mouse_state;
  102. internal static Point mouse_position;
  103. internal static WndProc wnd_proc;
  104. internal static bool themes_enabled;
  105. #endregion // Local Variables
  106. #region Private Structs
  107. [StructLayout(LayoutKind.Sequential)]
  108. private struct WNDCLASS {
  109. internal int style;
  110. internal WndProc lpfnWndProc;
  111. internal int cbClsExtra;
  112. internal int cbWndExtra;
  113. internal IntPtr hInstance;
  114. internal IntPtr hIcon;
  115. internal IntPtr hCursor;
  116. internal IntPtr hbrBackground;
  117. internal string lpszMenuName;
  118. internal string lpszClassName;
  119. }
  120. [StructLayout(LayoutKind.Sequential)]
  121. private struct RECT {
  122. internal int left;
  123. internal int top;
  124. internal int right;
  125. internal int bottom;
  126. }
  127. [StructLayout(LayoutKind.Sequential)]
  128. private struct POINT {
  129. internal int x;
  130. internal int y;
  131. }
  132. [StructLayout(LayoutKind.Sequential)]
  133. private struct PAINTSTRUCT {
  134. internal IntPtr hdc;
  135. internal int fErase;
  136. internal RECT rcPaint;
  137. internal int fRestore;
  138. internal int fIncUpdate;
  139. internal int Reserved1;
  140. internal int Reserved2;
  141. internal int Reserved3;
  142. internal int Reserved4;
  143. internal int Reserved5;
  144. internal int Reserved6;
  145. internal int Reserved7;
  146. internal int Reserved8;
  147. }
  148. internal enum ClassStyle {
  149. CS_VREDRAW = 0x00000001,
  150. CS_HREDRAW = 0x00000002,
  151. CS_KEYCVTWINDOW = 0x00000004,
  152. CS_DBLCLKS = 0x00000008,
  153. CS_OWNDC = 0x00000020,
  154. CS_CLASSDC = 0x00000040,
  155. CS_PARENTDC = 0x00000080,
  156. CS_NOKEYCVT = 0x00000100,
  157. CS_NOCLOSE = 0x00000200,
  158. CS_SAVEBITS = 0x00000800,
  159. CS_BYTEALIGNCLIENT = 0x00001000,
  160. CS_BYTEALIGNWINDOW = 0x00002000,
  161. CS_GLOBALCLASS = 0x00004000,
  162. CS_IME = 0x00010000
  163. }
  164. internal enum PeekMessageFlags {
  165. PM_NOREMOVE = 0x00000000,
  166. PM_REMOVE = 0x00000001,
  167. PM_NOYIELD = 0x00000002
  168. }
  169. internal enum VirtualKeys {
  170. VK_LBUTTON = 0x01,
  171. VK_RBUTTON = 0x02,
  172. VK_CANCEL = 0x03,
  173. VK_MBUTTON = 0x04,
  174. VK_XBUTTON1 = 0x05,
  175. VK_XBUTTON2 = 0x06,
  176. VK_BACK = 0x08,
  177. VK_TAB = 0x09,
  178. VK_CLEAR = 0x0C,
  179. VK_RETURN = 0x0D,
  180. VK_SHIFT = 0x10,
  181. VK_CONTROL = 0x11,
  182. VK_MENU = 0x12,
  183. VK_CAPITAL = 0x14,
  184. VK_ESCAPE = 0x1B,
  185. VK_SPACE = 0x20,
  186. VK_PRIOR = 0x21,
  187. VK_NEXT = 0x22,
  188. VK_END = 0x23,
  189. VK_HOME = 0x24,
  190. VK_LEFT = 0x25,
  191. VK_UP = 0x26,
  192. VK_RIGHT = 0x27,
  193. VK_DOWN = 0x28,
  194. VK_SELECT = 0x29,
  195. VK_EXECUTE = 0x2B,
  196. VK_SNAPSHOT = 0x2C,
  197. VK_HELP = 0x2F,
  198. VK_0 = 0x30,
  199. VK_1 = 0x31,
  200. VK_2 = 0x32,
  201. VK_3 = 0x33,
  202. VK_4 = 0x34,
  203. VK_5 = 0x35,
  204. VK_6 = 0x36,
  205. VK_7 = 0x37,
  206. VK_8 = 0x38,
  207. VK_9 = 0x39,
  208. VK_A = 0x41,
  209. VK_B = 0x42,
  210. VK_C = 0x43,
  211. VK_D = 0x44,
  212. VK_E = 0x45,
  213. VK_F = 0x46,
  214. VK_G = 0x47,
  215. VK_H = 0x48,
  216. VK_I = 0x49,
  217. VK_J = 0x4A,
  218. VK_K = 0x4B,
  219. VK_L = 0x4C,
  220. VK_M = 0x4D,
  221. VK_N = 0x4E,
  222. VK_O = 0x4F,
  223. VK_P = 0x50,
  224. VK_Q = 0x51,
  225. VK_R = 0x52,
  226. VK_S = 0x53,
  227. VK_T = 0x54,
  228. VK_U = 0x55,
  229. VK_V = 0x56,
  230. VK_W = 0x57,
  231. VK_X = 0x58,
  232. VK_Y = 0x59,
  233. VK_Z = 0x5A,
  234. VK_NUMPAD0 = 0x60,
  235. VK_NUMPAD1 = 0x61,
  236. VK_NUMPAD2 = 0x62,
  237. VK_NUMPAD3 = 0x63,
  238. VK_NUMPAD4 = 0x64,
  239. VK_NUMPAD5 = 0x65,
  240. VK_NUMPAD6 = 0x66,
  241. VK_NUMPAD7 = 0x67,
  242. VK_NUMPAD8 = 0x68,
  243. VK_NUMPAD9 = 0x69,
  244. VK_MULTIPLY = 0x6A,
  245. VK_ADD = 0x6B,
  246. VK_SEPARATOR = 0x6C,
  247. VK_SUBTRACT = 0x6D,
  248. VK_DECIMAL = 0x6E,
  249. VK_DIVIDE = 0x6F,
  250. VK_ATTN = 0xF6,
  251. VK_CRSEL = 0xF7,
  252. VK_EXSEL = 0xF8,
  253. VK_EREOF = 0xF9,
  254. VK_PLAY = 0xFA,
  255. VK_ZOOM = 0xFB,
  256. VK_NONAME = 0xFC,
  257. VK_PA1 = 0xFD,
  258. VK_OEM_CLEAR = 0xFE,
  259. VK_LWIN = 0x5B,
  260. VK_RWIN = 0x5C,
  261. VK_APPS = 0x5D,
  262. VK_LSHIFT = 0xA0,
  263. VK_RSHIFT = 0xA1,
  264. VK_LCONTROL = 0xA2,
  265. VK_RCONTROL = 0xA3,
  266. VK_LMENU = 0xA4,
  267. VK_RMENU = 0xA5
  268. }
  269. private enum GetSysColorIndex {
  270. COLOR_SCROLLBAR =0,
  271. COLOR_BACKGROUND =1,
  272. COLOR_ACTIVECAPTION =2,
  273. COLOR_INACTIVECAPTION =3,
  274. COLOR_MENU =4,
  275. COLOR_WINDOW =5,
  276. COLOR_WINDOWFRAME =6,
  277. COLOR_MENUTEXT =7,
  278. COLOR_WINDOWTEXT =8,
  279. COLOR_CAPTIONTEXT =9,
  280. COLOR_ACTIVEBORDER =10,
  281. COLOR_INACTIVEBORDER =11,
  282. COLOR_APPWORKSPACE =12,
  283. COLOR_HIGHLIGHT =13,
  284. COLOR_HIGHLIGHTTEXT =14,
  285. COLOR_BTNFACE =15,
  286. COLOR_BTNSHADOW =16,
  287. COLOR_GRAYTEXT =17,
  288. COLOR_BTNTEXT =18,
  289. COLOR_INACTIVECAPTIONTEXT =19,
  290. COLOR_BTNHIGHLIGHT =20,
  291. COLOR_3DDKSHADOW =21,
  292. COLOR_3DLIGHT =22,
  293. COLOR_INFOTEXT =23,
  294. COLOR_INFOBK =24,
  295. COLOR_DESKTOP =1,
  296. COLOR_3DFACE =16,
  297. COLOR_3DSHADOW =16,
  298. COLOR_3DHIGHLIGHT =20,
  299. COLOR_3DHILIGHT =20,
  300. COLOR_BTNHILIGHT =20
  301. }
  302. private enum LoadCursorType {
  303. IDC_ARROW =32512,
  304. IDC_IBEAM =32513,
  305. IDC_WAIT =32514,
  306. IDC_CROSS =32515,
  307. IDC_UPARROW =32516,
  308. IDC_SIZE =32640,
  309. IDC_ICON =32641,
  310. IDC_SIZENWSE =32642,
  311. IDC_SIZENESW =32643,
  312. IDC_SIZEWE =32644,
  313. IDC_SIZENS =32645,
  314. IDC_SIZEALL =32646,
  315. IDC_NO =32648,
  316. IDC_HAND =32649,
  317. IDC_APPSTARTING =32650,
  318. IDC_HELP =32651
  319. }
  320. #endregion
  321. #region Constructor & Destructor
  322. private XplatUIWin32() {
  323. WNDCLASS wndClass;
  324. bool result;
  325. // Handle singleton stuff first
  326. ref_count=0;
  327. // Now regular initialization
  328. key_state = Keys.None;
  329. mouse_state = MouseButtons.None;
  330. mouse_position = Point.Empty;
  331. themes_enabled = false;
  332. // Prepare 'our' window class
  333. wnd_proc = new WndProc(NativeWindow.WndProc);
  334. wndClass.style = (int)ClassStyle.CS_OWNDC;
  335. wndClass.lpfnWndProc = wnd_proc;
  336. wndClass.cbClsExtra = 0;
  337. wndClass.cbWndExtra = 0;
  338. wndClass.hbrBackground = (IntPtr)(GetSysColorIndex.COLOR_BTNFACE+1);
  339. wndClass.hCursor = Win32LoadCursor(IntPtr.Zero, LoadCursorType.IDC_ARROW);
  340. wndClass.hIcon = IntPtr.Zero;
  341. wndClass.hInstance = IntPtr.Zero;
  342. wndClass.lpszClassName = XplatUI.DefaultClassName;
  343. wndClass.lpszMenuName = "";
  344. result=Win32RegisterClass(ref wndClass);
  345. if (result==false) {
  346. Win32MessageBox(IntPtr.Zero, "Could not register the "+XplatUI.DefaultClassName+" window class, win32 error " + Win32GetLastError().ToString(), "Oops", 0);
  347. }
  348. FosterParent=Win32CreateWindow(0, "Static", "Foster Parent Window", (int)WindowStyles.WS_OVERLAPPEDWINDOW, 0, 0, 0, 0, IntPtr.Zero, IntPtr.Zero, IntPtr.Zero, IntPtr.Zero);
  349. if (FosterParent==IntPtr.Zero) {
  350. Win32MessageBox(IntPtr.Zero, "Could not create foster window, win32 error " + Win32GetLastError().ToString(), "Oops", 0);
  351. }
  352. Console.WriteLine("#region #line XplatUI WIN32 Constructor called, result {0}", result);
  353. }
  354. ~XplatUIWin32() {
  355. Console.WriteLine("XplatUI Destructor called");
  356. }
  357. #endregion // Constructor & Destructor
  358. #region Private Support Methods
  359. private static IntPtr DefWndProc(IntPtr hWnd, Msg msg, IntPtr wParam, IntPtr lParam) {
  360. return Win32DefWindowProc(hWnd, msg, wParam, lParam);
  361. }
  362. #endregion // Private Support Methods
  363. #region Static Properties
  364. internal override Keys ModifierKeys {
  365. get {
  366. return key_state;
  367. }
  368. }
  369. internal override MouseButtons MouseButtons {
  370. get {
  371. return mouse_state;
  372. }
  373. }
  374. internal override Point MousePosition {
  375. get {
  376. return mouse_position;
  377. }
  378. }
  379. internal override bool DropTarget {
  380. get {
  381. return false;
  382. }
  383. set {
  384. if (value) {
  385. throw new NotImplementedException("Need to figure out D'n'D for Win32");
  386. }
  387. }
  388. }
  389. #endregion // Static Properties
  390. #region Singleton Specific Code
  391. public static XplatUIWin32 GetInstance() {
  392. if (instance==null) {
  393. instance=new XplatUIWin32();
  394. }
  395. ref_count++;
  396. return instance;
  397. }
  398. public int Reference {
  399. get {
  400. return ref_count;
  401. }
  402. }
  403. #endregion
  404. #region Public Static Methods
  405. internal override IntPtr InitializeDriver() {
  406. key_state=Keys.None;
  407. mouse_state=MouseButtons.None;
  408. mouse_position=Point.Empty;
  409. Console.WriteLine("#region #line XplatUI Win32 Constructor called");
  410. return IntPtr.Zero;
  411. }
  412. internal override void ShutdownDriver(IntPtr token) {
  413. Console.WriteLine("XplatUIWin32 ShutdownDriver called");
  414. }
  415. internal void Version() {
  416. Console.WriteLine("Xplat version $revision: $");
  417. }
  418. internal override void Exit() {
  419. Win32PostQuitMessage(0);
  420. }
  421. internal override void EnableThemes() {
  422. themes_enabled=true;
  423. }
  424. internal override IntPtr CreateWindow(CreateParams cp) {
  425. IntPtr WindowHandle;
  426. IntPtr ParentHandle;
  427. ParentHandle=cp.Parent;
  428. if ((ParentHandle==IntPtr.Zero) && (cp.Style & (int)WindowStyles.WS_CHILD)!=0) {
  429. // We need to use our foster parent window until this poor child gets it's parent assigned
  430. ParentHandle=FosterParent;
  431. }
  432. Console.WriteLine("Creating window at {0}:{1} {2}x{3}", cp.X, cp.Y, cp.Width, cp.Height);
  433. WindowHandle = Win32CreateWindow((uint)cp.ExStyle, cp.ClassName, cp.Caption, (uint)cp.Style, cp.X, cp.Y, cp.Width, cp.Height, ParentHandle, IntPtr.Zero, IntPtr.Zero, IntPtr.Zero);
  434. if (WindowHandle==IntPtr.Zero) {
  435. uint error = Win32GetLastError();
  436. Win32MessageBox(IntPtr.Zero, "Error : " + error.ToString(), "Failed to create window", 0);
  437. }
  438. return WindowHandle;
  439. }
  440. internal override IntPtr CreateWindow(IntPtr Parent, int X, int Y, int Width, int Height) {
  441. CreateParams create_params = new CreateParams();
  442. create_params.Caption = "";
  443. create_params.X = X;
  444. create_params.Y = Y;
  445. create_params.Width = Width;
  446. create_params.Height = Height;
  447. create_params.ClassName=XplatUI.DefaultClassName;
  448. create_params.ClassStyle = 0;
  449. create_params.ExStyle=0;
  450. create_params.Parent=IntPtr.Zero;
  451. create_params.Param=0;
  452. return CreateWindow(create_params);
  453. }
  454. internal override void DestroyWindow(IntPtr handle) {
  455. Console.WriteLine("#region #line");
  456. return;
  457. }
  458. internal override void RefreshWindow(IntPtr handle) {
  459. Win32InvalidateRect(handle, IntPtr.Zero, true);
  460. Win32UpdateWindow(handle);
  461. }
  462. [MonoTODO("Add support for internal table of windows/DCs for cleanup")]
  463. internal override PaintEventArgs PaintEventStart(IntPtr handle) {
  464. IntPtr hdc;
  465. PAINTSTRUCT ps;
  466. PaintEventArgs paint_event;
  467. RECT rect;
  468. Rectangle clip_rect;
  469. clip_rect = new Rectangle();
  470. rect = new RECT();
  471. ps = new PAINTSTRUCT();
  472. if (Win32GetUpdateRect(handle, ref rect, false)) {
  473. hdc = Win32BeginPaint(handle, ref ps);
  474. // FIXME: Add the DC to internal list
  475. // FIXME: Figure out why the rectangle is always 0 size
  476. clip_rect = new Rectangle(ps.rcPaint.left, ps.rcPaint.top, ps.rcPaint.right-ps.rcPaint.left, ps.rcPaint.bottom-ps.rcPaint.top);
  477. // clip_rect = new Rectangle(rect.top, rect.left, rect.right-rect.left, rect.bottom-rect.top);
  478. } else {
  479. hdc = Win32GetDC(handle);
  480. // FIXME: Add the DC to internal list
  481. clip_rect = new Rectangle(rect.top, rect.left, rect.right-rect.left, rect.bottom-rect.top);
  482. }
  483. paint_event = new PaintEventArgs(Graphics.FromHdc(hdc), clip_rect);
  484. return paint_event;
  485. }
  486. internal override void PaintEventEnd(IntPtr handle) {
  487. // FIXME: Lookup in the internal list how to clean
  488. ;
  489. // paintEventArgs.Dispose();
  490. }
  491. internal override void SetWindowPos(IntPtr handle, int x, int y, int width, int height) {
  492. Win32MoveWindow(handle, x, y, width, height, true);
  493. return;
  494. }
  495. internal override void GetWindowPos(IntPtr handle, out int x, out int y, out int width, out int height, out int client_width, out int client_height) {
  496. RECT rect;
  497. POINT pt;
  498. Win32GetWindowRect(handle, out rect);
  499. width = rect.right - rect.left;
  500. height = rect.bottom - rect.top;
  501. pt.x=rect.left;
  502. pt.y=rect.top;
  503. Win32ScreenToClient(Win32GetParent(handle), ref pt);
  504. x = pt.x;
  505. y = pt.y;
  506. Win32GetClientRect(handle, out rect);
  507. client_width = rect.right - rect.left;
  508. client_height = rect.bottom - rect.top;
  509. return;
  510. }
  511. internal override void Activate(IntPtr handle) {
  512. Win32SetActiveWindow(handle);
  513. }
  514. internal override void Invalidate(IntPtr handle, Rectangle rc, bool clear) {
  515. RECT rect;
  516. rect.left=rc.Left;
  517. rect.top=rc.Top;
  518. rect.right=rc.Right;
  519. rect.bottom=rc.Bottom;
  520. Win32InvalidateRect(handle, ref rect, clear);
  521. }
  522. internal override IntPtr DefWndProc(ref Message msg) {
  523. msg.Result=Win32DefWindowProc(msg.HWnd, (Msg)msg.Msg, msg.WParam, msg.LParam);
  524. return msg.Result;
  525. }
  526. internal override void HandleException(Exception e) {
  527. StackTrace st = new StackTrace(e);
  528. Win32MessageBox(IntPtr.Zero, e.Message+st.ToString(), "Exception", 0);
  529. Console.WriteLine("{0}{1}", e.Message, st.ToString());
  530. }
  531. internal override void DoEvents() {
  532. MSG msg = new MSG();
  533. while (Win32PeekMessage(ref msg, IntPtr.Zero, 0, 0, (uint)PeekMessageFlags.PM_REMOVE)!=true) {
  534. if (msg.message==Msg.WM_PAINT) {
  535. XplatUI.TranslateMessage(ref msg);
  536. XplatUI.DispatchMessage(ref msg);
  537. }
  538. }
  539. }
  540. internal override bool PeekMessage(ref MSG msg, IntPtr hWnd, int wFilterMin, int wFilterMax, uint flags) {
  541. return Win32PeekMessage(ref msg, hWnd, wFilterMin, wFilterMax, flags);
  542. }
  543. internal override bool GetMessage(ref MSG msg, IntPtr hWnd, int wFilterMin, int wFilterMax) {
  544. return Win32GetMessage(ref msg, hWnd, wFilterMin, wFilterMax);
  545. }
  546. internal override bool TranslateMessage(ref MSG msg) {
  547. return Win32TranslateMessage(ref msg);
  548. }
  549. internal override bool DispatchMessage(ref MSG msg) {
  550. return Win32DispatchMessage(ref msg);
  551. }
  552. internal override bool Text(IntPtr handle, string text) {
  553. Win32SetWindowText(handle, text);
  554. return true;
  555. }
  556. internal override bool SetVisible(IntPtr handle, bool visible) {
  557. Console.WriteLine("Setting window visibility: {0}", visible);
  558. return true;
  559. }
  560. internal override bool IsVisible(IntPtr handle) {
  561. Console.WriteLine("Getting window visibility");
  562. return true;
  563. }
  564. internal override IntPtr SetParent(IntPtr handle, IntPtr parent) {
  565. return Win32SetParent(handle, parent);
  566. }
  567. internal override IntPtr GetParent(IntPtr handle) {
  568. return Win32GetParent(handle);
  569. }
  570. internal override void GrabWindow(IntPtr hWnd) {
  571. Win32SetCapture(hWnd);
  572. }
  573. internal override void ReleaseWindow(IntPtr hWnd) {
  574. Win32ReleaseCapture();
  575. }
  576. internal override bool CalculateWindowRect(IntPtr hWnd, ref Rectangle ClientRect, int Style, bool HasMenu, out Rectangle WindowRect) {
  577. RECT rect;
  578. rect.left=ClientRect.Left;
  579. rect.top=ClientRect.Top;
  580. rect.right=ClientRect.Right;
  581. rect.bottom=ClientRect.Bottom;
  582. if (!Win32AdjustWindowRectEx(ref rect, Style, HasMenu, 0)) {
  583. WindowRect = new Rectangle(ClientRect.Left, ClientRect.Top, ClientRect.Width, ClientRect.Height);
  584. return false;
  585. }
  586. WindowRect = new Rectangle(rect.left, rect.top, rect.right-rect.left, rect.bottom-rect.top);
  587. return true;
  588. }
  589. internal override void GetCursorPos(IntPtr handle, out int x, out int y) {
  590. POINT pt;
  591. Win32GetCursorPos(out pt);
  592. if (handle!=IntPtr.Zero) {
  593. Win32ScreenToClient(handle, ref pt);
  594. }
  595. x=pt.x;
  596. y=pt.y;
  597. }
  598. internal override void ScreenToClient(IntPtr handle, ref int x, ref int y)
  599. {
  600. POINT pnt;
  601. pnt.x = x;
  602. pnt.y = y;
  603. Win32ScreenToClient (handle, ref pnt);
  604. x = pnt.x;
  605. y = pnt.y;
  606. }
  607. // Santa's little helper
  608. static void Where() {
  609. Console.WriteLine("Here: {0}", new StackTrace().ToString());
  610. }
  611. #endregion // Public Static Methods
  612. #region Win32 Imports
  613. [DllImport ("kernel32.dll", EntryPoint="GetLastError", CharSet=CharSet.Ansi, CallingConvention=CallingConvention.StdCall)]
  614. private extern static uint Win32GetLastError();
  615. [DllImport ("user32.dll", EntryPoint="CreateWindowExA", CallingConvention=CallingConvention.StdCall)]
  616. internal extern static IntPtr Win32CreateWindow(uint dwExStyle, string lpClassName, string lpWindowName, uint dwStyle, int x, int y, int nWidth, int nHeight, IntPtr hWndParent, IntPtr hMenu, IntPtr hInstance, IntPtr lParam);
  617. [DllImport ("user32.dll", EntryPoint="PeekMessageA", CallingConvention=CallingConvention.StdCall)]
  618. internal extern static bool Win32PeekMessage(ref MSG msg, IntPtr hWnd, int wFilterMin, int wFilterMax, uint flags);
  619. [DllImport ("user32.dll", EntryPoint="GetMessageA", CallingConvention=CallingConvention.StdCall)]
  620. internal extern static bool Win32GetMessage(ref MSG msg, IntPtr hWnd, int wFilterMin, int wFilterMax);
  621. [DllImport ("user32.dll", EntryPoint="TranslateMessage", CallingConvention=CallingConvention.StdCall)]
  622. internal extern static bool Win32TranslateMessage(ref MSG msg);
  623. [DllImport ("user32.dll", EntryPoint="DispatchMessageA", CallingConvention=CallingConvention.StdCall)]
  624. internal extern static bool Win32DispatchMessage(ref MSG msg);
  625. [DllImport ("user32.dll", EntryPoint="MoveWindow", CallingConvention=CallingConvention.StdCall)]
  626. internal extern static bool Win32MoveWindow(IntPtr hWnd, int x, int y, int width, int height, bool repaint);
  627. [DllImport ("user32.dll", EntryPoint="SetWindowTextA", CallingConvention=CallingConvention.StdCall)]
  628. internal extern static bool Win32SetWindowText(IntPtr hWnd, string lpString);
  629. [DllImport ("user32.dll", EntryPoint="SetParent", CallingConvention=CallingConvention.StdCall)]
  630. internal extern static IntPtr Win32SetParent(IntPtr hWnd, IntPtr hParent);
  631. [DllImport ("user32.dll", EntryPoint="RegisterClassA", CharSet=CharSet.Ansi, CallingConvention=CallingConvention.StdCall)]
  632. private extern static bool Win32RegisterClass(ref WNDCLASS wndClass);
  633. [DllImport ("user32.dll", EntryPoint="LoadCursorA", CharSet=CharSet.Ansi, CallingConvention=CallingConvention.StdCall)]
  634. private extern static IntPtr Win32LoadCursor(IntPtr hInstance, LoadCursorType type);
  635. [DllImport ("user32.dll", EntryPoint="DefWindowProcA", CharSet=CharSet.Ansi, CallingConvention=CallingConvention.StdCall)]
  636. private extern static IntPtr Win32DefWindowProc(IntPtr hWnd, Msg Msg, IntPtr wParam, IntPtr lParam);
  637. [DllImport ("user32.dll", EntryPoint="PostQuitMessage", CharSet=CharSet.Ansi, CallingConvention=CallingConvention.StdCall)]
  638. private extern static IntPtr Win32PostQuitMessage(int nExitCode);
  639. [DllImport ("user32.dll", EntryPoint="UpdateWindow", CharSet=CharSet.Ansi, CallingConvention=CallingConvention.StdCall)]
  640. private extern static IntPtr Win32UpdateWindow(IntPtr hWnd);
  641. [DllImport ("user32.dll", EntryPoint="GetUpdateRect", CharSet=CharSet.Ansi, CallingConvention=CallingConvention.StdCall)]
  642. private extern static bool Win32GetUpdateRect(IntPtr hWnd, ref RECT rect, bool erase);
  643. [DllImport ("user32.dll", EntryPoint="BeginPaint", CharSet=CharSet.Ansi, CallingConvention=CallingConvention.StdCall)]
  644. private extern static IntPtr Win32BeginPaint(IntPtr hWnd, ref PAINTSTRUCT ps);
  645. [DllImport ("user32.dll", EntryPoint="EndPaint", CharSet=CharSet.Ansi, CallingConvention=CallingConvention.StdCall)]
  646. private extern static bool Win32EndPaint(IntPtr hWnd, ref PAINTSTRUCT ps);
  647. [DllImport ("user32.dll", EntryPoint="GetDC", CharSet=CharSet.Ansi, CallingConvention=CallingConvention.StdCall)]
  648. private extern static IntPtr Win32GetDC(IntPtr hWnd);
  649. [DllImport ("user32.dll", EntryPoint="ReleaseDC", CharSet=CharSet.Ansi, CallingConvention=CallingConvention.StdCall)]
  650. private extern static IntPtr Win32ReleaseDC(IntPtr hWnd, IntPtr hDC);
  651. [DllImport ("user32.dll", EntryPoint="MessageBoxA", CharSet=CharSet.Ansi, CallingConvention=CallingConvention.StdCall)]
  652. private extern static IntPtr Win32MessageBox(IntPtr hParent, string pText, string pCaption, uint uType);
  653. [DllImport ("user32.dll", EntryPoint="InvalidateRect", CharSet=CharSet.Ansi, CallingConvention=CallingConvention.StdCall)]
  654. private extern static IntPtr Win32InvalidateRect(IntPtr hWnd, ref RECT lpRect, bool bErase);
  655. [DllImport ("user32.dll", EntryPoint="InvalidateRect", CharSet=CharSet.Ansi, CallingConvention=CallingConvention.StdCall)]
  656. private extern static IntPtr Win32InvalidateRect(IntPtr hWnd, IntPtr lpRect, bool bErase);
  657. [DllImport ("user32.dll", EntryPoint="SetCapture", CharSet=CharSet.Ansi, CallingConvention=CallingConvention.StdCall)]
  658. private extern static IntPtr Win32SetCapture(IntPtr hWnd);
  659. [DllImport ("user32.dll", EntryPoint="ReleaseCapture", CharSet=CharSet.Ansi, CallingConvention=CallingConvention.StdCall)]
  660. private extern static IntPtr Win32ReleaseCapture();
  661. [DllImport ("user32.dll", EntryPoint="GetWindowRect", CharSet=CharSet.Ansi, CallingConvention=CallingConvention.StdCall)]
  662. private extern static IntPtr Win32GetWindowRect(IntPtr hWnd, out RECT rect);
  663. [DllImport ("user32.dll", EntryPoint="GetClientRect", CharSet=CharSet.Ansi, CallingConvention=CallingConvention.StdCall)]
  664. private extern static IntPtr Win32GetClientRect(IntPtr hWnd, out RECT rect);
  665. [DllImport ("user32.dll", EntryPoint="ScreenToClient", CharSet=CharSet.Ansi, CallingConvention=CallingConvention.StdCall)]
  666. private extern static bool Win32ScreenToClient(IntPtr hWnd, ref POINT pt);
  667. [DllImport ("user32.dll", EntryPoint="GetParent", CharSet=CharSet.Ansi, CallingConvention=CallingConvention.StdCall)]
  668. private extern static IntPtr Win32GetParent(IntPtr hWnd);
  669. [DllImport ("user32.dll", EntryPoint="SetActiveWindow", CharSet=CharSet.Ansi, CallingConvention=CallingConvention.StdCall)]
  670. private extern static IntPtr Win32SetActiveWindow(IntPtr hWnd);
  671. [DllImport ("user32.dll", EntryPoint="PostQuitMessage", CharSet=CharSet.Ansi, CallingConvention=CallingConvention.StdCall)]
  672. private extern static IntPtr Win32PostQuitMessage(IntPtr hWnd);
  673. [DllImport ("user32.dll", EntryPoint="AdjustWindowRectEx", CharSet=CharSet.Ansi, CallingConvention=CallingConvention.StdCall)]
  674. private extern static bool Win32AdjustWindowRectEx(ref RECT lpRect, int dwStyle, bool bMenu, int dwExStyle);
  675. [DllImport ("user32.dll", EntryPoint="GetCursorPos", CharSet=CharSet.Ansi, CallingConvention=CallingConvention.StdCall)]
  676. private extern static bool Win32GetCursorPos(out POINT lpPoint);
  677. #endregion
  678. }
  679. }