Пример #1
0
		void PerformNCCalc(Hwnd hwnd) {
			XplatUIWin32.NCCALCSIZE_PARAMS	ncp;
			IntPtr				ptr;
			Rectangle			rect;

			rect = new Rectangle (0, 0, hwnd.Width, hwnd.Height);

			ncp = new XplatUIWin32.NCCALCSIZE_PARAMS();
			ptr = Marshal.AllocHGlobal(Marshal.SizeOf(ncp));

			ncp.rgrc1.left = rect.Left;
			ncp.rgrc1.top = rect.Top;
			ncp.rgrc1.right = rect.Right;
			ncp.rgrc1.bottom = rect.Bottom;

			Marshal.StructureToPtr(ncp, ptr, true);
			NativeWindow.WndProc(hwnd.client_window, Msg.WM_NCCALCSIZE, (IntPtr)1, ptr);
			ncp = (XplatUIWin32.NCCALCSIZE_PARAMS)Marshal.PtrToStructure(ptr, typeof(XplatUIWin32.NCCALCSIZE_PARAMS));
			Marshal.FreeHGlobal(ptr);


			rect = new Rectangle(ncp.rgrc1.left, ncp.rgrc1.top, ncp.rgrc1.right - ncp.rgrc1.left, ncp.rgrc1.bottom - ncp.rgrc1.top);
			hwnd.ClientRect = rect;
		
			rect = TranslateClientRectangleToXClientRectangle (hwnd);

			if (hwnd.visible) {
				MoveResizeWindow (DisplayHandle, hwnd.client_window, rect.X, rect.Y, rect.Width, rect.Height);
			}

			AddExpose (hwnd, hwnd.WholeWindow == hwnd.ClientWindow, 0, 0, hwnd.Width, hwnd.Height);
		}
