注册窗口类

一、MFC应用程序与win32应用程序的区别

  Win32编程:是调用Win32SDK中的API函数进行编程,注册窗口类,建立窗口,现实窗口,设置消息循环……等等的方式建立Windows程序,以前的Windows程序都这样开发的,写程序要写大量代码。

  MFC库:后来微软为了方便编程人员开发,将Win32SDK中的函数进行C/C++封装,于是就是MFC库(架构),开发程序比以往的Win32SDK方式更加简便快捷。

  相同:调用的API都是Win32SDK的API

  不同:MFC的程序执行起来慢,而且用MFC写程序不自由

   Win32SDK开发速度慢,而且要编写的代码多得惊人

1.win32应用程序注册窗口类

  一般在Win32下编程,简单的步骤是:
  (1)设计窗口类
  (2) 注册窗口类
  (3)Create窗口
  (4)显示窗口
  (5)更新窗口
  (6)消息循环(关键)

  我们用Visual Studio创建一个win32项目上会自动生成一个注册窗口类。如下:

 1 ATOM MyRegisterClass(HINSTANCE hInstance)
 2 {
 3     WNDCLASSEX wcex;
 4 
 5     wcex.cbSize = sizeof(WNDCLASSEX);                    // UINT    cbSize 
 6 
 7     wcex.style          = CS_HREDRAW | CS_VREDRAW;       // UINT    style
 8     wcex.lpfnWndProc    = WndProc;              // WNDPROC  lpfnWndProc
 9     wcex.cbClsExtra     = 0;                  // int     cbClsExtra
10     wcex.cbWndExtra     = 0;                  // int     cbWndExtra
11     wcex.hInstance      = hInstance;             // HINSTANCE hInstance
12     wcex.hIcon          = LoadIcon(hInstance, MAKEINTRESOURCE(IDI_WIN32PROJECT5));  // HICON hIcon
13     wcex.hCursor        = LoadCursor(NULL, IDC_ARROW);  // HCURSOR  hCursor
14     wcex.hbrBackground  = (HBRUSH)(COLOR_WINDOW+1);    // HBRUSH   hbrBackground
15     wcex.lpszMenuName   = MAKEINTRESOURCE(IDC_WIN32PROJECT5); // LPCTSTR lpszMenuName
16     wcex.lpszClassName  = szWindowClass;          // LPCTSTR   lpszClassName
17     wcex.hIconSm        = LoadIcon(wcex.hInstance, MAKEINTRESOURCE(IDI_SMALL));     // HICON hIconSm
18 
19     return RegisterClassEx(&wcex);
20 }

WNDCLASSEX结构体中:
  cbSize:存储表示该结构大小的字节数,通常以sizeof(WNDCLASSEX)的形式对该域进行设置

  style :存储表示窗口类风格的整数,它决定了该窗口的外观和内在特征。

  lpfnWndProc指向窗口处理函数(回调函数)。

  cbClsExtra为窗口类的额外信息做记录,初始化为0

  cbWndExtra记录窗口实例的额外信息,系统初始为0

  hIcon :存储该类窗口的图标的句柄

  hCursor:存贮表示窗口类光标的句柄,该域必须是一个光标资源的句柄。

  hbrBackground窗口类的背景刷,为背景刷句柄,也可以为系统颜色值,如果颜色值已给出,则必须转化为以下的HBRUSH的值

  lpszMenuName:存储以空结尾的指定类菜单资源名的字符串指针,类菜单资源名已经在资源文件中进行了定义。

  lpszClassName:存储以空结尾的字符串的指针,或存储一个原子元素(ATOM)。

  hIConSm:存储该类窗口小图标的句柄。

 2.MFC应用程序注册窗口类

  MFC下编程,省去了窗口设计步骤,直接通过GetClassInfo()来获取标准窗口的信息。

  MFC中,#32770 代表标准窗口类

BOOL CBBBApp::SetRegisterClass()
{
    WNDCLASS wndcls;
    ZeroMemory(&wndcls, sizeof(WNDCLASS));   // start with NULL

    HINSTANCE hInst;
    hInst = AfxGetInstanceHandle();
    ASSERT(hInst != 0);
GetClassInfo(hInst, _T("#32770"), &wndcls); wndcls.lpszClassName = _T("YourClassName"); if (FALSE == AfxRegisterClass(&wndcls)) { AfxThrowResourceException(); return FALSE; } return TRUE; }

1)AfxGetInstanceHandle

  作用获取当前实例句柄

  原型HINSTANCE AFXAPI AfxGetInstanceHandle( );

  返回值返回应用程序当前实例的句柄。如果是从与MFC的USRDLL版本连接的DLL内调用的,则返回代表DLL的HINSTANCE值

