private static void RemovePendingMessages(int msgMin, int msgMax)
        {
            if (!control.IsDisposed)
            {
                MSG msg = new MSG();
                IntPtr handle = control.Handle;
                while (PeekMessage(ref msg, new HandleRef(control, handle), msgMin, msgMax, 1))
                {
                }
            }

        }
Beispiel #2
0
		internal extern static IntPtr Win32DispatchMessage(ref MSG msg);
Beispiel #3
0
		internal extern static bool Win32GetMessage(ref MSG msg, IntPtr hWnd, int wFilterMin, int wFilterMax);
Beispiel #4
0
		internal override IntPtr DispatchMessage(ref MSG msg) {
			return Win32DispatchMessage(ref msg);
		}
Beispiel #5
0
		private bool GetMessage(ref MSG msg, IntPtr hWnd, int wFilterMin, int wFilterMax, bool blocking) {
			bool		result;

			msg.refobject = 0;
			if (RetrieveMessage(ref msg)) {
				return true;
			}

			if (blocking) {
				result = Win32GetMessage(ref msg, hWnd, wFilterMin, wFilterMax);
			} else {
				result = Win32PeekMessage(ref msg, hWnd, wFilterMin, wFilterMax, (uint)PeekMessageFlags.PM_REMOVE);
				if (!result) {
					return false;
				}
			}

			// We need to fake WM_MOUSE_ENTER
			switch (msg.message) {
				case Msg.WM_LBUTTONDOWN: {
					mouse_state |= MouseButtons.Left;
					break;
				}

				case Msg.WM_MBUTTONDOWN: {
					mouse_state |= MouseButtons.Middle;
					break;
				}

				case Msg.WM_RBUTTONDOWN: {
					mouse_state |= MouseButtons.Right;
					break;
				}

				case Msg.WM_LBUTTONUP: {
					mouse_state &= ~MouseButtons.Left;
					break;
				}

				case Msg.WM_MBUTTONUP: {
					mouse_state &= ~MouseButtons.Middle;
					break;
				}

				case Msg.WM_RBUTTONUP: {
					mouse_state &= ~MouseButtons.Right;
					break;
				}

				case Msg.WM_ASYNC_MESSAGE: {
					XplatUIDriverSupport.ExecuteClientMessage((GCHandle)msg.lParam);
					break;
				}

				case Msg.WM_MOUSEMOVE: {
					if (msg.hwnd != prev_mouse_hwnd) {
						TRACKMOUSEEVENT	tme;

						mouse_state = Control.FromParamToMouseButtons ((int)msg.lParam.ToInt32());

						// The current message will be sent out next time around
						StoreMessage(ref msg);

						// This is the message we want to send at this point
						msg.message = Msg.WM_MOUSE_ENTER;

						prev_mouse_hwnd = msg.hwnd;

						tme = new TRACKMOUSEEVENT();
						tme.size = Marshal.SizeOf(tme);
						tme.hWnd = msg.hwnd;
						tme.dwFlags = TMEFlags.TME_LEAVE | TMEFlags.TME_HOVER;
						Win32TrackMouseEvent(ref tme);
						return result;
					}
					break;
				}

				case Msg.WM_NCMOUSEMOVE: {
					if (wm_nc_registered == null || !wm_nc_registered.Contains (msg.hwnd))
						break;

					mouse_state = Control.FromParamToMouseButtons ((int)msg.lParam.ToInt32 ());

					TRACKMOUSEEVENT tme;

					tme = new TRACKMOUSEEVENT ();
					tme.size = Marshal.SizeOf(tme);
					tme.hWnd = msg.hwnd;
					tme.dwFlags = (TMEFlags)wm_nc_registered[msg.hwnd];
					Win32TrackMouseEvent (ref tme);
					return result;
				}

				case Msg.WM_DROPFILES: {
					return Win32DnD.HandleWMDropFiles(ref msg);
				}

				case Msg.WM_MOUSELEAVE: {
					prev_mouse_hwnd = IntPtr.Zero;
					break;
				}

				case Msg.WM_TIMER: {
					Timer timer=(Timer)timer_list[(int)msg.wParam];

					if (timer != null) {
						timer.FireTick();
					}
					break;
				}
			}

			return result;
		}
Beispiel #6
0
		internal override bool PeekMessage(Object queue_id, ref MSG msg, IntPtr hWnd, int wFilterMin, int wFilterMax, uint flags) {
			return Win32PeekMessage(ref msg, hWnd, wFilterMin, wFilterMax, flags);
		}
        /// <summary>
        /// Send key commands to text view if it has focus
        /// </summary>
        /// <param name="msg"></param>
        /// <returns></returns>
        public int TranslateAccelerator(MSG[] messagesToTranslate)
        {
            int hr = VSConstants.S_FALSE;
            if (messagesToTranslate == null)
            {
                return hr;
            }

            // defer to active code window
            if (activeTextView != null)
            {
                IVsWindowPane vsWindowPane = (IVsWindowPane) activeTextView;
                hr = vsWindowPane.TranslateAccelerator(messagesToTranslate);
            }
            else
            {
                switch (messagesToTranslate[0].message)
                {
                    case NativeMethods.WM_KEYDOWN:
                    case NativeMethods.WM_SYSKEYDOWN:
                    case NativeMethods.WM_CHAR:
                    case NativeMethods.WM_SYSCHAR:
                        {
                            Message msg = new Message();
                            msg.HWnd = messagesToTranslate[0].hwnd;
                            msg.Msg = (int) messagesToTranslate[0].message;
                            msg.LParam = messagesToTranslate[0].lParam;
                            msg.WParam = messagesToTranslate[0].wParam;

                            Control ctrl = FromChildHandle(msg.HWnd);
                            if (ctrl != null && ctrl.PreProcessMessage(ref msg))
                                hr = VSConstants.S_OK;
                        }
                        break;

                    default:
                        break;
                }
            }


            return hr;
        }
Beispiel #8
0
 internal abstract bool PeekMessage(Object queue_id, ref MSG msg, IntPtr hWnd, int wFilterMin, int wFilterMax, uint flags);
