Question

I have a vb6 form with an ocx control on it. The ocx control has a button on it that I want to press from code. How do I do this?

I have:

Dim b As CommandButton
Set b = ocx.GetButton("btnPrint")
SendMessage ocx.hwnd, WM_COMMAND, GetWindowLong(b.hwnd, GWL_ID), b.hwnd

but it doesn't seem to work.

Was it helpful?

Solution

I believe the following will work:

Dim b As CommandButton
Set b = ocx.GetButton("btnPrint")
b = True

CommandButtons actually have two functions. One is the usual click button and the other is a toggle button that acts similar to a CheckBox. The default property of the CommandButton is actually the Value property that indicates whether a button is toggled. By setting the property, the Click event is generated. This is done even if the button is not styled as a ToggleButton and therefore doesn't change its state.

OTHER TIPS

If you have access to the OCX code, you could expose the associated event handler and invoke it directly.
Don't know if an equivalent of .Net Button's Click() method existed back in VB6 days

For keypress you can also use sendmessage sending both keydown and keyup:

Private Declare Function SendMessage Lib "user32" Alias "SendMessageA" (ByVal hWnd As Long, ByVal wMsg As Long, ByVal wParam As Long, lParam As Long) As Long
Const WM_KEYDOWN As Integer = &H100
Const WM_KEYUP As Integer = &H101
Const VK_SPACE = &H20

Private Sub cmdCommand1_Click()
    Dim b As CommandButton
    Set b = ocx.GetButton("btnPrint")
    SendMessage b.hWnd, WM_KEYDOWN, VK_SPACE, 0&
    SendMessage b.hWnd, WM_KEYUP, VK_SPACE, 0&
End Sub

This:

Dim b As CommandButton
Set b = ocx.GetButton("btnPrint")
b = True

does work. Completely unintuitive. I'd expect it to throw an error since a bool is not a valid CommandButton, but it is because of the default property thing.

WM_LBUTTONDOWN would be a mouse click, what I want is a button click (button as in a hwnd button, not a mouse button).

I don't have access to the source of the ocx (it's a 3rd party control). If I did, I would expose the function that I wanted to call (the original writer of the ocx should have exposed it).

Do you have access to the OCX code? You shouldn't really be directly invoking the click of a button. You should refactor the code so that the OCX button click code calls a function, e.g.

CMyWindow::OnLButtonDown()
{
  this->FooBar();
}

Then from your VB6 app, directly call the FooBar method. If you can't directly call functions from VB6 you can wrap the FooBar() method with a windows message proc function, e.g.

#define WM_FOOBAR WM_APP + 1

Then use SendMessage in the VB6, like SendMessage(WM_FOOBAR, ...)

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top