wtl体系结构_wtl mdi-程序员宅基地

技术标签: 笔记  

应用程序类型 描述
sdi 单文本
多线程sdi 一进程,多窗口
mdi 框架内,多窗口
对话 基于对话框

多线程sdi新建sdi窗口,应用程序,都可作com服务器.钢筋条工具栏等的容器.命令栏可把窗口加至工具栏中.有了rebar,按工具栏实现工具条和菜单.这样,菜单也有关联图标.
可选视:

描述
简单窗口 处理WM_PAINT,直接画时.
表单 对话框模版,应用程序操作
列表框 加串.
编辑框 给你编辑
列表视 控制面板
树视 用于层级关系,
富文本 富文本

程序线程

atl,有个_Module,为CAppModule/CServerAppModule(com)实例.应用程序具1/多ui线程.单ui调用全局Run.

int Run(LPTSTR /*lpstrCmdLine*/ = NULL, int nCmdShow = SW_SHOWDEFAULT)
{
    
    CMessageLoop theLoop;
    _Module.AddMessageLoop(&theLoop);
    CMainFrame wndMain;
    if (wndMain.CreateEx() == NULL)
    {
    
        ATLTRACE(_T("创建主窗口失败"));
        return 0;
    }
    wndMain.ShowWindow(nCmdShow);
    int nRet = theLoop.Run();
    _Module.RemoveMessageLoop();
    return nRet;
}

CMessageLoop内循环消息.放入全局消息映射组.按线程索引.有过滤消息/处理空闲,界面元素可有自己的空闲处理.将自身加入消息循环的处理器数组中即可.Run包含主消息映射:

MSG m_msg;
int CMessageLoop::Run()
{
    
    for (;;)
    {
    
        while (!::PeekMessage(&m_msg, NULL, 0, 0, PM_NOREMOVE))
            DoIdleHandlers();//空闲
        bRet = ::GetMessage(&m_msg, NULL, 0, 0);
        if(bRet == -1)continue;
        else if(!bRet)break;
        if (!DoMessageFilters(&m_msg))
        {
    
            ::TranslateMessage(&m_msg);
            ::DispatchMessage(&m_msg);
        }//分发
    }
    return (int)m_msg.wParam;
}

多界面线程,则用wtl线程管理器.

int nRet = m_dwCount;
DWORD dwRet;
while(m_dwCount > 0)
{
    
    dwRet = ::MsgWaitForMultipleObjects(m_dwCount, m_arrThreadHandles,FALSE, INFINITE, QS_ALLINPUT);
    if(dwRet >= WAIT_OBJECT_0 && dwRet <= (WAIT_OBJECT_0 + m_dwCount - 1))
        RemoveThread(dwRet - WAIT_OBJECT_0);//删线程
    else if(dwRet == (WAIT_OBJECT_0 + m_dwCount))
    {
    
        ::GetMessage(&msg, NULL, 0, 0);
        if(msg.message == WM_USER)
            AddThread(_T(""), SW_SHOWNORMAL);//加线程,加了就启动
    }
}

移出线程/收到WM_USER消息时,断开wait.也可在线管中加入自己的消息处理器.当有多种窗口类型时,要创建窗口,只需要任意窗口执行.

::PostThreadMessage(_Module.m_dwMainThreadID, WM_USER, 0, 0L);

界面线程,有个线程过程.线管用了MsgWaitForMultipleObjects,因而最多MAXIMUM_WAIT_OBJECTS(64)线程,最多63个窗口.

框架

wtl,两类窗口:框架/视图窗口.框架提供标题栏/边框,代码处理工具条/菜单.视图客户区.
线程创建主框架,在WM_CREATE中创建视图.sdi拥有个视图类,调用创建就好了.
MDI,则在CMDIFrameWindowImpl<>::CreateMDIClient()中建立叫MDICLIENT的窗口.将CMDIChildWindowImpl<>作为子窗口(有视图),即mdi1/多窗口(有边框/标题栏等).