Beispiel #9
0
        internal static void RunLoop(bool Modal, ApplicationContext context)
        {
            Queue              toplevels;
            MSG                msg;
            Object             queue_id;
            MWFThread          thread;
            ApplicationContext previous_thread_context;

            thread = MWFThread.Current;

            /*
             * There is a NotWorking test for this, but since we are using this method both for Form.ShowDialog as for ApplicationContexts we'll
             * fail on nested ShowDialogs, so disable the check for the moment.
             */
            //if (thread.MessageLoop) {
            //        throw new InvalidOperationException ("Starting a second message loop on a single thread is not a valid operation. Use Form.ShowDialog instead.");
            //}

            msg = new MSG();

            if (context == null)
            {
                context = new ApplicationContext();
            }

            previous_thread_context = thread.Context;
            thread.Context          = context;

            if (context.MainForm != null)
            {
                context.MainForm.is_modal = Modal;
                context.MainForm.context  = context;
                context.MainForm.closing  = false;
                context.MainForm.Visible  = true;                       // Cannot use Show() or scaling gets confused by menus
                // XXX the above line can be used to close the form. another problem with our handling of Show/Activate.
                if (context.MainForm != null)
                {
                    context.MainForm.Activate();
                }
            }

                        #if DebugRunLoop
            Console.WriteLine("Entering RunLoop(Modal={0}, Form={1})", Modal, context.MainForm != null ? context.MainForm.ToString() : "NULL");
                        #endif

            if (Modal)
            {
                toplevels = new Queue();
                DisableFormsForModalLoop(toplevels, context);

                // FIXME - need activate?
                /* make sure the MainForm is enabled */
                if (context.MainForm != null)
                {
                    XplatUI.EnableWindow(context.MainForm.Handle, true);
                    XplatUI.SetModal(context.MainForm.Handle, true);
                }
            }
            else
            {
                toplevels = null;
            }

            queue_id           = XplatUI.StartLoop(Thread.CurrentThread);
            thread.MessageLoop = true;

            bool quit = false;

            while (!quit && XplatUI.GetMessage(queue_id, ref msg, IntPtr.Zero, 0, 0))
            {
                Message m = Message.Create(msg.hwnd, (int)msg.message, msg.wParam, msg.lParam);

                if (Application.FilterMessage(ref m))
                {
                    continue;
                }

                switch ((Msg)msg.message)
                {
                case Msg.WM_KEYDOWN:
                case Msg.WM_SYSKEYDOWN:
                case Msg.WM_CHAR:
                case Msg.WM_SYSCHAR:
                case Msg.WM_KEYUP:
                case Msg.WM_SYSKEYUP:
                    Control c;
                    c = Control.FromHandle(msg.hwnd);

                    // If we have a control with keyboard capture (usually a *Strip)
                    // give it the message, and then drop the message
                    if (keyboard_capture != null)
                    {
                        // WM_SYSKEYUP does not make it into ProcessCmdKey, so do it here
                        if ((Msg)m.Msg == Msg.WM_SYSKEYDOWN)
                        {
                            if (m.WParam.ToInt32() == (int)Keys.Menu)
                            {
                                keyboard_capture.GetTopLevelToolStrip().Dismiss(ToolStripDropDownCloseReason.Keyboard);
                                continue;
                            }
                        }

                        m.HWnd = keyboard_capture.Handle;

                        switch (keyboard_capture.PreProcessControlMessageInternal(ref m))
                        {
                        case PreProcessControlState.MessageProcessed:
                            continue;

                        case PreProcessControlState.MessageNeeded:
                        case PreProcessControlState.MessageNotNeeded:
                            if (((m.Msg == (int)Msg.WM_KEYDOWN || m.Msg == (int)Msg.WM_CHAR) && !keyboard_capture.ProcessControlMnemonic((char)m.WParam)))
                            {
                                if (c == null || !ControlOnToolStrip(c))
                                {
                                    continue;
                                }
                                else
                                {
                                    m.HWnd = msg.hwnd;
                                }
                            }
                            else
                            {
                                continue;
                            }

                            break;
                        }
                    }

                    if (((c != null) && c.PreProcessControlMessageInternal(ref m) != PreProcessControlState.MessageProcessed) ||
                        (c == null))
                    {
                        goto default;
                    }
                    break;

                case Msg.WM_LBUTTONDOWN:
                case Msg.WM_MBUTTONDOWN:
                case Msg.WM_RBUTTONDOWN:
                    if (keyboard_capture != null)
                    {
                        Control c2 = Control.FromHandle(msg.hwnd);

                        // The target is not a winforms control (an embedded control, perhaps), so
                        // release everything
                        if (c2 == null)
                        {
                            ToolStripManager.FireAppClicked();
                            goto default;
                        }

                        // Skip clicks on owner windows, eg. expanded ComboBox
                        if (Control.IsChild(keyboard_capture.Handle, msg.hwnd))
                        {
                            goto default;
                        }

                        // Close any active toolstrips drop-downs if we click outside of them,
                        // but also don't close them all if we click outside of the top-most
                        // one, but into its owner.
                        Point c2_point = c2.PointToScreen(new Point(
                                                              (int)(short)(m.LParam.ToInt32() & 0xffff),
                                                              (int)(short)(m.LParam.ToInt32() >> 16)));
                        while (keyboard_capture != null && !keyboard_capture.ClientRectangle.Contains(keyboard_capture.PointToClient(c2_point)))
                        {
                            keyboard_capture.Dismiss();
                        }
                    }

                    goto default;

                case Msg.WM_QUIT:
                    quit = true;                     // make sure we exit
                    break;

                default:
                    XplatUI.TranslateMessage(ref msg);
                    XplatUI.DispatchMessage(ref msg);
                    break;
                }

                // If our Form doesn't have a handle anymore, it means it was destroyed and we need to *wait* for WM_QUIT.
                if ((context.MainForm != null) && (!context.MainForm.IsHandleCreated))
                {
                    continue;
                }

                // Handle exit, Form might have received WM_CLOSE and set 'closing' in response.
                if ((context.MainForm != null) && (context.MainForm.closing || (Modal && !context.MainForm.Visible)))
                {
                    if (!Modal)
                    {
                        XplatUI.PostQuitMessage(0);
                    }
                    else
                    {
                        break;
                    }
                }
            }
                        #if DebugRunLoop
            Console.WriteLine("   RunLoop loop left");
                        #endif

            thread.MessageLoop = false;
            XplatUI.EndLoop(Thread.CurrentThread);

            if (Modal)
            {
                Form old = context.MainForm;

                context.MainForm = null;

                EnableFormsForModalLoop(toplevels, context);

                if (old != null && old.IsHandleCreated)
                {
                    XplatUI.SetModal(old.Handle, false);
                }
                                #if DebugRunLoop
                Console.WriteLine("   Done with the SetModal");
                                #endif
                old.RaiseCloseEvents(true, false);
                old.is_modal = false;
            }

                        #if DebugRunLoop
            Console.WriteLine("Leaving RunLoop(Modal={0}, Form={1})", Modal, context.MainForm != null ? context.MainForm.ToString() : "NULL");
                        #endif

            if (context.MainForm != null)
            {
                context.MainForm.context = null;
                context.MainForm         = null;
            }

            thread.Context = previous_thread_context;

            if (!Modal)
            {
                thread.Exit();
            }
        }
Beispiel #10
0
        static public bool TrackPopupMenu(Menu menu, Point pnt)
        {
            if (menu.MenuItems.Count <= 0)              // No submenus to track
            {
                return(true);
            }

            MenuTracker tracker = menu.tracker;

            tracker.active       = true;
            tracker.popup_active = true;

            // Set GrabControl
            Control src_ctrl = (tracker.TopMenu as ContextMenu).SourceControl;

            tracker.GrabControl = src_ctrl.FindForm();
            if (tracker.GrabControl == null)
            {
                tracker.GrabControl = src_ctrl.FindRootParent();
            }
            tracker.GrabControl.ActiveTracker = tracker;

            menu.Wnd          = new PopUpWindow(tracker.GrabControl, menu);
            menu.Wnd.Location = menu.Wnd.PointToClient(pnt);
            ((PopUpWindow)menu.Wnd).ShowWindow();

            bool no_quit = true;

            Object queue_id = XplatUI.StartLoop(Thread.CurrentThread);

            while ((menu.Wnd != null) && menu.Wnd.Visible && no_quit)
            {
                MSG msg = new MSG();
                no_quit = XplatUI.GetMessage(queue_id, ref msg, IntPtr.Zero, 0, 0);

                switch ((Msg)msg.message)
                {
                case Msg.WM_KEYDOWN:
                case Msg.WM_SYSKEYDOWN:
                case Msg.WM_CHAR:
                case Msg.WM_SYSCHAR:
                case Msg.WM_KEYUP:
                case Msg.WM_SYSKEYUP:
                    Control c = Control.FromHandle(msg.hwnd);
                    if (c != null)
                    {
                        Message m = Message.Create(msg.hwnd, (int)msg.message, msg.wParam, msg.lParam);
                        c.PreProcessControlMessageInternal(ref m);
                    }
                    break;

                default:
                    XplatUI.TranslateMessage(ref msg);
                    XplatUI.DispatchMessage(ref msg);
                    break;
                }
            }

            if (tracker.GrabControl.IsDisposed)
            {
                return(true);
            }

            if (!no_quit)
            {
                XplatUI.PostQuitMessage(0);
            }

            if (menu.Wnd != null)
            {
                menu.Wnd.Dispose();
                menu.Wnd = null;
            }

            return(true);
        }
Beispiel #11
0
 internal static bool PostMessage(ref MSG msg)
 {
     DriverDebug("PostMessage ({0}): Called", msg);
     return(driver.PostMessage(msg.hwnd, msg.message, msg.wParam, msg.lParam));
 }
