1. Using the New Project Wizard, create a new WCE Console Application named HelloWorld. Use the Typical Hello_World Application option.
2. Before the _tmain function, implement a thread function named ThreadProc:
DWORD WINAPI ThreadProc( LPVOID lpParameter) {
RETAILMSG(1,(TEXT("Thread started")));
// Suspend Thread execution for 3 seconds
Sleep(3000);
RETAILMSG(1,(TEXT("Thread Ended")));
// Return code of the thread 0,
// usually used to indicate no errors.
return 0;
}
3. By using the CreateThread function, start a thread:
HANDLE hThread = CreateThread( NULL, 0, ThreadProc, NULL, 0, NULL);
4. Check the returned value of CreateThread to verify that the thread was created successfully.
5. Wait for the thread to reach the end of the thread function and exit:
WaitForSingleObject(hThread, INFINITE);
6. Build the run-time image and download it to the target device.
7. Launch Remote Kernel Tracker and analyze how threads are managed on the system.
8. Start the HelloWorld application and follow the thread execution in the Remote Kernel Tracker window, as illustrated in Figure 3–11.
Figure 3-11Tracking thread execution in Remote Kernel Tracker tool
► Enable Power Management Notification Messages
1. Continue to use the HelloWorld application in Visual Studio.
2. Generate power-management notifications in more frequent intervals by going into the subproject registry settings and setting the registry entry for the UserIdle timeout in AC power mode (ACUserIdle) to five seconds:
[HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\Power\Timeouts]
"ACUserIdle"=dword:5 ; in seconds
3. In the ThreadProc function, create a message queue object:
// Size of a POWER_BROADCAST message.
DWORD cbPowerMsgSize =
sizeof POWER_BROADCAST + (MAX_PATH * sizeof TCHAR);
// Initialize our MSGQUEUEOPTIONS structure.
MSGQUEUEOPTIONS mqo;
mqo.dwSize = sizeof(MSGQUEUEOPTIONS);
mqo.dwFlags = MSGQUEUE_NOPRECOMMIT;
mqo.dwMaxMessages = 4;
mqo.cbMaxMessage = cbPowerMsgSize;
mqo.bReadAccess = TRUE;
//Create a message queue to receive power notifications.
HANDLE hPowerMsgQ = CreateMsgQueue(NULL, &mqo);
if (NULL == hPowerMsgQ) {
RETAILMSG(1, (L"CreateMsgQueue failed: %x\n", GetLastError()));
return -1;
}
4. Request to receive notifications from Power Manager and check the received messages:
// Request power notifications
HANDLE hPowerNotifications = RequestPowerNotifications(hPowerMsgQ,
PBT_TRANSITION | PBT_RESUME | PBT_POWERINFOCHANGE);
DWORD dwCounter = 20;
// Wait for a power notification or for the app to exit
while(dwCounter-- &&
WaitForSinglObject(hPowerMsgQ, INFINITE) == WAIT_OBJECT_0) {
DWORD cbRead;
DWORD dwFlags;
POWER_BROADCAST *ppb =
(POWER_BROADCAST*) new BYTE[cbPowerMsgSize];
// loop through in case there is more than 1 msg.
while(ReadMsgQueue(hPowerMsgQ, ppb, cbPowerMsgSize,
&cbRead, 0, &dwFlags)) {
switch(ppb->Message) {
case PBT_TRANSITION: {
RETAILMSG(1,(L"Notification: PBT_TRANSITION\n"));
if(ppb->Length) {
RETAILMSG(1,(L"SystemPowerState: %s\n", ppb->SystemPowerState));
}
break;
}
case PBT_RESUME: {
RETAILMSG(1,(L"Notification: PBT_RESUME\n"));
break;
}
case PBT_POWERINFOCHANGE: {
RETAILMSG(1,(L"Notification: PBT_POWERINFOCHANGE\n"));
break;
}
default:
break;
}
}
delete[] ppb;
}
5. Build the application and rebuild the run-time image.
6. Start the run-time image.
7. You generate user activity by moving the mouse cursor. After five seconds of inactivity, Power Manager should notify the application, as illustrated in Figure 3-12.
Figure 3-12Received Power Management notifications
1. Create a WCE Application named Subproject_Shell using the Subproject Wizard. Use the Typical Hello_World Application option.
2. Before the first LoadString line, add a SignalStarted instruction.
// Initialization complete,
// call SignalStarted...
SignalStarted(_wtol(lpCmdLine));
3. Build the application.
4. Add a registry key in the subproject .reg file to launch the application at startup. Add the following lines, which create the corresponding Launch99 and Depend99 entries:
[HKEY_LOCAL_MACHINE\INIT]
"Launch99"="Subproject_Shell.exe"
"Depend99"=hex:14,00,1e,00
5. Build and start the run-time image.
6. Verify that the Subproject_Shell application starts automatically.
7. Replace the reference to Explorer.exe in the Launch50 registry key with a reference to the Subproject_Shell application, as follows:
[HKEY_LOCAL_MACHINE\INIT]
"Launch50"="Subproject_Shell.exe"
"Depend50"=hex:14,00,1e,00
8. Build and start the run-time image.
9. Verify that the target device runs the Subproject_Shell application in place of the standard shell, as illustrated in Figure 3-13.
Figure 3-13Replacing the standard shell with a Subproject_Shell application
Windows Embedded CE provides a variety of tools, features, and APIs that you can use to ensure optimal system performance and power consumption on your target devices. Performance tools, such as ILTiming, OSBench, and Remote Performance Monitor, can help identify performance issues within and between drivers, applications, and OAL code, such as deadlocks or other issues related to thread synchronization. The Remote Kernel Tracker enables you to examine process and thread execution in great detail, while relying on structured exception handling, which Windows Embedded CE supports natively.
Windows Embedded CE is a componentized operating system. You can include or exclude optional components and even replace the standard shell with a custom application. Replacing the standard shell with an application configured to start automatically lays the groundwork for enabling a kiosk configuration. Windows Embedded CE runs with a black shell in a kiosk configuration, meaning that the user cannot start or switch to other applications on your device.
Читать дальше