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:
9 // The above copyright notice and this permission notice shall be
10 // included in all copies or substantial portions of the Software.
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.
20 // Copyright (c) 2004 Novell, Inc.
23 // Peter Bartok pbartok@novell.com
32 using System.ComponentModel;
33 using System.Collections;
34 using System.Diagnostics;
35 using System.Runtime.InteropServices;
39 namespace System.Windows.Forms {
40 internal class XplatUIWin32 : XplatUIDriver {
41 #region Local Variables
42 private static XplatUIWin32 instance;
43 private static int ref_count;
44 private static IntPtr FosterParent;
46 internal static MouseButtons mouse_state;
47 internal static Point mouse_position;
48 internal static bool grab_confined;
49 internal static IntPtr grab_hwnd;
50 internal static Rectangle grab_area;
51 internal static WndProc wnd_proc;
52 internal static IntPtr prev_mouse_hwnd;
53 internal static IntPtr override_cursor;
55 internal static bool themes_enabled;
56 private Hashtable timer_list;
57 private static Queue message_queue;
58 #endregion // Local Variables
60 #region Private Structs
61 [StructLayout(LayoutKind.Sequential, CharSet=CharSet.Unicode)]
\r
62 private struct WNDCLASS {
\r
64 internal WndProc lpfnWndProc;
\r
65 internal int cbClsExtra;
\r
66 internal int cbWndExtra;
\r
67 internal IntPtr hInstance;
\r
68 internal IntPtr hIcon;
\r
69 internal IntPtr hCursor;
\r
70 internal IntPtr hbrBackground;
\r
71 [MarshalAs(UnmanagedType.LPWStr)]
\r
72 internal string lpszMenuName;
\r
73 [MarshalAs(UnmanagedType.LPWStr)]
\r
74 internal string lpszClassName;
\r
77 [StructLayout(LayoutKind.Sequential)]
\r
78 internal struct RECT {
\r
82 internal int bottom;
\r
85 [StructLayout(LayoutKind.Sequential)]
\r
86 internal struct POINT {
\r
91 internal enum WindowPlacementFlags {
95 SW_SHOWMINIMIZED = 2,
\r
96 SW_SHOWMAXIMIZED = 3,
\r
98 SW_SHOWNOACTIVATE = 4,
\r
101 SW_SHOWMINNOACTIVE = 7,
\r
104 SW_SHOWDEFAULT = 10,
\r
105 SW_FORCEMINIMIZE = 11,
\r
109 [StructLayout(LayoutKind.Sequential)]
\r
110 private struct WINDOWPLACEMENT {
\r
111 internal uint length;
\r
112 internal uint flags;
\r
113 internal WindowPlacementFlags showCmd;
\r
114 internal POINT ptMinPosition;
\r
115 internal POINT ptMaxPosition;
\r
116 internal RECT rcNormalPosition;
\r
119 [StructLayout(LayoutKind.Sequential)]
\r
120 internal struct NCCALCSIZE_PARAMS {
\r
121 internal RECT rgrc1;
\r
122 internal RECT rgrc2;
\r
123 internal RECT rgrc3;
\r
124 internal IntPtr lppos;
\r
128 private enum TMEFlags {
\r
129 TME_HOVER = 0x00000001,
\r
130 TME_LEAVE = 0x00000002,
\r
131 TME_QUERY = unchecked((int)0x40000000),
\r
132 TME_CANCEL = unchecked((int)0x80000000)
\r
135 [StructLayout(LayoutKind.Sequential)]
\r
136 private struct TRACKMOUSEEVENT {
\r
138 internal TMEFlags dwFlags;
\r
139 internal IntPtr hWnd;
\r
140 internal int dwHoverTime;
\r
143 [StructLayout(LayoutKind.Sequential)]
\r
144 private struct PAINTSTRUCT {
\r
145 internal IntPtr hdc;
\r
146 internal int fErase;
\r
147 internal RECT rcPaint;
\r
148 internal int fRestore;
\r
149 internal int fIncUpdate;
\r
150 internal int Reserved1;
\r
151 internal int Reserved2;
\r
152 internal int Reserved3;
\r
153 internal int Reserved4;
\r
154 internal int Reserved5;
\r
155 internal int Reserved6;
\r
156 internal int Reserved7;
\r
157 internal int Reserved8;
\r
160 internal enum ClassStyle {
\r
161 CS_VREDRAW = 0x00000001,
\r
162 CS_HREDRAW = 0x00000002,
\r
163 CS_KEYCVTWINDOW = 0x00000004,
\r
164 CS_DBLCLKS = 0x00000008,
\r
165 CS_OWNDC = 0x00000020,
\r
166 CS_CLASSDC = 0x00000040,
\r
167 CS_PARENTDC = 0x00000080,
\r
168 CS_NOKEYCVT = 0x00000100,
\r
169 CS_NOCLOSE = 0x00000200,
\r
170 CS_SAVEBITS = 0x00000800,
\r
171 CS_BYTEALIGNCLIENT = 0x00001000,
\r
172 CS_BYTEALIGNWINDOW = 0x00002000,
\r
173 CS_GLOBALCLASS = 0x00004000,
\r
174 CS_IME = 0x00010000
\r
177 internal enum SetWindowPosZOrder {
185 internal enum SetWindowPosFlags {
186 SWP_ASYNCWINDOWPOS = 0x4000,
187 SWP_DEFERERASE = 0x2000,
188 SWP_DRAWFRAME = 0x0020,
189 SWP_FRAMECHANGED = 0x0020,
190 SWP_HIDEWINDOW = 0x0080,
191 SWP_NOACTIVATE = 0x0010,
192 SWP_NOCOPYBITS = 0x0100,
194 SWP_NOOWNERZORDER = 0x0200,
195 SWP_NOREDRAW = 0x0008,
196 SWP_NOREPOSITION = 0x0200,
197 SWP_NOENDSCHANGING = 0x0400,
199 SWP_NOZORDER = 0x0004,
200 SWP_SHOWWINDOW = 0x0040
203 internal enum GetSysColorIndex {
\r
204 COLOR_SCROLLBAR =0,
\r
205 COLOR_BACKGROUND =1,
\r
206 COLOR_ACTIVECAPTION =2,
\r
207 COLOR_INACTIVECAPTION =3,
\r
210 COLOR_WINDOWFRAME =6,
\r
212 COLOR_WINDOWTEXT =8,
\r
213 COLOR_CAPTIONTEXT =9,
\r
214 COLOR_ACTIVEBORDER =10,
\r
215 COLOR_INACTIVEBORDER =11,
\r
216 COLOR_APPWORKSPACE =12,
\r
217 COLOR_HIGHLIGHT =13,
\r
218 COLOR_HIGHLIGHTTEXT =14,
\r
220 COLOR_BTNSHADOW =16,
\r
221 COLOR_GRAYTEXT =17,
\r
223 COLOR_INACTIVECAPTIONTEXT =19,
\r
224 COLOR_BTNHIGHLIGHT =20,
\r
225 COLOR_3DDKSHADOW =21,
\r
227 COLOR_INFOTEXT =23,
\r
231 COLOR_3DSHADOW =16,
\r
232 COLOR_3DHIGHLIGHT =20,
\r
233 COLOR_3DHILIGHT =20,
\r
234 COLOR_BTNHILIGHT =20,
235 COLOR_MAXVALUE =24,/* Maximum value */
\r
238 private enum LoadCursorType {
\r
244 IDC_UPARROW = 32516,
\r
247 IDC_SIZENWSE = 32642,
\r
248 IDC_SIZENESW = 32643,
\r
249 IDC_SIZEWE = 32644,
\r
250 IDC_SIZENS = 32645,
\r
251 IDC_SIZEALL = 32646,
\r
254 IDC_APPSTARTING = 32650,
\r
260 private enum WindowLong {
\r
262 GWL_HINSTANCE = -6,
\r
263 GWL_HWNDPARENT = -8,
\r
266 GWL_USERDATA = -21,
\r
271 private enum LogBrushStyle {
\r
278 BS_DIBPATTERNPT = 6,
\r
280 BS_DIBPATTERN8X8 = 8,
\r
285 private enum LogBrushHatch {
\r
286 HS_HORIZONTAL = 0, /* ----- */
\r
287 HS_VERTICAL = 1, /* ||||| */
\r
288 HS_FDIAGONAL = 2, /* \\\\\ */
\r
289 HS_BDIAGONAL = 3, /* ///// */
\r
290 HS_CROSS = 4, /* +++++ */
\r
291 HS_DIAGCROSS = 5, /* xxxxx */
\r
294 private struct COLORREF {
\r
301 [StructLayout(LayoutKind.Sequential)]
\r
302 private struct LOGBRUSH {
\r
303 internal LogBrushStyle lbStyle;
\r
304 internal COLORREF lbColor;
\r
305 internal LogBrushHatch lbHatch;
\r
308 [StructLayout(LayoutKind.Sequential)]
\r
309 internal struct TEXTMETRIC {
\r
310 internal int tmHeight;
\r
311 internal int tmAscent;
\r
312 internal int tmDescent;
\r
313 internal int tmInternalLeading;
\r
314 internal int tmExternalLeading;
\r
315 internal int tmAveCharWidth;
\r
316 internal int tmMaxCharWidth;
\r
317 internal int tmWeight;
\r
318 internal int tmOverhang;
\r
319 internal int tmDigitizedAspectX;
\r
320 internal int tmDigitizedAspectY;
\r
321 internal byte tmFirstChar;
\r
322 internal byte tmLastChar;
\r
323 internal byte tmDefaultChar;
\r
324 internal byte tmBreakChar;
\r
325 internal byte tmItalic;
\r
326 internal byte tmUnderlined;
\r
327 internal byte tmStruckOut;
\r
328 internal byte tmPitchAndFamily;
\r
329 internal byte tmCharSet;
\r
333 private enum ScrollWindowExFlags {
335 SW_SCROLLCHILDREN = 0x0001,
336 SW_INVALIDATE = 0x0002,
338 SW_SMOOTHSCROLL = 0x0010
341 internal enum SystemMetrics {
358 SM_CXFULLSCREEN = 16,
\r
359 SM_CYFULLSCREEN = 17,
\r
360 SM_CYKANJIWINDOW = 18,
\r
361 SM_MOUSEPRESENT = 19,
\r
365 SM_SWAPBUTTON = 23,
\r
376 SM_CXMINTRACK = 34,
\r
377 SM_CYMINTRACK = 35,
\r
378 SM_CXDOUBLECLK = 36,
\r
379 SM_CYDOUBLECLK = 37,
\r
380 SM_CXICONSPACING = 38,
\r
381 SM_CYICONSPACING = 39,
\r
382 SM_MENUDROPALIGNMENT = 40,
\r
383 SM_PENWINDOWS = 41,
\r
384 SM_DBCSENABLED = 42,
\r
385 SM_CMOUSEBUTTONS = 43,
386 SM_CXFIXEDFRAME = SM_CXDLGFRAME,
\r
387 SM_CYFIXEDFRAME = SM_CYDLGFRAME,
\r
388 SM_CXSIZEFRAME = SM_CXFRAME,
\r
389 SM_CYSIZEFRAME = SM_CYFRAME,
393 SM_CXMINSPACING = 47,
\r
394 SM_CYMINSPACING = 48,
\r
397 SM_CYSMCAPTION = 51,
\r
400 SM_CXMENUSIZE = 54,
\r
401 SM_CYMENUSIZE = 55,
\r
403 SM_CXMINIMIZED = 57,
\r
404 SM_CYMINIMIZED = 58,
\r
405 SM_CXMAXTRACK = 59,
\r
406 SM_CYMAXTRACK = 60,
\r
407 SM_CXMAXIMIZED = 61,
\r
408 SM_CYMAXIMIZED = 62,
\r
413 SM_SHOWSOUNDS = 70,
\r
414 SM_CXMENUCHECK = 71,
\r
415 SM_CYMENUCHECK = 72,
\r
416 SM_SLOWMACHINE = 73,
\r
417 SM_MIDEASTENABLED = 74,
\r
418 SM_MOUSEWHEELPRESENT = 75,
\r
419 SM_XVIRTUALSCREEN = 76,
\r
420 SM_YVIRTUALSCREEN = 77,
\r
421 SM_CXVIRTUALSCREEN = 78,
\r
422 SM_CYVIRTUALSCREEN = 79,
\r
424 SM_SAMEDISPLAYFORMAT = 81,
\r
426 SM_CXFOCUSBORDER = 83,
\r
427 SM_CYFOCUSBORDER = 84,
\r
429 SM_MEDIACENTER = 87,
\r
433 // We'll only support _WIN32_IE < 0x0500 for now
434 internal enum NotifyIconMessage {
435 NIM_ADD = 0x00000000,
436 NIM_MODIFY = 0x00000001,
437 NIM_DELETE = 0x00000002,
441 internal enum NotifyIconFlags {
442 NIF_MESSAGE = 0x00000001,
443 NIF_ICON = 0x00000002,
444 NIF_TIP = 0x00000004,
447 [StructLayout(LayoutKind.Sequential, CharSet=CharSet.Unicode)]
448 internal struct NOTIFYICONDATA {
449 internal uint cbSize;
\r
450 internal IntPtr hWnd;
\r
452 internal NotifyIconFlags uFlags;
\r
453 internal uint uCallbackMessage;
\r
454 internal IntPtr hIcon;
\r
455 [MarshalAs(UnmanagedType.ByValTStr, SizeConst=64)]
\r
456 internal string szTip;
\r
460 internal enum DCExFlags {
461 DCX_WINDOW = 0x00000001,
\r
462 DCX_CACHE = 0x00000002,
\r
463 DCX_NORESETATTRS = 0x00000004,
\r
464 DCX_CLIPCHILDREN = 0x00000008,
\r
465 DCX_CLIPSIBLINGS = 0x00000010,
\r
466 DCX_PARENTCLIP = 0x00000020,
\r
467 DCX_EXCLUDERGN = 0x00000040,
\r
468 DCX_INTERSECTRGN = 0x00000080,
\r
469 DCX_EXCLUDEUPDATE = 0x00000100,
\r
470 DCX_INTERSECTUPDATE = 0x00000200,
\r
471 DCX_LOCKWINDOWUPDATE = 0x00000400,
\r
472 DCX_USESTYLE = 0x00010000,
\r
473 DCX_VALIDATE = 0x00200000
476 [StructLayout(LayoutKind.Sequential, CharSet=CharSet.Unicode)]
477 internal struct CLIENTCREATESTRUCT {
478 internal IntPtr hWindowMenu;
479 internal uint idFirstChild;
482 private enum ClassLong : int {
484 GCL_HBRBACKGROUND = -10,
\r
488 GCL_CBWNDEXTRA = -18,
\r
489 GCL_CBCLSEXTRA = -20,
\r
496 [StructLayout(LayoutKind.Sequential, CharSet=CharSet.Unicode)]
497 internal struct MINMAXINFO {
498 internal POINT ptReserved;
499 internal POINT ptMaxSize;
500 internal POINT ptMaxPosition;
501 internal POINT ptMinTrackSize;
502 internal POINT ptMaxTrackSize;
506 #region Constructor & Destructor
507 private XplatUIWin32() {
511 // Handle singleton stuff first
514 // Now regular initialization
515 mouse_state = MouseButtons.None;
516 mouse_position = Point.Empty;
518 message_queue = new Queue();
520 themes_enabled = false;
522 // Prepare 'our' window class
523 wnd_proc = new WndProc(NativeWindow.WndProc);
524 wndClass.style = (int)(ClassStyle.CS_OWNDC | ClassStyle.CS_DBLCLKS);
525 wndClass.lpfnWndProc = wnd_proc;
526 wndClass.cbClsExtra = 0;
527 wndClass.cbWndExtra = 0;
528 wndClass.hbrBackground = IntPtr.Zero;
529 wndClass.hCursor = Win32LoadCursor(IntPtr.Zero, LoadCursorType.IDC_ARROW);
530 wndClass.hIcon = IntPtr.Zero;
531 wndClass.hInstance = IntPtr.Zero;
532 wndClass.lpszClassName = XplatUI.DefaultClassName;
533 wndClass.lpszMenuName = "";
535 result=Win32RegisterClass(ref wndClass);
537 Win32MessageBox(IntPtr.Zero, "Could not register the "+XplatUI.DefaultClassName+" window class, win32 error " + Win32GetLastError().ToString(), "Oops", 0);
540 FosterParent=Win32CreateWindow(0, "static", "Foster Parent Window", (int)WindowStyles.WS_OVERLAPPEDWINDOW, 0, 0, 0, 0, IntPtr.Zero, IntPtr.Zero, IntPtr.Zero, IntPtr.Zero);
542 if (FosterParent==IntPtr.Zero) {
543 Win32MessageBox(IntPtr.Zero, "Could not create foster window, win32 error " + Win32GetLastError().ToString(), "Oops", 0);
546 timer_list = new Hashtable ();
548 #endregion // Constructor & Destructor
550 #region Private Support Methods
551 private static IntPtr DefWndProc(IntPtr hWnd, Msg msg, IntPtr wParam, IntPtr lParam) {
552 return Win32DefWindowProc(hWnd, msg, wParam, lParam);
555 private static bool MessageWaiting {
557 if (message_queue.Count == 0) {
564 private static bool RetrieveMessage(ref MSG msg) {
567 if (message_queue.Count == 0) {
571 message = (MSG)message_queue.Dequeue();
577 private static bool StoreMessage(ref MSG msg) {
578 MSG message = new MSG();
581 message_queue.Enqueue(message);
585 #endregion // Private Support Methods
587 #region Static Properties
588 internal override Keys ModifierKeys {
593 key_state = Keys.None;
595 state = Win32GetKeyState(VirtualKeys.VK_SHIFT);
596 if ((state & 0x8000) != 0) {
597 key_state |= Keys.Shift;
599 state = Win32GetKeyState(VirtualKeys.VK_CONTROL);
600 if ((state & 0x8000) != 0) {
601 key_state |= Keys.Control;
604 state = Win32GetKeyState(VirtualKeys.VK_MENU);
605 if ((state & 0x8000) != 0) {
606 key_state |= Keys.Alt;
613 internal override MouseButtons MouseButtons {
619 internal override Point MousePosition {
621 return mouse_position;
625 internal override bool DropTarget {
632 //throw new NotImplementedException("Need to figure out D'n'D for Win32");
637 internal override Size CursorSize {
639 return new Size(Win32GetSystemMetrics(SystemMetrics.SM_CXCURSOR), Win32GetSystemMetrics(SystemMetrics.SM_CYCURSOR));
643 internal override bool DragFullWindows {
649 internal override Size DragSize {
651 return new Size(Win32GetSystemMetrics(SystemMetrics.SM_CXDRAG), Win32GetSystemMetrics(SystemMetrics.SM_CYDRAG));
655 internal override Size IconSize {
657 return new Size(Win32GetSystemMetrics(SystemMetrics.SM_CXICON), Win32GetSystemMetrics(SystemMetrics.SM_CYICON));
661 internal override Size MaxWindowTrackSize {
663 return new Size(Win32GetSystemMetrics(SystemMetrics.SM_CXMAXTRACK), Win32GetSystemMetrics(SystemMetrics.SM_CYMAXTRACK));
667 internal override Size MinimizedWindowSize {
669 return new Size(Win32GetSystemMetrics(SystemMetrics.SM_CXMINIMIZED), Win32GetSystemMetrics(SystemMetrics.SM_CYMINIMIZED));
673 internal override Size MinimizedWindowSpacingSize {
675 return new Size(Win32GetSystemMetrics(SystemMetrics.SM_CXMINSPACING), Win32GetSystemMetrics(SystemMetrics.SM_CYMINSPACING));
679 internal override Size MinimumWindowSize {
681 return new Size(Win32GetSystemMetrics(SystemMetrics.SM_CXMIN), Win32GetSystemMetrics(SystemMetrics.SM_CYMIN));
685 internal override Size MinWindowTrackSize {
687 return new Size(Win32GetSystemMetrics(SystemMetrics.SM_CXMINTRACK), Win32GetSystemMetrics(SystemMetrics.SM_CYMINTRACK));
691 internal override Size SmallIconSize {
693 return new Size(Win32GetSystemMetrics(SystemMetrics.SM_CXSMICON), Win32GetSystemMetrics(SystemMetrics.SM_CYSMICON));
697 internal override int MouseButtonCount {
699 return Win32GetSystemMetrics(SystemMetrics.SM_CMOUSEBUTTONS);
703 internal override bool MouseButtonsSwapped {
705 return Win32GetSystemMetrics(SystemMetrics.SM_SWAPBUTTON) != 0;
709 internal override bool MouseWheelPresent {
711 return Win32GetSystemMetrics(SystemMetrics.SM_MOUSEWHEELPRESENT) != 0;
715 internal override Rectangle VirtualScreen {
717 return new Rectangle( Win32GetSystemMetrics(SystemMetrics.SM_XVIRTUALSCREEN), Win32GetSystemMetrics(SystemMetrics.SM_YVIRTUALSCREEN),
718 Win32GetSystemMetrics(SystemMetrics.SM_CXVIRTUALSCREEN), Win32GetSystemMetrics(SystemMetrics.SM_CYVIRTUALSCREEN));
722 internal override Rectangle WorkingArea {
724 return new Rectangle(0, 0, Win32GetSystemMetrics(SystemMetrics.SM_CXSCREEN), Win32GetSystemMetrics(SystemMetrics.SM_CYSCREEN));
727 #endregion // Static Properties
729 #region Singleton Specific Code
730 public static XplatUIWin32 GetInstance() {
731 if (instance==null) {
732 instance=new XplatUIWin32();
738 public int Reference {
745 #region Public Static Methods
746 internal override IntPtr InitializeDriver() {
\r
747 mouse_state=MouseButtons.None;
748 mouse_position=Point.Empty;
750 Console.WriteLine("#region #line XplatUI Win32 Constructor called");
752 return IntPtr.Zero;
\r
755 internal override void ShutdownDriver(IntPtr token) {
\r
756 Console.WriteLine("XplatUIWin32 ShutdownDriver called");
760 internal void Version() {
761 Console.WriteLine("Xplat version $revision: $");
764 internal override void Exit() {
765 Win32PostQuitMessage(0);
768 internal override void GetDisplaySize(out Size size) {
771 Win32GetWindowRect(Win32GetDesktopWindow(), out rect);
773 size = new Size(rect.right - rect.left, rect.bottom - rect.top);
776 internal override void EnableThemes() {
780 internal override IntPtr CreateWindow(CreateParams cp) {
788 ParentHandle=cp.Parent;
790 if ((ParentHandle==IntPtr.Zero) && (cp.Style & (int)(WindowStyles.WS_CHILD))!=0) {
791 // We need to use our foster parent window until this poor child gets it's parent assigned
792 ParentHandle=FosterParent;
795 lParam = IntPtr.Zero;
796 if (cp.Param != null && cp.Param is CLIENTCREATESTRUCT) {
797 lParam = Marshal.AllocHGlobal(Marshal.SizeOf(cp.Param));
798 Marshal.StructureToPtr(cp.Param, lParam, false);
801 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, lParam);
803 if (lParam != IntPtr.Zero) {
804 Marshal.FreeHGlobal(lParam);
807 if (WindowHandle==IntPtr.Zero) {
808 uint error = Win32GetLastError();
810 Win32MessageBox(IntPtr.Zero, "Error : " + error.ToString(), "Failed to create window, class '"+cp.ClassName+"'", 0);
813 hwnd.ClientWindow = WindowHandle;
815 Win32SetWindowLong(WindowHandle, WindowLong.GWL_USERDATA, (IntPtr)ThemeEngine.Current.DefaultControlBackColor.ToArgb());
820 internal override IntPtr CreateWindow(IntPtr Parent, int X, int Y, int Width, int Height) {
821 CreateParams create_params = new CreateParams();
823 create_params.Caption = "";
826 create_params.Width = Width;
827 create_params.Height = Height;
829 create_params.ClassName=XplatUI.DefaultClassName;
830 create_params.ClassStyle = 0;
831 create_params.ExStyle=0;
832 create_params.Parent=IntPtr.Zero;
833 create_params.Param=0;
835 return CreateWindow(create_params);
838 internal override void DestroyWindow(IntPtr handle) {
841 hwnd = Hwnd.ObjectFromHandle(handle);
842 Win32DestroyWindow(handle);
847 internal override FormWindowState GetWindowState(IntPtr handle) {
850 style = Win32GetWindowLong(handle, WindowLong.GWL_STYLE);
851 if ((style & (uint)WindowStyles.WS_MAXIMIZE) != 0) {
852 return FormWindowState.Maximized;
853 } else if ((style & (uint)WindowStyles.WS_MINIMIZE) != 0) {
854 return FormWindowState.Minimized;
856 return FormWindowState.Normal;
859 internal override void SetWindowState(IntPtr hwnd, FormWindowState state) {
861 case FormWindowState.Normal: {
862 Win32ShowWindow(hwnd, WindowPlacementFlags.SW_SHOWNORMAL);
866 case FormWindowState.Minimized: {
867 Win32ShowWindow(hwnd, WindowPlacementFlags.SW_SHOWMINIMIZED);
871 case FormWindowState.Maximized: {
872 Win32ShowWindow(hwnd, WindowPlacementFlags.SW_SHOWMAXIMIZED);
878 internal override void SetWindowStyle(IntPtr handle, CreateParams cp) {
879 Win32SetWindowLong(handle, WindowLong.GWL_STYLE, (IntPtr)cp.Style);
880 Win32SetWindowLong(handle, WindowLong.GWL_EXSTYLE, (IntPtr)cp.ExStyle);
883 internal override void UpdateWindow(IntPtr handle) {
\r
884 Win32UpdateWindow(handle);
\r
887 internal override void SetWindowBackground(IntPtr handle, Color color) {
888 Win32SetWindowLong(handle, WindowLong.GWL_USERDATA, (IntPtr)color.ToArgb());
891 [MonoTODO("Add support for internal table of windows/DCs for cleanup")]
892 internal override PaintEventArgs PaintEventStart(IntPtr handle) {
895 PaintEventArgs paint_event;
900 clip_rect = new Rectangle();
902 ps = new PAINTSTRUCT();
904 hwnd = Hwnd.ObjectFromHandle(handle);
906 if (Win32GetUpdateRect(handle, ref rect, false)) {
907 hdc = Win32BeginPaint(handle, ref ps);
909 hwnd.user_data = (object)ps;
911 // FIXME: Figure out why the rectangle is always 0 size
912 clip_rect = new Rectangle(ps.rcPaint.left, ps.rcPaint.top, ps.rcPaint.right-ps.rcPaint.left, ps.rcPaint.bottom-ps.rcPaint.top);
913 // clip_rect = new Rectangle(rect.left, rect.top, rect.right-rect.left, rect.bottom-rect.top);
915 if (ps.fErase != 0) {
916 Console.WriteLine("Hit Clear background");
917 EraseWindowBackground(handle, hdc);
920 hdc = Win32GetDC(handle);
921 // FIXME: Add the DC to internal list
922 clip_rect = new Rectangle(rect.top, rect.left, rect.right-rect.left, rect.bottom-rect.top);
925 hwnd.client_dc = Graphics.FromHdc(hdc);
926 paint_event = new PaintEventArgs(hwnd.client_dc, clip_rect);
931 internal override void PaintEventEnd(IntPtr handle) {
\r
935 hwnd = Hwnd.ObjectFromHandle(handle);
936 hwnd.client_dc.Dispose();
938 if (hwnd.user_data != null) {
939 ps = (PAINTSTRUCT)hwnd.user_data;
940 Win32EndPaint(handle, ref ps);
945 internal override void SetWindowPos(IntPtr handle, int x, int y, int width, int height) {
946 Win32MoveWindow(handle, x, y, width, height, true);
950 internal override void GetWindowPos(IntPtr handle, bool is_toplevel, out int x, out int y, out int width, out int height, out int client_width, out int client_height) {
954 Win32GetWindowRect(handle, out rect);
955 width = rect.right - rect.left;
956 height = rect.bottom - rect.top;
960 Win32ScreenToClient(Win32GetParent(handle), ref pt);
964 Win32GetClientRect(handle, out rect);
965 client_width = rect.right - rect.left;
966 client_height = rect.bottom - rect.top;
970 internal override void Activate(IntPtr handle) {
971 Win32SetActiveWindow(handle);
974 internal override void Invalidate(IntPtr handle, Rectangle rc, bool clear) {
980 rect.bottom=rc.Bottom;
981 Win32InvalidateRect(handle, ref rect, clear);
984 internal override IntPtr DefWndProc(ref Message msg) {
985 msg.Result=Win32DefWindowProc(msg.HWnd, (Msg)msg.Msg, msg.WParam, msg.LParam);
989 internal override void HandleException(Exception e) {
990 StackTrace st = new StackTrace(e);
991 Win32MessageBox(IntPtr.Zero, e.Message+st.ToString(), "Exception", 0);
992 Console.WriteLine("{0}{1}", e.Message, st.ToString());
995 internal override void DoEvents() {
998 while (Win32PeekMessage(ref msg, IntPtr.Zero, 0, 0, (uint)PeekMessageFlags.PM_REMOVE)!=true) {
999 if (msg.message==Msg.WM_PAINT) {
1000 XplatUI.TranslateMessage(ref msg);
1001 XplatUI.DispatchMessage(ref msg);
1006 internal override bool PeekMessage(ref MSG msg, IntPtr hWnd, int wFilterMin, int wFilterMax, uint flags) {
1007 return Win32PeekMessage(ref msg, hWnd, wFilterMin, wFilterMax, flags);
1010 internal override bool GetMessage(ref MSG msg, IntPtr hWnd, int wFilterMin, int wFilterMax) {
1013 if (RetrieveMessage(ref msg)) {
1017 result = Win32GetMessage(ref msg, hWnd, wFilterMin, wFilterMax);
1019 // We need to fake WM_MOUSE_ENTER/WM_MOUSE_LEAVE
1020 switch (msg.message) {
1021 case Msg.WM_LBUTTONDOWN: {
1022 mouse_state |= MouseButtons.Left;
1026 case Msg.WM_MBUTTONDOWN: {
1027 mouse_state |= MouseButtons.Middle;
1031 case Msg.WM_RBUTTONDOWN: {
1032 mouse_state |= MouseButtons.Right;
1036 case Msg.WM_LBUTTONUP: {
1037 mouse_state &= ~MouseButtons.Left;
1041 case Msg.WM_MBUTTONUP: {
1042 mouse_state &= ~MouseButtons.Middle;
1046 case Msg.WM_RBUTTONUP: {
1047 mouse_state &= ~MouseButtons.Right;
1051 case Msg.WM_ASYNC_MESSAGE: {
1052 GCHandle handle = (GCHandle)msg.lParam;
1053 AsyncMethodData asyncdata = (AsyncMethodData) handle.Target;
1054 AsyncMethodResult asyncresult = asyncdata.Result.Target as AsyncMethodResult;
1055 object ret = asyncdata.Method.DynamicInvoke (asyncdata.Args);
1056 if (asyncresult != null) {
1057 asyncresult.Complete (ret);
1063 case Msg.WM_MOUSEMOVE: {
1064 if (msg.hwnd != prev_mouse_hwnd) {
1065 TRACKMOUSEEVENT tme;
1067 // The current message will be sent out next time around
1068 StoreMessage(ref msg);
1070 // This is the message we want to send at this point
1071 msg.message = Msg.WM_MOUSE_ENTER;
1073 prev_mouse_hwnd = msg.hwnd;
1075 tme = new TRACKMOUSEEVENT();
1076 tme.size = Marshal.SizeOf(tme);
1077 tme.hWnd = msg.hwnd;
1078 tme.dwFlags = TMEFlags.TME_LEAVE | TMEFlags.TME_HOVER;
1079 Win32TrackMouseEvent(ref tme);
1085 case Msg.WM_MOUSELEAVE: {
1086 prev_mouse_hwnd = IntPtr.Zero;
1087 msg.message=Msg.WM_MOUSE_LEAVE;
1091 case Msg.WM_TIMER: {
1092 Timer timer=(Timer)timer_list[(int)msg.wParam];
1094 if (timer != null) {
1104 internal override bool TranslateMessage(ref MSG msg) {
1105 return Win32TranslateMessage(ref msg);
1108 internal override IntPtr DispatchMessage(ref MSG msg) {
1109 return Win32DispatchMessage(ref msg);
1112 internal override bool SetZOrder(IntPtr hWnd, IntPtr AfterhWnd, bool Top, bool Bottom) {
1114 Win32SetWindowPos(hWnd, SetWindowPosZOrder.HWND_TOP, 0, 0, 0, 0, SetWindowPosFlags.SWP_NOMOVE | SetWindowPosFlags.SWP_NOSIZE);
1116 } else if (!Bottom) {
1117 Win32SetWindowPos(hWnd, AfterhWnd, 0, 0, 0, 0, SetWindowPosFlags.SWP_NOMOVE | SetWindowPosFlags.SWP_NOSIZE);
1119 Win32SetWindowPos(hWnd, (IntPtr)SetWindowPosZOrder.HWND_BOTTOM, 0, 0, 0, 0, SetWindowPosFlags.SWP_NOMOVE | SetWindowPosFlags.SWP_NOSIZE);
1125 internal override bool SetTopmost(IntPtr hWnd, IntPtr hWndOwner, bool Enabled) {
1127 Win32SetWindowPos(hWnd, SetWindowPosZOrder.HWND_TOPMOST, 0, 0, 0, 0, SetWindowPosFlags.SWP_NOMOVE | SetWindowPosFlags.SWP_NOSIZE);
1130 Win32SetWindowPos(hWnd, SetWindowPosZOrder.HWND_NOTOPMOST, 0, 0, 0, 0, SetWindowPosFlags.SWP_NOMOVE | SetWindowPosFlags.SWP_NOSIZE);
1135 internal override bool Text(IntPtr handle, string text) {
1136 Win32SetWindowText(handle, text);
1140 internal override bool GetText(IntPtr handle, out string text) {
1143 sb = new StringBuilder(256);
1144 Win32GetWindowText(handle, sb, sb.Capacity);
1145 text = sb.ToString();
1149 internal override bool SetVisible(IntPtr handle, bool visible) {
1151 Win32ShowWindow(handle, WindowPlacementFlags.SW_SHOWNORMAL);
1153 Win32ShowWindow(handle, WindowPlacementFlags.SW_HIDE);
1158 internal override bool IsVisible(IntPtr handle) {
1159 return IsWindowVisible (handle);
1162 internal override IntPtr SetParent(IntPtr handle, IntPtr parent) {
1163 return Win32SetParent(handle, parent);
1166 internal override IntPtr GetParent(IntPtr handle) {
1167 return Win32GetParent(handle);
1170 internal override void GrabWindow(IntPtr hWnd, IntPtr ConfineToHwnd) {
1172 Win32SetCapture(hWnd);
1175 internal override void GrabInfo(out IntPtr hWnd, out bool GrabConfined, out Rectangle GrabArea) {
1177 GrabConfined = grab_confined;
1178 GrabArea = grab_area;
1181 internal override void UngrabWindow(IntPtr hWnd) {
1182 Win32ReleaseCapture();
1183 grab_hwnd = IntPtr.Zero;
1186 internal override bool CalculateWindowRect(IntPtr hWnd, ref Rectangle ClientRect, int Style, int ExStyle, IntPtr MenuHandle, out Rectangle WindowRect) {
1189 rect.left=ClientRect.Left;
1190 rect.top=ClientRect.Top;
1191 rect.right=ClientRect.Right;
1192 rect.bottom=ClientRect.Bottom;
1194 if (!Win32AdjustWindowRectEx(ref rect, Style, MenuHandle != IntPtr.Zero, ExStyle)) {
1195 WindowRect = new Rectangle(ClientRect.Left, ClientRect.Top, ClientRect.Width, ClientRect.Height);
1199 WindowRect = new Rectangle(rect.left, rect.top, rect.right-rect.left, rect.bottom-rect.top);
1203 internal override void SetCursor(IntPtr window, IntPtr cursor) {
1204 if (override_cursor == IntPtr.Zero) {
1205 Win32SetCursor(cursor);
1208 Win32SetCursor(override_cursor);
1211 internal override void ShowCursor(bool show) {
1212 Win32ShowCursor(show);
1215 internal override void OverrideCursor(IntPtr cursor) {
1216 override_cursor = cursor;
1219 internal override IntPtr DefineCursor(Bitmap bitmap, Bitmap mask, Color cursor_pixel, Color mask_pixel, int xHotSpot, int yHotSpot) {
1221 Bitmap cursor_bitmap;
1229 // Win32 only allows creation cursors of a certain size
1230 if ((bitmap.Width != Win32GetSystemMetrics(SystemMetrics.SM_CXCURSOR)) || (bitmap.Width != Win32GetSystemMetrics(SystemMetrics.SM_CXCURSOR))) {
1231 cursor_bitmap = new Bitmap(bitmap, new Size(Win32GetSystemMetrics(SystemMetrics.SM_CXCURSOR), Win32GetSystemMetrics(SystemMetrics.SM_CXCURSOR)));
1232 cursor_mask = new Bitmap(mask, new Size(Win32GetSystemMetrics(SystemMetrics.SM_CXCURSOR), Win32GetSystemMetrics(SystemMetrics.SM_CXCURSOR)));
1234 cursor_bitmap = bitmap;
1238 width = cursor_bitmap.Width;
1239 height = cursor_bitmap.Height;
1241 cursor_bits = new Byte[(width / 8) * height];
1242 mask_bits = new Byte[(width / 8) * height];
1244 for (int y = 0; y < height; y++) {
1245 for (int x = 0; x < width; x++) {
1246 pixel = cursor_bitmap.GetPixel(x, y);
1248 if (pixel == cursor_pixel) {
1249 cursor_bits[y * width / 8 + x / 8] |= (byte)(0x80 >> (x % 8));
1252 pixel = cursor_mask.GetPixel(x, y);
1254 if (pixel == mask_pixel) {
1255 mask_bits[y * width / 8 + x / 8] |= (byte)(0x80 >> (x % 8));
1260 cursor = Win32CreateCursor(IntPtr.Zero, xHotSpot, yHotSpot, width, height, cursor_bits, mask_bits);
1265 [MonoTODO("Define the missing cursors")]
1266 internal override IntPtr DefineStdCursor(StdCursor id) {
1268 case StdCursor.AppStarting: return Win32LoadCursor(IntPtr.Zero, LoadCursorType.IDC_APPSTARTING);
1269 case StdCursor.Arrow: return Win32LoadCursor(IntPtr.Zero, LoadCursorType.IDC_ARROW);
1270 case StdCursor.Cross: return Win32LoadCursor(IntPtr.Zero, LoadCursorType.IDC_CROSS);
1271 case StdCursor.Default: return Win32LoadCursor(IntPtr.Zero, LoadCursorType.IDC_ARROW);
1272 case StdCursor.Hand: return Win32LoadCursor(IntPtr.Zero, LoadCursorType.IDC_HAND);
1273 case StdCursor.Help: return Win32LoadCursor(IntPtr.Zero, LoadCursorType.IDC_HELP);
1274 case StdCursor.HSplit: return Win32LoadCursor(IntPtr.Zero, LoadCursorType.IDC_ARROW); // FIXME
1275 case StdCursor.IBeam: return Win32LoadCursor(IntPtr.Zero, LoadCursorType.IDC_IBEAM);
1276 case StdCursor.No: return Win32LoadCursor(IntPtr.Zero, LoadCursorType.IDC_NO);
1277 case StdCursor.NoMove2D: return Win32LoadCursor(IntPtr.Zero, LoadCursorType.IDC_ARROW); // FIXME
1278 case StdCursor.NoMoveHoriz: return Win32LoadCursor(IntPtr.Zero, LoadCursorType.IDC_ARROW); // FIXME
1279 case StdCursor.NoMoveVert: return Win32LoadCursor(IntPtr.Zero, LoadCursorType.IDC_ARROW); // FIXME
1280 case StdCursor.PanEast: return Win32LoadCursor(IntPtr.Zero, LoadCursorType.IDC_ARROW); // FIXME
1281 case StdCursor.PanNE: return Win32LoadCursor(IntPtr.Zero, LoadCursorType.IDC_ARROW); // FIXME
1282 case StdCursor.PanNorth: return Win32LoadCursor(IntPtr.Zero, LoadCursorType.IDC_ARROW); // FIXME
1283 case StdCursor.PanNW: return Win32LoadCursor(IntPtr.Zero, LoadCursorType.IDC_ARROW); // FIXME
1284 case StdCursor.PanSE: return Win32LoadCursor(IntPtr.Zero, LoadCursorType.IDC_ARROW); // FIXME
1285 case StdCursor.PanSouth: return Win32LoadCursor(IntPtr.Zero, LoadCursorType.IDC_ARROW); // FIXME
1286 case StdCursor.PanSW: return Win32LoadCursor(IntPtr.Zero, LoadCursorType.IDC_ARROW); // FIXME
1287 case StdCursor.PanWest: return Win32LoadCursor(IntPtr.Zero, LoadCursorType.IDC_ARROW); // FIXME
1288 case StdCursor.SizeAll: return Win32LoadCursor(IntPtr.Zero, LoadCursorType.IDC_SIZEALL);
1289 case StdCursor.SizeNESW: return Win32LoadCursor(IntPtr.Zero, LoadCursorType.IDC_SIZENESW);
1290 case StdCursor.SizeNS: return Win32LoadCursor(IntPtr.Zero, LoadCursorType.IDC_SIZENS);
1291 case StdCursor.SizeNWSE: return Win32LoadCursor(IntPtr.Zero, LoadCursorType.IDC_SIZENWSE);
1292 case StdCursor.SizeWE: return Win32LoadCursor(IntPtr.Zero, LoadCursorType.IDC_SIZEWE);
1293 case StdCursor.UpArrow: return Win32LoadCursor(IntPtr.Zero, LoadCursorType.IDC_UPARROW);
1294 case StdCursor.VSplit: return Win32LoadCursor(IntPtr.Zero, LoadCursorType.IDC_ARROW); // FIXME
1295 case StdCursor.WaitCursor: return Win32LoadCursor(IntPtr.Zero, LoadCursorType.IDC_WAIT);
1297 throw new NotImplementedException ();
1300 internal override void DestroyCursor(IntPtr cursor) {
\r
1301 if ((cursor.ToInt32() < (int)LoadCursorType.First) || (cursor.ToInt32() > (int)LoadCursorType.Last)) {
\r
1302 Win32DestroyCursor(cursor);
\r
1307 internal override void GetCursorInfo(IntPtr cursor, out int width, out int height, out int hotspot_x, out int hotspot_y) {
1308 throw new NotImplementedException ();
1311 internal override void SetCursorPos(IntPtr handle, int x, int y) {
1312 Win32SetCursorPos(x, y);
1315 internal override void EnableWindow(IntPtr handle, bool Enable) {
1316 Win32EnableWindow(handle, Enable);
1319 internal override void SetModal(IntPtr handle, bool Modal) {
1320 // we do nothing on Win32; Application.cs simulates modal dialogs by disabling all toplevel windows
1323 internal override void GetCursorPos(IntPtr handle, out int x, out int y) {
1326 Win32GetCursorPos(out pt);
1328 if (handle!=IntPtr.Zero) {
1329 Win32ScreenToClient(handle, ref pt);
1336 internal override void ScreenToClient(IntPtr handle, ref int x, ref int y)
1338 POINT pnt = new POINT();
1342 Win32ScreenToClient (handle, ref pnt);
1348 internal override void ClientToScreen(IntPtr handle, ref int x, ref int y) {
1349 POINT pnt = new POINT();
1354 Win32ClientToScreen(handle, ref pnt);
1360 internal override void ScreenToMenu(IntPtr handle, ref int x, ref int y) {
1361 ScreenToClient(handle, ref x, ref y);
1364 internal override void MenuToScreen(IntPtr handle, ref int x, ref int y) {
1365 ClientToScreen(handle, ref x, ref y);
1368 internal override void SendAsyncMethod (AsyncMethodData method)
1370 Win32PostMessage(FosterParent, Msg.WM_ASYNC_MESSAGE, IntPtr.Zero, (IntPtr)GCHandle.Alloc (method));
1373 internal override void SetTimer (Timer timer)
1377 index = timer.GetHashCode();
1380 timer_list[index]=timer;
1383 Win32SetTimer(FosterParent, index, (uint)timer.Interval, IntPtr.Zero);
1386 internal override void KillTimer (Timer timer)
1390 index = timer.GetHashCode();
1392 Win32KillTimer(FosterParent, index);
1395 timer_list.Remove(index);
1400 private void CaretCallback(object sender, EventArgs e) {
\r
1401 Console.WriteLine("CaretCallback hit");
\r
1404 internal override void CreateCaret(IntPtr hwnd, int width, int height) {
1405 Win32CreateCaret(hwnd, IntPtr.Zero, width, height);
1408 internal override void DestroyCaret(IntPtr hwnd) {
1409 Win32DestroyCaret();
1412 internal override void SetCaretPos(IntPtr hwnd, int x, int y) {
1413 Win32SetCaretPos(x, y);
1416 internal override void CaretVisible(IntPtr hwnd, bool visible) {
1418 Win32ShowCaret(hwnd);
1420 Win32HideCaret(hwnd);
1424 internal override void SetFocus(IntPtr hwnd) {
\r
1425 Win32SetFocus(hwnd);
\r
1428 internal override IntPtr GetActive() {
1429 return Win32GetActiveWindow();
1432 internal override bool GetFontMetrics(Graphics g, Font font, out int ascent, out int descent) {
1436 tm = new TEXTMETRIC();
1438 dc = Win32GetDC(IntPtr.Zero);
1439 Win32SelectObject(dc, font.ToHfont());
1440 if (Win32GetTextMetrics(dc, ref tm) == false) {
1441 Win32ReleaseDC(IntPtr.Zero, dc);
1446 Win32ReleaseDC(IntPtr.Zero, dc);
1448 ascent = tm.tmAscent;
1449 descent = tm.tmDescent;
1454 internal override void ScrollWindow(IntPtr hwnd, Rectangle rectangle, int XAmount, int YAmount, bool with_children) {
\r
1457 rect = new RECT();
\r
1458 rect.left = rectangle.X;
\r
1459 rect.top = rectangle.Y;
\r
1460 rect.right = rectangle.Right;
\r
1461 rect.bottom = rectangle.Bottom;
\r
1463 Win32ScrollWindowEx(hwnd, XAmount, YAmount, ref rect, IntPtr.Zero, IntPtr.Zero, IntPtr.Zero, ScrollWindowExFlags.SW_INVALIDATE | ScrollWindowExFlags.SW_ERASE | (with_children ? ScrollWindowExFlags.SW_SCROLLCHILDREN : ScrollWindowExFlags.SW_NONE));
\r
1464 Win32UpdateWindow(hwnd);
1467 internal override void ScrollWindow(IntPtr hwnd, int XAmount, int YAmount, bool with_children) {
\r
1468 Win32ScrollWindowEx(hwnd, XAmount, YAmount, IntPtr.Zero, IntPtr.Zero, IntPtr.Zero, IntPtr.Zero, ScrollWindowExFlags.SW_INVALIDATE | ScrollWindowExFlags.SW_ERASE | (with_children ? ScrollWindowExFlags.SW_SCROLLCHILDREN : ScrollWindowExFlags.SW_NONE));
\r
1471 internal override bool SystrayAdd(IntPtr hwnd, string tip, Icon icon, out ToolTip tt) {
\r
1472 NOTIFYICONDATA nid;
\r
1474 nid = new NOTIFYICONDATA();
\r
1476 nid.cbSize = (uint)Marshal.SizeOf(nid);
\r
1477 nid.hIcon = icon.Handle;
\r
1480 nid.uCallbackMessage = (uint)Msg.WM_USER;
\r
1481 nid.uFlags = NotifyIconFlags.NIF_MESSAGE;
\r
1483 if (tip != null) {
\r
1485 nid.uFlags |= NotifyIconFlags.NIF_TIP;
\r
1488 if (icon != null) {
\r
1489 nid.hIcon = icon.Handle;
\r
1490 nid.uFlags |= NotifyIconFlags.NIF_ICON;
\r
1495 return Win32Shell_NotifyIcon(NotifyIconMessage.NIM_ADD, ref nid);
\r
1498 internal override bool SystrayChange(IntPtr hwnd, string tip, Icon icon, ref ToolTip tt) {
\r
1499 NOTIFYICONDATA nid;
\r
1501 nid = new NOTIFYICONDATA();
\r
1503 nid.cbSize = (uint)Marshal.SizeOf(nid);
\r
1504 nid.hIcon = icon.Handle;
\r
1507 nid.uCallbackMessage = (uint)Msg.WM_USER;
\r
1508 nid.uFlags = NotifyIconFlags.NIF_MESSAGE;
\r
1510 if (tip != null) {
\r
1512 nid.uFlags |= NotifyIconFlags.NIF_TIP;
\r
1515 if (icon != null) {
\r
1516 nid.hIcon = icon.Handle;
\r
1517 nid.uFlags |= NotifyIconFlags.NIF_ICON;
\r
1520 return Win32Shell_NotifyIcon(NotifyIconMessage.NIM_MODIFY, ref nid);
\r
1523 internal override void SystrayRemove(IntPtr hwnd, ref ToolTip tt) {
\r
1524 NOTIFYICONDATA nid;
\r
1526 nid = new NOTIFYICONDATA();
\r
1528 nid.cbSize = (uint)Marshal.SizeOf(nid);
\r
1533 Win32Shell_NotifyIcon(NotifyIconMessage.NIM_DELETE, ref nid);
\r
1537 internal override void SetBorderStyle(IntPtr handle, BorderStyle border_style) {
\r
1538 throw new NotImplementedException();
\r
1541 internal override void SetMenu(IntPtr handle, IntPtr menu_handle) {
\r
1542 // Trigger WM_NCCALC
\r
1543 Win32SetWindowPos(handle, IntPtr.Zero, 0, 0, 0, 0, SetWindowPosFlags.SWP_FRAMECHANGED);
\r
1547 internal override Graphics GetMenuDC(IntPtr hwnd, IntPtr ncpaint_region) {
\r
1552 // hdc = Win32GetDCEx(hwnd, ncpaint_region, DCExFlags.DCX_WINDOW | DCExFlags.DCX_INTERSECTRGN | DCExFlags.DCX_USESTYLE);
\r
1553 hdc = Win32GetDCEx(hwnd, ncpaint_region, DCExFlags.DCX_WINDOW);
\r
1555 g = Graphics.FromHdc(hdc);
\r
1557 Win32ReleaseDC(hwnd, hdc);
\r
1562 internal override Point GetMenuOrigin(IntPtr handle) {
1563 // FIXME - this does not yet consider different window styles
1564 return new Point(SystemInformation.FrameBorderSize.Width, SystemInformation.FrameBorderSize.Height + ThemeEngine.Current.CaptionHeight);
1568 internal override void ReleaseMenuDC(IntPtr hwnd, Graphics dc) {
1572 internal override void SetIcon(IntPtr hwnd, Icon icon) {
\r
1573 Win32SendMessage(hwnd, Msg.WM_SETICON, (IntPtr)1, icon.Handle); // 1 = large icon (0 would be small)
\r
1576 internal override void EraseWindowBackground(IntPtr hWnd, IntPtr hDc) {
\r
1583 argb = Win32GetWindowLong(hWnd, WindowLong.GWL_USERDATA);
\r
1584 lb = new LOGBRUSH();
\r
1586 lb.lbColor.B = (byte)((argb & 0xff0000)>>16);
\r
1587 lb.lbColor.G = (byte)((argb & 0xff00)>>8);
\r
1588 lb.lbColor.R = (byte)(argb & 0xff);
\r
1590 lb.lbStyle = LogBrushStyle.BS_SOLID;
\r
1591 hbr = Win32CreateBrushIndirect(ref lb);
\r
1592 Win32GetClientRect(hWnd, out rect);
\r
1593 Win32FillRect(hDc, ref rect, hbr);
\r
1594 Win32DeleteObject(hbr);
\r
1597 internal override int KeyboardSpeed {
1599 Console.WriteLine ("KeyboardSpeed: need to query Windows");
1602 // Return values range from 0 to 31 which map to 2.5 to 30 repetitions per second.
1608 internal override int KeyboardDelay {
1610 Console.WriteLine ("KeyboardDelay: need to query Windows");
1613 // Return values must range from 0 to 4, 0 meaning 250ms,
1614 // and 4 meaning 1000 ms.
1620 internal override event EventHandler Idle;
1622 // Santa's little helper
1623 static void Where() {
1624 Console.WriteLine("Here: {0}", new StackTrace().ToString());
1626 #endregion // Public Static Methods
1628 #region Win32 Imports
1629 [DllImport ("kernel32.dll", EntryPoint="GetLastError", CallingConvention=CallingConvention.StdCall)]
1630 private extern static uint Win32GetLastError();
1632 [DllImport ("user32.dll", EntryPoint="CreateWindowExW", CharSet=CharSet.Unicode, CallingConvention=CallingConvention.StdCall)]
1633 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);
1635 [DllImport ("user32.dll", EntryPoint="DestroyWindow", CallingConvention=CallingConvention.StdCall)]
1636 internal extern static bool Win32DestroyWindow(IntPtr hWnd);
1638 [DllImport ("user32.dll", EntryPoint="PeekMessageW", CharSet=CharSet.Unicode, CallingConvention=CallingConvention.StdCall)]
1639 internal extern static bool Win32PeekMessage(ref MSG msg, IntPtr hWnd, int wFilterMin, int wFilterMax, uint flags);
1641 [DllImport ("user32.dll", EntryPoint="GetMessageW", CharSet=CharSet.Unicode, CallingConvention=CallingConvention.StdCall)]
1642 internal extern static bool Win32GetMessage(ref MSG msg, IntPtr hWnd, int wFilterMin, int wFilterMax);
1644 [DllImport ("user32.dll", EntryPoint="TranslateMessage", CallingConvention=CallingConvention.StdCall)]
1645 internal extern static bool Win32TranslateMessage(ref MSG msg);
1647 [DllImport ("user32.dll", EntryPoint="DispatchMessageW", CharSet=CharSet.Unicode, CallingConvention=CallingConvention.StdCall)]
1648 internal extern static IntPtr Win32DispatchMessage(ref MSG msg);
1650 [DllImport ("user32.dll", EntryPoint="MoveWindow", CallingConvention=CallingConvention.StdCall)]
1651 internal extern static bool Win32MoveWindow(IntPtr hWnd, int x, int y, int width, int height, bool repaint);
1653 [DllImport ("user32.dll", EntryPoint="SetWindowPos", CallingConvention=CallingConvention.StdCall)]
1654 internal extern static bool Win32SetWindowPos(IntPtr hWnd, IntPtr hWndInsertAfter, int x, int y, int cx, int cy, SetWindowPosFlags Flags);
1656 [DllImport ("user32.dll", EntryPoint="SetWindowPos", CallingConvention=CallingConvention.StdCall)]
1657 internal extern static bool Win32SetWindowPos(IntPtr hWnd, SetWindowPosZOrder pos, int x, int y, int cx, int cy, SetWindowPosFlags Flags);
1659 [DllImport ("user32.dll", EntryPoint="SetWindowTextW", CharSet=CharSet.Unicode, CallingConvention=CallingConvention.StdCall)]
1660 internal extern static bool Win32SetWindowText(IntPtr hWnd, string lpString);
1662 [DllImport ("user32.dll", EntryPoint="GetWindowTextW", CharSet=CharSet.Unicode, CallingConvention=CallingConvention.StdCall)]
1663 internal extern static bool Win32GetWindowText(IntPtr hWnd, StringBuilder lpString, int nMaxCount);
1665 [DllImport ("user32.dll", EntryPoint="SetParent", CallingConvention=CallingConvention.StdCall)]
1666 internal extern static IntPtr Win32SetParent(IntPtr hWnd, IntPtr hParent);
1668 [DllImport ("user32.dll", EntryPoint="RegisterClassW", CharSet=CharSet.Unicode, CallingConvention=CallingConvention.StdCall)]
1669 private extern static bool Win32RegisterClass(ref WNDCLASS wndClass);
1671 [DllImport ("user32.dll", EntryPoint="LoadCursorW", CharSet=CharSet.Unicode, CallingConvention=CallingConvention.StdCall)]
1672 private extern static IntPtr Win32LoadCursor(IntPtr hInstance, LoadCursorType type);
1674 [DllImport ("user32.dll", EntryPoint="ShowCursor", CallingConvention=CallingConvention.StdCall)]
1675 private extern static IntPtr Win32ShowCursor(bool bShow);
1677 [DllImport ("user32.dll", EntryPoint="SetCursor", CallingConvention=CallingConvention.StdCall)]
1678 private extern static IntPtr Win32SetCursor(IntPtr hCursor);
1680 [DllImport ("user32.dll", EntryPoint="CreateCursor", CallingConvention=CallingConvention.StdCall)]
1681 private extern static IntPtr Win32CreateCursor(IntPtr hInstance, int xHotSpot, int yHotSpot, int nWidth, int nHeight, Byte[] pvANDPlane, Byte[] pvORPlane);
1683 [DllImport ("user32.dll", EntryPoint="DestroyCursor", CallingConvention=CallingConvention.StdCall)]
1684 private extern static bool Win32DestroyCursor(IntPtr hCursor);
1686 [DllImport ("user32.dll", EntryPoint="DefWindowProcW", CharSet=CharSet.Unicode, CallingConvention=CallingConvention.StdCall)]
1687 private extern static IntPtr Win32DefWindowProc(IntPtr hWnd, Msg Msg, IntPtr wParam, IntPtr lParam);
1689 [DllImport ("user32.dll", EntryPoint="DefDlgProcW", CharSet=CharSet.Unicode, CallingConvention=CallingConvention.StdCall)]
1690 private extern static IntPtr Win32DefDlgProc(IntPtr hWnd, Msg Msg, IntPtr wParam, IntPtr lParam);
1692 [DllImport ("user32.dll", EntryPoint="PostQuitMessage", CallingConvention=CallingConvention.StdCall)]
1693 private extern static IntPtr Win32PostQuitMessage(int nExitCode);
1695 [DllImport ("user32.dll", EntryPoint="UpdateWindow", CallingConvention=CallingConvention.StdCall)]
1696 private extern static IntPtr Win32UpdateWindow(IntPtr hWnd);
1698 [DllImport ("user32.dll", EntryPoint="GetUpdateRect", CallingConvention=CallingConvention.StdCall)]
1699 private extern static bool Win32GetUpdateRect(IntPtr hWnd, ref RECT rect, bool erase);
1701 [DllImport ("user32.dll", EntryPoint="BeginPaint", CallingConvention=CallingConvention.StdCall)]
1702 private extern static IntPtr Win32BeginPaint(IntPtr hWnd, ref PAINTSTRUCT ps);
1704 [DllImport ("user32.dll", EntryPoint="EndPaint", CallingConvention=CallingConvention.StdCall)]
1705 private extern static bool Win32EndPaint(IntPtr hWnd, ref PAINTSTRUCT ps);
1707 [DllImport ("user32.dll", EntryPoint="GetDC", CallingConvention=CallingConvention.StdCall)]
1708 private extern static IntPtr Win32GetDC(IntPtr hWnd);
1710 [DllImport ("user32.dll", EntryPoint="GetDCEx", CallingConvention=CallingConvention.StdCall)]
1711 private extern static IntPtr Win32GetDCEx(IntPtr hWnd, IntPtr hRgn, DCExFlags flags);
1713 [DllImport ("user32.dll", EntryPoint="ReleaseDC", CallingConvention=CallingConvention.StdCall)]
1714 private extern static IntPtr Win32ReleaseDC(IntPtr hWnd, IntPtr hDC);
1716 [DllImport ("user32.dll", EntryPoint="MessageBoxW", CharSet=CharSet.Unicode, CallingConvention=CallingConvention.StdCall)]
1717 private extern static IntPtr Win32MessageBox(IntPtr hParent, string pText, string pCaption, uint uType);
1719 [DllImport ("user32.dll", EntryPoint="InvalidateRect", CallingConvention=CallingConvention.StdCall)]
1720 private extern static IntPtr Win32InvalidateRect(IntPtr hWnd, ref RECT lpRect, bool bErase);
1722 [DllImport ("user32.dll", EntryPoint="InvalidateRect", CallingConvention=CallingConvention.StdCall)]
1723 private extern static IntPtr Win32InvalidateRect(IntPtr hWnd, IntPtr lpRect, bool bErase);
1725 [DllImport ("user32.dll", EntryPoint="SetCapture", CallingConvention=CallingConvention.StdCall)]
1726 private extern static IntPtr Win32SetCapture(IntPtr hWnd);
1728 [DllImport ("user32.dll", EntryPoint="ReleaseCapture", CallingConvention=CallingConvention.StdCall)]
1729 private extern static IntPtr Win32ReleaseCapture();
1731 [DllImport ("user32.dll", EntryPoint="GetWindowRect", CallingConvention=CallingConvention.StdCall)]
1732 private extern static IntPtr Win32GetWindowRect(IntPtr hWnd, out RECT rect);
1734 [DllImport ("user32.dll", EntryPoint="GetClientRect", CallingConvention=CallingConvention.StdCall)]
1735 private extern static IntPtr Win32GetClientRect(IntPtr hWnd, out RECT rect);
1737 [DllImport ("user32.dll", EntryPoint="ScreenToClient", CallingConvention=CallingConvention.StdCall)]
1738 private extern static bool Win32ScreenToClient(IntPtr hWnd, ref POINT pt);
1740 [DllImport ("user32.dll", EntryPoint="ClientToScreen", CallingConvention=CallingConvention.StdCall)]
1741 private extern static bool Win32ClientToScreen(IntPtr hWnd, ref POINT pt);
1743 [DllImport ("user32.dll", EntryPoint="GetParent", CallingConvention=CallingConvention.StdCall)]
1744 private extern static IntPtr Win32GetParent(IntPtr hWnd);
1746 [DllImport ("user32.dll", EntryPoint="SetActiveWindow", CallingConvention=CallingConvention.StdCall)]
1747 private extern static IntPtr Win32SetActiveWindow(IntPtr hWnd);
1749 [DllImport ("user32.dll", EntryPoint="PostQuitMessage", CallingConvention=CallingConvention.StdCall)]
1750 private extern static IntPtr Win32PostQuitMessage(IntPtr hWnd);
1752 [DllImport ("user32.dll", EntryPoint="AdjustWindowRectEx", CallingConvention=CallingConvention.StdCall)]
1753 private extern static bool Win32AdjustWindowRectEx(ref RECT lpRect, int dwStyle, bool bMenu, int dwExStyle);
1755 [DllImport ("user32.dll", EntryPoint="GetCursorPos", CallingConvention=CallingConvention.StdCall)]
1756 private extern static bool Win32GetCursorPos(out POINT lpPoint);
1758 [DllImport ("user32.dll", EntryPoint="SetCursorPos", CallingConvention=CallingConvention.StdCall)]
1759 private extern static bool Win32SetCursorPos(int x, int y);
1761 [DllImport ("user32.dll", EntryPoint="GetWindowPlacement", CallingConvention=CallingConvention.StdCall)]
1762 private extern static bool Win32GetWindowPlacement(IntPtr hWnd, ref WINDOWPLACEMENT lpwndpl);
1764 [DllImport ("user32.dll", EntryPoint="TrackMouseEvent", CallingConvention=CallingConvention.StdCall)]
1765 private extern static bool Win32TrackMouseEvent(ref TRACKMOUSEEVENT tme);
1767 [DllImport ("gdi32.dll", EntryPoint="CreateBrushIndirect", CallingConvention=CallingConvention.StdCall)]
1768 private extern static IntPtr Win32CreateBrushIndirect(ref LOGBRUSH lb);
1770 [DllImport ("user32.dll", EntryPoint="FillRect", CallingConvention=CallingConvention.StdCall)]
1771 private extern static int Win32FillRect(IntPtr hdc, ref RECT rect, IntPtr hbr);
1773 [DllImport ("user32.dll", EntryPoint="SetWindowLong", CallingConvention=CallingConvention.StdCall)]
1774 private extern static IntPtr Win32SetWindowLong(IntPtr hwnd, WindowLong index, IntPtr value);
1776 [DllImport ("user32.dll", EntryPoint="GetWindowLong", CallingConvention=CallingConvention.StdCall)]
1777 private extern static uint Win32GetWindowLong(IntPtr hwnd, WindowLong index);
1779 [DllImport ("gdi32.dll", EntryPoint="DeleteObject", CallingConvention=CallingConvention.StdCall)]
1780 private extern static bool Win32DeleteObject(IntPtr o);
1782 [DllImport ("user32.dll", EntryPoint="PostMessage", CallingConvention=CallingConvention.StdCall)]
1783 private extern static bool Win32PostMessage(IntPtr hwnd, Msg msg, IntPtr wParam, IntPtr lParam);
1785 [DllImport ("user32.dll", EntryPoint="GetKeyState", CallingConvention=CallingConvention.StdCall)]
1786 private extern static short Win32GetKeyState(VirtualKeys nVirtKey);
1788 [DllImport ("user32.dll", EntryPoint="GetDesktopWindow", CallingConvention=CallingConvention.StdCall)]
1789 private extern static IntPtr Win32GetDesktopWindow();
1791 [DllImport ("user32.dll", EntryPoint="SetTimer", CallingConvention=CallingConvention.StdCall)]
1792 private extern static IntPtr Win32SetTimer(IntPtr hwnd, int nIDEvent, uint uElapse, IntPtr timerProc);
1794 [DllImport ("user32.dll", EntryPoint="KillTimer", CallingConvention=CallingConvention.StdCall)]
1795 private extern static IntPtr Win32KillTimer(IntPtr hwnd, int nIDEvent);
1797 [DllImport ("user32.dll", EntryPoint="ShowWindow", CallingConvention=CallingConvention.StdCall)]
1798 private extern static IntPtr Win32ShowWindow(IntPtr hwnd, WindowPlacementFlags nCmdShow);
1800 [DllImport ("user32.dll", EntryPoint="EnableWindow", CallingConvention=CallingConvention.StdCall)]
1801 private extern static IntPtr Win32EnableWindow(IntPtr hwnd, bool Enabled);
1803 [DllImport ("user32.dll", EntryPoint="SetFocus", CallingConvention=CallingConvention.StdCall)]
1804 internal extern static IntPtr Win32SetFocus(IntPtr hwnd);
1806 [DllImport ("user32.dll", EntryPoint="CreateCaret", CallingConvention=CallingConvention.StdCall)]
1807 internal extern static bool Win32CreateCaret(IntPtr hwnd, IntPtr hBitmap, int nWidth, int nHeight);
1809 [DllImport ("user32.dll", EntryPoint="DestroyCaret", CallingConvention=CallingConvention.StdCall)]
1810 private extern static bool Win32DestroyCaret();
1812 [DllImport ("user32.dll", EntryPoint="ShowCaret", CallingConvention=CallingConvention.StdCall)]
1813 private extern static bool Win32ShowCaret(IntPtr hwnd);
1815 [DllImport ("user32.dll", EntryPoint="HideCaret", CallingConvention=CallingConvention.StdCall)]
1816 private extern static bool Win32HideCaret(IntPtr hwnd);
1818 [DllImport ("user32.dll", EntryPoint="SetCaretPos", CallingConvention=CallingConvention.StdCall)]
1819 private extern static bool Win32SetCaretPos(int X, int Y);
1821 [DllImport ("user32.dll", EntryPoint="GetCaretBlinkTime", CallingConvention=CallingConvention.StdCall)]
1822 private extern static uint Win32GetCaretBlinkTime();
1824 [DllImport ("gdi32.dll", EntryPoint="GetTextMetricsW", CharSet=CharSet.Unicode, CallingConvention=CallingConvention.StdCall)]
1825 internal extern static bool Win32GetTextMetrics(IntPtr hdc, ref TEXTMETRIC tm);
1827 [DllImport ("gdi32.dll", EntryPoint="SelectObject", CallingConvention=CallingConvention.StdCall)]
1828 internal extern static bool Win32SelectObject(IntPtr hdc, IntPtr hgdiobject);
1830 [DllImport ("user32.dll", EntryPoint="ScrollWindowEx", CallingConvention=CallingConvention.StdCall)]
1831 private extern static bool Win32ScrollWindowEx(IntPtr hwnd, int dx, int dy, ref RECT prcScroll, ref RECT prcClip, IntPtr hrgnUpdate, out RECT prcUpdate, ScrollWindowExFlags flags);
1833 [DllImport ("user32.dll", EntryPoint="ScrollWindowEx", CallingConvention=CallingConvention.StdCall)]
1834 private extern static bool Win32ScrollWindowEx(IntPtr hwnd, int dx, int dy, ref RECT prcScroll, ref RECT prcClip, IntPtr hrgnUpdate, IntPtr prcUpdate, ScrollWindowExFlags flags);
1836 [DllImport ("user32.dll", EntryPoint="ScrollWindowEx", CallingConvention=CallingConvention.StdCall)]
1837 private extern static bool Win32ScrollWindowEx(IntPtr hwnd, int dx, int dy, ref RECT prcScroll, IntPtr prcClip, IntPtr hrgnUpdate, IntPtr prcUpdate, ScrollWindowExFlags flags);
1839 [DllImport ("user32.dll", EntryPoint="ScrollWindowEx", CallingConvention=CallingConvention.StdCall)]
1840 private extern static bool Win32ScrollWindowEx(IntPtr hwnd, int dx, int dy, IntPtr prcScroll, IntPtr prcClip, IntPtr hrgnUpdate, IntPtr prcUpdate, ScrollWindowExFlags flags);
1842 [DllImport ("user32.dll", EntryPoint="GetActiveWindow", CallingConvention=CallingConvention.StdCall)]
1843 private extern static IntPtr Win32GetActiveWindow();
1845 [DllImport ("user32.dll", EntryPoint="GetSystemMetrics", CallingConvention=CallingConvention.StdCall)]
1846 private extern static int Win32GetSystemMetrics(SystemMetrics nIndex);
1848 [DllImport ("shell32.dll", EntryPoint="Shell_NotifyIconW", CharSet=CharSet.Unicode, CallingConvention=CallingConvention.StdCall)]
1849 private extern static bool Win32Shell_NotifyIcon(NotifyIconMessage dwMessage, ref NOTIFYICONDATA lpData);
1851 [DllImport ("gdi32.dll", EntryPoint="CreateRectRgn", CallingConvention=CallingConvention.StdCall)]
1852 internal extern static IntPtr Win32CreateRectRgn(int nLeftRect, int nTopRect, int nRightRect, int nBottomRect);
1854 [DllImport ("user32.dll", EntryPoint="IsWindowVisible", CallingConvention=CallingConvention.StdCall)]
\r
1855 private extern static bool IsWindowVisible(IntPtr hwnd);
\r
1857 [DllImport ("user32.dll", EntryPoint="SetClassLong", CallingConvention=CallingConvention.StdCall)]
\r
1858 private extern static bool Win32SetClassLong(IntPtr hwnd, ClassLong nIndex, IntPtr dwNewLong);
\r
1860 [DllImport ("user32.dll", EntryPoint="SendMessageW", CharSet=CharSet.Unicode, CallingConvention=CallingConvention.StdCall)]
\r
1861 private extern static bool Win32SendMessage(IntPtr hwnd, Msg msg, IntPtr wParam, IntPtr lParam);
\r