Beispiel #12
0
 internal static bool PeekMessage(Object queue_id, ref MSG msg, IntPtr hWnd, int wFilterMin, int wFilterMax, uint flags)
 {
     return(driver.PeekMessage(queue_id, ref msg, hWnd, wFilterMin, wFilterMax, flags));
 }
Beispiel #13
0
 internal static bool GetMessage(object queue_id, ref MSG msg, IntPtr hWnd, int wFilterMin, int wFilterMax)
 {
     return(driver.GetMessage(queue_id, ref msg, hWnd, wFilterMin, wFilterMax));
 }
Beispiel #14
0
		private static bool StoreMessage(ref MSG msg) {
			MSG message = new MSG();

			message = msg;
			message_queue.Enqueue(message);

			return true;
		}
Beispiel #15
0
 internal abstract bool GetMessage(object queue_id, ref MSG msg, IntPtr hWnd, int wFilterMin, int wFilterMax);
 static extern bool PeekMessage(ref MSG msg, IntPtr hWnd, int messageFilterMin, int messageFilterMax, int flags);
Beispiel #17
0
 internal abstract bool TranslateMessage(ref MSG msg);
 /// <summary>
 /// Gives the component a chance to process the message before it is translated and dispatched.
 /// </summary>
 /// <param name="pMsg">The message to process.</param>
 /// <returns>TRUE (not zero) if the message is consumed, otherwise FALSE (zero).</returns>
 /// <remarks>
 /// The component can do TranslateAccelerator, do IsDialogMessage, modify pMsg, or take some other action.
 /// </remarks>
 public int FPreTranslateMessage(MSG[] pMsg)
 {
     return 0;
 }
Beispiel #19
0
 internal abstract IntPtr DispatchMessage(ref MSG msg);
Beispiel #20
0
 internal static IntPtr DispatchMessage(ref MSG msg)
 {
     return(driver.DispatchMessage(ref msg));
 }
Beispiel #21
0
        // ----------------------------------------------------------------------------------
        /// <summary>
        /// Allow the embedded editor to handle keyboard messages before they are dispatched
        /// to the window that has the focus.
        /// </summary>
        // ----------------------------------------------------------------------------------
        protected override bool PreProcessMessage(ref Message m)
        {
            if (_surface != null && _surface._ViewAdapter != null)
            {
                // copy the Message into a MSG[] array, so we can pass
                // it along to the active core editor's IVsWindowPane.TranslateAccelerator
                var pMsg = new MSG[1];
                pMsg[0].hwnd = m.HWnd;
                pMsg[0].message = (uint)m.Msg;
                pMsg[0].wParam = m.WParam;
                pMsg[0].lParam = m.LParam;

                var vsWindowPane = (IVsWindowPane)_surface._ViewAdapter;
                return vsWindowPane.TranslateAccelerator(pMsg) == 0;
            }
            return base.PreProcessMessage(ref m);
        }
Beispiel #22
0
		internal override bool GetMessage(Object queue_id, ref MSG msg, IntPtr hWnd, int wFilterMin, int wFilterMax) {
			return GetMessage(ref msg, hWnd, wFilterMin, wFilterMax, true);
		}
Beispiel #23
0
		public DragDropEffects StartDrag (IntPtr handle, object data,
				DragDropEffects allowed_effects)
		{
			drag_data = new DragData ();
			drag_data.Window = handle;
			drag_data.State = DragState.Beginning;
			drag_data.MouseState = XplatUIX11.MouseState;
			drag_data.Data = data;
			drag_data.SupportedTypes = DetermineSupportedTypes (data);
			drag_data.AllowedEffects = allowed_effects;
			drag_data.Action = ActionFromEffect (allowed_effects);

			if (CursorNo == null) {
				// Make sure the cursors are created
				CursorNo = new Cursor (typeof (X11Dnd), "DnDNo.cur");
				CursorCopy = new Cursor (typeof (X11Dnd), "DnDCopy.cur");
				CursorMove = new Cursor (typeof (X11Dnd), "DnDMove.cur");
				CursorLink = new Cursor (typeof (X11Dnd), "DnDLink.cur");
			}

			drag_data.LastTopLevel = IntPtr.Zero;
			control = null;

			System.Windows.Forms.MSG msg = new MSG();
			object queue_id = XplatUI.StartLoop (Thread.CurrentThread);

			Timer timer = new Timer ();
			timer.Tick += new EventHandler (DndTickHandler);
			timer.Interval = 100;

			int suc;
			drag_data.State = DragState.Dragging;

			suc = XplatUIX11.XSetSelectionOwner (display, XdndSelection,
					drag_data.Window, IntPtr.Zero);

			if (suc == 0) {
				Console.Error.WriteLine ("Could not take ownership of XdndSelection aborting drag.");
				drag_data.Reset ();
				return DragDropEffects.None;
			}

			drag_data.State = DragState.Dragging;
			drag_data.CurMousePos = new Point ();
			source = toplevel = target = IntPtr.Zero;
			dropped = false;
			tracking = true;
			motion_poll = -1;
			timer.Start ();

			// Send Enter to the window initializing the dnd operation - which initializes the data
			SendEnter (drag_data.Window, drag_data.Window, drag_data.SupportedTypes);
			drag_data.LastTopLevel = toplevel;

			while (tracking && XplatUI.GetMessage (queue_id, ref msg, IntPtr.Zero, 0, 0)) {

				if (msg.message >= Msg.WM_KEYFIRST && msg.message <= Msg.WM_KEYLAST) {
					HandleKeyMessage (msg);
				} else {
					switch (msg.message) {
					case Msg.WM_LBUTTONUP:
					case Msg.WM_RBUTTONUP:
					case Msg.WM_MBUTTONUP:
						if (msg.message == Msg.WM_LBUTTONDOWN && drag_data.MouseState != MouseButtons.Left)
							break;;
						if (msg.message == Msg.WM_RBUTTONDOWN && drag_data.MouseState != MouseButtons.Right)
							break;
						if (msg.message == Msg.WM_MBUTTONDOWN && drag_data.MouseState != MouseButtons.Middle)
							break;
						
						HandleButtonUpMsg ();

						// We don't want to dispatch button up neither (Match .Net)
						// Thus we have to remove capture by ourselves
						RemoveCapture (msg.hwnd);
						continue;
					case Msg.WM_MOUSEMOVE:
						motion_poll = 0;

						drag_data.CurMousePos.X = Control.LowOrder ((int) msg.lParam.ToInt32 ());
						drag_data.CurMousePos.Y = Control.HighOrder ((int) msg.lParam.ToInt32 ());

						HandleMouseOver ();
						// We don't want to dispatch mouse move
						continue;
					}

					XplatUI.DispatchMessage (ref msg);
				}
			}

			timer.Stop ();

			// If the target is a mwf control, return until DragEnter/DragLeave has been fired,
			// which means the respective -already sent- dnd ClientMessages have been received and handled.
			if (control != null)
				Application.DoEvents ();

			if (!dropped)
				return DragDropEffects.None;
			if (drag_event != null)
				return drag_event.Effect;

			// Fallback.
			return DragDropEffects.None;
		}
Beispiel #24
0
		internal override bool TranslateMessage(ref MSG msg) {
			return Win32TranslateMessage(ref msg);
		}
Beispiel #25
0
		public void HandleKeyMessage (MSG msg)
		{
			if (VirtualKeys.VK_ESCAPE == (VirtualKeys) msg.wParam.ToInt32()) {
				QueryContinue (true, DragAction.Cancel);
			}
		}
Beispiel #26
0
		internal extern static bool Win32PeekMessage(ref MSG msg, IntPtr hWnd, int wFilterMin, int wFilterMax, uint flags);