LRESULT OnCreate(UINT, WPARAM, LPARAM, BOOL&)
{
    
    //创建工具栏(命令栏)
    HWND hWndCmdBar = m_CmdBar.Create(m_hWnd, rcDefault,NULL, ATL_SIMPLE_CMDBAR_PANE_STYLE);
    //加框架菜单(工具栏菜单)
    m_CmdBar.AttachMenu(GetMenu());//加图标
    m_CmdBar.LoadImages(IDR_MAINFRAME);
    //删旧菜单,
    SetMenu(NULL);
    HWND hWndToolBar = CreateSimpleToolBarCtrl(m_hWnd, IDR_MAINFRAME,FALSE, ATL_SIMPLE_TOOLBAR_PANE_STYLE);
    CreateSimpleReBar(ATL_SIMPLE_REBAR_NOBORDER_STYLE);//工具条,关联至命令栏
    AddSimpleReBarBand(hWndCmdBar);
//钢筋条.是个容器,命令栏,工具栏.
    AddSimpleReBarBand(hWndToolBar, NULL, TRUE);
    CreateSimpleStatusBar();
    m_hWndClient = m_view.Create(m_hWnd, rcDefault, NULL,WS_CHILD | WS_VISIBLE | WS_CLIPSIBLINGS | WS_CLIPCHILDREN,WS_EX_CLIENTEDGE);//句柄.
    UIAddToolBar(hWndToolBar);//运行时改变
    UISetCheck(ID_VIEW_TOOLBAR, 1);
    UISetCheck(ID_VIEW_STATUS_BAR, 1);
    CMessageLoop* pLoop = _Module.GetMessageLoop();
    pLoop->AddMessageFilter(this);
    pLoop->AddIdleHandler(this);//两个过滤
    return 0;
}
class CMainFrame :
    public CFrameWindowImpl<CMainFrame>,
    public CUpdateUI<CMainFrame>,
    public CMessageFilter,
    public CIdleHandler
//主框架

CUpdateUI<>支持更新界面映射.

视图

class CMyView : public CWindowImpl<CMyView>
{
    
public:
    DECLARE_WND_CLASS(NULL)
    BOOL PreTranslateMessage(MSG* pMsg)
    {
    
        pMsg;return FALSE;
    }
    BEGIN_MSG_MAP(CMyView)
        MESSAGE_HANDLER(WM_PAINT, OnPaint)
    END_MSG_MAP()
    LRESULT OnPaint(UINT, WPARAM, LPARAM, BOOL&)
    {
    
        CPaintDC dc(m_hWnd);//待办:加绘画代码
        return 0;
    }
};

多线程SDI和MDI差不多,但没有PreTranslateMessage方法.sdi利用它,在框架处理前分发处理消息,一般是转发消息给视图类.
要支持鼠标键盘,则加相应消息处理函数至消息映射.如果想基于控件,则加入AtlCtrls.h.
要加入滚动条:

class CMyView : public CScrollWindowImpl<CMyView>
{
    
public:
    typedef CScrollWindowImpl<CMyView> parent;
    BEGIN_MSG_MAP(CMyView)
        CHAIN_MSG_MAP(parent)//链上.
    END_MSG_MAP()
    void DoPaint(CDCHandle dc)//函数换了.
    {
    //画整个视图,不是`WM_PAINT`
    }
}

要指定滚动范围,大小或起点,要在WM_CREATE中初化.
框架窗口会改变视图窗口大小.你还可用分割器窗口,这样,一边树视,一边列视.
你要改变框架窗口,让分割器窗口作为视图.如框架中有:

CSplitterWindow m_view;
CTreeViewCtrl m_tree;
CListViewCtrl m_list;

创建时:

RECT rect;GetClientRect(&rect);//取客户区.
m_hWndClient = m_view.Create(m_hWnd, rect,NULL, WS_CHILD | WS_VISIBLE);//视图创建客户
m_tree.Create(m_view, rcDefault, NULL,WS_CHILD | WS_VISIBLE | TVS_HASBUTTONS | TVS_HASLINES | TVS_LINESATROOT,WS_EX_CLIENTEDGE);//树视
m_list.Create(m_view, rcDefault,NULL, WS_CHILD | WS_VISIBLE | LVS_REPORT, WS_EX_CLIENTEDGE);//列视
m_view.SetSplitterPanes(m_tree, m_list);
m_view.SetSplitterPos();//无参时,中线为0,出现在最左边,隐藏了左窗口.

