msgapi 範例簡介
msgapi 範例
Symbian C++
Visual C++
Visual C#
Visual Basic
說明如何實作一個簡單的程式,呼叫QuickMark應用程式進行條碼辨識並且得到回傳結果。
注意事項:
此範例開發者必須具備Symbian C++或Windows Mobile平台開發基礎。
範例路徑: \API_Example\SymbianOS\ 步驟1: 啟動QuickMark程式進行辨識。
void CmsgapiAppUi::StartQuickMark() { //=========================================== //QuickMark應用程式UID //S60 2nd Edition: 0x0c5567c0 //above S60 3rd Edition: 0x20004FFE //=========================================== const TInt KQuickmarkUid = 0x20004FFE; TUid id( TUid::Uid( KQuickmarkUid ) ); TUid msgapid(TUid::Uid( _UID3 )); //Client msgapi Uid TApaTaskList taskList(CEikonEnv::Static()->WsSession()); TApaTask task = taskList.FindApp( id ); if ( task.Exists() ) //QuickMark運行中 { //傳送Client msgapi Uid給QuickMark(回傳用) //若是S60 3rd Edition以上,必須具備SwEvent能力 _LIT8(params,""); task.SendMessage( msgapid, params); task.BringToForeground(); }else{ //啟動QuickMark HBufC* param = HBufC::NewLC( 256 ); param->Des().AppendNum(msgapid.iUid); RApaLsSession appArcSession; // connect to AppArc server User::LeaveIfError(appArcSession.Connect()); TThreadId idt; appArcSession.StartDocument(*param, TUid::Uid(KQuickmarkUid),idt); appArcSession.Close(); CleanupStack::PopAndDestroy(); // param } }
步驟2: 接收QuickMark回傳結果。
MCoeMessageObserver::TMessageResponse CmsgapiAppUi::HandleMessageL(TUint32 aClientHandleOfTargetWindowGroup, TUid aMessageUid, const TDesC8 &aMessageParameters) { TBuf<1024> iQuickMarkResult; iQuickMarkResult.Zero(); //convert UTF8 to UCS2 //QuickMark回傳字串將以UTF編碼 CnvUtfConverter::ConvertToUnicodeFromUtf8(iQuickMarkResult,aMessageParameters); //TODO: Add your code iEikonEnv->InfoWinL( _L("Result"), iQuickMarkResult); return MCoeMessageObserver::EMessageHandled; }
範例路徑: \API_Example\WindowsMobile\msgapi_C++_source.rar 步驟1: QuickMark使用WM_COPYDATA來傳送與接收訊息,因此利用RegisterWindowMessage方法註冊 QuickMarkMessengerAPIApplication訊息。
UINT RM_QuickMarkMessengerAPIApp = 0; //全域變數 ... RM_QuickMarkMessengerAPIApp = RegisterWindowMessage(TEXT("QuickMarkMessengerAPIApplication"));
步驟2:啟動QuickMark程式進行辨識。
void LaunchQuickMark() { //1):至登錄檔讀取QuickMark執行檔位置。 //---------------------------------------------- //Path:[HKEY_CURRENT_USER]\Software\QuickMark //Key:QuickMarkAppPath //Value:String //---------------------------------------------- TCHAR szQuickMarkApp[MAX_PATH]; TCHAR temp[1024]; CRegKey key; HRESULT hr; DWORD dwSize = 0; TCHAR szQMReg[] = _T("Software\\QuickMark"); memset(szQuickMarkApp,0,MAX_PATH*sizeof(TCHAR)); memset(temp,0,1024*sizeof(TCHAR)); hr = key.Open(HKEY_CURRENT_USER, szQMReg); if (hr == ERROR_SUCCESS) { if (key.QueryStringValue(_T("QuickMarkAppPath"),NULL,&dwSize) == ERROR_SUCCESS) key.QueryStringValue(_T("QuickMarkAppPath"), szQuickMarkApp, &dwSize); } key.Close(); //2):假如登錄檔資訊無法取得,設為預設路徑 \Program Files\QuickMark\QuickMark.exe if (_tcslen(szQuickMarkApp) == 0) wsprintf(szQuickMarkApp, L"\\Program Files\\QuickMark\\QuickMark.exe"); //default path //3):啟動QuickMark HANDLE h = NULL; WIN32_FIND_DATA f; int checkWin = 0; h = FindFirstFile(szQuickMarkApp, &f); if(h != INVALID_HANDLE_VALUE) { SHELLEXECUTEINFO ShExecInfo; memset(&ShExecInfo, 0, sizeof(SHELLEXECUTEINFO)); ShExecInfo.cbSize = sizeof(SHELLEXECUTEINFO); ShExecInfo.lpVerb = L"Open"; ShExecInfo.lpFile =szQuickMarkApp; ShExecInfo.lpParameters = L""; ShExecInfo.nShow = SW_SHOW; ShellExecuteEx(&ShExecInfo); Sleep(1000); //wait one second. } FindClose(h); //4):傳送 RM_QuickMarkMessengerAPIApp 至所有上層的視窗。 //---------------------------------------------- //參數說明: //HWND hWnd : HWND_BROADCAST ,發送消息至系統中所有上層視窗 //UINT Msg : 與QuickMark應用程式溝通的訊息id //WPARAM wParam : 要接收結果的視窗 //LPARAM lParam : QuickMark應用程式開啟時,預設掃描的類型。(1: 一維條碼 2: 二維條碼) //---------------------------------------------- int DefaultBarcodeType = 2; //預設為二維條碼 PostMessage(HWND_BROADCAST, RM_QuickMarkMessengerAPIApp, (WPARAM)hwndMain, (LPARAM)DefaultBarcodeType); }
步驟3: 接收QuickMark回傳結果。
LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam) { switch (message) { ... //接收QuickMark回傳結果 case WM_COPYDATA: QuickMarkMSG( hWnd, message, wParam, lParam); break; } } ... ... LRESULT QuickMarkMSG( HWND hWnd, UINT wMsg, WPARAM wParam, LPARAM lParam) { //顯示回傳結果 //---------------------------------------------- //STRUCT COPYDATASTRUCT member //dwData: 未使用 //lpData: 回傳資料的指標,資料字串以Unicode編碼 //cbData: lpData的資料長度 (單位: bytes) //---------------------------------------------- COPYDATASTRUCT* oCopyData; oCopyData=(COPYDATASTRUCT *)lParam; wchar_t receive[1024]; wsprintfW(receive,(LPCWSTR)oCopyData->lpData); MessageBox(hWnd, receive, TEXT("Result"), MB_OK); return 1; }
範例路徑: \API_Example\WindowsMobile\msgapi_C#_source.rar 步驟1: 引用
using System.Diagnostics; using System.Runtime.InteropServices; using Microsoft.Win32; using System.IO; using Microsoft.WindowsCE.Forms; //加入參考Microsoft.WindowCE.Forms
步驟2:QuickMark使用WM_COPYDATA來傳送與接收訊息,因此利用RegisterWindowMessage方法註冊 QuickMarkMessengerAPIApplication訊息。
private UInt32 RM_QuickMarkMessengerAPIApp = 0; //全域變數 ... this.RM_QuickMarkMessengerAPIApp = RegisterWindowMessage("QuickMarkMessengerAPIApplication");
步驟3:啟動QuickMark程式進行辨識。
private void LaunchQuickMark() { //1):至登錄檔讀取QuickMark執行檔位置。 //---------------------------------------------- //Path:[HKEY_CURRENT_USER]\Software\QuickMark //Key:QuickMarkAppPath //Value:String //---------------------------------------------- String szQuickMarkApp = ""; RegistryKey QuickMarkKey = Registry.CurrentUser; QuickMarkKey = QuickMarkKey.OpenSubKey("Software\\QuickMark", false); szQuickMarkApp = QuickMarkKey.GetValue("QuickMarkAppPath").ToString(); QuickMarkKey.Close(); //2):假如登錄檔資訊無法取得,設為預設路徑 \Program Files\QuickMark\QuickMark.exe if (szQuickMarkApp.Length == 0) szQuickMarkApp = "\\Program Files\\QuickMark\\QuickMark.exe"; //3):啟動QuickMark if (File.Exists(szQuickMarkApp)) { //Launch application Process P = new Process(); P.StartInfo.FileName = szQuickMarkApp; P.StartInfo.Verb= "Open"; P.Start(); P.WaitForExit(1000); //wait 1 second //4):傳送 RM_QuickMarkMessengerAPIApp 至所有上層的視窗。 //---------------------------------------------- //參數說明: //HWND hWnd : HWND_BROADCAST ,發送消息至系統中所有上層視窗 //UINT Msg : 與QuickMark應用程式溝通的訊息id //WPARAM wParam : 要接收結果的視窗 //LPARAM lParam : QuickMark應用程式開啟時,預設掃描的類型。(1: 一維條碼 2: 二維條碼) //---------------------------------------------- int DefaultBarcodeType = 2; //預設為二維條碼 PostMessageW(HWND_BROADCAST, RM_QuickMarkMessengerAPIApp, messageWindow.Hwnd, (System.IntPtr)DefaultBarcodeType); } else { MessageBox.Show("QuickMark not found!"); } }
步驟4:接收QuickMark回傳結果。
private MyMessageWindow messageWindow; //宣告 ... this.messageWindow = new MyMessageWindow(); ... ... //MyMessageWindow 類別實作 internal class MyMessageWindow : MessageWindow { private const int WM_COPYDATA = 0x004A; //---------------------------------------------- //STRUCT COPYDATASTRUCT member //dwData: 未使用 //lpData: 回傳資料的指標,資料字串以Unicode編碼 //cbData: lpData的資料長度 (單位: bytes) //---------------------------------------------- public struct COPYDATASTRUCT { public int dwData; public int cbData; public IntPtr lpData; } protected override void WndProc(ref Message msg) { switch (msg.Msg) { case WM_COPYDATA: { //接收回傳結果 string str = GetMsgString(msg.LParam); MessageBox.Show(str,"Result"); //TODO:Add your code here to process with the str. } break; } base.WndProc(ref msg); } public static string GetMsgString(IntPtr lParam) { //取得回傳結果字串 if(lParam!=IntPtr.Zero) { COPYDATASTRUCT st = (COPYDATASTRUCT) Marshal.PtrToStructure(lParam,typeof(COPYDATASTRUCT)); string str = Marshal.PtrToStringUni(st.lpData); return str; } else { return null; } } }
範例路徑: \API_Example\WindowsMobile\msgapi_VB_source.rar 步驟1: 引用
Imports System.Diagnostics Imports System.Runtime.InteropServices Imports Microsoft.Win32 Imports System.IO Imports Microsoft.WindowsCE.Forms //加入參考Microsoft.WindowCE.Forms
Private RM_QuickMarkMessengerAPIApp As UInt32 = 0 //全域變數 ... Me.RM_QuickMarkMessengerAPIApp = RegisterWindowMessage("QuickMarkMessengerAPIApplication")
Private Sub LaunchQuickMark() '1):至登錄檔讀取QuickMark執行檔位置。 '---------------------------------------------- 'Path:[HKEY_CURRENT_USER]\Software\QuickMark 'Key:QuickMarkAppPath 'Value:String '---------------------------------------------- Dim szQuickMarkApp As String = "" Dim QuickMarkKey As RegistryKey = Registry.CurrentUser QuickMarkKey = QuickMarkKey.OpenSubKey("Software\QuickMark", False) szQuickMarkApp = QuickMarkKey.GetValue("QuickMarkAppPath").ToString() QuickMarkKey.Close() '2):假如登錄檔資訊無法取得,設為預設路徑 \Program Files\QuickMark\QuickMark.exe If szQuickMarkApp.Length = 0 Then szQuickMarkApp = "\Program Files\QuickMark\QuickMark.exe" End If '3):啟動QuickMark If File.Exists(szQuickMarkApp) Then 'Launch application Dim P As New Process() P.StartInfo.FileName = szQuickMarkApp P.StartInfo.Verb = "Open" P.Start() P.WaitForExit(1000) 'wait 1 second '4):傳送 RM_QuickMarkMessengerAPIApp 至所有上層的視窗。 '---------------------------------------------- '參數說明: 'HWND hWnd : HWND_BROADCAST ,發送消息至系統中所有上層視窗 'UINT Msg : 與QuickMark應用程式溝通的訊息id 'WPARAM wParam : 要接收結果的視窗 'LPARAM lParam : QuickMark應用程式開啟時,預設掃描的類型。(1: 一維條碼 2: 二維條碼) '---------------------------------------------- Dim DefaultBarcodeType As Integer DefaultBarcodeType = 2 '預設為二維條碼 PostMessageW(HWND_BROADCAST, RM_QuickMarkMessengerAPIApp, messageWindow.Hwnd, DefaultBarcodeType) Else MessageBox.Show("QuickMark not found!") End If End Sub
步驟4: 接收QuickMark回傳結果。
Private messageWindow As MyMessageWindow //宣告 ... Me.messageWindow = New MyMessageWindow() ... ... 'MyMessageWindow 類別實作 Friend Class MyMessageWindow Inherits MessageWindow Private Const WM_COPYDATA As Integer = 74 '---------------------------------------------- 'STRUCT COPYDATASTRUCT member 'dwData: 未使用 'lpData: 回傳資料的指標,資料字串以Unicode編碼 'cbData: lpData的資料長度 (單位: bytes) '---------------------------------------------- Public Structure COPYDATASTRUCT Public dwData As Integer Public cbData As Integer Public lpData As IntPtr End Structure Protected Overloads Overrides Sub WndProc(ByRef msg As Message) Select Case msg.Msg Case WM_COPYDATA '接收回傳結果 Dim str As String = GetMsgString(msg.LParam) 'TODO:Add your code here to process with the str. MessageBox.Show(str, "Result") Exit Select End Select MyBase.WndProc(msg) End Sub Public Shared Function GetMsgString(ByVal lParam As IntPtr) As String '取得回傳結果字串 If lParam <> IntPtr.Zero Then Dim st As COPYDATASTRUCT = DirectCast(Marshal.PtrToStructure(lParam, GetType(COPYDATASTRUCT)), COPYDATASTRUCT) Dim str As String = Marshal.PtrToStringUni(st.lpData) Return str Else Return Nothing End If End Function End Class