zl程序教程

您现在的位置是:首页 >  其他

当前栏目

注册窗口类 registerclass

注册 窗口
2023-09-11 14:16:46 时间

window把窗口以不同的类别进行设计,通过不同的类别来管理不同的资源,体现模块化管理的思想。以mfc为例Button类别有ccheckbox,cbutton,radiobutton等 ,Static类别有cstatic、staticgroup等。
 
一个应用程序在创建某个类型的窗口前,必须首先注册该“窗口类”(Windows Class)。注意,这里不是C++类的类。Register Window把窗口过程、窗口类型以及其他类型信息和要登记的窗口类关联起来。
“窗口类”的数据结构

“窗口类”是Windows系统的数据结构,可以把它理解为Windows系统的类型定义,而Windows窗口则是相应“窗口类”的实例。Windows使用一个结构来描述“窗口类”,其定义如下:
typedef struct _WNDCLASSEX { 
UINT cbSize; //该结构的字节数
UINT style; //窗口类的风格
WNDPROC lpfnWndProc; //窗口过程
int cbClsExtra; 
int cbWndExtra; 
HANDLE hInstance; //该窗口类的窗口过程所属的应用实例
HICON hIcon; //该窗口类所用的像标
HCURSOR hCursor; //该窗口类所用的光标
HBRUSH hbrBackground; //该窗口类所用的背景刷
LPCTSTR lpszMenuName; //该窗口类所用的菜单资源
LPCTSTR lpszClassName; //该窗口类的名称
HICON hIconSm; //该窗口类所用的小像标
} WNDCLASSEX; 
从“窗口类”的定义可以看出,它包含了一个窗口的重要信息,如窗口风格、窗口过程、显示和绘制窗口所需要的信息,等等。关于窗口过程,将在后面消息映射等有关章节作详细论述。
Windows系统在初始化时,会注册(Register)一些全局的“窗口类”,例如通用控制窗口类。应用程序在创建自己的窗口时,首先必须注册自己的窗口类。
这个窗口结构体最最重要的就是窗口类别名称(LPCTSTR lpszClassName),这个名称限制了是属于哪一种类。
下面序列说明:

static LRESULT CALLBACK mywndproc( HWND hwnd, UINT nid, WPARAM wparm, LPARAM lparm );
hwnd m_myhwnd = null;
 m_myhwnd = CreateWindowEx(0, _T("Button"), _T("first"), WS_DISABLED, CW_USEDEFAULT,CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT
  , NULL, NULL,0,0);
 SetWindowLong( m_myhwnd, GWL_WNDPROC, reinterpret_cast<int>(mywndproc));
static LRESULT CALLBACK mywndproc( HWND hwnd, UINT nid, WPARAM wparm, LPARAM lparm )
{
 switch( nid )
 {
 case 10:
  {
   AfxMessageBox("first");
   break;
  }
 case 11:
  {
   AfxMessageBox("first11");
   break;
  }
  
 default:
  CString str;
  str.Format( "%d", nid);
  //AfxMessageBox(str);
 }
 return 0;
}
 
这样就写完了一个窗口,你可以通过::sendmessage或postmessage向窗口发送消息。注意::必须要带上(api),若不带上是mfc cwd里面的成员函数。
此时你会发现怎么没有注册窗口呢,而是直接创建窗口呢。问的很好,因为此处使用了注册了得窗口类Button,故不需要再注册窗口类,若此处窗口类不是”Button"或者也不是注册了得窗口类,则创建窗口失败,m_myhwnd为空。
 
 
通过registerClass和RegisterClassEx函数返回一个原子。什么是原子?所有注册窗口类的名字被保存在一个原子表的内部,以USER32。由类注册函数的返回值是原子。您还可以检索一个窗口类,该类的窗口通过GetClassWord(HWND,GCW_ATOM)要求其类原子的原子。原子可以转换为整数的原子通过的MAKEINTATOM的宏,然后就可以使用函数接受字符串或原子的形式中的类名。最常见的情况是lpClassName参数CreateWindow的宏观和CreateWindowEx函数。不太常用,你也可以作为的lpClassName的getClassInfo并GetClassInfoEx功能参数使用。
 (虽然你为什么会做到这一点我无法弄清楚。为了使原子传递到摆在首位GetClassInfo,你必须注册类(因为那是什么返回原子),在这种情况下,为什么你要求有关类的信息,你注册了吗?)转换类原子的类的名称,你可以创建一个该类的虚拟窗口,然后做上述GetClassWord(HWND,GCW_ATOM)的。或者您可以采取的事实,从GetClassInfoEx函数的返回值是原子类,转换为一个BOOL的优势。这可以让你做转换,而无需创建一个虚拟的窗口。 (请注意,然而,GetClassInfoEx的返回值是不是原子在Windows
 95的派生操作系统。)但是,什么是原子?不多,真的。当然,它可以节省你不必像CreateWindow的函数传递一个字符串,但它确实是替换字符串与一个整数,你现在有一个全局变量中保存供以后使用。什么是一个字符串,你可以硬编码现在是一个原子,你必须跟踪。目前还不清楚,你实际上有赢得什么。我想你可以用它快速检查一个窗口是否属于一个特定的类。你得到这个类的原子(通过GetClassInfo,说),然后得到窗口的原子,并加以比较。但你不能缓存类的原子,因为类可能会得到未注册和重新注册(这将给它一个新的原子数)。你不能预取类原子,因为类可能尚未被登记在你预取点。
 (如上所述,你可以不缓存预取的价值了。),所以这种情况是相当多的非起动无论如何,你可能也使用GetClassName函数和比较你要找的类生成的类名为。换句话说,窗口类的原子是不合时宜的。替换对话框类一样,这是一个Win32 API的那些泛泛从未真正得到掉在地上,但必须进行向前向后兼容性。但至少现在,你知道它们是什么。

原文:https://blog.csdn.net/hanyujianke/article/details/8502337