2

On request I have implemented support for moving an OS X window by dragging it using an area within the content part of the window, i.e replicating the drag and move functionality of the title bar but in another area.

The problem I have yet to resolve is the fact that if the user drags the mouse quickly it can leave the window area and then no more mouse move events are received.

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

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

I have found Carbon API methods like for example TrackMouseLocation() but can't really see how I could use them for this application. In 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() blocks waiting for input. Blocking is something this application can not do since it also host a flash player that must be called many times per second.

The protototype I have assembled when trying to figure this 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?

4

3 回答 3

1

我觉得你应该在窗口和窗口外跟踪鼠标。以下代码应该可以解决您的问题,

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){}

希望能帮助到你!!

于 2009-12-25T11:00:47.987 回答
0

您也可以尝试只调用DragWindow以响应您窗口内容区域中的点击。我认为您不需要自己实现拖动。

于 2010-06-25T17:30:37.627 回答
0

我希望它对你也有帮助:

   // 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);

我正在寻找在某个位置(在所有应用程序的所有窗口上)获取 WindowPart 参考的方法

Carbon 中的某些方法不起作用,总是返回 0 作为 windowRef ... 有什么想法吗?

于 2010-04-13T10:24:58.273 回答