我知道,我不是第一个尝试在OSX上使用Cocoa和现有的c/c ++主循环的人,但我并不是真的喜欢我到目前为止遇到的解决方案所以我提出了一个不同的想法我'我想讨论一下.我发现的最常见的方式(在glut,glfw,SDL以及QT中我认为)是使用轮询来替换NSApplications run方法并自行处理事件:
nextEventMatchingMask:untilDate:inMode:dequeue:
Run Code Online (Sandbox Code Playgroud)
这有一个很大的缺点,即cpu永远不会真正空闲,因为你必须轮询整个时间来检查是否有任何新事件,而且它不是NSApplications运行函数内部唯一的事情,所以它可能会破坏一些细节,如果你用这个替代品.
所以我想做的是保持cocoa runLoop完好无损.想象一下,你有自己的计时器方法在c ++中实现,通常会在你的主循环中进行管理和触发(这只是一个小部分作为例子).我的想法是将所有循环部分移动到辅助线程(因为据我所知,NSApplication运行需要从主线程调用),然后将自定义事件发布到NSApplication的派生版本中,该版本在其中适当地处理它们sendEvent:方法.例如,如果我的计时器在我的c ++循环测量中测量,我会向NSApplication发布一个自定义事件,然后运行我的应用程序的loopFunc()函数(也驻留在mainthread中),该函数适当地将事件发送到我的c ++事件链中.首先,您认为这是一个很好的解决方案吗?如是,
otherEventWithType:location:modifierFlags:timestamp:windowNumber:context:subtype:data1:data2:
然后使用类似的东西:
[NSApp postEvent:atStart:]
Run Code Online (Sandbox Code Playgroud)
通知NSApplication.
我宁愿发布没有任何窗口信息的事件(在otherEventWithType中),我可以简单地忽略那部分吗?
然后我想象覆盖NSApplications sendEvent函数类似于:
- (void)sendEvent:(NSEvent *)event
{
//this is my custom event that simply tells NSApplication
//that my app needs an update
if( [event type] == NSApplicationDefined)
{
myCppAppPtr->loopFunc(); //only iterates once
}
//transform cocoa events into my own input events
else if( [event type] == NSLeftMouseDown)
{
...
myCppAppPtr->loopFunc(); //also run the loopFunc to propagate input events
}
...
//dont break the cocoa event …Run Code Online (Sandbox Code Playgroud) 我有一个后台进程,当按下热键时会出现透明窗口:
[window makeKeyAndOrderFront:nil];
[[content animator] setAlphaValue:1.0]; // alpha was 0.0
Run Code Online (Sandbox Code Playgroud)
...窗口显示正常并在其他窗口前面(我想要它),但是直到我手动点击窗口,无论应用程序处于活动状态,当窗口出现时仍保持活动状态.我期待'makeKeyAndOrderFront'也可以使应用程序处于活动状态,但是在我的-applicationWillBecomeActive中添加NSLog行会显示在执行鼠标单击之前没有获得任何活动通知.
有没有人知道我如何设置我的应用程序@我同时发出-makeKeyAndOrderFront?我需要它激活,以便它可以开始接受键盘输入 - 需要任何帮助:-)
我想我应该检查是否[NSApplication presentationOptions]包含NSFullScreenModeApplicationPresentationOptions,但我该如何实现呢?
编辑:使用[NSApplication presentationOptions]不像在我的基于文档的应用程序中那样,全屏可能有一些文档而其他文档没有.我现在正在寻找另一种解决方案.我想知道为什么没有一个叫做的财产[NSWindow isFullscreen]或类似的东西.
我认为这是第一个响应问题,但我不确定.我正在为表视图中的数据实现编辑窗口.在概念上与用于编辑Mail.app中的过滤规则的UI非常相似.
我有一个编辑窗口,我附加到我的主窗口:
[NSApp beginSheet: criteriaEditPanel
modalForWindow: [self window]
modalDelegate: self
didEndSelector: @selector(criteriaEditDidEnd:returnCode:contextInfo:)
contextInfo: (void *)[criteriaList objectAtIndex: index]];
Run Code Online (Sandbox Code Playgroud)
面板从主窗口的标题栏中正确显示.我可以使用鼠标操作面板上的弹出控件,但我无法编辑文本字段,我无法在字段之间切换.其他一切都很好.有任何想法吗?
乔
好的,这真的让我很难过:
我在窗口上创建一个模态表格
-(IBAction) login: (id) sender {
[NSApp beginSheet:loginWindow
modalForWindow:window
modalDelegate:nil
didEndSelector:nil
contextInfo:nil];
}
Run Code Online (Sandbox Code Playgroud)
并试着删除它
-(IBAction) loginWindowCancelPressed: (id) sender {
debugLog(@"cancel");
[NSApp endSheet:loginWindow];
}
Run Code Online (Sandbox Code Playgroud)
但它仍然存在.
我已经检查了所有明显的事情,比如IB连接,并确保window和loginWindow存在且处于正常状态.
所以,问题是:我错过了什么吗?
我创建了NSApplication子类:
class MyApplication: NSApplication {
override func sendEvent(theEvent: NSEvent) {
if theEvent.type == NSEventType.KeyUp && (theEvent.modifierFlags & .CommandKeyMask).rawValue != 0 {
self.keyWindow?.sendEvent(theEvent)
} else {
super.sendEvent(theEvent)
}
}
}
Run Code Online (Sandbox Code Playgroud)
之后,我将Info.plist中的"Principal class"更改为MyApplication,最后在Main.storyboard的Application Scene中,我也将Application更改为MyApplication.
当我运行应用程序时,我得到以下消息:
class MyApplication: NSApplication {
override func sendEvent(theEvent: NSEvent) {
if theEvent.type == NSEventType.KeyUp && (theEvent.modifierFlags & .CommandKeyMask).rawValue != 0 {
self.keyWindow?.sendEvent(theEvent)
} else {
super.sendEvent(theEvent)
}
}
}
Run Code Online (Sandbox Code Playgroud)
有人可以帮我弄这个吗?
我有什么选择(如果有的话)向NSApplication收到orderFrontStandardAboutPanel消息时显示的标准Cocoa关于对话框添加其他任意数据.
从k CGWindowNumber,我如何获得NSWindow参考.我试过用:
[NSApp windowWithWindowNumber:windowNumber]
Run Code Online (Sandbox Code Playgroud)
但我总是得到一个空值.我需要NSWindow申请[window setlevel:NSFloatingWindowLevel],我已经设置了一个给定窗口的顶部.有谁知道如何解决这个问题或有任何替代解决方案?
谢谢你的回答,但这不是解决方案,我已经尝试但它不起作用,实际上我做了一个测试,我尝试了下面的代码:
for (NSInteger i = 0; i <10000; i + +) {
NSWindow * wind;
wind = [NSApp windowWithWindowNumber: windowNumber];
NSLog (@ "\ n Window:% @", wind);
}
Run Code Online (Sandbox Code Playgroud)
但结果总是如此 Window: (null)
我有一个窗口列表,在哪里可以获得OwnerPid窗口ecc .. ecc的数量...现在我需要设置总是在一些窗口的顶部.
Always on top可能设置为whit:[window setlevel:NSFloatingWindowLevel],window是一个NSwindow对象,它是真的吗?
你有解决方案吗?或者另一个想法,对我的问题?
我一直在寻找如何以编程方式终止我的应用程序.我发现很多人都在使用NSApp terminate:id.
在Xcode terminate:id中交叉.这种方法是否已被弃用?我应该用它来终止我的申请吗?如果没有哪个是正确的方法呢?
更新:
当我说它越过时我的意思的图片:

在尝试学习菜单处理的基础知识时.我的测试应用程序的菜单栏有3个菜单 - 即"TestApp","文件"和"帮助".我发现我可以完全删除这些菜单,只需调用say:
NSMenu* rootMenu = [NSApp mainMenu];
[rootMenu removeItemAtIndex:2];
Run Code Online (Sandbox Code Playgroud)
但是,我只想暂时禁用它们(灰掉它们).请问有同样简单的方法吗?
nsapplication ×10
cocoa ×8
objective-c ×5
macos ×3
nswindow ×3
c++ ×1
fullscreen ×1
integration ×1
nsmenu ×1
osx-lion ×1
swift ×1