Showing posts with label barcode. Show all posts
Showing posts with label barcode. Show all posts

Saturday, September 12, 2009

Generate DataMatrix Barcode from Your .NET Application

Data Matrix barcode has several advantages over 1D barcodes such as:
  • Contains more character even alphanumeric.
  • Has square form for easier layout on printout.
  • Digital camera friendly even using your old cellphone camera.
  • Redundant information, you can scan 75% area of the barcode only for scanning.
  • A little bit omni scan direction.
Too bad my trusted DevExpress XtraReport XRBarcode doesn't have this symbology. Since I can't wait for DevExpress to implement Data Matrix so I decided to find open source solutions. Thanks God, I found external link on Data Matrix Wiki page for iec16022sharp an open source .NET Data Matrix generator library. Since I use VB.NET, I built the iec16022sharp assembly and use it by adding a reference to it. I am glad that iec16022sharp usage is very easy.
Here is my iec16022sharp usage snippet:
...
Imports IEC16022Sharp
...
Dim aReport As New RptBarcode
Dim aDataMatrix As New DataMatrix(BindSrcMaster.GetDataValue("BarcodeNum").ToString.Trim)

HierarchyRefreshDataRow(BindSrcMaster.GetDataRow)
With aReport
.CallingForm = Me
.PbDataMatrix.Image = DMImgUtility.SimpleResizeBmp(aDataMatrix.Image, 6, 0)
.QueryLoad(Application.StartupPath + "\CustomReport\Barcode.xml", BindSrcMaster)
.ShowPreview()
End With
...

The only functions I called from this library is a DataMatrix constructor and a static function DMImgUtility.SimpleResizeBmp. From the DataMatrix constructor I already have a small DataMatrix barcode. For enlarging the generated DataMatrix I just called the SimpleResizeBmp for enlarging it six times with zero pixel border. Hope my post give you an idea on using DataMatrix. Thank you.
...Read more

Wednesday, September 2, 2009

Application for Enabling Your WM Camera into a Barcode Scanner

I was really excited when I found QuickMark (I am not affiliated with QuickMark). This Taiwan company makes 2D and 1D barcode scanner software for Windows Mobile and Symbian. You can find a lot of similar software like QuickMark on the web. But QuickMark has one thing that stands in the crowd. You can call QuickMark using its API from your .NET Compact Framework 2.0 application and get the scan result. I already tested their API and it worked even for my EAN13 1D barcode. For only U$ 10 your WM Camera becomes a barcode scanner yippeee. I have polished their API demo below (sorry the source codes are not colored).
FrmQuickMarkAPIDemo (the form that uses QuickMarkAPI):
Public Class FrmQuickMarkAPIDemo
Private WithEvents aQuickMarkAPI As New QuickMarkAPI(AddressOf GetMsgString)

Public Sub New()
InitializeComponent()
End Sub

Private Sub MnuOK_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MnuOK.Click
aQuickMarkAPI.LaunchQuickMark()
End Sub

Private Sub GetMsgString(ByVal MsgString As String)
MsgBox(MsgString)
End Sub
'Just an alternative receive the message string using an event
'Private Sub aQuickMarkAPI_OnGetMsgString(ByVal MsgString As String) Handles aQuickMarkAPI.OnGetMsgString
' MsgBox(MsgString)
'End Sub
End Class

QuickMarkAPIDemo (The API itself):
Imports System.Diagnostics
Imports System.Runtime.InteropServices
Imports Microsoft.Win32
Imports System.IO
Imports Microsoft.WindowsCE.Forms
'QuickMark

'Flow of QuickMark Messenger
'Open msgapi --> Register a window message for inter-application communication (RegisterWindowMessage)
'-->launch QuickMark (Press OK button) --> send a unique message for inter-application communication(HWND_BROADCAST)
' --> QuickMark recevie the handle of msgapi's window. --> Decoding using QuickMark
' --> QuickMark send result to handle. --> msgapi show the result.

Class QuickMarkAPI
Inherits MessageWindow

<DllImport("coredll.dll")> _
Private Shared Function RegisterWindowMessage(ByVal lpString As String) As UInteger
End Function

<DllImport("coredll.dll", SetLastError:=True, CharSet:=CharSet.Auto)> _
Private Shared Function PostMessageW( _
ByVal hWnd As IntPtr, _
ByVal Msg As UInteger, _
ByVal wParam As IntPtr, _
ByVal lParam As IntPtr) As Boolean
End Function

Friend Shared ReadOnly HWND_BROADCAST As New IntPtr(65535)

'a unique message for inter-application communication
Private RM_QuickMarkMessengerAPIApp As UInt32 = 0

'Handle to the window whose window procedure will receive the decoded result.
Public Delegate Sub OnGetMsgStringHandler(ByVal MsgString As String)
Public DefaultBarcodeType As Integer = 2 'Default is 2D scanning.
Event OnGetMsgString As OnGetMsgStringHandler
Private Const WM_COPYDATA As Integer = 74
Private aGetMsgString As OnGetMsgStringHandler = Nothing
Public Sub LaunchQuickMark()
' Step 1: Get application path of QuickMark from registry.
Dim szQuickMarkApp As String = ""
Dim QuickMarkKey As RegistryKey = 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 Then
szQuickMarkApp = "\Program Files\QuickMark\QuickMark.exe"
End If

