An open-source library is good.
Author Blog: http://hi.csdn.net/space-157361.html
VckBase page: http://www.vckbase.com/document/viewdoc? Id = 1849
Source code download: http://www.codeproject.com/KB/GDI/SonicUI.aspx
Make UI development easy and happy, and use the SonicUI engine to achieve common UI Effects
Author: Sonic
Download source code
Abstract: As a windows engineer, UI development is inevitable. Whether you are writing a supply and marketing storage system or chatting IM, UI development will always occupy a lot of your time. Next, we will show a very easy and quick UI development solution in windows to implement the UI effects that you often need to implement in your actual work, strive to free you from complicated UI work and devote your attention to more challenging work.
Keywords: UI engine profiled forms animation buttons gdi Engine Self-painted controls lightweight
As a windows engineer, UI development is inevitable. Whether you are writing a supply and marketing storage system or chatting IM, UI development will always occupy a lot of your time. Some time ago, in the company's development project, I realized a UI engine that had been conceived for a long time with a little selfishness. During the use process, I felt that the UI development efficiency was greatly improved, I hope to share with you and use your suggestions for continuous improvement.
Next, we will take several common UI development problems in actual work as an example to introduce the implementation methods and effects. I believe these problems can resonate with the client UI development colleagues.
1. Support for multi-format images
2. Text and hyperlink
3. Custom button
4. Dirty processing and region refresh
5. Special-shaped forms (including pixel-level transparent special-shaped forms)
1. Support for multi-format images
UI development is inseparable from images. windows APIs provide some image loading methods, such as commonly used LoadImage, which are easy to use. However, its function is as simple as its usage. It can only load bmp, ico, and other formats. As we all know, bmp does not contain alpha channels. Once the shadow and other alpha gradient effects need to be achieved, the APIS provided by the system will be somewhat stretched. Of course many people will think of the well-known CxImage, which is also a good choice. I also encapsulated CxImage internally to help load and store multi-format images, but after loading, image data processing is self-processed, because CxImage is processing RGB to hsl, A large number of floating point operations are used in special effects such as rotation, and the efficiency cannot be satisfactory. I converted all the floating-point operations into integer operations, and used a lot of SSE2 commands for optimization. The test results show that in the special effects such as rotation, HSL conversion, and gray conversion, the efficiency can be increased by 4-10 times (the CPU is T2330 1.6 GHz ). Image loading supports three methods: From file, from resource, and from dc. You must specify the resource type as IMAGE when loading resources.
The Demo code is as follows:
// GetSonicUI is the only function exported by the engine. It is the class factory and engine control, and is responsible for creating and destroying objects.
ISonicImage * pImg = GetSonicUI ()-> CreateImage ();
PImg-> Load ("C: \ 1.png ");
PImg-> Draw (hdc, 10, 10 );
GetSonicUI ()-> DestroyObject (pImg );
OK. A png image with a transparent channel is ready to be drawn. Is it easy.
2. Text and hyperlink
In the UI development process, the most troublesome thing is to draw text. You need to initialize the font constantly and set the font attributes. If the product personnel require the text to be formatted or output the color text, that is our nightmare. Adding hyperlinks to your own interface already has a lot of DEMO code on the Internet, but I believe ISonicString is a simpler implementation solution. ISonicString is a UI component object for message interaction. You only need to add some similar controllers like the html language, and you can control the font size, color, hyperlink, and other attributes as you like, which is very convenient.
ISonicString * pStr = GetSonicUI ()-> CreateString ();
PStr-> Format ("/c = % x, a = 'HTTP: // hi.csdn.net/zskof', font, font_height = 16/click here to open the link", # 0000ff );
Lresult callback WndProc (HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
{
PAINTSTRUCT ps;
HDC hdc;
Switch (message)
{
Case WM_PAINT:
{
Hdc = BeginPaint (hWnd, & ps );
PStr-> TextOut (hdc, 0, 0, hWnd );
EndPaint (hWnd, & ps );
}
Break;
}
.
.
.
}
You only need to create a line, Format a string like the Format of CString, and output it in the WM_PAINT response. You only need three steps to get a complete line of blue hyperlinks, is it very convenient. By controlling characters, you can also set the underline style, Mouse shape, and color change when responding to the mouse. For details, see the comments in ISonicUI. h.
ISonicString can also be used to output text and image in combination or to make the image have hyperlink attributes. You must use the 'p' control to specify the id of an ISonicImage:
ISonicImage * pImg = GetSonicUI ()-> CreateImage ();
PImg-> Load ("C: \ 1.png ");
ISonicString * pStr = GetSonicUI ()-> CreateString ();
PStr-> Format ("/c = % x/Hello, friend/p = % d, a = 'HTTP: // hi.csdn.net/zskof'/", # 0000ff, pImg-> GetObjectId ());
In this way, you can perform text and image mixed typographical output on your interface just like writing a webpage.
3. Custom button
A self-painted button is probably the most common and repetitive work in UI writing. It is generally inherited from CButton and then ownerdraw. My implementation is not to use pure self-painting of forms. In fact, Hyperlinks can also be understood as one type of buttons, so the usage of Self-painted buttons is similar to that of hyperlinks.
Void WINAPI OnMove (ISonicString * pStr, LPVOID)
{
G_pEffect-> MoveGently (0, 0 );
}
// Load three-state image resources
ISonicImage * pImgNormal = GetSonicUI ()-> CreateImage ();
PImgNormal-> Load (BMP _normal );
PImgNormal-> SetColorKey (# ff00ff );
ISonicImage * pImgHover = GetSonicUI ()-> CreateImage ();
PImgHover-> Load (BMP _hover );
PImgHover-> SetColorKey (# ff00ff );
ISonicImage * pImgClick = GetSonicUI ()-> CreateImage ();
PImgClick-> Load (BMP _click );
PImgClick-> SetColorKey (# ff00ff );
// ISonicString * g_pTest [10]
G_pTest [10]-> Format ("/a, p = % d, ph = % d, pc = % d, linkt = 'click to move '/", pImgNormal-> GetObjectId (), pImgHover-> GetObjectId (),
PImgClick-> GetObjectId ());
G_pTest [10]-> Delegate (DELEGATE_EVENT_CLICK, NULL, NULL, OnMove );
Similarly, the formatted ISonicString can be output when OnPaint is used, so that you have a beautiful button with three-state transformation. The 'P' keyword indicates the normal state, 'ph' indicates the hover state, and 'pc' indicates the click state. It doesn't matter if the source image obtained from the artist is a three-state tiled image. You only need to direct the ph and pc to the same img, and the source area is automatically cropped internally. In addition, people who have used QQ2009 may find that many of the buttons in 2009 are gradient and have a good experience. ISonicString can be used in the same way. You only need to modify it when formatting,
G_pTest [10]-> Format ("/a, p = % d, ph = % d, pc = % d, linkt = 'click my mobile ', animation = 40/", pImgNormal-> GetObjectId (),
PImgHover-> GetObjectId (), pImgClick-> GetObjectId ());
Add a 'animation = 40' controller (40 is the gradient speed) to get a three-state gradient button as beautiful as QQ2009. The button click response uses the "delegate" method. You need to delegate a global function or class member function, such as void WINAPI Func (ISonicBase *, LPVOID), to the button, for callback when the engine is clicked.
Figure 1: Custom button
4. Dirty processing and region refresh
We all know that the drawing efficiency of gdi is not high and it cannot be as refreshing as the direct operation of the memory buffer in DDraw. Therefore, InvalidateRect provides the partial refresh parameter, partial refresh is also the key to optimization in gdi. In practice, I don't often see people doing this fine cutting. It's a matter of InvalidateRect (hwnd, NULL, TRUE. It's no wonder that I am using a string in TextOut. If I want to care about how many regions it occupies, cross-cutting between regions, and so on, it's too tedious. Therefore, my engine provides an ISonicPaint object. Its name is a canvas. When creating this canvas, you can specify that it has its own memDC. To save the gdi object, you can also specify that it is a canvas without memDC, how to Choose based on the actual situation.
Create a canvas
ISonicPaint * pPaint = GetSonicUI ()-> CreatePaint ();
PPaint-> Create (FALSE/* Whether memDC */, m_rtString.Width ()/* width */, m_rtString.Height ()/* height */);
After creating the canvas, you only need to call the Draw method of the screen in WM_PAINT, which is very simple. If you want to draw on the canvas, You need to delegate your own painting process to the canvas, just like the self-painted button, so that you can call it each time you redraw the canvas. The sample code is as follows:
class CTest
{
public:
void RenderImage(ISonicPaint * pPaint, LPVOID);
};
void CTest::RenderImage(ISonicPaint * pPaint, LPVOID)
{
if(pPaint->GetCurrentPaint() == NULL)
{
return;
}
HDC hdc = pPaint->GetCurrentPaint()->hdc;
int x = pPaint->GetCurrentPaint()->x;
int y = pPaint->GetCurrentPaint()->y;
// draw here
...
}
CTest test;
pPaint->Delegate(DELEGATE_EVENT_PAINT, NULL, &test, CSonicString::RenderImage);
In this way, you only need to call pPaint-> Redraw () to re-paint the area of the canvas. Here, we need to note that ISonicString, including the following objects, are all canvas-based. That is to say, all the objects in the engine are subject to dirty checking and region self-drawing optimization, this greatly improves the running efficiency.
In addition to delegate painting, you can also directly add UI objects to the canvas. Supported objects include ISonicImage, ISonicString, and ISonicPaint.
5. Special-shaped forms (including pixel-level transparent special-shaped forms)
Special form is also a frequently used technology in UI special effects. There are two common implementation methods. One method is to crop an rgn Based on the image and call setjavaswrgn. The other method is to set the form to the WS_EX_LAYERED attribute and call SetLayeredWindowAttributes or UpdateLayeredWindow to achieve transparent cropping. The former method is less efficient, and there will be ugly shadows when you drag the form. The latter method has better performance. When you drag the form, you can avoid shadows, but it cannot act on the form of the WS_CHILD attribute. Both have advantages and disadvantages. SonicUI also provides these two implementation methods, which can be selected as needed.
Method 1:
...
// ISonicImage * pImg
SetWindowRgn(hWnd, pImg->CreateRgn());
Method 2:
...
// ISonicImage * pImg
// ISonicWndEffect * pEffect
PEffect-> Attach (hWnd, TRUE); // use the pixel-level alpha mode attach
PEffect-> SetShapeByImage (pImg );
Figure 2: Special form
It is worth mentioning that if UpdateLayeredWindow is used for Pixel-level alpha effects on the form, text output becomes a hassle, because the text output function of gdi does not contain the alpha channel, directly going to TextOut does not work normally. However, ISonicString can help you solve this problem. I have added an alpha channel to the text to better adapt to the background.
Conclusion: The engine also contains rolling subtitle components, animation components, and other commonly used UI presentation components, which are not described in detail. Please refer to the instructions in ISonicUI. h for your own trial. The basic principle for designing this engine is light and efficient. If you have any suggestions or requirements during use, please contact me to help me improve this engine. Because the engine has tens of thousands of lines of complete implementation code and is still owned by the company, the complete source code will not be published for the moment. If you are interested in some technical implementation details, contact me, learn and make progress together.
QQ: 20346020
E_mail: zs_kof@163.com
Bytes --------------------------------------------------------------------------------------
Other UI Software
Http://topic.csdn.net/u/20100306/00/ad4496f4-7d82-459b-b523-e18b42675580.html
SkinSE (full name: skin so easy)
The documentation is also comprehensive.
SkinSB
Http://topic.csdn.net/u/20100127/12/491a7a32-9231-4227-bc33-fb9a2f629457.html
Http://www.skinse.com/update.html
Codejock Xtreme Toolkit
VS 2008 Feature Pack
Http://blog.csdn.net/barech/archive/2009/07/02/4315157.aspx