Beispiel #27
0
		void WaitForHwndMessage (Hwnd hwnd, Msg message, bool process) {
			MSG msg = new MSG ();
			XEventQueue queue;

			queue = ThreadQueue(Thread.CurrentThread);

			queue.DispatchIdle = false;

			bool done = false;
			string key = hwnd.Handle + ":" + message;
			if (!messageHold.ContainsKey (key))	
				messageHold.Add (key, 1);
			else
				messageHold[key] = ((int)messageHold[key]) + 1;
			
					
			do {

				DebugHelper.WriteLine  ("Waiting for message " + message + " on hwnd " + String.Format("0x{0:x}", hwnd.Handle.ToInt32 ()));
				DebugHelper.Indent ();
				
				if (PeekMessage(queue, ref msg, IntPtr.Zero, 0, 0, (uint)PeekMessageFlags.PM_REMOVE)) {
					if ((Msg)msg.message == Msg.WM_QUIT) {
						PostQuitMessage (0);
						done = true;
					}
					else {
						
						DebugHelper.WriteLine  ("PeekMessage got " + msg);
						
						if (msg.hwnd == hwnd.Handle) {
							if ((Msg)msg.message == message) {
								if (process) {
									TranslateMessage (ref msg);
									DispatchMessage (ref msg);
								}
								break;
							}
							else if ((Msg)msg.message == Msg.WM_DESTROY)
								done = true;
						}

						TranslateMessage (ref msg);
						DispatchMessage (ref msg);
					}
				}
				
				done = !messageHold.ContainsKey (key) || ((int)messageHold[key] < 1) || done;
			} while (!done);
						
			messageHold.Remove (key);

			DebugHelper.Unindent ();
			DebugHelper.WriteLine  ("Finished waiting for " + key);			

			queue.DispatchIdle = true;

		}
Beispiel #28
0
		internal extern static bool Win32TranslateMessage(ref MSG msg);
Beispiel #29
0
		internal override IntPtr DispatchMessage(ref MSG msg)
		{
			return NativeWindow.WndProc(msg.hwnd, msg.message, msg.wParam, msg.lParam);
		}
Beispiel #30
0
		private static bool RetrieveMessage(ref MSG msg) {
			MSG	message;

			if (message_queue.Count == 0) {
				return false;
			}

			message = (MSG)message_queue.Dequeue();
			msg = message;

			return true;
		}
Beispiel #31
0
		internal override void DoEvents()
		{
			DebugHelper.Enter ();

			MSG	msg = new MSG ();
			XEventQueue queue;

			if (OverrideCursorHandle != IntPtr.Zero) {
				OverrideCursorHandle = IntPtr.Zero;
			}

			queue = ThreadQueue(Thread.CurrentThread);

			queue.DispatchIdle = false;
			in_doevents = true;

			while (PeekMessage(queue, ref msg, IntPtr.Zero, 0, 0, (uint)PeekMessageFlags.PM_REMOVE)) {
				Message m = Message.Create (msg.hwnd, (int)msg.message, msg.wParam, msg.lParam);

				if (Application.FilterMessage (ref m))
					continue;

				TranslateMessage (ref msg);
				DispatchMessage (ref msg);

				string key = msg.hwnd + ":" + msg.message;				
				if (messageHold[key] != null) {
					messageHold[key] = ((int)messageHold[key]) - 1;
					DebugHelper.WriteLine  ("Got " + msg + " for " + key);
				}
			}

			in_doevents = false;
			queue.DispatchIdle = true;

			DebugHelper.Leave ();
		}
        public virtual int TranslateAccelerator(MSG[] arrMsg)
        {
            MSG msg = arrMsg[0];

            if ((msg.message < NativeMethods.WM_KEYFIRST || msg.message > NativeMethods.WM_KEYLAST) && (msg.message < NativeMethods.WM_MOUSEFIRST || msg.message > NativeMethods.WM_MOUSELAST))
                return 1;

            return (NativeMethods.IsDialogMessageA(this.panel.Handle, ref msg)) ? 0 : 1;
        }
