sun.yh 发表于 2021-1-19 11:38:45

怕你们误解,特地在9-12楼说了一下.net消息帧

.net开环OK,当然OK,开始就说了开环是OK的

sun.yh 发表于 2021-1-19 11:53:57

注意,也不要把.net消息帧插到宿主里面。因为原码是场景模拟。真实的消息环是封装的,没有源码的

sun.yh 发表于 2021-1-19 11:55:47

响应必须是win32可翻译的消息。我们看不到AR源码,所以不知道AR是否使用了.net特有消息

KearneyKang 发表于 2021-1-19 12:09:35

本帖最后由 KearneyKang 于 2021-1-19 12:22 编辑

目前给的办法是这样,跟研发沟通后,他们给的就是当前的这个解决办法。但是我已经就你说的C++消息环的问题也在同时跟他们进行沟通,看看有么有其他的方式解决

sun.yh 发表于 2021-1-20 21:02:39

问题发出的时候就说了.net消息环的是没有问题的。你这发回来告诉我加上.net消息环就OK了
还告诉我这个问题就这么处理,这样做不好吧

Lenka.Guo 发表于 2021-1-21 13:39:26

本帖最后由 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





sun.yh 发表于 2021-1-21 15:15:25

我跟踪到,改用这个Dispatcher.PushFrame(new DispatcherFrame())也是解决不了问题的。

sun.yh 发表于 2021-1-21 15:16:29

需要使用:UnsafeNativeMethods.IMsoComponentManager.FPushMessageLoop

sun.yh 发表于 2021-1-21 15:21:36

我通过一步一步向前推,找到了private void RunMessageLoopInner(int reason, ApplicationContext context),是可以的。
进一步前推到UnsafeNativeMethods.IMsoComponentManager.FPushMessageLoop
这个方法的第一个参数一值搞不定
那么就请帮忙看一下,这个消息环哪些代码会与问题有关

sun.yh 发表于 2021-1-21 15:22:26

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;
                  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 = 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;
            }
页: 1 2 3 4 [5] 6 7
查看完整版本: AR非Application.Run打开的,工具栏状态不会同步