




版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领
文档简介
WTL在开发者之间的悄悄已经超过一年了,传闻它是基于ATL的,并在微软.这理所当然的引起了ATL开发者社区的主意.这些人从ATL1.1开始,ATL控件书写UI代码,但是他们发现,他们的所写的代码常常就是纯的Win32GDI代码.我告诉您,WTL并没有多大不同.是不是让人失望不,因为ATL只是COM进行了简单的封装,这也是ATL的强大之处.是的,ATL您必COM.ATLCOM所作的努力比起来,简直微不足道.这跟那些需要把主要精力花费在学习类库本身,忽略COM的库是完全不同的.WTL与此类似.您需要懂得Win32窗术和GDI.只要您懂得,学习WTL就似清风抚面,再简单不过了.如果您不懂这些,那么您最好使用VB来写UI代码.WTL有什么它给各种类型的应用程序提供了一个基本的框架.注意,虽然您没有MFC那样的文档/视结构,但是您有视(views).在WTL有大量的代码来管理视,而且加入您自己的代码也很容易.WTL有AppWizard,可以生成SDI,MDI和多线程SDI程序多线程SDIIE或WindowsExplorer很像.它看起来是打开了多个另外,您的程序可以是基于框的,也可以是基于视的.视可以是基于CWindowImpl的,也可以是基于控件,甚至是IE里的一个HTML页.您可以选择您的程序是否需要一个rebarcommandbarCE-liketoolbar/或statusbar.另外,您的程序可以主持ActiveX控件,以及成为一个COM服务器这里有几个关于视的选项WTL提供splitter窗口类(这样在一个视里您可以有两个窗口)和scroll窗口类(这样您的窗口可以比它显示的"视"小).WTLMFC的UpDateUI的东西,但是它们不是很一样-主要的区别是您需要把需要更新的映射标注出来,然后您在您的类里加入执行UpdateUI的代码.DDX/DDVWTL也支持,同样类似MFC,但有不同.您必须加一个宏映射来实现DoDataExchange,然后加现在WTL也有GDI类了.然而,HDC的封装类就像CWindow一样,-它几乎没有加入任何新的功能.不过,在WTL,你可以得到meta文件和OpenGL支持.最有价值的我猜应该是DC的那些继承类-WTL有支持,甚至打印预览.当然也有GDI对象的封装.诸如画笔,画刷,区域等.WTL对所有的Win32(和W2K)通用框进行了封装.同样尽管简单,但是它的确使请求字体或者文件变合成了旧的AtlControls.h,新加了一些封装类.这些封装类封装W2K控件,Win32的"控件",CommandBar,bitmapbutton,hyperlink和waitcursor.WTL最终把消息分离带入了ATL!一些新的MSG映射宏将消息分离,调用您类里的消息处理函数.消息处理最后,WTL还有一些实用类.最重要的是CString.不错,它是从MFC克隆得到的(copyonwrite),具有(在我知道的范围内)MFC版本的所有方法.还有查找文件的API的封装类,以及CRect,CSizeandCPoint.如果您打算写一个Win32界面程序,我建议您在考虑MFC之前,先试试WTL.使用WTL来写您的代码,程序将变得小巧些,也更有效率些.使用WTL,您还将得到ATL支持COM好处.MFC没有对COM的支持.您可以在2000年一月份的平台SDK中找到WTL.在MSI选项页的SourceCodesection下WTLWTL了,而且提供了我所希望的功能.我在WTLBytesize(译文)的文章列出WTL在本文中,我将描述一下WTL些简单的例子来演示如何使用它的那些特征.希WTL型,供您在AppWizard取下表对这些应用程序进行了描述WTL系结构的一部分描SDI–MultipleThreadsMDI–在框架内,您可以有零个或多个子窗Dialog你可能还是首次听说多线程SDI用担心,它的概念很容易理解.一个多线程SDI序启动后它会有一个窗口档要程序要再创建一个文档时,问题就出现了--SDI程序只能显示一个文档.为了解决这个问题,多线程SDI建了另一个SDI口.看起来是一个新的实例在运行,实际上它不过是原来的进程创建了一个新的窗口,并把它依附到进程的一个新线程.IE口除了多线程所有这些应用程序都可以作为服务器,并且应用程序向导(AppWizard)为此提供了一个选项.另外应用程序向导还可以让你指定该程序是否主持ActiveX控件.令人费解的是,不同的程序类型,选取"HostActiveXControls"的地方不同.除框应用程序外的其他类型在第一页上选取,(toolbar),状态条(statusbar)和视窗口(View如果选取了"Toolbar"选项,你可以通过"Rebar"选择是否将工具条放入IERebar果你选取了Rebar,你就可以通过框架窗口(framewindow)的成员m_hWndToolBar(后边会有详细的描述)来访问它.你可以按照你的意愿,在里边加入其他的工具条.选取了"Rebar"后,你可以决定是否选取"CommandBar".CommandbarCEcommandbar只是WTL现,而在CE,commandbar一个系统窗口类(systemwindowclass).Commandbar用,它能够把窗口也加入到工具条中去.如果你选取了这个选项被当做toolbar实现.这使菜单项也可以有关联的图标,并且当你移动鼠标到一个菜单项上时,该菜单项会被置成高亮.从Office97来,Office有上第二页还有指定程序是否使用视的选项(多半你想要使用视描Generic一个简单的窗口.此类窗口允许程序员编写WM_PAINT消息的处理函数.适用于需要直接进行paint的文档.这类视具有一个框模版.适用于带ActiveX控件的窗口.应用程序来操作这些控件List这个视是个listbox.它最简单的形式意味着可以通过调用AddString()方法来添加字符这个视是个editcontrol.本质上,它提供了一个像Notepad一样的程序List这个视是个listview通用控件.用这个控件来显示相关的项(比如,Explorer主持的ListView,所有的项都是控制面板Tree这个视是个treeview通用控件.这个适用于具有层次关系的数据,比如,可以用它来显示数据库的schema.顶层分支为表和过程,次级的分支为表中的字段.Rich这个视是个richedit控件,HTML这个视主持了一个IEWebBrowser控件.它把主持的一个webpage当成一个视本文的例子需要一个框模版,同时还需要菜单,因此Formview是个理想的选择程序线跟ATL一样,WTL程序也需要一个_Module全局变量来保存全局数据,方便应用级代码.在WTL中,每个应用程序具有一个或者多个UI线程.WTL使用两种方式来管理这些线程.如果应用程序只有一个UI线程(除了多线程SDI以外,其他程序类型默认只有一个UI线程),线程调用全局函数run():intRun(LPTSTR/*lpstrCmdLine*/=NULL,intnCmdShow={CMainFramewndMain;if(wndMain.CreateEx()=={ATLTRACE(_T("Mainwindowcreationfailed!\n"));return0;}intnRet=theLoop.Run();returnnRet;}线程的消息循环包含在CMessageLoop内部.函数创建了一个CMessageLoop实例,把它放入全局的消息循环映射(messageloopmap)数组.以线程ID为索引,线程中运行的其他的代码可以到这个实例.消息循环对象包含了messagefilter和idlehandler.运行在这个UI线程的UI元件(UIelement)可以有它自己的idlehandler,程的消息队列为空时运行【译注:通过CMessageLoop::AddIdleHandler()把这个UI元件加入到CMessageLoop的idlehandler数组中】.CMessageLoop::Run()包含了UI线程的主消息映射(mainmessagemap).下边是它的伪代码:MSGint{for{while(!::PeekMessage(&m_msg,NULL,0,0,PM_NOREMOVE))bRet=::GetMessage(&m_msg,NULL,0,if(bRet==-elseif(!bRet)if{ }}return }可以看到,这个函数推动着消息队列.没有消息时,运行到线程的idlehander.如果在队列中检测到消息,把它取出来,传给每个messagefilter.如果消息没有被这些函数处理,它将按照通常的方式,发送到如果程序有超过一个的UI线程,可以用WTL的线程管理器,多线程SDI就是这样做的主线程作为一个管理者线程,它会为每个新窗口创建一个新的新线程.主要流程如下:intnRet=m_dwCount;DWORDdwRet;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);elseif(dwRet==(WAIT_OBJECT_0+{::GetMessage(&msg,NULL,0,0);if(msgmessage==WM_USER)}}那些线程句柄放在一个数组中.线程通过AddThread()加入到数组(同时启动线程),RemoveThread()从数组移走.wait语句在两种情况下会被打断:线程(将线程从数组中移出)或线程收到了WM_USER消息(一个线程在一个新线程里新建了一个窗口).线程管理者为程序中的一个类,因此可以在循环中加入自己的messagehandler,比如,当程序有不止一种窗口类型时.创建一个新的窗口非常简单,只需在任意一个::PostThreadMessage(_Modulem_dwMainThreadID,WM_USER,0,这个循环会一直运行下去,直到所有的UI线程都关闭了UI线程具有一个threadprocedure,UI线程的Run()方法一样.不过,由于线程管理者使用了MsgWaitForMultipleObjects()这意味者最多只能有UM_WAIT_OBJECTS-1个UI线程,这也意味着最多只能创建63个窗口.框WTL实际上是两类窗口:框架窗口和视图窗口.正如名字所暗示的那样,框架窗口为窗口提供标题窗口,视图覆盖了框架窗口的客户区.客户区是指框架窗口没有被诸如状态条,工具条之类的修饰部件所遮线程会创建主框架窗口的一个实例,创建视图的工作由主框架窗口的WM_CREATE消息处理函数完成.对于SDI程序来说,这个过程很简单.把视图类的一个实例作为主框架类的一个成员,调用视图类的Create()方法即可.MDI程序稍微有些不同,MDI主框架窗口通过 ()建立一个名为MDI 的窗口.这个客户窗口将CMDIChildWindowImpl<>窗口当做它的子窗口,子窗口有一个视图.这也反映了这么一个事实,MDI程框架窗口的OnCreate()很有意思,让我看看LRESULT RAM,LPARAM,{//createcommandbarHWNDhWndCmdBar=m_CmdBar.Create(m_hWnd,rcDefault,NULL,ATL_SIMPLE_CMDBAR_PANE_STYLE);//attach//loadcommandbarimages//remove HWNDhWndToolBar=CreateSimpleToolBarCtrl(m_hWnd,IDR_MAINFRAME,FALSE,ATL_SIMPLE_TOOLBAR_PANE_STYLE);AddSimpleReBarBand(hWndToolBar,NULL,TRUE); =m_view.Create(m_hWnd,rcDefault,WS_CHILD|WS_VISIBLE|WS_CLIPSIBLINGS|WS_CLIPCHILDREN,UISetCheck(ID_VIEW_TOOLBAR,1);CMessageLoop*pLoop=_Module.GetMessageLoop();return0;}这是从一个SDI程序拿来的一段代码,该程序有一个基于commandbar的工具条和一个状态条.函的第一行创建了一个commandbar实例,然后对它进行初始化,在其中加入框架窗口的菜单和工具条位图.这段代码先将菜单取出,把所有的下拉菜单转换为工具条按钮,并将菜单保存在一个变量中,以备后用.给人的感觉是菜单是由工具条实现的-那我们就把它叫做工具条菜单(toolbar)吧.然后CommandBar将程序工具条的图标装入imagelist并将它们的ID保存在数组中..进行比较,这些ID跟imagelist中的工具条按钮图标是相关联的.如果比较成功,则将关联的图标加到菜单项上去.ID的菜单项和工具条按钮具有相同的图标.接下来创建工具条并把它关联到commandbar,然后创建状态条和视图.可以看到视图的HWND存放在框架窗口的m_hWnd变量中.WM_SIZEhandler中会用到.当框架窗口改变大小时自身于此同时也要考虑状态条和mandbar.在下来的三行(从调用UIAddToolBar()开始)用来显示在运行时会改变状态的UI项(UIitem).文章后面还会重提这个话题.最后,消息循环(messageloop),你应该还记得该消息循环存放在一全局数组中.GetMessageLoop()取得当前线程的消息循环,加入框架窗口的messagefilter和idlehandler,分别默认是PreTranslateMessage()OnIdle().classCMainFrame:publicCFrameWindowImpl<CMainFrame>,publicCUpdateUI<CMainFrame>,publicCMessageFilter,publicCidleHandler后两个抽象类宣称了框架窗口类实现了PreTranslateMessage()OnIdle().CUpdateUI<>继承表示框架类支持UIupdatemap.视classCMyView:public{{return}MESSAGE_HANDLER(WM_PAINT,OnPaint)LRESULT RAM,LPARAM,{CPaintDC//TODO:Addyourdrawingcodereturn}上面是一个SDI程序的视图类.多线程SDI和MDI的视图类在本质上也跟这个一样,但他们没有PreTranslateMessage()方法.SDI程序就是使用这个函数,赶在框架类处理消息之前把消息抓住.PreTranslateMessage()在SDI的框架类中的实现是,直接将消息转发给视图类.这里显示的视图实际上没有做什么工作.你应该自己在OnPaint()函数中加入画出文档内容的代码.如果需要支持输入,如鼠标的点击和键盘的按键,你应该加入相应消息处理函数到类和映射中.可以看到这个窗口是从CWindowImpl<>继承下来的,Win32控件的话,就应该从定义在AtlCtrls.h文件中某个WTL类继承.classCMyView:public{typedefCScrollWindowImpl<CMyView>parent;voidDoPaint(CDCHandle{}分.取而代之的是,在你的类里实现DoPaint(),在这里你需要画出整个视图.如果你想指定滚动的范围,大小或起点,你需要加上处理WM_CREATE消息的函数,把这些初始化代码放到里边.为视图所填充.在大多数情况下,这样就够了.但是当你想要一个具有WindowsExplorer样子的程序时,该怎么办呢?WindowsExplorer的窗口包含了一个treeview和一listview,还有两者之间的分割条.WTL的解决方案很简单:使用splitter窗口!为此你需要改变一下框架窗口,让它创建splitter窗口的一个实例作为它的视图.例如,在你的框架类里CSplitterWindowm_view;CTreeViewCtrlm_tree;CListViewCtrlm_list;//getthe rect,sothatwesetthesplitterinitial//andwecangetthesplitterbarintheRECTGetm_hWnd=m_view.Create(m_hWnd,rect,NULL,WS_CHILD|WS_VISIBLE);m_tree.Create(m_view,rcDefault,WS_CHILD|WS_VISIBLE|TVS_HASBUTTONS|TVS_HASLINES|TVS_LINESATROOT,NULL,WS_CHILD|WS_VISIBLE|LVS_REPORT,WS_EX_m_view.SetSplitterPanes(m_tree,m_list);Splitter窗口如同一个视图,将框架窗口作为它的父窗口.在这段代码里,我将框架窗口客户区的实际大小传给了splitter窗口.我也可以在这里使用rcDefault,因为一旦框架窗口创建完成,框架窗口就会转发WM_SIZE消息给splitter.这样splitter可以马上改变自身的大小来填充框架.然而,当我准备使用不带参数SetSplitterPos(),把分割条设置于窗口中线时,出现了问题.Splitter窗口使用它的大小来决定中线的位置,由于rcDefault告诉窗口它的大小是0(因此中线的位置也是0),从而意味着分割条将出现在z最左创建了splitter窗口后,你需要创建那些你想要分割的窗口了.它们将作为splitter窗口的子窗口被创建.最后你将这些子窗口通过SetSplitterPanes()加到splitter窗口中去,并确定分割条的位置所在.UI菜单项可以被设置为有效或无效,可以带check记号或着像radio按钮一样,在一组菜单项中同时有且只有一个能被check.此外,菜单项还可以带图标和文字.所有的这些状态都可以在运行时根据程序中的某的一部分被置成有效或无效,推入推出.UIupdate机制允许你指定哪些UI元件(UIelement)的状态可以在运行时改变.WTL使用如下的UIupdate映射来实现这能:UPDATE_ELEMENT(ID_FILE_SAVERESULTS,UPDUI_ POPUP|UPDUI_TOOLBAR)UPDATE_ELEMENT(ID_VIEW_TOOLBAR,UPDUI_POPUP)UPDATE_ELEMENT(ID_VIEW_STATUS_BAR,UPDUI_ 这个例子三个菜单项在运行时有一个状态需要显示,其中的一个,ID_FILE_SAVERESULTS,还有一个工具条按钮跟它相关联.WTL通过建立一个数组来保存这些信息.为此你需要完成两方面的工作:首先是UI元件的状态.如果是菜单项,你可以使用UIEnable()使能该菜单项,UISetCheck()设置check记号UISetText()改变菜单的文字.如果是工具条按钮,那么你使用UIEnable()使能该按钮,UISetCheck()或者UISetRadio()决定按钮是推入还是推出.下边的代码根据是否有文本被选中,来使能Cut菜单项和工具条按钮:BOOLbSelected=GetSelected();UIEnable(ID_EDIT_CUT,bSelected);的处理函数中),或者放入OnIdle()方法,通过检查某个类变量来决定元件的状态.其次是确定各个UI元件是否都被更新了,CUpdateUI<>的某个方法将UI元件加入到列表中.主菜单已被自动加入,但是其他的任何菜单和所有的工具条必须分别通过调用UIAddBar()和其他还有一堆事情要注意.首先,设置了工具条的状态后,使用UIUpdateToolBar()以使工具条状态更新.对于菜单,你不需如此,因为子菜单是动态生成的.UIUpdate 用是把菜单恢复到初始状态,如果你改变过某些项的文字,调用UIUpdate 尽管还有一个方法UISetRadio(),但是还没有一个把几个菜单项或者工具条按钮当做radio按钮组(也就框ATL的框支持一向很好,对此WTL新增了通用框的封装.本质上是为框加入了输入验证和回调函数.比如,你想在用户改变年Open框中的文件夹时有所动作,那么你应该从CFileDialogImpl<>继承一个类,实现OnFolderChange():classCMyFileDialog:public{:CFileDialogImpl<CMyFileDialog>(b){}voidOnFolderChange(LPOFNOTIFYlpon){char{}}当文件夹的路径改变时,CFileDialogImpl<>调用OnFolderChange().该函数使用基类的控WTL为所有的Win
温馨提示
- 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
- 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
- 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
- 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
- 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
- 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
- 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。
最新文档
- 乡镇土地承包经营合同范本
- 化妆品代加工合同范本
- 2024福建龙岩市水利投资发展有限公司所属分公司招聘7人笔试参考题库附带答案详解
- 2025年桨扇发动机项目立项申请报告模板
- 第19课 亚非拉国家的新发展(教学设计)-2024-2025学年九年级历史下册素养提升教学设计(统编版)
- 2025年眼用抗感染药项目规划申请报告
- 2025年金融数据加密机项目提案报告模稿
- 2025年细菌类诊断抗原项目规划申请报告模稿
- 2025年智能电网配电设备项目申请报告模板
- 会计能力实训报告范文
- 初三物理常识试卷单选题100道及答案
- 高中英语新课程标准解读课件
- 1.2《友邦惊诧论》教学设计-【中职专用】高二语文同步讲堂(高教版2024·拓展模块上册)
- 质量管理体系过程识别矩阵图及与条款对照表
- 加班调休单(最新版)
- 智慧金字塔立体篇第四册、第五册答案全解
- 导论公共财政学概论.ppt
- 2022年人力资源管理师课程表
- 梦中的婚礼钢琴简谱(共6页)
- 新生儿心理的发生
- 2013八年级上英语培优参考word
评论
0/150
提交评论