Beispiel #33
0
		internal override bool GetMessage(Object queue_id, ref MSG msg, IntPtr handle, int wFilterMin, int wFilterMax)
		{
			XEvent	xevent;
			bool	client;
			Hwnd	hwnd;

			ProcessNextMessage:

			if (((XEventQueue)queue_id).Count > 0) {
				xevent = (XEvent) ((XEventQueue)queue_id).Dequeue ();
			} else {
				UpdateMessageQueue ((XEventQueue)queue_id);

				if (((XEventQueue)queue_id).Count > 0) {
					xevent = (XEvent) ((XEventQueue)queue_id).Dequeue ();
				} else if (((XEventQueue)queue_id).Paint.Count > 0) {
					xevent = ((XEventQueue)queue_id).Paint.Dequeue();
				} else {
					msg.hwnd= IntPtr.Zero;
					msg.message = Msg.WM_ENTERIDLE;
					return true;
				}
			}

			hwnd = Hwnd.GetObjectFromWindow(xevent.AnyEvent.window);

#if DriverDebugDestroy			
			if (hwnd != null)
				if (hwnd.zombie)
					Console.WriteLine ( "GetMessage zombie, got Event: " + xevent.ToString () + " for 0x{0:x}", hwnd.Handle.ToInt32());
				else	
					Console.WriteLine ( "GetMessage, got Event: " + xevent.ToString () + " for 0x{0:x}", hwnd.Handle.ToInt32());
#endif
			// Handle messages for windows that are already or are about to be destroyed.

			// we need a special block for this because unless we remove the hwnd from the paint
			// queue it will always stay there (since we don't handle the expose), and we'll
			// effectively loop infinitely trying to repaint a non-existant window.
			if (hwnd != null && hwnd.zombie && xevent.type == XEventName.Expose) {
				hwnd.expose_pending = hwnd.nc_expose_pending = false;
				hwnd.Queue.Paint.Remove (hwnd);
				goto ProcessNextMessage;
			}

			// We need to make sure we only allow DestroyNotify events through for zombie
			// hwnds, since much of the event handling code makes requests using the hwnd's
			// client_window, and that'll result in BadWindow errors if there's some lag
			// between the XDestroyWindow call and the DestroyNotify event.
			if (hwnd == null || hwnd.zombie && xevent.AnyEvent.type != XEventName.ClientMessage) {
				DriverDebug("GetMessage(): Got message {0} for non-existent or already destroyed window {1:X}", xevent.type, xevent.AnyEvent.window.ToInt32());
				goto ProcessNextMessage;
			}


			// If we get here, that means the window is no more but there are Client Messages
			// to be processed, probably a Posted message (for instance, an WM_ACTIVATE message) 
			// We don't want anything else to run but the ClientMessage block, so reset all hwnd
			// properties that might cause other processing to occur.
			if (hwnd.zombie) {
				hwnd.resizing_or_moving = false;
			}

			if (hwnd.client_window == xevent.AnyEvent.window) {
				client = true;
				//Console.WriteLine("Client message {1}, sending to window {0:X}", msg.hwnd.ToInt32(), xevent.type);
			} else {
				client = false;
				//Console.WriteLine("Non-Client message, sending to window {0:X}", msg.hwnd.ToInt32());
			}

			msg.hwnd = hwnd.Handle;

			// Windows sends WM_ENTERSIZEMOVE when a form resize/move operation starts and WM_EXITSIZEMOVE 
			// when it is done. The problem in X11 is that there is no concept of start-end of a moving/sizing.
			// Configure events ("this window has resized/moved") are sent for each step of the resize. We send a
			// WM_ENTERSIZEMOVE when we get the first Configure event. The problem is the WM_EXITSIZEMOVE.
			// 
			//  - There is no way for us to know which is the last Configure event. We can't traverse the events 
			//    queue, because the next configure event might not be pending yet.
			//  - We can't get ButtonPress/Release events for the window decorations, because they are not part 
			//    of the window(s) we manage.
			//  - We can't rely on the mouse state to change to "up" before the last Configure event. It doesn't.
			// 
			// We are almost 100% guaranteed to get another event (e.g Expose or other), but we can't know for sure 
			// which, so we have here to check if the mouse buttons state is "up" and send the WM_EXITSIZEMOVE
			//
			if (hwnd.resizing_or_moving) {
				int root_x, root_y, win_x, win_y, keys_buttons;
				IntPtr  root, child;
				XQueryPointer (DisplayHandle, hwnd.Handle, out root, out child, out root_x, out root_y, 
					       out win_x, out win_y, out keys_buttons);
				if ((keys_buttons & (int)MouseKeyMasks.Button1Mask) == 0 &&
				    (keys_buttons & (int)MouseKeyMasks.Button2Mask) == 0 &&
				    (keys_buttons & (int)MouseKeyMasks.Button3Mask) == 0) {
					hwnd.resizing_or_moving = false;
					SendMessage (hwnd.Handle, Msg.WM_EXITSIZEMOVE, IntPtr.Zero, IntPtr.Zero);
				}
			}

			//
			// 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);

					// F1 key special case - WM_HELP sending
					if (msg.wParam == (IntPtr)VirtualKeys.VK_F1 || msg.wParam == (IntPtr)VirtualKeys.VK_HELP) {
						// Send wM_HELP and then return it as a keypress message in
						// case it needs to be preproccessed.
						HELPINFO helpInfo = new HELPINFO ();
						GetCursorPos (IntPtr.Zero, out helpInfo.MousePos.x, out helpInfo.MousePos.y);
						IntPtr helpInfoPtr = Marshal.AllocHGlobal (Marshal.SizeOf (helpInfo));
						Marshal.StructureToPtr (helpInfo, helpInfoPtr, true);
						NativeWindow.WndProc (FocusWindow, Msg.WM_HELP, IntPtr.Zero, helpInfoPtr);
						Marshal.FreeHGlobal (helpInfoPtr);
					}
					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;
								msg.wParam = GetMousewParam (0);
							} else {
								msg.message = Msg.WM_NCLBUTTONDOWN;
								msg.wParam = (IntPtr) NCHitTest (hwnd, xevent.MotionEvent.x, xevent.MotionEvent.y);
								MenuToScreen (xevent.AnyEvent.window, ref xevent.ButtonEvent.x, ref xevent.ButtonEvent.y);
							}
							break;
						}

						case 2: {
							MouseState |= MouseButtons.Middle;
							if (client) {
								msg.message = Msg.WM_MBUTTONDOWN;
								msg.wParam = GetMousewParam (0);
							} else {
								msg.message = Msg.WM_NCMBUTTONDOWN;
								msg.wParam = (IntPtr) NCHitTest (hwnd, xevent.MotionEvent.x, xevent.MotionEvent.y);
								MenuToScreen (xevent.AnyEvent.window, ref xevent.ButtonEvent.x, ref xevent.ButtonEvent.y);
							}
							break;
						}

						case 3: {
							MouseState |= MouseButtons.Right;
							if (client) {
								msg.message = Msg.WM_RBUTTONDOWN;
								msg.wParam = GetMousewParam (0);
							} else {
								msg.message = Msg.WM_NCRBUTTONDOWN;
								msg.wParam = (IntPtr) NCHitTest (hwnd, xevent.MotionEvent.x, xevent.MotionEvent.y);
								MenuToScreen (xevent.AnyEvent.window, ref xevent.ButtonEvent.x, ref xevent.ButtonEvent.y);
							}
							break;
						}

						case 4: {
							msg.hwnd = FocusWindow;
							msg.message=Msg.WM_MOUSEWHEEL;
							msg.wParam=GetMousewParam(120);
							break;
						}

						case 5: {
							msg.hwnd = FocusWindow;
							msg.message=Msg.WM_MOUSEWHEEL;
							msg.wParam=GetMousewParam(-120);
							break;
						}

					}

					msg.lParam=(IntPtr) (xevent.ButtonEvent.y << 16 | xevent.ButtonEvent.x);
					mouse_position.X = xevent.ButtonEvent.x;
					mouse_position.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)(mouse_position.Y << 16 | mouse_position.X);
					}

					if (Grab.Hwnd != IntPtr.Zero) {
						msg.hwnd = Grab.Hwnd;
					}

					if (ClickPending.Pending && ((((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;
					} else {
						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;
					}
					
					if (msg.message == Msg.WM_LBUTTONDOWN || msg.message == Msg.WM_MBUTTONDOWN || msg.message == Msg.WM_RBUTTONDOWN) {
						SendParentNotify(msg.hwnd, msg.message, mouse_position.X, mouse_position.Y);
					}
					
					break;
				}

				case XEventName.ButtonRelease: {
					switch(xevent.ButtonEvent.button) {
						case 1: {
							if (client) {
								msg.message = Msg.WM_LBUTTONUP;
							} else {
								msg.message = Msg.WM_NCLBUTTONUP;
								msg.wParam = (IntPtr) NCHitTest (hwnd, xevent.MotionEvent.x, xevent.MotionEvent.y);
								MenuToScreen (xevent.AnyEvent.window, ref xevent.ButtonEvent.x, ref xevent.ButtonEvent.y);
							}
							MouseState &= ~MouseButtons.Left;
							msg.wParam = GetMousewParam (0);
							break;
						}

						case 2: {
							if (client) {
								msg.message = Msg.WM_MBUTTONUP;
							} else {
								msg.message = Msg.WM_NCMBUTTONUP;
								msg.wParam = (IntPtr) NCHitTest (hwnd, xevent.MotionEvent.x, xevent.MotionEvent.y);
								MenuToScreen (xevent.AnyEvent.window, ref xevent.ButtonEvent.x, ref xevent.ButtonEvent.y);
							}
							MouseState &= ~MouseButtons.Middle;
							msg.wParam = GetMousewParam (0);
							break;
						}

						case 3: {
							if (client) {
								msg.message = Msg.WM_RBUTTONUP;
							} else {
								msg.message = Msg.WM_NCRBUTTONUP;
								msg.wParam = (IntPtr) NCHitTest (hwnd, xevent.MotionEvent.x, xevent.MotionEvent.y);
								MenuToScreen (xevent.AnyEvent.window, ref xevent.ButtonEvent.x, ref xevent.ButtonEvent.y);
							}
							MouseState &= ~MouseButtons.Right;
							msg.wParam = GetMousewParam (0);
							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)(mouse_position.Y << 16 | mouse_position.X);
					}

					if (Grab.Hwnd != IntPtr.Zero) {
						msg.hwnd = Grab.Hwnd;
					}

					msg.lParam=(IntPtr) (xevent.ButtonEvent.y << 16 | xevent.ButtonEvent.x);
					mouse_position.X = xevent.ButtonEvent.x;
					mouse_position.Y = xevent.ButtonEvent.y;

					// Win32 splurts MouseMove events all over the place, regardless of whether the mouse is actually moving or
					// not, especially after mousedown and mouseup. To support apps relying on mousemove events between and after 
					// mouse clicks to repaint or whatever, we generate a mousemove event here. *sigh*
					if (msg.message == Msg.WM_LBUTTONUP || msg.message == Msg.WM_MBUTTONUP || msg.message == Msg.WM_RBUTTONUP) {
						XEvent motionEvent = new XEvent ();
						motionEvent.type = XEventName.MotionNotify;
						motionEvent.MotionEvent.display = DisplayHandle;
						motionEvent.MotionEvent.window = xevent.ButtonEvent.window;
						motionEvent.MotionEvent.x = xevent.ButtonEvent.x;
						motionEvent.MotionEvent.y = xevent.ButtonEvent.y;
						hwnd.Queue.EnqueueLocked (motionEvent);
					}
					break;
				}

				case XEventName.MotionNotify: {
					if (client) {
						DriverDebug("GetMessage(): Window {0:X} MotionNotify x={1} y={2}",
							    client ? hwnd.client_window.ToInt32() : hwnd.whole_window.ToInt32(),
							    xevent.MotionEvent.x, xevent.MotionEvent.y);

						if (Grab.Hwnd != IntPtr.Zero) {
							msg.hwnd = Grab.Hwnd;
						} else {
							if (hwnd.Enabled) {
								NativeWindow.WndProc(msg.hwnd, Msg.WM_SETCURSOR, msg.hwnd, (IntPtr)HitTest.HTCLIENT);
							}
						}

						if (xevent.MotionEvent.is_hint != 0)
						{
							IntPtr root, child;
							int mask;
							XQueryPointer (DisplayHandle, xevent.AnyEvent.window,
											out root, out child,
											out xevent.MotionEvent.x_root, 
											out xevent.MotionEvent.y_root,
											out xevent.MotionEvent.x,      
											out xevent.MotionEvent.y, out mask);
						}

						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)(mouse_position.Y << 16 | mouse_position.X);
						}

						mouse_position.X = xevent.MotionEvent.x;
						mouse_position.Y = xevent.MotionEvent.y;

						if ((HoverState.Timer.Enabled) &&
						    (((mouse_position.X + HoverState.Size.Width) < HoverState.X) ||
						    ((mouse_position.X - HoverState.Size.Width) > HoverState.X) ||
						    ((mouse_position.Y + HoverState.Size.Height) < HoverState.Y) ||
						    ((mouse_position.Y - HoverState.Size.Height) > HoverState.Y))) {
							HoverState.Timer.Stop();
							HoverState.Timer.Start();
							HoverState.X = mouse_position.X;
							HoverState.Y = mouse_position.Y;
						}

						break;
					} else {
						HitTest	ht;
						IntPtr dummy;

						DriverDebug("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);
						msg.message = Msg.WM_NCMOUSEMOVE;

						if (!hwnd.Enabled) {
							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)(mouse_position.Y << 16 | mouse_position.X);
						}

						ht = NCHitTest (hwnd, xevent.MotionEvent.x, xevent.MotionEvent.y);
						NativeWindow.WndProc(hwnd.client_window, Msg.WM_SETCURSOR, msg.hwnd, (IntPtr)ht);

						mouse_position.X = xevent.MotionEvent.x;
						mouse_position.Y = xevent.MotionEvent.y;
					}

					break;
				}

				case XEventName.EnterNotify: {
					if (!hwnd.Enabled) {
						goto ProcessNextMessage;
					}
					if (xevent.CrossingEvent.mode == NotifyMode.NotifyGrab || xevent.AnyEvent.window != hwnd.client_window) {
						goto ProcessNextMessage;
					}
					if (xevent.CrossingEvent.mode == NotifyMode.NotifyUngrab) { // Pseudo motion caused by grabbing
						if (LastPointerWindow == xevent.AnyEvent.window)
							goto ProcessNextMessage;

						if (LastPointerWindow != IntPtr.Zero) {
							Point enter_loc = new Point (xevent.ButtonEvent.x, xevent.ButtonEvent.y);

							// We need this due to EnterNotify being fired on all the parent controls
							// of the Control being grabbed, and obviously in that scenario we are not
							// actuallty entering them
							Control ctrl = Control.FromHandle (hwnd.client_window);
							foreach (Control child_control in ctrl.Controls.GetAllControls ())
								if (child_control.Bounds.Contains (enter_loc))
									goto ProcessNextMessage;

							// A MouseLeave/LeaveNotify event is sent to the previous window
							// until the mouse is ungrabbed, not when actually leaving its bounds
							int x = xevent.CrossingEvent.x_root;
							int y = xevent.CrossingEvent.y_root;
							ScreenToClient (LastPointerWindow, ref x, ref y);

							XEvent leaveEvent = new XEvent ();
							leaveEvent.type = XEventName.LeaveNotify;
							leaveEvent.CrossingEvent.display = DisplayHandle;
							leaveEvent.CrossingEvent.window = LastPointerWindow;
							leaveEvent.CrossingEvent.x = x;
							leaveEvent.CrossingEvent.y = y;
							leaveEvent.CrossingEvent.mode = NotifyMode.NotifyNormal;
							Hwnd last_pointer_hwnd = Hwnd.ObjectFromHandle (LastPointerWindow);
							last_pointer_hwnd.Queue.EnqueueLocked (leaveEvent);
						}
					}

					LastPointerWindow = xevent.AnyEvent.window;

					msg.message = Msg.WM_MOUSE_ENTER;
					HoverState.X = xevent.CrossingEvent.x;
					HoverState.Y = xevent.CrossingEvent.y;
					HoverState.Timer.Enabled = true;
					HoverState.Window = xevent.CrossingEvent.window;

					// Win32 sends a WM_MOUSEMOVE after mouse enter
					XEvent motionEvent = new XEvent ();
					motionEvent.type = XEventName.MotionNotify;
					motionEvent.MotionEvent.display = DisplayHandle;
					motionEvent.MotionEvent.window = xevent.ButtonEvent.window;
					motionEvent.MotionEvent.x = xevent.ButtonEvent.x;
					motionEvent.MotionEvent.y = xevent.ButtonEvent.y;
					hwnd.Queue.EnqueueLocked (motionEvent);
					break;
				}

				case XEventName.LeaveNotify: {
					if (xevent.CrossingEvent.mode == NotifyMode.NotifyUngrab) {
						WindowUngrabbed (hwnd.Handle);
						goto ProcessNextMessage;
					}
					if (!hwnd.Enabled) {
						goto ProcessNextMessage;
					}
					if ((xevent.CrossingEvent.mode != NotifyMode.NotifyNormal) || (xevent.CrossingEvent.window != hwnd.client_window)) {
						goto ProcessNextMessage;
					}
					// If a grab is taking place, ignore it - we handle it in EnterNotify
					if (Grab.Hwnd != IntPtr.Zero)
						goto ProcessNextMessage;

					// Reset the cursor explicitly on X11.
					// X11 remembers the last set cursor for the window and in cases where 
					// the control won't get a WM_SETCURSOR	X11 will restore the last 
					// known cursor, which we don't want.
					// 
					SetCursor (hwnd.client_window, IntPtr.Zero);

					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) && (xevent.ReparentEvent.window == hwnd.whole_window)) {
							hwnd.Reparented = true;

							// The location given by the event is not reliable between different wm's, 
							// so use an alternative way of getting it.
							Point location = GetTopLevelWindowLocation (hwnd);
							hwnd.X = location.X;
							hwnd.Y = location.Y;

							if (hwnd.opacity != 0xffffffff) {
								IntPtr opacity;

								opacity = (IntPtr)(Int32)hwnd.opacity;
								XChangeProperty(DisplayHandle, XGetParent(hwnd.whole_window), _NET_WM_WINDOW_OPACITY, (IntPtr)Atom.XA_CARDINAL, 32, PropertyMode.Replace, ref opacity, 1);
							}
							SendMessage(msg.hwnd, Msg.WM_WINDOWPOSCHANGED, msg.wParam, msg.lParam);
							goto ProcessNextMessage;
						} else {
							hwnd.Reparented = false;
							goto ProcessNextMessage;
						}
					}
					goto ProcessNextMessage;
				}

				case XEventName.ConfigureNotify: {
					if (!client && (xevent.ConfigureEvent.xevent == xevent.ConfigureEvent.window)) {	// Ignore events for children (SubstructureNotify) and client areas
						DriverDebug("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);

						lock (hwnd.configure_lock) {
							Form form = Control.FromHandle (hwnd.client_window) as Form;
							if (form != null && !hwnd.resizing_or_moving) {
								if (hwnd.x != form.Bounds.X || hwnd.y != form.Bounds.Y) {
									SendMessage (form.Handle, Msg.WM_SYSCOMMAND, (IntPtr)SystemCommands.SC_MOVE, IntPtr.Zero);
									hwnd.resizing_or_moving = true;
								} else if (hwnd.width != form.Bounds.Width || hwnd.height != form.Bounds.Height) {
									SendMessage (form.Handle, Msg.WM_SYSCOMMAND, (IntPtr)SystemCommands.SC_SIZE, IntPtr.Zero);
									hwnd.resizing_or_moving = true;
								}
								if (hwnd.resizing_or_moving)
									SendMessage (form.Handle, Msg.WM_ENTERSIZEMOVE, IntPtr.Zero, IntPtr.Zero);
							}
	
							SendMessage(msg.hwnd, Msg.WM_WINDOWPOSCHANGED, IntPtr.Zero, IntPtr.Zero);
							hwnd.configure_pending = false;
	
							// We need to adjust our client window to track the resize of whole_window
							if (hwnd.whole_window != hwnd.client_window)
								PerformNCCalc(hwnd);
						}
					}
					goto ProcessNextMessage;
				}

				case XEventName.FocusIn: {
					// We received focus. We use X11 focus only to know if the app window does or does not have focus
					// We do not track the actual focussed window via it. Instead, this is done via FocusWindow internally
					// Receiving focus means we've gotten activated and therefore we need to let the actual FocusWindow know 
					// about it having focus again
					if (xevent.FocusChangeEvent.detail != NotifyDetail.NotifyNonlinear) {
						goto ProcessNextMessage;
					}

					
					if (FocusWindow == IntPtr.Zero) {
						Control c = Control.FromHandle (hwnd.client_window);

						if (c == null)
							goto ProcessNextMessage;						
						Form form = c.FindForm ();
						if (form == null)
							goto ProcessNextMessage;
					
						if (ActiveWindow != form.Handle) {
							ActiveWindow = form.Handle;
							SendMessage (ActiveWindow, Msg.WM_ACTIVATE, (IntPtr) WindowActiveFlags.WA_ACTIVE, IntPtr.Zero);
						}
						goto ProcessNextMessage;
					}
					Keyboard.FocusIn (FocusWindow);
					SendMessage(FocusWindow, Msg.WM_SETFOCUS, IntPtr.Zero, IntPtr.Zero);
					goto ProcessNextMessage;
				}

				case XEventName.FocusOut: {
					// Se the comment for our FocusIn handler
					if (xevent.FocusChangeEvent.detail != NotifyDetail.NotifyNonlinear) {
						goto ProcessNextMessage;
					}

					while (Keyboard.ResetKeyState(FocusWindow, ref msg)) {
						SendMessage(FocusWindow, msg.message, msg.wParam, msg.lParam);
					}

					Keyboard.FocusOut(hwnd.client_window);
					SendMessage(FocusWindow, Msg.WM_KILLFOCUS, IntPtr.Zero, IntPtr.Zero);
					goto ProcessNextMessage;
				}

				// We are already firing WM_SHOWWINDOW messages in the proper places, but I'm leaving this code
				// in case we break a scenario not taken into account in the tests
				case XEventName.MapNotify: {
					/*if (client && (xevent.ConfigureEvent.xevent == xevent.ConfigureEvent.window)) {	// Ignore events for children (SubstructureNotify) and client areas
						hwnd.mapped = true;
						msg.message = Msg.WM_SHOWWINDOW;
						msg.wParam = (IntPtr) 1;
						// XXX we're missing the lParam..
						break;
					}*/
					goto ProcessNextMessage;
				}

				case XEventName.UnmapNotify: {
					/*if (client && (xevent.ConfigureEvent.xevent == xevent.ConfigureEvent.window)) {	// Ignore events for children (SubstructureNotify) and client areas
						hwnd.mapped = false;
						msg.message = Msg.WM_SHOWWINDOW;
						msg.wParam = (IntPtr) 0;
						// XXX we're missing the lParam..
						break;
					}*/
					goto ProcessNextMessage;
				}

				case XEventName.Expose: {
					if (!hwnd.Mapped) {
						if (client) {
							hwnd.expose_pending = false;
						} else {
							hwnd.nc_expose_pending = false;
						}
						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);
								if (hwnd.border_static)
									ControlPaint.DrawBorder3D(g, new Rectangle(0, 0, hwnd.Width, hwnd.Height), Border3DStyle.SunkenOuter);
								else
									ControlPaint.DrawBorder3D(g, new Rectangle(0, 0, hwnd.Width, hwnd.Height), Border3DStyle.Sunken);
								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;
							}
						}
						DriverDebug("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);

						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 == IntPtr.Zero ? (IntPtr)1 : hrgn;
						msg.refobject = region;
						break;
					}
					DriverDebug("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);
					if (Caret.Visible == true) {
						Caret.Paused = true;
						HideCaret();
					}

					if (Caret.Visible == true) {
						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 != null) && (hwnd.client_window == xevent.DestroyWindowEvent.window)) {
						CleanupCachedWindows (hwnd);

						DriverDebug("Received X11 Destroy Notification for {0}", XplatUI.Window(hwnd.client_window));

						msg.hwnd = hwnd.client_window;
						msg.message=Msg.WM_DESTROY;
						hwnd.Dispose();
					} else {
						goto ProcessNextMessage;
					}

					break;
				}

				case XEventName.ClientMessage: {
					if (Dnd.HandleClientMessage (ref xevent)) {
						goto ProcessNextMessage;
					}

					if (xevent.ClientMessageEvent.message_type == AsyncAtom) {
						XplatUIDriverSupport.ExecuteClientMessage((GCHandle)xevent.ClientMessageEvent.ptr1);
						goto ProcessNextMessage;
					}

					if (xevent.ClientMessageEvent.message_type == HoverState.Atom) {
						msg.message = Msg.WM_MOUSEHOVER;
						msg.wParam = GetMousewParam(0);
						msg.lParam = (IntPtr) (xevent.ClientMessageEvent.ptr1);
						return true;
					}

					if (xevent.ClientMessageEvent.message_type == (IntPtr)PostAtom) {						
						DebugHelper.Indent ();
						DebugHelper.WriteLine (String.Format ("Posted message:" + (Msg) xevent.ClientMessageEvent.ptr2.ToInt32 () + " for 0x{0:x}", xevent.ClientMessageEvent.ptr1.ToInt32 ()));
						DebugHelper.Unindent ();
						msg.hwnd = xevent.ClientMessageEvent.ptr1;
						msg.message = (Msg) xevent.ClientMessageEvent.ptr2.ToInt32 ();
						msg.wParam = xevent.ClientMessageEvent.ptr3;
						msg.lParam = xevent.ClientMessageEvent.ptr4;
						if (msg.message == (Msg)Msg.WM_QUIT)
							return false;
						else
							return true;
					}

					if  (xevent.ClientMessageEvent.message_type == _XEMBED) {
#if DriverDebugXEmbed
						Console.WriteLine("GOT EMBED MESSAGE {0:X}, detail {1:X}", xevent.ClientMessageEvent.ptr2.ToInt32(), xevent.ClientMessageEvent.ptr3.ToInt32());
#endif

						if (xevent.ClientMessageEvent.ptr2.ToInt32() == (int)XEmbedMessage.EmbeddedNotify) {
							XSizeHints hints = new XSizeHints();
							IntPtr dummy;

							XGetWMNormalHints(DisplayHandle, hwnd.whole_window, ref hints, out dummy);

							hwnd.width = hints.max_width;
							hwnd.height = hints.max_height;
							hwnd.ClientRect = Rectangle.Empty;
							SendMessage(msg.hwnd, Msg.WM_WINDOWPOSCHANGED, IntPtr.Zero, IntPtr.Zero);
						}
					}

					if  (xevent.ClientMessageEvent.message_type == WM_PROTOCOLS) {
						if (xevent.ClientMessageEvent.ptr1 == WM_DELETE_WINDOW) {
							SendMessage (msg.hwnd, Msg.WM_SYSCOMMAND, (IntPtr)SystemCommands.SC_CLOSE, IntPtr.Zero);
							msg.message = Msg.WM_CLOSE;
							return true;
						}

						// We should not get this, but I'll leave the code in case we need it in the future
						if (xevent.ClientMessageEvent.ptr1 == WM_TAKE_FOCUS) {
							goto ProcessNextMessage;
						}
					}
					goto ProcessNextMessage;
				}

				default: {
					goto ProcessNextMessage;
				}
			}

			return true;
		}
