Search code examples
vb.netdatetimepickersendmessagecitrix

How to automatically drop down DateTimePicker in Vb.net through a Citrix client


Through a variety of reasons I am forced to use the incredibly frustrating vb.net DateTimePicker control, in the even more frustrating Citrix client, for an application. This isn't actually my main problem, the problem is, I have to make the datetimepicker automatically drop down when the user presses any button (besides tab, escape, etc).

I really need to get this to work, the users won't really take no for an answer. I would prefer to not get a new custom control, but if one exists that is easy to implement (and doesn't allow the user to type in the date) then I would be open to it.

This is what I've done so far, it works perfectly well outside of Citrix, but when it triggers in Citrix the DateTimePicker doesn't refresh when the user navigates around it. Meaning the square is over the current date, and the user can press arrow keys to their heart's content, but it never shows this to the user. (Even if the user uses the mouse to drop it down.)

Again outside of Citrix this works fine.

'Used to manually dropdown datetimepickers
Private dateTimePickerControl As DateTimePicker
Private Declare Auto Function SendMessage Lib "user32.dll" (ByVal hWnd As IntPtr, ByVal msg As Integer, ByVal wParam As IntPtr, ByVal lParam As IntPtr) As IntPtr


Public Sub DropDownCalendar()
    Const WM_LBUTTONDOWN As Int32 = &H201
    Const WM_LBUTTONUP As Int32 = &H202

    Dim x As Integer = Me.dateTimePickerControl.Width - 10
    Dim y As Integer = CInt(Me.dateTimePickerControl.Height / 2)
    Dim lParam As Integer = x + y * &H10000

    'click down, and show the calendar
    SendMessage(Me.dateTimePickerControl.Handle, WM_LBUTTONDOWN, CType(1, IntPtr), CType(lParam, IntPtr))

    'Click-up, and activate the calendar (without this the calendar is shown, but is not active, and doesn't work as expected)
    SendMessage(Me.dateTimePickerControl.Handle, WM_LBUTTONUP, CType(1, IntPtr), CType(lParam, IntPtr))
End Sub


Private Sub dteDate_KeyDown(sender As Object, e As System.Windows.Forms.KeyEventArgs) Handles dteDate.KeyDown
    Try
        If e.KeyCode = Keys.Delete Then
            sender.customFormat = " "
            e.Handled = True
        ElseIf e.KeyCode <> Keys.Tab And e.KeyCode <> Keys.ShiftKey Then
            sender.focus()
            dateTimePickerControl = sender
            DropDownCalendar()
        End If
    Catch ex As Exception
        MsgBox(ex.Message)
    End Try
End Sub

I'm completely at a loss. Is such a thing even possible in Citrix? In a previous attempt I used SendKeys("{F4}") which worked fine outside of Citrix, but in Citrix would just drop down a frozen white background.

Does anyone have any ideas that could help me out here?


Solution

  • Sometimes we've had to add DoEvents when sending messages like this in our VB app hosted on Citrix. See if this works for you:

    Private Declare Auto Function SendMessage Lib "user32.dll" (ByVal hWnd As IntPtr, ByVal msg As Integer, ByVal wParam As IntPtr, ByVal lParam As IntPtr) As IntPtr
    
    Private Sub DropDownCalendar(ctl As DateTimePicker)
        Const WM_LBUTTONDOWN = &H201
        Const WM_LBUTTONUP = &H202
    
        If ctl Is Nothing Then
            Exit Sub
        End If
    
        ctl.Select()
    
        Dim lParam = (ctl.Width - 10) + (CInt(ctl.Height / 2) * &H10000)
    
        'click down, and show the calendar
        SendMessage(ctl.Handle, WM_LBUTTONDOWN, CType(1, IntPtr), CType(lParam, IntPtr))
    
        Application.DoEvents()
    
        'Click-up, and activate the calendar (without this the calendar is shown, but is not active, and doesn't work as expected)
        SendMessage(ctl.Handle, WM_LBUTTONUP, CType(1, IntPtr), CType(lParam, IntPtr))
    End Sub
    
    Private Sub dteDate_KeyDown(sender As Object, e As System.Windows.Forms.KeyEventArgs) Handles dteDate.KeyDown
        Try
            If e.KeyCode = Keys.Delete Then
                CType(sender, DateTimePicker).CustomFormat = " "
                e.Handled = True
            ElseIf e.KeyCode <> Keys.Tab And e.KeyCode <> Keys.ShiftKey Then
                DropDownCalendar(CType(sender, DateTimePicker))
            End If
        Catch ex As Exception
            MsgBox(ex.Message)
        End Try
    End Sub