Пример #2
0
		internal override bool GetMessage (ref MSG msg, IntPtr handle, int wFilterMin, int wFilterMax)
		{
			XEvent	xevent;
			bool	client;
			Hwnd	hwnd;
			
			ProcessNextMessage:
			
			if (MessageQueue.Count > 0) {
				xevent = (XEvent) MessageQueue.Dequeue ();
			} else {
				UpdateMessageQueue ();
				
				if (MessageQueue.Count > 0) {
					xevent = (XEvent) MessageQueue.Dequeue ();
				} else {
					if (!PostQuitState) {
						msg.hwnd = IntPtr.Zero;
						msg.message = Msg.WM_ENTERIDLE;
						return true;
					}
					
					// We reset ourselves so GetMessage can be called again
					PostQuitState = false;
					
					return false;
				}
			}
			
			// FIXME - handle filtering
			
			hwnd = Hwnd.GetObjectFromWindow (xevent.AnyEvent.window);
			
			// Handle messages for windows that are already or are about to be destroyed
			if (hwnd == null) {
				#if DriverDebug
					Console.WriteLine("GetMessage(): Got message {0} for non-existent or already destroyed window {1:X}", xevent.type, xevent.AnyEvent.window.ToInt32());
				#endif
				goto ProcessNextMessage;
			}
			
			if (hwnd.client_window == xevent.AnyEvent.window) {
				client = true;
				//Console.WriteLine("Client message, sending to window {0:X}", msg.hwnd.ToInt32());
			} else {
				client = false;
				//Console.WriteLine("Non-Client message, sending to window {0:X}", msg.hwnd.ToInt32());
			}
			
			msg.hwnd = hwnd.Handle;
			
			//
			// If you add a new event to this switch make sure to add it in
			// UpdateMessage also unless it is not coming through the X event system.
			//
			switch (xevent.type) {
			case XEventName.KeyPress: {
					Keyboard.KeyEvent (FocusWindow, xevent, ref msg);
					break;
				}
				
			case XEventName.KeyRelease: {
					Keyboard.KeyEvent (FocusWindow, xevent, ref msg);
					break;
				}
				
			case XEventName.ButtonPress: {
					switch (xevent.ButtonEvent.button) {
					case 1: {
							MouseState |= MouseButtons.Left;
							if (client) {
								msg.message = Msg.WM_LBUTTONDOWN;
							} else {
								msg.message = Msg.WM_NCLBUTTONDOWN;
								WholeToScreen (msg.hwnd, ref xevent.ButtonEvent.x, ref xevent.ButtonEvent.y);
							}
							// TODO: For WM_NCLBUTTONDOWN wParam specifies a hit-test value not the virtual keys down
							msg.wParam = GetMousewParam (0);
							break;
						}
						
					case 2: {
							MouseState |= MouseButtons.Middle;
							if (client) {
								msg.message = Msg.WM_MBUTTONDOWN;
							} else {
								msg.message = Msg.WM_NCMBUTTONDOWN;
								WholeToScreen (msg.hwnd, ref xevent.ButtonEvent.x, ref xevent.ButtonEvent.y);
							}
							msg.wParam = GetMousewParam (0);
							break;
						}
						
					case 3: {
							MouseState |= MouseButtons.Right;
							if (client) {
								msg.message = Msg.WM_RBUTTONDOWN;
							} else {
								msg.message = Msg.WM_NCRBUTTONDOWN;
								WholeToScreen (msg.hwnd, ref xevent.ButtonEvent.x, ref xevent.ButtonEvent.y);
							}
							msg.wParam = GetMousewParam (0);
							break;
						}
						
					case 4: {
							msg.message = Msg.WM_MOUSEWHEEL;
							msg.wParam = GetMousewParam (120);
							break;
						}
						
					case 5: {
							msg.message = Msg.WM_MOUSEWHEEL;
							msg.wParam = GetMousewParam (-120);
							break;
						}
						
					}
					
					msg.lParam = (IntPtr) (xevent.ButtonEvent.y << 16 | xevent.ButtonEvent.x);
					MousePosition.X = xevent.ButtonEvent.x;
					MousePosition.Y = xevent.ButtonEvent.y;
					
					if (!hwnd.Enabled) {
						IntPtr dummy;
						
						msg.hwnd = hwnd.EnabledHwnd;
						XTranslateCoordinates (DisplayHandle, xevent.AnyEvent.window, Hwnd.ObjectFromHandle (msg.hwnd).ClientWindow, xevent.ButtonEvent.x, xevent.ButtonEvent.y, out xevent.ButtonEvent.x, out xevent.ButtonEvent.y, out dummy);
						msg.lParam = (IntPtr)(MousePosition.Y << 16 | MousePosition.X);
					}
					
					if (Grab.Hwnd != IntPtr.Zero) {
						msg.hwnd = Grab.Hwnd;
					}
					
					if (!ClickPending.Pending) {
						ClickPending.Pending = true;
						ClickPending.Hwnd = msg.hwnd;
						ClickPending.Message = msg.message;
						ClickPending.wParam = msg.wParam;
						ClickPending.lParam = msg.lParam;
						ClickPending.Time = (long)xevent.ButtonEvent.time;
					} else {
						if ((((long)xevent.ButtonEvent.time - ClickPending.Time) < DoubleClickInterval) && (msg.wParam == ClickPending.wParam) && (msg.lParam == ClickPending.lParam) && (msg.message == ClickPending.Message)) {
							// Looks like a genuine double click, clicked twice on the same spot with the same keys
							switch (xevent.ButtonEvent.button) {
							case 1: {
									msg.message = client ? Msg.WM_LBUTTONDBLCLK : Msg.WM_NCLBUTTONDBLCLK;
									break;
								}
								
							case 2: {
									msg.message = client ? Msg.WM_MBUTTONDBLCLK : Msg.WM_NCMBUTTONDBLCLK;
									break;
								}
								
							case 3: {
									msg.message = client ? Msg.WM_RBUTTONDBLCLK : Msg.WM_NCRBUTTONDBLCLK;
									break;
								}
							}
						}
						ClickPending.Pending = false;
					}
					
					break;
				}
				
			case XEventName.ButtonRelease: {
					Dnd.HandleButtonRelease (ref xevent);
					switch (xevent.ButtonEvent.button) {
					case 1: {
							if (client) {
								msg.message = Msg.WM_LBUTTONUP;
							} else {
								msg.message = Msg.WM_NCLBUTTONUP;
								WholeToScreen (msg.hwnd, ref xevent.ButtonEvent.x, ref xevent.ButtonEvent.y);
							}
							msg.wParam = GetMousewParam (0);
							MouseState &= ~MouseButtons.Left;
							break;
						}
						
					case 2: {
							if (client) {
								msg.message = Msg.WM_MBUTTONUP;
							} else {
								msg.message = Msg.WM_NCMBUTTONUP;
								WholeToScreen (msg.hwnd, ref xevent.ButtonEvent.x, ref xevent.ButtonEvent.y);
							}
							msg.wParam = GetMousewParam (0);
							MouseState &= ~MouseButtons.Middle;
							break;
						}
						
					case 3: {
							if (client) {
								msg.message = Msg.WM_RBUTTONUP;
							} else {
								msg.message = Msg.WM_NCRBUTTONUP;
								WholeToScreen (msg.hwnd, ref xevent.ButtonEvent.x, ref xevent.ButtonEvent.y);
							}
							msg.wParam = GetMousewParam (0);
							MouseState &= ~MouseButtons.Right;
							break;
						}
						
					case 4: {
							goto ProcessNextMessage;
						}
						
					case 5: {
							goto ProcessNextMessage;
						}
					}
					
					if (!hwnd.Enabled) {
						IntPtr dummy;
						
						msg.hwnd = hwnd.EnabledHwnd;
						XTranslateCoordinates (DisplayHandle, xevent.AnyEvent.window, Hwnd.ObjectFromHandle (msg.hwnd).ClientWindow, xevent.ButtonEvent.x, xevent.ButtonEvent.y, out xevent.ButtonEvent.x, out xevent.ButtonEvent.y, out dummy);
						msg.lParam = (IntPtr)(MousePosition.Y << 16 | MousePosition.X);
					}
					
					if (Grab.Hwnd != IntPtr.Zero) {
						msg.hwnd = Grab.Hwnd;
					}
					
					msg.lParam = (IntPtr) (xevent.ButtonEvent.y << 16 | xevent.ButtonEvent.x);
					MousePosition.X = xevent.ButtonEvent.x;
					MousePosition.Y = xevent.ButtonEvent.y;
					break;
				}
				
			case XEventName.MotionNotify: {
					if (client) {
						#if DriverDebugExtra
							Console.WriteLine("GetMessage(): Window {0:X} MotionNotify x={1} y={2}", client ? hwnd.client_window.ToInt32() : hwnd.whole_window.ToInt32(), xevent.MotionEvent.x, xevent.MotionEvent.y);
						#endif
						
						if (Dnd.HandleMotionNotify (ref xevent))
							goto ProcessNextMessage;
						if (Grab.Hwnd != IntPtr.Zero) {
							msg.hwnd = Grab.Hwnd;
						} else {
							NativeWindow.WndProc (msg.hwnd, Msg.WM_SETCURSOR, msg.hwnd, (IntPtr)HitTest.HTCLIENT);
						}
						
						msg.message = Msg.WM_MOUSEMOVE;
						msg.wParam = GetMousewParam (0);
						msg.lParam = (IntPtr) (xevent.MotionEvent.y << 16 | xevent.MotionEvent.x & 0xFFFF);
						
						if (!hwnd.Enabled) {
							IntPtr dummy;
							
							msg.hwnd = hwnd.EnabledHwnd;
							XTranslateCoordinates (DisplayHandle, xevent.AnyEvent.window, Hwnd.ObjectFromHandle (msg.hwnd).ClientWindow, xevent.MotionEvent.x, xevent.MotionEvent.y, out xevent.MotionEvent.x, out xevent.MotionEvent.y, out dummy);
							msg.lParam = (IntPtr)(MousePosition.Y << 16 | MousePosition.X);
						}
						
						HoverState.X = MousePosition.X = xevent.MotionEvent.x;
						HoverState.Y = MousePosition.Y = xevent.MotionEvent.y;
						
						break;
					} else {
						#if DriverDebugExtra
							Console.WriteLine("GetMessage(): non-client area {0:X} MotionNotify x={1} y={2}", client ? hwnd.client_window.ToInt32() : hwnd.whole_window.ToInt32(), xevent.MotionEvent.x, xevent.MotionEvent.y);
						#endif
						msg.message = Msg.WM_NCMOUSEMOVE;
						msg.lParam = (IntPtr) (xevent.MotionEvent.y << 16 | xevent.MotionEvent.x & 0xFFFF);
						
						if (!hwnd.Enabled) {
							IntPtr dummy;
							
							msg.hwnd = hwnd.EnabledHwnd;
							XTranslateCoordinates (DisplayHandle, xevent.AnyEvent.window, Hwnd.ObjectFromHandle (msg.hwnd).ClientWindow, xevent.MotionEvent.x, xevent.MotionEvent.y, out xevent.MotionEvent.x, out xevent.MotionEvent.y, out dummy);
							msg.lParam = (IntPtr)(MousePosition.Y << 16 | MousePosition.X);
						}
						
						#if notyet
							// Not sure we need this...
							HitTest	ht;
							ht = NativeWindow.WndProc(hwnd.client_window, Msg.WM_NCHITTEST, IntPtr.Zero, msg.lParam);
						#endif
						
						MousePosition.X = xevent.MotionEvent.x;
						MousePosition.Y = xevent.MotionEvent.y;
					}
					
					break;
				}
				
			case XEventName.EnterNotify: {
					if (!hwnd.Enabled) {
						goto ProcessNextMessage;
					}
					if (xevent.CrossingEvent.mode != NotifyMode.NotifyNormal) {
						goto ProcessNextMessage;
					}
					msg.message = Msg.WM_MOUSE_ENTER;
					HoverState.Timer.Enabled = true;
					HoverState.Window = xevent.CrossingEvent.window;
					break;
				}
				
			case XEventName.LeaveNotify: {
					if (!hwnd.Enabled) {
						goto ProcessNextMessage;
					}
					if (xevent.CrossingEvent.mode != NotifyMode.NotifyNormal) {
						goto ProcessNextMessage;
					}
					msg.message = Msg.WM_MOUSELEAVE;
					HoverState.Timer.Enabled = false;
					HoverState.Window = IntPtr.Zero;
					break;
				}
				
				#if later
				case XEventName.CreateNotify: {
					if (client && (xevent.ConfigureEvent.xevent == xevent.ConfigureEvent.window)) {
						msg.message = WM_CREATE;
						// Set up CreateStruct
					} else {
						goto ProcessNextMessage;
					}
					break;
				}
				#endif
				
				
			case XEventName.ReparentNotify: {
					if (hwnd.parent == null) {	// Toplevel
						if (xevent.ReparentEvent.parent != IntPtr.Zero) {
							// We need to adjust x/y
							int	dummy_int;
							
							hwnd.Reparented = true;
							
							gdk_window_get_geometry (gdk_window_lookup (hwnd.whole_window), out hwnd.x, out hwnd.y, out dummy_int, out dummy_int, out dummy_int);
							msg.message = Msg.WM_WINDOWPOSCHANGED;
							if (hwnd.opacity != 0xffffffff) {
								uint opacity;
								
								opacity = hwnd.opacity;
								XChangeProperty (DisplayHandle, XGetParent (hwnd.whole_window), NetAtoms [(int)NA._NET_WM_WINDOW_OPACITY], Atom.XA_CARDINAL, 32, PropertyMode.Replace, ref opacity, 1);
							}
						} else {
							hwnd.Reparented = false;
							goto ProcessNextMessage;
						}
					}
					break;
				}
				
			case XEventName.ConfigureNotify: {
					if (!client && (xevent.ConfigureEvent.xevent == xevent.ConfigureEvent.window)) {	// Ignore events for children (SubstructureNotify) and client areas
						XplatUIWin32.NCCALCSIZE_PARAMS	ncp;
						IntPtr				ptr;
						Rectangle			rect;
						
						#if DriverDebugExtra
							Console.WriteLine("GetMessage(): Window {0:X} ConfigureNotify x={1} y={2} width={3} height={4}", hwnd.client_window.ToInt32(), xevent.ConfigureEvent.x, xevent.ConfigureEvent.y, xevent.ConfigureEvent.width, xevent.ConfigureEvent.height);
						#endif
						msg.message = Msg.WM_WINDOWPOSCHANGED;
						hwnd.configure_pending = false;
						
						// We need to adjust our client window to track the resize of whole_window
						rect = hwnd.DefaultClientRect;
						
						ncp = new XplatUIWin32.NCCALCSIZE_PARAMS ();
						ptr = Marshal.AllocHGlobal (Marshal.SizeOf (ncp));
						
						ncp.rgrc1.left = rect.Left;
						ncp.rgrc1.top = rect.Top;
						ncp.rgrc1.right = rect.Right;
						ncp.rgrc1.bottom = rect.Bottom;
						
						Marshal.StructureToPtr (ncp, ptr, true);
						NativeWindow.WndProc (hwnd.client_window, Msg.WM_NCCALCSIZE, (IntPtr)1, ptr);
						ncp = (XplatUIWin32.NCCALCSIZE_PARAMS)Marshal.PtrToStructure (ptr, typeof(XplatUIWin32.NCCALCSIZE_PARAMS));
						Marshal.FreeHGlobal (ptr);
						
						// FIXME - debug this with Menus, need to set hwnd.ClientRect
						
						rect = new Rectangle (ncp.rgrc1.left, ncp.rgrc1.top, ncp.rgrc1.right - ncp.rgrc1.left, ncp.rgrc1.bottom - ncp.rgrc1.top);
						//Console.WriteLine("CreateOffscreenbuffer...");
//						CreateOffscreenBuffer (ref hwnd.client_offscreen, rect.Width, rect.Height);
						
						XMoveResizeWindow (DisplayHandle, hwnd.client_window, rect.X, rect.Y, rect.Width, rect.Height);
					} else {
						goto ProcessNextMessage;
					}
					
					msg.lParam = IntPtr.Zero;		// FIXME - Generate LPWINDOWPOS structure and pass on
					break;
				}
				
			case XEventName.FocusIn: {
					if (!hwnd.Enabled) {
						goto ProcessNextMessage;
					}
					msg.message = Msg.WM_SETFOCUS;
					msg.wParam = IntPtr.Zero;
					break;
				}
				
			case XEventName.FocusOut: {
					if (!hwnd.Enabled) {
						goto ProcessNextMessage;
					}
					msg.message = Msg.WM_KILLFOCUS;
					msg.wParam = IntPtr.Zero;
					break;
				}
				
			case XEventName.Expose: {
					if (PostQuitState) {
						goto ProcessNextMessage;
					}
					
					
					if (client) {
						if (!hwnd.expose_pending) {
							goto ProcessNextMessage;
						}
					} else {
						if (!hwnd.nc_expose_pending) {
							goto ProcessNextMessage;
						}
						
						switch (hwnd.border_style) {
						case FormBorderStyle.Fixed3D: {
								Graphics g;
								
								g = Graphics.FromHwnd (hwnd.whole_window);
								ControlPaint.DrawBorder3D (g, new Rectangle (0, 0, hwnd.Width, hwnd.Height));
								g.Dispose ();
								break;
							}
							
						case FormBorderStyle.FixedSingle: {
								Graphics g;
								
								g = Graphics.FromHwnd (hwnd.whole_window);
								ControlPaint.DrawBorder (g, new Rectangle (0, 0, hwnd.Width, hwnd.Height), Color.Black, ButtonBorderStyle.Solid);
								g.Dispose ();
								break;
							}
						}
						#if DriverDebugExtra
							Console.WriteLine("GetMessage(): Window {0:X} Exposed non-client area {1},{2} {3}x{4}", hwnd.client_window.ToInt32(), xevent.ExposeEvent.x, xevent.ExposeEvent.y, xevent.ExposeEvent.width, xevent.ExposeEvent.height);
						#endif
						
						Rectangle rect = new Rectangle (xevent.ExposeEvent.x, xevent.ExposeEvent.y, xevent.ExposeEvent.width, xevent.ExposeEvent.height);
						Region region = new Region (rect);
						IntPtr hrgn = region.GetHrgn (null); // Graphics object isn't needed
						msg.message = Msg.WM_NCPAINT;
						msg.wParam = hrgn;
						hwnd.nc_expose_pending = false;
						break;
					}
					#if DriverDebugExtra
						Console.WriteLine("GetMessage(): Window {0:X} Exposed area {1},{2} {3}x{4}", hwnd.client_window.ToInt32(), xevent.ExposeEvent.x, xevent.ExposeEvent.y, xevent.ExposeEvent.width, xevent.ExposeEvent.height);
					#endif
					if (Caret.Visible == 1) {
						Caret.Paused = true;
						HideCaret ();
					}
					
					if (Caret.Visible == 1) {
						ShowCaret ();
						Caret.Paused = false;
					}
					msg.message = Msg.WM_PAINT;
					break;
				}
				
			case XEventName.DestroyNotify: {
					
					// This is a bit tricky, we don't receive our own DestroyNotify, we only get those for our children
					hwnd = Hwnd.ObjectFromHandle (xevent.DestroyWindowEvent.window);
					
					// We may get multiple for the same window, act only one the first (when Hwnd still knows about it)
					if (hwnd.client_window == xevent.DestroyWindowEvent.window) {
						msg.hwnd = hwnd.client_window;
						msg.message = Msg.WM_DESTROY;
						hwnd.Dispose ();
						
						#if DriverDebug
							Console.WriteLine("Got DestroyNotify on Window {0:X}", msg.hwnd.ToInt32());
						#endif
					} else {
						goto ProcessNextMessage;
					}
					
					break;
				}
				
			case XEventName.ClientMessage: {
					if (Dnd.HandleClientMessage (ref xevent)) {
						goto ProcessNextMessage;
					}
					
					if (xevent.ClientMessageEvent.message_type == (IntPtr)AsyncAtom) {
						XplatUIDriverSupport.ExecuteClientMessage ((GCHandle)xevent.ClientMessageEvent.ptr1);
						break;
					}
					
					if (xevent.ClientMessageEvent.message_type == (IntPtr)HoverState.Atom) {
						msg.message = Msg.WM_MOUSEHOVER;
						msg.wParam = GetMousewParam (0);
						msg.lParam = (IntPtr) (xevent.ClientMessageEvent.ptr1);
						break;
					}
					
					if (xevent.ClientMessageEvent.message_type == (IntPtr)PostAtom) {
						msg.hwnd = xevent.ClientMessageEvent.ptr1;
						msg.message = (Msg) xevent.ClientMessageEvent.ptr2.ToInt32 ();
						msg.wParam = xevent.ClientMessageEvent.ptr3;
						msg.lParam = xevent.ClientMessageEvent.ptr4;
						break;
					}
					
					#if dontcare
					if  (xevent.ClientMessageEvent.message_type == (IntPtr)NetAtoms[(int)NA._XEMBED]) {
						Console.WriteLine("GOT EMBED MESSAGE {0:X}", xevent.ClientMessageEvent.ptr2.ToInt32());
						break;
					}
					#endif
					
					if  (xevent.ClientMessageEvent.message_type == (IntPtr)NetAtoms [(int)NA.WM_PROTOCOLS]) {
						if (xevent.ClientMessageEvent.ptr1 == (IntPtr)NetAtoms [(int)NA.WM_DELETE_WINDOW]) {
							msg.message = Msg.WM_CLOSE;
							Graphics.FromHdcInternal (IntPtr.Zero);
							break;
						}
						
						// We should not get this, but I'll leave the code in case we need it in the future
						if (xevent.ClientMessageEvent.ptr1 == (IntPtr)NetAtoms [(int)NA.WM_TAKE_FOCUS]) {
							goto ProcessNextMessage;
						}
					}
					break;
				}
				
			case XEventName.TimerNotify: {
					xevent.TimerNotifyEvent.handler (this, EventArgs.Empty);
					break;
				}
				
			default: {
					goto ProcessNextMessage;
				}
			}
			
			return true;
		}
		internal void PerformNCCalc(Hwnd hwnd) {
			XplatUIWin32.NCCALCSIZE_PARAMS  ncp;
			IntPtr ptr;
			Rectangle rect;

			rect = new Rectangle (0, 0, hwnd.Width, hwnd.Height);

			ncp = new XplatUIWin32.NCCALCSIZE_PARAMS();
			ptr = Marshal.AllocHGlobal(Marshal.SizeOf(ncp));

			ncp.rgrc1.left = rect.Left;
			ncp.rgrc1.top = rect.Top;
			ncp.rgrc1.right = rect.Right;
			ncp.rgrc1.bottom = rect.Bottom;

			Marshal.StructureToPtr(ncp, ptr, true);
			NativeWindow.WndProc(hwnd.client_window, Msg.WM_NCCALCSIZE, (IntPtr)1, ptr);
			ncp = (XplatUIWin32.NCCALCSIZE_PARAMS)Marshal.PtrToStructure(ptr, typeof(XplatUIWin32.NCCALCSIZE_PARAMS));
			Marshal.FreeHGlobal(ptr);


			rect = new Rectangle(ncp.rgrc1.left, ncp.rgrc1.top, ncp.rgrc1.right - ncp.rgrc1.left, ncp.rgrc1.bottom - ncp.rgrc1.top);
			hwnd.ClientRect = rect;

			rect = TranslateClientRectangleToQuartzClientRectangle (hwnd);

			if (hwnd.visible) {
				Carbon.HIRect r = new Carbon.HIRect (rect.X, rect.Y, rect.Width, rect.Height);
				HIViewSetFrame (hwnd.client_window, ref r);
			}
	
			AddExpose (hwnd, false, 0, 0, hwnd.Width, hwnd.Height);
		}
