Cocoa Can';无法使用NSOpenGLView从NextEventMachingMask获取NSMouseMoved事件

Cocoa Can';无法使用NSOpenGLView从NextEventMachingMask获取NSMouseMoved事件,cocoa,nsopenglview,Cocoa,Nsopenglview,我正在尝试使用典型的win样式的事件循环创建一个带有鼠标输入的基本opengl窗口。问题是,我正在努力获取要生成的NSMouseMoved事件。下面的代码输出关于鼠标向上、鼠标向下、鼠标拖动等的调试信息,但没有鼠标移动,即使我告诉窗口setAcceptsMouseMovedEvents:YES。那么,在下面的示例中,有没有关于如何让鼠标移动正常工作的想法 显然,我创建窗口的方式非常不类似于可可,但是我尝试移植一个基于MaxFixMeX的C++ C++代码库来做一些棘手的线程。这就是为什么我坚持使

我正在尝试使用典型的win样式的事件循环创建一个带有鼠标输入的基本opengl窗口。问题是,我正在努力获取要生成的
NSMouseMoved
事件。下面的代码输出关于鼠标向上、鼠标向下、鼠标拖动等的调试信息,但没有鼠标移动,即使我告诉窗口
setAcceptsMouseMovedEvents:YES
。那么,在下面的示例中,有没有关于如何让鼠标移动正常工作的想法

显然,我创建窗口的方式非常不类似于可可,但是我尝试移植一个基于MaxFixMeX的C++ C++代码库来做一些棘手的线程。这就是为什么我坚持使用类似win32循环的样式,使用
GetMsg()

此外,为了构建,我只使用:

gcc -o hellogl hellogl.m -framework Foundation -framework Cocoa -framework OpenGL
谢谢你的帮助

#import <Foundation/Foundation.h>
#import <Cocoa/Cocoa.h>

#include <OpenGL/gl.h>
#include <stdlib.h>

@interface BaseWinDelegate : NSWindow<NSWindowDelegate>

@end

@implementation BaseWinDelegate
- (void) windowWillClose:(NSNotification*)notification
{
    printf("Closing.\n");

    NSEvent * evt = [NSEvent otherEventWithType:NSApplicationDefined
                     location: NSMakePoint(0,0)
                     modifierFlags: 0
                     timestamp: 0.0
                     windowNumber: 0
                     context: nil
                     subtype: 0
                     data1: 0
                     data2: 0];

    [NSApp postEvent:evt atStart:NO];
}
@end

@interface BaseView : NSOpenGLView
- (void) update;
- (void) drawRect:(NSRect)rect;
- (void) reshape;
@end

@implementation BaseView

- (void) drawRect:(NSRect)rect
{
    glClearColor(0.2f,0.2f,0.2f,0.0f);
    glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);

    [[self openGLContext] flushBuffer];
}

- (void) update
{
    printf("Update.\n");
}

- (void) reshape
{
    NSRect rect;

    [[self openGLContext] update];
    rect = [self bounds];

    printf("Reshape - %f, %f\n", rect.size.width,rect.size.height);
}

@end

