C# 封裝miniblink 使用HTML/CSS/JS來構(gòu)建.Net 應(yīng)用程序界面和簡(jiǎn)易瀏覽器
當(dāng)前位置:點(diǎn)晴教程→知識(shí)管理交流
→『 技術(shù)文檔交流 』
MiniBlink的作者是 龍泉寺掃地僧 miniblink是什么? (抄了一下 龍泉寺掃地僧 寫的簡(jiǎn)潔)Miniblink是一個(gè)全新的、追求極致小巧的瀏覽器內(nèi)核項(xiàng)目, 為什么要做miniblink?市面上作為嵌入的組件的可用的瀏覽器內(nèi)核,不外乎這幾個(gè):webkit、cef、nwjs、electron。 cef:優(yōu)點(diǎn)是由于集成的chromium內(nèi)核,所以對(duì)H5支持的很全,同時(shí)因?yàn)槭褂玫娜艘捕?,各種教程、示例,資源很多。但缺點(diǎn)很明顯,太大了。最新的cef已經(jīng)夸張到了100多M,還要帶一堆的文件。同時(shí)新的cef已經(jīng)不支持xp了(chromium對(duì)應(yīng)版本是M49)。而且由于是多進(jìn)程架構(gòu),對(duì)資源的消耗也很夸張。如果只是想做個(gè)小軟件,一坨文件需要帶上、超大的安裝包,顯然不能忍受。 nwjs,或者最近大火的electron:和cef內(nèi)核類似,都是chromium內(nèi)核。缺點(diǎn)和cef一模一樣。優(yōu)點(diǎn)是由于可以使用nodejs的資源,同時(shí)又自帶了各種api的綁定,所以可以用的周邊資源非常豐富;而基于js的開發(fā)方案,使得前端很容易上手。所以最近N多項(xiàng)目都是基于nwjs或electron來實(shí)現(xiàn)。例如vscode,atom等等。 原版webkit:現(xiàn)在官網(wǎng)還在更新windows port,但顯然漫不在心,而且最新的webkit也很大了,超過20幾M。最關(guān)鍵的是,周邊資源很少,幾乎沒人再基于webkit來做開發(fā)。同時(shí)由于windows版的saferi已經(jīng)停止開發(fā)了,所以用webkit就用不了他的dev tools了。這是個(gè)大遺憾。 WKE:這是個(gè)很老的webkit內(nèi)核的裁剪版了。小是小,但bug太多了。 那么關(guān)鍵點(diǎn)來了,使用miniblink有啥好處呢?? 首先,miniblink對(duì)大小要求非常嚴(yán)格。原版chromium、blink里對(duì)排版渲染沒啥大用的如音視頻全都被砍了,只專注于網(wǎng)頁的排版和渲染。甚至為了裁剪大小,我不惜使用vc6的crt來跑mininblink。這個(gè)也算前無古人后無來者了。 其次,miniblink緊跟最新chromium,這意味著chromium相關(guān)的資源都可以利用。在未來的規(guī)劃里,我是打算把electron的接口也加上的,這樣可以無縫替換electron。使用miniblink的話,開發(fā)調(diào)試時(shí)用原版electron,發(fā)布的時(shí)候再替換掉那些dll,直接可以無縫切換,非常方便。 miniblink如何裁剪到這么小?這個(gè)比較復(fù)雜了。主要就是把blink從chromium抽離了出來,同時(shí)補(bǔ)上了cc層(硬件渲染層)。現(xiàn)在的blink,已經(jīng)不是當(dāng)年的那個(gè)webkit了,渲染部分全走cc層,復(fù)雜無比。我這大半年都在重寫他那個(gè)蛋疼又復(fù)雜的cc層。 和webkit比,miniblink架構(gòu)有什么優(yōu)勢(shì)現(xiàn)在的webkit版本,已經(jīng)比miniblink落后太多了。blink一直在加入各種極富創(chuàng)造力和想象力的功能、組件。例如,blink早就加入多線程解析html token、blink gc回收器、多線程錄制回放渲染機(jī)制。這些能讓blink的解析渲染速度極大提升。下一次,我會(huì)先開源出blink gc組件,這東西很有意思,在c++里硬是搞出了一個(gè)垃圾回收機(jī)制,能讓你像寫java一樣寫c++。 miniblink 開源地址:https://github.com/weolar/miniblink49 我們可以通過miniblink做桌面應(yīng)用的UI,超小的附加dll,壓縮之后大約5M,比起Cefsharp 小太多了。VSCode也是用 Electron 網(wǎng)頁開發(fā)的 Html開發(fā)UI和WPF對(duì)比有什么優(yōu)勢(shì)? 1、 Html 前端資源豐富,各種框架 2、 會(huì)Html的人比會(huì)WPF的人多太多了,入門簡(jiǎn)單 3、.Net2.0照樣可以用 4、網(wǎng)站和桌面程序界面可以統(tǒng)一,甚至大部分前端代碼復(fù)用 資源消耗方面,和WPF差不多,畢竟瀏覽器也是內(nèi)存消耗大戶 不過對(duì)比electron 這種純 Html CSS + js的,我更喜歡 用C# 代替JS 做業(yè)務(wù)邏輯,我感覺JS寫大項(xiàng)目 代碼比較亂,維護(hù)比C#麻煩。所以 JS做前端輔助比較合適,業(yè)務(wù)邏輯用C#實(shí)現(xiàn) 接下來,我寫個(gè)簡(jiǎn)單的MiniBlink封裝案例!更多功能你們可以自行封裝 或者 看看 DSkin 采用 PInvoke 和Winform封裝方式,MiniBlink對(duì)外提供的接口主要在 wke.h ,miniblink 的dll可以通過GitHub源碼編譯出來。具體封裝規(guī)則,你們可以百度查查看 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 //調(diào)用這個(gè)之后要手動(dòng)調(diào)用 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();//創(chuàng)建 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 } 代碼寫好之后,生成一下,工具箱里就有控件了,然后拖到界面,設(shè)置Url,運(yùn)行就有效果了
如果你想偷懶,要更完整的功能你可以看看 DSKin DSkin已經(jīng)封裝好 Html構(gòu)建桌面UI的快捷開發(fā)方式,資源內(nèi)嵌,C#和JS互相調(diào)用,無需寫麻煩的參數(shù)數(shù)據(jù)轉(zhuǎn)換,通過Vue實(shí)現(xiàn)C#屬性和頁面雙向綁定,頁面和C#類對(duì)應(yīng)等等,就像WebForm開發(fā)。 窗體陰影、系統(tǒng)按鈕那些都是Html+CSS定義的 簽名:<-CPF C# 跨平臺(tái)桌面UI框架,支持Windows,Mac,Linux,包括XP,國產(chǎn)麒麟Linux等等->
轉(zhuǎn)載:https://www.cnblogs.com/dskin/p/8664912.html 該文章在 2024/1/23 10:53:58 編輯過 |
關(guān)鍵字查詢
相關(guān)文章
正在查詢... |