找回密码
 立即注册

QQ登录

只需一步,快速开始

sun.yh

最新发帖
sun.yh
注册会员   /  发表于:2021-1-19 11:38:45
41#
怕你们误解,特地在9-12楼说了一下.net消息帧

.net开环OK,当然OK,开始就说了开环是OK的
回复 使用道具 举报
sun.yh
注册会员   /  发表于:2021-1-19 11:53:57
42#
注意,也不要把.net消息帧插到宿主里面。因为原码是场景模拟。真实的消息环是封装的,没有源码的
回复 使用道具 举报
sun.yh
注册会员   /  发表于:2021-1-19 11:55:47
43#
响应必须是win32可翻译的消息。  我们看不到AR源码,所以不知道AR是否使用了.net特有消息
回复 使用道具 举报
KearneyKang讲师达人认证 悬赏达人认证
超级版主   /  发表于:2021-1-19 12:09:35
44#
本帖最后由 KearneyKang 于 2021-1-19 12:22 编辑

目前给的办法是这样,跟研发沟通后,他们给的就是当前的这个解决办法。但是我已经就你说的C++消息环的问题也在同时跟他们进行沟通,看看有么有其他的方式解决
回复 使用道具 举报
sun.yh
注册会员   /  发表于:2021-1-20 21:02:39
45#
问题发出的时候就说了.net消息环的是没有问题的。你这发回来告诉我加上.net消息环就OK了
还告诉我这个问题就这么处理,这样做不好吧
回复 使用道具 举报
Lenka.Guo讲师达人认证 悬赏达人认证
超级版主   /  发表于:2021-1-21 13:39:26
46#
本帖最后由 Lenka.Guo 于 2021-1-21 13:44 编辑

您好,
因为你的使用方法比较特殊,C++引用Winform 项目。但Winform 机制项目的消息循环只能有一个,也因为您的用法比较特殊,我们和研发同事进行了沟通,主要是集中在C++ 调用Winform项目的消息循环如何处理的问题。我们也跟多名资深的.net 开发工程师沟通,在C++中重写Windows 消息循环是非常复杂的,很难做到。


参考资料
https://referencesource.microsoft.com/#WindowsBase/Base/System/Windows/Threading/Dispatcher.cs,2471





本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有帐号?立即注册

