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;
					}
				}
			}
		}
Beispiel #2
0
        void ProcessItemHit(int index, Point pt)
        {
            bool itemPressed = true;
            Capture = true;
            using (Graphics g = Graphics.FromHwnd(Handle))
            {
                Rectangle itemRect = GetItemRect(g, bands[currentBandIndex], index, Rectangle.Empty);
                DrawItem(g, index, itemRect, true, true, Rectangle.Empty, null);
                bool dragging = false;
                int deltaX = 0;
                int deltaY = 0;
                bool itemHighlighted = false;
                int dragItemIndex = -1;

                bool doLoop = true;
                while (doLoop)
                {
                    // Check messages until we find a condition to break out of the loop
                    Win32.MSG msg = new Win32.MSG();
                    WindowsAPI.GetMessage(ref msg, 0, 0, 0);
                    Point point = new Point(0, 0);
                    if (msg.message == (int)Msg.WM_MOUSEMOVE || msg.message == (int)Msg.WM_LBUTTONUP)
                    {
                        point = WindowsAPI.GetPointFromLPARAM((int)msg.lParam);
                        if (msg.message == (int)Msg.WM_MOUSEMOVE)
                        {
                            deltaX = pt.X - point.X;
                            deltaY = pt.Y - point.Y;
                        }
                    }

                    switch (msg.message)
                    {
                        case (int)Msg.WM_MOUSEMOVE:
                        {
                            int currentIndex;
                            HitTestType hit = HitTest(point, out currentIndex, dragging);
                            if (dragging)
                            {

                                if (hit == HitTestType.DropLine || hit == HitTestType.DropLineLastItem)
                                {
                                    Cursor.Current = dragCursor;
                                    // Draw the Dragline
                                    DrawDropLine(g, currentIndex, true, hit);
                                }
                                else
                                {
                                    Cursor.Current = Cursors.No;
                                    // Erase the Dragline
                                    DrawDropLine(g, index, false, hit);
                                }

                                if (hit == HitTestType.Item && currentIndex == index)
                                {
                                    if (itemHighlighted == false)
                                    {
                                        DrawItem(g, index, itemRect,
                                        true, false, Rectangle.Empty, null);
                                        itemHighlighted = true;
                                    }
                                }
                                else
                                {
                                    if (hit == HitTestType.Item)
                                    {

                                        // Erase previous highlighting first
                                        if (itemHighlighted)
                                        {
                                            DrawItem(g, index, itemRect,
                                            false, false, Rectangle.Empty, null);
                                        }

                                        // Highlight new item
                                        itemRect = GetItemRect(g, bands[currentBandIndex], currentIndex, Rectangle.Empty);
                                        index = currentIndex;
                                        DrawItem(g, index, itemRect,
                                        true, false, Rectangle.Empty, null);
                                    }
                                    else
                                    {
                                        // the mouse did not hit an item
                                        if (itemHighlighted)
                                        {
                                            DrawItem(g, index, itemRect,
                                            false, false, Rectangle.Empty, null);
                                            itemHighlighted = false;
                                        }
                                    }
                                }
                            }
                            else
                            {
                                if (hit == HitTestType.Item && currentIndex == index)
                                {

                                    // Set no drag cursor if there have been at least
                                    // a 5 pixel movement
                                    int pixelmov = 5;
                                    if (bands[currentBandIndex].IconView == IconView.Small)
                                        pixelmov = 2;
                                    bool unpressed = false;
                                    if (Math.Abs(deltaX) >= pixelmov || Math.Abs(deltaY) >= pixelmov)
                                    {
                                        unpressed = true;
                                        Cursor.Current = Cursors.No;
                                        dragging = true;
                                        dragItemIndex = index;
                                    }

                                    if (itemPressed && unpressed)
                                    {
                                        DrawItem(g, index, itemRect,
                                        true, false, Rectangle.Empty, null);
                                        itemPressed = false;
                                        itemHighlighted = true;
                                    }
                                }
                            }
                            break;
                        }
                        case (int)Msg.WM_LBUTTONUP:
                        {

                            // Highlight the item
                            if (itemPressed)
                            {
                                DrawItem(g, index, itemRect, true, false, Rectangle.Empty, null);
                                itemPressed = false;
                            }

                            int newIndex;
                            HitTestType ht = HitTest(point, out newIndex, true);
                            bool doDrop = false;
                            if (dragging && (ht == HitTestType.DropLine || ht == HitTestType.DropLineLastItem))
                            {
                                // Delete dropline
                                Cursor.Current = Cursors.Default;
                                // Erase the Dragline
                                DrawDropLine(g, index, false, ht);

                                // Move the dragged item to the new location
                                // only if the new location is not contiguous to its
                                // own location
                                if (dragItemIndex > droppedPosition
                                && Math.Abs(dragItemIndex - droppedPosition) > 0)
                                    doDrop = true;
                                else if (dragItemIndex < droppedPosition
                                && Math.Abs(dragItemIndex - droppedPosition) > 1)
                                    doDrop = true;

                                if (doDrop)
                                {
                                    // Remove item from its old location
                                    OutlookBarItem dragItem = bands[currentBandIndex].Items[dragItemIndex];
                                    bands[currentBandIndex].Items.RemoveAt(dragItemIndex);
                                    // Insert item in its new location
                                    if (dragItemIndex < droppedPosition)
                                        droppedPosition--;

                                    bands[currentBandIndex].Items.Insert(droppedPosition, dragItem);
                                }
                            }

                            // Repaint the bar just in case we had a dropline painted
                            Invalidate();

                            // Highlight item
                            if (!dragging)
                            {
                                // do not highlight if we are dropping
                                forceHightlight = true;
                                forceHightlightIndex = index;
                                // Fire item clicked property
                                FireItemClicked(index);
                            }
                            else
                            {
                                // Fire item dropped event
                                if (droppedPosition != -1 && doDrop)
                                    FireItemDropped(droppedPosition);
                            }

                            doLoop = false;
                            break;
                        }
                        case (int)Msg.WM_KEYDOWN:
                        {
                            if ((int)msg.wParam == (int)VirtualKeys.VK_ESCAPE)
                                doLoop = false;
                            break;
                        }
                        default:
                            WindowsAPI.DispatchMessage(ref msg);
                            break;
                    }
                }
            }
            Capture = false;
        }
