• 注册窗口类


    一、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 // 指定消息处理的结果,依赖于所发送的消息
      );

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

     
  • 相关阅读:
    (补充)移除动态添加的控件
    (非技术)遇见讨饭者的思考
    datalist或datagrid的数据源是数组的时候怎么写绑定?
    (原创)一步一步学Remoting之二:激活模式
    一步一步学Remoting系列文章
    如何向某网址Post信息,并得到CookieContainer以便以后直接通过验证(续)
    (原创)一步一步学Remoting之六:事件(2)
    (原创)一步一步学Remoting之五:异步操作
    【收藏】根据拼音首字母筛选人名
    (原创)一步一步学Remoting之四:承载方式(1)
  • 原文地址:https://www.cnblogs.com/SnailProgramer/p/4236022.html
Copyright © 2020-2023  润新知