示例#1
0
        private unsafe void OnShouldSerializeValue(Com2PropertyDescriptor sender, GetBoolValueEvent gbvevent)
        {
            if (sender.TargetObject is VSSDK.IVsPerPropertyBrowsing vsObj)
            {
                // by default we say it's default
                BOOL    pfResult = BOOL.TRUE;
                HRESULT hr       = vsObj.HasDefaultValue(sender.DISPID, &pfResult);
                if (hr == HRESULT.S_OK && pfResult.IsFalse())
                {
                    // specify a default value editor
                    gbvevent.Value = true;
                }
            }

            Debug.Assert(sender.TargetObject is null || sender.TargetObject is VSSDK.IVsPerPropertyBrowsing, "Object is not " + Interface.Name + "!");
        }
            BOOL IMsoComponentManager.FPushMessageLoop(
                UIntPtr dwComponentID,
                msoloop uReason,
                void *pvLoopData)
            {
                // Hold onto old state to allow restore before we exit...
                msocstate currentLoopState = _currentState;
                BOOL      continueLoop     = BOOL.TRUE;

                if (!OleComponents.TryGetValue(dwComponentID, out ComponentHashtableEntry entry))
                {
                    return(BOOL.FALSE);
                }

                IMsoComponent prevActive = _activeComponent;

                try
                {
                    User32.MSG    msg = new User32.MSG();
                    IMsoComponent requestingComponent = entry.component;
                    _activeComponent = requestingComponent;

                    Debug.WriteLineIf(
                        CompModSwitches.MSOComponentManager.TraceInfo,
                        $"ComponentManager : Pushing message loop {uReason}");
                    Debug.Indent();

                    while (continueLoop.IsTrue())
                    {
                        // Determine the component to route the message to
                        IMsoComponent component = _trackingComponent ?? _activeComponent ?? requestingComponent;

                        bool useAnsi = false;
                        BOOL peeked  = User32.PeekMessageW(ref msg);

                        if (peeked.IsTrue())
                        {
                            useAnsi = msg.hwnd != IntPtr.Zero && User32.IsWindowUnicode(msg.hwnd).IsFalse();
                            if (useAnsi)
                            {
                                peeked = User32.PeekMessageA(ref msg);
                            }
                        }

                        if (peeked.IsTrue())
                        {
                            continueLoop = component.FContinueMessageLoop(uReason, pvLoopData, &msg);

                            // If the component wants us to process the message, do it.
                            if (continueLoop.IsTrue())
                            {
                                if (useAnsi)
                                {
                                    User32.GetMessageA(ref msg);
                                    Debug.Assert(User32.IsWindowUnicode(msg.hwnd).IsFalse());
                                }
                                else
                                {
                                    User32.GetMessageW(ref msg);
                                    Debug.Assert(msg.hwnd == IntPtr.Zero || User32.IsWindowUnicode(msg.hwnd).IsTrue());
                                }

                                if (msg.message == User32.WM.QUIT)
                                {
                                    Debug.WriteLineIf(
                                        CompModSwitches.MSOComponentManager.TraceInfo,
                                        "ComponentManager : Normal message loop termination");

                                    ThreadContext.FromCurrent().DisposeThreadWindows();

                                    if (uReason != msoloop.Main)
                                    {
                                        User32.PostQuitMessage((int)msg.wParam);
                                    }

                                    continueLoop = BOOL.FALSE;
                                    break;
                                }

                                // Now translate and dispatch the message.
                                //
                                // Reading through the rather sparse documentation,
                                // it seems we should only call FPreTranslateMessage
                                // on the active component.
                                if (component.FPreTranslateMessage(&msg).IsFalse())
                                {
                                    User32.TranslateMessage(ref msg);
                                    if (useAnsi)
                                    {
                                        User32.DispatchMessageA(ref msg);
                                    }
                                    else
                                    {
                                        User32.DispatchMessageW(ref msg);
                                    }
                                }
                            }
                        }
                        else
                        {
                            // If this is a DoEvents loop, then get out. There's nothing left for us to do.
                            if (uReason == msoloop.DoEvents || uReason == msoloop.DoEventsModal)
                            {
                                break;
                            }

                            // Nothing is on the message queue. Perform idle processing and then do a WaitMessage.
                            bool continueIdle = false;

                            if (OleComponents != null)
                            {
                                IEnumerator enumerator = OleComponents.Values.GetEnumerator();

                                while (enumerator.MoveNext())
                                {
                                    ComponentHashtableEntry idleEntry = (ComponentHashtableEntry)enumerator.Current;
                                    continueIdle |= idleEntry.component.FDoIdle(msoidlef.All).IsTrue();
                                }
                            }

                            // Give the component one more chance to terminate the message loop.
                            continueLoop = component.FContinueMessageLoop(uReason, pvLoopData, null);

                            if (continueLoop.IsTrue())
                            {
                                if (continueIdle)
                                {
                                    // If someone has asked for idle time, give it to them.  However,
                                    // don't cycle immediately; wait up to 100ms.  Why?  Because we don't
                                    // want someone to attach to idle, forget to detach, and then cause
                                    // CPU to end up in race condition.  For Windows Forms this generally isn't an issue because
                                    // our component always returns false from its idle request
                                    User32.MsgWaitForMultipleObjectsEx(0, IntPtr.Zero, 100, User32.QS.ALLINPUT, User32.MWMO.INPUTAVAILABLE);
                                }
                                else
                                {
                                    // We should call GetMessage here, but we cannot because
                                    // the component manager requires that we notify the
                                    // active component before we pull the message off the
                                    // queue.  This is a bit of a problem, because WaitMessage
                                    // waits for a NEW message to appear on the queue.  If a
                                    // message appeared between processing and now WaitMessage
                                    // would wait for the next message.  We minimize this here
                                    // by calling PeekMessage.
                                    if (User32.PeekMessageW(ref msg, IntPtr.Zero, 0, 0, User32.PM.NOREMOVE).IsFalse())
                                    {
                                        User32.WaitMessage();
                                    }
                                }
                            }
                        }
                    }

                    Debug.Unindent();
                    Debug.WriteLineIf(CompModSwitches.MSOComponentManager.TraceInfo, $"ComponentManager : message loop {uReason} complete.");
                }
                finally
                {
                    _currentState    = currentLoopState;
                    _activeComponent = prevActive;
                }

                return(continueLoop.IsFalse() ? BOOL.TRUE : BOOL.FALSE);
            }
            protected unsafe override IntPtr HookProc(IntPtr hwnd, int msg, IntPtr wParam, IntPtr lParam)
            {
                switch ((User32.WM)msg)
                {
                case User32.WM.INITDIALOG:
                    User32.SendDlgItemMessageW(
                        hwnd,
                        (User32.DialogItemID)Comdlg32.COLOR.HUE,
                        (User32.WM)User32.EM.SETMARGINS,
                        (IntPtr)(User32.EC.LEFTMARGIN | User32.EC.RIGHTMARGIN));
                    User32.SendDlgItemMessageW(
                        hwnd,
                        (User32.DialogItemID)Comdlg32.COLOR.SAT,
                        (User32.WM)User32.EM.SETMARGINS,
                        (IntPtr)(User32.EC.LEFTMARGIN | User32.EC.RIGHTMARGIN));
                    User32.SendDlgItemMessageW(
                        hwnd,
                        (User32.DialogItemID)Comdlg32.COLOR.LUM,
                        (User32.WM)User32.EM.SETMARGINS,
                        (IntPtr)(User32.EC.LEFTMARGIN | User32.EC.RIGHTMARGIN));
                    User32.SendDlgItemMessageW(
                        hwnd,
                        (User32.DialogItemID)Comdlg32.COLOR.RED,
                        (User32.WM)User32.EM.SETMARGINS,
                        (IntPtr)(User32.EC.LEFTMARGIN | User32.EC.RIGHTMARGIN));
                    User32.SendDlgItemMessageW(
                        hwnd,
                        (User32.DialogItemID)Comdlg32.COLOR.GREEN,
                        (User32.WM)User32.EM.SETMARGINS,
                        (IntPtr)(User32.EC.LEFTMARGIN | User32.EC.RIGHTMARGIN));
                    User32.SendDlgItemMessageW(
                        hwnd,
                        (User32.DialogItemID)Comdlg32.COLOR.BLUE,
                        (User32.WM)User32.EM.SETMARGINS,
                        (IntPtr)(User32.EC.LEFTMARGIN | User32.EC.RIGHTMARGIN));
                    IntPtr hwndCtl = User32.GetDlgItem(hwnd, (User32.DialogItemID)Comdlg32.COLOR.MIX);
                    User32.EnableWindow(hwndCtl, BOOL.FALSE);
                    User32.SetWindowPos(
                        hwndCtl,
                        User32.HWND_TOP,
                        flags: User32.SWP.HIDEWINDOW);
                    hwndCtl = User32.GetDlgItem(hwnd, (User32.DialogItemID)User32.ID.OK);
                    User32.EnableWindow(hwndCtl, BOOL.FALSE);
                    User32.SetWindowPos(
                        hwndCtl,
                        User32.HWND_TOP,
                        flags: User32.SWP.HIDEWINDOW);
                    Color = Color.Empty;
                    break;

                case User32.WM.COMMAND:
                    if (PARAM.LOWORD(wParam) == (int)Comdlg32.COLOR.ADD)
                    {
                        BOOL success = BOOL.FALSE;
                        byte red     = (byte)User32.GetDlgItemInt(hwnd, (int)Comdlg32.COLOR.RED, &success, BOOL.FALSE);
                        Debug.Assert(success.IsFalse(), "Couldn't find dialog member COLOR_RED");

                        byte green = (byte)User32.GetDlgItemInt(hwnd, (int)Comdlg32.COLOR.GREEN, &success, BOOL.FALSE);
                        Debug.Assert(success.IsFalse(), "Couldn't find dialog member COLOR_GREEN");

                        byte blue = (byte)User32.GetDlgItemInt(hwnd, (int)Comdlg32.COLOR.BLUE, &success, BOOL.FALSE);
                        Debug.Assert(success.IsFalse(), "Couldn't find dialog member COLOR_BLUE");

                        Color = Color.FromArgb(red, green, blue);
                        User32.PostMessageW(
                            hwnd,
                            User32.WM.COMMAND,
                            PARAM.FromLowHigh((int)User32.ID.OK, 0),
                            User32.GetDlgItem(hwnd, (User32.DialogItemID)User32.ID.OK));
                        break;
                    }

                    break;
                }

                return(base.HookProc(hwnd, msg, wParam, lParam));
            }