Beispiel #3
0
        protected void SimulateGrabFocus()
        {
            if (!_manualFocus)
            {
                _manualFocus = true;
                _animateFirst = true;

                Form parentForm = this.FindForm();

                // Want notification when user selects a different Form
                parentForm.Deactivate += new EventHandler(OnParentDeactivate);

                // Must hide caret so user thinks focus has changed
                bool hideCaret = User32.HideCaret(IntPtr.Zero);

                // Create an object for storing windows message information
                Win32.MSG msg = new Win32.MSG();

                _exitLoop = false;

                // Process messages until exit condition recognised
                while(!_exitLoop)
                {
                    // Suspend thread until a windows message has arrived
                    if (User32.WaitMessage())
                    {
                        // Take a peek at the message details without removing from queue
                        while(!_exitLoop && User32.PeekMessage(ref msg, 0, 0, 0, (int)Win32.PeekMessageFlags.PM_NOREMOVE))
                        {
            //							Console.WriteLine("Loop {0} {1}", this.Handle, ((Win32.Msgs)msg.message).ToString());

                            if (User32.GetMessage(ref msg, 0, 0, 0))
                            {
                                // Should this method be dispatched?
                                if (!ProcessInterceptedMessage(ref msg))
                                {
                                    User32.TranslateMessage(ref msg);
                                    User32.DispatchMessage(ref msg);
                                }
                            }
                        }
                    }
                }

                // Remove notification when user selects a different Form
                parentForm.Deactivate -= new EventHandler(OnParentDeactivate);

                // If caret was hidden then show it again now
                if (hideCaret)
                    User32.ShowCaret(IntPtr.Zero);

                // We lost the focus
                _manualFocus = false;
            }
        }
