最近在做一個餐飲項目(C#Winform),其中有一塊是做點菜寶接口的對接,點菜寶的廠商提供了一個WX.exe的驅動程序,這個驅動程序無直接打開,只能通過自己的編寫的接口程序調用和關閉,當時提供的例子一個VB和Delphi的用例,可是這塊項目組的人都沒有接觸過,後來通過廠商了解到接口程序的開發原理是基於文本+消息機制的。 文本是說要用到文本文件的讀和寫, 消息是說要用到 Windows 窗口消息的發與收。
了解到這些後,我們就要去調用WinAPI用來接收驅動消息和向驅動程序發送消息,話不多說,直接上代碼說明
***
[DllImport("user32.dll", CharSet = CharSet.Auto, SetLastError = false)]
private static extern IntPtr SendMessage(IntPtr hWnd, uint Msg, IntPtr wParam, IntPtr lParam);//
[DllImport("user32", CharSet = CharSet.Ansi, EntryPoint = "FindWindowA", ExactSpelling = false, SetLastError = true)]
public static extern IntPtr FindWindow(string lpClassName, string lpWindowName);
消息,就是指Windows發出的一個通知,告訴應用程序某個事情發生了。
例如,單擊鼠標、改變窗口尺寸、按下鍵盤上的一個鍵都會使Windows發送一個消息給應用程序。
消息本身是作為一個記錄傳遞給應用程序的,這個記錄中包含了消息的類型以及其他信息。
例如,對於單擊鼠標所產生的消息來說,這個記錄中包含了單擊鼠標時的坐標。這個記錄類型叫做TMsg,
它在Windows單元中是這樣聲明的:
HWND hwnd; //目標窗口句柄
UINT message; //消息常量標識符
WPARAM wParam; // 32位消息的特定附加信息
LPARAM lParam; // 32位消息的特定附加信息
DWORD time; //消息創建時的時間
TPoint pt; //消息創建時的鼠標位置
hwnd 32位的窗口句柄。窗口可以是任何類型的屏幕對象,因為Win32能夠維護大多數可視對象的句柄(窗口、對話框、按鈕、編輯框等)。
message 用於區別其他消息的常量值,這些常量可以是Windows單元中預定義的常量,也可以是自定義的常量。
wParam 通常是一個與消息有關的常量值,也可能是窗口或控件的句柄。
lParam 通常是一個指向內存中數據的指針。上示例的代碼:
protected override void WndProc(ref System.Windows.Forms.Message m)
{
if (m.Msg == 0x500)
{
if (toHandler == (IntPtr)0)
{
toHandler = m.LParam;//獲得WX句柄(這是驅動程序的句柄)
}
else
{
int MessageTag=m.LParam.ToInt32();
if (MessageTag >= 1 && MessageTag <= 8)//處理1-8基站的請求,並回復
{
ProcessBaseStaion(MessageTag);
//發回響應通知WX.exe
SendMessage(toHandler, (uint)0x500, new IntPtr(0), new IntPtr(MessageTag));
}
else if (MessageTag == 10)////有登陸請求程序驗證密碼的正確性,內容在DL.TXT,請回復到DL.TXT。
{
FileUtil.WriteContent(@".\TXT\DL.TXT", "1");
//發回響應通知WX.exe
SendMessage(toHandler, (uint)0x500, new IntPtr(0), new IntPtr(10));
}
}
}
base.WndProc(ref m);
}
上面的代碼就是我在項目中寫的一段代碼,驅動程序向我的窗體發消息時m.Msg(消息常量標識符)的數值是固定的值0x500,並且在發送的消息的附件信息中包含著驅動程序的句柄,so我就可以通過m.Msg甄別驅動發過來的消息,並且通過 SendMessage函數向驅動程序發送信息,這樣就完成了一次信息的交互了。