2012-06-20 49 views
0

爲什麼函數displayChanged在下面的代碼中被觸發?CGDisplayRegisterReconfigurationCallback:回調未調用

#import <Cocoa/Cocoa.h> 

static void displayChanged(CGDirectDisplayID displayID, CGDisplayChangeSummaryFlags flags, void *userInfo) { 
    NSLog(@"%@, %@", displayID, flags); 
} 

int main(int argc, const char * argv[]) 
{ 

    @autoreleasepool { 

     CGDisplayRegisterReconfigurationCallback(displayChanged, NULL); 

     CFRunLoopRun(); 
    } 
    return 0; 
} 

我在物理上刪除(和插入)我的外部顯示器,但該功能從未運行。 爲什麼?

+0

你在做什麼有沒有真正目的C.嘗試實例化一個目標C對象,並把你的「'CGDisplayRegisterReconfigurationCallback'」函數調用在。我建議這樣做的原因是因爲我認爲你的代碼直接進入到「CFRunLoopRun」中,並且任何回調(不在Objective C對象上下文中)都沒有機會被調用。 –

+0

@MichaelDautermann我不認爲我理解,但你能提供一些代碼嗎? – Tyilo

回答

2

剛剛發現的this other question

解調用CFRunLoopRun你必須調用NSApplicationLoad建立與窗口服務器的連接之前。這是原來的問題固定的代碼:

#import <Cocoa/Cocoa.h> 

static void displayChanged(CGDirectDisplayID displayID, CGDisplayChangeSummaryFlags flags, void *userInfo) { 
    NSLog(@"%u, %u", displayID, flags); 
} 

int main(int argc, const char * argv[]) 
{ 

    @autoreleasepool { 

     CGDisplayRegisterReconfigurationCallback(displayChanged, NULL); 

     NSApplicationLoad(); // establish a connection to the window server. In <Cocoa/Cocoa.h> 
     CFRunLoopRun();  // run the event loop 
    } 
    return 0; 
} 
+0

這是一個更好的解決方案,也適用於OS X 10.10,與我的回答不同。 – Tyilo

0

我不能讓CGDisplayRegisterReconfigurationCallback工作,所以我採用了分佈式通知,而是:如果您使用了AppKit

int main(int argc, const char * argv[]) { 
    @autoreleasepool { 
     [[NSDistributedNotificationCenter defaultCenter] addObserverForName:@"com.apple.BezelServices.BMDisplayHWReconfiguredEvent" object:nil queue:nil usingBlock:^(NSNotification *notification) { 
      NSLog(@"Displays changed!"); 
     }]; 

     CFRunLoopRun(); 
    } 
    return 0; 
} 
0

(並有運行NSApplication事件循環),你可以監聽NSApplicationDidChangeScreenParametersNotification通知。或者,您可以在應用程序委託中實現-applicationDidChangeScreenParameters:方法,這相當於同樣的事情。

+0

這是一個守護進程,所以我沒有任何用戶界面。 – Tyilo

+0

好的。我不確定,因爲你導入了包含AppKit的'。 –