Beispiel #34
0
        int IPropertyPage.TranslateAccelerator(MSG[] pMsg) {
            Utilities.ArgumentNotNull("pMsg", pMsg);

            MSG msg = pMsg[0];

            if ((msg.message < NativeMethods.WM_KEYFIRST || msg.message > NativeMethods.WM_KEYLAST) && (msg.message < NativeMethods.WM_MOUSEFIRST || msg.message > NativeMethods.WM_MOUSELAST)) {
                return VSConstants.S_FALSE;
            }

            return (NativeMethods.IsDialogMessageA(Control.Handle, ref msg)) ? VSConstants.S_OK : VSConstants.S_FALSE;
        }
Beispiel #35
0
		internal override bool PeekMessage(Object queue_id, ref MSG msg, IntPtr hWnd, int wFilterMin, int wFilterMax, uint flags)
		{
			XEventQueue queue = (XEventQueue) queue_id;
			bool	pending;

			if ((flags & (uint)PeekMessageFlags.PM_REMOVE) == 0) {
				throw new NotImplementedException("PeekMessage PM_NOREMOVE is not implemented yet");	// FIXME - Implement PM_NOREMOVE flag
			}

			pending = false;
			if (queue.Count > 0) {
				pending = true;
			} else {
				// Only call UpdateMessageQueue if real events are pending 
				// otherwise we go to sleep on the socket
				if (XPending(DisplayHandle) != 0) {
					UpdateMessageQueue((XEventQueue)queue_id);
					pending = true;
				} else if (((XEventQueue)queue_id).Paint.Count > 0) {
					pending = true;
				}
			}

			CheckTimers(queue.timer_list, DateTime.UtcNow);

			if (!pending) {
				return false;
			}
			return GetMessage(queue_id, ref msg, hWnd, wFilterMin, wFilterMax);
		}
 // Any component that needs idle time, the ability to process
 // messages before they are translated (for example, to call TranslateAccelerator
 // or IsDialogMessage), notification about modal states, or the ability to push message
 // loops must implement this interface and register with the Component Manager.
 /// <summary>
 /// Called during each iteration of a message loop that the component pushed.
 /// </summary>
 /// <param name="uReason">The reason for the call.</param>
 /// <param name="pvLoopData">The component's private data.</param>
 /// <param name="pMsgPeeked">The peeked message, or NULL if no message is in the queue.</param>
 /// <returns>
 /// TRUE (not zero) if the message loop should continue, otherwise FALSE (zero).
 /// If false is returned, the component manager terminates the loop without
 /// removing pMsgPeeked from the queue.
 /// </returns>
 /// <remarks>
 /// This method is called after peeking the next message in the queue (via PeekMessage)
 /// but before the message is removed from the queue.  This method may be additionally 
 /// called when the next message has already been removed from the queue, in which case
 /// pMsgPeeked is passed as NULL.
 /// </remarks>
 public int FContinueMessageLoop(uint uReason, IntPtr pvLoopData, MSG[] pMsgPeeked)
 {
     throw new Exception("The method or operation is not implemented.");
 }