分割器视图一样,以框架父窗口,也可用rcDefault.在WM_SIZE时调整.
创建分割器窗口后,要创建子窗口,用SetSplitterPanes确定分割条位置.

更新界面

使能菜单,可带标记,或单选/多选.菜单可有图标和文字.运行时,都可改变.工具栏只是菜单的外化.因而可有效分组.更新界面让你指定哪些界面运行时可改变.通过更新界面宏来实现.

BEGIN_UPDATE_UI_MAP(CMainFrame)
    UPDATE_ELEMENT(ID_FILE_SAVERESULTS, UPDUI_MENUPOPUP | UPDUI_TOOLBAR)
    UPDATE_ELEMENT(ID_VIEW_TOOLBAR, UPDUI_MENUPOPUP)
    UPDATE_ELEMENT(ID_VIEW_STATUS_BAR, UPDUI_MENUPOPUP)
END_UPDATE_UI_MAP()

wtl建立数组来保存这些信息.
改变状态:

命令
菜单,工具条按钮 UIEnable
勾号 UISetCheck
菜单文字 UISetText
选入选出 UISetRadio/UISetCheck

如:

BOOL bSelected = GetSelected();//条件
//是否选中文本.
UIEnable(ID_EDIT_CUT, bSelected);//是否允许

可放入相应处理函数/OnIdle中,检查类变量来决定元素状态.
还要确定,是否都更新了,调用CUpdateUI<>的某个方法来加入界面元件至列表,已自动加入主菜单.
其他通过UIAddMenuBar()和UIAddToolBar()等来加入菜单/工具栏.
设置工具栏状态后,用UIUpdateToolBar更新状态.而菜单不必这样,因为是动态生成子菜单的.而UIUpdateMenuBar为恢复初始状态.
UISetRadio(多个只单选)很少用,要自己编码.

对话框

wtl加了输入验证和回调函数.如:你想在用户改变打开对话框中文件夹时动作,从CFileDialogImpl<>继承,并实现OnFolderChange函数.

class CMyFileDialog : public CFileDialogImpl<CMyFileDialog>
{
    
public:
    CMyFileDialog(BOOL b)
        : CFileDialogImpl<CMyFileDialog>(b) {
     }
    void OnFolderChange(LPOFNOTIFY lpon)
    {
    
        char strFolder[MAX_PATH];
        if (GetFolderPath(strFolder, sizeof(strFolder)) > 0)//基类的.取路径.
        {
    
            MessageBox(strFolder);
        }
    }
};

这样,改变文件夹时就执行了.

控件

WTL为所有的Win32和通用控件提供了封装类.
两种使用方法:如对话框中有控件,将控件HWND依附至封装对象,用其方法来访问控件,简化读写控件数据和处理通知消息.
二,把类加入视图类的继承中.

class CMyView : public CWindowImpl<CMyView, CListBox>
//该窗口,从CListBox继承,

GetWndClassName取得窗口类名字.消息会传给你,如未处理由父窗口搞定.
发生事件时,多数窗口控件会发送通知父窗口.由窗口来处理.如要处理按钮点击时,只需处理BN_CLICKED通知,由按钮发送给窗口类.或从CContainedWindow<>继承按钮窗口来处理点击事件.处理通知消息更快,继承麻烦.
wtl还提供了命令栏.其他有用类:

描述
CBitmapButton 位图代替标题,可提供列表,在正常状态,失效, 推入和鼠标落在按钮上等时切换
CHyperLink 超链接,点击时,打开网页.
CWaitCursor 构造时等待,析构时还原.
CCheckListViewCtrl 检查列表框.
CMultiPaneStatusBarCtrl 多面板状态栏.
版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
本文链接:https://blog.csdn.net/fqbqrr/article/details/117396350

