WINX如何做到可视化界面开发

【黑马-产品经理入门基础课笔记】01.认识产品经理 问题定义 ==> 可行性研究 ==> 需求分析。 阅读详情

概要

先简单回顾一下。到目前为止,我们已经介绍了: 

这里需要解释一个细节。上面提到的两个窗口类(Windows窗口类和SW系统的窗口类)概念有细节差异,不能完全等同。前者是Windows SDK中的概念,后者指的是C++窗口类(实现某一类窗口逻辑的C++类)。不过,由于C++窗口类最终也提供RegisterClass函数,因此把它可以理解为是Windows SDK中的窗口类之C++表现。后文除非特殊情况下两者均简称窗口类,不做细节差异上的深究。

WINX一直强调简单易用,可视化开发。前文我亦已经给过在WINX中进行可视化开发的例子:

那么,现在就让我们开始剖析一下,WINX是如何做到可视化界面开发的?

 

可视化开发的途径

 

1. 制作专用的可视化编辑工具。

为特定的界面库制作专用的可视化编辑工具,这种方式看起来虽然是一种高代价的方式,但几乎所有的界面库无一例外地走了这一步。如:VCL,MFC,wxWidgets,QT,SmartWin,等等。WINX未来亦可能提供专用的可视化编辑工具。

 

2.  使用Windows资源编辑工具。

在没有专用的可视化编辑工具时,使用通用的Windows资源编辑工具是一个不错的主意。这种编辑工具不少,如Visual C++的资源编辑器(MFC的可视化编辑环境依附于它),Borland的Workshop等等。特点:

  • 兼容性好(Windows直接支持)。
  • 由于是纯粹的资源编辑,故此无法提供一些高级特性,如事件响应。
  • 由于通用,故此无法识别用户自定义控件(虽然允许出现用户自定义控件)。
  • 支持ActiveX控件。

WINX目前推荐你使用资源编辑工具进行可视化开发。

 

如何提供可视化的界面控件?

 

1. 提供ActiveX控件。

不可否认,ATL一定程度上是因为ActiveX控件而存在。如果你采用ATL/WTL开发,这可能是唯一的途径。虽然ActiveX是复杂的(无论是理解上还是实现上)。以后我们会有相应的内容描述ActiveX的相关内容,以及如何在WINX中实现ActiveX控件。

 

2. 提供Windows控件。

WINX是有界面库以来,第一个支持这种方式开发控件的库。通过它你可以让你的控件象Windows标准控件(Static、Edit、ListBox、ComboBox等等)一样使用。最为关键的是,这种控件比之ActiveX控件容易理解很多,也轻量很多。通过我下面的解释你将迅速理解并掌握它。

无论是MFC,ATL/WTL,还是我之前写的SW系统,无一例外地在窗口的Create函数上加点东西。

  • SW
创建窗口代码:
 调用CreateWindow创建窗口,并将窗口对象pWnd通过附加参数lpParam传递;
  • MFC
BOOL CWnd::CreateEx(DWORD dwExStyle, LPCTSTR lpszClassName,
    LPCTSTR lpszWindowName, DWORD dwStyle,
    
int  x,  int  y,  int  nWidth,  int  nHeight,
    HWND hWndParent, HMENU nIDorHMenu, LPVOID lpParam)
{
    CREATESTRUCT cs;
    cs.dwExStyle 
=  dwExStyle;
    cs.lpszClass 
=  lpszClassName;
    cs.lpszName 
=  lpszWindowName;
    cs.style 
=  dwStyle;
    cs.x 
=  x;
    cs.y 
=  y;
    cs.cx 
=  nWidth;
    cs.cy 
=  nHeight;
    cs.hwndParent 
=  hWndParent;
    cs.hMenu 
=  nIDorHMenu;
    cs.hInstance 
=  AfxGetInstanceHandle();
    cs.lpCreateParams 
=  lpParam;

    
if  ( ! PreCreateWindow(cs))
    {
        PostNcDestroy();
        
return  FALSE;
    }

    AfxHookWindowCreate(
this );
    HWND hWnd 
=  ::CreateWindowEx(cs.dwExStyle, cs.lpszClass,
            cs.lpszName, cs.style, cs.x, cs.y, cs.cx, cs.cy,
            cs.hwndParent, cs.hMenu, cs.hInstance, cs.lpCreateParams);

    
if  ( ! AfxUnhookWindowCreate())
        PostNcDestroy();        
//  cleanup if CreateWindowEx fails too soon

    ...
}
  • ATL/WTL