示例#4
0
            public unsafe HRESULT GetDragDropEffect(BOOL fDrag, User32.MK grfKeyState, Ole32.DROPEFFECT *pdwEffect)
            {
                if (pdwEffect is null)
                {
                    return(HRESULT.E_POINTER);
                }

                Debug.WriteLineIf(RichTextDbg.TraceVerbose, "IRichEditOleCallback::GetDragDropEffect");

                if (owner.AllowDrop || owner.EnableAutoDragDrop)
                {
                    if (fDrag.IsTrue() && grfKeyState == (User32.MK) 0)
                    {
                        // This is the very first call we receive in a Drag-Drop operation,
                        // so we will let the control know what we support.

                        // Note that we haven't gotten any data yet, so we will let QueryAcceptData
                        // do the OnDragEnter. Note too, that grfKeyState does not yet reflect the
                        // current keystate
                        if (owner.EnableAutoDragDrop)
                        {
                            lastEffect = (DragDropEffects.All | DragDropEffects.None);
                        }
                        else
                        {
                            lastEffect = DragDropEffects.None;
                        }
                    }
                    else
                    {
                        // We are either dragging over or dropping

                        // The below is the complete reverse of what the docs on MSDN suggest,
                        // but if we follow the docs, we would be firing OnDragDrop all the
                        // time instead of OnDragOver (see

                        // drag - fDrag = false, grfKeyState != 0
                        // drop - fDrag = false, grfKeyState = 0
                        // We only care about the drag.
                        //
                        // When we drop, lastEffect will have the right state
                        if (fDrag.IsFalse() && lastDataObject is not null && grfKeyState != (User32.MK) 0)
                        {
                            DragEventArgs e = new DragEventArgs(lastDataObject,
                                                                (int)grfKeyState,
                                                                Control.MousePosition.X,
                                                                Control.MousePosition.Y,
                                                                DragDropEffects.All,
                                                                lastEffect);

                            // Now tell which of the allowable effects we want to use, but only if we are not already none
                            if (lastEffect != DragDropEffects.None)
                            {
                                e.Effect = ((grfKeyState & User32.MK.CONTROL) == User32.MK.CONTROL) ? DragDropEffects.Copy : DragDropEffects.Move;
                            }

                            owner.OnDragOver(e);
                            lastEffect = e.Effect;
                        }
                    }

                    *pdwEffect = (Ole32.DROPEFFECT)lastEffect;
                }
                else
                {
                    *pdwEffect = Ole32.DROPEFFECT.NONE;
                }

                return(HRESULT.S_OK);
            }