I have been learning self-painted controls (MFC) since the beginning of this semester. The goal is to make a player interface, mainly to lay a good foundation, because my infrastructure is really bad .... let's talk about my own experiences and methods of self-painted controls. It's a bit of a joke, something wrong or incomplete, or something better. Please don't hesitate to give me some advice.
My machine environment is: Windows 7 flagship Service Pack 1, Visual Studio 2005
1 ). when re-painting a widget, we strongly recommend that you use the subclass method. For example, to customize the button control, first add your own cmybutton class to inherit from cbutton and declare a cmybutton object, then use subclassdlgitem (uint NID, cwnd * pparent); // The first parameter indicates the Control ID, and the second parameter indicates the pointer to the parent window object, this is generally used (if you do not want to use subclassdlgitem. Then, you can use the Create method provided by cmybutton to dynamically create a button. In this way, you can add and rewrite the window process function windowproc () in your own class. It is very, very, and important, for other controls, see this document.
2 ). the first control I started with was the button. I finally knew how bad my foundation was. Many basic functions such as getdlgitem () and subclassdlgitem () Didn't Know. I checked the information, looking at the source code, it takes a lot of time to basically complete the self-painting of the button. In addition, the self-Painting
By default, buttons cannot respond to press enter on the keyboard, and additional processing is required. (Key Words: bs_ownerdraw, drawitem) (in the later stage, I added an effect to the button for simulating QQ login. Hover and leave are gradient-based and only set
The button in the dialog box is used)
3). Then there is radiobutton. the checkbox is actually the same as the button. We recommend that you understand three API functions: checkradiobutton (), setcheck (), and getcheck ().
4). For irregular button implementation, You need to master the setjavaswrgn (), combinergn (), selectcliprgn () Three API functions. For other irregular windows, controls can also refer to this method.
5 ). then the Edit Control is self-painted, which is not completely self-painted. Only non-customer areas are re-painted (if there is no special need, there is no need to re-paint the customer area), and the background color is changed, I changed the font, but I added an effect later. The border is gradient when the mouse is in edit and when leaving edit (Off
Key word: ctlcolor, wm_ncpaint), RichEdit can also use this method
6 ). then tooltip (bubble prompt control). Microsoft provides the nm_customdraw announcement message, which is sent in the form of wm_notify. You can use the MFC class Wizard to add it to your own derived class, however, I recommend that you rewrite the onpaint function to fully self-paint (difficult:
Calculate the control size and display position based on the text content)
In the later stages, I realized the effect of Fade-in, click-out, and fade-out (two notification messages, ttn_pop and ttn_show, need to be mapped). However, the effect of fade-out and fade-out cannot be realized. Please provide guidance.
7 ). next is sliderctrl. Microsoft provides the nm_customdraw announcement message, which is sent in the form of wm_notify. You can use the MFC class Wizard to add it to your derived class. I used this method in the early stage, however, it is found that this method has great limitations in the future,
We recommend that you override the onpaint function and completely customize it (key point: store thumb (thumb button), channel (groove), and the entire control size in presubclasswindow for painting in onpaint)
8 ). then there is the Staic control. This is relatively simple. Rewrite the onpaint function to draw the text and set the DC to the transparent mode. Some people will say that the setbkmode (transparent) can be set directly in ctlcolor, you don't need to process it in onpaint, but this is a question.
If the text is always changed, the old text is not erased, and the new text is covered again. Select the appropriate method based on the purpose of the control.
9 ). then there is menu. This is difficult. Strictly speaking, menu is not a control. It is derived from the cobject class. Microsoft provides two virtual function classes: measureitem and drawitem for self-painting, measureitem is used to calculate the menu height and width.
The maximum value of the text content is used as the menu width. The role of drawitem is as its name implies, but there is a fatal problem. The self-painted menu has a default system border, which is very evil and ugly. (modifystyle and
Setwindowlong does not remove the boundary.) In the cmymenu derived from itself, Microsoft only provided five virtual functions for us, but did not provide windowproc, this is not a pitfall ....... in this case, the general method is derived from
Cwnd implements the menu function by itself. however, if you have checked the following information, you can do it yourself: You need to use a hook to replace the menu window. If you are interested in removing the border stytle during wm_create, You can Google it. (Difficulty: replacing the menu window)
10). Then there is the ComboBox control, which is difficult. Microsoft provides four virtual functions: compareitem, deleteitem, drawitem, and measureitem for self-painting. I only use the last two (if only cbs_sort is added, the compareitem
Function, unless you use cbs_hasstrings | cbs_sort, you can not overwrite compareitem (). Do not think this is all done. After running the function, open the list displayed in ComboBox and there is a system default border !!! Modifystyle and setwindowlong
The boundary cannot be removed. the old rules are used to check the information. If you don't know what to do, you are shocked. ComboBox is composed of three controls (no wonder it is called a combo box), which are edit, ListBox, and combo itself (except edit and the rest of ListBox), I was shocked and confused.
Now! In this case, you need to add the onctlcolor function, and use the subclasswindow () API function to subclass ListBox and edit (before that, you need to prepare the self-painted ListBox control and edit control) comboBox has three styles
Cbs_simple, cbs_dropdownlist, and cbs_dropdown. The first option is not commonly used. The second option is not to input. You can only click Select. The third option is to input and click Select. My program uses the cbs_dropdownlist style.
11 ). in Windows 7, ComboBox has doubts: Disable sliding to open the special effects of the combo box. In the self-painted ComboBox, you can remove the boundary and cut the window (rounded rectangle). If you enable sliding to open the special effects of the combo box, the system adds a border to the cropped rounded corner.
It turns to a right angle. The tracing debugging finds that it is a ghost in the wm_windowposchanging message. If you are interested, you can compare it and find a solution for the moment...
Enable/disable Sliding Open combo box special effects: computer-right-click Properties-advanced system settings-advanced-Performance Settings-Visual Effects
12 ). then tabctrl. Microsoft provides two virtual functions drawitem and measureitem for self-painting. You need to add the tcs_ownerdrawfixed stytle to indicate that the control needs to be self-painted, but I didn't use this method, I have directly rewritten the onpaint function.
Completely self-painted (difficulty: You need to calculate the size, position, and the displayed position of the bound DIALOG) of each tag)
13 ). finally, the form frame is drawn (not in the customer zone). This is difficult. I read the source code of many examples and spent a lot of time. wm_move, wm_paint, wm_ncpaint, wm_ncactivate, the key to successful self-painting of the four messages is also required during the painting.
Calculate the size and position of the border/title bar (the returned value of getsystemmetrics () in win7 and XP is different ).
// Provides the key code that the Framework does not flash and is completely original.
If (Message = wm_ncactivate &&! Wparam) // wparam = 0, deactive
{
Return 1; // 1 must be returned to process the default message (if 1 is not returned, all pop-up windows (modal, non-modal) cannot be clicked)
}
If (Message = wm_ncactivate & wparam) // wparam = 1, active
{
Return 0; // return any result (both 0 and 1)
}
If (Message = wm_ncpaint)
{
Return 0; // block the default frame painting (an application returns zero if it processes this message is from msdn)
}
In this way, the boundary and title bar are retained. In fact, the original painting is covered, and it is successful if it is not blinking. Of course, you can also remove the default boundary and title bar of the system, work out a boundary and title bar in the customer area, and process some messages for better implementation.
To make a more beautiful interface.
14) it may be that I am a tough guy. I wonder why I didn't implement a playback function on the player interface. Microsoft provides the MCI-media control interface, you have encapsulated a playback class to implement some basic playback functions. This is the first
The version is complete.
--- Test environment: 6 win7 and 2 XP
--- Interface Test: Windows 7 and XP run normally (for any defect, see article 11th)
--- Playback test: I can play rmvb, RM, Avi, MP4, WMV, FLV on my computer. In some cases, all 6 formats of Windows 7 can be played, however, some tested Windows 7 computers can only play AVI, MP4, and WMV (why? Please answer ...).
--- In addition, the WMV Format increases the playback speed and reduces the playback speed, which does not seem to work.
--- You can open video files in the XP system, but you can only hear the sound and cannot see the image. How can this problem be solved?
This result is indeed quite painful. You can test whether the interface is normal and whether the playback function is normal.
15) in view of the unsatisfactory playback test of the mci version, I once again suffered a headache, because a senior told me to try ActiveX controls. Well, it took two days to study ActiveX controls, and oleview was used to study the aplayer control,
The DLL file aplayer_001.dll is the aplayer ActiveX Control (You must register the ActiveX control before using it. If you only register aplayer_001.dll in the Code, the program can run but cannot play the file, because when playing the file
The aplayer control also loads some DLL files and ax files based on the playback file type. These files add up to more than 80 mb. This is a pitfall ....) in fact, aplaer is a player component of thunder. If Thunder is installed :\
\ Program Files \ common files \ thunder network can find the aplaer folder. If Thunder is not installed or the aplayer component program is not running.
Note: This aplayer has a defect. When playing the rmvb and MKV files, click to locate the error. For large files, it is difficult to find this defect. You can find a short video file of one or two minutes and use thunder to check whether it is opened and click to locate it. The defect is very obvious.
Since the aplayer playing process is not the same as that of the MCI, it took some time to build the second version. (It is said that this aplaer component was developed by an organization outside China. It seems that Thunder has bought the copyright)
--- Test environment: 6 win7 and 2 XP
--- Interface Test: Windows 7 and XP run normally (for any defect, see article 11th)
--- Playback test: rmvb, RM, Avi, MP4, WMV, FLV, MKV, MP3, WMA, WAV can be played on win7.
--- If you open a file in the XP system, you can only hear the sound and cannot see the image. For the playing problem of the XP system, you have not found a solution. (is it because I registered the aplayer of win7 ?).
--- In addition, the program has a defect: it will be reduced when you click the aplayer control for the first time. After debugging, it is found that wm_lbuttondown is not entered, and wm_windowposchanging, wm_windowposchanged, and wm_size are used directly.
I don't know where the message was sent .... (I used a bad solution. Since it will be reduced only when I click it for the first time, in presubclasswindow: postmessage (wm_lbuttondown, mk_lbutton,
(Lparam) & userdown); postmessage (wm_lbuttonup, mk_lbutton, (lparam) & userdown);) The two messages do not seem to have been reduced, however, I encountered this problem again when I ran it yesterday. The probability of this problem is very low ....
Speechless)
16)
All the tests of the program are done by yourself, and many functions cannot be tested. Therefore, the program may have such a problem. I can't help myself, but I hope to be gentle.
The program hotkey is not doing well. It is not global or background. It must obtain the focus of the window to respond.
The tray function is added later.
Added the playlist function. A maximum of 10 files are supported. If there are more than 10 files that cover 10th files, double-click the file name in the list to play the file. However, I did not create a single window for the playlist, which is placed on the 3rd tags in the Setting dialog box.
The drag-and-drop open file function was added to the strong demand of students (I filtered out some file extensions, not every file type is valid for drag-and-drop, and the formats supported by the MCI and ActiveX versions are different, different filtering conditions)
The program was originally named ikan player but found that the PPLIVE has already used this name and changed it to the ICAN player ....
The following is a supplement to the above:
1 ). add an advanced reload-able function presubclasswindow (). My understanding is that it allows users to perform additional processing before subclass. This reload function is also very important and requires considerable attention. You can change the widget size, position, and window style here.
, Font, and so on... all you can think of can be changed here.
2). Supplementary description on EDIT: my original self-painting method was to use the non-customer area processed in wm_ncpaint to draw the border by myself, so as to realize the different boundary between hover and leave. However, I later found that because the non-customer zone is too small, the boundary is 2 pixels. If
The mouse moves quickly. Sometimes the system cannot detect the current state of the mouse, so the edit in the program is drawn in onpaint. However, there is a core API-default () to view the code.
Void ceditex: onpaint ()
{
Default (); // key
If (! M_bhover)
Drawboder (); // draw your own boundary
}. This is the method used for the Self-painted edit in the program.
3) for the hover and leave effects of the control, simply put, the hover is the mouse floating on the control, and the leave is the mouse leaving the control. How can this effect be achieved? Let me give the source code directly.
Use the edit control as the column
Add to header file
Afx_msg void onmousemove (uint nflags, cpoint point );
Afx_msg lresult onmouseleave (wparam, lparam );
Afx_msg lresult onmousehover (wparam, lparam );
Add in CPP:
Begin_message_map (ceditex, cedit)
On_message (wm_mouseleave, onmouseleave)
On_message (wm_mousehover, onmousehover)
On_wm_mousemove ()
End_message_map ()
Note: on_wm_mousemove () can be added using the Class Wizard. However, onmouseleave and onmousehover must be manually added.
Then define in CPP:
Void ceditex: onmousemove (uint nflags, cpoint point)
{
If (! M_bhover)
{
Trackmouseevent tme;
Tme. cbsize = sizeof (TME );
Tme. hwndtrack = m_hwnd;
Tme. dwflags = tme_leave | tme_hover;
Tme. dwhovertime = 1;
M_bhover = _ trackmouseevent (& TME); // m_bhover: bool member variable
}
Cedit: onmousemove (nflags, point );
}
Lresult ceditex: onmouseleave (wparam, lparam)
{
M_bhover = false;
//
Perform corresponding operations
//
Return 0;
}
Lresult ceditex: onmousehover (wparam, lparam)
{
//
Perform corresponding operations
//
Return 0;
}
Most controls can use this method. However, some controls may require you to simulate hover and leave in onmousemove, such as tabctrl in the program...
4). I have sorted out the posts I have read for your reference (many posts have been forgotten for a long time ):
Progress bar self-painted: http://www.codeproject.com/KB/miscctrl/cprogressctrlst.aspx (with project source code)
Transparent controls (multiple controls) Implementation: http://www.codeguru.com/cpp/controls/buttonctrl/advancedbuttons/article.php/c15603/General-Solution-for-a-Transparent-Control.htm (with project source code)
Transparent form: http://msdn.microsoft.com/en-us/library/ms997507 (menu, form, ComboBox can refer to this method to achieve any transparency, I also refer to this method)
Irregular button implementation: http://www.codeguru.com/cpp/controls/buttonctrl/non-rectangularbuttons/article.php/c2085/Universal-Button---beauty-of-HRGN.htm
Two posts on the Self-painted button:
Http://www.vckbase.com/document/viewdoc? Id = 551
Http://www.vckbase.com/document/viewdoc? Id = 561
The difference between custom draw and owner draw (it is in full English, but it is helpful for you to understand the idea of self-painting, and you have time to translate it ):
Http://blog.csdn.net/xiexievv/article/details/6279219
The discussion of wm_drawitem and drawitem () is helpful for Control Self-Painting:
Http://blog.csdn.net/xiexievv/article/details/6259194
The following posts will surely have some unexpected gains, not just the self-painted controls. This will allow us to raise the overall understanding of MFC by one level.
Differences between ondraw and onpaint in MFC:
Http://blog.csdn.net/xiexievv/article/details/6271153
In-depth analysis of Message reflection mechanisms:
Http://blog.csdn.net/xiexievv/article/details/6282205
Differences between pretranslatemessage and translatemessage:
Http://blog.csdn.net/xiexievv/article/details/6299027
Differences between windowproc and defwindowproc:
Http://blog.csdn.net/xiexievv/article/details/6299016
Differences between precreatewindow, presubclasswindow, and subclasswindow in cwnd:
Http://blog.csdn.net/xiexievv/article/details/6233423
We also recommend several good learning websites:
Http://www.codeproject.com)
Http://www.codeguru.com)
Http://www.pudn.com
Http://www.vckbase.com/document/index.asp
Http://www.hackchina.com
Let's write so much about it. I personally think that the most useful information is msdn, of course, there is also a powerful csdn. The self-painting of each control is not fixed and regular, so do not move it like a mess, to learn and use it. You may not be able to understand it now. It doesn't matter if everyone is here.