Tag Archives: VB.Net

Its time. I’m making a stand. MyNamingConventionManifesto.

Standard

Variable names, filenames and other technical names.  Hungarian notion, abbreviations, verbosity, camel case and mixed case.  How many of my projects have used mixtures of these conventions?  How often do I forget what abbrev I usd????

?!It_never_ends!?   

no-longer   

I-AM-SICK-OF-IT!

_this_has_to_stop

<rant>It is time to do away with inconsistency forever.  </rant>

I am happy to comply with the conventions of a language (eg in .net mixed case is used for public attributes and properties whereas camel case is used for parameters) or the conventions of an existing project, but if there isn’t any, MyNamingConventionManifesto comes into play.

The decisions are around:

CASE (Upper, Lower, Mixed or Camel Case) 

DELIMITER (None, Minus, Underscore or Space)

PREFIX

SUFFIX

So, I hereby declare that my naming convention will not use prefixes or suffixes, neither will it use delimiters.  In short, this is:

MyNamingConventionManifesto 

 

ThankyouThatWillBeAll

 

Advertisements

Capturing a still image from a Webcam in .net

Standard

image 

What if you want to capture a single image from a webcam?  It turns out that this is quite straight forward to do using a couple of Win32 api calls to the avicap32.dll library.

I encapsulated these api calls in a simple class.

To write a file called “snapshot.jpg” out to the desktop from a single webcam, simply declare the class and call a the TakePicture method.

Dim loSnap As New WebcamSnap
loSnap.TakePicture(0)

The devices collection shows a list of all webcam devices on your machine so you can populate a combo with them.

Note: This example has no decent error handling, which I suspect will be needed in the “real world” of multiple devices.

Here’s the WebcamSnap class:

Option Explicit On
Imports System.IO
Imports System.Runtime.InteropServices
''' <summary>
''' This class takes a snapshot from any or all attached webcams
''' </summary>
''' <remarks></remarks>
Public Class WebcamSnap
    Const WM_CAP As Short = &H400S

    Const WM_CAP_DRIVER_CONNECT As Integer = WM_CAP + 10
    Const WM_CAP_DRIVER_DISCONNECT As Integer = WM_CAP + 11
    Const WM_CAP_EDIT_COPY As Integer = WM_CAP + 30
    Const WS_CHILD As Integer = &H40000000
    Const WS_VISIBLE As Integer = &H10000000
    Declare Function SendMessage Lib "user32" Alias "SendMessageA" _
        (ByVal hwnd As Integer, ByVal wMsg As Integer, ByVal wParam As Integer, _
        <MarshalAs(UnmanagedType.AsAny)> ByVal lParam As Object) As Integer

    Declare Function capCreateCaptureWindowA Lib "avicap32.dll" _
        (ByVal lpszWindowName As String, ByVal dwStyle As Integer, _
        ByVal x As Integer, ByVal y As Integer, ByVal nWidth As Integer, _
        ByVal nHeight As Short, ByVal hWndParent As Integer, _
        ByVal nID As Integer) As Integer

    Declare Function capGetDriverDescriptionA Lib "avicap32.dll" (ByVal wDriver As Short, _
        ByVal lpszName As String, ByVal cbName As Integer, ByVal lpszVer As String, _
        ByVal cbVer As Integer) As Boolean

    Public Devices As New List(Of String)
    Public Height As Integer = 480
    Public Width As Integer = 640
    Public OutputPath As String = Environment.GetFolderPath(Environment.SpecialFolder.DesktopDirectory)
    Public FilenamePrefix As String = "snapshot"
    Public Sub New()
        mLoadDeviceList()
    End Sub
    Private Sub mLoadDeviceList()
        Dim lsName As String = Space(100)
        Dim lsVers As String = Space(100)
        Dim lbReturn As Boolean
        Dim x As Integer = 0

        Do
            '   Get Driver name and version
            lbReturn = capGetDriverDescriptionA(x, lsName, 100, lsVers, 100)

            ' If there was a device add device name to the list
            If lbReturn Then Devices.Add(lsName.Trim)
            x += 1
        Loop Until lbReturn = False
    End Sub
    Public Sub TakePicture()
        For i = 0 To Me.Devices.Count - 1
            Dim lsFilename As String = Path.Combine(OutputPath, Me.FilenamePrefix & i & ".jpg")
            TakePicture(i, lsFilename)
        Next
    End Sub
    Public Sub TakePicture(ByVal iDevice As Integer)
        Me.TakePicture(iDevice, Path.Combine(OutputPath, Me.FilenamePrefix & ".jpg"))
    End Sub
    Public Sub TakePicture(ByVal iDevice As Integer, ByVal filename As String)

        Dim lhHwnd As Integer ' Handle to preview window

        ' Create a form to play with
        Using loWindow As New System.Windows.Forms.Form

            ' Create capture window
            lhHwnd = capCreateCaptureWindowA(iDevice, WS_VISIBLE Or WS_CHILD, 0, 0, Me.Width, _
               Me.Height, loWindow.Handle.ToInt32, 0)

            ' Hook up the device
            SendMessage(lhHwnd, WM_CAP_DRIVER_CONNECT, iDevice, 0)
            ' Allow the webcam apeture to let enough light in
            For i = 1 To 10
                Application.DoEvents()
            Next

            ' Copy image to clipboard
            SendMessage(lhHwnd, WM_CAP_EDIT_COPY, 0, 0)

            ' Get image from clipboard and convert it to a bitmap
            Dim loData As IDataObject = Clipboard.GetDataObject()
            If loData.GetDataPresent(GetType(System.Drawing.Bitmap)) Then
                Using loBitmap As Image = CType(loData.GetData(GetType(System.Drawing.Bitmap)), Image)
                    loBitmap.Save(filename, Imaging.ImageFormat.Jpeg)
                End Using
            End If

            SendMessage(lhHwnd, WM_CAP_DRIVER_DISCONNECT, iDevice, 0)

        End Using

    End Sub