x
回复 使用道具 举报
sun.yh
注册会员   /  发表于:2021-1-21 15:15:25
47#
我跟踪到,改用这个Dispatcher.PushFrame(new DispatcherFrame())也是解决不了问题的。
回复 使用道具 举报
sun.yh
注册会员   /  发表于:2021-1-21 15:16:29
48#
需要使用:UnsafeNativeMethods.IMsoComponentManager.FPushMessageLoop
回复 使用道具 举报
sun.yh
注册会员   /  发表于:2021-1-21 15:21:36
49#
我通过一步一步向前推,找到了private void RunMessageLoopInner(int reason, ApplicationContext context),是可以的。
进一步前推到UnsafeNativeMethods.IMsoComponentManager.FPushMessageLoop
这个方法的第一个参数一值搞不定
那么就请帮忙看一下,这个消息环哪些代码会与问题有关
回复 使用道具 举报
sun.yh
注册会员   /  发表于:2021-1-21 15:22:26
50#
bool UnsafeNativeMethods.IMsoComponentManager.FPushMessageLoop(
                                                      IntPtr dwComponentID,
                                                      int reason,
                                                      int pvLoopData          // PVOID
                                                      ) {

                int dwLocalComponentID = unchecked((int)(long)dwComponentID);
                // Hold onto old state to allow restore before we exit...
                //
                int currentLoopState = currentState;
                bool continueLoop = true;

                if (!OleComponents.ContainsKey(dwLocalComponentID)) {
                    return false;
                }

                UnsafeNativeMethods.IMsoComponent prevActive = this.activeComponent;

                try {
                    // Execute the message loop until the active component tells us to stop.
                    //
                    NativeMethods.MSG msg = new NativeMethods.MSG();
                    NativeMethods.MSG[] rgmsg = new NativeMethods.MSG[] {msg};
                    bool unicodeWindow = false;
                    UnsafeNativeMethods.IMsoComponent requestingComponent;

                    ComponentHashtableEntry entry = (ComponentHashtableEntry)OleComponents[dwLocalComponentID];
                    if (entry == null) {
                        return false;
                    }



                    requestingComponent = entry.component;

                    this.activeComponent = requestingComponent;

                    Debug.WriteLineIf(CompModSwitches.MSOComponentManager.TraceInfo, "ComponentManager : Pushing message loop " + reason.ToString(CultureInfo.InvariantCulture));
                    Debug.Indent();

                    while (continueLoop) {

                        // Determine the component to route the message to
                        //
                        UnsafeNativeMethods.IMsoComponent component;

                        if (trackingComponent != null) {
                            component = trackingComponent;
                        }
                        else if (activeComponent != null) {
                            component = activeComponent;
                        }
                        else {
                            component = requestingComponent;
                        }

                        bool peeked = UnsafeNativeMethods.PeekMessage(ref msg, NativeMethods.NullHandleRef, 0, 0, NativeMethods.PM_NOREMOVE);

                        if (peeked) {

                            rgmsg[0] = msg;
                            continueLoop = component.FContinueMessageLoop(reason, pvLoopData, rgmsg);

                            // If the component wants us to process the message, do it.
                            // The component manager hosts windows from many places.  We must be sensitive
                            // to ansi / Unicode windows here.
                            //
                            if (continueLoop) {
                                if (msg.hwnd != IntPtr.Zero && SafeNativeMethods.IsWindowUnicode(new HandleRef(null, msg.hwnd))) {
                                    unicodeWindow = true;
                                    UnsafeNativeMethods.GetMessageW(ref msg, NativeMethods.NullHandleRef, 0, 0);
                                }
                                else {
                                    unicodeWindow = false;
                                    UnsafeNativeMethods.GetMessageA(ref msg, NativeMethods.NullHandleRef, 0, 0);
                                }

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

                                    Application.ThreadContext.FromCurrent().DisposeThreadWindows();

                                    if (reason != NativeMethods.MSOCM.msoloopMain) {
                                        UnsafeNativeMethods.PostQuitMessage((int)msg.wParam);
                                    }

                                    continueLoop = 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.  But frankly, I'm afraid of what that might break.
                                // See ASURT 29415 for more background.
                                if (!component.FPreTranslateMessage(ref msg)) {
                                    UnsafeNativeMethods.TranslateMessage(ref msg);
                                    if (unicodeWindow) {
                                        UnsafeNativeMethods.DispatchMessageW(ref msg);
                                    }
                                    else {
                                        UnsafeNativeMethods.DispatchMessageA(ref msg);
                                    }
                                }
                            }
                        }
                        else {

                            // If this is a DoEvents loop, then get out.  There's nothing left
                            // for us to do.
                            //
                            if (reason == NativeMethods.MSOCM.msoloopDoEvents ||
                                reason == NativeMethods.MSOCM.msoloopDoEventsModal) {
                                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(-1);
                                }
                            }

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

                            if (continueLoop) {
                                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 ----
                                    // the CPU.  For Windows Forms this generally isn't an issue because
                                    // our component always returns false from its idle request
                                    UnsafeNativeMethods.MsgWaitForMultipleObjectsEx(0, IntPtr.Zero, 100, NativeMethods.QS_ALLINPUT, NativeMethods.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 (!UnsafeNativeMethods.PeekMessage(ref msg, NativeMethods.NullHandleRef, 0, 0, NativeMethods.PM_NOREMOVE)) {
                                        UnsafeNativeMethods.WaitMessage();
                                    }
                                }
                            }
                        }
                    }

                    Debug.Unindent();
                    Debug.WriteLineIf(CompModSwitches.MSOComponentManager.TraceInfo, "ComponentManager : message loop " + reason.ToString(CultureInfo.InvariantCulture) + " complete.");
                }
                finally {
                    currentState = currentLoopState;
                    this.activeComponent = prevActive;
                }

                return !continueLoop;
            }
回复 使用道具 举报
您需要登录后才可以回帖 登录 | 立即注册
返回顶部