[vtkusers] Re: Can't catch double clicks in vtkWin32RenderWindowInteractor

list at kobenetz.de list at kobenetz.de
Thu Mar 22 04:30:14 EDT 2007


> list at kobenetz.de wrote:
>> VTK 5.0.2, WinXP SP2 on Mac(Intel) with Bootcamp, C++, Visual Studio
>> 2005
>>
>> Hi,
>>
>> I'm having some trouble with the vtkWin32RenderWindowInteractor and the
>> mouse:
>>
>> 1. I can't catch double-clicks
>> 2. The mouse-picking as described in
>> http://www.vtk.org/Wiki/VTK_Mouse_Picking does not work for me. See
>> description below.
>>
>>
>> 1. I've tried using vtkRenderWindowInteractor::GetRepeatCount() with the
>> Default style and the TrackballCamera style. GetRepeatCount does never
>> return 1.
>>
>> I've looked through the source and traced back the problem to the
>> following file and inserted two 'printf's to see if the clicks are
>> beeing
>> caught:
>>
>> vtkWin32RenderWindowInteractor.cxx:
>> ---- Line 640
>>
>>     case WM_LBUTTONDBLCLK:
>>       me->OnLButtonDown(hWnd,wParam,MAKEPOINTS(lParam).x,MAKEPOINTS(lParam).y,
>> 1);
>> 	  printf ("\n\nDouble-click!\n\n");
>>       break;
>>
>>     case WM_LBUTTONDOWN:
>>       me->OnLButtonDown(hWnd,wParam,MAKEPOINTS(lParam).x,MAKEPOINTS(lParam).y,
>> 0);
>> 	  printf ("\n\nSingle-click!\n\n");
>>       break;
>>
>> ----
>>
>> When I double-click the mouse in the RenderWindow I get the
>> "Single-click"
>> message twice, not the "Double-click" one. Where's the problem?
>>
>>
>> 2. When trying to use the mouse picking as described, "press"-"don't
>> move"-"release" it always appears that the mouse has been moved in
>> between:
>>
>>
>> ----
>> void cb_leftButtonDown( vtkObject *caller, unsigned long eid, void
>> *clientdata, void *calldata )
>> {
>> 	MouseMotion = 0;
>> 	cout << "cb_leftButtonDown\n";
>>
>> 	if( iren->GetRepeatCount() == 1 )
>> 	{
>> 		// This never happens anyway ...
>> 		cout << "Double-click!\n";
>> 	}
>>
>> 	style->OnLeftButtonDown();
>> }
>>
>> void cb_leftButtonUp( vtkObject *caller, unsigned long eid, void
>> *clientdata, void *calldata )
>> {
>>
>> 	cout << "cb_leftButtonUp\n";
>>
>> 	if( MouseMotion == 0 )
>> 	{
>> 		picker->Pick( iren->GetEventPosition()[0],
>> iren->GetEventPosition()[1],
>> 0.0, ren1);
>> 		showPick( 0,0,0,0 ); // Draw some info about picking location ...
>> 	}
>>
>> 	style->OnLeftButtonUp();
>> }
>>
>> void cb_mouseMove( vtkObject *caller, unsigned long eid, void
>> *clientdata,
>> void *calldata )
>> {
>> 	if( MouseMotion == 0 )
>> 	{
>> 		cout << "Mouse has been moved!";
>> 	}
>> 	MouseMotion = 1;
>>
>> 	style->OnMouseMove();
>> }
>> ----
>>
>> What happens is the following: I click and hold the mouse button without
>> moving the mouse (Optical mouse up in the air). Instantly I get the
>> Message "cb_leftButtonDown" and a few MILLISECONS later "Mouse has been
>> moved!". If I click-release fast enough I can manage to get a pick, but
>> why do I get this unexpected behaviour?
>>
>> Thanks,
>>
>> Christoph
>
> Hi Christoph,
>
> The RepeatCount will only be set when you've released the button, so
> should be accessed in your cb_leftButtonUp method...

Nope. Look at the vtk code. The exact opposite is the case: After a
ButtonRelease event the RepeatCount will ALWAYS be 0:

----vtkWin32RenderWindowInteractor.cxx:

void vtkWin32RenderWindowInteractor::OnLButtonDown(HWND wnd,UINT nFlags,
                                                   int X, int Y, int repeat)
{
  if (!this->Enabled)
    {
    return;
    }
  SetCapture(wnd);
  this->SetEventInformationFlipY(X,
                                 Y,
                                 nFlags & MK_CONTROL,
                                 nFlags & MK_SHIFT,
                                 0, repeat); /* HERE repeat is set */
  this->InvokeEvent(vtkCommand::LeftButtonPressEvent,NULL);
}

void vtkWin32RenderWindowInteractor::OnLButtonUp(HWND,UINT nFlags,
                                                 int X, int Y)
{
  if (!this->Enabled)
    {
    return;
    }
  this->SetEventInformationFlipY(X,
                                 Y,
                                 nFlags & MK_CONTROL,
                                 nFlags & MK_SHIFT); /* HERE repeat is not
set and defaults to 0 */
  this->InvokeEvent(vtkCommand::LeftButtonReleaseEvent,NULL);
  ReleaseCapture( );
}
----


----vtkWin32RenderWindowInteractor.h:
  // Description:
  // Set all the event information in one call.
  void SetEventInformation(int x,
                           int y,
                           int ctrl=0,
                           int shift=0,
                           char keycode=0,
                           int repeatcount=0,
                           const char* keysym=0)
    {
      this->LastEventPosition[0] = this->EventPosition[0];
      this->LastEventPosition[1] = this->EventPosition[1];
      this->EventPosition[0] = x;
      this->EventPosition[1] = y;
      this->ControlKey = ctrl;
      this->ShiftKey = shift;
      this->KeyCode = keycode;
      this->RepeatCount = repeatcount;
      if(keysym)
        {
        this->SetKeySym(keysym);
        }
      this->Modified();
    }

----

>
> if( MouseMotion == 0 && iren->GetRepeatCount() == 1)
>    {
> ...
>    }
>
> Have you cut out where you declare the "iren" and "style" pointers in
> your callback?
> You'll have to cast "caller" as a pointer to vtkInteractorStyle and call:

Anyway, the code-modification I did with the
printf("\n\nDouble-Click\n\n"); above is independent of any vtk-callback.
How could vtk know about a  double-click when the win32 WM_LBUTTONDBLCLK
event is never fired? My question is: What does prevent the
WM_LBUTTONDBLCLK-event?

> vtkInteractorStyle *style = vtkInteractorStyle::SafeDownCast(caller);
> vtkRenderWindowInteractor *iren = style->GetInteractor();
>
> I've only tried this code with Tcl scripts (and the modified C++
> classes)... there could be a bug with the win32 events.
>
> hth
>
> Goodwin

Christoph




More information about the vtkusers mailing list