Beispiel #4
0
        void ProcessArrowScrolling(Rectangle arrowButton, ref bool arrowVisible, ref bool arrowPressed, ref bool timerTicking)
        {
            // Capture the mouse
            Capture = true;
            // Draw the arrow button pushed
            timerTicking = true;
            // Draw pushed button
            buttonPushed = true;
            DrawArrowButton(arrowButton, ButtonState.Pushed);

            // Start timer
            using (System.Windows.Forms.Timer timer = new System.Windows.Forms.Timer())
            {
                timer.Tick += new EventHandler(ScrollingTick);
                timer.Interval = 300;
                timer.Start();

            doScrollingLoop = true;
                while (doScrollingLoop)
                {
                    // Check messages until we find a condition to break out of the loop
                    Win32.MSG msg = new Win32.MSG();
                    WindowsAPI.GetMessage(ref msg, 0, 0, 0);
                    Point point = new Point(0, 0);
                    if (msg.message == (int)Msg.WM_MOUSEMOVE || msg.message == (int)Msg.WM_LBUTTONUP)
                    {
                        point = WindowsAPI.GetPointFromLPARAM((int)msg.lParam);
                    }

                    switch (msg.message)
                    {
                        case (int)Msg.WM_MOUSEMOVE:
                            {
                                if (arrowButton.Contains(point))
                                {
                                    if (!buttonPushed)
                                    {
                                        DrawArrowButton(arrowButton, ButtonState.Pushed);
                                        arrowVisible = true;
                                        arrowPressed = true;
                                        buttonPushed = true;
                                    }
                                }
                                else
                                {
                                    if (buttonPushed)
                                    {
                                        DrawArrowButton(arrowButton, ButtonState.Normal);
                                        arrowVisible = false;
                                        arrowPressed = false;
                                        buttonPushed = false;
                                    }
                                }
                                break;
                            }
                        case (int)Msg.WM_LBUTTONUP:
                            {
                                if (buttonPushed)
                                {
                                    if (!flatArrowButtons)
                                    {
                                        // Only if using regular buttons
                                        DrawArrowButton(arrowButton, ButtonState.Normal);
                                    }
                                    buttonPushed = false;
                                }
                                arrowVisible = false;
                                if (arrowButton.Contains(point))
                                {
                                    if (arrowButton.Equals(upArrowRect))
                                    {
                                        if (firstItem > 0)
                                        {
                                            firstItem--;
                                            Rectangle rc = GetViewPortRect();
                                            Invalidate(rc);
                                        }
                                    }
                                    else if (arrowButton.Equals(downArrowRect))
                                    {
                                        using (Graphics g = Graphics.FromHwnd(Handle))
                                        {
                                            // Get the last item rectangle
                                            OutlookBarBand band = bands[currentBandIndex];
                                            if (band != null)
                                            {
                                                Rectangle rcItem = GetItemRect(g, band, band.Items.Count - 1, Rectangle.Empty);
                                                Rectangle rc = GetViewPortRect();
                                                if (rcItem.Bottom > rc.Bottom)
                                                {
                                                    firstItem++;
                                                    Invalidate(rc);
                                                }
                                            }
                                        }
                                    }
                                }
                                doScrollingLoop = false;
                                break;
                            }
                        case (int)Msg.WM_KEYDOWN:
                            {
                                if ((int)msg.wParam == (int)VirtualKeys.VK_ESCAPE)
                                    doScrollingLoop = false;
                                break;
                            }
                        default:
                            WindowsAPI.DispatchMessage(ref msg);
                            break;
                    }
                }

                // Release the capture
                Capture = false;
                // Stop timer
                timer.Stop();
            }
            // Reset flags
            arrowVisible = false;
            arrowPressed = false;
            timerTicking = false;
            Rectangle viewPortRect = GetViewPortRect();
            Invalidate(viewPortRect);
        }
Beispiel #5
0
        void ProcessHeaderHit(int index)
        {
            Capture = true;
            Rectangle rc = GetHeaderRect(index);
            // Draw header pressed
            using (Graphics g = Graphics.FromHwnd(Handle))
            {
                DrawHeader(g, index, rc, Border3DStyle.Sunken);

            #if !__MonoCS__
                bool headerPressed = true;
                bool doLoop = true;
                while (doLoop)
                {
                    // Check messages until we find a condition to break out of the loop
                    Win32.MSG msg = new Win32.MSG();
                    WindowsAPI.GetMessage(ref msg, 0, 0, 0);
                    Point point = new Point(0,0);
                    if ( msg.message == (int)Msg.WM_MOUSEMOVE || msg.message == (int)Msg.WM_LBUTTONUP )
                    {
                        point = WindowsAPI.GetPointFromLPARAM((int)msg.lParam);
                    }

                    switch(msg.message)
                    {
                        case (int)Msg.WM_MOUSEMOVE:
                        {
                            int currentIndex;
                            HitTestType hit = HitTest(point, out currentIndex, false);
                            if (hit == HitTestType.Header && currentIndex == index)
                            {
                                if (!headerPressed)
                                {
                                    DrawHeader(g, index, rc, Border3DStyle.Sunken);
                                    headerPressed = true;
                                }
                            }
                            else
                            {
                                if (headerPressed)
                                {
                                    DrawHeader(g, index, rc, Border3DStyle.RaisedInner);
                                    headerPressed = false;
                                }
                            }
                            break;
                        }
                        case (int)Msg.WM_LBUTTONUP:
                        {
                            if (headerPressed)
                            {
                                DrawHeader(g, index, rc, Border3DStyle.RaisedInner);
                                headerPressed = false;
                            }
                            int newIndex;
                            HitTestType ht = HitTest(point, out newIndex, false);
                            if ( ht == HitTestType.Header && newIndex != selectedHeader )
                                SetCurrentBand(newIndex);
                            doLoop = false;
                            break;
                        }
                        case (int)Msg.WM_KEYDOWN:
                        {
                            if ( (int)msg.wParam == (int)VirtualKeys.VK_ESCAPE)
                                doLoop = false;
                            break;
                        }
                        default:
                            WindowsAPI.DispatchMessage(ref msg);
                            break;
                    }
                }
            #else
                // TODO-Linux: Windows dependant code.
            #endif

                // Reset flags
                Capture = false;
            }
        }
