图形用户界面若干基础疑问

来来来,挖坑挖坑,思来想去,先把这个坑填掉,不深入研究,只求解惑。–2020年4月29日 11点43分

一直有几个问题,在若干年前就开始疑惑了:

  1. 这些图形界面库是怎么画出来的?
  • Win32\WTL\ATL\MFC\

  • Qt\wxWidgets\FLTK\Nana\

  • WinForms\WPF\

  • DirectUI\Duilib\

  • SWing\

  • tkinter\

    windows平台下都调用了win32接口,只是封装了起来而已。

    Win32窗口机制,是windows一系列图形界面的基石。无论你是MFC一层薄薄的封装,还是QT等第三方工具,都是基于对Win32一系列 API的调用。CreateWindow之后,一个基于HWND句柄的空白窗口出现你眼前。虽然此时你什么也不做,但Win32窗口依然不间断的收到各种类型的窗口消息。在这一系列消息中,WM_PAINT消息至关重要,它决定了你程序的最终UI界面。PANIT消息是一个数据结构,提供了绘图关键的HDC设备上下文接口。
    作者:网络芝麻
    链接:https://www.zhihu.com/question/56870169/answer/150731083
    来源:知乎
    著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。

  1. 项目的实际需求中,只涉及到很少的功能,大部分界面库太厚重了,没用的东西太多,怎样才能做到符合实际需求?

    回到题目上,为什么不用QT/MFC?从专业性上来讲因为公司有实力和资源自主开发一个框架,这样可以不受制于人,并且根据自身业务特点对框架进行针对性的定制和性能优化,而且这也是大公司非常专业的做法。Client开发不像后台开发有很多可靠的开源解决方案,所以造轮子是十分必要的,而且可以造出来比市面上更好的轮子。为什么公司喜欢造轮子,因为造轮子才显得专业:
    作者:tishion
    链接:https://www.zhihu.com/question/67320946/answer/253059396
    来源:知乎
    著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。

  2. 目前的跨平台库都是以兼容各大平台的接口实现的。那么windows平台下,是否可以摆脱win32 API?

    理论上不可以。除非突破平台限制,直接与硬件驱动对话。

  3. 是否可以自定义实现一个简单的界面?

    可以,但它喵的需要时间,连环嵌套坑。这坑基本就等同于windows平台下的win32SDK开发。别想乱七八糟了,反正都是win32的封装。

    如果想开发界面程序,并且有能够深入理解Windows的机制,特别建议用WTL,WTL是微软ATL的那些人开放的一个WindowsGUI程序开发的模板库,无论是迅雷的Blot还是金山的界面库,还有腾讯的界面库,基本上都是在WTL的基础上搭建起来的,WTL解决了一个重要问题,Win32窗口类必须是全局函数,所以用类封装的时候,必须用一些取巧的机制才能顺利的封装窗口类,并且又不失效率,而WTL的thunk机制非常先进,成功的解决了这个问题。在追求效率和开发速度,WTL都做的不错,模板技术的使用使得编译后体积和运行速度远远优于MFC,C#没有Native的时候,WPF开发的程序一旦体积巨大,问题就会暴露出来。Qt,在Windows上体积太大,信号和槽的机制和Windows消息机制存在一定的差异,封装过程的代价还未可知。所以个人看法建议使用WTL,唯一不足是WTL并没有得道官方的正式支持,但代码依然在更新,最近增加了Nuget的支持。
    作者:Charlie
    链接:https://www.zhihu.com/question/24461881/answer/28646451
    来源:知乎
    著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。

  4. ​tcl/tk中tkinter是怎么运作的?:
    ​tcl/tk:http://www.tcl.tk/
    惭愧,这个问题暂时无法回答,下次来放答案吧(可能没下次了 )。这简直是个轮回,上次关注tcl是在2010年。my god。

  5. ​vtk中的win32窗口从哪里来?
    之前专门找过VTK中的窗口创建,详细说明请移步这里:vtk中的win32窗口

  6. ​如何自己封装一套界面库?
    网上的轮子很多了,借过来学习一下是非常值得的,前提是要合理安排时间。
    Win32++:http://win32-framework.sourceforge.net/
    Gaclib:http://www.gaclib.net/

本文不会扩展太大的范围,旨在学习windows绘制窗口的原理,只要自己能回答上面几个问题即可,点到为止。

唉,gui的本质就是一个死循环,根本不存在,万物皆假象,这个时候还提什么gui,会用哪个用哪个罢了!最后给出一个简单的类,假装自己动过手。
win32gui.h

#pragma once

#include <windows.h>
#include <stdio.h>
#include <stdlib.h>
#pragma comment(lib,"winmm.lib")
#define WINCLASSNAME "win32gui" //应用程序名称
LRESULT WINAPI WndProc( HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam ); //声明窗口函数

