private static int scroll_height;
private static Hashtable wm_nc_registered;
private static RECT clipped_cursor_rect;
+ private Hashtable registered_classes;
+ private Hwnd HwndCreating; // the Hwnd we are currently creating (see CreateWindow)
#endregion // Local Variables
internal int top;
internal int right;
internal int bottom;
- public override string ToString() {
+
+ public RECT (int left, int top, int right, int bottom)
+ {
+ this.left = left;
+ this.top = top;
+ this.right = right;
+ this.bottom = bottom;
+ }
+
+ #region Instance Properties
+ public int Height { get { return bottom - top + 1; } }
+ public int Width { get { return right - left + 1; } }
+ public Size Size { get { return new Size (Width, Height); } }
+ public Point Location { get { return new Point (left, top); } }
+ #endregion
+
+ #region Instance Methods
+ public Rectangle ToRectangle ()
+ {
+ return Rectangle.FromLTRB (left, top, right, bottom);
+ }
+
+ public static RECT FromRectangle (Rectangle rectangle)
+ {
+ return new RECT (rectangle.Left, rectangle.Top, rectangle.Right, rectangle.Bottom);
+ }
+
+ public override int GetHashCode ()
+ {
+ return left ^ ((top << 13) | (top >> 0x13))
+ ^ ((Width << 0x1a) | (Width >> 6))
+ ^ ((Height << 7) | (Height >> 0x19));
+ }
+
+ public override string ToString ()
+ {
return String.Format("RECT left={0}, top={1}, right={2}, bottom={3}, width={4}, height={5}", left, top, right, bottom, right-left, bottom-top);
}
+ #endregion
- }
+ #region Operator overloads
+ public static implicit operator Rectangle (RECT rect)
+ {
+ return Rectangle.FromLTRB (rect.left, rect.top, rect.right, rect.bottom);
+ }
- [StructLayout(LayoutKind.Sequential)]
- internal struct POINT {
- internal int x;
- internal int y;
+ public static implicit operator RECT (Rectangle rect)
+ {
+ return new RECT (rect.Left, rect.Top, rect.Right, rect.Bottom);
+ }
+ #endregion
}
internal enum SPIAction {
+ SPI_GETKEYBOARDSPEED = 0x000A,
+ SPI_GETKEYBOARDDELAY = 0x0016,
SPI_GETWORKAREA = 0x0030,
SPI_GETMOUSEHOVERWIDTH = 0x0062,
SPI_GETMOUSEHOVERHEIGHT = 0x0064,
SPI_GETMOUSEHOVERTIME = 0x0066,
+ SPI_GETWHEELSCROLLLINES = 0x0068
}
internal enum WindowPlacementFlags {
CS_BYTEALIGNCLIENT = 0x00001000,
CS_BYTEALIGNWINDOW = 0x00002000,
CS_GLOBALCLASS = 0x00004000,
- CS_IME = 0x00010000
+ CS_IME = 0x00010000,
+ // Windows XP+
+ CS_DROPSHADOW = 0x00020000
}
internal enum SetWindowPosZOrder {
#region Constructor & Destructor
private XplatUIWin32() {
- WNDCLASS wndClass;
- bool result;
-
// Handle singleton stuff first
ref_count=0;
themes_enabled = false;
- // Prepare 'our' window class
- wnd_proc = new WndProc(NativeWindow.WndProc);
- wndClass.style = (int)(ClassStyle.CS_OWNDC | ClassStyle.CS_DBLCLKS);
- wndClass.lpfnWndProc = wnd_proc;
- wndClass.cbClsExtra = 0;
- wndClass.cbWndExtra = 0;
- wndClass.hbrBackground = IntPtr.Zero;
- wndClass.hCursor = Win32LoadCursor(IntPtr.Zero, LoadCursorType.IDC_ARROW);
- wndClass.hIcon = IntPtr.Zero;
- wndClass.hInstance = IntPtr.Zero;
- wndClass.lpszClassName = XplatUI.DefaultClassName;
- wndClass.lpszMenuName = "";
-
- result=Win32RegisterClass(ref wndClass);
- if (result==false) {
- Win32MessageBox(IntPtr.Zero, "Could not register the "+XplatUI.DefaultClassName+" window class, win32 error " + Win32GetLastError().ToString(), "Oops", 0);
- }
+ wnd_proc = new WndProc(InternalWndProc);
FosterParent=Win32CreateWindow((int)WindowExStyles.WS_EX_TOOLWINDOW, "static", "Foster Parent Window", (int)WindowStyles.WS_OVERLAPPEDWINDOW, 0, 0, 0, 0, IntPtr.Zero, IntPtr.Zero, IntPtr.Zero, IntPtr.Zero);
scroll_width = Win32GetSystemMetrics(SystemMetrics.SM_CXVSCROLL);
timer_list = new Hashtable ();
+ registered_classes = new Hashtable ();
}
#endregion // Constructor & Destructor
#region Private Support Methods
+ private string RegisterWindowClass (int classStyle)
+ {
+ string class_name;
+
+ lock (registered_classes) {
+ class_name = (string)registered_classes[classStyle];
+
+ if (class_name != null)
+ return class_name;
+
+ class_name = string.Format ("Mono.WinForms.{0}.{1}", System.Threading.Thread.GetDomainID ().ToString (), classStyle);
+
+ WNDCLASS wndClass;
+
+ wndClass.style = classStyle;
+ wndClass.lpfnWndProc = wnd_proc;
+ wndClass.cbClsExtra = 0;
+ wndClass.cbWndExtra = 0;
+ wndClass.hbrBackground = (IntPtr)(GetSysColorIndex.COLOR_WINDOW + 1);
+ wndClass.hCursor = Win32LoadCursor (IntPtr.Zero, LoadCursorType.IDC_ARROW);
+ wndClass.hIcon = IntPtr.Zero;
+ wndClass.hInstance = IntPtr.Zero;
+ wndClass.lpszClassName = class_name;
+ wndClass.lpszMenuName = "";
+
+ bool result = Win32RegisterClass (ref wndClass);
+
+ if (result == false)
+ Win32MessageBox (IntPtr.Zero, "Could not register the window class, win32 error " + Win32GetLastError ().ToString (), "Oops", 0);
+
+ registered_classes[classStyle] = class_name;
+ }
+
+ return class_name;
+ }
+
private static bool RetrieveMessage(ref MSG msg) {
MSG message;
}
}
+ internal override int MouseWheelScrollDelta {
+ get {
+ int delta = 120;
+ Win32SystemParametersInfo(SPIAction.SPI_GETWHEELSCROLLLINES, 0, ref delta, 0);
+ return delta;
+ }
+ }
+
internal override int HorizontalScrollBarHeight {
get {
return scroll_height;
ParentHandle = FosterParent;
}
- // Since we fake MDI dont tell Windows that this is a real MDI window
- if ((cp.ExStyle & (int) WindowExStyles.WS_EX_MDICHILD) != 0) {
- SetMdiStyles (cp);
- }
+ FakeStyles (cp);
+
+ string class_name = RegisterWindowClass (cp.ClassStyle);
+ HwndCreating = hwnd;
+
+ WindowHandle = Win32CreateWindow ((uint)cp.ExStyle, class_name, cp.Caption, (uint)cp.Style, cp.X, cp.Y, cp.Width, cp.Height, ParentHandle, IntPtr.Zero, IntPtr.Zero, IntPtr.Zero);
- 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);
+ HwndCreating = null;
if (WindowHandle==IntPtr.Zero) {
uint error = Win32GetLastError();
internal override void SetWindowStyle(IntPtr handle, CreateParams cp) {
- if ((cp.ExStyle & (int) WindowExStyles.WS_EX_MDICHILD) != 0) {
- SetMdiStyles (cp);
- }
+ FakeStyles (cp);
Win32SetWindowLong(handle, WindowLong.GWL_STYLE, (uint)cp.Style);
Win32SetWindowLong(handle, WindowLong.GWL_EXSTYLE, (uint)cp.ExStyle);
SetWindowPosFlags.SWP_DRAWFRAME);
}
+ private IntPtr InternalWndProc (IntPtr hWnd, Msg msg, IntPtr wParam, IntPtr lParam)
+ {
+ if (HwndCreating != null && HwndCreating.ClientWindow == IntPtr.Zero)
+ HwndCreating.ClientWindow = hWnd;
+ return NativeWindow.WndProc (hWnd, msg, wParam, lParam);
+ }
+
internal override IntPtr DefWndProc(ref Message msg) {
msg.Result=Win32DefWindowProc(msg.HWnd, (Msg)msg.Msg, msg.WParam, msg.LParam);
return msg.Result;
}
}
- // We need to fake WM_MOUSE_ENTER/WM_MOUSE_LEAVE
+ // We need to fake WM_MOUSE_ENTER
switch (msg.message) {
case Msg.WM_LBUTTONDOWN: {
mouse_state |= MouseButtons.Left;
case Msg.WM_MOUSELEAVE: {
prev_mouse_hwnd = IntPtr.Zero;
- msg.message=Msg.WM_MOUSE_LEAVE;
break;
}
return false;
}
- internal override bool SetTopmost(IntPtr hWnd, IntPtr hWndOwner, bool Enabled) {
+ internal override bool SetTopmost(IntPtr hWnd, bool Enabled) {
if (Enabled) {
Win32SetWindowPos(hWnd, SetWindowPosZOrder.HWND_TOPMOST, 0, 0, 0, 0, SetWindowPosFlags.SWP_NOMOVE | SetWindowPosFlags.SWP_NOSIZE | SetWindowPosFlags.SWP_NOACTIVATE);
return true;
return true;
}
}
+
+ internal override bool SetOwner(IntPtr hWnd, IntPtr hWndOwner) {
+ Win32SetWindowLong(hWnd, WindowLong.GWL_HWNDPARENT, (uint) hWndOwner);
+ return true;
+ }
internal override bool Text(IntPtr handle, string text) {
Win32SetWindowText(handle, text);
internal override bool SetVisible (IntPtr handle, bool visible, bool activate)
{
if (visible) {
- if (Control.FromHandle (handle) is Form) {
+ Control c = Control.FromHandle (handle);
+ if (c is Form) {
Form f;
f = (Form)Control.FromHandle (handle);
case FormWindowState.Maximized: flags = WindowPlacementFlags.SW_MAXIMIZE; break;
}
- if (Hwnd.ObjectFromHandle (handle).no_activate)
- flags |= WindowPlacementFlags.SW_SHOWNOACTIVATE;
+ if (!f.ActivateOnShow)
+ flags = WindowPlacementFlags.SW_SHOWNOACTIVATE;
Win32ShowWindow (handle, flags);
}
else {
- if (Hwnd.ObjectFromHandle (handle).no_activate)
- Win32ShowWindow (handle, WindowPlacementFlags.SW_SHOWNOACTIVATE);
- else
+ if (c.ActivateOnShow)
Win32ShowWindow (handle, WindowPlacementFlags.SW_SHOWNORMAL);
+ else
+ Win32ShowWindow (handle, WindowPlacementFlags.SW_SHOWNOACTIVATE);
}
}
else {
return;
}
+ #if NET_2_0
+ internal override void ShowBalloonTip(int timeout, string tipTitle, string tipText, ToolTipIcon tipIcon)
+ {
+ // TODO:
+ }
+#endif
+
internal override void SendAsyncMethod (AsyncMethodData method)
{
Win32PostMessage(FosterParent, Msg.WM_ASYNC_MESSAGE, IntPtr.Zero, (IntPtr)GCHandle.Alloc (method));
timer_list.Remove(index);
}
}
-
- private void SetMdiStyles (CreateParams cp)
+
+ private void FakeStyles (CreateParams cp)
{
- cp.Style = (int)WindowStyles.WS_CHILD | (int)WindowStyles.WS_CLIPCHILDREN | (int)WindowStyles.WS_CLIPSIBLINGS;
- cp.ExStyle = 0;
+ if (cp.HasWindowManager) {
+ // Remove all styles but WS_VISIBLE.
+ cp.WindowStyle &= WindowStyles.WS_VISIBLE;
+ // Set styles that enables us to use the window manager.
+ cp.WindowStyle |= WindowStyles.WS_CHILD | WindowStyles.WS_CLIPCHILDREN | WindowStyles.WS_CLIPSIBLINGS;
+ cp.ExStyle = 0;
+ }
}
-
+
internal override void CreateCaret(IntPtr hwnd, int width, int height) {
Win32CreateCaret(hwnd, IntPtr.Zero, width, height);
caret_visible = false;
internal override int KeyboardSpeed {
get {
- Console.WriteLine ("KeyboardSpeed: need to query Windows");
-
+ int speed = 0;
+ Win32SystemParametersInfo(SPIAction.SPI_GETKEYBOARDSPEED, 0, ref speed, 0);
//
// Return values range from 0 to 31 which map to 2.5 to 30 repetitions per second.
//
- return 0;
+ return speed;
}
}
internal override int KeyboardDelay {
get {
- Console.WriteLine ("KeyboardDelay: need to query Windows");
-
+ int delay = 1;
+ Win32SystemParametersInfo(SPIAction.SPI_GETKEYBOARDDELAY, 0, ref delay, 0);
//
// Return values must range from 0 to 4, 0 meaning 250ms,
// and 4 meaning 1000 ms.
//
- return 1;
+ return delay;
}
}