Why is it necessary to RegisterClass in Windows AP

2019-02-10 12:46发布

问题:

I would like to ask why, in developing Windows GUI's using the API, is it necessary to register a window class? What is the concept of it?

I have already read the first 3 chapters of Programming Windows by Charles Petzold, but I still wonder what's the purpose of explicitly registering a class. Why would I want to do it explicitly? Why isn't it done in the background for instance in the CreateWindow() (or CreateWindowEx()) function? I mean, why isn't the code that RegisterClass() executes inside CreateWindow(), or why doesn't CreateWindow() call the RegisterClass() itself?

I have also been reading the documentation on MSDN and I know that the RegisterClass() function associates a window procedure with a window class, by filling a WNDCLASS structure. I know that this is the function that handles the messages from the OS, however why is it necessary to register that function (the WinProc one) to a class inside a separate function from CreateWindow()?

I can understand the reasons to exist the CreateWindow() function, and why it doesn't automatically shows the window created. This implies I also understand the purpose of the ShowWindow() function.

I'm sure that there must be good reasons for this behavior, to let the programmer register a class when he wants, I'm just failing to see those reasons, and that's why I am asking you guys to shed light on the subject.

Please keep in mind that I am very new to GUI development with the Windows API. I have done some GUI's in MATLAB, which being different from the Windows API, still allowed me to understand some of the Windows philosophy, specifically the purpose of callback functions. I don't know if this info is useful, but if you need to make some analogies please be my guest.

回答1:

Since you've tagged your question with C++ I'll give you a C++ analogy...

RegisterClass is basically you defining a class and including it in your program (much like a #include in C++). The WNDPROC is your handler for anything that happens within the window if and when an instance is created.

CreateWindow is conceptually the same as you doing a new in C++. You're asking Windows to create a new window, and you've got to tell it the type of window. Windows includes a set of predefined windows, such as Button or Edit, but if you want to create an instance of your own window then that's fine, you just need to tell it the "class" you'd like to create. You've already registered this class by calling RegisterClass, so Windows can now go straight to the definition and create an instance of your window.



回答2:

Another way to think is because Windows is a closed source, so API writers do not want you to know much inside the API. So now, they think: "What if the user want to create their own window class with their own behavior?". That's why WNDCLASS is created for the users to declare the information of the class they need by assign value like names, procedure in the member field. It's something like filling the form. Therefore, you can see that API writers achieve 2 things:

(1) users don't know anything about the API, since they don't explicitly extend API classes to custom, cause if they do, so API writers have to provide the headers of the classes and users can mess up with that making Windows is not closed anymore.

(2) users still can define their own window classes.

Now, after you define your own window class, and you want to use it, so you have to register the class, so that the Windows OS know what class is that so they can maintain information about it for further need, and then you can create the instance of it.



回答3:

You need to RegisterClass to define the style, window's procedure, that is necessary to program the thread that owns the window to respond to messages and events and do something or nothing for each message that the window receives and for each event that occurs, the icon of your window, the cursor the user sees when hovering over the window, background of window's client and windows's menu.

How can you imagine a window without all these properties?

Maybe you ask why all these window properties are not parameters of the CreateWindow function, so I set them with CreateWindow function and not with RegisterClass function, right?

If all window properties are parameters of CreateWindow function then CreateWindow function is very complicated and the line that invokes CreateWindow properly is very long.

This makes the code very large, less readable and less productive.

RegisterClass simplifies CreateWindow a lot.

This is one of the reasons that Microsoft wants the Win32 developers to invoke RegisterClass first before CreateWindow.

Also suppose that you want at least two windows with the same properties.

You allocate only one instance of WNDCLASS structure, set his fields to set the common properties of your windows and you invoke RegisterClass function only once, but you invoke CreateWindow as many times as needed to create all of the windows you want, but everyone with the same class name.

RegisterClass not only simplifies and shortens the code a lot significantly, but it also prevents duplicate of the same large code in CreateWindow.

RegisterClass also makes the code more productive.

This is an excellent design to first allocate an instance of WNDCLASS, set his fields, invoke RegisterClass function and then invoke CreateWindow function as many times as you want.

Although you need to invoke RegisterClass multiple times, if you want windows with different properties of course.

You will also have to modify the WNDCLASS instance before each call to RegisterClass function.