ATL的GUI程序设计(3)

2016-02-19 16:40 0 1 收藏

在这个颜值当道,屌丝闪边的时代,拼不过颜值拼内涵,只有知识丰富才能提升一个人的内在气质和修养,所谓人丑就要多学习,今天图老师给大家分享ATL的GUI程序设计(3),希望可以对大家能有小小的帮助。

【 tulaoshi.com - 编程语言 】

  第二章 一个最简单窗口程序的转型

  我知道,可能会有很多朋友对上一章的Hello, World!ATL版不以为然,因为它并不能算是什么ATL程序毕竟它只不过是有了个CComModule而已。不过不管怎样我还是要说,它几乎仍然拥有了一个ATL GUI程序的所有组成部分:入口、初始化、程序体、卸载

  等等!也许你会突然打断我,还有注册窗口类、消息循环呢?

  当然,对于一个完整的GUI程序来讲,这也是必要的。

  貌似废话

  不清楚你是否已经为本章的内容做好了准备,因为下面我们就要动真格的了。不过考虑到本书的读者群中可能会存在着相当一部分了解MFC却对Win32 GUI的基本原理和流程不甚熟悉的朋友,所以李马特别为你们准备了这一节的内容。SDK的粉丝们可以跳过这一节,如果你们觉得李马讲的有些拖沓冗长的话。

  那么,我还是先以一个标准的Win32 SDK程序开始:

  

//////////////////////////////////////////////////////////////////////////// ATL的GUI程序设计配套源代码// 第二章 一个最简单窗口程序的转型// 工程名称:HelloSDK// 作者:李马// http://www.titilima.cn//////////////////////////////////////////////////////////////////////////#include windows.h#include tchar.hLRESULT CALLBACK HelloWndProc( HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam ){  switch ( uMsg )  {  case WM_DESTROY:    {      PostQuitMessage( 0 );    }    break;  case WM_PAINT:    {      HDC hdc;      PAINTSTRUCT ps;      hdc = BeginPaint( hWnd, &ps );      DrawText( hdc, _T("Hello, SDK!"), -1, &ps.rcPaint, DT_CENTER | DT_VCENTER | DT_SINGLELINE );      EndPaint( hWnd, &ps );    }    break;  default:    return DefWindowProc( hWnd, uMsg, wParam, lParam );  }  return 0;}BOOL InitApplication( HINSTANCE hInstance ){  WNDCLASS wc;  wc.cbClsExtra  = 0;  wc.cbWndExtra  = 0;  wc.hbrBackground = (HBRUSH)GetStockObject( WHITE_BRUSH );  wc.hCursor    = LoadCursor( NULL, IDC_ARROW );  wc.hIcon     = LoadIcon( NULL, IDI_APPLICATION );  wc.hInstance   = hInstance;  wc.lpfnWndProc  = HelloWndProc;  wc.lpszClassName = _T("HelloSDK");  wc.lpszMenuName = NULL;  wc.style     = CS_HREDRAW | CS_VREDRAW;  return RegisterClass( &wc );}int WINAPI _tWinMain( HINSTANCE hInstance, HINSTANCE hPrevInstance, LPTSTR lpCmdLine, int nShowCmd ){  // 注册窗口类  InitApplication( hInstance );  // 创建窗口  HWND hWnd = CreateWindow( _T("HelloSDK"), _T("Hello SDK"), WS_OVERLAPPEDWINDOW, CW_USEDEFAULT, CW_USEDEFAULT,    CW_USEDEFAULT, CW_USEDEFAULT, NULL, NULL, hInstance, NULL );  ShowWindow( hWnd, nShowCmd );  UpdateWindow( hWnd );  // 消息循环  MSG msg;  while ( GetMessage( &msg, NULL, 0, 0 ) )  {    TranslateMessage( &msg );    DispatchMessage( &msg );  }  return msg.wParam;}

  不知道你是否会觉得这段代码有些冗长?事实上,这个程序已经体现了Win32 GUI程序运行的所有流程(请注意,我并不会对这些代码进行详细的解释,因为我已经假设你已经了解了这些代码具体行为的必要细节。如果不是这样的话,请参考相关的书籍或者MSDN):