' Step 3: Launch 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
'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 window whose window procedure will receive the decoded result.
' LPARAM lParam : Set QuickMark application to 1D or 2D scanning. (1:1D 2:2D)
PostMessageW(HWND_BROADCAST, RM_QuickMarkMessengerAPIApp, Me.Hwnd, DefaultBarcodeType)
Else
MessageBox.Show("QuickMark not found!")
End If
End Sub
'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 Structure COPYDATASTRUCT
Public dwData As Integer
Public cbData As Integer
Public lpData As IntPtr
End Structure
Public Sub New(ByVal aGetMsgString As OnGetMsgStringHandler)
Me.aGetMsgString = aGetMsgString
'Register a window message for inter-application communication
Me.RM_QuickMarkMessengerAPIApp = RegisterWindowMessage("QuickMarkMessengerAPIApplication")
End Sub

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")
If aGetMsgString IsNot Nothing Then
aGetMsgString.Invoke(str)
End If
RaiseEvent OnGetMsgString(str)
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


...Read more

Tuesday, August 25, 2009

My First Journey to Mobile Database Application

My company assigns me and my team mates to automate our warehouses processes. We need to automate the manual recording of inventory flows processes.
Our first development approach is ASP.NET 2.0. This approach is the fastest to get done because we don't need to think about mobile database and server database. As long as there is wireless connection and a capable browser, the mobile devices can be used for data input. Our intended device is Motorola Symbol MC5590 with QWERTY keypad and built in barcode scanner. For development purpose we use HTC TyTN II with Windows Mobile 6.1 Pro OS. We found a China company specializing in barcodes, Sumlung and tried their software for reading a barcode through PDA camera. But their software is incompatible with our mobile device. When budget is your main consideration in developing a barcode application, you can review their solutions. We use AJAX control toolkit for automating our web pages. But to be our disappointment this ASP.NET 2.0 is failed. Our ASP.NET 2.0 website was running fine on Windows Mobile 6 Pro Emulator Images IE Mobile. But some features failed on our HTC TyTN II IE Mobile. The most obvious one is asp:Login control, the button doesn't react to a mouse click. So we find alternative browsers for our WM6. Opera Mobile can be used for running our web pages but the layout size doesn't seem right to us. Luckily we found the Iris browser. The browser can run our web pages just like we want them. Since there are no problems with software development, the project rolls onto hardware infrastructures planning. We are pretty surprised with the wireless infrastructure site survey result. Our company needs to spend a large amount of money for a full wireless LAN coverages on its warehouses. We thought an alternative from in house wireless infrastructures to unlimited HSDPA data plan from mobile telco operators. We use Hamachi Mobile from LogMeIn for connecting our mobile devices to our server. Everything seems right unless one crucial problem, Indonesia mobile telco operators are unreliable. At least there is 1 day in a week we can not connect from our mobile telco operator. We came back to wireless LAN infrastructures with reduced coverages. It seems there is no easy path on Mobile Database Application, we have to develop a .NET CF 2.0 database application.

Second approach, .NET CF 2.0 database application. First things we do are download all necessary software:
Windows Mobile 6 Pro Emulator Images (downloaded previously)
Windows Mobile 6 SDK
ActiveSync 4.5 for Windows XP (allow DMA connection for docking emulator)
Windows Mobile Device Center for Windows Vista
.NET CF 2.0 SP 2 for our Visual Studio 2005
SQL Server CE 3.1 (we download the Developer SDK and Tools for Visual Studio SP 1)
We are pretty surprised there are no significant differences between developing a desktop ADO.NET 2.0 application and a mobile ADO.NET 2.0 application. To cut the learning curve, we do not use Microsoft Synchronization Services, we use compact framework SqlClient directly to upload to and download from SQL Server 2005. There are several things about SqlCE we bumped into:
  1. Do not use ComboBox for looking up a table with a lot of records. We create a SearchDialog that utilizes a scrollable SqlCeResultSet bound to a DataGrid instead of ComboBox. The SqlCeConnection must be always connected for using SqlCeResultSet. SqlCeResultSet will only fetch shown records on DataGrid so you don't need to wait the whole records to be loaded. Our SearchDialog construct incremental search select SQL and return a HashTable of a row selected.
  2. SqlCE doesn't support update and delete using join, sub query and batch command. So we must keep this in our minds.
  3. Eliminate unneeded columns on SqlCE.
  4. Denormalize wisely for gaining performance.
  5. We use untyped dataset and it took time to load it so we serialize the dataset schema to database and deserialize it on form load. PS: We hate typed dataset :-).
  6. Our select, insert, update and delete command constructed on the fly based on table schema and it took time to load also. So we serialize and deserialize them using XML into database also.
The problem about performance and incompatible SQL make us considering several alternatives such as: SQLite, VistaDB and SSCE Direct. But time constraint makes us stay with SqlCE. For SQL Server 2005 side, all tables to be synchronized to SqlCE equipped with timestamp columns CreateTime and UpdateTime and Deleted tables for storing the deleted primary keys and their DeleteTime for each tables. We also applied these for all SqlCE tables to be uploaded to SQL Server. Records inserted in SqlCE use negative integer primary key, they will have positive integer primary key after synchronize with server.

I hope my share about our experience in developing mobile database application can be useful for all of you. Thank you.
...Read more