Beispiel #37
0
		internal override bool TranslateMessage(ref MSG msg)
		{
			return Keyboard.TranslateMessage (ref msg);
		}
Beispiel #38
0
		internal static bool HandleEvent (IntPtr callref, IntPtr eventref, IntPtr handle, uint kind, ref MSG msg) {
			Control control;
			DataObject data;
			DragEventArgs drag_event;
			DragDropEffects allowed;
			QDPoint point = new QDPoint ();
			UInt32 actions = 0;
			IntPtr dragref = IntPtr.Zero;
			Hwnd hwnd = Hwnd.ObjectFromHandle (handle);

			if (hwnd == null || hwnd.Handle != handle)
				return false;

			GetEventParameter (eventref, kEventParamDragRef, typeDragRef, IntPtr.Zero, (uint) Marshal.SizeOf (typeof (IntPtr)), IntPtr.Zero, ref dragref);
			XplatUICarbon.GetGlobalMouse (ref point);
			GetDragAllowableActions (dragref, ref actions);
			control = Control.FromHandle (hwnd.Handle);
			allowed = DragActionsToEffects (actions);
			data = DragToDataObject (dragref);
			drag_event = new DragEventArgs (data, 0, point.x, point.y, allowed, DragDropEffects.None);
				
			switch (kind) {
				case ControlHandler.kEventControlDragEnter: {
					bool accept = control.AllowDrop;
					SetEventParameter (eventref, ControlHandler.kEventParamControlLikesDrag, ControlHandler.typeBoolean, (uint)Marshal.SizeOf (typeof (bool)), ref accept);

					control.DndEnter (drag_event);
					effects = drag_event.Effect;
					return false;
				}
				case ControlHandler.kEventControlDragWithin:
					control.DndOver (drag_event);
					effects = drag_event.Effect;
					break;
				case ControlHandler.kEventControlDragLeave:
					control.DndLeave (drag_event);
					break;
				case ControlHandler.kEventControlDragReceive:
					control.DndDrop (drag_event);
					break;
			}
			return true;
		}
