【问题标题】:How to use WPF UserControls or Windows from inside Visual FoxPro 9如何在 Visual FoxPro 9 中使用 WPF 用户控件或 Windows
【发布时间】:2018-03-27 19:19:09
【问题描述】:

我有一个非常庞大且复杂的 Visual FoxPro 9 应用程序。我想在 WPF 中重写此应用程序的部分内容,最终目标是在几年后完成切割。我花了相当多的时间在 google 和 stackoverflow 上搜索端到端的“hello world”类型示例,以了解如何使用 COM 互操作实现这一点。找到了一些零碎的东西,但没有完整的显示 FoxPro 端和 WPF 端。

我的直觉告诉我,如果我尝试通过 COM Interop 运行 WPF 应用程序,我可能会遇到 XAML 资源、第三方控件或其他正常功能的问题。

所以,有两个问题。谁能指出我从 FoxPro 启动 WPF 窗口或让我在 FoxPro 窗体上删除 WPF 用户控件的端到端小示例?还是我对潜在互操作问题的担忧是正确的,应该完全避免这种情况?如果是这样,是否有推荐的方式让这两个可执行文件相互通信?

【问题讨论】:

  • 几年后,Windows 7 将被弃用,WPF 将随之弃用。如果你对 windows 没有问题,你应该看看一些更新的东西,也许是 Electron 或 UWP
  • 最近是否有来自 Microsoft 的资源说明了这一点,或者这只是您的意见?
  • 这是一个非常大非常复杂的问题。我完全按照你的要求做了。这里有一些资源:west-wind.com/presentations/VfpDotNetInterop/DotNetFromVFP.aspcodemag.com/Article/0703112 ; west-wind.com/presentations/dotnetfromVfp/… ; stackoverflow.com/questions/2186829/… 。我还可以告诉您,我在使用 WPF 类应用程序时遇到了问题。如果你有耐心,我可以给你写我的研究案例。
  • 我不对 WPF 的未来发表评论。但无论如何,这是一个特定于 MS 的东西。在 VFP 之后,您还会冒着再次信任 MS 的风险吗?这是一件事,另一件事是,我会远离 COM(又是一个特定于平台的事情)。我和你处于同样的位置,做了一些你过去描述的事情,并且永远不会再走那条路(即 COM 和 Silverlight - SL 是另一个展示 MS 可信赖性的示例)。也许您应该期待使用 REST、micro、gRPC ... 数据服务和基于 HTML 的 UI 界面(Qt 是另一个不错的跨平台 UI 选项)
  • 我必须坚持使用可以与 foxpro 应用程序尽可能紧密集成的技术。完全重写它需要近 50 万美元的开发成本,而所有权不会这样做。一次做一点是我现在最好的选择,这会留下 WPF。找到了一些用于启动进程并监控它们是否仍在运行的代码示例。所以,我可能会采用某种双进程实现,让 foxpro 和 wpf 应用程序能够通信。

标签: wpf visual-foxpro


【解决方案1】:

我完全不知道您是否可以在可视 FoxPro 中运行 wpf。我猜你必须把它写成一个activex。 我最近做了一些扩展 MS Access 应用程序的工作。 我的 wpf 应用程序是完全独立的,并与 ms access 应用程序一起运行。 我使用 MS Message Queue(这是一个 com 组件)在两者之间进行通信。 也许这种方法对你有用。

当我想通过访问在 wpf 中显示一个屏幕时,我在本地消息队列中添加了一段 xml。 wpf 应用程序侦听这些消息,将它们转换为对象,这些对象告诉它要显示哪个屏幕并为其提供任何参数。 MS Access 订阅消息队列中收到的消息事件,这样它就可以知道 wpf 窗口何时关闭以及用户何时完成。 这是为了使用扼杀者模式来逐步替换旧访问应用程序中的功能。

这里有一些用于驱动一切的队列监听器的代码。各种 pop 类从消息中反序列化,我将其构建为访问中的字符串。

internal class QueueListener
{
    public const string qFromMadge = @".\private$\XXXXQ";
    public static string qToMadge = @".\private$\XXXXReturnQ";
    private MessageQueue mq;
    internal QueueListener()
    {
        try
        {
            SystemEvents.SessionSwitch += SystemEvents_SessionSwitch;
            SubscribeHandler();

            var mqSend = setUpQueue(qToMadge);
            mqSend.Close();
        }
        catch (Exception ex)
        {
            MessageBox.Show(ex.InnerException.Message);
        }
    }
    private MessageQueue setUpQueue(string qName)
    {
        MessageQueue q;
        if (MessageQueue.Exists(qName))
        {
            q = new MessageQueue(qName);
        }
        else
        {
            q = MessageQueue.Create(qName);
        }
        q.ResetPermissions();
        q.SetPermissions("Everyone", MessageQueueAccessRights.FullControl, AccessControlEntryType.Set);
        q.Purge();
        return q;
    }
    private void ReceiveMsgCompleted(Object source, ReceiveCompletedEventArgs asyncResult)
    {
        MessageQueue mq = (MessageQueue)source;
        Message m = mq.EndReceive(asyncResult.AsyncResult);
        m.Formatter = new XmlMessageFormatter(new[] { "XXXX.Popaaaa, XXXX"
                                                    , "XXXX.Popbbbb, XXXXX"
                                                    , "XXXX.Popcccc, XXXX"
                                                    , "XXXX.Popdddd, XXXX"
        });

        ((BasePopView) m.Body).Pop();

        mq.BeginReceive();
    }

    public  void UnsubscribeHandler()
    {
        if (mq == null)
        {
            return;
        }
        mq.Close();
        mq.ReceiveCompleted -= new ReceiveCompletedEventHandler(ReceiveMsgCompleted);
        mq = null;
    }
    public  void SubscribeHandler()
    {
        if(mq != null)
        {
            return;
        }
        mq = setUpQueue(qFromMadge);
        mq.ReceiveCompleted += ReceiveMsgCompleted;
        mq.BeginReceive();
    } 

【讨论】:

猜你喜欢
  • 1970-01-01
  • 2011-10-14
  • 1970-01-01
  • 1970-01-01
  • 2011-02-21
  • 1970-01-01
  • 1970-01-01
  • 2018-07-31
  • 1970-01-01
相关资源
最近更新 更多