为什么CreateWindow()在注册窗口类时已经提供了hInstance作为参数?

sad*_*ezz 4 c winapi

注册窗口类时,必须填写WNDCLASS结构,其中包含一个hInstance字段:

typedef struct {
    UINT style;
    WNDPROC lpfnWndProc;
    int cbClsExtra;
    int cbWndExtra;
    HINSTANCE hInstance;
    HICON hIcon;
    HCURSOR hCursor;
    HBRUSH hbrBackground;
    LPCTSTR lpszMenuName;
    LPCTSTR lpszClassName;
} WNDCLASS
Run Code Online (Sandbox Code Playgroud)

然后,创建窗口,使用CreateWindow()它来获取这些参数:

HWND CreateWindow(          
    LPCTSTR lpClassName,
    LPCTSTR lpWindowName,
    DWORD dwStyle,
    int x,
    int y,
    int nWidth,
    int nHeight,
    HWND hWndParent,
    HMENU hMenu,
    HINSTANCE hInstance,
    LPVOID lpParam
);
Run Code Online (Sandbox Code Playgroud)
  • 如果hInstance与提供WNDCLASS上课的时候登记的,为什么有必要提供一个hInstanceCreateWindow()

  • hInstance提供的WNDCLASS应该与hInstance提供的相同CreateWindow()吗?

  • 如果WNDCLASS hInstanceCreateWindow() hInstance它们不同,它们是什么意思?


这是一个演示类注册/窗口创建的示例程序:

#include <windows.h>

LPSTR szClassName = "MyClass";
HINSTANCE hInstance;
LRESULT CALLBACK MyWndProc(HWND, UINT, WPARAM, LPARAM);

int WINAPI WinMain(HINSTANCE hInst, HINSTANCE hPrevInstance, LPSTR szCmdLine, int iCmdShow)
{
   WNDCLASS wnd;
   MSG msg;
   HWND hwnd;

   hInstance = hInst;

   wnd.style = CS_HREDRAW | CS_VREDRAW; //we will explain this later
   wnd.lpfnWndProc = MyWndProc;
   wnd.cbClsExtra = 0;
   wnd.cbWndExtra = 0;
   wnd.hInstance = hInstance;
   wnd.hIcon = LoadIcon(NULL, IDI_APPLICATION); //default icon
   wnd.hCursor = LoadCursor(NULL, IDC_ARROW);   //default arrow mouse cursor
   wnd.hbrBackground = (HBRUSH)(COLOR_BACKGROUND+1);
   wnd.lpszMenuName = NULL;                     //no menu
   wnd.lpszClassName = szClassName;

   if(!RegisterClass(&wnd))                     //register the WNDCLASS
   {
       MessageBox(NULL, "This Program Requires Windows NT", 
                        "Error", MB_OK);
       return 0;
   }

   hwnd = CreateWindow(szClassName,
                       "Window Title",
                       WS_OVERLAPPEDWINDOW, //basic window style
                       CW_USEDEFAULT,
                       CW_USEDEFAULT,       //set starting point to default value
                       CW_USEDEFAULT,
                       CW_USEDEFAULT,       //set all the dimensions to default value
                       NULL,                //no parent window
                       NULL,                //no menu
                       hInstance,
                       NULL);               //no parameters to pass
   ShowWindow(hwnd, iCmdShow);              //display the window on the screen
   UpdateWindow(hwnd);             //make sure the window is updated correctly

   while(GetMessage(&msg, NULL, 0, 0))      //message loop
   {
       TranslateMessage(&msg);
       DispatchMessage(&msg);
   }
   return msg.wParam;
}

LRESULT CALLBACK MyWndProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam)
{
   switch(msg)
   {
       case WM_DESTROY:
           PostQuitMessage(0);
           return 0;
   }
   return DefWindowProc(hwnd, msg, wParam, lParam);
}
Run Code Online (Sandbox Code Playgroud)

Jon*_*ter 7

注册窗口类时,它可以是全局的(CS_GLOBALCLASS样式设置)或注册它的模块的本地.对于全局类,类名必须是唯一的,但对于模块本地类,类名可以冲突 - 没有什么能阻止两个DLL注册同名的窗口类,并且可执行文件可以加载这两个DLL.

因此,您需要告诉CreateWindow函数您要使用哪个模块的命名类实例来创建窗口.

  • @sadjezz:如果模块P使用P的hInstance注册classname X,并且模块Q也使用Q的hInstance注册相同的类名X,那么你必须告诉CreateWindow()你是否要使用P的类或Q的类.这就是CreateWindow()具有hInstance参数的原因. (2认同)