SDF Sample: Getting MouseUp and MouseDown for controls without those events

Problem
In my application I really need to know when and where the mouse button is clicked/stylus is tapped on some controls like the Button control.  Unfortunately the Compact Framework doesn’t expose MouseDown and MouseUp for all controls. What can the SDF do for me?


Solution
[Tested on the PPC2003SE Emulator with CF 2.0 SP1]


The CF doesn’t expose managed events for all Windows messages that the control gets during the course of execution, but those messages still occur.  You can intercept them using an OpenNETCF.Windows.Forms.IMessageFilter-derived class coupled with the OpenNETCF.Windows.Forms.Application2.Run method.


Here is an example. Create an app with a single Form containing a single Button.  Note that you must modify the project properties to set the startup object to Sub Main.


Imports OpenNETCF.Windows.Forms
Imports OpenNETCF.Win32.WM
Imports System.Diagnostics

Public Class Form1
  Private noClickFont As Font
  Private clickFont As Font

 
Private
Sub Form1_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
    ‘ wire up the event handlers
    AddHandler MyApplication.buttonFilter.MouseDown, AddressOf ButtonMouseDown
    AddHandler MyApplication.buttonFilter.MouseUp, AddressOf ButtonMouseUp

    ‘ add our button to the filter
    MyApplication.buttonFilter.WatchButton(Me.Button1)

    ‘ save some font info for later use
    noClickFont = Button1.Font
    clickFont = New Font(noClickFont.Name, 14, FontStyle.Bold Or FontStyle.Italic)
  End Sub

  Private Sub ButtonMouseDown(ByVal sender As Object, ByVal e As MouseEventArgs)
    Debug.WriteLine(String.Format(“Button Down at ({0},{1})”, e.X, e.Y))

    ‘ change the font while the button is down

    Dim s As Button = CType(sender, Button)
    s.Font
= clickFont
 
End
Sub

  Private
Sub ButtonMouseUp(ByVal sender As Object, ByVal e As MouseEventArgs)
    Debug.WriteLine(String.Format(“Button Up at ({0},{1})”, e.X, e.Y))

    ‘ revert the font while the button is up

    Dim s As Button = CType(sender, Button)
    s.Font
= noClickFont
 
End
Sub
End Class

Public Class MyApplication
  ‘ global filter object
  Public Shared buttonFilter As New ButtonEventFilter()

  Public Shared Sub Main()
    ‘ add the filter
    Application2.AddMessageFilter(buttonFilter)
    ‘ start the app’s main Form
    Application2.Run(New Form1())
  End Sub
End Class

Public Class ButtonEventFilter
  Implements IMessageFilter

  Private m_buttonList As New List(Of Button)()

  Public Sub WatchButton(ByVal buttonToWatch As Button)
    m_buttonList.Add(buttonToWatch)
  End Sub

  Public Event MouseUp As MouseEventHandler
  Public Event MouseDown As MouseEventHandler

  Public Function PreFilterMessage(ByRef m As Microsoft.WindowsCE.Forms.Message) As Boolean 
      Implements OpenNETCF.Windows.Forms.IMessageFilter.PreFilterMessage
    
    PreFilterMessage = False

    ‘ only look for mouse button down and up
    If m.Msg <> LBUTTONDOWN And m.Msg <> LBUTTONUP Then Exit Function

    ‘ see if the control is a watched button
    For Each watchedButton As Button In m_buttonList
      If m.HWnd = watchedButton.Handle Then
        Dim i As Integer = CType(m.LParam, Integer)
        Dim x As Integer = i And &HFFFF
        Dim y As Integer = (i And &HFFFF0000) >> 16
        Dim args As New MouseEventArgs(CType(m.WParam, MouseButtons), 0, x, y, 0)

        If m.Msg = LBUTTONDOWN Then
          RaiseEvent MouseDown(watchedButton, args)
          ‘ alter the BackColor
          watchedButton.BackColor = Color.Red
       
ElseIf
m.Msg = LBUTTONUP Then
          RaiseEvent MouseUp(watchedButton, args)
          ‘ alter the BackColor
          watchedButton.BackColor = Color.Green
       
End
If

        ‘ refresh

        watchedButton.Refresh()
        ‘ prevent the default behavior (which will be a black background on click
        PreFilterMessage = True
     
End
If
    Next
  End Function
End Class

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s