Beispiel #39
0
		internal override void DoEvents() {
			MSG msg = new MSG();

			while (GetMessage(ref msg, IntPtr.Zero, 0, 0, false)) {
				Message m = Message.Create (msg.hwnd, (int)msg.message, msg.wParam, msg.lParam);

				if (Application.FilterMessage (ref m))
					continue;

				XplatUI.TranslateMessage(ref msg);
				XplatUI.DispatchMessage(ref msg);
			}
		}
Beispiel #40
0
    private void PowerEventThread()
    {
      //Log.Debug( "Service1.PowerEventThread started" );

      Thread.BeginThreadAffinity();
      try
      {
        _powerEventThreadId = GetCurrentThreadId();

        WNDCLASS wndclass;
        wndclass.style = 0;
        wndclass.lpfnWndProc = PowerEventThreadWndProc;
        wndclass.cbClsExtra = 0;
        wndclass.cbWndExtra = 0;
        wndclass.hInstance = Process.GetCurrentProcess().Handle;
        wndclass.hIcon = IntPtr.Zero;
        wndclass.hCursor = IntPtr.Zero;
        wndclass.hbrBackground = IntPtr.Zero;
        wndclass.lpszMenuName = null;
        wndclass.lpszClassName = "TVServicePowerEventThreadWndClass";

        RegisterClass(ref wndclass);

        IntPtr handle = CreateWindowEx(0x80, wndclass.lpszClassName, "", 0x80000000, 0, 0, 0, 0, IntPtr.Zero,
                                       IntPtr.Zero, wndclass.hInstance, IntPtr.Zero);

        if (handle.Equals(IntPtr.Zero))
        {
          Log.Error("TV service PowerEventThread cannot create window handle, exiting thread");
          return;
        }

        // this thread needs an message loop
        Log.Debug("TV service PowerEventThread message loop is running");
        while (true)
        {
          try
          {
            MSG msgApi = new MSG();

            if (!GetMessageA(ref msgApi, IntPtr.Zero, 0, 0)) // returns false on WM_QUIT
              return;

            TranslateMessage(ref msgApi);

            Log.Debug("TV service PowerEventThread {0}", msgApi.message);


            DispatchMessageA(ref msgApi);
          }
          catch (Exception ex)
          {
            Log.Error("TV service PowerEventThread: Exception: {0}", ex.ToString());
          }
        }
      }
      finally
      {
        Thread.EndThreadAffinity();
        Log.Debug("TV service PowerEventThread finished");
      }
    }
Beispiel #41
0
 internal static bool TranslateMessage(ref MSG msg)
 {
     return(driver.TranslateMessage(ref msg));
 }