template  < class  TBase,  class  TWinTraits >
HWND CWindowImplBaseT
<  TBase, TWinTraits  > ::Create(HWND hWndParent, RECT &  rcPos, LPCTSTR szWindowName,
        DWORD dwStyle, DWORD dwExStyle, UINT nID, ATOM atom, LPVOID lpCreateParam)
{
    ATLASSERT(m_hWnd 
==  NULL);

    
if (atom  ==   0 )
        
return  NULL;

    _Module.AddCreateWndData(
&m_thunk.cd, this );

    
if (nID  ==   0   &&  (dwStyle  &  WS_CHILD))
        nID 
=  (UINT) this ;

    HWND hWnd 
=  ::CreateWindowEx(dwExStyle, (LPCTSTR)MAKELONG(atom,  0 ), szWindowName,
        dwStyle, rcPos.left, rcPos.top, rcPos.right 
-  rcPos.left,
        rcPos.bottom 
-  rcPos.top, hWndParent, (HMENU)nID,
        _Module.GetModuleInstance(), lpCreateParam);

    ATLASSERT(m_hWnd 
==  hWnd);

    
return  hWnd;
}

 

这意味着,通过程序代码动态创建的窗口,与通过对话框资源中创建创建子窗口的流程并不一致。所以,通过这些界面库实现的窗口类,如果不是ActiveX控件,将不能直接插入到对话框中。而在WINX中,Create窗口对象的过程,直接就是CreateWindow这个Windows API。那么,问题的关键在于,CreateWindow这个API(或者换句话说对话框)为什么居然可以知道WINX中C++窗口类,并且把它new出来?这的确是WINX让人感到magic的地方。我们下面来拨开这个谜团。

 

对话框创建WINX窗口类的过程

对话框CreateDialog初始化流程大概如下:

  1. 根据对话框资源ID,取得对话框资源数据。
  2. 由对话框资源数据,取得对话框各个子控件的初始化数据(详细参见CreateWindowEx),大概如下:
    • 子控件的窗口类名
    • 子控件的位置
    • 子控件的ID
    • 子控件的风格(Sytle,StyleEx)
  3. 调用CreateWindowEx函数创建子控件。

CreateWindowEx流程如下:

  1. 根据窗口类名,取得窗口类信息(如窗口过程等)。这一步要求该窗口类已经RegisterClass。
  2. 通过窗口类信息,创建Windows内核窗口对象。
  3. 发送WM_NCCREATE, WM_CREATE等消息给窗口过程。
  4. 返回Windows内核窗口对象的句柄(HWND)。

这所有的过程中,除了窗口过程获得了WM_NCCREATE, WM_CREATE等消息外,所有的流程都不受干预。所以关键在于WINX的窗口过程了。我们看看代码:

