zoukankan      html  css  js  c++  java
  • C# 封装miniblink 使用HTML/CSS/JS来构建.Net 应用程序界面和简易浏览器

    MiniBlink的作者是 龙泉寺扫地僧

    miniblink是什么?   (抄了一下 龙泉寺扫地僧 写的简洁)

    Miniblink是一个全新的、追求极致小巧的浏览器内核项目,
    其基于chromium最新版内核,去除了chromium所有多余的部件,只保留最基本的排版引擎blink。
    Miniblink保持了10M左右的极简大小,是所有同类产品最小的体积,同时支持windows xp、npapi。

    为什么要做miniblink?

    市面上作为嵌入的组件的可用的浏览器内核,不外乎这几个:webkit、cef、nwjs、electron。

    cef:优点是由于集成的chromium内核,所以对H5支持的很全,同时因为使用的人也多,各种教程、示例,资源很多。但缺点很明显,太大了。最新的cef已经夸张到了100多M,还要带一堆的文件。同时新的cef已经不支持xp了(chromium对应版本是M49)。而且由于是多进程架构,对资源的消耗也很夸张。如果只是想做个小软件,一坨文件需要带上、超大的安装包,显然不能忍受。

    nwjs,或者最近大火的electron:和cef内核类似,都是chromium内核。缺点和cef一模一样。优点是由于可以使用nodejs的资源,同时又自带了各种api的绑定,所以可以用的周边资源非常丰富;而基于js的开发方案,使得前端很容易上手。所以最近N多项目都是基于nwjs或electron来实现。例如vscode,atom等等。

    原版webkit:现在官网还在更新windows port,但显然漫不在心,而且最新的webkit也很大了,超过20几M。最关键的是,周边资源很少,几乎没人再基于webkit来做开发。同时由于windows版的saferi已经停止开发了,所以用webkit就用不了他的dev tools了。这是个大遗憾。

    WKE:这是个很老的webkit内核的裁剪版了。小是小,但bug太多了。

    那么关键点来了,使用miniblink有啥好处呢??

    首先,miniblink对大小要求非常严格。原版chromium、blink里对排版渲染没啥大用的如音视频全都被砍了,只专注于网页的排版和渲染。甚至为了裁剪大小,我不惜使用vc6的crt来跑mininblink。这个也算前无古人后无来者了。

    其次,miniblink紧跟最新chromium,这意味着chromium相关的资源都可以利用。在未来的规划里,我是打算把electron的接口也加上的,这样可以无缝替换electron。使用miniblink的话,开发调试时用原版electron,发布的时候再替换掉那些dll,直接可以无缝切换,非常方便。

     

    miniblink如何裁剪到这么小?

    这个比较复杂了。主要就是把blink从chromium抽离了出来,同时补上了cc层(硬件渲染层)。现在的blink,已经不是当年的那个webkit了,渲染部分全走cc层,复杂无比。我这大半年都在重写他那个蛋疼又复杂的cc层。

    和webkit比,miniblink架构有什么优势

    现在的webkit版本,已经比miniblink落后太多了。blink一直在加入各种极富创造力和想象力的功能、组件。例如,blink早就加入多线程解析html token、blink gc回收器、多线程录制回放渲染机制。这些能让blink的解析渲染速度极大提升。下一次,我会先开源出blink gc组件,这东西很有意思,在c++里硬是搞出了一个垃圾回收机制,能让你像写java一样写c++。

    miniblink 开源地址:https://github.com/weolar/miniblink49

    我们可以通过miniblink做桌面应用的UI,超小的附加dll,压缩之后大约5M,比起Cefsharp 小太多了。VSCode也是用  Electron 网页开发的

    Html开发UI和WPF对比有什么优势?

    1、 Html 前端资源丰富,各种框架

    2、 会Html的人比会WPF的人多太多了,入门简单

    3、.Net2.0照样可以用

    4、网站和桌面程序界面可以统一,甚至大部分前端代码复用

    资源消耗方面,和WPF差不多,毕竟浏览器也是内存消耗大户

    不过对比electron 这种纯 Html CSS + js的,我更喜欢 用C# 代替JS 做业务逻辑,我感觉JS写大项目 代码比较乱,维护比C#麻烦。所以 JS做前端辅助比较合适,业务逻辑用C#实现

    接下来,我写个简单的MiniBlink封装案例!更多功能你们可以自行封装 或者 看看 DSkin

    采用 PInvoke 和Winform封装方式,MiniBlink对外提供的接口主要在 wke.h ,miniblink 的dll可以通过GitHub源码编译出来。具体封装规则,你们可以百度查查看

      1 using System;
      2 using System.Collections.Generic;
      3 using System.Linq;
      4 using System.Text;
      5 using System.Runtime.InteropServices;
      6 //by:DSkin
      7 
      8 namespace MiniBlink
      9 {
     10     public static class MiniblinkPInvoke
     11     {
     12         const string miniblinkdll = "node.dll";
     13 
     14 
     15         [DllImport(miniblinkdll, CallingConvention = CallingConvention.Cdecl)]
     16         public static extern void wkeSetHandle(IntPtr webView, IntPtr wnd);
     17 
     18         [DllImport(miniblinkdll, CharSet = CharSet.Unicode)]
     19         public static extern IntPtr wkeGetStringW(IntPtr @string);
     20 
     21         [DllImport(miniblinkdll, CharSet = CharSet.Unicode)]
     22         public static extern IntPtr wkeToStringW(IntPtr @string);
     23 
     24         [DllImport(miniblinkdll, CallingConvention = CallingConvention.Cdecl)]
     25         public static extern IntPtr wkeGetString(IntPtr @string);
     26 
     27         [DllImport(miniblinkdll)]
     28         public static extern void wkeSetDebugConfig(IntPtr webView, string debugString, IntPtr param);
     29 
     30         [DllImport(miniblinkdll)]
     31         public static extern Int64 wkeRunJSW(IntPtr webView, [In] [MarshalAs(UnmanagedType.LPWStr)] string script);
     32 
     33         [return: MarshalAs(UnmanagedType.I1)]
     34         [DllImport(miniblinkdll, CallingConvention = CallingConvention.Cdecl)]
     35         public static extern bool wkeFireMouseEvent(IntPtr webView, uint message, int x, int y, uint flags);
     36 
     37         [return: MarshalAs(UnmanagedType.I1)]
     38         [DllImport(miniblinkdll, CallingConvention = CallingConvention.Cdecl)]
     39         public static extern bool wkeFireMouseWheelEvent(IntPtr webView, int x, int y, int delta, uint flags);
     40 
     41         [DllImport(miniblinkdll, CallingConvention = CallingConvention.Cdecl)]
     42         [return: MarshalAs(UnmanagedType.I1)]
     43         public static extern bool wkeFireKeyUpEvent(IntPtr webView, uint virtualKeyCode, uint flags, [MarshalAs(UnmanagedType.I1)] bool systemKey);
     44 
     45         [return: MarshalAs(UnmanagedType.I1)]
     46         [DllImport(miniblinkdll, CallingConvention = CallingConvention.Cdecl)]
     47         public static extern bool wkeFireKeyDownEvent(IntPtr webView, uint virtualKeyCode, uint flags, [MarshalAs(UnmanagedType.I1)] bool systemKey);
     48 
     49         [DllImport(miniblinkdll, CallingConvention = CallingConvention.Cdecl)]
     50         [return: MarshalAs(UnmanagedType.I1)]
     51         public static extern bool wkeFireKeyPressEvent(IntPtr webView, uint charCode, uint flags, [MarshalAs(UnmanagedType.I1)] bool systemKey);
     52 
     53         [DllImport(miniblinkdll, CallingConvention = CallingConvention.Cdecl)]
     54         public static extern void wkeSetFocus(IntPtr webView);
     55 
     56         [DllImport(miniblinkdll, CallingConvention = CallingConvention.Cdecl)]
     57         public static extern void wkeKillFocus(IntPtr webView);
     58 
     59         [DllImport(miniblinkdll, CallingConvention = CallingConvention.Cdecl)]
     60         public static extern void wkeResize(IntPtr webView, int w, int h);
     61 
     62         [DllImport(miniblinkdll)]
     63         public static extern IntPtr wkeCreateWebView();
     64 
     65         [DllImport(miniblinkdll, CallingConvention = CallingConvention.Cdecl)]
     66         public static extern void wkeDestroyWebView(IntPtr webView);
     67 
     68         [DllImport(miniblinkdll)]
     69         public static extern void wkeInitialize();
     70 
     71         [DllImport(miniblinkdll)]
     72         public static extern void wkeLoadFile(IntPtr webView, [In, MarshalAs(UnmanagedType.LPWStr)] string filename);
     73 
     74         [DllImport(miniblinkdll)]
     75         public static extern void wkeLoadHTML(System.IntPtr webView, [In()] [MarshalAs(UnmanagedType.LPStr)] string html);
     76 
     77         [DllImport(miniblinkdll, CallingConvention = CallingConvention.Cdecl)]
     78         public static extern void wkeOnURLChanged2(IntPtr webView, UrlChangedCallback2 callback, IntPtr callbackParam);
     79 
     80         [DllImport(miniblinkdll, CharSet = CharSet.Auto, CallingConvention = CallingConvention.Cdecl)]
     81         public static extern void wkeLoadURLW(IntPtr webView, [In, MarshalAs(UnmanagedType.LPWStr)] string url);
     82 
     83         [DllImport(miniblinkdll, CallingConvention = CallingConvention.Cdecl)]
     84         public static extern void wkeOnPaintUpdated(IntPtr webView, wkePaintUpdatedCallback callback, IntPtr callbackParam);
     85 
     86         [DllImport(miniblinkdll, CallingConvention = CallingConvention.Cdecl)]
     87         public static extern void wkePaint(IntPtr webView, IntPtr bits, int pitch);
     88         [DllImport(miniblinkdll, CallingConvention = CallingConvention.Cdecl)]
     89         public static extern WkeCursorInfo wkeGetCursorInfoType(IntPtr webView);
     90 
     91         public static string Utf8IntptrToString(this IntPtr ptr)
     92         {
     93             var data = new List<byte>();
     94             var off = 0;
     95             while (true)
     96             {
     97                 var ch = Marshal.ReadByte(ptr, off++);
     98                 if (ch == 0)
     99                 {
    100                     break;
    101                 }
    102                 data.Add(ch);
    103             }
    104             return Encoding.UTF8.GetString(data.ToArray());
    105         }
    106      //调用这个之后要手动调用  Marshal.FreeHGlobal(ptr);
    107         public static IntPtr Utf8StringToIntptr(this string str)
    108         {
    109             byte[] utf8bytes = Encoding.UTF8.GetBytes(str);
    110             IntPtr ptr = Marshal.AllocHGlobal(utf8bytes.Length + 1);
    111             Marshal.Copy(utf8bytes, 0, ptr, utf8bytes.Length);
    112             Marshal.WriteByte(ptr, utf8bytes.Length, 0);
    113             return ptr;
    114         }
    115 
    116 
    117         public enum WkeCursorInfo
    118         {
    119             WkeCursorInfoPointer = 0,
    120             WkeCursorInfoCross = 1,
    121             WkeCursorInfoHand = 2,
    122             WkeCursorInfoIBeam = 3,
    123             WkeCursorInfoWait = 4,
    124             WkeCursorInfoHelp = 5,
    125             WkeCursorInfoEastResize = 6,
    126             WkeCursorInfoNorthResize = 7,
    127             WkeCursorInfoNorthEastResize = 8,
    128             WkeCursorInfoNorthWestResize = 9,
    129             WkeCursorInfoSouthResize = 10,
    130             WkeCursorInfoSouthEastResize = 11,
    131             WkeCursorInfoSouthWestResize = 12,
    132             WkeCursorInfoWestResize = 13,
    133             WkeCursorInfoNorthSouthResize = 14,
    134             WkeCursorInfoEastWestResize = 15,
    135             WkeCursorInfoNorthEastSouthWestResize = 16,
    136             WkeCursorInfoNorthWestSouthEastResize = 17,
    137             WkeCursorInfoColumnResize = 18,
    138             WkeCursorInfoRowResize = 19,
    139         }
    140         public enum wkeMouseMessage : uint
    141         {
    142             WKE_MSG_MOUSEMOVE = 0x0200,
    143             WKE_MSG_LBUTTONDOWN = 0x0201,
    144             WKE_MSG_LBUTTONUP = 0x0202,
    145             WKE_MSG_LBUTTONDBLCLK = 0x0203,
    146             WKE_MSG_RBUTTONDOWN = 0x0204,
    147             WKE_MSG_RBUTTONUP = 0x0205,
    148             WKE_MSG_RBUTTONDBLCLK = 0x0206,
    149             WKE_MSG_MBUTTONDOWN = 0x0207,
    150             WKE_MSG_MBUTTONUP = 0x0208,
    151             WKE_MSG_MBUTTONDBLCLK = 0x0209,
    152             WKE_MSG_MOUSEWHEEL = 0x020A,
    153         }
    154         public enum wkeMouseFlags
    155         {
    156             WKE_LBUTTON = 0x01,
    157             WKE_RBUTTON = 0x02,
    158             WKE_SHIFT = 0x04,
    159             WKE_CONTROL = 0x08,
    160             WKE_MBUTTON = 0x10,
    161         }
    162 
    163 
    164         [UnmanagedFunctionPointer(CallingConvention.Cdecl)]
    165         public delegate void wkePaintUpdatedCallback(IntPtr webView, IntPtr param, IntPtr hdc, int x, int y, int cx, int cy);
    166 
    167         [UnmanagedFunctionPointer(CallingConvention.Cdecl)]
    168         public delegate void UrlChangedCallback2(IntPtr webView, IntPtr param, IntPtr frameId, IntPtr url);
    169     }
    170 }
      1 using System;
      2 using System.Collections;
      3 using System.Collections.Generic;
      4 using System.ComponentModel;
      5 using System.Drawing;
      6 using System.Drawing.Imaging;
      7 using System.IO;
      8 using System.Linq;
      9 using System.Reflection;
     10 using System.Runtime.InteropServices;
     11 using System.Text;
     12 using System.Text.RegularExpressions;
     13 using System.Windows.Forms;
     14 //by:DSkin
     15 
     16 namespace MiniBlink
     17 {
     18     public class TestControl : Control
     19     {
     20         IntPtr handle = IntPtr.Zero;
     21         string url = string.Empty;
     22 
     23         IntPtr bits = IntPtr.Zero;
     24         Size oldSize;
     25         MiniblinkPInvoke.UrlChangedCallback2 UrlChangedCallback2;
     26         MiniblinkPInvoke.wkePaintUpdatedCallback wkePaintUpdatedCallback;
     27 
     28         public TestControl()
     29         {
     30             SetStyle(ControlStyles.OptimizedDoubleBuffer |
     31             ControlStyles.DoubleBuffer |
     32             ControlStyles.AllPaintingInWmPaint |
     33             ControlStyles.ResizeRedraw |
     34             ControlStyles.UserPaint, true);
     35         }
     36 
     37         public string Url
     38         {
     39             get
     40             {
     41                 return url;
     42             }
     43 
     44             set
     45             {
     46                 url = value;
     47                 if (handle != IntPtr.Zero)
     48                 {
     49                     MiniblinkPInvoke.wkeLoadURLW(handle, value);
     50                 }
     51             }
     52         }
     53 
     54         protected override void OnCreateControl()
     55         {
     56             base.OnCreateControl();
     57             if (!DesignMode)
     58             {
     59                 MiniblinkPInvoke.wkeInitialize();
     60                 handle = MiniblinkPInvoke.wkeCreateWebView();//创建 WebView
     61                 MiniblinkPInvoke.wkeSetHandle(handle, this.Handle);
     62                 MiniblinkPInvoke.wkeResize(handle, Width, Height);
     63 
     64                 UrlChangedCallback2 = (webView, param, frameId, url) =>
     65                 {
     66                     this.url = MiniblinkPInvoke.wkeGetString(url).Utf8IntptrToString();
     67                     OnUrlChanged(EventArgs.Empty);
     68                 };
     69                 MiniblinkPInvoke.wkeOnURLChanged2(handle, UrlChangedCallback2, IntPtr.Zero);
     70 
     71                 wkePaintUpdatedCallback = (IntPtr webView, IntPtr param, IntPtr hdc, int x, int y, int cx, int cy) =>
     72                 {
     73                     Invalidate();
     74                 };
     75                 MiniblinkPInvoke.wkeOnPaintUpdated(handle, wkePaintUpdatedCallback, IntPtr.Zero);
     76 
     77                 Url = url;
     78             }
     79         }
     80 
     81         protected override void OnPaint(PaintEventArgs e)
     82         {
     83             if (handle != IntPtr.Zero)
     84             {
     85                 if (bits == IntPtr.Zero || oldSize != Size)
     86                 {
     87                     if (bits != IntPtr.Zero)
     88                     {
     89                         Marshal.FreeHGlobal(bits);
     90                     }
     91                     oldSize = Size;
     92                     bits = Marshal.AllocHGlobal(Width * Height * 4);
     93                 }
     94 
     95                 MiniblinkPInvoke.wkePaint(handle, bits, 0);
     96                 using (Bitmap bmp = new Bitmap(Width, Height, Width * 4, PixelFormat.Format32bppPArgb, bits))
     97                 {
     98                     e.Graphics.DrawImage(bmp, 0, 0);
     99                 }
    100             }
    101             base.OnPaint(e);
    102             if (DesignMode)
    103             {
    104                 e.Graphics.DrawString("MiniBlinkBrowser", this.Font, Brushes.Red, new Point());
    105                 e.Graphics.DrawRectangle(Pens.Black, new Rectangle(0, 0, Width - 1, Height - 1));
    106             }
    107         }
    108 
    109         protected override void OnSizeChanged(EventArgs e)
    110         {
    111             base.OnSizeChanged(e);
    112             if (handle != IntPtr.Zero && Width > 1 && Height > 1)
    113             {
    114                 MiniblinkPInvoke.wkeResize(handle, Width, Height);
    115             }
    116         }
    117 
    118         protected override void OnMouseWheel(MouseEventArgs e)
    119         {
    120             base.OnMouseWheel(e);
    121             if (handle != IntPtr.Zero)
    122             {
    123                 uint flags = GetMouseFlags(e);
    124                 MiniblinkPInvoke.wkeFireMouseWheelEvent(handle, e.X, e.Y, e.Delta, flags);
    125             }
    126         }
    127         protected override void OnMouseDown(MouseEventArgs e)
    128         {
    129             base.OnMouseDown(e);
    130             uint msg = 0;
    131             if (e.Button == MouseButtons.Left)
    132             {
    133                 msg = (uint)MiniblinkPInvoke.wkeMouseMessage.WKE_MSG_LBUTTONDOWN;
    134             }
    135             else if (e.Button == MouseButtons.Middle)
    136             {
    137                 msg = (uint)MiniblinkPInvoke.wkeMouseMessage.WKE_MSG_MBUTTONDOWN;
    138             }
    139             else if (e.Button == MouseButtons.Right)
    140             {
    141                 msg = (uint)MiniblinkPInvoke.wkeMouseMessage.WKE_MSG_RBUTTONDOWN;
    142             }
    143             uint flags = GetMouseFlags(e);
    144             if (handle != IntPtr.Zero)
    145             {
    146                 MiniblinkPInvoke.wkeFireMouseEvent(handle, msg, e.X, e.Y, flags);
    147             }
    148         }
    149         protected override void OnMouseUp(MouseEventArgs e)
    150         {
    151             base.OnMouseUp(e);
    152             uint msg = 0;
    153             if (e.Button == MouseButtons.Left)
    154             {
    155                 msg = (uint)MiniblinkPInvoke.wkeMouseMessage.WKE_MSG_LBUTTONUP;
    156             }
    157             else if (e.Button == MouseButtons.Middle)
    158             {
    159                 msg = (uint)MiniblinkPInvoke.wkeMouseMessage.WKE_MSG_MBUTTONUP;
    160             }
    161             else if (e.Button == MouseButtons.Right)
    162             {
    163                 msg = (uint)MiniblinkPInvoke.wkeMouseMessage.WKE_MSG_RBUTTONUP;
    164             }
    165             uint flags = GetMouseFlags(e);
    166             if (handle != IntPtr.Zero)
    167             {
    168                 MiniblinkPInvoke.wkeFireMouseEvent(handle, msg, e.X, e.Y, flags);
    169             }
    170         }
    171         protected override void OnMouseMove(MouseEventArgs e)
    172         {
    173             base.OnMouseMove(e);
    174             if (this.handle != IntPtr.Zero)
    175             {
    176                 uint flags = GetMouseFlags(e);
    177                 MiniblinkPInvoke.wkeFireMouseEvent(this.handle, 0x200, e.X, e.Y, flags);
    178 
    179                 switch (MiniblinkPInvoke.wkeGetCursorInfoType(handle))
    180                 {
    181                     case MiniblinkPInvoke.WkeCursorInfo.WkeCursorInfoPointer:
    182                         Cursor = Cursors.Default;
    183                         break;
    184                     case MiniblinkPInvoke.WkeCursorInfo.WkeCursorInfoCross:
    185                         Cursor = Cursors.Cross;
    186                         break;
    187                     case MiniblinkPInvoke.WkeCursorInfo.WkeCursorInfoHand:
    188                         Cursor = Cursors.Hand;
    189                         break;
    190                     case MiniblinkPInvoke.WkeCursorInfo.WkeCursorInfoIBeam:
    191                         Cursor = Cursors.IBeam;
    192                         break;
    193                     case MiniblinkPInvoke.WkeCursorInfo.WkeCursorInfoWait:
    194                         Cursor = Cursors.WaitCursor;
    195                         break;
    196                     case MiniblinkPInvoke.WkeCursorInfo.WkeCursorInfoHelp:
    197                         Cursor = Cursors.Help;
    198                         break;
    199                     case MiniblinkPInvoke.WkeCursorInfo.WkeCursorInfoEastResize:
    200                         Cursor = Cursors.SizeWE;
    201                         break;
    202                     case MiniblinkPInvoke.WkeCursorInfo.WkeCursorInfoNorthResize:
    203                         Cursor = Cursors.SizeNS;
    204                         break;
    205                     case MiniblinkPInvoke.WkeCursorInfo.WkeCursorInfoNorthEastResize:
    206                         Cursor = Cursors.SizeNESW;
    207                         break;
    208                     case MiniblinkPInvoke.WkeCursorInfo.WkeCursorInfoNorthWestResize:
    209                         Cursor = Cursors.SizeNWSE;
    210                         break;
    211                     case MiniblinkPInvoke.WkeCursorInfo.WkeCursorInfoSouthResize:
    212                         Cursor = Cursors.SizeNS;
    213                         break;
    214                     case MiniblinkPInvoke.WkeCursorInfo.WkeCursorInfoSouthEastResize:
    215                         Cursor = Cursors.SizeNWSE;
    216                         break;
    217                     case MiniblinkPInvoke.WkeCursorInfo.WkeCursorInfoSouthWestResize:
    218                         Cursor = Cursors.SizeNESW;
    219                         break;
    220                     case MiniblinkPInvoke.WkeCursorInfo.WkeCursorInfoWestResize:
    221                         Cursor = Cursors.SizeWE;
    222                         break;
    223                     case MiniblinkPInvoke.WkeCursorInfo.WkeCursorInfoNorthSouthResize:
    224                         Cursor = Cursors.SizeNS;
    225                         break;
    226                     case MiniblinkPInvoke.WkeCursorInfo.WkeCursorInfoEastWestResize:
    227                         Cursor = Cursors.SizeWE;
    228                         break;
    229                     case MiniblinkPInvoke.WkeCursorInfo.WkeCursorInfoNorthEastSouthWestResize:
    230                         Cursor = Cursors.SizeAll;
    231                         break;
    232                     case MiniblinkPInvoke.WkeCursorInfo.WkeCursorInfoNorthWestSouthEastResize:
    233                         Cursor = Cursors.SizeAll;
    234                         break;
    235                     case MiniblinkPInvoke.WkeCursorInfo.WkeCursorInfoColumnResize:
    236                         Cursor = Cursors.Default;
    237                         break;
    238                     case MiniblinkPInvoke.WkeCursorInfo.WkeCursorInfoRowResize:
    239                         Cursor = Cursors.Default;
    240                         break;
    241                     default:
    242                         Cursor = Cursors.Default;
    243                         break;
    244                 }
    245             }
    246         }
    247         protected override void OnKeyDown(KeyEventArgs e)
    248         {
    249             base.OnKeyDown(e);
    250             if (handle != IntPtr.Zero)
    251             {
    252                 MiniblinkPInvoke.wkeFireKeyDownEvent(handle, (uint)e.KeyValue, 0, false);
    253             }
    254         }
    255         protected override void OnKeyPress(KeyPressEventArgs e)
    256         {
    257             base.OnKeyPress(e);
    258             if (handle != IntPtr.Zero)
    259             {
    260                 e.Handled = true;
    261                 MiniblinkPInvoke.wkeFireKeyPressEvent(handle, (uint)e.KeyChar, 0, false);
    262             }
    263         }
    264         protected override void OnKeyUp(KeyEventArgs e)
    265         {
    266             base.OnKeyUp(e);
    267             if (handle != IntPtr.Zero)
    268             {
    269                 MiniblinkPInvoke.wkeFireKeyUpEvent(handle, (uint)e.KeyValue, 0, false);
    270             }
    271         }
    272 
    273         protected override void OnGotFocus(EventArgs e)
    274         {
    275             base.OnGotFocus(e);
    276             if (handle != IntPtr.Zero)
    277             {
    278                 MiniblinkPInvoke.wkeSetFocus(handle);
    279             }
    280         }
    281 
    282         protected override void OnLostFocus(EventArgs e)
    283         {
    284             base.OnLostFocus(e);
    285             if (handle != IntPtr.Zero)
    286             {
    287                 MiniblinkPInvoke.wkeKillFocus(handle);
    288             }
    289         }
    290 
    291         protected override void OnPreviewKeyDown(PreviewKeyDownEventArgs e)
    292         {
    293             base.OnPreviewKeyDown(e);
    294             switch (e.KeyCode)
    295             {
    296                 case Keys.Down:
    297                 case Keys.Up:
    298                 case Keys.Left:
    299                 case Keys.Right:
    300                 case Keys.Tab:
    301                     e.IsInputKey = true;
    302                     break;
    303             }
    304         }
    305         private static uint GetMouseFlags(MouseEventArgs e)
    306         {
    307             uint flags = 0;
    308             if (e.Button == MouseButtons.Left)
    309             {
    310                 flags = flags | (uint)MiniblinkPInvoke.wkeMouseFlags.WKE_LBUTTON;
    311             }
    312             if (e.Button == MouseButtons.Middle)
    313             {
    314                 flags = flags | (uint)MiniblinkPInvoke.wkeMouseFlags.WKE_MBUTTON;
    315             }
    316             if (e.Button == MouseButtons.Right)
    317             {
    318                 flags = flags | (uint)MiniblinkPInvoke.wkeMouseFlags.WKE_RBUTTON;
    319             }
    320             if (Control.ModifierKeys == Keys.Control)
    321             {
    322                 flags = flags | (uint)MiniblinkPInvoke.wkeMouseFlags.WKE_CONTROL;
    323             }
    324             if (Control.ModifierKeys == Keys.Shift)
    325             {
    326                 flags = flags | (uint)MiniblinkPInvoke.wkeMouseFlags.WKE_SHIFT;
    327             }
    328             return flags;
    329         }
    330 
    331 
    332         protected override void Dispose(bool disposing)
    333         {
    334             base.Dispose(disposing);
    335             if (handle != IntPtr.Zero)
    336             {//资源释放
    337                 MiniblinkPInvoke.wkeDestroyWebView(handle);
    338                 handle = IntPtr.Zero;
    339             }
    340             if (bits != IntPtr.Zero)
    341             {
    342                 Marshal.FreeHGlobal(bits);
    343                 bits = IntPtr.Zero;
    344             }
    345         }
    346 
    347         public event EventHandler UrlChanged;
    348 
    349         protected virtual void OnUrlChanged(EventArgs e)
    350         {
    351             if (UrlChanged != null)
    352             {
    353                 UrlChanged(this, e);
    354             }
    355         }
    356 
    357     }
    358 }

    代码写好之后,生成一下,工具箱里就有控件了,然后拖到界面,设置Url,运行就有效果了

    如果你想偷懒,要更完整的功能你可以看看 DSKin

    DSkin已经封装好 Html构建桌面UI的快捷开发方式,资源内嵌,C#和JS互相调用,无需写麻烦的参数数据转换,通过Vue实现C#属性和页面双向绑定,页面和C#类对应等等,就像WebForm开发。 窗体阴影、系统按钮那些都是Html+CSS定义的

  • 相关阅读:
    ajax与302响应
    读过/在读/想读的英文原著
    从编译DotNetOpenAuth中学到的程序集强签名知识
    百度输入法引起的Mac远程桌面Ctrl+.快捷键不起作用
    MacBook鼠标指针乱窜/不受控制问题的解决方法
    IIS中User-mode caching引起的Cache-Control不为public的问题
    让IIS8支持WCF的最简单方法
    在ASP.NET Web Forms中用System.Web.Optimization取代SquishIt
    苹果官方发布,iPhone 6 & Plus 设计素材
    jQuery 特效:盒子破碎和移动动画效果
  • 原文地址:https://www.cnblogs.com/dskin/p/8664912.html
Copyright © 2011-2022 走看看