Beispiel #6
0
		protected bool ProcessKeyRight()
		{
			// Are we the first submenu of a parent control?
			bool autoRight = (_parentControl != null);

			bool checkKeys = false;

			bool ret = false;

			// Is an item currently selected?
			if (_trackItem != -1)
			{
				DrawCommand dc = _drawCommands[_trackItem] as DrawCommand;

				// Does this item have a submenu?
				if (dc.SubMenu)
				{
					// Consume the keyboard message to prevent the submenu immediately
					// processing the same message again. Remember this routine is called
					// after PeekMessage but the message is still on the queue at this point
					Win32.MSG msg = new Win32.MSG();
					WindowsAPI.GetMessage(ref msg, 0, 0, 0);

					// Handle the submenu
					OperateSubMenu(_trackItem, true);

					ret = true;
				}
				else
				{
					// Grab the current column/row values
					int col = dc.Col;
					int row = dc.Row;

					// If not in the first column then move left one
					int newItem = -1;
					int newRow = -1;
					int findCol = col + 1;
					DrawCommand newDc = null;

					for(int i=0; i<_drawCommands.Count; i++)
					{
						DrawCommand listDc = _drawCommands[i] as DrawCommand;

						// Interesting in cells in the required column
						if (listDc.Col == findCol)
						{
							// Is this Row nearer to the one required than those found so far?
							if ((listDc.Row <= row) && (listDc.Row > newRow) &&
								!listDc.Separator && listDc.Enabled)
							{
								// Remember this item
								newRow = listDc.Row;
								newDc = listDc;
								newItem = i;
							}
						}
					}

					if (newDc != null)
					{
						// Track the new item
						// Modify the display of the two items
						SwitchSelection(_trackItem, newItem, false, false);
					}
					else
						checkKeys = true;
				}
			}
			else
			{
				if (_parentMenu != null)
				{
					if (!ProcessKeyDown())
						checkKeys = true;
				}
				else
					checkKeys = true;
			}

			// If we have a parent control and nothing to move right into
			if (autoRight && checkKeys)
			{
				_returnCommand = null;

				// Finish processing messages
				_timer.Stop();
				_exitLoop = true;

				_returnDir = 1;
			}

			return ret;
		}
