天天看點

WINCE6.0在控制台添加應用程式

MSDN參考:

http://msdn.microsoft.com/zh-cn/library/ee502286

摘自:

http://blog.csdn.net/jjunjoe/article/details/6120601

作者:ARM-WinCE

WinCE系統中的控制台和Windows系統中的控制台原理是一樣的,裡面就是包含了一些應用程式。WinCE系統的控制台由Ctlpnl.exe,Control.exe和一些.cpl檔案組成,其中Ctlpnl.exe和Control.exe用于控制控制台的檔案夾顯示和架構,而.cpl檔案和控制台中的實際應用程式相對應。

WinCE的控制台中的每個應用程式都由兩部分組成:應用程式本身和所對應的.cpl檔案。實際上.cpl檔案就是一個dll,在該dll中會導出CPLApplet函數,該函數會處理來自控制台的消息(CPL_INIT, CPL_DBCLK, CPL_STOP等),然後根據相應的消息來調用應用程式。

先來看一下CPlApplet函數,如下:

LONG CPlApplet(HWND hwndCPl, UINT msg, LPARAM lParam1, LPARAM lParam2)

hwndCPl:控制台視窗的句柄

msg:發給控制面應用程式的消息

lParam1:消息參數1

lParam2:消息參數2

該函數會根據msg參數傳入的消息進行相應的處理,WinCE中所支援的控制台消息如下:

CPL_INIT:被首次加載的時候會收到該消息,也是第一個消息,用于初始化控制台應用程式,比如記憶體配置設定等。

CPL_GETCOUNT:第二個被收到的消息,該消息用于獲得該控制台應用程式中的元件數,因為.cpl檔案中可能包含多個Applet程式。

CPL_NEWINQUIRE:查詢元件資訊,如果該.cpl中包含多個元件,那麼lParam1表示元件号,lParam2是一個指向NEWCPLINFO結構的指針,其中NEWCPLINFO結構用于描述元件資訊。

CPL_DBCLK:使用者在控制台界面中輕按兩下某個應用時,會收到該消息,在該消息中執行對應的應用程式。如果包含多個元件,那麼lParam1表示組建号,lParam2為傳給應用程式的資料。

CPL_STOP:關閉控制面應用程式時,收到該消息,用于釋放資源。如果包含多個元件,那麼lParam1表示元件号,lParam2為傳給應用程式的資料。

CPL_EXIT:在CPL_STOP消息之後,控制台釋放該應用程式時,收到該消息。

在CPlApplet中收到CPL_NEWINQUIRE消息時,會初始化NEWCPLINFO結構來描述元件資訊,該結構定義如下:

typedef struct tagNEWCPLINFO {

  DWORD dwSize;

  DWORD dwFlags;

  DWORD dwHelpContext;

  LONG lData;

  HICON hIcon;

  TCHAR szName[32];

  TCHAR szInfo[64];

  TCHAR szHelpFile[128];

} NEWCPLINFO;

dwSize:該結構的資訊

dwFlags:忽略

dwHelpContext:忽略

lData:傳給組建程式的資料

hIcon:顯示在控制台中的圖示的句柄

szName:顯示在控制台中的元件的名字

szInfo:顯示在控制台中的描述資訊

szHelpFile:忽略

前面介紹了控制台的基礎知識,下面就開始添加應用程式到WinCE控制台中,步驟如下:

1. 建立一個WinCE的工程,然後添加一個應用程式:

首先要有一個WinCE的工程,然後點選File->New->Subproject,然後選擇WCE Application,然後可以選擇Hello World應用程式。

2. 為應用程式建立CPL工程:

同樣點選File->New->Subproject,然後選擇WCE Dynamic-Link Library,工程名為HelloCPL,然後點選Next,在Auto-generated subproject files頁面中選擇A Dll that exports some symbols,然後點選Finish完成。

3. 添加CPlApplet函數:

打開HelloCPL工程,并打開HelloCPL.cpp檔案,添加如下頭檔案:

#include <tchar.h>

#include “cpl.h”

然後添加如下代碼:

#define lengthof(exp) ((sizeof((exp)))/sizeof((*(exp))))

HMODULE g_hModule = NULL;   // Handle to the DLL.

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_HELLO;

         // 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_HELLO));

          LoadString(g_hModule, IDS_APP_TITLE, lpNewCplInfo->szName,

                     lengthof(lpNewCplInfo->szName));

          LoadString(g_hModule, IDC_Hello, 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//Hello.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

具體不做解釋了,相信自己看一下都能看明白。在上面的代碼中,處理消息CPL_NEWINQUIRE的時候,加載了IDI_HELLO,IDS_APP_TITLE和IDC_Hello三個資源,分别是一個圖示和兩個字元串。為工程添加rc資源檔案和resource.h頭檔案,導入圖示資源和字元串資源。資源的導入和定義比較簡單,是以不介紹具體步驟了。

4. 修改HelloCPL工程配置:

打開HelloCPL.bib檔案,添加如下内容:

MODULES

HelloCPL.cpl  $(_FLATRELEASEDIR)/HelloCPL.cpl               NK

右擊HelloCPL工程,選擇Properities,選擇General頁面,在Custom Variables項中添加變量,變量名字為CPL,值為1。

再次右擊HelloCPL工程,選擇Properities,選擇C/C++頁面,确認Additional Macro Definitions的值為$(CDEFINES) -DHelloCPL_EXPORTS。設定DLL Entry Point項為DllMain。在Include Directories項中添加路徑$(_PROJECTROOT)/cesysgen/oak/inc。

5. 編譯Hello應用程式和HelloCPL工程:

編譯開始建立的Hello應用程式和HelloCPL工程,在WinCE6.0中,編譯完成後會自動Makeimg操作。

通過上面的步驟,可以把應用程式添加到WinCE系統的控制台中,最後編譯成功以後,就可以下載下傳運作了,在此我添加了一個Hello的應用程式,名字叫Hello application,運作結果如圖

繼續閱讀