定制 Windows CE .NET 用戶界面
Mike Hall
Microsoft Corporation
Microsoft Corporation
Steve Maillet
Entelechy Consulting
April 4, 2002
Entelechy Consulting
April 4, 2002
// interface翻譯成界面,部分時(shí)候翻譯成接口
(沒有全文翻譯,只是摘記了一些有用的信息,和自己的一些理解)
WinCE 的UI是skinnable。
Recently, while preparing for a talk at an Embedded event, a bullet point in my presentation seemed to beg for elaboration: the skinnable UI for Microsoft? Windows? CE .NET. I had talked to this point at a number of conferences, but had spent little time playing with the code to produce a customized UI. Since I had a few moments in the speaker lounge (and also an article to write), it seemed a good time to take a look at how the UI can be customized for Windows CE. On my wish list: customized screen colors, Windows controls that don't look like they belong to Windows, an OK/Close button in the non-client area that looks like a smiley face, a replacement shell (perhaps based on Microsoft? Internet Explorer 5.5 browser), and a shiny bike with basket and bell for Christmas...
Okay, so on with the article; let's see what's lurking beneath the hood of the Windows CE UI.
Windows CE .NET 提供為你的嵌入式設(shè)計(jì)定制用戶界面的能力。如 POS terminals, ATM machines, or other 'fixed function' devices。也可以用Internet 瀏覽器和應(yīng)用程序.以前版本的WINCE也可以定制用戶界面,但帶有明顯的WINDOWS外觀和感覺。現(xiàn)在WINCE 。NET改變了這個(gè)。
這里有一些選擇,在為一個(gè)Windows CE .NET 設(shè)備定制界面時(shí):
· 使用 Microsoft Internet Explorer 作為設(shè)備的shell. 這是一個(gè)非常彈性的選擇。使用HTML(和DHTML)編制高度定制化的用戶界面是快速的,簡單的和彈性的??梢猿浞掷梦粓D,動(dòng)畫,動(dòng)態(tài)。
· 創(chuàng)建一個(gè)獨(dú)立的應(yīng)用程序來取代標(biāo)準(zhǔn)shell。在概念上,這個(gè)和使用IE是類似的。是一個(gè)很好的選擇在一個(gè)功能單一的設(shè)備上,如點(diǎn)銷售終端(point-of-sale terminal)上。 It's possible to change the appearance of controls within an application by subclassing the control, which is achieved through GetWindowLong( ) and SetWindowLong( ) API's. (Feel free to check out any of the number of articles on MSDN that discuss subclassing.)
· 在操作系統(tǒng)里改變某些用戶界面組件的外觀??梢酝ㄟ^改變位圖和代碼來實(shí)現(xiàn)。
Microsoft在Windows CE .NET中提供了2種皮膚: Windows 95 外觀和Windows XP 外觀. 這些分別為通用控件,windows控件,和非客戶區(qū)提供windows外觀。“皮膚”文件 在下面文件夾處:
WINCE420PUBLICCOMMONOAKDRIVERSSKINNABLEUI.
在skinnableui 文件夾下提供的代碼可以改動(dòng)(因?yàn)槭窃趐ublic樹下),可以被你的設(shè)備所采用。
Take a look in the skinnableui folder. There are two sets of user interface components: GWE/COMMCTRL (Windows 95 appearance) and GWEXP/COMMCTRLXP (Windows XP).
Here's how we choose which of the 'skins' is applied to our device:
1. Build an operating system image using the default catalog options; this will give a Windows 95 appearance.
2. 從catalog里選擇Windows XP skin。在 Core O/S/Display Based Devices/Shell and User Interface/User Interface/Customizable UI/Windows XP-like sample skin. 加這個(gè)組件到平臺(tái)里,或者設(shè)置the SYSGEN_XPSKIN 環(huán)境變量.
How do these skins differ? Let's take a look at some of the UI differences. We can then take a look at how to further customize the Windows CE .NET user interface.
Figure 1. Windows 95 外觀,使用標(biāo)準(zhǔn)皮膚。
Figure 2. Windows XP 外觀, 使用XP-風(fēng)格皮膚。
Let's now examine how we modify the Windows CE .NET user interface. This includes:
· Changing the user interface colors.
· Modifying user interface bitmaps.
· Modifying Windows CE .NET controls appearance.
· Modifying standard UI dialogs (for instance, Startupwhich can be used to show device configuration or password screen, Out of Memory, and Touch Screen Calibration).
· Using Internet Explorer as the shell of our device.
Changing the User Interface Colors
One of the quickest and simplest ways to modify the appearance of a device is to modify some or all of the user interface colors. This is achieved through the registry. Note that the default system colors are not visible in the devices registry. To set colors to something other than the default system colors, we need to override the color map in the registry. The easiest way to do this is to build an operating system image using Platform Builder, download the image to either the emulation environment or to a reference board, use the control panel to modify the color scheme to match the colors you require for your device, and then use the remote registry editor to take a snapshot of the updated colors from the registry—after all, who wants to spend time guessing RGB values? The color map can be found in the following registry location: HKEY_LOCAL_MACHINESYSTEMGWESysColor.
If we were to modify the system color map on a device (or emulator) and use Remote Registry Editor to extract a .REG file, here's how the extracted .REG file might look. Once we've extracted the registry information we can then add this to our Project.REG file and rebuild our platform to take advantage of the new color scheme.
[HKEY_LOCAL_MACHINESYSTEMGWE]
"SysColor"=hex:E0,E0,E0,00, 00,80,80,00, 80,80,FF,00, 80,80,80,00,
C0,C0,C0,00, FF,FF,FF,00, 00,00,00,00, 00,00,00,00,
00,00,00,00, FF,FF,00,00, C0,C0,C0,00, C0,C0,C0,00,
80,80,80,00, 00,00,FF,00, 00,00,FF,00, C0,C0,C0,00,
80,80,80,00, 80,80,80,00, 00,00,00,00, C0,C0,C0,00,
FF,FF,FF,00, 00,00,00,00, DF,DF,DF,00, 00,00,00,00,
FF,FF,E1,00
The .REG file contents directly map to the following colors on the device (note that each color is represented by 4 hex digits).
COLOR_SCROLLBAR
COLOR_BACKGROUND
COLOR_ACTIVECAPTION
COLOR_INACTIVECAPTION
COLOR_MENU
COLOR_WINDOW
COLOR_WINDOWFRAME
COLOR_MENUTEXT
COLOR_WINDOWTEXT
COLOR_CAPTIONTEXT
COLOR_ACTIVEBORDER
COLOR_INACTIVEBORDER
COLOR_APPWORKSPACE
COLOR_HIGHLIGHT
COLOR_HIGHLIGHTTEXT
COLOR_BTNFACE
COLOR_BTNSHADOW
COLOR_GRAYTEXT
COLOR_BTNTEXT
COLOR_INACTIVECAPTIONTEXT
COLOR_BTNHIGHLIGHT
COLOR_3DDKSHADOW
COLOR_3DLIGHT
COLOR_INFOTEXT
COLOR_INFOBK
COLOR_STATIC
COLOR_STATICTEXT
COLOR_BACKGROUND
COLOR_ACTIVECAPTION
COLOR_INACTIVECAPTION
COLOR_MENU
COLOR_WINDOW
COLOR_WINDOWFRAME
COLOR_MENUTEXT
COLOR_WINDOWTEXT
COLOR_CAPTIONTEXT
COLOR_ACTIVEBORDER
COLOR_INACTIVEBORDER
COLOR_APPWORKSPACE
COLOR_HIGHLIGHT
COLOR_HIGHLIGHTTEXT
COLOR_BTNFACE
COLOR_BTNSHADOW
COLOR_GRAYTEXT
COLOR_BTNTEXT
COLOR_INACTIVECAPTIONTEXT
COLOR_BTNHIGHLIGHT
COLOR_3DDKSHADOW
COLOR_3DLIGHT
COLOR_INFOTEXT
COLOR_INFOBK
COLOR_STATIC
COLOR_STATICTEXT
Note that COLOR_BTNFACE is used throughout the Windows XP-like user interface as the color for caption bars and the like.
Modifying User Interface Bitmaps
Another way to get a UI facelift is to alter some of the standard UI bitmaps.The bitmaps contain the toolbar button images used in standard Windows CE .NET applications, such as Microsoft? Windows Explorer. The toolbar bitmaps can be found in the following folder: WINCE400publiccommonOAKFILES.
· Stdsm.bmp: Windows 95-like toolbar bitmaps.
· Stdsmxp.bmp: Windows XP-like toolbar bitmaps.
· Viewsm.bmp: Windows 95 'file' toolbar bitmaps.
· Viewsmxp.bmp: Windows XP 'file' toolbar bitmaps.
So how about the 'Close' button on an applications caption bar? Can we also modify how this looks? Yes, absolutely. Let's look at how to change the Windows XP look.
This isn't as simple as it first seems. There are two parts to the Close button. The first is the background bitmap, which can be found in C:wince400publiccommonOAKDRIVERSSKINNABLEUIGWEXPGCACHEVIEWXPRES—the file is Closebutton.bmp. This contains the button background in up, down, selected, and disabled form. So how does the white "X" get added to the button?
Right, lets roll up them sleeves and dig into some of the skinnableui source code???… Perhaps the first stop on the tour of the code is the initialization function for the XP skin code. The code is wrapped into a class called CacheView_t. The initialization function is called Init( ). The CacheView_t::Init( ) function is located in SKINNABLEUIGWEXPGCACHEVIEWXPgcacheviewxp.cpp. Let's take a look at some of the code. This is where the GDI object cache is setup.
// close button
HBITMAP hbmCloseButton = NULL;
hbmCloseButton = LoadBitmapW_I (hInstance,
MAKEINTRESOURCE(GWES_CLOSEBUTTON));
ASSERT (hbmCloseButton);
g_cacheview.hdcCloseButton = Gdi::CreateCompatibleDC_I(NULL);
ASSERT(g_cacheview.hdcCloseButton);
Gdi::SelectObject_I(g_cacheview.hdcCloseButton,
(HGDIOBJ)hbmCloseButton);
Here's what's happening: We're loading a bitmap resource "GWES_CLOSEBUTTON" and selecting this into a cached device context
g_cacheview.hdcCloseButton
, so that this is ready to use later. GWES_CLOSEBUTTON is defined in gcacheviewxp.res as follows:GWES_CLOSEBUTTON BITMAP res\CloseButton.bmp
The bitmap is getting loaded from SKINABLEUIGWEXPGCACHEVIEWXPRES.
So, we've loaded the background bitmap. We now need to figure out where
g_cacheview.hdcCloseButton
is getting used. Since the caption bar is part of the non-client area, it's a safe bet that we will find the code we're looking for in the following folder: SKINNABLEUIGWEXPNCLIENTVIEWXP. Let's take a look at nclientviewxp.cpp.Below is part of the DrawClose( ) function. We can clearly see the call to DrawCaptionButton( ) passing in the cached hdcCloseButton. (I've skipped some lines that aren't interesting for this part of the article.) We can then see the calls to SelectObject_I(hdc, hNewBrush), which selects a white brush into the device context. We then call DrawDiagonalLine( ) twice to place the cross onto the close button. This can, of course, be easily replaced with whatever background bitmap and foreground text/figure you want.
DrawCaptionButton(hdc, lprc, wControlState, g_cacheview.hdcCloseButton);
// ???… skip some lines???…
hOldBrush = (HBRUSH)Gdi::SelectObject_I(hdc, hNewBrush);
DrawDiagonalLine(hdc, lprc, 1, 2, 0);
DrawDiagonalLine(hdc, lprc, -1, 2, 0);
Modifying the Appearance of Windows CE .NET Controls
Ok, so we've looked at changing colors and replacing some of the standard bitmaps. These are quick and effective ways of changing the appearance of a device. Now comes the interesting bit: altering the drawing code for some of the standard windows and controls. Here's a list of the items within Windows CE .NET that support skinning:
Window Controls
· Scroll bar
· Button—radio, check, push
· Combo box (edit and list)
· List box
· Static controls
· Group box
Non-Client Area
· Caption bar/window border
Common Controls
· Command band/command bar
· Header control
· Trackbar (slider)
· Progress bar
Skinning of the above items requires modification to source code (and in some cases, modifying bitmaps).
We have two options for creating a new skin for Windows CE .NET. The first option is to make a copy of the contents of either C:wince400publiccommonOAKDRIVERSSKINNABLEUI (GWE COMMCTRL) or (GWEXP COMMCTRLXP), and create a new skin project folder, perhaps called MYGWE and MYCOMMCTRL. We will also need to modify the DIRS file in C:wince400publiccommonOAKDRIVERSSKINNABLEUI to include my new project files into the build. Then we need to replace the standard operating system build components with my new components. This is achieved through setting the SYSGEN_REPLACESKIN=1 environment variable (using Platform/Settings/Environment).
Lets examine the use of these environment variables. Here's a section of cesysgen.bat (part of the build system). We can see the first line checks for SYSGEN_REPLACESKIN. If this is set, then we skip including the standard Windows 95 and Windows XP UI components. If this is not set, then we look for SYSGEN_XPSKIN being set, and if it is, then we include the Windows XP skin components. If SYSGEN_XPSKIN is not set, then we include the Windows 95 skin components. Simple.
REM //XP or 9X UI
if "%SYSGEN_REPLACESKIN%"=="1" goto ReplaceSkin
if "%SYSGEN_XPSKIN%"=="1"
set GWE4_COMPONENTS=%GWE4_COMPONENTS%
sbcmnviewxp nclientviewxp gcacheviewxp btnctlviewxp
stcctlviewxp cmbctlviewxp lbctlviewxp
if not "%SYSGEN_XPSKIN%"=="1"
set GWE4_COMPONENTS=%GWE4_COMPONENTS%
sbcmnview nclientview gcacheview btnctlview
stcctlview cmbctlview lbctlview
:ReplaceSkin
To replace the default component with the component you customize, you must modify your cesysgen.bat file, and add a line similar to the following, which lists the skinning replacement libraries:
set GWE4_COMPONENTS=%GWE4_COMPONENTS%
sbcmnview nclientview gcacheview btnctlview
stcctlview cmbctlview lbctlview
The cesysgen.bat file can be found in the following folder: WINCE400public%PROJECT_NAME%WINCE400%TARGETNAME%oakMISC. For an emulator project I'm working on, the cesysgen.bat file would be found here: WINCE400publicUIDemoWINCE400EmulatoroakMISC.
We now understand how to remove the existing UI skin libraries (SYSGEN_REPLACESKIN) and how to add our own libraries to the build (cesysgen.bat). Let's now take a look at some of the Windows XP skin source code.
In this example, we could easily replace the 'button' focus rectangle drawing code with a solid rectangle. The Windows XP 'button' drawing code can be found in the following folder: WINCE400publiccommonOAKDRIVERSSKINNABLEUIGWEXPBTNCTLVIEWXP. The file we're interested in is buttonviewxp.cpp. Search for
DrawFocusRect_I
. This is in the ButtonView_t::DrawText( ) function. We could replace the DrawFocusRect_I function call with a call to Gdi::Rectangle_I( ) to get a solid 'focus' rectangle. I'm sure you can think of many other ways to change the appearance of some of the Windows CE .NET user interface controls.And then we're back to bitmaps—for example, changing the look of a scrollbar is as simple as using the Windows Paint program. The following folder contains the Scrollbar bitmaps: WINCE400publiccommonoakdriversskinnableuigwexpgcacheviewxpres. Take a look at ScrollThumb.bmp and ScrollShaft.bmp; these are the bitmaps for vertical and horizontal 'thumbs,' and the horizontal and vertical 'shaft.' Simply edit the bitmaps, rebuild the operating system, and you have a whole new look.
Modifying Standard UI Dialogs (Startup, Out of Memory, Touch Screen Calibration)
Windows CE .NET contains a number of standard user interface components that can be OEM customized. These include the Startup UI, the Out-of-Memory UI, and the Touch-Screen-Calibration UI.
We may have specific setup/configuration options for our device that can be handled through the Startup UI (this is typically used to prompt for a password, and display user information). The Out-of-Memory UI component can be modified to prompt a user in a specific manner, or to work with headless devices, perhaps creating a log file or sending a message across the network to alert a system administrator. (Having a UI component isn't much use on headless devices!) Touch Screen Calibration is self-explanatory.
So how do we replace/modify these components?
This requires some modification of cesysgen.bat (see Modifying the Appearance of Windows CE .NET Controls above for the location of this file), and the setting of environment variables. Here's how:
First we need to remove the ComponentName (oomui, startui, calibrui) from cesysgen.bat for each component being replaced. Below is an extract from cesysgen.bat. We can see the oomui component highlighted; remove this from cesysgen (unless you are modifying the existing code).
set GWE4_COMPONENTS=%GWE4_COMPONENTS% startup oomui oom startui cmbctl cdlctl edctl imgctl lbctl scbctl
Use GWES_REPLACE to replace components with .res files, and GWES_REPLACECOMPONENT to replace a component without a .res file.
We then need to set the environment variable GWES_REPLACE with the name of the module we are inserting into the build process to replace (in this case) oomui. The GWES_REPLACE environment variable can be set using Platform/Settings/Environment in the Platform Builder IDE.
We could, for example set GWES_REPLACE=myoomui—I know you are asking how the build system knows where to get this file. That's simple. The build system will pick up the .lib file from the following folder: C:WINCE400publiccommonOAKLIB%PROCESSORDEBUG/RETAIL.
That's all there is to it. In this month's column, we've taken a look at how to change the user interface colors using the registry, modify user interface bitmaps for common dialogs, and modify Windows CE .NET controls appearance. I'm sure the creative side of you is just itching to get started with building customized Windows CE user interface components. We'd certainly be interested in seeing any samples you produce. As always, let us know if you'd be interested in getting more information in this area, or have suggestions for additional articles.
But wait, there's more???… Next month we will take a look at how to replace the standard shell and create a flexible user interface using the Internet Explorer 5.5 browser. This is an interesting shell solution, since we can quickly build a device user interface using HTML, DHTML, and Microsoft ActiveX? Controls.
Get Embedded
Mike Hall is a Product Manager in the Microsoft Embedded and Appliance Platform Group (EAPG). Mike has been working with Windows CE since 1996—in developer support, Embedded System Engineering, and the Embedded product group. When not at the office, Mike can be found with his family, working on Skunk projects, or riding a Honda ST1100.
Steve Maillet is the Founder and Senior Consultant for Entelechy Consulting. Steve has provided training and has developed Windows CE solutions for clients since 1997, when CE was first introduced. Steve is a frequent contributor to the Microsoft Windows CE development newsgroups. When he's not at his computer burning up the keys, Steve can be found jumping out of airplanes at the nearest drop zone.
linux操作系統(tǒng)文章專題:linux操作系統(tǒng)詳解(linux不再難懂)
評(píng)論