Beispiel #7
0
		protected MenuCommand InternalTrackPopup(bool selectFirst)
		{
			// MenuCommand to return as method result
			_returnCommand = null;

			// No item is being tracked
			_trackItem = -1;

			// Flag to indicate when to exit the message loop
			_exitLoop = false;

			// Assume the mouse does not start over our window
			_mouseOver = false;

			// Direction of key press if this caused dismissal
			_returnDir = 0;

			// Flag to indicate if the message should be dispatched
			bool leaveMsg = false;

			// Create and show the popup window (without taking the focus)
			CreateAndShowWindow();

			// Create an object for storing windows message information
			Win32.MSG msg = new Win32.MSG();

			// Draw everything now...
			//RefreshAllCommands();

			// Pretend user pressed key down to get the first valid item selected
			if (selectFirst)
				ProcessKeyDown();

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

						// Leave messages for children
						IntPtr hParent = WindowsAPI.GetParent(msg.hwnd);
						bool child = hParent == Handle;
						bool combolist = IsComboBoxList(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)
							{
								// Let the parent chain of PopupMenu's decide if they want it
								if (!ParentWantsMouseMessage(ref msg)&& !child && !combolist)
								{
									// 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;

									// Is a parent control specified?
									if (_parentControl != null)
									{
										// Is the mouse event destination the parent control?
										if (msg.hwnd == _parentControl.Handle)
										{
											// Then we want to consume the message so it does not get processed
											// by the parent control. Otherwise, pressing down will cause this
											// popup to disappear but the message will then get processed by
											// the parent and cause a popup to reappear again. When we actually
											// want the popup to disappear and nothing more.
											leaveMsg = false;
										}
									}
								}
							}
						}
						else
						{
							// Mouse move occured
							if (msg.message == (int)Msg.WM_MOUSEMOVE)
							{
								// Is the mouse event for this popup window?
								if (msg.hwnd != this.Handle)
								{
									// Do we still think the mouse is over our window?
									if (_mouseOver)
									{
										// Process mouse leaving situation
										OnWM_MOUSELEAVE();
									}

									// Let the parent chain of PopupMenu's decide if they want it
									if (!ParentWantsMouseMessage(ref msg) && !child && !combolist)
									{
										// 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;
									}
								}
							}
							else
							{
								// Was the alt key pressed?
								if (msg.message == (int)Msg.WM_SYSKEYDOWN)
								{
									// Alt key pressed on its own
									if((int)msg.wParam == (int)Win32.VirtualKeys.VK_MENU)	// ALT key
									{
										// Then we should dimiss ourself
										_exitLoop = true;
									}
								}

								// Was a key pressed?
								if (msg.message == (int)Msg.WM_KEYDOWN)
								{
									switch((int)msg.wParam)
									{
									case (int)Win32.VirtualKeys.VK_UP:
										ProcessKeyUp();
										break;
									case (int)Win32.VirtualKeys.VK_DOWN:
										ProcessKeyDown();
										break;
									case (int)Win32.VirtualKeys.VK_LEFT:
										ProcessKeyLeft();
										break;
									case (int)Win32.VirtualKeys.VK_RIGHT:
										if(ProcessKeyRight())
										{
											// Do not attempt to pull a message off the queue as the
											// ProcessKeyRight has eaten the message for us
											leaveMsg = true;
										}
										break;
									case (int)Win32.VirtualKeys.VK_RETURN:
										// Is an item currently selected
										if (_trackItem != -1)
										{
											DrawCommand dc = _drawCommands[_trackItem] as DrawCommand;

											// Does this item have a submenu?
											if (dc.SubMenu)
											{
												// Consume the keyboard message to prevent the submenu immediately
												// processing the same message again. Remember this routine is called
												// after PeekMessage but the message is still on the queue at this point
												Win32.MSG eat = new Win32.MSG();
												WindowsAPI.GetMessage(ref eat, 0, 0, 0);

												// Handle the submenu
												OperateSubMenu(_trackItem, false);

												// Do not attempt to pull a message off the queue as it has already
												// been eaten by us in the above code
												leaveMsg = true;
											}
											else
											{
												// Is this item the expansion command?
												if (dc.Expansion)
												{
													RegenerateExpansion();
												}
												else
												{
													// Define the selection to return to caller
													_returnCommand = dc.MenuCommand;

													// Finish processing messages
													_exitLoop = true;
												}
											}
										}
										break;
									case (int)Win32.VirtualKeys.VK_ESCAPE:
										// User wants to exit the menu, so set the flag to exit the message loop but
										// let the message get processed. This way the key press is thrown away.
										_exitLoop = true;
										break;
									default:
										// Any other key is treated as a possible mnemonic
										int selectItem = ProcessMnemonicKey((char)msg.wParam);

										if (selectItem != -1)
										{
											DrawCommand dc = _drawCommands[selectItem] as DrawCommand;

											// Define the selection to return to caller
											_returnCommand = dc.MenuCommand;

											// Finish processing messages
											_exitLoop = true;
										}
										break;
									}
								}
							}
						}

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

			// Do we have a focus we need to restore?
			if (_oldFocus != IntPtr.Zero)
				ReturnTheFocus();

			// Need to unset this window as the parent of the comboboxes
			// -- if any -- otherwise the combobox use in an toolbar would get "sick"
			UnsetComboBoxesParent();

			// Hide the window from view before killing it, as sometimes there is a
			// short delay between killing it and it disappearing because of the time
			// it takes for the destroy messages to get processed
			WindowsAPI.ShowWindow(this.Handle, (short)Win32.ShowWindowStyles.SW_HIDE);

			// Commit suicide
			DestroyHandle();

			// Was a command actually selected?
			if ((_parentMenu == null) && (_returnCommand != null))
			{
				// Pulse the selected event for the command
				_returnCommand.OnClick(EventArgs.Empty);
			}

			return _returnCommand;
		}
