Pocket PC SDK 提供 CeRapiInit 檢測連線,但若裝置未連接,該函式會無限期阻塞執行緒,導致程式假死。需使用非阻塞版 CeRapiInitEx 搭配事件等待機制。
| 函式 | 原型 | 行為 |
|---|---|---|
| CeRapiInit | HRESULT CeRapiInit(void); | 阻塞直到連線成功,回傳 S_OK;裝置未連時永不返回 |
| CeRapiInitEx | HRESULT CeRapiInitEx(RAPIINIT* pRapiInit); | 立即返回,回傳值不代表連線狀態;需監視結構內事件 |
RAPIINIT 結構typedef struct _RAPIINIT {
DWORD cbSize; // 結構大小
HANDLE heRapiInit; // 事件控制代碼,連線完成時觸發
HRESULT hrRapiInit; // 實際連線結果
} RAPIINIT;
RAPIINIT ri = {0};
ri.cbSize = sizeof(RAPIINIT);
HRESULT hInitResult = CeRapiInitEx(&ri); // 立即返回
// 等待連線事件,設定超時避免無限等待
DWORD dwWaitResult = WaitForSingleObject(ri.heRapiInit, 2000); // 2 秒超時
// 綜合判斷連線是否成功
if (hInitResult == S_OK && ri.hrRapiInit == S_OK && dwWaitResult != WAIT_TIMEOUT) {
// 連線成功,可進行 RAPI 操作
} else {
// 連線失敗或超時
CeRapiUninit(); // 記得清理
}
WaitForSingleObject 超時設 2000ms,平衡回應速度與可靠度。MSDN 建議 MsgWaitForMultipleObjects 以保持訊息泵運作,但實測 WaitForSingleObject 於工作執行緒中同樣可行且更簡潔。
使用 CeRapiInitEx + WaitForSingleObject 即可實現非阻塞、有超時保護的 Pocket PC 連線偵測,避免主執行緒卡死,提升使用者體驗。