From http://www.cnblogs.com/wangkewei/archive/2009/10/11/1580937.html
The previous article mentioned the user experience (UE), and said that there are few teams dedicated to ue in China. As far as I know, Microsoft, Nokia, Google, and Baidu in China have professional ue teams. For ordinary teams and developers like ours, there is little such experience. In addition, UE is generally regarded as a UI Designer and has little to do with developers like ours.
Of course not. The UE far exceeds the UI. Many factors lead to poor UE. For example, an incorrect copy of the data indicates that 17% of users think that the mobile phone is running slowly, and the long wait for Windows Mobile phones to start up is quite unbearable. Have our developed applications been optimized? Is the running efficiency quite satisfactory to users? Wait for these questions to be considered in development.
When using excellent products, you can experience, observe, and think carefully, and innovate on this basis. Gradually improve the UE design capability. (After Windows 7 is officially released, we can discuss its ue ^)
This article only discusses the technical issues related to interface development. In the course of learning, the deeper and wider the developer, the more he feels that his level is insufficient, we hope that we will discuss the interface development technology and UE.
Directories listed in the previous article:
1. Overview of related commercial products
2. Basic knowledge about Windows System Programming
3. DirectDraw Introduction
4. DirectDraw driver development
5. DirectDraw Application Development
6. A recommended entry sample
Part 1 has already been mentioned in the previous article. Due to space reasons, part 2, 3, 4, 5, and 6 will be introduced in the next article. This article first introduces how to use interfaces such as GDI under Win32 to implement a brilliant and efficient interface. In this way, we can discover the shortcomings of interfaces such as GDI and extend it to DirectDraw. (By default, you have basic Windows programming skills and are familiar with the concept of GDI .)
Supplementary content ● how to use interfaces such as GDI under Win32 to implement a brilliant and efficient interface
1. How to Make the interface beautiful?
How is it brilliant? Are there beautiful pictures? Is there Alpha transparency? Is there an animation?
Each person has different aesthetic points, so if many people think that your interface is beautiful, you can. The design interface is mainly the work of designer, including the design of UI logic, color matching design, etc. I think this can also be further divided into: designer familiar with user habits, aesthetic designer, etc. But in general, this allows programmers to do their jobs.
The following describes the interfaces that Windows provides to developers. You can use these interfaces to design beautiful interfaces.
2. How transparent? How translucent? How do I change the color gradient?
The following is a function encapsulated by the imaging COM component. You can use it to draw PNG images or other images. Creating PNG images with Alpha channels is transparent.
#include <imaging.h>#include <initguid.h>#include #pragma comment(lib, "Imaging.lib")BOOL DrawPNG(HDC hDC, TCHAR *szPicString, RECT &rcDraw){BOOL br = FALSE;IImagingFactory *pImgFactory = NULL;IImage *pImage = NULL;ImageInfo sImgInfo;CoInitializeEx(NULL, COINIT_MULTITHREADED);// Create the imaging factory.if (SUCCEEDED(CoCreateInstance(CLSID_ImagingFactory,NULL,CLSCTX_INPROC_SERVER,IID_IImagingFactory,(void **)&pImgFactory))){// Load the image from the JPG file.if (SUCCEEDED(pImgFactory->CreateImageFromFile(szPicString,&pImage))){// Draw the image.pImage->Draw(hDC, &rcDraw, NULL);pImage->Release();pImage = NULL;br = TRUE;}pImgFactory->Release();}CoUninitialize();return br;}
Bytes ------------------------------------------------------------------------------------------------------
The encapsulated function is used to draw a DC semi-transparent to another DC based on the Alpha value, and use the alphablend function.
BOOL AlphaBlt(HDC hdcDest, int nXOriginDest, int nYOriginDest, int nWidthDest, int nHeightDest, HDC hdcSrc, int nXOriginSrc, int nYoriginSrc, int nWidthSrc, int nHeightSrc, BYTE alpha) { BLENDFUNCTION bf; bf.BlendOp = AC_SRC_OVER; bf.BlendFlags = 0; bf.SourceConstantAlpha = alpha; bf.AlphaFormat = 0; return AlphaBlend(hdcDest, nXOriginDest, nYOriginDest, nWidthDest, nHeightDest, hdcSrc, nXOriginSrc, nYoriginSrc, nWidthSrc, nHeightSrc, bf);}
If your device supports alphablend hardware acceleration, it will be great, otherwise the software method will slightly affect the performance.
Bytes ------------------------------------------------------------------------------------------------------
Color gradient is also directly supported by APIs:
BOOL GradientFill( HDC hdc, PTRIVERTEX pVertex, ULONG nVertex, PVOID pMesh, ULONG nCount, ULONG ulMode);
HDC
[In] handle to the destination device context.
Pvertex
[In] pointer to an array of trivertex structures, each of which defines a triangle vertex.
Nvertex
[In] the number of vertices in pvertex.
Pmesh
[In] array of gradient_rect structures in Rectangle mode.
Ncount
[In] the number of rectangles in pmesh.
Ulmode
[In] specifies gradient fill mode. The following table shows the possible values for ulmode.
This function fills rectangular regions with a background color that is interpolated from color values specified at the vertices.
Whether you use the. net cf platform to call these Apis or Win32/mfc/ATL/wtl to directly call these APIs, you can achieve these effects. For more information, see the development documentation. After all, that is the best reference.
3. How to implement animation?
The principle of animation is that a frame-by-frame image moves backward Based on the timeline and becomes an animation after the eyes are cheated, therefore, the simplest way to get an animation is to draw a picture on the screen at a certain interval. Although it is very simple, this method is often used in programming. Sometimes simplicity is always the best.
Here is another technique, such as blurring each image with a motion filter in Photoshop, so that the animation obtained using the above method will feel very fast. You can also use a similar method to express 3D things in 2D to obtain 3D animation effects.
You can also use GIF animation, such as during startup and shutdown. The following encapsulated functions are for reference only.
BOOL DisplayGIF(TCHAR *szPicString){HANDLE hFile = CreateFile(strFileName, GENERIC_READ, 0, NULL, OPEN_EXISTING, 0, NULL);if (hFile == INVALID_HANDLE_VALUE){return FALSE;}DWORD dwFileSize = GetFileSize(hFile, NULL);if ( (DWORD)-1 == dwFileSize ){CloseHandle(hFile);return FALSE;}HGLOBAL hGlobal = GlobalAlloc(GMEM_MOVEABLE, dwFileSize);if (hGlobal == NULL){CloseHandle(hFile);return FALSE;}LPVOID pvData = GlobalLock(hGlobal);if (pvData == NULL){GlobalUnlock(hGlobal);CloseHandle(hFile);return FALSE;}DWORD dwBytesRead = 0;BOOL bRead = ReadFile(hFile, pvData, dwFileSize, &dwBytesRead, NULL);GlobalUnlock(hGlobal);CloseHandle(hFile);if (!bRead){return FALSE;}IStream* pStream = NULL;if ( FAILED(CreateStreamOnHGlobal(hGlobal, TRUE, &pStream)) ){return FALSE;}IImage *pImage = NULL;RECT rc;IImagingFactory *pImgFactory = NULL;CoInitializeEx(NULL, COINIT_MULTITHREADED);if ( !SUCCEEDED(CoCreateInstance(CLSID_ImagingFactory, NULL, CLSCTX_INPROC_SERVER, IID_IImagingFactory, (void **)&pImgFactory)) ){return FALSE;}IImageDecoder* pDecoder = NULL;UINT nCount = 0;if ( !SUCCEEDED(pImgFactory->CreateImageDecoder(pStream, DecoderInitFlagNone, &pDecoder)) ){return FALSE;}pDecoder->GetFrameDimensionsCount(&nCount);GUID *pDimensionIDs = (GUID*)new GUID[nCount];pDecoder->GetFrameDimensionsList(pDimensionIDs,nCount);TCHAR strGuid[39];StringFromGUID2(pDimensionIDs[0], strGuid, 39);UINT frameCount = 0;pDecoder->GetFrameCount(&pDimensionIDs[0],&frameCount);UINT iSize = 0;pDecoder->GetPropertyItemSize(PropertyTagFrameDelay,&iSize);BYTE* pBuff = new BYTE[iSize];PropertyItem* pItem = (PropertyItem*)pBuff;pDecoder->GetPropertyItem(PropertyTagFrameDelay,iSize,pItem);int fCount = 0;ImageInfo Info;pImgFactory->CreateImageFromStream(pStream,&pImage);pImage->GetImageInfo(&Info);rc.left = rc.top = 0;rc.right = Info.Width;rc.bottom = Info.Height;HDC tempDC;HBITMAP hbmNew = NULL;void * pv;BITMAPINFO bmi = { 0 };HBITMAP hbmOld = NULL;tempDC = CreateCompatibleDC(NULL);bmi.bmiHeader.biSize = sizeof(BITMAPINFOHEADER);bmi.bmiHeader.biWidth = Info.Width;bmi.bmiHeader.biHeight = Info.Height;bmi.bmiHeader.biPlanes = 1;bmi.bmiHeader.biBitCount = (SHORT) max(16, GetDeviceCaps(tempDC, BITSPIXEL));bmi.bmiHeader.biCompression = BI_RGB;hbmNew = CreateDIBSection(tempDC, &bmi, DIB_RGB_COLORS, &pv, NULL, 0);hbmOld = (HBITMAP)SelectObject(tempDC, hbmNew);pImage->Draw(tempDC, &rc, NULL);pDecoder->SelectActiveFrame(&pDimensionIDs[0], ++fCount);BitBlt(g_hdc, 0, 0, rc.right - rc.left, rc.bottom - rc.top, tempDC, 0, 0, SRCCOPY);delete []pBuff;delete []pDimensionIDs;pDecoder->Release();pImage->Release();pImgFactory->Release();CoUninitialize();return TRUE;}
4. How can we achieve high operation efficiency?
The subsequent content will introduce that using the "higher-level" interfaces of GDI is difficult to achieve high operation efficiency.
However, you can use some tips, such as "space for time ". Believe "lazy computation", you have heard of it. delay in processing this task until it is really needed (we will often use it in programming and need to be aware of it .) The skills used here are a little different. They process the things that users are likely to use in the future and store them, instead of waiting for the real needs of users.
For example, when you use the imaging COM component to draw a PNG image, you need to load the library file of the component each time, and then uninstall the component. The interface may need to be refreshed repeatedly, and then draw a PNG Image repeatedly. In this case, you can use a non-Interface main thread to save the PNG Image (for example, in the form of device context) when the program is started. When the interface is refreshed, only bitblt is sent to the target device. Bitblt is highly efficient. If you still cannot meet your efficiency requirements, consider the DirectDraw and other technologies described below.
The above method should be clear for those with rich development experience, but new users tend to ignore it. When developing the interface, we should ensure a basic principle: we should do everything possible to speed up the interface response to users under the existing conditions, and the interface should be user-centered. Therefore, we need to maintain this awareness during development.
5. How can I increase the startup speed of a program?
As mentioned in Part 1, to improve the running efficiency, You Can cache commonly used interfaces to the memory at program startup, so the startup time of the program will be greatly increased. How can this problem be solved? My suggestion is that the main UI thread can load the interface that a few users can directly see after starting, and another sub-thread (called a) is used to load other interfaces, after loading other interfaces, this sub-thread exits. When you click other interfaces, if the main thread finds that sub-thread A has not exited, it means that the other interfaces have not been fully loaded, and the user waits.
The benefit of this design is that the most time-consuming tasks can be apportioned to ensure that users can quickly see the interface and have a high efficiency in subsequent operations.
6. How to balance the beauty and efficiency?
The best way is to get the specific time consumption data during the interface runtime, and be accurate to each function if necessary. Obtain a copy of the data under normal circumstances of the system, and obtain a few copies of the data under bad circumstances (for example, the system is very busy, the device power is very small, and the data to be processed is very large ). Quantitative Analysis to solve these problems. If your beautiful interface still works well in a bad environment, Congratulations! You're so good!
Windows CE/Windows Mobile also provides some basic performance APIs (such as DirectDraw and other technologies also have their own performance interfaces and tools ):
BOOL QueryPerformanceCounter(LARGE_INTEGER* lpPerformanceCount);
-
Lpperformancecount
-
[In] pointer to a variable that the function sets, in counts, to the current performance-counter value. if the installed hardware does not support a high-resolution performance counter, this parameter can be set to zero.
This function retrieves the current value of the high-resolution performance counter if one is provided by the OEM.
BOOL QueryPerformanceFrequency(LARGE_INTEGER* lpFrequency);
-
Lpfrequency
-
[Out] pointer to a variable that the function sets, in counts per second, to the current performance-counter frequency. if the installed hardware does not support a high-resolution performance counter, the value passed back through this pointer can be zero.
This function retrieves the frequency of the high-resolution performance counter if one is provided by the OEM.
The above two APIs must be implemented by the OEM at the oal layer. The accuracy can be lower than 1 ms. Otherwise, the following APIs can be used.
DWORD GetTickCount(void);
For release comprehenations, this function returns the number of milliseconds since the device booted, excluding any time that the system was suincluded.GettickcountStarts at zero on boot and then counts up from there.
For debug configurations, 180 seconds is subtracted from the number of milliseconds since the device booted. This enables code that usesGettickcountTo be easily tested for correct overflow handling.
In addition, images such as PNG, bitmap, and GIF are optimized to make the image quality and size meet the requirements.
7. Why is the control so inefficient? How to reduce the use of controls?
Mobile phone software is different from desktop system software. On the one hand, mobile phone processing speed is lower, battery capacity is smaller, and on the other hand, users will use mobile phones to handle more urgent tasks. This is why I don't think we should fully learn from the desktop system software development experience on mobile phone software development. A x320 resolution mobile phone interface, you put 5, 6 controls, or even more, this interface is not too efficient, such an interface is not suitable as the most common interface for users, such as today's interface. On the other hand, Windows Standard and general controls do not have a very elegant appearance, even if they are customized. However, these controls provide significant development speed. So we need to coordinate well. The window cannot be used for the purpose of the window, nor can all windows be used.
Then you will ask how to coordinate. My suggestion is that you do not need to use any controls. In most cases, you can use images directly. For example, you can implement multi-state buttons as follows:
In wm_lbuttondown message processing, the system first checks whether the point is in the rect of the button. If the image in the pressed status is DC bitblt to the corresponding position on the screen, the wm_lbuttonup message processing will return bitblt.
8. The Win32-based interface is more efficient than the. net cf-based interface, but the development efficiency is low. What should I do?
Win32 programming is very old and lagging behind. But sometimes you have to choose a Windows Embedded device that is not as fast as running three. Encapsulate common functional code on the interface into a library (or a class library). accumulating such resources can improve the development efficiency of the team. C ++ generic programming exchange code reuse at the expense of compilation's validity rate, but does not affect the running's validity rate. It is worth further study and there are ready-made libraries available, such as STL.
Other technologies are available: DirectDraw (described later), direct3dm, and OpenGL ES. However, development is difficult.
9. How to Use GDI + (native/managed )?
GDI + is the next version of GDI, which has been improved and is easier to use. One advantage of GDI is that you do not have to know any details about how data is rendered on the device. GDI + has better implemented this advantage. That is to say, GDI is a medium-and low-level API, you may also need to know the device, while GDI + is a high-level API, you do not have to know the device. The following is a reference from the msdn document:
"2-D vector graphicsInvolves drawing primitives (such as lines, curves, and figures) that are specified by sets of points on a coordinate system.
For example, the rect class stores the location and size of a rectangle; the pen class stores information about line color, line width, and line style; and the graphics class has methods for drawing lines, rectangles, paths, and other figures. there are also several brush classes that store information about how closed figures and paths are to be filled with colors or patterns.
Certain kinds of pictures are difficult or impossible to display with the techniques of vector graphics.ImagingPart will resolve this problem. An example of such a class is cachedbitmap, which is used to store a bitmap in memory for fast access and display.
TypographyIs concerned with the display of text in a variety of fonts, sizes, and styles. One of the new features in GDI + is subpixel antialiasing."
Windows CE/Windows Mobile's GDI + is only a small subset of Windows desktop systems. Opennetcf encapsulates GDI +, which can be based on. net CF developers provide convenience. The native code version provided by Microsoft is the imaging COM component mentioned earlier. You can also directly call gdiplus. DLL class and method. Some of the features of Windows CE version GDI +, which are not supported by Windows CE, can be compiled online. You can use the Lib library and header file provided by it for development. But it may not be very stable.
Gdiplus. dll file in Windows Mobile 6:
Export the above DLL file to get the function:
10. How to implement transparent controls and other issues?
Windows does not support window Alpha transparency, so the background of the control cannot be transparent directly. The common method is to use the background of the window after the control as the background of the control.
The principle is a bit difficult. You can study the Code:
Http://www.codeproject.com/KB/mobile/transparent_controls.aspx (C ++)
Http://www.codeproject.com/KB/dotnet/TransparentControl.aspx #)
Other references:
Li Bo's blog
How to design a beautiful User Interface Program (win32) on Windows Mobile)
Buttons for customizing multiple States (win32) in Windows Mobile 6.0)
Multiple Status buttons (win32) for self-painting in Windows Mobile 6.0
Author: Wang Kewei
Source: http://wangkewei.cnblogs.com/
Copyright: The copyright of this article is shared by the author and the blog. The detailed link of this article must be noted during reprinting; otherwise, the author will reserve the right to pursue its legal liability.