I think there should be a lot of apps like QQ interface. I searched a lot and found out that there were only two or three apps that I did not imagine. I often see someone asking on csdn how to implement the QQ function and how to implement the interface. I summarized it and decided to write such a QQ-like interface program. All practical functions would not be implemented, imitation interface only:
Shaped window
Texture page
Adjustable UI color and Shading
Similar to various self-painted controls on the QQ Interface
The qq2009 interface is actually very complicated. It takes a lot of time to simulate the same interface. It is a nightmare to use APIs to implement it. Therefore, ringsdk is used here. For details about ringsdk, please go to this link. The image library of ringsdk can be combined with the interface library to implement some cool interfaces. This is the demonstration of the Image Library and interface library to achieve the qq2009 interface. OK, let's go! However, let's just explain that this is just an imitation of the interface. This is not the case with the actual QQ interface.
Qq2009 is a rectangle window in the garden corner, not a complex shape, so it is easy to implement. createroundrectrgn and setw.wrgn will be fine. But the window can be dragged to adjust the size, so it is not easy to set at the beginning, you need to change the rgn in the wm_size message at any time:
-
C/C ++ code
-
RECT rc; GetWindowRect(m_hWnd,&rc); OffsetRect(&rc,-rc.left,-rc.top); if(m_hrgn) DeleteObject(m_hrgn); m_hrgn = CreateRoundRectRgn(rc.left,rc.top,rc.right,rc.bottom,NCB_CORNERSIZE,NCB_CORNERSIZE); SetWindowRgn(m_hWnd,m_hrgn,TRUE); InvalidateRect(m_hWnd,NULL,TRUE); RECT rc; GetWindowRect(m_hWnd,&rc);OffsetRect(&rc,-rc.left,-rc.top); if(m_hrgn) DeleteObject(m_hrgn);m_hrgn = CreateRoundRectRgn(rc.left,rc.top,rc.right,rc.bottom,NCB_CORNERSIZE,NCB_CORNERSIZE);SetWindowRgn(m_hWnd,m_hrgn,TRUE);InvalidateRect(m_hWnd,NULL,TRUE);
Then, you need to draw the border during wm_ncpaint, create a QQ border color brush, and use roundrect to draw a rounded border.
The title bar and system buttons of QQ are self-painted. They should have been drawn in the wm_ncpaint message. However, an edit box is displayed when you click "Edit personalized signature, controls cannot be placed in the title bar. Therefore, when creating the main window, do not enter the title bar. All customer zones are displayed. A title bar area is displayed above the customer zone. To adjust the window size, the window type is ws_popupwindow | ws_thickframe | ws_minimizebox | ws_maximizebox. Therefore, the default window border does not meet our requirements, you need to set the border size in the wm_nccalcsize message:
-
C/C ++ code
-
Ringmainmsg (wm_nccalcsize) {lprect LPRC = (lprect) Param. lparam; LPRC-> top + = wnd_border; LPRC-> left + = wnd_border; LPRC-> right-= (wnd_border + 1 ); // set the position of the right border to the line of the border, 1 LPRC-> bottom-= (wnd_border + 1); // Similarly, return 0 ;}
Set the border size to 2. There is an interesting phenomenon here: Even if you do not respond to the wm_nccalcsize message, the created window does not have a title bar, and there is no smallest/big, close button, however, you can right-click the program button on the taskbar, minimize, move, size, and close a lot of options, and the window also responds to these commands. If the ws_ex_toolwindow extension type is added to the window, the program will not appear on the taskbar, which is the same as QQ. However, currently, our program only implements the texture of the title bar, this extension type is not supported for the time being. You can right-click the program button on the taskbar to minimize the window size and close the window. However, this is a little too much, so it is not a problem to add an icon to the system bar, the ringsdk encapsulates this. Here, addintaskbar (m_hwnd, loadicon (getinstance (), makeintresource (idi_qq), and "qq2009 interface. Click the pop-up menu of the response icon and I will not explain it here. You can see the code.
The next step is the interface texture, which is used to draw the upper and lower areas of QQ. The interface library is required here. First of all, we need to prepare images, which are not found in QQ resources, so I am too lazy to study them. I made it myself and set the width to 1, images with a height of 95 and 55 are tiled to the upper and lower backgrounds. The Vista-style system button pattern is a rounded corner and requires a transparent color. Therefore, the image is in GIF format. Bottom grain, the beach seagull pattern on the right side does not have this skill, and finds another similar, made into PNG format, PS adds a mask inside has alpha channel. The Image Library supports PNG semi-transparent rendering, As long as alphato is called. There is also a user profile picture, just cut one, add these materials to the resource, calculate the quasi-coordinates for double buffering, and draw them to the memory image in sequence. Here we will talk about the creation of memory images. A memory image with the same width as the screen and a height of 95 + 55 was created from the very beginning, so that it does not need to be released frequently in wm_size. The Code is as follows:
-
C/C ++ code
-
// First draw each clip to the memory image m_dibbanner // background m_dibbkg.stretchto (& m_dibbanner, RC. right, m_dibbanner.height (), m_dibbkg.width (), m_dibbkg.height (), false); // Title ("qq2009") m_dibcaption.alphato (& m_dibbanner ); // decorative pattern, that is, QQ's so-called "Shading" m_dibtatoo.alphato (& m_dibbanner, RC. right-m_dibTatoo.Width (), 0); // user profile m_dibuser.drawto (& m_dibbanner, m_dibuser.width (), m_dibuser.height ()); // username and signature (& m_dibbanner, 54,25, 0,0, m_dibuserbanner.width (), m_dibuserbanner.height (); // system button // minimize m_dibbtnrc.drawto (& m_dibbanner, RC. right-ncb_entirewidth-ncb_space, ypos, grcbtn [0]. x, grcbtn [0]. y, ncb_minwidth, ncb_height); // disable m_dibbtnrc.drawto (& m_dibbanner, RC. right-ncb_closewidth-ncb_space, ypos, grcbtn [ncb_closenormal]. x, grcbtn [ncb_closenormal]. y, ncb_closewidth, ncb_height); // maximize/restore if (iszoomed () {m_dibbtnrc.drawto (& m_dibbanner, RC. right-ncb_entirewidth-ncb_space + ncb_minwidth, ypos, grcbtn [ncb_restorenormal]. x, grcbtn [ncb_restorenormal]. y, ncb_maxwidth, ncb_height);} else {m_dibbtnrc.drawto (& m_dibbanner, RC. right-ncb_entirewidth-ncb_space + ncb_minwidth, ypos, grcbtn [ncb_maxnormal]. x, grcbtn [ncb_maxnormal]. y, ncb_maxwidth, ncb_height);} // draw to the window // The title bar area m_dibbanner.draw (HDC, RC. right, ncb_titleheight, RC. right, ncb_titleheight); // Bottom Bar m_dibbanner.draw (HDC, 0, RC. bottom-ncb_bottomheight, 0, ncb_titleheight, RC. right, ncb_bottomheight, RC. right, ncb_bottomheight); first, draw each clip to the memory image m_dibbanner // background m_dibbkg.stretchto (& m_dibbanner, RC. right, m_dibbanner.height (), m_dibbkg.width (), m_dibbkg.height (), false); // Title ("qq2009") m_dibcaption.alphato (& m_dibbanner ); // decorative pattern, that is, QQ's so-called "Shading" m_dibtatoo.alphato (& m_dibbanner, RC. right-m_dibTatoo.Width (), 0); // user profile m_dibuser.drawto (& m_dibbanner, m_dibuser.width (), m_dibuser.height ()); // username and signature (& m_dibbanner, 54,25, 0,0, m_dibuserbanner.width (), m_dibuserbanner.height (); // system button // minimize m_dibbtnrc.drawto (& m_dibbanner, RC. right-ncb_entirewidth-ncb_space, ypos, grcbtn [0]. x, grcbtn [0]. y, ncb_minwidth, ncb_height); // disable m_dibbtnrc.drawto (& m_dibbanner, RC. right-ncb_closewidth-ncb_space, ypos, grcbtn [ncb_closenormal]. x, grcbtn [ncb_closenormal]. y, ncb_closewidth, ncb_height); // maximize/restore if (iszoomed () {m_dibbtnrc.drawto (& m_dibbanner, RC. right-ncb_entirewidth-ncb_space + ncb_minwidth, ypos, grcbtn [ncb_restorenormal]. x, grcbtn [ncb_restorenormal]. y, ncb_maxwidth, ncb_height);} else {m_dibbtnrc.drawto (& m_dibbanner, RC. right-ncb_entirewidth-ncb_space + ncb_minwidth, ypos, grcbtn [ncb_maxnormal]. x, grcbtn [ncb_maxnormal]. y, ncb_maxwidth, ncb_height);} // draw to the window // The title bar area m_dibbanner.draw (HDC, RC. right, ncb_titleheight, RC. right, ncb_titleheight); // Bottom Bar m_dibbanner.draw (HDC, 0, RC. bottom-ncb_bottomheight, 0, ncb_titleheight, RC. right, ncb_bottomheight, RC. right, ncb_bottomheight );
Now the texture window is complete. Let's take a look at the program:
The current program can be dragged to adjust the size, double-click to maximize, the system bar icon right-click to pop up the QQ-like menu, however, only the "Open main panel" and "close" commands are valid. The buttons on the interface are only textures and do not respond to the mouse action. The next step is to implement the three-state and Functional Response of the interface buttons. Add other functions.
Note: The interface library supports MFC, and the texture code in the program can be copied to the MFC program. You only need to include "ringdib. H. However, you must first compile the zlib and PNG Libraries under libsrc \ freelib. To support JPG, you must also compile the JPG library.
Program: http://d.download.csdn.net/down/1974639/ringphone
This article from csdn blog, original address: http://blog.csdn.net/ringphone/archive/2010/01/08/5154760.aspx