zoukankan      html  css  js  c++  java
  • wpf中嵌入另一个子进程exe像本地的一个页面那样

      1 //新的一个子进程浏览器
      2 private void OpenNewWebBrowser(string webBrowserName, string url)
      3 {
      4 IntPtr targetPtr = this.CreateWebProcess();
      5 
      6 IntPtr pagePtr = this.GetOrAddNewPage(webBrowserName, url);
      7 
      8 lock (_lockObj)
      9 {
     10 _webBrowserPtr.Add(webBrowserName, targetPtr);
     11 }
     12 
     13 this.SetWebBrowserLoc(webBrowserName, pagePtr);
     14 
     15 this.SendParam(webBrowserName, url);
     16 }
     17 
     18 
     19 //创建一个新的webbrowser进程
     20 private IntPtr CreateWebProcess()
     21 {
     22 ProcessStartInfo psi = new ProcessStartInfo(_webBrowserStartPath);
     23 psi.WindowStyle = ProcessWindowStyle.Hidden;
     24 var process = Process.Start(psi);
     25 IntPtr targetPtr = IntPtr.Zero;
     26 while (targetPtr == IntPtr.Zero) //循环目标窗口启动完成
     27 {
     28 targetPtr = process.MainWindowHandle;
     29 if (targetPtr != IntPtr.Zero)
     30 {
     31 break;
     32 }
     33 Thread.Sleep(10);
     34 }
     35 return targetPtr;
     36 }
     37 
     38 private IntPtr GetOrAddNewPage(string webBrowserName, string url)
     39         {
     40            // if (!_urlAndPanelPtr.ContainsKey(url))
     41             {
     42                 System.Windows.Forms.Panel p = new System.Windows.Forms.Panel();
     43                 WindowsFormsHost host = new WindowsFormsHost();
     44                 host.Tag = webBrowserName;
     45                 host.Background = Brushes.Transparent;
     46                 host.Child = p;
     47 
     48                 host.Visibility = System.Windows.Visibility.Visible;
     49                 _webContainer.Children.Add(host);
     50 
     51               //  lock (_lockObj)
     52                //     _urlAndPanelPtr.Add(url, p.Handle);
     53                 return p.Handle;// 允许一个地址打开多个
     54             }
     55            // return _urlAndPanelPtr[url];
     56         }
     57 
     58  //设置浏览器位置
     59         private void SetWebBrowserLoc(string webBrowserName, IntPtr pagePtr)
     60         {
     61             if (!_webBrowserPtr.ContainsKey(webBrowserName))
     62                 return;
     63 
     64             IntPtr webBrowserPtr = _webBrowserPtr[webBrowserName];
     65 
     66             double h = _webContainer.ActualHeight;
     67 
     68             double w = _webContainer.ActualWidth;
     69 
     70             IntPtr preParentHandle=  Win32Helper.SetParent(webBrowserPtr, pagePtr);
     71 
     72             //如果设置父窗体失败,则重试5次
     73             int tryNum = 5;
     74             while(preParentHandle==IntPtr.Zero)
     75             {
     76                 Thread.Sleep(10);
     77 
     78                 preParentHandle = Win32Helper.SetParent(webBrowserPtr, pagePtr);
     79 
     80                 if (tryNum <= 0) break;
     81 
     82                 tryNum--;
     83             }
     84 
     85             bool moveResult= Win32Helper.MoveWindow(webBrowserPtr, 0, 0, (int)w, (int)h, true);
     86 
     87             //如果窗体位置移动失败,则尝试5次
     88             tryNum = 5;
     89             while(!moveResult)
     90             {
     91                 Thread.Sleep(10);
     92                 moveResult = Win32Helper.MoveWindow(webBrowserPtr, 0, 0, (int)w, (int)h, true);
     93                 if (tryNum <= 0) break;
     94 
     95                 tryNum--;
     96             }
     97         }
     98 
     99 
    100 
    101 
    102 
    103 
    104 
    105  public class WebEmbedHelper: IWebEmbedHelper
    106     {
    107         string _isNeedReflesh = "0";//是否需要刷新url页面
    108         readonly Grid _webContainer = null;
    109         /// <summary>
    110         /// webbrowser容器句柄
    111         /// </summary>
    112         readonly IntPtr _parentIntPrt;
    113         static Dictionary<string, IntPtr> _urlAndPanelPtr = new Dictionary<string, IntPtr>();//url- panel句柄
    114         static Dictionary<string, IntPtr> _webBrowserPtr = new Dictionary<string, IntPtr>();//名称 - webbrowser窗体句柄
    115         static Dictionary<string, IntPtr> _urlAndBroserPrt = new Dictionary<string, IntPtr>();//url -webbrowser窗体句柄
    116         //url - 回调函数
    117         static Dictionary<string, Action<string, string>> _msgCallBackDic = new Dictionary<string, Action<string, string>>();
    118         readonly string _webBrowserStartPath;
    119 
    120          string _currentOpenUrl;//当前打开的url页面
    121          IntPtr _webProcessPtr;//当前的WebBrowser进程句柄
    122          bool _isChrome = false;
    123         public  IntPtr WebProcessPtr
    124          {
    125             get
    126              {
    127                  return _webProcessPtr;
    128              }
    129             set
    130              {
    131                  _webProcessPtr = value;
    132              }
    133          }
    134         public Action<int, object> GetWinAction { get; set; }//获取主客户端进程消息的action
    135 
    136         static object _lockObj = new object();
    137 
    138         /// <summary>
    139         /// WebBrowser构造函数
    140         /// </summary>
    141         /// <param name="parentIntPrt">WebBrowser容器父窗体句柄</param>
    142         /// <param name="grid">用于装载WebBrowser的容器</param>
    143         /// <param name="webBrowserStartPath">WebBrowser启动完整路径</param>
    144         public WebEmbedHelper(IntPtr parentIntPrt, Grid grid, string webBrowserStartPath)
    145         {
    146             _parentIntPrt = parentIntPrt;
    147             _webContainer = grid;
    148             _webBrowserStartPath = webBrowserStartPath;
    149 
    150             this.GetWinAction = ReceiveWinMsg;
    151 
    152             _webContainer.SizeChanged += webContainer_SizeChanged;
    153         }
    154 
    155         //窗体大小变更,对应的页面也应该自适应
    156         private void webContainer_SizeChanged(object sender, System.Windows.SizeChangedEventArgs e)
    157         {
    158             double w = _webContainer.ActualWidth;
    159             double h = _webContainer.ActualHeight;
    160             foreach (var itm in _webBrowserPtr)
    161             {
    162                 Win32Helper.MoveWindow(itm.Value, 0, 0, (int)w, (int)h, true);
    163             }
    164         }
    165 
    166         #region//打开web相关的私有方法
    167         private IntPtr GetOrAddNewPage(string webBrowserName, string url)
    168         {
    169            // if (!_urlAndPanelPtr.ContainsKey(url))
    170             {
    171                 System.Windows.Forms.Panel p = new System.Windows.Forms.Panel();
    172                 WindowsFormsHost host = new WindowsFormsHost();
    173                 host.Tag = webBrowserName;
    174                 host.Background = Brushes.Transparent;
    175                 host.Child = p;
    176 
    177                 host.Visibility = System.Windows.Visibility.Visible;
    178                 _webContainer.Children.Add(host);
    179 
    180               //  lock (_lockObj)
    181                //     _urlAndPanelPtr.Add(url, p.Handle);
    182                 return p.Handle;// 允许一个地址打开多个
    183             }
    184            // return _urlAndPanelPtr[url];
    185         }
    186 
    187         private void FindAndOpenWebBrowser(string webBrowserName, string url)
    188         {
    189             if (!_webBrowserPtr.ContainsKey(webBrowserName))
    190             {
    191                 this.OpenNewWebBrowser(webBrowserName, url);
    192             }
    193             else
    194             {
    195                 OpenExistWebBrowser(webBrowserName, url);
    196             }
    197         }
    198 
    199         //打开新的浏览器
    200         private void OpenNewWebBrowser(string webBrowserName, string url)
    201         {
    202             IntPtr targetPtr = this.CreateWebProcess();
    203          
    204             IntPtr pagePtr = this.GetOrAddNewPage(webBrowserName, url);
    205 
    206             lock (_lockObj)
    207             {
    208                 _webBrowserPtr.Add(webBrowserName, targetPtr);
    209             }
    210 
    211             this.SetWebBrowserLoc(webBrowserName, pagePtr);
    212 
    213             this.SendParam(webBrowserName, url);
    214         }
    215         //打开已存在的页面
    216         private void OpenExistWebBrowser(string webBrowserName, string url)
    217         {
    218             //显示隐藏窗体
    219             foreach (var itm in _webContainer.Children)
    220             {
    221                 WindowsFormsHost wfh = itm as WindowsFormsHost;
    222                 if (wfh == null) continue;
    223                 if (wfh.Tag.ToString() == webBrowserName)
    224                     wfh.Visibility = Visibility.Visible;
    225                 else
    226                     wfh.Visibility = Visibility.Collapsed;
    227             }
    228 
    229             IntPtr webBrowserPtr = _webBrowserPtr[webBrowserName];
    230 
    231             double h = _webContainer.ActualHeight - 10;
    232 
    233             double w = _webContainer.ActualWidth - 10;
    234 
    235             Win32Helper.MoveWindow(webBrowserPtr, 0, 0, (int)w, (int)h, true);
    236 
    237             this.SendParam(webBrowserName, url);
    238         }
    239         //设置浏览器位置
    240         private void SetWebBrowserLoc(string webBrowserName, IntPtr pagePtr)
    241         {
    242             if (!_webBrowserPtr.ContainsKey(webBrowserName))
    243                 return;
    244 
    245             IntPtr webBrowserPtr = _webBrowserPtr[webBrowserName];
    246 
    247             double h = _webContainer.ActualHeight;
    248 
    249             double w = _webContainer.ActualWidth;
    250 
    251             IntPtr preParentHandle=  Win32Helper.SetParent(webBrowserPtr, pagePtr);
    252 
    253             //如果设置父窗体失败,则重试5次
    254             int tryNum = 5;
    255             while(preParentHandle==IntPtr.Zero)
    256             {
    257                 Thread.Sleep(10);
    258 
    259                 preParentHandle = Win32Helper.SetParent(webBrowserPtr, pagePtr);
    260 
    261                 if (tryNum <= 0) break;
    262 
    263                 tryNum--;
    264             }
    265 
    266             bool moveResult= Win32Helper.MoveWindow(webBrowserPtr, 0, 0, (int)w, (int)h, true);
    267 
    268             //如果窗体位置移动失败,则尝试5次
    269             tryNum = 5;
    270             while(!moveResult)
    271             {
    272                 Thread.Sleep(10);
    273                 moveResult = Win32Helper.MoveWindow(webBrowserPtr, 0, 0, (int)w, (int)h, true);
    274                 if (tryNum <= 0) break;
    275 
    276                 tryNum--;
    277             }
    278         }
    279         //向浏览器发送数据
    280         private void SendParam(string webBrowserName, string url)
    281         {
    282             if (!_webBrowserPtr.ContainsKey(webBrowserName))
    283                 return;
    284 
    285             _webProcessPtr = _webBrowserPtr[webBrowserName];
    286 
    287             UrlModel um = new UrlModel() { Url = url, isChrome = _isChrome };
    288 
    289             if (this._isNeedReflesh == "1")
    290                 um.IsNeedRefresh = true;
    291 
    292             //发送message
    293             this.SendMessage(um);
    294         }
    295 
    296 
    297         public void SendLoadedParam(string pMsgId, string pUrl)
    298         {
    299 
    300             UrlModel um = new UrlModel() { MsgId = pMsgId, Url = pUrl };
    301             //发送message
    302             this.SendMessage(um);
    303         }
    304 
    305         #endregion
    306 
    307         //创建一个新的webbrowser进程
    308         private IntPtr CreateWebProcess()
    309         {
    310             ProcessStartInfo psi = new ProcessStartInfo(_webBrowserStartPath);
    311             psi.WindowStyle = ProcessWindowStyle.Hidden;
    312             var process = Process.Start(psi);
    313             IntPtr targetPtr = IntPtr.Zero;
    314             while (targetPtr == IntPtr.Zero) //循环目标窗口启动完成
    315             {
    316                 targetPtr = process.MainWindowHandle;
    317                 if (targetPtr != IntPtr.Zero)
    318                 {
    319                     break;
    320                 }
    321                 Thread.Sleep(10);
    322             }
    323             return targetPtr;
    324         }
    325         /// <summary>
    326         /// 接收web页面JS调用发送的数据
    327         /// </summary>
    328         private void ReceiveWinMsg(int index,object msg)
    329         {
    330             if (msg == null) return;
    331             string data = msg.ToString();
    332 
    333             if (!data.Contains("MsgId")) return;
    334 
    335             ////js->web->web进程-->客户端主进程
    336             JsInvokeClientModel jm = JsonConvert.DeserializeObject<JsInvokeClientModel>(data);
    337             if (jm != null && _msgCallBackDic.ContainsKey(jm.Url))
    338             {
    339                 //将web页面js调用的参数回调到具体订阅的业务模块中
    340                 _msgCallBackDic[jm.Url](jm.Cmd, jm.Params);
    341             }
    342 
    343             //客户端主进程->web进程->js
    344             ClientInvokeJsModel jsResp = JsonConvert.DeserializeObject<ClientInvokeJsModel>(data);
    345             if (jsResp != null && _jsCallBackData.ContainsKey(jsResp.MsgId))
    346             {
    347                 jsResp.IsCompleted = true;
    348                 _jsCallBackData[jsResp.MsgId] = jsResp;
    349             }
    350         }
    351         /// <summary>
    352         /// 发送message
    353         /// </summary>
    354         /// <param name="message"></param>
    355         private void SendMessage(MessageBase message)
    356         {
    357             ////将message序列化为json传输
    358             string json = JsonConvert.SerializeObject(message);
    359             byte[] sarr = System.Text.Encoding.Default.GetBytes(json);
    360             int len = sarr.Length;
    361             CopyDataStruct cds = new CopyDataStruct
    362             {
    363                 DwData = (IntPtr)100,
    364                 LpData = json,
    365                 CbData = len + 1
    366             };
    367           var value=   Win32Helper.SendMessage(this._webProcessPtr, WmConst.WM_COPYDATA, this._parentIntPrt, ref cds);
    368         }
    369 
    370        
    371 
    372         #region//Interface实现
    373         public void Open(string url, string webBrowserName = null, bool isNeedReflesh = false, Action<string, string> callBack = null, bool  pIsChrome=false)
    374         {
    375             _currentOpenUrl = url;
    376             _isChrome = pIsChrome;
    377             _isNeedReflesh = isNeedReflesh ? "1" : "0";
    378 
    379             if (string.IsNullOrEmpty(webBrowserName))
    380                 webBrowserName = "defaultName";
    381 
    382             //IE浏览器打开方式:查找webBrowser进程窗体句柄
    383             this.FindAndOpenWebBrowser(webBrowserName, url);
    384             //谷歌的打开方式
    385 
    386             //绑定委托
    387             if (callBack != null)
    388             {
    389                 if (!_msgCallBackDic.ContainsKey(url))
    390                     _msgCallBackDic.Add(url, callBack);
    391                 else
    392                     _msgCallBackDic[url] = callBack;
    393             }
    394 
    395             // 移除允许 一个url地址 多个窗体打开
    396             //if (!_urlAndBroserPrt.ContainsKey(url) && _webBrowserPtr.ContainsKey(webBrowserName))
    397             //{
    398             //    _urlAndBroserPrt.Add(url, _webBrowserPtr[webBrowserName]);
    399             //}
    400         }
    401 
    402         public void Close(string webBrowserName, string url = null)
    403         {
    404             //特殊处置,为了兼容模块嵌入页面同时“设置”项也嵌入页面问题,先查询key的前6位
    405             if (webBrowserName.Length > 6)
    406                 webBrowserName = webBrowserName.Substring(0, 6);
    407 
    408             List<string> delKeys = new List<string>();
    409             foreach(var itm in _webBrowserPtr)
    410             {
    411                 if(itm.Key.Contains(webBrowserName))
    412                 {
    413                     delKeys.Add(itm.Key);
    414                 }
    415             }
    416 
    417             foreach(var key in delKeys)
    418             {
    419                 if (_webBrowserPtr.ContainsKey(key))
    420                 {
    421                     IntPtr ptr = _webBrowserPtr[key];
    422                     //发送关闭命令
    423                     Win32Helper.SendMessage(ptr, WmConst.C_WM_CLOSE, 0, 0);
    424                     _webBrowserPtr.Remove(key);
    425                 }
    426             }
    427             
    428             if (!string.IsNullOrEmpty(url))
    429             {
    430                 //_urlAndPanelPtr.Remove(url);
    431                 _msgCallBackDic.Remove(url);
    432             }
    433         }
    434 
    435         static Dictionary<string, ClientInvokeJsModel> _jsCallBackData = new Dictionary<string, ClientInvokeJsModel>();
    436         //public async Task<object> InvokeScript(string scriptName)
    437         //{
    438         //   return await this.InvokeScript(scriptName, null);
    439         //}
    440 
    441         //public async Task<object> InvokeScript(string scriptName, params object[] args)
    442         //{
    443         //    ClientInvokeJsModel js = new ClientInvokeJsModel() { Url = _currentOpenUrl, ScriptName = scriptName, ReqParamList = args };
    444 
    445         //    js.MsgId = Guid.NewGuid().ToString();
    446 
    447         //    if (!_jsCallBackData.ContainsKey(js.MsgId))
    448         //    {
    449         //        _jsCallBackData.Add(js.MsgId, js);
    450         //    }
    451         //    this.SendMessage(js);
    452         //    object result = null;
    453         //    await Task<object>.Run(() =>
    454         //    {
    455         //        while (true)
    456         //        {
    457         //            if (_jsCallBackData[js.MsgId].IsCompleted)
    458         //            {
    459         //                result = _jsCallBackData[js.MsgId];
    460         //                _jsCallBackData.Remove(js.MsgId); break;
    461         //            }
    462         //        }
    463         //    });
    464 
    465         //    return result;
    466         //}
    467 
    468 
    469         #endregion
    470     }
  • 相关阅读:
    自我学习笔记08
    自我学习笔记07
    自我学习笔记06
    自我学习笔记05
    自我学习笔记04
    自我学习笔记03
    自我学习笔记02
    WebApi HttpUtils
    Android 正则表达式,Pattern,Matcher基本使用
    Andriod项目结构
  • 原文地址:https://www.cnblogs.com/bkyrslf/p/13301118.html
Copyright © 2011-2022 走看看