分享

2.Windows 界面技术发展现状

 ekylin 2019-09-29

毫无疑问,Windows的流行推动了图形界面的发展,从最原始的Win32界面库到MFC,再到最近UWP界面库,Windows界面库的发展也代表了界面库和整个软件行业的发展方向。本文就简单梳理下整个Windows界面库的发展历程和现状。

Win32

Windows 整个系统的图形界面是建立在Win32图形界面接口上的,它提供了Windows界面编程的基本模型——显示管理窗口和消息循环分发事件。Win32是C接口形式,一个典型的窗口程序如下,可以看到就是按照通用界面库模型来的,不再赘述,对此感兴趣的可以看Petzold的《Windows程序设计》。Win32需要考虑细节太多,目前实际编程很少再用原生win32了,一般是第三方界面库基于Win32包装或其他语言通过包装Win32来提供基本界面功能。

  1. #include <windows.h>
  2. LRESULT CALLBACK WndProc (HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam);
  3. int WINAPI WinMain (HINSTANCE hInstance, HINSTANCE hPrevInstance, PSTR szCmdLine, int iCmdShow)
  4. {
  5. static TCHAR szAppName[] = TEXT ("窗口类名称");
  6. HWND hwnd;
  7. MSG msg;
  8. WNDCLASSEX wndclassex = {0};
  9. //设计窗口类
  10. wndclassex.cbSize = sizeof(WNDCLASSEX);
  11. wndclassex.style = CS_HREDRAW | CS_VREDRAW;
  12. wndclassex.lpfnWndProc = WndProc;
  13. wndclassex.cbClsExtra = 0;
  14. wndclassex.cbWndExtra = 0;
  15. wndclassex.hInstance = hInstance;
  16. wndclassex.hIcon = LoadIcon (NULL, IDI_APPLICATION);
  17. wndclassex.hCursor = LoadCursor (NULL, IDC_ARROW);
  18. wndclassex.hbrBackground = (HBRUSH) GetStockObject (WHITE_BRUSH);
  19. wndclassex.lpszMenuName = NULL;
  20. wndclassex.lpszClassName = szAppName;
  21. wndclassex.hIconSm = wndclassex.hIcon;
  22. //注册窗口类
  23. if (!RegisterClassEx (&wndclassex))
  24. {
  25. MessageBox (NULL, TEXT ("RegisterClassEx failed!"), szAppName, MB_ICONERROR);
  26. return 0;
  27. }
  28. //产生窗口
  29. hwnd = CreateWindowEx (WS_EX_OVERLAPPEDWINDOW,
  30. szAppName,
  31. TEXT ("窗口名称"),
  32. WS_OVERLAPPEDWINDOW,
  33. CW_USEDEFAULT,
  34. CW_USEDEFAULT,
  35. CW_USEDEFAULT,
  36. CW_USEDEFAULT,
  37. NULL,
  38. NULL,
  39. hInstance,
  40. NULL);
  41. //显示窗口
  42. ShowWindow (hwnd, iCmdShow);
  43. UpdateWindow (hwnd);
  44. //启动消息循环泵循环获取消息分配到窗体过程函数处理
  45. while (GetMessage (&msg, NULL, 0, 0))
  46. {
  47. TranslateMessage (&msg);
  48. DispatchMessage (&msg);
  49. }
  50. return msg.wParam;
  51. }
  52. //窗体过程函数
  53. LRESULT CALLBACK WndProc (HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
  54. {
  55. HDC hdc;
  56. PAINTSTRUCT ps;
  57. switch (message)
  58. {
  59. case WM_CREATE:
  60. return (0);
  61. case WM_PAINT:
  62. hdc = BeginPaint (hwnd, &ps);
  63. EndPaint (hwnd, &ps);
  64. return (0);
  65. case WM_DESTROY:
  66. PostQuitMessage (0);
  67. return (0);
  68. }
  69. return DefWindowProc (hwnd, message, wParam, lParam);
  70. }

 MFC

可以看到Win32创建一个简单的界面需要大段的代码,既然是遵循相同的模型,恰好适逢C++技术发展,微软借助C++技术将界面编程抽象成许多类,包装诸多细节,最明显的两个特征:

1.简化窗口创建,窗口创建和类绑定,创建的公共操作封装到基类中

2.窗口过程统一勾到一个处理函数中,然后分发到对应的每个窗口类中(可以参考我的这篇文章)

这样开发者只需要重写部分虚函数,填充消息消息响应表实现响应函数即可,大大减少了开发者的工作量,而且结合VC提供的可视化功能,能够快速的完成界面代码的生成。但是MFC封装臃肿了,继承层次过多,且当时的C++标准尚未完善为了弥补有很多hack设计,但是MFC经过这么多年的发展已经相当稳定了,所以现在主要用在工业领域,算是工业领域的一个标准了,一些小公司和小工具也还是在用MFC,感兴趣的入门可以看看孙鑫《VC++深入详解》,提高可以看侯捷的《深入详解MFC》和David《Visual C++ 技术内幕》。

WTL

因为MFC的臃肿,微软的一个开发小组业余开发了WTL,并且逐渐被大家接受,WTL主要基于C++ 模板技术,封装很轻量级,而且兼具MFC的诸多优点,还可以和MFC混用。但是因为WTL技术上相对MFC要求较高,目前主要是一些大厂(360、金山等)在用,而且由于WTL的封装很易于扩展,国内大多数Windows C++界面库都是基于WTL开发的,接下来关于界面库的编写也主要基于WTL讲解。

WTL出来的相对较晚,微软也没有大力宣传过,市面上讲解的书不多,详细了解WTL可以看看WTL for MFC Programmers系列文章,这是中文版本链接

Qt Widget

qt并非微软的界面库,他是一个跨平台的C++界面库,最早由诺基亚开发用于手机界面展示,现在由奇趣公司维护。之所以把Qt放在这里讲,是因为Qt在Windows上使用非常广泛,而且引入了非常多新的设计。如果把原生Win32比作界面库1.0,MFC/WTL比作界面库2.0,那么Qt Widget可以算是界面库3.0。它引入了xml布局界面,支持Qss样式,支持非常多系统组件,非常易于编写现代化的DirectUI界面,现在Qt被广泛的用在了工业领域,互联网产品比如WPS,YY语音等也都是基于Qt编写。可以说如果需要一种跨平台的C++界面库,那么Qt是最好的选择。可以参考书籍Jasmin 《C++ GUI Qt 4编程(第2版)》,这本书有点老,可以结合现在文档一起看,Qt的文档写的非常好。

WinForm

winform并非C++界面库,但是微软后期的主要精力在于推广自己的C#语言,因此winform可以看做是微软界面库发展的延续。Winform是基于Win32封装,屏蔽了很多细节,拥有超多组件,结合VC编写所见即所得界面非常简单。但是打包发布Winform窗体程序时,一般需要带上对应.Net 运行时,因此程序体积比较大,但是胜在开发效率快和COM、数据库集合非常好,很多企业化办公和管理系统都是基于Winform来编写的。

WPF

Winform主要还是基于win32界面库,在新的互联网时代DirectUI的诞生让开发者可以编写更加现代化更加炫酷支持更多自定义的界面,为此微软大力推出了WPF。DirectUI技术某种程度上其实就是在客户端界面编程做到类似Web前端开发,通过声明式的类xml和css控制显示,通过类脚本控制界面动作和效果,做到显示和逻辑分离

WPF曾是微软大力推的界面技术,它引入了很多革新的概念——xaml布局、数据绑定技术等等,支持更加复杂的绘制和特效,和Qt Widget类似,但是更加强大,进一步提高了开发效率,可以看做界面库3.5。但是由于WPF最开始基于CPU渲染,有很大的性能问题,现在某种程度上已经得到了很好的优化,然而和winform一样有依赖.net运行时的问题,而许多互联网公司的产品都是需要支持Window XP(比如QQ、360安全卫士等),所以WPF不是桌面应用程序界面开发首选,WPF现在还是主要用在企业化办公和管理系统。

UWP和Qt QML

在移动互联网的路上,微软并没有走的很好,为了打出差异,推出了手机/平板/PC一体的Win8,随之推出的是号称一次编写到处运行UWP应用,其实UWP很像WPF,但是界面编写方式更贴近Web前端。UMP应用市场正在逐渐完善,但是毕竟操作体验和传统PC windows有差别,且很多地方还是处于一种混合的方式,只能等待微软改进和时间磨合了,具体前途怎样现在很难说,依赖于.Net的问题同样是现阶段的一个制约,微软马上要停止Win7的支持,可能有利于UWP的发展,国内的一些大厂都推出了自家的UWP应用(比如QQ、爱奇艺等)做提前布局。UWP可以看做界面库4.0,当然这是我个人的排序,仅做参考,感兴趣的可以直接看官方MSDN文档,示例非常全。

Qt QML和UWP很像,同时支持PC/平板/应用编写,编写方式也很类似Web前端,如果之前就是Qt Widget开发者可以很快入门,特别是有一些有跨平台需求多系统支持的场合应用较多,感兴趣的可以看看Qt官方文档。

libcef/node-webkit/electron

前面说过因为Web前端的方式真正做到了显示和逻辑分离,PC界面库越来越模仿Web前端的方式,与其模仿Web前端不如直接就用Web前端来写界面。之前介绍过通过内嵌IE浏览器来编写桌面应用的程序,但是因为微软各个版本的IE对现代化Web前端的支持有限,只能做有限的工作。得益于Google开源的Chromium项目,开发者们基于Chromium改造提供基于Web浏览器的界面库libcef/node-webkit/electron:

1.libcef打包了一部分Chromium常用功能,封装成库,开发者可以在程序中直接调用就完成了浏览器的嵌入

2.node-webkit/electron更甚,直接基于 Chromium 和 Node.js打造一套完整框架, 让你可以使用 HTML, CSS 和 JavaScript 构建应用

越来越多的应用开始采用这种方式,比如网易云音乐、网易云笔记甚至微软自家产品VS Code,唯一限制这种方式流行的是需要打包很多Chromium库,安装包体积较大,但是在现在这种宽带和磁盘体积下,似乎也不是什么大问题。

这种方式支持跨平台,支持老系统,且直接使用现有Web前端开发人员即可完成开发,减少学习成本,可以说是一个非常好的方式,这也是我强烈推荐的现阶段桌面应用构建方式。当然它也不是万能的,如果你想写个简单工具,或者系统优化应用最好还是用传统的方式。

Windows界面库的发展就介绍到这里,基本上整个脉络如此,由于主要讨论的是一般PC桌面应用开发,相关的其他技术比如DirectX、OpenGL、SiverLight不在讨论范围,感兴趣的可以自行查找下相关资料。

    本站是提供个人知识管理的网络存储空间,所有内容均由用户发布,不代表本站观点。请注意甄别内容中的联系方式、诱导购买等信息,谨防诈骗。如发现有害或侵权内容,请点击一键举报。
    转藏 分享 献花(0

    0条评论

    发表

    请遵守用户 评论公约

    类似文章 更多