Пример #4
0
		public void PerformNCCalc ()
		{
			XplatUIWin32.NCCALCSIZE_PARAMS	ncp;
			IntPtr				ptr;
			Rectangle			rect;

			rect = DefaultClientRect;

			ncp = new XplatUIWin32.NCCALCSIZE_PARAMS ();
			ptr = Marshal.AllocHGlobal (Marshal.SizeOf(ncp));

			ncp.rgrc1.left = rect.Left;
			ncp.rgrc1.top = rect.Top;
			ncp.rgrc1.right = rect.Right;
			ncp.rgrc1.bottom = rect.Bottom;

			Marshal.StructureToPtr (ncp, ptr, true);
			NativeWindow.WndProc (ClientWindow, Msg.WM_NCCALCSIZE, (IntPtr)1, ptr);
			ncp = (XplatUIWin32.NCCALCSIZE_PARAMS)Marshal.PtrToStructure (ptr, typeof(XplatUIWin32.NCCALCSIZE_PARAMS));
			Marshal.FreeHGlobal(ptr);

			// FIXME - debug this with Menus

			rect = new Rectangle(ncp.rgrc1.left, ncp.rgrc1.top, ncp.rgrc1.right - ncp.rgrc1.left, ncp.rgrc1.bottom - ncp.rgrc1.top);
			ClientRect = rect;

			if (Visible) {
				if ((rect.Width < 1) || (rect.Height < 1))
					Xlib.XMoveResizeWindow (display.Handle, ClientWindow, -5, -5, 1, 1);
				else
					Xlib.XMoveResizeWindow (display.Handle, ClientWindow, rect.X, rect.Y, rect.Width, rect.Height);
			}

			InvalidateNC ();
		}