QuickMark API 範例程式

msgapi 範例簡介

說明如何實作一個簡單的程式,呼叫QuickMark應用程式進行條碼辨識並且得到回傳結果。

注意事項:

此範例開發者必須具備Symbian C++或Windows Mobile平台開發基礎。

Symbian C++

Top

範例路徑: \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;
}         

Visual C++

Top

範例路徑: \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;
}                               
     

Visual C#

Top

範例路徑: \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;
        }
    }
}
       

Visual Basic

Top

範例路徑: \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
       

步驟2:QuickMark使用WM_COPYDATA來傳送與接收訊息,因此利用RegisterWindowMessage方法註冊 QuickMarkMessengerAPIApplication訊息。

新視窗
Private RM_QuickMarkMessengerAPIApp As UInt32 = 0 //全域變數
...
Me.RM_QuickMarkMessengerAPIApp = RegisterWindowMessage("QuickMarkMessengerAPIApplication")
       

步驟3:啟動QuickMark程式進行辨識。

新視窗
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
       
Top