Beispiel #8
0
        protected MenuCommand InternalTrackPopup(bool selectFirst)
        {
            // MenuCommand to return as method result
            _returnCommand = null;

            // No item is being tracked
            _trackItem = -1;

            // Flag to indicate when to exit the message loop
            _exitLoop = false;

            // Assume the mouse does not start over our window
            _mouseOver = false;

            // Direction of key press if this caused dismissal
            _returnDir = 0;

            // Flag to indicate if the message should be dispatched
            bool leaveMsg = false;

            // First time a submenu is shown we pass in our value
            _animateFirst = true;

            // Create and show the popup window (without taking the focus)
            CreateAndShowWindow();

            // Create an object for storing windows message information
            Win32.MSG msg = new Win32.MSG();

            // Pretend user pressed key down to get the first valid item selected
            if (selectFirst)
                ProcessKeyDown();

            // Always use the arrow cursor
            User32.SetCursor(User32.LoadCursor(IntPtr.Zero, (uint)Win32.Cursors.IDC_ARROW));

            // Must hide caret so user thinks focus has changed
            bool hideCaret = User32.HideCaret(IntPtr.Zero);

            // Process messages until exit condition recognised
            while(!_exitLoop)
            {
                // Suspend thread until a windows message has arrived
                if (User32.WaitMessage())
                {
                    // Take a peek at the message details without removing from queue
                    while(!_exitLoop && User32.PeekMessage(ref msg, 0, 0, 0, (int)Win32.PeekMessageFlags.PM_NOREMOVE))
                    {
            //						Console.WriteLine("Track {0} {1}", this.Handle, ((Win32.Msgs)msg.message).ToString());

                        bool eatMessage = false;

                        int localWidth = _currentSize.Width - _position[(int)_style, (int)PI.ShadowWidth];
                        int localHeight = _currentSize.Height - _position[(int)_style, (int)PI.ShadowHeight];

                        // Mouse was pressed in a window of this application
                        if ((msg.message == (int)Win32.Msgs.WM_LBUTTONUP) ||
                            (msg.message == (int)Win32.Msgs.WM_MBUTTONUP) ||
                            (msg.message == (int)Win32.Msgs.WM_RBUTTONUP) ||
                            (msg.message == (int)Win32.Msgs.WM_XBUTTONUP) ||
                            (msg.message == (int)Win32.Msgs.WM_NCLBUTTONUP) ||
                            (msg.message == (int)Win32.Msgs.WM_NCMBUTTONUP) ||
                            (msg.message == (int)Win32.Msgs.WM_NCRBUTTONUP) ||
                            (msg.message == (int)Win32.Msgs.WM_NCXBUTTONUP))
                        {
                            Win32.POINT screenPos = MousePositionToScreen(msg);

                            // Is the POINT inside the Popup window rectangle
                            if ((screenPos.x >= _currentPoint.X) && (screenPos.x <= (_currentPoint.X + localWidth)) &&
                                (screenPos.y >= _currentPoint.Y) && (screenPos.y <= (_currentPoint.Y + localHeight)))
                            {
                                OnWM_YBUTTONUP(screenPos.x, screenPos.y);

                                // Eat the message to prevent the intended destination getting it
                                eatMessage = true;
                            }
                            else
                            {
                                PopupMenu target = ParentPopupMenuWantsMouseMessage(screenPos, ref msg);

                                // Let the parent chain of PopupMenu's decide if they want it
                                if (target != null)
                                {
                                    target.OnWM_YBUTTONUP(screenPos.x, screenPos.y);

                                    // Eat the message to prevent the intended destination getting it
                                    eatMessage = true;
                                }
                            }
                        }

                        // Mouse was pressed in a window of this application
                        if ((msg.message == (int)Win32.Msgs.WM_LBUTTONDOWN) ||
                            (msg.message == (int)Win32.Msgs.WM_MBUTTONDOWN) ||
                            (msg.message == (int)Win32.Msgs.WM_RBUTTONDOWN) ||
                            (msg.message == (int)Win32.Msgs.WM_XBUTTONDOWN) ||
                            (msg.message == (int)Win32.Msgs.WM_NCLBUTTONDOWN) ||
                            (msg.message == (int)Win32.Msgs.WM_NCMBUTTONDOWN) ||
                            (msg.message == (int)Win32.Msgs.WM_NCRBUTTONDOWN) ||
                            (msg.message == (int)Win32.Msgs.WM_NCXBUTTONDOWN))
                        {
                            Win32.POINT screenPos = MousePositionToScreen(msg);

                            // Is the POINT inside the Popup window rectangle
                            if ((screenPos.x >= _currentPoint.X) && (screenPos.x <= (_currentPoint.X + localWidth)) &&
                                (screenPos.y >= _currentPoint.Y) && (screenPos.y <= (_currentPoint.Y + localHeight)))
                            {
                                // Eat the message to prevent the intended destination getting it
                                eatMessage = true;
                            }
                            else
                            {
                                // Let the parent chain of PopupMenu's decide if they want it
                                if (ParentPopupMenuWantsMouseMessage(screenPos, ref msg) == null)
                                {
                                    if (ParentControlWantsMouseMessage(screenPos, ref msg))
                                    {
                                        // Let the MenuControl do its business
                                        _parentControl.OnWM_MOUSEDOWN(screenPos);

                                        // Eat the message to prevent the intended destination getting it
                                        eatMessage = true;
                                    }
                                    else
                                    {
                                        // 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;

                                        // Is a parent control specified?
                                        if (_parentControl != null)
                                        {
                                            // Is the mouse event destination the parent control?
                                            if (msg.hwnd == _parentControl.Handle)
                                            {
                                                // Then we want to consume the message so it does not get processed
                                                // by the parent control. Otherwise, pressing down will cause this
                                                // popup to disappear but the message will then get processed by
                                                // the parent and cause a popup to reappear again. When we actually
                                                // want the popup to disappear and nothing more.
                                                leaveMsg = false;
                                            }
                                        }
                                    }
                                }
                                else
                                {
                                    // Eat the message to prevent the intended destination getting it
                                    eatMessage = true;
                                }
                            }
                        }

                        // Mouse move occured
                        if (msg.message == (int)Win32.Msgs.WM_MOUSEMOVE)
                        {
                            Win32.POINT screenPos = MousePositionToScreen(msg);

                            // Is the POINT inside the Popup window rectangle
                            if ((screenPos.x >= _currentPoint.X) && (screenPos.x <= (_currentPoint.X + localWidth)) &&
                                (screenPos.y >= _currentPoint.Y) && (screenPos.y <= (_currentPoint.Y + localHeight)))
                            {
                                OnWM_MOUSEMOVE(screenPos.x, screenPos.y);
                            }
                            else
                            {
                                // Do we still think the mouse is over our window?
                                if (_mouseOver)
                                {
                                    // Process mouse leaving situation
                                    OnWM_MOUSELEAVE();
                                }

                                // Let the parent chain of PopupMenu's decide if they want it
                                PopupMenu target = ParentPopupMenuWantsMouseMessage(screenPos, ref msg);

                                if (target != null)
                                {
                                    // Let parent target process the message
                                    target.OnWM_MOUSEMOVE(screenPos.x, screenPos.y);
                                }
                                else
                                {
                                    if (ParentControlWantsMouseMessage(screenPos, ref msg))
                                    {
                                        // Let the MenuControl do its business
                                        _parentControl.OnWM_MOUSEMOVE(screenPos);
                                    }
                                }
                            }

                            // Eat the message to prevent the intended destination getting it
                            eatMessage = true;
                        }

                        if (msg.message == (int)Win32.Msgs.WM_SETCURSOR)
                        {
                            OnWM_SETCURSOR();

                            // Eat the message to prevent the intended destination getting it
                            eatMessage = true;
                        }

                        // Was the alt key pressed?
                        if (msg.message == (int)Win32.Msgs.WM_SYSKEYDOWN)
                        {
                            // Alt key pressed on its own
                            if((int)msg.wParam == (int)Win32.VirtualKeys.VK_MENU)	// ALT key
                            {
                                // Then we should dimiss ourself
                                _exitLoop = true;
                            }
                            else
                            {
                                // Pretend it is a normal keypress for processing
                                msg.message = (int)Win32.Msgs.WM_KEYDOWN;
                            }
                        }

                        // Was a non-alt key pressed?
                        if (msg.message == (int)Win32.Msgs.WM_KEYDOWN)
                        {
                            switch((int)msg.wParam)
                            {
                                case (int)Win32.VirtualKeys.VK_UP:
                                    ProcessKeyUp();
                                    break;
                                case (int)Win32.VirtualKeys.VK_DOWN:
                                    ProcessKeyDown();
                                    break;
                                case (int)Win32.VirtualKeys.VK_LEFT:
                                    ProcessKeyLeft();
                                    break;
                                case (int)Win32.VirtualKeys.VK_RIGHT:
                                    if(ProcessKeyRight())
                                    {
                                        // Do not attempt to pull a message off the queue as the
                                        // ProcessKeyRight has eaten the message for us
                                        leaveMsg = true;
                                    }
                                    break;
                                case (int)Win32.VirtualKeys.VK_RETURN:
                                    // Is an item currently selected
                                    if (_trackItem != -1)
                                    {
                                        DrawCommand dc = _drawCommands[_trackItem] as DrawCommand;

                                        // Does this item have a submenu?
                                        if (dc.SubMenu)
                                        {
                                            // Handle the submenu
                                            OperateSubMenu(_trackItem, false);

                                            // Do not attempt to pull a message off the queue as it has already
                                            // been eaten by us in the above code
                                            leaveMsg = true;
                                        }
                                        else
                                        {
                                            // Is this item the expansion command?
                                            if (dc.Expansion)
                                            {
                                                RegenerateExpansion();
                                            }
                                            else
                                            {
                                                // Define the selection to return to caller
                                                _returnCommand = dc.MenuCommand;

                                                // Finish processing messages
                                                _exitLoop = true;
                                            }
                                        }
                                    }
                                    break;
                                case (int)Win32.VirtualKeys.VK_ESCAPE:
                                    // User wants to exit the menu, so set the flag to exit the message loop but
                                    // let the message get processed. This way the key press is thrown away.
                                    _exitLoop = true;
                                    break;
                                default:
                                    // Any other key is treated as a possible mnemonic
                                    int selectItem = ProcessMnemonicKey((char)msg.wParam);

                                    if (selectItem != -1)
                                    {
                                        DrawCommand dc = _drawCommands[selectItem] as DrawCommand;

                                        // Define the selection to return to caller
                                        _returnCommand = dc.MenuCommand;

                                        // Finish processing messages
                                        _exitLoop = true;

                                        // Do not attempt to pull a message off the queue as it has already
                                        // been eaten by us in the above code
                                        leaveMsg = true;
                                    }
                                    break;
                            }
                        }

                        // We consume all keyboard input
                        if ((msg.message == (int)Win32.Msgs.WM_KEYDOWN) ||
                            (msg.message == (int)Win32.Msgs.WM_KEYUP) ||
                            (msg.message == (int)Win32.Msgs.WM_SYSKEYDOWN) ||
                            (msg.message == (int)Win32.Msgs.WM_SYSKEYUP))
                        {
                            // Eat the message to prevent the intended destination getting it
                            eatMessage = true;
                        }

                        // Should the message be eaten to prevent intended destination getting it?
                        if (eatMessage)
                        {
                            Win32.MSG eat = new Win32.MSG();
                            User32.GetMessage(ref eat, 0, 0, 0);
                        }
                        else
                        {
                            // Should the message we pulled from the queue?
                            if (!leaveMsg)
                            {
                                if (User32.GetMessage(ref msg, 0, 0, 0))
                                {
                                    User32.TranslateMessage(ref msg);
                                    User32.DispatchMessage(ref msg);
                                }
                            }
                            else
                                leaveMsg = false;
                        }
                    }
                }
            }

            // If caret was hidden then show it again now
            if (hideCaret)
                User32.ShowCaret(IntPtr.Zero);

            // Remove tracking of any item, this ensure 'Deselected' event is generated if required
            SwitchSelection(_trackItem, -1, false, false);

            // Hide the window from view before killing it, as sometimes there is a
            // short delay between killing it and it disappearing because of the time
            // it takes for the destroy messages to get processed
            HideMenuWindow();

            // Commit suicide
            DestroyHandle();

            // Was a command actually selected in a top level PopupMenu AND we
            // are not here at the request of a MenuControl
            if ((_parentMenu == null) && (_returnCommand != null) && (_parentControl == null))
            {
                // Pulse the selected event for the command
                _returnCommand.OnClick(EventArgs.Empty);
            }

            return _returnCommand;
        }
		/// <summary>
		/// Abort resetting if the user types anything, anywhere.
		/// Also sets the flag (if it returns true) to indicate the search WAS aborted.
		/// </summary>
		/// <returns></returns>
		private bool ShouldAbort()
		{
			Win32.MSG msg = new Win32.MSG();
			if (Win32.PeekMessage(ref msg, IntPtr.Zero, (uint)Win32.WinMsgs.WM_KEYDOWN, (uint)Win32.WinMsgs.WM_KEYDOWN,
				(uint)Win32.PeekFlags.PM_NOREMOVE))
			{
				m_fResetSearchAborted = true;
				if (m_resetTimer == null)
				{
					m_resetTimer = new System.Windows.Forms.Timer();
					m_resetTimer.Interval = 100; // try again in 1/10 second.
					m_resetTimer.Tick += new EventHandler(m_resetTimer_Tick);
					m_resetTimer.Start();
				}
				return true;
			}
			return false;
		}
