What API can I use to _capture_ the mouse when moving OS X Carbon Windows?

Upon request, I have implemented support for moving an OS X window by dragging it using an area within a piece of window content, i.e. replicating the title bar drag and drop functionality, but in a different area.

The problem that I have not yet resolved is that if the user drags the mouse quickly, he may leave the window area and then no more mouse move events will be received.

In windows, this type of problem can simply be fixed by calling the SetCapture () method of win32, what's the appropriate OSX method?

This app is a cross-platform C ++ application using Carbon for specific parts of OS X. (And yes, I know all about the benefits of Cocoa, but this is an earlier code base and time and money for the Cocoa port at this point in time. )

I've found Carbon API methods like TrackMouseLocation () for example, but can't figure out how I can use them for this application. Listing 2-7 here http://developer.apple.com/legacy/mac/library/documentation/Carbon/Conceptual/Carbon_Event_Manager/Tasks/CarbonEventsTasks.html the mouse is captured, but the problem is that TrackMouseLocation () is blocking waiting for input ... Blocking is something this app cannot do as it also contains a flash player that has to be called many times per second.

The prototype I put together trying to figure it out basically looks like this:

switch(GetEventKind(inEvent))
{
  case kEventMouseDown:
    // A silly test to make parts of the window border "draggable"
    dragging = local_loc.v < 25 || local_loc.h < 25; 
    last_screen_loc = screen_loc;
    break;
  case kEventMouseUp:
    dragging = false;
    break;
  case kEventMouseMoved:
    break;
  case kEventMouseDragged:
    if (dragging) {
      Rect rect;
      GetWindowBounds (windowRef, kWindowContentRgn, &rect);
      int dx = screen_loc.h - last_screen_loc.h;
      int dy = screen_loc.v - last_screen_loc.v;
      rect.left += dx;
      rect.right += dx;
      rect.top += dy;
      rect.bottom += dy;
      SetWindowBounds (windowRef, kWindowContentRgn, &rect);
    }
    last_screen_loc = screen_loc;
    break;

      

Any ideas appreciated?

+2


source to share


3 answers


I feel like you should keep track of the mouse in the window as well as out of the window. The following code should solve your problem,

EventHandlerRef     m_ApplicationMouseDragEventHandlerRef;          
EventHandlerRef     m_MonitorMouseDragEventHandlerRef;

{
    OSStatus ErrStatus;

    static const EventTypeSpec kMouseDragEvents[] =
      {
        { kEventClassMouse, kEventMouseDragged }
      };

    ErrStatus = InstallEventHandler(GetEventMonitorTarget(), NewEventHandlerUPP(MouseHasDragged), GetEventTypeCount(kMouseDragEvents), kMouseDragEvents, this, &m_MonitorMouseDragEventHandlerRef);

    ErrStatus = InstallApplicationEventHandler(NewEventHandlerUPP(MouseHasDragged), GetEventTypeCount(kMouseDragEvents), kMouseDragEvents, this, &m_ApplicationMouseDragEventHandlerRef);

    return true;
}

//implement these functions
OSStatus MouseHasDragged(EventHandlerCallRef inCaller, EventRef inEvent, void *pUserData){}

      



Hope it helps!

+1


source


I hope this helps too:

   // Get Mouse Position --> WAY 1      
printf("Get Mouse Position Way 1\n");   

HICoordinateSpace space = 2;    

HIGetMousePosition(space, NULL, &point);    
printf("Mouse Position: %.2f %.2f \n", point.x, point.y);


// Get Mouse Position --> WAY 2 
printf("Get Mouse Position Way 2\n");

CGEventRef ourEvent = CGEventCreate(NULL);
point = CGEventGetLocation(ourEvent);
printf("Mouse Position: %.2f, y = %.2f \n", (float)point.x, (float)point.y);

      



I am looking for a way to get the WindowPart reference at a specific location (above all windows of all applications)

Some methods in Carbon don't work, always return 0 as windowRef ... Any ideas?

0


source


You can also try to simply call DragWindow

in response to a click in the window's content area. I don't think you need to realize drag yourself.

0


source







All Articles