template  < class  WindowClass,  class  HandleClass  =  DefaultWindowHandle >
class  Window
{
public :
    
static  LRESULT CALLBACK WindowProc(
        HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
    {
        WindowClass
*  pWnd  =  (WindowClass * )WindowMap::GetWindow(hWnd);
        
if  (pWnd  ==  NULL)
        {
            
if  (message  !=  WM_NCCREATE)
                
return  pWnd -> InternalDefault(hWnd, message, wParam, lParam);
            LPCREATESTRUCT lpCS 
=  (LPCREATESTRUCT)lParam;
            
if  (lpCS -> lpCreateParams) {
                pWnd 
=  (WindowClass * )lpCS -> lpCreateParams;
                lpCS
-> lpCreateParams  =  NULL;
            }
            
else  {
                
if  (WindowClass::StackWindowObject) {
                    WINX_ASSERT(
! " WindowClass::StackWindowObject - unexpected! " );
                    
return  FALSE;
                }
                
else  {
                    pWnd 
=  WINX_NEW(WindowClass);
                }
            }
            WindowMap::SetWindow(hWnd, pWnd);
        }
        
return  pWnd -> ProcessMessage(hWnd, message, wParam, lParam);
    }
};

注:关于其中的WindowMap、StackWindowObject等,要了解详细的信息,请参见《剖析WINX的Hello程序》一文。

分析一下,你会觉得很有意思,因为WINX支持两种窗口对象的创建方式:

  1. 和MFC、ATL/WTL、SW系统类似,C++窗口对象(pWnd)先于Windows内核窗口对象(hWnd)生成。首先我们生成窗口对象pWnd,并通过CreateWindowEx附加参数lpParam传递。在WM_NCCREATE消息中取得pWnd,并将其与窗口句柄hWnd关联。
     