Beispiel #10
0
        public override IntPtr Call16from32(Machine machine, bool hook, bool dlgproc, ref Win32.MSG msg32, ref Win16.MSG msg16, Func <uint> callback)
        {
            // Convert info
            var info32 = Marshal.PtrToStructure <Win32.MDINEXTMENU>(msg32.lParam);
            var info16 = info32.Convert();

            // Setup message
            msg16.wParam = msg32.lParam.Loword();
            msg16.lParam = machine.SysAlloc(info16);

            try
            {
                // Do it
                return(BitUtils.DWordToIntPtr(callback()));
            }
            finally
            {
                // Clean up
                machine.SysFree(msg16.lParam);
            }
        }
Beispiel #11
0
        public override IntPtr Call16from32(Machine machine, bool hook, bool dlgproc, ref Win32.MSG msg32, ref Win16.MSG msg16, Func <uint> callback)
        {
            var di32   = Marshal.PtrToStructure <Win32.DRAWITEMSTRUCT>(msg32.lParam);
            var di16   = di32.Convert();
            var saveSP = machine.sp;

            try
            {
                // NB: This needs to be on stack - Wordzap incorrectly uses near pointer from lParam and won't work
                //     if drawitemstruct is in a different segment (see red bar in Skill -> Handcap, comms options)
                var ptr = machine.StackAlloc(di16);
                msg16.wParam = (ushort)msg32.wParam.ToInt32();
                msg16.lParam = ptr;
                var retv = callback();
                return((IntPtr)retv);
            }
            finally
            {
                machine.sp = saveSP;
            }
        }
Beispiel #12
0
        public override uint Call32from16(Machine machine, bool hook, bool dlgproc, ref Win16.MSG msg16, ref Win32.MSG msg32, Func <IntPtr> callback)
        {
            var di16 = machine.ReadStruct <Win16.DRAWITEMSTRUCT>(msg16.lParam);

            unsafe
            {
                Win16.DRAWITEMSTRUCT *ptr = &di16;
                msg32.wParam = (IntPtr)msg16.wParam;
                msg32.lParam = (IntPtr)ptr;
                var retv = callback();
                return((uint)retv.ToInt32());
            }
        }