2)GetClassInfo

  作用:获得窗体类信息

  原型

  BOOL GetClassInfo(      
      HINSTANCE hInstance,
      LPCTSTR lpClassName,
      LPWNDCLASS lpWndClass
  );

  参数hInstance,创建类的应用程序实例

          lpClassName,类名

       lpWndClass,指向WNDCLASS结构体的指针

  返回值:返回非零成功,返回零不成功

3)AfxRegisterClass

  作用:注册类

  原型:BOOL AFXAPI AfxRegisterClass( WNDCLASS* lpWndClass );

  参数:指向WNDCLASS结构体的指针

  返回值:若类成功注册则返回零,否则非零。

4)AfxThrowResourceException

  这个函数抛出一个资源异常。通常在不能载入Windows资源的时候调用这个函数。

3.注册窗口类的目的

  

  1)注册窗口类以后同一类窗口都用一套WindowProc。有统一的行为

  在我们构造一个窗口类结构后,我们需要将这个类结构指针加入到system atom table 即SAT中,这样系统就可以通过查找这张表来找到用户自定义的窗口类

  2)注册好窗口类之后就可以用FindWindow函数来找到这个窗口类并获得其句柄,然后即可以向该窗口发送消息。

    HWND hComm = ::FindWindow(_T("YourClassName"), NULL);
    if (NULL == hComm)  return FALSE;
if (hComm && ::IsWindow(hComm)) { DWORD dwResult = 0; LRESULT lResult = ::SendMessageTimeout(hComm, WM_NULL, 0, 0, SMTO_ABORTIFHUNG, 500, &dwResult); }

1)FindWindow
  作用:该函数获得一个顶层窗口的句柄,该窗口的类名和窗口名与给定的字符串相匹配。

  原型

  HWND FindWindow(
    LPCSTR lpClassName,      // {即窗口的类名}
    LPCSTR lpWindowName   // {即窗口的标题} 如果此参数为NULL,则匹配所有窗口名。
  );
  返回值
    如果函数执行成功,则返回值是拥有指定窗口类名或窗口名的窗口的句柄。
    如果函数执行失败,则返回值为 NULL
 
2)FindWindowEX
  //FindWindowEx 比 FindWindow 多出两个句柄参数:
  FindWindowEx(
    Parent: HWND;     {要查找子窗口的父窗口句柄}
    Child: HWND;       {子窗口句柄}
    ClassName: PChar; {}
    WindowName: PChar {}
  ): HWND;
  {
  如果 Parent 是 0, 则函数以桌面窗口为父窗口, 查找桌面窗口的所有子窗口;
  如果  是 HWND_MESSAGE, 函数仅查找所有消息窗口;
  子窗口必须是 Parent 窗口的直接子窗口;
  如果 Child 是 0, 查找从 Parent 的第一个子窗口开始;
  如果 Parent 和 Child 同时是 0, 则函数查找所有的顶层窗口及消息窗口.
  }
 

2)SendMessageTimeout

  作用:该函数将指定的消息发送到一个或多个窗口。

  原型

  LRESULT SendMessageTimeout(
    HWND hwnd,        // 其窗口程序将接收消息的窗口的句柄。
                // 如果此参数为HWND_BROADCAST,则消息将被发送到系统中所有顶层窗口,包括无效或不可见的非自身拥有的窗口。
    UINT Msg,            // 指定被发送的消息
    WPARAM wParam,// 指定附加的消息指定信息。
    LPARAM IParam,  // 指定附加的消息指定信息。
    UINT fuFlags,  // 指定如何发送消息。
              // SMTO_ABORTIFHUNG:如果接收进程处于“hung”状态,不等待超时周期结束就返回。
              // SMTO_BLOCK:阻止调用线程处理其他任何请求,直到函数返回。
  
              // SMTO_NORMAL:调用线程等待函数返回时,不被阻止处理其他请求。
              // SMTO_NOTIMEOUTIFNOTHUNG:Windows 95及更高版本:如果接收线程没被挂起,当超时周期结束时不返回。
    UIUT uTimeout,  // 为超时周期指定以毫秒为单位的持续时间。如果GetLastError返回零,表明函数超时
    LPDWORD lpdwResultult // 指定消息处理的结果,依赖于所发送的消息
  );

  返回值:若函数调用成功则返回非零值,若失败或超时返回零。

 
原文地址:https://www.cnblogs.com/SnailProgramer/p/4236022.html