  2. C++窗口对象(pWnd)后于Windows内核窗口对象(hWnd)生成。CreateWindowEx 附加参数lpParam传入NULL(对话框就是这样做),此时WINX会主动new出一个窗口对象,并将其与窗口句柄hWnd关联。

哈哈,看到这里你可能会心一笑。现在,你无疑已经知道WINX是如何制作Windows控件了。你得承认,没有比这更容易实现的控件了。—— 那么,请始终牢牢记住一点:在WINX中,所有窗口类都可以直接放入对话框。甚至包括对话框,你亦可以将他插入到另一个对话框中(代码参考:tutorials/winx/step004-user-ctrl/3.superdialog/hello.cpp)。

 
CryoEM - 使用 ChimeraX 工具 操作 冷冻电镜的 MRC 密度图(Density Map) 教程 由冷冻电镜 CryoSparc 软件所生成的 Volume,需要观察其内部结构,建议使用 ChimeraX 进行操作。 阅读详情

相关推荐

【VisualStdio】手把手教你做一个上位机(1)控件设计布局

网上有很多形形色色的制作上位机教程,有些写的挺好的,但是过于单调。

m0_73409202的博客 5439

windows标准控件的介绍与使用

一、 Windows标准控件概述 (一)Windows标准控件 Windows系统提供的标准控件主要包括静态控件、按钮控件、编辑框控件、列表框控件、组合框控件等,如表所示。 Windows标准控件的类型 类别 MFC类控件类型 静态控件CStatic Static Text, Group Box 按钮控件CBut

holybin的专栏 1万+

UART全功能测试指南:环路/DMA/RS485/硬件流控实战

UART(通用异步收发器)是嵌入式系统中最基础的串行通信接口,其核心原理基于起始位、数据位、校验位与停止位的异步帧结构,依赖精确的波特率时钟同步与采样重建机制。在工业与物联网场景中,UART不仅需保障基本通信可靠性,更需支持DMA卸载、RS485半双工自动方向控制、RTS/CTS硬件流控等进阶能力,以提升实时性、抗干扰性与系统资源效率。典型应用涵盖调试日志输出、传感器数据采集、Modbus RTU总线通信及固件空中升级。本指南聚焦UART外设测试实践,覆盖环路自检、DMA吞吐验证、RS485时序对齐、硬件流

weixin_42599908的博客 134

给CListBox增加个性化的ToolTip

转载请注明来源:http://blog.youkuaiyun.com/caoshiying/article/details/52218409 新建一个MFC应用程序项目,无项目设置要求 添加一个对话框,添加一个ListBox,无属性设置要求,ListBox宽度最好设小点,以突出效果。 添加CShel...

cheqiane9431的博客 213

STM32+W5500实战:5分钟搞定FreeModbus TCP移植(附完整代码)

本文详细介绍了如何在STM32微控制器上,结合W5500以太网芯片,快速完成FreeModbus TCP协议栈的移植,构建稳定可靠的工业级Modbus TCP服务器。内容涵盖硬件连接、软件架构、驱动适配、核心移植代码实现及调试优化技巧,旨在提供可直接应用于实际项目的完整解决方案。

life6的博客 879

化工设计软件:AutoCAD Plant 3D二次开发_(1).AutoCADPlant3D概述

AutoCAD Plant 3D 是一款专为化工行业设计的三维工厂设计和建模软件。它基于AutoCAD平台,提供了强大的三维建模功能和专业的化工设计工具,帮助工程师和设计师在工厂设计过程中提高效率和准确性。AutoCAD Plant 3D不仅能够创建详细的三维模型,还可以进行管道设计、设备布置、支架设计等复杂任务。通过上述案例,我们可以看出 AutoCAD Plant 3D 在化工厂设计中的强大功能和优势。该软件不仅提供了丰富的建模工具和专业的设计功能,还支持二次开发,使用户能够根据具体需求进行定制化操作。

kkchenjj的博客 1108

白乔原创:VC之美化界面篇

导读:   本文专题讨论VC中的界面美化,适用于具有中等VC水平的读者。读者最好具有以下VC基础:   1. 大致了解MFC框架的基本运作原理;   2. 熟悉Windows消息机制,熟悉MFC的消息映射和反射机制;   3. 熟悉OOP理论和技术;   本文根据笔者多年的开发经验,并结合简单的例子一一展开,希望对读者有所帮助。   1. 美化界面之开题篇   相信使用过《金山毒霸》、《瑞

zk520的专栏 1001

在jetson上对fastdeploy进行源码编译(完整版)

在大多数Linux发行版中,你可以使用包管理器安装Python开发包。根据jetpack的版本选择对应的推理库版本。在~/.bashrc中写入这三行。

如果想成为中心,那么就到中心去吧。 679

[转]MFC学习总结(五)

http://www.cnblogs.com/cy163/archive/2007/06/27/532871.html51. 如何获得其他程序的图标,并显示在View中 [问题提出] 有的时候,如:类资源管理器会遇到获得程序图标并显示的操作,如何实现呢? [解决方法] SDK函数SHGetFileInfo来获得有关文件的很多信息:如大小图标,属性,类型等.  [程序实现] 建立名为My的SDI

blueblood_jing的专栏 1917

uni-app - 最新实现将 uniapp 项目打包编译为 H5 网站,并上传部署到 web 服务器进行发布预览(从打包到发布完整流程步骤,Hbuilder 编译打包 h5 发行到 web 服务器)

uniapp,打包h5,打包编译H5网站,怎么打包h5,uniapp打包成H5部署到服务器教程,uniapp打包H5页面发布到服务器,uniapp开发,打包成H5部署到服务器_uniapp打包h5,uniapp如何打包h5项目,怎么把项目打包成H5,uniapp如何打包成H5并且放到web端上,打包成h5部署到服务器的步骤,打包发行到h5报错怎么办,如何将uniapp打包的h5网站放到服务器上,编译打包后怎么放到web服务器中,如何将uniapp开发的H5打包并部署到服务器,部署使用uniapp开发的h5

🏆 前端领域优质创作者 1万+

前言:为什么要学习爬虫和逆向,该如何学习?

学习爬虫和逆向技术是当今数字化时代的重要技能,尤其在数据分析、安全研究、自动化工具开发等领域有广泛应用。以下是详细的学习理由、路径和方法:

数据知道的博客 1万+

致歉 —— 关于《WINX如何做到可视化界面开发》

在《WINX如何做到可视化界面开发》一文中我曾说预计昨天(周六)会完成它,结果到今天才将其补充完毕,很不好意思,这里向各位读者致歉。

QBox/Golang/CERL/StdExt/TPL/WinxGui - 许式伟的专栏 1878

Vue - 在纯 HTML 普通项目中实现组件化,让原生 html 项目支持引入 *.vue 组件 / 组件与组件间的互相引用等,完美解决了引入组件出现的跨域问题(保姆级详细教程,完整示例源码及插件)

html中使用vue组件,在HTML页面中引入vue组件,HTML界面利用http-vue-loader.js以组件方式引入vue文件,使用http-vue-loader引入组件出现报错,在html页面使用http-vue-loader插件引入组件报跨域错误,如何解决http-vue-loader引用组件时出现跨域问题,纯html原生web项目引入vue后如何实现组件引入,使用http-vue-loader插件控制台报错跨域,http-vue-loader跨域怎么办官方文档,html页面如何引入.vu

🏆 前端领域优质创作者 3910

winx 印象

看了winx的介绍,计划很宏大。http://winxcn.blogspot.com/2006/09/004-hello-winx.html>>尽管目前尚且没没有专门针对WINX进行可视化界面开发的工具,但是它是WINX的发展方向.当没有可视化界面开发的工具的时候,我肯定不会用winx来进行开发。 替代方法是:一些人会选用c++ builder来编程;而我会采用delphi来写界面,用

ftfind的专栏 1180

Data-Structures-and-Algorithm-Analysis-in-Java.pdf

作者: Weiss, Mark A. 出版社: Addison Wesley Data Structures and Algorithm Analysis in Java is an “advanced algorithms” book that fits between traditional CS2 and Algorithms Analysis courses. In the old ACM Curriculum Guidelines, this course was known as CS7. This text is for readers who want to learn good programming and algorithm analysis skills simultaneously so that they can develop such programs with the maximum amo...

OV9734 DATASHEET,完整规格书

OV9734完整规格书,包括电气参数,尺寸规格,寄存器配置表等

欢迎使用 FreeCode for VS60/VS2005 Add-in

FreeCode是WinxGui for VS60/VS2005的可视化界面开发插件。 下载:FreeCode2.zip作者:fox1996 / QWL1996参见:http://www.winxgui.cn/blog/?p=163 一 安装 VS60菜单 Tools-&gt;Customeze…-&gt;Add-ins and Macro Files -&gt;Browse…选择Fre...

javatoyou 113

计算机控制技术及应用

《计算机控制技术及应用》通过总结作者的科研成果和吸收国内外的先进理论、方法和技术,以计算机控制系统的网络化、开放化、智能化和集成化发展趋势为主线索,主要介绍计算机控制系统的基本概念和计算机控制系统的典型形式,计算机控制系统的数学描述与基本分析方法,以及数字PID控制器、最少拍控制系统、达林算法、状态变量设计法等设计方法及其各种改进算法。重点突出计算机控制系统输入输出通道接口的设计方法和典型控制系统的设计案例与实现方法等。

剖析WINX的Hello程序

概述我们已经介绍了Windows SDK的Hello程序,它的流程主要分为三个步骤: 注册窗口类(RegisterClass)。并且我们详细解释了为何要有窗口类,为何要RegisterClass。 创建并显示窗口(CreateWindow and ShowWindow)。 消息循环(MessageLoop)。即:取得消息 -> 分派消息 -> 处理消息。

QBox/Golang/CERL/StdExt/TPL/WinxGui - 许式伟的专栏 4630

VB摄像头监控

该VB模块可对摄像头捕获的画面进行录像等,可在创建的窗口进行控制

WINX窗口类对象的内存管理

WINX窗口类对象的内存管理许式伟2006-12-29 为了引入WINX窗口类对象的内存管理(生命周期模型),我绕了一大圈子。实在是,内存管理太重要了,花多少口舌介绍它都不过分。我曾经见到这样一句话:"C++程序员觉得内存管理太重要了,所以一定要自己进行管理;Java/C#程序员觉得内存管理太重要了,所以一定不能自己去管理"。从某种意义上说,两者都是对的。 我在《C++内存管理变革》系列中提到

软件开发资料汇总 298
上一篇: 剖析WINX的Hello程序
下一篇: Windows程序内部运行机制
iiprogram
博客等级 码龄25年 1068粉丝 1515原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值