BOOL IMsoComponentManager.FRegisterComponent( IMsoComponent component, MSOCRINFO *pcrinfo, UIntPtr *pdwComponentID) { if (pcrinfo == null || pdwComponentID == null || pcrinfo->cbSize < sizeof(MSOCRINFO)) { return(BOOL.FALSE); } // Construct Hashtable entry for this component ComponentHashtableEntry entry = new ComponentHashtableEntry { component = component, componentInfo = *pcrinfo }; _cookieCounter += 1; OleComponents.Add(_cookieCounter, entry); // Return the cookie *pdwComponentID = _cookieCounter; Debug.WriteLineIf(CompModSwitches.MSOComponentManager.TraceInfo, $"ComponentManager: Component registered. ID: {_cookieCounter}"); return(BOOL.TRUE); }
/// <include file='doc\Application.uex' path='docs/doc[@for="Application.ComponentManager.UnsafeNativeMethods.IMsoComponentManager.FRegisterComponent"]/*' /> /// <devdoc> /// Register component piComponent and its registration info pcrinfo with /// this component manager. Return in *pdwComponentID a cookie which will /// identify the component when it calls other IMsoComponentManager /// methods. /// Return TRUE if successful, FALSE otherwise. /// </devdoc> bool UnsafeNativeMethods.IMsoComponentManager.FRegisterComponent(UnsafeNativeMethods.IMsoComponent component, NativeMethods.MSOCRINFOSTRUCT pcrinfo, out IntPtr dwComponentID) { // Construct Hashtable entry for this component // ComponentHashtableEntry entry = new ComponentHashtableEntry(); entry.component = component; entry.componentInfo = pcrinfo; OleComponents.Add(++cookieCounter, entry); // Return the cookie // dwComponentID = (IntPtr)cookieCounter; Debug.WriteLineIf(CompModSwitches.MSOComponentManager.TraceInfo, "ComponentManager: Component registered. ID: " + cookieCounter.ToString(CultureInfo.InvariantCulture)); return true; }
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); }
bool System.Windows.Forms.UnsafeNativeMethods.IMsoComponentManager.FRegisterComponent(System.Windows.Forms.UnsafeNativeMethods.IMsoComponent component, System.Windows.Forms.NativeMethods.MSOCRINFOSTRUCT pcrinfo, out IntPtr dwComponentID) { ComponentHashtableEntry entry = new ComponentHashtableEntry { component = component, componentInfo = pcrinfo }; this.OleComponents.Add(++this.cookieCounter, entry); dwComponentID = (IntPtr) this.cookieCounter; return true; }