Creating a Control Panel Application (Windows Embedded CE 6.0)

1/6/2010

After you create the OS design and complete the subsequent steps as described in How to Implement a Control Panel Application, you will create a DLL application for your Control Panel application and then add specific Control Panel code to it. When it is complete, this Control Panel application invokes a simple application called HelloWorld.exe.

Note

Although this information is presented in terms of using the Platform Builder IDE during OS development, an application developer can use other development tools in conjunction with an SDK for a Windows Embedded CE-based platform to create Control Panel applications outside of the OS development process.

For more information about the general elements of a Control Panel application and how they interact, see Control Panel.

To create a DLL project

  1. From the File menu, choose New, and then select Subproject.

  2. In the Windows Embedded CE Subproject Wizard, select WCE Dynamic-Link Library.

  3. Type the name HelloCPL for your Control Panel application in the Subproject name box. Click Next.

    Be sure to use the specific name HelloCPL. Some of the code in related steps relies on auto-generated data types that are provided by the New Project Wizard and based on this name.

    Note

    Do not add the .cpl file extension to your project name. You provide this later when you configure the build settings for your project.

  4. In the Auto-generated subproject files page, select A DLL that exports some symbols and then click Finish.

As a result of these steps, the Windows Embedded CE Subproject Wizard creates several header, resource, and source files for your project. You may want to review the contents of these files to see the structure of your project. Specifically, the comments at the beginning of your project's header file, HelloCPL.h, explain the macros created to identify symbols exported by your DLL.

At this point, the DLL project is simply an empty shell with the correct infrastructure and settings to compile your project into a DLL. The next step is to add the actual code for your Control Panel application.

To add Control Panel code to your project

  1. In the Solution Explorer window, expand the Subprojects node, expand the HelloCPL node, and then expand the Source Files node. Double-click HelloCPL.cpp to open the main source file for your project.

    The file contains a small amount of code that was automatically generated by the wizard.

  2. Replace the existing code with the following code:

    //
    // HelloCPL.cpp : Defines the entry point for the DLL
    //
    
    #include "stdafx.h"    // Auto-generated by wizard.
    #include "HelloCPL.h"  // Auto-generated by wizard.
    #include "resource.h"  // Auto-generated at compile time
    
    #include <tchar.h>     // General text functions.
    #include "cpl.h"       // Control Panel support.
    
    // Returns the number of characters in an expression.
    #define lengthof(exp) ((sizeof((exp)))/sizeof((*(exp))))
    
    HMODULE g_hModule = NULL;   // Handle to the DLL.
    
    // =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
    // Main entry point for the Control Panel DLL.
    // =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
    extern "C" BOOL APIENTRY DllMain( HANDLE hModule, 
                           DWORD  ul_reason_for_call, 
                           LPVOID lpReserved )
    {
      switch (ul_reason_for_call)
      {
        case DLL_PROCESS_ATTACH:
        {
          g_hModule = (HMODULE) hModule;
        }
        case DLL_THREAD_ATTACH:
        case DLL_THREAD_DETACH:
        case DLL_PROCESS_DETACH:
           break;
        }
        return TRUE;
    }
    
    // =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
    // The entry point to the Control Panel application.
    // =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
    extern "C" HelloCPL_API LONG CALLBACK CPlApplet(HWND hwndCPL,
                      UINT message, LPARAM lParam1, LPARAM lParam2)
    {
      switch (message)
      {
        case CPL_INIT:
          // Perform global initializations, especially memory
          // allocations, here.
          // Return 1 for success or 0 for failure.
          // Control Panel does not load if failure is returned.
          return 1;
    
        case CPL_GETCOUNT:
          // The number of actions supported by this Control
          // Panel application.
          return 1;
    
        case CPL_NEWINQUIRE:
          // This message is sent once for each dialog box, as
          // determined by the value returned from CPL_GETCOUNT.
          // lParam1 is the 0-based index of the dialog box.
          // lParam2 is a pointer to the NEWCPLINFO structure.
        {
          ASSERT(0 == lParam1);
          ASSERT(lParam2);
    
          NEWCPLINFO* lpNewCplInfo = (NEWCPLINFO *) lParam2;
          if (lpNewCplInfo)
          {
             lpNewCplInfo->dwSize = sizeof(NEWCPLINFO);
             lpNewCplInfo->dwFlags = 0;
             lpNewCplInfo->dwHelpContext = 0;
             lpNewCplInfo->lData = IDI_HELLOWORLD;
    
             // The large icon for this application. Do not free this 
             // HICON; it is freed by the Control Panel infrastructure.
             lpNewCplInfo->hIcon = LoadIcon(g_hModule,
                                      MAKEINTRESOURCE(IDI_HELLOWORLD));
    
              LoadString(g_hModule, IDS_APP_TITLE, lpNewCplInfo->szName,
                         lengthof(lpNewCplInfo->szName));
              LoadString(g_hModule, IDS_HELLO, lpNewCplInfo->szInfo,
                         lengthof(lpNewCplInfo->szInfo));
            LoadString(g_hModule, IDC_HelloWorld, lpNewCplInfo->szInfo,
                         lengthof(lpNewCplInfo->szInfo));
              _tcscpy(lpNewCplInfo->szHelpFile, _T(""));
              return 0;
          }
          return 1;  // Nonzero value means CPlApplet failed.
        }
    
        case CPL_DBLCLK:
        {
          // The user has double-clicked the icon for the
          // dialog box in lParam1 (zero-based).
          PROCESS_INFORMATION pi = {0};
          if (CreateProcess(_T("\\Windows\\HelloWorld.exe"), NULL, NULL,
                                 NULL, FALSE, 0, NULL, NULL, NULL, &pi))
          {
            CloseHandle(pi.hThread);
            CloseHandle(pi.hProcess);
            return 0;
          }
          return 1;     // CPlApplet failed.
        }
    
        case CPL_STOP:
          // Called once for each dialog box. Used for cleanup.
        case CPL_EXIT:
          // Called only once for the application. Used for cleanup.
        default:
          return 0;
      }
    
      return 1;  // CPlApplet failed.
      }  // CPlApplet
    

In this code, the definitions for both DllMain and CPlApplet are preceded with extern "C" declarations. This assures that they are recognized by C-style calls within the OS.

The working code for a Control Panel application can be written into the DLL, that is, the .cpl file itself.

However, as the previous code shows, this is not a requirement in the handling of CPL_DBLCLK. A Control Panel application can delegate the bulk of its work to another process.

The code uses an icon resource named IDI_HELLOWORLD and three string resources named IDS_APP_TITLE, IDS_HELLO and IDC_HelloWorld. Before you can compile your application, you must add these resources to your project. For information, see Adding Resources to a Control Panel Application.

See Also

Reference

CPL_DBLCLK
CPL_EXIT
CPL_GETCOUNT
CPL_INIT
CPL_NEWINQUIRE
CPL_STOP
LoadIcon
NEWCPLINFO

Concepts

How to Implement a Control Panel Application

Other Resources

CloseHandle
CreateProcess
DllMain
LoadString
PROCESS_INFORMATION