int main(int argc, const char * argv[])
{
    printf("Starting.\n");

    NSAutoreleasePool * myPool = [[NSAutoreleasePool alloc] init ];
    NSApplicationLoad();

    NSRect rect = NSMakeRect(100,100,640,480);
    NSWindow * win = [[NSWindow alloc] initWithContentRect:rect
                        styleMask:NSTitledWindowMask |     NSClosableWindowMask | NSMiniaturizableWindowMask | NSResizableWindowMask
                        backing: NSBackingStoreBuffered
                        defer: NO];

    NSOpenGLPixelFormatAttribute attributes[] =
    {
        NSOpenGLPFADoubleBuffer,
        0
    };

    NSOpenGLPixelFormat* pf = [[NSOpenGLPixelFormat alloc]     initWithAttributes:attributes];

    BaseView * pView = [[BaseView alloc] initWithFrame:rect pixelFormat:pf];
        BaseWinDelegate * myDelegate = [BaseWinDelegate alloc];

    [win setDelegate:myDelegate];
    [win setContentView: pView];
    [win makeKeyAndOrderFront: NSApp];
    [win setAcceptsMouseMovedEvents:YES];

    do
    {
        NSEvent * evt = [NSApp nextEventMatchingMask : NSAnyEventMask
                               untilDate : [NSDate distantFuture]
                               inMode : NSDefaultRunLoopMode
                               dequeue : YES ];

        NSEventType evtType = [evt type];

        if (evtType == NSApplicationDefined)
        {
            break;
        }

        printf("%d\n",(int)evtType);
        [NSApp sendEvent : evt];
    } while (1);

    [myPool drain];
    return EXIT_SUCCESS;
}
#导入
#进口
#包括
#包括
@BaseWinDelegate接口:NSWindow
@结束
@基于WinDelegate的实现
-(无效)窗口将关闭:(NSNotification*)通知
{
printf(“关闭。\n”);
NSEvent*evt=[NSEvent otherEventWithType:NSApplicationDefined
位置:NSMakePoint(0,0)
modifierFlags:0
时间戳:0.0
窗口号:0
上下文:无
子类型:0
数据1:0
数据2:0];
[NSApp postEvent:evt atStart:NO];
}
@结束
@接口BaseView:NSOpenGLView
-(b)更新;
-(void)drawRect:(NSRect)rect;
-(空)重塑;
@结束
@实现BaseView
-(void)drawRect:(NSRect)rect
{
glClearColor(0.2f、0.2f、0.2f、0.0f);
glClear(GL_颜色_缓冲_位| GL_深度_缓冲_位);
[[self-openGLContext]flushBuffer];
}
-(作废)更新
{
printf(“更新。\n”);
}
-(空)重塑
{
NSRect rect;
[[self-openGLContext]更新];
rect=[自边界];
printf(“重塑-%f,%f\n”,矩形尺寸.宽度,矩形尺寸.高度);
}
@结束
int main(int argc,const char*argv[]
{
printf(“开始。\n”);
NSAutoreleasePool*myPool=[[NSAutoreleasePool alloc]init];
NSApplicationLoad();
NSRect rect=NSMakeRect(100100640480);
NSWindow*win=[[NSWindow alloc]initWithContentRect:rect
样式掩码:NSTitledWindowMask | NSClosableWindowMask | nsMinimableWindowMask | nsrEssizableWindowMask
backing:NSBackingStoreBuffered
延期:否];
NSOpenGLPixelFormatAttribute属性[]=
{
NSOPENGLPFADOUBLEBUFER,
0
};
NSOpenGLPixelFormat*pf=[[NSOpenGLPixelFormat alloc]initWithAttributes:attributes];
BaseView*pView=[[BaseView alloc]initWithFrame:rect像素格式:pf];
BaseWinDelegate*myDelegate=[BaseWinDelegate alloc];
[win setDelegate:myDelegate];
[win setContentView:pView];
[win MakeKeyandDerfront:NSApp];
[win setAcceptsMouseMovedEvents:是];
做
{
NSEvent*evt=[NSApp下一个EventMachingMask:NSAnyEventMask
截止日期:[NSDate distantFuture]
inMode:NSDefaultRunLoopMode
出列:是];
NSEventType evtType=[evt type];
if(evtType==NSApplicationDefined)
{
打破
}
printf(“%d\n”,(int)evtType);
[NSApp sendEvent:evt];
}而(1),;
[我的泳池排水沟];
返回退出成功;
}

好的,算了。问题是它不是一个前台进程。因此,添加此代码可以修复它

ProcessSerialNumber psn;
GetCurrentProcess(&psn);
TransformProcessType(&psn, kProcessTransformToForegroundApplication);
SetFrontProcess(&psn);
这会阻止窗口成为关键窗口并发送鼠标移动事件。希望它能帮助其他人(即0.1%喜欢处理自己事件循环的人)