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