智能推荐

PCL_Tutorial2-1.7-点云保存PNG_pcl::io:savepng-程序员宅基地

文章浏览阅读4.4k次。1.7-savingPNG介绍代码详情函数详解savePNGFile()源码savePNGFile()源码提示savePNGFile()推荐用法处理结果代码链接介绍PCL提供了将点云的值保存到PNG图像文件的可能性。这只能用有有序的云来完成,因为结果图像的行和列将与云中的行和列完全对应。例如,如果您从类似Kinect或Xtion的传感器中获取了点云,则可以使用它来检索与该云匹配的640x480 RGB图像。代码详情#include <pcl / io / pcd_io.h>#incl_pcl::io:savepng

知乎问答:程序员在咖啡店编程,喝什么咖啡容易吸引妹纸?-程序员宅基地

文章浏览阅读936次。吸引妹子的关键点不在于喝什么咖啡,主要在于竖立哪种男性人设。能把人设在几分钟内快速固定下来,也就不愁吸引对口的妹子了。我有几个备选方案,仅供参考。1. 运动型男生左手单手俯卧撑,右手在键盘上敲代码。你雄壮的腰腹肌肉群活灵活现,简直就是移动的春药。2.幽默男生花 20 块找一个托(最好是老同学 or 同事)坐你对面。每当你侃侃而谈,他便满面涨红、放声大笑、不能自已。他笑的越弱_咖啡厅写代码

【笔试面试】腾讯WXG 面委会面复盘总结 --一次深刻的教训_腾讯面委会面试是什么-程序员宅基地

文章浏览阅读1.2w次,点赞5次,收藏5次。今天 (应该是昨天了,昨晚太晚了没发出去)下午参加了腾讯WXG的面委会面试。前面在牛客上搜索了面委会相关的面经普遍反映面委会较难,因为都是微信的核心大佬,问的问题也会比较深。昨晚还蛮紧张的,晚上都没睡好。面试使用的是腾讯会议,时间到了面试官准时进入会议。照例是简单的自我介绍,然后是几个常见的基础问题:例如数据库索引,什么时候索引会失效、设计模式等。这部分比较普通,问的也不是很多,不再赘述。现在回想下,大部分还是简历上写的技能点。接下来面试官让打开项目的代码,对着代码讲解思路。我笔记本上没有这部分代码,所_腾讯面委会面试是什么

AI绘画自动生成器:艺术创作的新浪潮-程序员宅基地

文章浏览阅读382次,点赞3次,收藏4次。AI绘画自动生成器是一种利用人工智能技术,特别是深度学习算法,来自动创建视觉艺术作品的软件工具。这些工具通常基于神经网络模型,如生成对抗网络(GANs),通过学习大量的图像数据来生成新的图像。AI绘画自动生成器作为艺术与科技结合的产物,正在开启艺术创作的新篇章。它们不仅为艺术家和设计师提供了新的工具,也为普通用户提供了探索艺术的机会。随着技术的不断进步,我们可以预见,AI绘画自动生成器将在未来的创意产业中发挥越来越重要的作用。

获取list集合中重复的元素_list找到重复的元素-程序员宅基地

