void StartPeekMessageLoop() { // Create an object for storing windows message information Win32.MSG msg = new Win32.MSG(); bool leaveMsg = false; // Process messages until exit condition recognised while (!exitLoop) { // Suspend thread until a windows message has arrived if (WindowsAPI.WaitMessage()) { // Take a peek at the message details without removing from queue while (!exitLoop && WindowsAPI.PeekMessage(ref msg, 0, 0, 0, (int)Win32.PeekMessageFlags.PM_NOREMOVE)) { //Console.WriteLine("Track {0} {1}", this.Handle, ((Msg)msg.message).ToString()); //Console.WriteLine("Message is for {0 }", msg.hwnd); // Mouse was pressed in a window of this application if ((msg.message == (int)Msg.WM_LBUTTONDOWN) || (msg.message == (int)Msg.WM_MBUTTONDOWN) || (msg.message == (int)Msg.WM_RBUTTONDOWN) || (msg.message == (int)Msg.WM_NCLBUTTONDOWN) || (msg.message == (int)Msg.WM_NCMBUTTONDOWN) || (msg.message == (int)Msg.WM_NCRBUTTONDOWN)) { // Is the mouse event for this popup window? if (msg.hwnd != this.Handle && !IsChild(msg.hwnd)) { // No, then we need to exit the popup menu tracking exitLoop = true; // DO NOT process the message, leave it on the queue // and let the real destination window handle it. leaveMsg = true; } } else { // Mouse move occured if (msg.message == (int)Msg.WM_MOUSEMOVE) { // Is the mouse event for this popup window? if ((msg.hwnd != this.Handle && !IsChild(msg.hwnd))) { // Eat the message to prevent the destination getting it Win32.MSG eat = new Win32.MSG(); WindowsAPI.GetMessage(ref eat, 0, 0, 0); // Do not attempt to pull a message off the queue as it has already // been eaten by us in the above code leaveMsg = true; } } } // Should the message we pulled from the queue? if (!leaveMsg) { if (WindowsAPI.GetMessage(ref msg, 0, 0, 0)) { WindowsAPI.TranslateMessage(ref msg); WindowsAPI.DispatchMessage(ref msg); } } else { leaveMsg = false; } } } } }