本文示例代码或素材下载

(本文来源于图老师网站,更多请访问https://www.tulaoshi.com/bianchengyuyan/)注册窗口类的部分。在这个程序中,InitApplication函数完成了这一工作。窗口类的概念类似于OO(面向对象)中的类,所有你在Windows中能看到的窗口都是某个特定窗口类的一份实例。但是,窗口类并非任何一种OOP语言中的类它所包括的并不是通称的属性和方法(在C++中称作成员变量和成员函数),而是属性和响应。这个区别可能会使你感到费解,我会在下一章中为你详细介绍因为ATL中对窗口的封装类将这一点体现得十分淋漓尽致。 创建窗口的部分。在通常的SDK代码里,这些代码被封装在一个名为InitInstance的函数中。这段代码所做的工作一般是创建窗口并将其显示出来。 消息循环。Windows是一个基于消息机制的操作系统,各个窗口之间的通信也主要是靠Windows消息来完成的。而程序中的消息循环也就是将本程序UI线程中的消息队列中提取各种消息,进行处理(如果有必要的话)之后分发给各个消息的属主窗口(或者说是目标窗口)。

  在这里需要指出的是,HelloWndProc是我们自己定义的一个函数,我们需要用它来控制我们对特定窗口消息的特定响应。我们只需要在注册窗口类之前,将这个函数的地址(也就是函数名)赋值给WNDCLASS::lpfnWndProc成员就可以了。这个函数我们自己不需要进行调用,它的调用是当我们的窗口收到窗口消息后,由Windows完成的。在这个回调函数中,我们的处理是这样的:

WM_DESTROY。在窗口被销毁的时候,窗口会收到此消息。在这里,我们会调用PostQuitMessage,用以向当前UI线程的消息队列之中发送一条WM_QUIT消息,GetMessage在收到这条消息后,会返回FALSE,也就结束了消息循环,WinMain也就结束了。 WM_PAINT。在窗口需要绘制的时候,窗口会收到此消息。在这里我们只是简单的在窗口的中间绘制了一行文字Hello, SDK!。 其它消息。这些消息都是我们不关心的,所以我们将其交由系统默认的窗口过程DefWindowProc来处理。

  这段代码貌似冗长,但实际上还是很有条理的,你可以根据它以及我以上的解说来对照这个程序的ATL版本。

  ATL等同品

(本文来源于图老师网站,更多请访问https://www.tulaoshi.com/bianchengyuyan/)

  在写作这本书的时候,我总是希望我每次都能够能使用让你不太陌生的代码来循序渐进地引导你。考虑再三,对于Hello, ATL!的这个程序,我决定先把它的WinMain展现给你:

  

int WINAPI _tWinMain( HINSTANCE hInstance, HINSTANCE hPrevInstance, LPTSTR lpCmdLine, int nShowCmd ){  _Module.Init( NULL, hInstance );  // 创建窗口  CHelloATLWnd wnd;  wnd.Create( NULL, CHelloATLWnd::rcDefault, _T("Hello ATL") );  wnd.ShowWindow( nShowCmd );  wnd.UpdateWindow();  // 消息循环  MSG msg;  while ( GetMessage( &msg, NULL, 0, 0 ) )  {    TranslateMessage( &msg );    DispatchMessage( &msg );  }  _Module.Term();  return msg.wParam;}

  OK,上一章介绍过的_Module又出现在你的眼前了不过还是没有什么特别的变化,仍然是那熟悉的Init和Term。而且,正如山哟还是那座山一样,消息循环哟也仍然是那个消息循环。当然,你肯定也发现了那寥寥的变化:CHelloATLWnd是什么?在我将它的代码展现给你之前,你可能会做出这样的猜想:

这是一个C++类,它对Win32窗口类进行了封装。 这个类封装了大多数窗口操作的API函数,诸如CreateWindow、ShowWindow、UpdateWindow。 窗口类的注册可能也是在这个C++类中完成的。

  好,打住,这就够了。让我们来撩开CHelloATLWnd那貌似神秘的面纱吧,赶紧着。

  

class CHelloATLWnd : public CWindowImpl CHelloATLWnd, CWindow, CWinTraits WS_OVERLAPPEDWINDOW  {public:  CHelloATLWnd()  {    CWndClassInfo& wci   = GetWndClassInfo();    wci.m_bSystemCursor  = TRUE;    wci.m_lpszCursorID   = IDC_ARROW;    wci.m_wc.hbrBackground = (HBRUSH)GetStockObject( WHITE_BRUSH );    wci.m_wc.hIcon     = LoadIcon( NULL, IDI_APPLICATION );  }public:  DECLARE_WND_CLASS( _T("HelloATL") )public:  BEGIN_MSG_MAP( CHelloATLWnd )    MESSAGE_HANDLER( WM_DESTROY, OnDestroy )    MESSAGE_HANDLER( WM_PAINT, OnPaint )  END_MSG_MAP()public:  LRESULT OnDestroy( UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& hHandled )  {    ::PostQuitMessage( 0 );    return 0;  }  LRESULT OnPaint( UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& hHandled )  {    HDC hdc;    PAINTSTRUCT ps;    hdc = BeginPaint( &ps );    DrawText( hdc, _T("Hello, ATL!"), -1, &ps.rcPaint, DT_CENTER | DT_VCENTER | DT_SINGLELINE );    EndPaint( &ps );    return 0;  }};

本文示例代码或素材下载

(本文来源于图老师网站,更多请访问https://www.tulaoshi.com/bianchengyuyan/)

来源:https://www.tulaoshi.com/n/20160219/1612715.html

延伸阅读
标签: Web开发
一、使用Ajax的主要原因 1、通过适当的Ajax应用达到更好的用户体验; 2、把以前的一些服务器负担的工作转嫁到客户端,利于客户端闲置的处理能力来处理,减轻服务器和带宽的负担,从而达到节约ISP的空间及带宽租用成本的目的。 二、引用 Ajax这个概念的最早提出者Jesse James Garrett认为: Ajax是Asynchronous JavaScript and XML的缩...
标签: Java JAVA基础
一:理解多线程 多线程是这样一种机制,它允许在程序中并发执行多个指令流,每个指令流都称为一个线程,彼此间互相独立。 线程又称为轻量级进程,它和进程一样拥有独立的执行控制,由操作系统负责调度,区别在于线程没有独立的存储空间,而是和所属进程中的其它线程共享一个存储空间,这使得线程间的通信远较进程简单。 ...
   Java Applet 是用Java 语言编写的一些小应用程序,这些程序是直接嵌入到页面中,由支持Java的浏览器(IE 或 Nescape)解释执行能够产生特殊效果的程序。它可以大大提高Web页面的交互能力和动态执行能力。包含Applet的网页被称为Java-powered页,可以称其为Java支持的网页。 当用户访问这样的网页时,Applet被下载到用户的计算机上...
本节主要介绍Turbo C程序设计的基本步骤及如何编译、调试和运行源程序。并给出Turbo C的常用编辑命令。最后介绍Turbo C编译、连接和运行时的常见错误。 一、Turbo C程序设计基本步骤 程序设计方法包括三个基本步骤: 第一步: 分析问题。 第二步: 画出程序的基本轮廓。 第三步: 实现该程序。 3a. 编写程序 3b. 测试和调试程...
  Java程序设计语言作为典型的面向对象程序设计语言,早已经占据了一块相当牢固的地位。在众多网友都推出自己的Java学习资源的时候,我也按捺不住来写一个帖子作为自己进行Java程序设计语言学习经常参考的材料总结,以享各位网友。   首先向大家推荐的是进行Java程序设计必需的开发环境, Java SDK。这一部分还是...

经验教程

995

收藏

65
微博分享 QQ分享 QQ空间 手机页面 收藏网站 回到头部