[Win32] What is a control?

Source: Internet
Author: User

[Win32] What is a control?
Statement:
This topic is very big and I have finished writing it, and I regret it. After all, I only wrote Win32 for less than two months.ProgramIt is not very comprehensive. If you have any mistakes, please point them out. It is also helpful to your younger brother .:-)

 

I. Windows Message Mechanism
Windows is message-driven (see "Modern Operating System", which is called event-driven). When messages are generated and messages are responded, it is a loosely coupled design.
Regardless of the window, you need to register the class before create, and you need registerclass. there is no essential difference between the concept of this class and the concept of class in OO, And the classname needs to be created in createwindow, which is an instance of this class.
The response to the message is completed in the wndproc member of the class. Why is it put here? Long Sheng-long, Feng Sheng-feng, the mouse's child will make holes ~~ The same class processes messages in the same form, because it is the same class.
Let's look at the principles of this loose coupling structure.
Because classname needs to be specified during createwindow, a window will have a classname and a wndproc, Which is intuitive and important outside. an hwnd has a wndproc, which is obvious. with this, the main thread does not have to worry about it. He just needs to take out the message from the message queue, distribute it, and then execute it.
While (getmessage (& MSG, null, 0, 0 ))
{
Translatemessage (& MSG );
Dispatchmessage (& MSG );
}
This is our common message loop.
Because MSG has an hwnd member, and an hwnd has a classname member, so that wndproc can be known, it is easier to execute dispatchmessage.
The main thread only needs a strong getmessage and dispatchmessage. Whoever gets the message will go to where the wndproc will be executed.

 static lresult imagebuttonproc (hwnd, unit, wparam, lparam); wndproc procimagebutton = NULL; wndproc procold = NULL; procimagebutton = imagebuttonproc; procold = (wndproc) getwindowlong (hwnd, gwl_wndproc); bool result = setwindowlong (hwnd, unknown, (long) procimagebutton); Assert (result); static lresult imagebuttonproc, unit message, wparam, lparam) {lresult result = 0; Switch (Message) {Case wm_erasebkgnd: Return true; Case wm_paint: // specify return result here; Case wm_lbuttondown: setcapture (hwnd); return result; Case wm_lbuttonup: releasecapture (); // The click event occurs here. // Of course, this is just a hypothesis, return result also needs to be determined based on the mouse clicking position;} result = callwindowproc (procold, hwnd, message, wparam, lparam);} 

The preceding is the front key for writing independent controls.
Another condition is that we need to control the window process. because the corresponding onclick is required for clicking the button, and the lable clicking is basically not done. it is precisely because of this difference that we need to control wndproc.
Windows provides registerclass, allowing us to register our own class and customize wndproc. windows default controls, such as static controls, such as edit, are used to process messages.
Set.
With registerclass, we can write many controls. We only need to create one or N wndproc.
OK, that's a way, but I don't want to use that method.
Windows also provides us with another mechanism. We need to make a personalized control, which is nothing more than a window handle and its message processing, as long as we can get it done.
Getwindowlong/setwindowlong can help us do something.
OK. Let's see how it works.

2. Create a control by yourself
In fact, I have mentioned it before, and I can find it by turning over my blog.
No matter what method you use or the obtained window handle hwnd, to make it an imagebutton, you basically only need:

If we complete the above imagebuttonproc, then the hwnd window becomes an imagebutton, whether it is listview or static. we can see that getwindowlong/setwindowlong gives us a lot of imagination.

Iii. Encapsulation
A control has been completed above, which is not easy to use. The root cause is the programming model problem. that is a pure process model, which is different from the class library of the OO model we usually see. although we can also make that thing easy to use in some ways, we need to use the idea of "1" and the C Implementation of dependency inversion, otherwise, it seems a little troublesome. this article does not want to discuss this issue ....
Each control processes messages differently, and only the control itself knows how to handle the messages. This may be a dynamic difference. the window process is obviously global and static, and the processing of messages can only be static. so if you want to build a class library, you must solve this problem!
This reminds me of the OO encapsulation method of MFC and MFC. You can process various messages in your own classes without worrying about the real message loop.
Now let's take a look at "1". Windows itself provides me with a lot of ideas and we need to think about them. dispatchmessage obtains the message, but simply finds its Window Process Based on hwnd and runs it. however, hwnd-> wndproc is a ing concept. this ing solves the dependency problem.
We can also do this, but this ING also needs to be done by ourselves!

 // This is only the approximate prototype. // It only describes the principle. Class control {public: hwnd; Control () {// XXXXX // here is the above. Find a way to create an hwnd and then replace the window process} virtual lresult wndproc (hwnd, uint, wparam, lparam ); static void register (hwnd, control *); protected: wndproc newproc; wndproc oldproc ;}; // implement static Map 
  
    controlcache; void control :: register (hwnd, control * pcontrol) {assert (hwnd & pcontrol); controlcac He. insert (make_pair 
   
     (hwnd, pcontrol);} lresult defaultwndproc (hwnd, uint message, wparam, lparam) {Map 
    
     : iterator I = controlcache. find (hwnd); Assert (I! = Controlcache. End (); if (I! = Controlcache. end () {return (* I)-> wndproc (hwnd, message, wparam, lparam);} return defwindowproc (hwnd, message, wparam, lparam );} 
    
   
  

CodeThe prototype is like that. The default window process is only sending messages, and the real processing is in your own control.
The idea was that when Win32 was used for ui a week or two ago, although oo encapsulation was abandoned (because of insufficient time), I thought it was a simple oo encapsulation, you can easily construct the desired control.
Because Windows default controls are ugly, there is basically only painting for beautification. If I paint, what painting is not used? Why do I have to use the method provided by Win32 default controls for painting? I used listview once and found that the control was not listview, but a god control. It was very complicated. Later I gave up the control and drew one by myself using static, and the code was no more than 200 lines, customization is also strong. (A gridview is similar)

PS:
1. Some people call getwindowlong/setwindowlong sub-classes. Think about it too. My processing is the process of inheritance.
2. Later I chatted with a friend in the group and found that I had known it for a long time. MFC is similar. The bottom layer is only responsible for distribution and upper layer processing.
3. To put it bluntly, I have a one-sided understanding of OO, so I can write out things that others have implemented decades ago. % >_<%
4. because I have not read the template (because TC ++ PL did not write ...), the two companies are not allowed to use wtl, So I basically don't know the ATL/wtl mechanism, and how it handles and distributes messages.
This is a defect in this article, and we have a one-sided understanding.

 

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.