class win32gui
{
public:
	win32gui(void);
	~win32gui(void);

	bool RegWnd(UINT Icon=0,UINT cur=0);//注册窗口
	bool CreateWnd(LPCTSTR title,HINSTANCE PrevInst,bool isFull);//创建窗口
	bool Run();//消息循环
	void DeleteWnd();//结束应用程序
private:
	WNDCLASSEX wc;
	MSG m_msg;
	int m_width;
	int m_height;
	HWND m_hWnd;

	HINSTANCE hInstance;
};

win32gui.cpp

#include "win32gui.h"

win32gui::win32gui(void)
{
	hInstance = GetModuleHandle(NULL);//获取实例句柄
}
win32gui::~win32gui(void)
{
}
//-----------------------------------------------------------------------
//注册窗口
//----------------------------------------------------------------------
bool win32gui::RegWnd(UINT Icon,UINT cur)
{
	// 定义一个Windows类,指定消息的处理函数为MsgProc
	wc.cbSize = sizeof(WNDCLASSEX);
	wc.style = CS_HREDRAW | CS_VREDRAW;
	wc.lpfnWndProc = WndProc;
	wc.cbClsExtra = wc.cbWndExtra = NULL;
	wc.hInstance = hInstance;
	wc.hbrBackground = (HBRUSH)GetStockObject(COLOR_WINDOW+1);
	wc.lpszMenuName = NULL;
	wc.lpszClassName = TEXT("win32gui");
	wc.hIcon = wc.hIconSm = LoadIcon(NULL,IDI_APPLICATION); 
	wc.hCursor = LoadCursor(NULL,IDC_ARROW); 
	if(cur)  
		wc.hCursor=LoadCursor(NULL,IDC_ARROW);     //定义鼠标图标 
	// 注册这个窗口类
	RegisterClassEx( &wc );
	return true;
}
//-------------------------------------------------------------------------------------------
//创建窗口
//-------------------------------------------------------------------------------------------
bool win32gui::CreateWnd(LPCTSTR title,HINSTANCE PrevInst,bool isFull)
{
	if(PrevInst) 
		return false;                  //判断是否已经有相同的应用实体在运行

	// 创建应用程序窗口
	m_hWnd = CreateWindowEx(NULL,
							wc.lpszClassName,
							wc.lpszClassName,
							WS_OVERLAPPEDWINDOW,
							CW_USEDEFAULT,
							CW_USEDEFAULT,
							CW_USEDEFAULT,
							CW_USEDEFAULT,
							NULL,
							NULL,
							wc.hInstance,
							NULL );//创建窗口

	if(!m_hWnd)  
		return false; 
	// 显示窗口
	ShowWindow( m_hWnd, SW_SHOW );
	UpdateWindow( m_hWnd );
	return true;
}
//----------------------------------------------------------------------------------------------
//运行,消息循环
//----------------------------------------------------------------------------------------------
bool win32gui::Run()
{      
	if( m_msg.message != WM_QUIT)
	{
		////进入消息循环
		while(true)
		{
			if(!GetMessage(&m_msg,0,0,0))
				break;
			TranslateMessage(&m_msg);
			DispatchMessage(&m_msg);
		}
		return true;
	}
	else 
		return false; 
}
//-------------------------------------------------------------------------------
// 注销窗口类
//--------------------------------------------------------------------------------
void win32gui::DeleteWnd()
{ 
     UnregisterClass(TEXT("win32gui"), wc.hInstance );
}
//窗口过程回调函数,在这里处理窗口消息
LRESULT WINAPI WndProc( HWND hWnd,UINT uMsg,WPARAM wParam,LPARAM lParam)
{
	switch(uMsg)
	{
	case WM_DESTROY:
		PostQuitMessage(NULL);
		break;
	}
	return DefWindowProc(hWnd, uMsg, wParam, lParam);
}

main.cpp:

#include "win32gui.h"
int main()
{
	win32gui *m_gui = new win32gui;
	m_gui->RegWnd();
	m_gui->CreateWnd(TEXT("win32gui"),0,0);
	m_gui->Run();
	return 0;
}

参考文献

  1. 腾讯QQ为什要自研UI框架,而不用QT/MFC? - 知乎
    https://www.zhihu.com/question/67320946/answer/253059396
  2. Gaclib – GPU Accelerated C++ User Interface (vczh)
    http://www.gaclib.net/
  3. win32窗口创建之通俗易懂版_运维_DGDDHDHDH的博客-CSDN博客
  4. Win32++:http://win32-framework.sourceforge.net/
  5. Nana C++ Library - a modern C++ GUI library:http://nanapro.org/en-us/

猜你喜欢

转载自blog.csdn.net/rabbitbride/article/details/105836391