End Class

Links

I found the original code sample here:

http://www.experts-exchange.com/Programming/Languages/.NET/Visual_Basic.NET/Q_22482234.html

(Although I’ve seen it all over the web in various guises)

Enabling callto (Skype) in your application

Standard

image image

You may have noticed that Skype seems to embed itself into Internet Explorer, Firefox and Chrome.  It recognises contacts and phone numbers in the page and provides the ability to call them.

I believe people will expect this kind of functionality in conventional windows applications also.  To assist with this I created a little class that will not only allow calls, but allows a check for the existence of a skype and give the ability to extract the calling applications icon.

Sample Project

The sample winforms project includes the CallTo class and a simple Winforms test form:

image

The form has a textbox and button.   One load, the call button is enabled and give an image.  The button makes the call.

 

Public Class Form1

    Private Sub Form1_Load(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.Load
        Dim loCallTo As New CallTo
        cmdCall.Image = loCallTo.Image
        cmdCall.Enabled = loCallTo.Enabled
    End Sub
    Private Sub cmdCall_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles cmdCall.Click
        Dim loCallTo As New CallTo
        loCallTo.DoCall(txtPhoneNumber.Text)
    End Sub

End Class

 

 

Heres the source of CallTo.vb:

 

Imports Microsoft.Win32
Imports System.Runtime
Imports System.Runtime.InteropServices

''' <summary>
''' This class allows for making callto calls
''' </summary>
Public Class CallTo

    ''' <summary>
    ''' Gets the image.
    ''' </summary>
    ''' <value>The image.</value>
    Public ReadOnly Property Image() As Image
        Get
            If Not Enabled Then Return Nothing

            Dim lsValue As String
            With Registry.ClassesRoot.OpenSubKey("callto\DefaultIcon")
                lsValue = .GetValue("")
            End With

            If lsValue.Contains(",") Then
                Dim lsBits() As String = lsValue.Split(","c)
                Dim lsFilename As String = lsBits(0).Trim(New Char() {""""c})
                Dim liPosition As Integer = Val(lsBits(1))
                Return moGetIconFromExeOrDll(lsFilename, liPosition)
            Else
                Return Nothing
            End If

        End Get
    End Property
    Private Declare Auto Function ExtractIcon Lib "shell32" ( _
ByVal hInstance As IntPtr, ByVal lpszExeFileName As String, _
ByVal nIconIndex As Integer) As IntPtr
    Private Function moGetIconFromExeOrDll(ByVal filename As String, ByVal position As Integer) As Image
        Dim hInstance As IntPtr = Marshal.GetHINSTANCE( _
           System.Reflection.Assembly.GetExecutingAssembly.GetModules()(0))
        Dim hIcon As IntPtr = ExtractIcon(hInstance, filename, position)
        Dim loBitmap As Bitmap = Bitmap.FromHicon(hIcon)
        Dim loReturn As Image = loBitmap.GetThumbnailImage(16, 16, Nothing, Nothing)

        loBitmap.Dispose()
        Return loReturn

    End Function

    ''' <summary>
    ''' Gets a value indicating whether this CallTo is enabled.
    ''' </summar
    ''' <value><c>true</c> if enabled; otherwise, <c>false</c>.</value>
    Public ReadOnly Property Enabled() As Boolean
        Get
            Try
                Dim loReg As RegistryKey = Registry.ClassesRoot.OpenSubKey("callto", False)
                loReg.Close()
            Catch
                Return False
            End Try
            Return True
        End Get
    End Property
    ''' <summary>
    ''' Does the call.
    ''' </summary>
    ''' <param name="destination">The destination.</param>
    Public Sub DoCall(ByVal destination As String)

        If Not Enabled Then Throw New ApplicationException("Callto is not enabled")
        Process.Start("callto://" & destination)

    End Sub

End Class

 

Download Sample

Twittering using the Compact Framework

Standard

 image

My twitter updates are done using a variety of code.  At the moment I use the Curl command line  in conjunction with SlickRun.  In the past I did this with Outlook (see the article Twittering from Outlook Using VBA).  In the past I’ve found this pretty easy to do using the Twitter Api.

 

I also like to do updates from my Pocket PC, but am not keen on SMS charges.  The solution of course is to create my own client, which I’ll be posting about shortly.

For my client program I intend to use TwitterLib library.  Sadly this does not work for the compact framework unaltered.  I am currently working on porting it to the compact framework.

 

In the interim I want to share with you a simple code sample for submitting tweets to Twitter. 

The example is simple enough to be used by people who want to do HTTP posts to similar services.

 

    Dim lsParams As String = "status=" & Uri.EscapeDataString(tweetText)

    Dim loRequest As HttpWebRequest = CType(HttpWebRequest.Create("http://twitter.com/statuses/update.xml"), HttpWebRequest)
           With loRequest
               .Proxy = System.Net.GlobalProxySelection.GetEmptyWebProxy()

               .Timeout = 10000
               .AllowAutoRedirect = True
               .AllowWriteStreamBuffering = True

               .Method = "POST"

               .ContentType = "application/x-www-form-urlencoded"
               .ContentLength = Len(lsParams)

               Dim loCred As New System.Net.NetworkCredential("someusername", "somepassword")
               .Credentials = loCred

               ' Write the request paramater
               Dim stOut As New StreamWriter(.GetRequestStream(), System.Text.Encoding.ASCII)
               stOut.Write(lsParams)
               stOut.Flush()
               stOut.Close()

               Dim loResp = .GetResponse
               With loResp

                   .Close()
               End With

           End With

 

The most important difference with the full .net framework is the “GetEmptyWebProxy” and “AllowWriteStreamBuffering” lines.  It won’t work without it.

Share this post :

Give the "Gift of Text" by sending an SMS with VB.NET and Skype

Standard

image

Never underestimate the value (to some) of sending someone a note.  In my case, a note to my beloved is an excellent way of ensuring a happier homecoming.

Each note has to have an appropriately original sentiment, and be sent in a timely fashion.  Sometimes circumstances do not permit time for the creative effort required.   (Although I’ve heard that Generation Y can shoot of a text message faster than I just wrote the word faster…)

So why not queue up some appropriate messages and let my computer send one a day at the appropriate time?  Yes I’m sure you can think of plenty, but this is just an intro to a code sample….

So to send an SMS, all you need to do is install Skype and get a reference to the COM type library:

image

 

After this, the following code sample should be enough to get you in trouble:

 

Public Sub SendSMS(ByVal strNumber As String, ByVal strBody As String)
    Dim loSkype As New SKYPE4COMLib.Skype
    Dim loSmsMessage As SKYPE4COMLib.SmsMessage

    loSmsMessage = loSkype.CreateSms(SKYPE4COMLib.TSmsMessageType.smsMessageTypeOutgoing, strNumber)
    loSmsMessage.Body = strBody
    loSmsMessage.Send()
    Trace.WriteLine(loSmsMessage.Status.ToString)

    loSmsMessage = Nothing
    loSkype = Nothing

End Sub

 

Have fun!

Links

Original VBA post by Conrad Sharry

Share this post :

Getting a Screenshot with VB.NET on the Compact Framework 2.0

Standard

 

image

I believe that “thumbnail” images of data in applications is a powerful way of giving an overview to a user.

One sort of application that uses this technique is the “Flip 3D” functionality of Vista.

The code sample below provides a routine that “grabs” a rectangle of the currently displayed screen.  Just like it’s desktop equivalent, it can only take screenshots of the visible screen, not graphics that are off-screen. (Anyone know how to do that? Please let me know!)

Here’s the code:

Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click
    picScreenshot.Image = GetControlBitmap(Me.CreateGraphics, Me.SomeControl.Bounds)
End Sub
Const SRCCOPY As Integer = &HCC0020
Public Declare Function BitBlt Lib "coredll.dll" (ByVal hdc As IntPtr, ByVal nXDest As Integer, ByVal nYDest As Integer, ByVal nWidth As Integer, ByVal nHeight As Integer, ByVal hdcSrc As IntPtr, ByVal nXSrc As Integer, ByVal nYSrc As Integer, ByVal dwRop As Integer) As Boolean

Private Function GetControlBitmap(ByVal gx As Graphics, ByVal rect As Rectangle) As Bitmap

    ' Create the bitmap to output
    Dim loBitmap As Bitmap = New Bitmap(rect.Width, rect.Height)

    ' Create compatible graphics
    Dim loCompGraphics As Graphics = Graphics.FromImage(loBitmap)

    ' Blit the image data
    BitBlt(loCompGraphics.GetHdc(), 0, 0, rect.Width, rect.Height, gx.GetHdc(), rect.Left, rect.Top, SRCCOPY)

    ' Cleanup
    loCompGraphics.Dispose()
    Return loBitmap
End Function

The function “GetControlBitmap” will get a bitmap of a control or any rectangle passed into it.

Links

Share this post :