Log

2009. március 11.

2D-s vonalkód készítés és olvasás

Nokia BarcodeNokia BarcodeTöbbek között a Nokia oldalán online lehet 2D-s (balra DataMatrix, jobbra QR) vonalkódot készíteni az alábbi címen: http://mobilecodes.nokia.com/create.jsp?terms=accepted Ezt most tavasszal a Pannon és a T-Mobile is nyomatja egy játékkal a www.kodstart.hu oldalon. A kód olvasása mobiltelefonon egy kis program telepítése után lehetséges. A Windows Mobile platformú telefonokról azonban megfeledkeztek vagy direkt kihagyták. Erre is van azonban egy remek kis program, ami a www.quickmark.com.tw oldalról letölthető. A program képes szokásos és 2D-s vonalkód olvasására. A szokásos vonalkód (nevezhetnénk 1D-snek is, de az olyan furának hangzik) olvasása nagyon nehezen megy neki, viszont a 2D-s remekül. A program érdekessége az, hogy fejlesztők is tudják használni vonalkódok olvasására. Letölthető hozzá C, VB és C# példa. Pár éve néztem már ilyen programot, de akkor siralmas volt még a képfeldolgozás sebessége. Azóta viszont rengeteget gyorsult. Lassan tényleg mindenki számára elérhetővé válik, hogy saját vonalkód olvasót használjon a mindennapi életben. Legalábbis a lehetőség meg lesz rá, kérdés, hogy a média mennyire fogja ezt a lehetőséget kihasználni és támogatni. Majd egy év múlva kiderül :)

Az emlegetett példa c#. Az első kód msgapi.cs névre hallgat és mindent tud, ami a vonalkód olvasó program meghívásához kell. Ami az eredeti példakódtól megkülönbözteti az az, hogy egy saját osztályba raktam és a példány létrehozásakor át kell adni neki a hívó példány objektum hivatkozását is. Azért kell, hogy amikor a kód olvasása megtörtént, meg tudjon hívni egy metódust. Nem szép megoldás tudom, első gyors munka, de működik.

using System;
using System.Collections.Generic;
using System.Text;
using System.Diagnostics;
using System.IO;
using System.Runtime.InteropServices;
using Microsoft.Win32;
using Microsoft.WindowsCE.Forms;

namespace Leltar
{
public class MyMessageWindow : MessageWindow
{
[DllImport("coredll.dll")]
private static extern uint RegisterWindowMessage(string lpString);

[DllImport("coredll.dll")]
public static extern int PostMessageW(IntPtr hWnd, uint Msg, IntPtr wParam, IntPtr lParam);

internal static readonly IntPtr HWND_BROADCAST = new IntPtr(0xFFFF);
internal string ScanData = "";

//a unique message for inter-application communication
private UInt32 RM_QuickMarkMessengerAPIApp = 0;

//Handle to the window whose window procedure will receive the decoded result.
private MainForm x;
private const int WM_COPYDATA = 0x004A;

//Receive the decoded result.
//STRUCT COPYDATASTRUCT member
//dwData:Data types of data.
// TYPE_CHAR: The data is a Binary data.
// TYPE_WIDECHAR: The data is a Unicode string.
//lpData:Long pointer to data.
//cbData:Specifies the size, in bytes, of the data pointed to by the lpData member.

public MyMessageWindow(MainForm ob)
{
//Register a window message for inter-application communication
this.RM_QuickMarkMessengerAPIApp = RegisterWindowMessage("QuickMarkMessengerAPIApplication");
x = ob;
}

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:
{
ScanData = GetMsgString(msg.LParam);
x.ScanDataUpdate();
}
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;
}
}
public void LaunchQuickMark()
{
// Step 1: Get application path of QuickMark from registry.
String szQuickMarkApp = "";
RegistryKey QuickMarkKey = Registry.CurrentUser;
QuickMarkKey = QuickMarkKey.OpenSubKey("Software\\QuickMark", false);
szQuickMarkApp = QuickMarkKey.GetValue("QuickMarkAppPath").ToString();
QuickMarkKey.Close();

// Step 2: Set default path of QuickMark.
if (szQuickMarkApp.Length == 0)
szQuickMarkApp = "\\Program Files\\QuickMark\\QuickMark.exe";

//Step 3: Launch 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

//step 4: send RM_QuickMarkMessengerAPIApp to all top windows.
//parameters:
// HWND hWnd : HWND_BROADCAST , all top windows.
// UINT Msg : A unique message for inter-application communication.
// WPARAM wParam : Handle to the main window.
// LPARAM lParam : Handle to the window whose window procedure will receive the decoded result.
PostMessageW(HWND_BROADCAST, RM_QuickMarkMessengerAPIApp, x.Handle, x.messageWindow.Hwnd);
}
else
{
x.ShowErrorMessage("QuickMark not found!");
}
}
}
}





A form kódjának konstruktorába pedig egy sort kell berakni és persze a két hivatkozott metódust. Az egészet a btnScan gombra való klikkelés indítja. Amint sikeres vonalkódolvasás történt, az osztály meghívja a ScanDataUpdate metódust.



          public MyMessageWindow messageWindow;
public MainForm()
{
InitializeComponent();
this.messageWindow = new MyMessageWindow(this);
}

public void ScanDataUpdate()
{
txtScan.Text = "";
txtScan.Text = messageWindow.ScanData;
txtScan.Refresh();
}

public void ShowErrorMessage(string s)
{
MessageBox.Show(s);
}

private void btnScan_Click(object sender, EventArgs e)
{
messageWindow.LaunchQuickMark();
}

0 hozzászólás: