WinCE 開機即運行定制的 Shell 是很多系統的基本要求,有時還需要屏蔽 WinCE 自帶的 Shell 。 WinCE 中程序的自啟動,一般有兩個實現方法,修改注冊表和添加自啟動快捷方式。修改注冊表比較方便,如下:
[HKEY_LOCAL_MACHINE/init]
"Launch70"="MyApp.exe"
"Depend70"=hex:14,00,1e,00
只要將 MyApp.exe 打包到 NK ,并在 platform.reg 中加入上面的注冊表信息,這樣 WinCE 啟動時便會自動運行該程序。但這時 WinCE 自帶的 Shell 總是先出來,然后才運行 MyApp.exe ,為了避免這種情況,我們可以將注冊表設置修改如下:
[HKEY_LOCAL_MACHINE/init]
"Launch50"="MyApp.exe"
"Depend50"=hex:14,00,1e,00
即將原來啟動 explorer.exe 的值換為 MyApp.exe 。這樣 WinCE 啟動時直接進入定制的 Shell ,而不啟動 explorer.exe 。但這時有可能引入了新問題,如果定制的 Shell 是基于 MFC 編寫的,并且其中用到了如 CFileDialog 等類庫時,就會出現意想不到的情況,如下圖所示:
上圖是在不啟動 Explorer.exe 時,嘗試導入注冊表文件出現的狀況截圖,而在啟動 explorer.exe 時是沒有問題的。這說明 CFileDialog 在某種程度上依賴于 explorer.exe ,具體細節沒研究。但說明不啟動 explorer.exe ,基于 MFC 的 Shell 運行時就可能會出問題。所以 explorer.exe 必須啟動,但又不能出現 WinCE 界面。要解決這個問題自然就想到修改 explorer.exe 了。 WinCE5.0 和 WinCE6.0 中,這一部分的代碼都是公開的,在 WinCE6.0 中 Shell 的相關代碼在 C:/WINCE600/PUBLIC/SHELL/OAK/HPC/EXPLORER/MAIN 目錄下。
大致看了一下這一部分的代碼,發現只需修改如下兩個文件,就應該能實現需求。
C:/WINCE600/PUBLIC/SHELL/OAK/HPC/EXPLORER/MAIN/desktop.cpp

bool CDesktopWnd::Create()
{
IShellFolder *pSHF;
FOLDERSETTINGS fs;
RECT rc;
HRESULT hr = E_FAIL;
// Get a shell folder for the desktop
hr = SHGetDesktopFolder( &pSHF );
if(hr || !pSHF)
goto Cleanup;
// create a shell view for it
hr = pSHF->CreateViewObject(NULL, IID_IShellView, (LPVOID *) &_psv );
if(hr || !_psv)
goto Cleanup;
fs.ViewMode = FVM_ICON;
fs.fFlags = FWF_DESKTOP | FWF_ALIGNLEFT | FWF_NOSCROLL;
//++changed by hjb
//將Desktop的窗口大小設為0
//SetRect( &rc , 0, 0, GetSystemMetrics(SM_CXVIRTUALSCREEN), GetSystemMetrics(SM_CYVIRTUALSCREEN));
SetRect( &rc , 0, 0, 0, 0);
//--changed by hjb
// create the desktop's view window (no need to AddRef since CreateViewWindow does it)
hr = _psv->CreateViewWindow(NULL, &fs , (IShellBrowser *)this, &rc , &_hWnd );
if(hr || !_hWnd)
{
Release();
goto Cleanup;
}
RegisterDesktop(_hWnd);
Cleanup:
if(pSHF)
pSHF->Release();
return (hr == S_OK);
}
C:/WINCE600/PUBLIC/SHELL/OAK/HPC/EXPLORER/MAIN/explorer.cpp

DWORD WINAPI CreateTaskBar(LPVOID pEvent)
{
HANDLE hSyncEvent = *((HANDLE *) pEvent);
CTaskBar *pTaskBar = NULL;
HWND hwndTB = NULL;
pTaskBar = new CTaskBar;
//++added by hjb
//在創建任務欄時強制終止
if(pTaskBar)
{
delete pTaskBar;
SetEvent(hSyncEvent);
return 0;
}
//--added by hjb
if(!pTaskBar)
{
SetEvent(hSyncEvent);
return 0;
}
g_TaskBar = pTaskBar;
if(!pTaskBar->Register(g_hInstance))
{
g_TaskBar = NULL;
delete pTaskBar;
SetEvent(hSyncEvent);
return 0;
}
RegisterTaskBar(pTaskBar->GetWindow());
SetEvent(hSyncEvent);
DWORD dwRet = pTaskBar->MessageLoop();
delete pTaskBar;
return dwRet;
}
修改完這兩處后,先編譯該目錄,然后再重新編譯整個系統 ( 執行 Sysgen) 應該就可以了。 Explorer.exe 依然啟動,依然可以聽到 WinCE 啟動的聲音,但 WinCE 的界面已經屏蔽掉了。此時,基于 MFC 的 Shell 也能正常工作,如下圖所示:
在實際操作時,我沒有通過修改源代碼編譯來完成這個測試。因為在編譯 C:/WINCE600/PUBLIC/SHELL/OAK/HPC/EXPLORER/MAIN 目錄時,發現它只生成了 explorer.lib 。考慮到重新編譯整個系統的時間太長,所以直接修改了工程目錄下的 explorer.exe 的文件, MakeImg 后測試的。這里應該有快速編譯的方法,但目前不知怎么弄。
修改后,在 WinCE6.0 的模擬器中測試,達到了預想的效果。這樣就大概解決了基于 MFC 的 Shell 和 Explorer.exe 之間的矛盾,是不是有隱患還不清楚,目前看來沒問題。
另外需要注意,修改 public 和 private 目錄下的文件時,一定先做好備份,以免后患。
修改后的 WinCE6.0 的 explorer.exe 及演示視頻的下載地址 :
http://www.cnblogs.com/we-hjb/archive/2008/12/28/1364070.html
更多文章、技術交流、商務合作、聯系博主
微信掃碼或搜索:z360901061

微信掃一掃加我為好友
QQ號聯系: 360901061
您的支持是博主寫作最大的動力,如果您喜歡我的文章,感覺我的文章對您有幫助,請用微信掃描下面二維碼支持博主2元、5元、10元、20元等您想捐的金額吧,狠狠點擊下面給點支持吧,站長非常感激您!手機微信長按不能支付解決辦法:請將微信支付二維碼保存到相冊,切換到微信,然后點擊微信右上角掃一掃功能,選擇支付二維碼完成支付。
【本文對您有幫助就好】元
