Custom Controls implement traffic signals

Source: Internet
Author: User

You will always see questions like this in the forum, such as "how to change an image with a button", "how to display the image in the dialog box", and "how to operate picturectrl of MFC, not all. In the face of such problems, I generally recommend that you use cwnd to derive a custom control from the row for processing. However, this is easy to say, but how can this control be implemented? So I often want to give an example to share with you. Of course, if you have any better solutions, I can also learn from them. However, the problem arises again. The simple implementation of such examples is actually a function problem-onpaint. However, there are too many exquisite aspects to be processed, and it is easy to take the lead. How can we find a solution with a discount? What kinds of theme examples are more representative? A post posted on the Forum over the past two days has inspired me to make a signal light control, which can explain the problem and make it simple and practical. You can also draw a line between them. This should be a good idea, so I made a demo and wrote this article.

This time I made a GIF. I made a three-state light, indicating the normal (green), warning (red), and unavailable (Gray) States. Status switching is implemented through the single-choice button. Of course, this can be controlled in any way we want. As you can see, this example is rough. In fact, it is to replace three different images. to highlight the main features, I did not add unnecessary modifications, such as hollowing out the processing.

Implementation to specific implementation, as mentioned above, I used cwnd to derive a csignallampctrl to implement a custom control, and then I drew a bitmap in onpaint of this class. Speaking of this, I inserted a sentence. At first, when I was just doing interface programming, every time I encountered a problem, I would depend on the Standard Control of MFC and find the closest reload self-painting, if there is no proximity, all the cstatic implementations will be reloaded. But later we found that static controls also have a lot of special processing. In order to achieve "static" static, there are a lot of processing that we do not need when doing general controls, therefore, when using this control, there will be a lot of unnecessary trouble. So I began to try to solve the problem through the custom control, and more adapted to this method. Although the custom control does not have some ready-to-use messages, it gives us the maximum control and freedom, so that we can do what we want without constraint.

You only need to pay attention to a small detail when using the custom control. You can see the class item in the control property editor. Enter the Class Name of the control here. At the same time, this class name needs to be registered, so you can find registerctrlclass in my class. Its specific implementation code is

Void csignallampctrl: registerctrlclass () <br/>{< br/> hinstance = AfxGetInstanceHandle (); </P> <p> wndclass wndclsctrl; <br/> zeromemory (& wndclsctrl, sizeof (wndclass); </P> <p> If (: getclassinfo (hinstance, str_class_name, & wndclsctrl )) <br/> return; </P> <p> // set control class information <br/> wndclsctrl. style = cs_hredraw | cs_vredraw | cs_owndc; <br/> wndclsctrl. lpfnwndproc =: defwindowproc; <br/> wndclsctrl. cbclsextra = 0; <br/> wndclsctrl. cbwndextra = 0; <br/> wndclsctrl. hinstance = hinstance; <br/> wndclsctrl. hicon = NULL; <br/> wndclsctrl. hcursor = afxgetapp ()-> loadstandardcursor (idc_arrow); <br/> wndclsctrl. hbrbackground = NULL; <br/> wndclsctrl. lpszmenuname = NULL; <br/> wndclsctrl. lpszclassname = str_class_name; </P> <p> // register the control class <br/> afxregisterclass (& wndclsctrl); <br/>}</P> <p>

I usually place it in the control constructor to automatically register it during use.

In fact, there is nothing to note about this example. The onpaint function is very simple, that is, to draw a bitmap, my bitmap is put into the resource, of course, it is okay to read it in through the file. Moreover, through cimage or GDI +, we can also display non-bitmap images. Interested readers can try it on their own. The onpaint code is as follows:

Void csignallampctrl: onpaint () <br/>{< br/> cbitmap bmlight; <br/> bitmap bmdata; <br/> cpaintdc DC (this ); <br/> CDC * pmemdc = new CDC; </P> <p> bmlight. loadbitmap (nidbitmap); <br/> // retrieves bitmap data <br/> bmlight. getbitmap (& bmdata); </P> <p> // create compatible DC <br/> pmemdc-> createcompatibledc (& DC ); </P> <p> // texture <br/> cbitmap * poldbitmap = pmemdc-> SelectObject (& bmlight); <br/> DC. bitblt (0, 0, bmdata. bmwidth, bmdata. bmheight, pmemdc, 0, 0, srccopy); <br/> pmemdc-> SelectObject (poldbitmap); </P> <p> Delete pmemdc; <br/>}

It can be noted that the bitmap is loaded through a variable nidbitmap. Here, the resource ID of the bitmap to be displayed is stored. Switching the bitmap is to switch the ID. I have implemented the setstate function.

Void csignallampctrl: setstate (statetype nstate) <br/>{< br/> switch (nstate) <br/>{< br/> case normal: nidbitmap = idb_bitmap_green; break; <br/> case warning: nidbitmap = idb_bitmap_red; break; <br/> case Disable: nidbitmap = idb_bitmap_gray; break; <br/>}</P> <p> invalidate (); <br/>}

In the radio message, the call to it is also very simple.

Void csignallampdlg: onbnclickedradionormal () <br/>{< br/> updatedata (); </P> <p> m_sldemo.setstate (csignallampctrl: statetype) m_nstate ); <br/>}

Here, you can use any method that you think is reasonable to switch images. If you use the ontimer message to control the switching of the signal lights, you can achieve the flashing animation effect of the signal lights. The last point I want to mention is that in presubclasswindow, I set a limit on the widget size so that it is the same as the image size. The specific code is

Void csignallampctrl: presubclasswindow () <br/>{< br/> cwnd: presubclasswindow (); </P> <p> crect rectctrl; <br/> cbitmap bmlight; <br/> bitmap bmdata; </P> <p> bmlight. loadbitmap (nidbitmap); <br/> // retrieves bitmap data <br/> bmlight. getbitmap (& bmdata); </P> <p> getwindowrect (rectctrl); <br/> rectctrl. bottom = rectctrl. top + bmdata. bmheight; <br/> rectctrl. right = rectctrl. left + bmdata. bmwidth; <br/> getparent ()-> screentoclient (rectctrl); <br/> movewindow (rectctrl); <br/>} 

Now, we have finished the introduction of this example. If you are interested, you can download the sample source code and have a look at it. I hope you can provide valuable comments. The limited horizontal example is too simple to make everyone laugh.

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.