有關GPRS、CDMA開發的文章網上已經有不少,但是由於WindowsMobile SDK提供的GPRS、CDMA連接操作的庫只有C++版本的(即Connection ManagerAPI),網上的文章大多數都是C++版本的,儘管也有C#編寫的但是大多封裝的有些不對並且沒有經過很好的測試,本文在網絡已有的資料上整理出如何用C#進行GPRS、CDMA開發。
參考文獻:
Windows Mobile 中如何建立 GPRS 連接以便 Socket 能正常通信
GPRS開發系列文章之進階篇
Establish a GPRS connection with TcpClient
開發環境
Visual Studio 2005
Windows Mobile 6 SDK Professional
頭文件封裝
我們要用到Windows Mobile SDK的一個C++的頭文件Connmgr.h,它的路徑是:c:\program files\windows mobile 6 sdk\pocketpc\include\armv4i\connmgr.h,首先要用C#重新定義要用到的這個頭文件的常量、結構和外部函數聲明。
有關C#平臺封送的更多說明可以參考MSDN:
http://msdn.microsoft.com/zh-cn/library/fzhhdwae(VS.80).aspx
常量聲明:
const int S_OK = 0;
const uint CONNMGR_PARAM_GUIDDESTNET = 0x1;
const uint CONNMGR_PRIORITY_USERINTERACTIVE = 0x08000;
const uint INFINITE = 0xffffffff;
const uint CONNMGR_STATUS_CONNECTED = 0x10;
const int CONNMGR_MAX_DESC = 128; // @constdefine Max size of a network description
const int CONNMGR_FLAG_PROXY_HTTP = 0x1; // @constdefine HTTP Proxy supported
const int CONNMGR_FLAG_PROXY_WAP = 0x2; // @constdefine WAP Proxy (gateway) supported
const int CONNMGR_FLAG_PROXY_SOCKS4 = 0x4; // @constdefine SOCKS4 Proxy supported
const int CONNMGR_FLAG_PROXY_SOCKS5 = 0x8; // @constdefine SOCKS5 Proxy supported
const UInt16 IDC_WAIT = 32514;
const UInt16 IDC_ARROW = 32512;
結構封裝聲明:
C++原型:
typedef struct _CONNMGR_CONNECTIONINFO
{
DWORD cbSize; // @field Size of this structure
DWORD dwParams; // @field Valid parms, set of CONNMGR_PARAM_*
DWORD dwFlags; // @field Connection flags, set of CONNMGR_FLAG_*
DWORD dwPriority; // @field Priority, one of CONNMGR_PRIORITY_*
BOOL bExclusive; // @field Connection is exclusive, see comments
BOOL bDisabled; // @field Don't actually connect
GUID guidDestNet; // @field GUID of network to connect to
HWND hWnd; // @field hWnd to post status change messages to
UINT uMsg; // @field Msg to use when posting status changes
LPARAM lParam; // @field lParam to use when posting status changes
ULONG ulMaxCost; // @field Max acceptable cost of connection
ULONG ulMinRcvBw; // @field Min acceptable receive bandwidth of connection
ULONG ulMaxConnLatency; // @field Max acceptable connect latency
} CONNMGR_CONNECTIONINFO;
typedef struct _CONNMGR_DESTINATION_INFO
{
GUID guid; // @field GUID associated with network
TCHAR szDescription[CONNMGR_MAX_DESC]; // @field Description of network
BOOL fSecure; // @field Is it OK to allow multi-homing on the network
} CONNMGR_DESTINATION_INFO;
typedef struct _GUID { // size is 16
DWORD Data1;
WORD Data2;
WORD Data3;
BYTE Data4[8];
} GUID;
C#聲明
[StructLayout(LayoutKind.Sequential)]
public struct CONNMGR_CONNECTIONINFO
{
public uint cbSize;
public uint dwParams;
public uint dwFlags;
public uint dwPriority;
public int bExclusive;
public int bDisabled;
public GUID guidDestNet;
public IntPtr hWnd;
public uint uMsg;
public uint lParam;
public uint ulMaxCost;
public uint ulMinRcvBw;
public uint ulMaxConnLatency;
}
[StructLayout(LayoutKind.Sequential, CharSet = CharSet.Unicode)]
public struct CONNMGR_DESTINATION_INFO
{
public GUID guid; // @field GUID associated with network
[MarshalAs(UnmanagedType.ByValTStr,SizeConst = CONNMGR_MAX_DESC)]
public string szDescription; // @field Description of network
public int fSecure; // @field Is it OK to allow multi-homing on the network
}
public struct GUID
{ // size is 16
public uint Data1;
public UInt16 Data2;
public UInt16 Data3;
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 8)]
public byte[] Data4;
}
函數封送聲明:
C++原型: 請參考connmgr.h C#聲明: |
[DllImport("coredll.dll")]
public static extern uint GetTickCount();
[DllImport("coredll.dll")]
public static extern uint WaitForSingleObject(IntPtr hHandle,uint dwMilliseconds);
[DllImport("cellcore.dll")]
public static extern int ConnMgrMapURL(string pwszURL, ref GUID pguid, ref uint pdwIndex);
[DllImport("cellcore.dll")]
public static extern int ConnMgrEstablishConnectionSync(ref CONNMGR_CONNECTIONINFO ci, ref IntPtr phConnection, uint dwTimeout, ref uint pdwStatus);
[DllImport("cellcore.dll")]
private static extern IntPtr ConnMgrApiReadyEvent();
[DllImport("cellcore.dll")]
public static extern int ConnMgrReleaseConnection(IntPtr hConnection, int bCache);
[DllImport("cellcore.dll")]
public static extern int ConnMgrEnumDestinations(int nIndex,ref CONNMGR_DESTINATION_INFO pDestInfo);
[DllImport("cellcore.dll")]
public static extern int ConnMgrConnectionStatus(IntPtr hConnection, // @parm Handle to connection, returned from ConnMgrEstablishConnection
ref uint pdwStatus // @parm Returns current connection status, one of CONNMGR_STATUS_*
);
[DllImport("coredll.dll")]
private static extern int CloseHandle(IntPtr hObject);
這裏參考 Windows Mobile 中如何建立 GPRS 連接以便 Socket 能正常通信 例子用C#封裝一個類庫,並實現類似的Demo。運行界面如下圖所示:
手機設置
在這裏給出GPRS連接的設置說明,大多數的手機採用默認設置就可以直接使用了,並不用自己設置,但是如果你發現上面代碼運行後不能建立GPRS連接,測可以嘗試下面的設置。
在上面的GPRS連接代碼中,我們使用了“Internet 設置”這個設置,如果手機還沒有建立這個連接設置或者已經建立設置但是連接總是失敗,則可以按下面的方式建立或修改連接設置(這裏使用Windows Mobile 5操作系統,動感地帶SIM卡,用模擬器截圖):
1.打開“開始->設置”,點擊“連接”如圖1所示。
圖 1連接
2.如果您的手機已經有Internet設置,則在圖2中會有“管理現有連接”的鏈接,點擊它可以進行修改設置,在這裏點擊“添加新調制解調器連接”,增加一個Internet 設置。
圖2 連接設置
3.在彈出的如圖3所示的對話框中,選擇調制解調器爲“電話線路(GPRS)”。
圖3 調制解調器 4.在彈出如圖4所示的對話框中,“訪問點名稱”輸入“cmnet”。 圖4 訪問點名稱 5.在彈出的如圖5所示的對話框中,直接點擊“完成”。對於專用網絡則要輸入移動提供的用戶名和密碼。 圖5用戶名密碼 6.點擊“完成”後在“Internet 設置”裏多了一個“GRPS連接互聯網”的設置,如果此處有幾個設置,請確保您要使用的設置處於選中狀態。點擊“OK”退出設置。此時您可以使用本問提供的實例程序來嘗試連接,在連接的時候手機不要和電腦處於同步狀態,否則手機可能不會進行撥號。 圖6 完成設置 從上面的使用我們可以知道,建立GPRS連接和建立CDMA連接的差別僅僅是連接設置的不同而已,也就是撥號的問題。但是網絡上很多人問GPRS開發和CDMA開發問題,這裏通過這個Demo,希望可以給學習移動開發的朋友們提供一些幫助。 |