This article should have demonstrated how to implement the intermediate customer area and the toolbar at the bottom of the imitation QQ interface. However, when implementing the toolbar at the bottom, it is found that there are many clever methods for the circular button and toolbar self-painting, add this article to explain how to implement the Circular button and toolbar self-painting.
The previous articles are all about how to implement the title bar on top of QQ, which is implemented by Window Textures. We also talk about how to implement it in different ways in the bottom area, therefore, the QQ button and toolbar at the bottom of this page are not drawn on the main window, but implemented using controls. The methods described here are not limited to the use of the ringsdk interface library and the implementation of this QQ-like interface program. Similar effects can be easily implemented using MFC or API.
When talking about the circle button, you will surely think of implementing the button self-painting. However, a clever method is to use static text controls for simulation, and do not need to do so. First, cut a QQ image as a resource, such:
This figure contains two buttons, one for collapse/expansion of the sidebar and the QQ button for the pop-up Main Menu, both of which are circular buttons. We will first create a subwindow of the same size as this image without borders, and use this image as the background of the window. If you want to use this image, all you need to do is call setbkgbitmap in the ringsdk interface library. Create two static text controls, with a size of 13*13 and a size of 36*36, which overwrite the two buttons. Static text controls are inherently transparent. As long as no text is set, the two controls are the same as they do not exist and do not affect the background. However, they occupy a position and can simulate the button action. Of course, the two controls must first createellipticrgn, and then setjavaswrgn to make it a circle, so that the mouse must enter the circular button area to respond to the action, you don't have to try to determine the mouse position in the main window :)
The first step is to simulate the highlighted state of the mouse move up. When the mouse moves over the button, the parent window does not have the wm_mousemove message. Therefore, the message must be processed by the control, the two static text controls need to be subclass. MFC has a 3rd-square static text control. The class name does not remember, so it implements hypertext links. If there is such a class, you don't need to subclass it yourself. You can use this class. The ringsdk interface library has encapsulated this function. You only need to call ringstatic: sethyperlink. The principle of implementing this hypertext link function is to call trackmouseevent and then process the wm_mousehover and wm_mouseleave messages. The two messages will be sent each time you move the cursor to the control and exit the control, therefore, you do not need to use a flag like the previous texture button to record the various states of the button. You only need to draw the highlighted status of the button in the wm_mousehover message, in the wm_mouseleave message, restore the original status of the button. The ringstatic class of the interface library sends custom messages wm_linkhover and wm_linkleave instead of forwarding the two messages to the parent window, therefore, the rendering of the demo program is processed in the two messages, which are the same as those of wm_mousehover and wm_mouseleave. It's easy to draw the code. paste the two resource images you use and you will see them at a glance, that is, draw different areas of the image to the window. 2nd images are animated based on continuous rendering. This image is generated in real time due to color matching.
-
C/C ++ code
-
RINGMSG(WndQQButton,WM_LINKHOVER)
{
if((HWND)param.wParam == m_btn->Handle())
{
int sx = BTN_PICWIDTH;
if(m_bIsSideToolHide)
sx += m_dibArrBtn.Width()/2;
m_dibArrBtn.Draw((BTN_WIDTH - BTN_PICWIDTH)/2,0,sx,0,BTN_PICWIDTH,BTN_PICHEIGHT,BTN_PICWIDTH,BTN_PICHEIGHT);
}
else if((HWND)param.wParam == m_btnQQ->Handle())
{
m_dibQQBtn.Draw(0,0,0,0,QQBTN_WIDTH,QQBTN_HEIGHT,QQBTN_WIDTH,QQBTN_HEIGHT);
Sleep(80);
m_dibQQBtn.Draw(0,0,QQBTN_WIDTH,0,QQBTN_WIDTH,QQBTN_HEIGHT,QQBTN_WIDTH,QQBTN_HEIGHT);
Sleep(80);
m_dibQQBtn.Draw(0,0,QQBTN_WIDTH*2,0,QQBTN_WIDTH,QQBTN_HEIGHT,QQBTN_WIDTH,QQBTN_HEIGHT);
}
return TRUE;
}
RINGMSG(WndQQButton,WM_LINKLEAVE)
{
if((HWND)param.wParam == m_btn->Handle())
{
int sx = 0;
if(m_bIsSideToolHide)
sx = m_dibArrBtn.Width()/2;
m_dibArrBtn.Draw((BTN_WIDTH - BTN_PICWIDTH)/2,0,sx,0,BTN_PICWIDTH,BTN_PICHEIGHT,BTN_PICWIDTH,BTN_PICHEIGHT);
}
else if((HWND)param.wParam == m_btnQQ->Handle())
{
m_dibQQBtn.Draw(0,0,QQBTN_WIDTH,0,QQBTN_WIDTH,QQBTN_HEIGHT,QQBTN_WIDTH,QQBTN_HEIGHT);
Sleep(80);
m_dibQQBtn.Draw(0,0,0,0,QQBTN_WIDTH,QQBTN_HEIGHT,QQBTN_WIDTH,QQBTN_HEIGHT);
Sleep(80);
m_dibBkg.Draw(0,0,QQBTN_X,QQBTN_Y,QQBTN_WIDTH,QQBTN_HEIGHT,QQBTN_WIDTH,QQBTN_HEIGHT);
}
return TRUE;
}
The m_dibxxx objects in the Code set the drawing target window as two static text controls during initialization. Therefore, Code such as getdc is not visible and encapsulated, because the Target DC is a static text control, the coordinates are well calculated. It is also easy to change the code into a GDI operation. The static text control has been set to a circle. Images other than DC will be drawn to the parent window, which meets our requirements, because there will be a halo (not obvious) when the mouse moves the small button up, and this halo is out of the button range.
In addition to initializing and creating static text controls, image coloring, and subclass static text control code, the two buttons in the lower left corner of qq2009 can be simulated in response to the above two messages. Isn't it easy? The code of the subclass static text control can be used to view the ringstatic. cpp of the ringsdk interface library or the code of the extended MFC hypertext link control class. The two buttons in qq2009 are not in the pressed status, but they are easy to add and implement. The code in the demo program can be easily changed to MFC or API, you can achieve your own Cool Button effect. By the way, the created static text control must be of the ss_policy window type; otherwise, the parent window cannot receive messages. The window type of the parent window does not need to be ws_clipchildren or ws_clipsiblings. Otherwise, the regional background occupied by the static text control is not drawn.
Next, let's talk about the self-painting in the toolbar.
One way to implement the self-painting toolbar is to subscribe to it and process its own wm_paint message. However, there are too many buttons in the toolbar, such as button form, flat form, highlighted, pressed, unavailable, etc., whether to display text, whether to display drop-down arrow, and so on, it is really troublesome to make a general self-painted toolbar. Here we will teach you a clever way. Taking the tool bar of qq2009 as an example, the subclass tool bar cannot be escaped, but you only need to process the wm_erasebkgnd message and refresh the background you want, you do not need to process the wm_paint message. Create a toolbar with the tbstyle_flat type and flat buttons, and prepare the following two images:
Next, the Code listed below is the called API:
-
C/C ++ code
-
Hbitmap = loadbitmap (...);
Himagelist himg = imagelist_create (20, 20, ilc_color32 | ilc_mask, 9, 4); // adjust the parameters here according to the image
Imagelist_addmasked (himg, HBM, 0x00ff00ff); // specify the transparent color as the purple color.
Sendmessage (hwndtoolbar, tb_setimagelist, 0, (lparam) himg );
Another image is processed as a method. sendmessage (m_hwndtoolbar, tb_sethotimagelist, 0, (lparam) himg) is set as a highlighted image. Then, send the tb_insertbutton message to add a button to the toolbar. The ibitmap of the tbbutton structure is set to the serial number of the corresponding button pattern in the image (starting from 0 ), in this way, the toolbar button pattern is not limited to 256 colors. Move the mouse over the button to display the highlighted pattern of the 2nd images, but there is still a border around the button, which the system will help you draw, A beautiful border has been drawn on the highlighted pattern. We don't need this border. How can we remove it? The parent window responds to the Message wm_notify of nm_customdraw:
-
C/C ++ code
-
Case wm_notify:
{
Lpnmhdr lpnm = (lpnmhdr) lparam;
If (lpnm-> code = nm_customdraw)
{
Lpnmcustomdraw lpnmdraw = (lpnmcustomdraw) lparam;
If (lpnmdraw-> dwdrawstage = cdds_prepaint)
Return cdrf_policyitemdraw; // specify the auto-painted notification button.
Else if (lpnmdraw-> dwdrawstage = cdds_itemprepaint)
Return tbcdrf_noedges; // The rest are handed over to the system for plotting, specifying that the button outer border is not needed
}
Break;
}
If the Custom button is required to return tbcdrf_noedges, the system will not draw the button border, so this Toolbar will be the same as the qq2009 toolbar at first glance. However, when the button is pressed, the border on the highlighted pattern is pressed along with the icon. After all, this border is not a real border, but a highlighted pattern. Of course, if you can accept this effect, it's okay. So far, it can save a lot of trouble.
Now, you only need to press the button, and the position of the border will not change. However, only two imagelist can be set in the toolbar, and one can be set without the imagelist in the pressed State. Therefore, you can only set the imagelist in the Self-painting state. You need to determine the lpnmdraw-> uitemstate flag, it is difficult to draw the border, draw the icon, and draw the text ..., hey, there is another clever method here. We only need to draw a pressed border and return tbcdrf_noedges. Other systems will help us. However, the system helps us draw a highlighted pattern and a pressed border. Therefore, we need to cancel the highlighted pattern, when creating the toolbar, you only need to send the tb_setimagelist Message setting button icon. We can draw the highlighted and pressed border by ourselves and prepare the following figure:
The left side is the highlighted border, and the right side is the pressed border. During Self-painting, draw the corresponding border of the Image Based on the lpnmdraw-> uitemstate mark:
-
C/C ++ code
-
Case wm_notify:
{
Lpnmhdr lpnm = (lpnmhdr) lparam;
If (lpnm-> code = nm_customdraw)
{
Lpnmcustomdraw lpnmdraw = (lpnmcustomdraw) lparam;
If (lpnmdraw-> dwdrawstage = cdds_prepaint)
Return cdrf_policyitemdraw; // specify the auto-painted notification button.
Else if (lpnmdraw-> dwdrawstage = cdds_itemprepaint)
{
Int SX;
Int off = (lpnmdraw-> RC. Bottom-lpnmdraw-> RC. Top-20)/2;
If (lpnmdraw-> uitemstate & cdis_selected ))
SX = 20;
Else if (lpnmdraw-> uitemstate, cdis_hot ))
SX = 0;
Else
Return tbcdrf_noedges;
HDC hmemdc = createcompatibledc (lpnmdraw-> HDC );
SelectObject (hmemdc, HBM); // HBM is the hbitmap of the pre-loaded border Pattern
Bitblt (lpnmdraw-> HDC, lpnmdraw-> RC. Left + off, lpnmdraw-> RC. Top + off, 20, 20, hmemdc, Sx, 0, srccopy );
Deletedc (hmemdc );
Return tbcdrf_noedges; // The rest are handed over to the system for plotting, specifying that the button outer border is not needed
}
}
Break;
}
OK, it's that simple. Now this toolbar has the same effect as the toolbar of qq2009.
Now let's talk about the tool bar implementation in the demo program. The code is similar, but it is much more complicated because the interface library encapsulates this. The interface library enables any sub-windows and controls to be docked. Therefore, the QQ button window and toolbar are docked at the bottom of the main interface, but they are set to not be dragged. Because it is a docked window, you cannot see the code of the mobile QQ button window and toolbar in the wm_size message in the main window, which is encapsulated. This is not the focus of this Article. If you are interested, you can go to the ringdocksite. cpp code in the interface library.
Now let's look at the program's:
The change is not very big. This article aims to teach you a simple method of creating a self-painted button and a self-painted toolbar. If you have any questions or different opinions, please leave a message for discussion. In the next article, the customer region in qq2009 and the pop-up menu in the lower left corner will be implemented.
Demo: http://d.download.csdn.net/down/2025754/ringphone
This article from the csdn blog, reproduced please indicate the source: http://blog.csdn.net/ringphone/archive/2010/01/26/5259819.aspx