CreateWindow和WNDCLASS中为什么都出现了HINSTANCE

众所周知,在windows下我们要创建窗口,必须依据一个已经有的或者自己创建一个新的窗口类,然后注册窗口类,最后才能根据这个窗口类创建一个用户自己的窗口,MSDN中WNDCLASS的类型定义为
typedef struct _WNDCLASS { 
    UINT       style; 
    WNDPROC    lpfnWndProc; 
    int        cbClsExtra; 
    int        cbWndExtra; 
    HINSTANCE  hInstance; 
    HICON      hIcon; 
    HCURSOR    hCursor; 
    HBRUSH     hbrBackground; 
    LPCTSTR    lpszMenuName; 
    LPCTSTR    lpszClassName; 
} WNDCLASS, *PWNDCLASS; 
注意这里已经有了HINSTANCE hInstance的定义,当我们定义了这样一个结构体后,根据这个结构体去注册这个窗口类,
调用ATOM RegisterClass(  CONST WNDCLASS *lpWndClass  // class data)即可,这样我们就可以根据这个窗口类创建窗口了
 
然而让人疑惑的是HWND CreateWindow(  
LPCTSTR lpClassName,  // registered class name  
LPCTSTR lpWindowName, // window name  
DWORD dwStyle,        // window style  
int x,                // horizontal position of window  
int y,                // vertical position of window  
int nWidth,           // window width  
int nHeight,          // window height  
HWND hWndParent,      // handle to parent or owner window  
HMENU hMenu,          // menu handle or child identifier  
HINSTANCE hInstance,  // handle to application instance  
LPVOID lpParam        // window-creation data
);中再次指定了hInstance,我们读windows编程或者其它常见的windows编程的书大体介绍都是CreateWindow是根据lpClassName这个变量创建新的窗口的,既然根据窗口类就可以创建窗口,而窗口类中已经有了关于hInstance的声明了,为什么还要重新声明,这不是多此一举吗?这下可把初学windows编程的很多人搞晕了,哈哈

尽信书不如无书,同学们想一想,当同一个程序的执行后,重新开启第二次执行的时候,两次注册的窗口类的名字是否一样呢?答案当然是肯定的,因为多个进程执行的代码段是相同的,但是每个进程的窗口类却不一样,因为在窗口类中还有一个hInstance的声明,用数据库的观点看就是说窗口类的主键不止是lpClassName而已,还有hInstance,这样以来当CreateWindow时当然同时需要指定窗口的lpClassName和hInstance喽

结论:窗口类名不足以唯一地标志窗口类。每个进程有自己的窗口类列表,窗口类列表中的每一项都由一个实例句柄和一个类名字组成。创建窗口时,windows的窗口管理器使用实例句柄和窗口类的组合来寻找窗口类

#include <windows.h> //窗口处理函数WndProc()的声明 LRESULT CALLBACK WndProc(HWND, UINT, WPARAM, LPARAM); //主函数,程序的入口,相当于之前的main()函数 int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, PSTR szCmdLine, int iCmdShow) { static char szAppName[] = "HelloWin"; HWND hwnd; MSG msg; WNDCLASS wndclass;//WNDCLASSEX也行,会多几个分量,配合RegisterClassEX使用 //设置WNDCLASS结构体,为下一步调用RegisterClass()函数做准备 wndclass.style = CS_HREDRAW | CS_VREDRAW;//支持重绘,不能为0 wndclass.lpfnWndProc = (WNDPROC)WndProc;//主函数与窗口处理函数绑定 wndclass.cbClsExtra = 0; wndclass.cbWndExtra = 0; wndclass.hInstance = hInstance; wndclass.hIcon = LoadIcon(NULL, IDI_APPLICATION); wndclass.hCursor = LoadCursor(NULL, IDC_ARROW); wndclass.hbrBackground = (HBRUSH)GetStockObject(WHITE_BRUSH); wndclass.lpszMenuName = NULL; wndclass.lpszClassName = szAppName; //注册 if (!RegisterClass(&wndclass)) { MessageBox(NULL, "This program requires Windows NT!", szAppName, MB_ICONERROR); return 0; } //调用CreateWindow()函数创建窗体 hwnd = CreateWindow (szAppName, // window class name "The Windows Program", // window caption WS_OVERLAPPEDWINDOW, // window style CW_USEDEFAULT, // initial x position CW_USEDEFAULT, // initial y position CW_USEDEFAULT, // initial x size CW_USEDEFAULT, // initial y size NULL, // parent window handle NULL, // window menu handle hInstance, // program instance handle NULL); // creation parameters //显示更新窗口 ShowWindow(hwnd, iCmdShow); UpdateWindow(hwnd); //消息循环,不停接收消息直至收到WM_QUIT消息后,跳出循环,程序结束 while(GetMessage(&msg, NULL, 0, 0))//如果函数取得WM_QUIT之外的其他消息,返回非零值。如果函数取得WM_QUIT消息,返回值是零 { TranslateMessage(&msg);//翻译消息,将按键消息转换为字符消息 DispatchMessage(&msg);//以此消息为参数转发给相应的窗口消息处理程序 } return msg.wParam; } //窗口处理函数,函数格式固定,函数名无所谓 LRESULT CALLBACK WndProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam) { //Code 使用以上的框架代码,编写程序,要求不断变换窗口屏幕中的颜色,以红橙黄绿青蓝紫的顺序依次变换,间隔0.5秒,不断循环
最新发布
03-12
在C语言中,`CreateWindow()`函数是用于创建Windows窗口的基本函数,它属于Windows API的一部分,主要用于MFC(Microsoft Foundation Classes)程序设计。这个函数创建一个新的窗口,并将其添加到应用程序的消息循环中。 `CreateWindow()`的原型通常像这样: ```c HWND CreateWindow( LPCSTR lpClassName, // 窗口名 LPCSTR lpWindowName, // 窗口标题 DWORD dwStyle, // 窗口样式 int x, // 窗口左上角X坐标 int y, // Y坐标 int nWidth, // 宽度 int nHeight, // 高度 HWND hWndParent = NULL, // 父窗口句柄,NULL表示顶级窗口 HMENU hMenu = NULL, // 菜单句柄 HINSTANCE hInstance, // 当前实例句柄 LPVOID lpParam = NULL // 用户自定义数据 ); ``` 以下是使用`CreateWindow()`创建简单窗口的一般步骤: 1. **包含头文件**:首先需要包含`windows.h`头文件,该文件包含了所有Windows API函数的声明。 ```c #include <windows.h> ``` 2. **获取进程实例**:`hInstance`通常是你应用程序的`HINSTANCE`,可以作为当前模块的句柄。 3. **定义窗口别**:创建一个窗口(`lpClassName`),这通常是你自己创建的一个结构体,包含窗口的各种属性。 4. **调用CreateWindow()函数**:传入上述参数,创建新窗口。 例如: ```c WNDCLASS wc; wc.lpfnWndProc = DefWindowProc; // 指向默认处理消息的函数 wc.lpszClassName = "MyWindowClass"; wc.style = WS_OVERLAPPEDWINDOW; wc.hCursor = LoadCursor(NULL, IDC_ARROW); // 加载鼠标图标 if (!RegisterClass(&wc)) { // 注册失败,错误处理 } HWND hWnd = CreateWindow( wc.lpszClassName, "Hello, World!", wc.style, CW_USEDEFAULT, // 使用系统默认位置 CW_USEDEFAULT, // 使用系统默认大小 0, 0, NULL, NULL, hInstance, NULL ); // 如果窗口创建成功,接下来可以设置窗口事件处理器、显示窗口等... ```
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值