【问题标题】:Listen for power button event in OS X在 OS X 中监听电源按钮事件
【发布时间】:2013-10-30 13:31:27
【问题描述】:

按下电源按钮时,我会看到以下对话框,如果已发送此通知:

__CFNotification 0x10011f410 {name = com.apple.logoutInitiated; object = 501}

问题:如何从 C++ 应用程序中侦听此事件并对其采取行动?

仅供参考:

我已经成功破解了一个 Objective C sn-p,它可以做到这一点:

#import "AppDelegate.h"

@implementation AppDelegate

- (void)applicationDidFinishLaunching:(NSNotification *)aNotification
{
    // Insert code here to initialize your application

    @autoreleasepool
    {
        [[NSDistributedNotificationCenter defaultCenter]
         addObserverForName: nil
         object: nil
         queue: [NSOperationQueue mainQueue]
         usingBlock: ^(NSNotification *notification) {

             //The event notification we are looking for:
             //__CFNotification 0x10011f410 {name = com.apple.logoutInitiated; object = 501}

             NSString *event = notification.name;
             BOOL res = [event isEqualToString:@"com.apple.logoutInitiated"];
             if (res)
             {
                 printf("POWER BUTTON PRESSED");
             }
             else
             {
                 printf("IGNORE");
             }
         }];

        [[NSRunLoop mainRunLoop] run];
    }

}

【问题讨论】:

  • 如果我错了,请纠正我,但我相信上面的代码不会拦截,而只是侦听通知。 (细微差别在于“拦截”允许您将通知隐藏到可能也在监听它的其他进程。)
  • 是的,抱歉,不需要拦截,只是为了听取此类事件并采取行动。
  • 您的 C++ 代码是在 mac 应用程序还是命令行实用程序中?
  • @trojanfoe,我看不出这有什么改变。
  • @QwertyBob 它没有,但我只是想了解可能适用于可能解决方案的限制。

标签: c++ macos


【解决方案1】:

一个简单的 c++ SCCE 看起来像:

#include <iostream>
#include <CoreFoundation/CoreFoundation.h>

void
myCallBack(CFNotificationCenterRef center,
           void *observer,
           CFStringRef name,
           const void *object,
           CFDictionaryRef userInfo) {
    std::cout << "Power Button Pressed" << std::endl;
}

int
main(int argc, const char * argv[])
{
    CFNotificationCenterRef distCenter;
    CFStringRef evtName = CFSTR("com.apple.logoutInitiated");
    distCenter = CFNotificationCenterGetDistributedCenter();
    if (NULL == distCenter)
        return 1;
    CFNotificationCenterAddObserver(distCenter, NULL, &myCallBack, evtName, NULL, CFNotificationSuspensionBehaviorDeliverImmediately);
    CFRunLoopRun();
    return 0;
}

并且将使用clang++ -framework CoreFoundation testfile.cpp进行编译。

如何将它连接到自己的应用程序中完全是另一回事。

【讨论】:

    【解决方案2】:

    CoreFoundation 有一个很好的用 C 编写的 API,因此您可以使用 CFNotificationCenterAddObserver 函数并将您的 C++ 程序链接到必要的框架。示例:

    clang++ <your options> -framework CoreFoundation
    

    请参阅official documentation。在这里快速搜索发现an example of how to use it

    【讨论】:

      【解决方案3】:

      本质上,您希望访问NSDistributedNotificationCenter 封装的底层功能。

      也许你应该看看CFNotificationCenterRef,更具体地说是CFNotificationCenterGetDistributedCenter()

      它们本身不是 C++,它们是 C 函数,但您可以从 C++ 中调用它们。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2012-08-05
        • 1970-01-01
        • 1970-01-01
        • 2017-09-27
        • 2016-10-02
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多