文章浏览阅读1.6w次,点赞3次,收藏13次。老规矩,二话不说直接上代码:package com.poinne17.test;import org.apache.commons.collections.CollectionUtils;import org.junit.Test;import java.util.*;/** * @author:Pionner17 * @date: 2017/9/3 22:41 * @em_list找到重复的元素

系统运维—1.0 解压缩_winzip收费-程序员宅基地

文章浏览阅读1k次。一、zip和unzip  一般情况下,windows中的压缩包都是rar或者zip格式,对应的压缩软件为winzip和winrar。winzip是免费的,winrar是收费的。rar比zip压缩率更高,即同样的文件压缩完后体积更小,同时因为国内盗版,以及winrar安装后,右击默认压缩为rar的原因,导致国内的rar的使用率远超zip。  放眼全世界,zip的使用率反而远超rar,在ubuntu中,zip是默认安装的,免费使用,而rar需要额外安装,并且收费。故在linux中一般情况下,我们使用zip格_winzip收费

随便推点

Flutter ListView ListView.build ListView.separated_flutter listview.separated和listview.builder-程序员宅基地

文章浏览阅读1.7k次。理解为ListView 的三种形式吧ListView 默认构造但是这种方式创建的列表存在一个问题:对于那些长列表或者需要较昂贵渲染开销的子组件,即使还没有出现在屏幕中但仍然会被ListView所创建,这将是一项较大的开销,使用不当可能引起性能问题甚至卡顿直接返回的是每一行的Widget,相当于ios的row。行高按Widget(cell)高设置ListView.build 就和io..._flutter listview.separated和listview.builder

2021 最新前端面试题及答案-程序员宅基地

文章浏览阅读1.4k次,点赞4次,收藏14次。废话不多说直接上干货1.js运行机制JavaScript单线程,任务需要排队执行同步任务进入主线程排队,异步任务进入事件队列排队等待被推入主线程执行定时器的延迟时间为0并不是立刻执行,只是代表相比于其他定时器更早的被执行以宏任务和微任务进一步理解js执行机制整段代码作为宏任务开始执行,执行过程中宏任务和微任务进入相应的队列中整段代码执行结束,看微任务队列中是否有任务等待执行,如果有则执行所有的微任务,直到微任务队列中的任务执行完毕,如果没有则继续执行新的宏任务执行新的宏任务,凡是在..._前端面试

linux基本概述-程序员宅基地

文章浏览阅读1k次。(3)若没有查到,则将请求发给根域DNS服务器,并依序从根域查找顶级域,由顶级查找二级域,二级域查找三级,直至找到要解析的地址或名字,即向客户机所在网络的DNS服务器发出应答信息,DNS服务器收到应答后现在缓存中存储,然后,将解析结果发给客户机。(3)若没有查到,则将请求发给根域DNS服务器,并依序从根域查找顶级域,由顶级查找二级域,二级域查找三级,直至找到要解析的地址或名字,即向客户机所在网络的DNS服务器发出应答信息,DNS服务器收到应答后现在缓存中存储,然后,将解析结果发给客户机。_linux

JavaScript学习手册十三:HTML DOM——文档元素的操作(一)_javascript学习手册十三:html dom——文档元素的操作(一)-程序员宅基地

文章浏览阅读7.9k次,点赞26次,收藏66次。HTML DOM——文档元素的操作1、通过id获取文档元素任务描述相关知识什么是DOM文档元素节点树通过id获取文档元素代码文件2、通过类名获取文档元素任务描述相关知识通过类名获取文档元素代码文件3、通过标签名获取文档元素任务描述相关知识通过标签名获取文档元素获取标签内部的子元素代码文件4、html5中获取元素的方法一任务描述相关知识css选择器querySelector的用法代码文件5、html5中获取元素的方法二任务描述相关知识querySelectorAll的用法代码文件6、节点树上的操作任务描述相关_javascript学习手册十三:html dom——文档元素的操作(一)

《LeetCode刷题》172. 阶乘后的零(java篇)_java 给定一个整数n,返回n!结果尾数中零的数量-程序员宅基地

文章浏览阅读132次。《LeetCode学习》172. 阶乘后的零(java篇)_java 给定一个整数n,返回n!结果尾数中零的数量

php 公众号消息提醒,如何开启公众号消息提醒功能-程序员宅基地

文章浏览阅读426次。请注意,本文将要给大家分享的并不是开启公众号的安全操作风险提醒,而是当公众号粉丝给公众号发消息的时候,公众号的管理员和运营者如何能在手机上立即收到消息通知,以及在手机上回复粉丝消息。第一步:授权1、在微信中点击右上角+,然后选择“添加朋友”,然后选择“公众号”,然后输入“微小助”并关注该公众号。2、进入微小助公众号,然后点击底部菜单【新增授权】,如下图所示:3、然后会打开一个温馨提示页面。请一定要..._php微信公众号服务提示

推荐文章

热门文章

相关标签