调用 TransformProcessType() 时,应用程序菜单不显示

发布于 2024-12-07 02:10:21 字数 277 浏览 1 评论 0原文

如果您像这样调用 TransformProcessType() :

ProcessSerialNumber psn = { 0, kCurrentProcess }; 
(void) TransformProcessType(&psn, kProcessTransformToForegroundApplication);

那么除非您在应用程序中尽早调用它(例如在 applicationWillFinishLaunching 中),否则可可应用程序菜单不会显示。

If you call TransformProcessType() like this :

ProcessSerialNumber psn = { 0, kCurrentProcess }; 
(void) TransformProcessType(&psn, kProcessTransformToForegroundApplication);

Then the cocoa app menu doesn't show up unless you call this early enough in your app (eg. in applicationWillFinishLaunching).

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

好久不见√ 2024-12-14 02:10:21

我向苹果公司寻求帮助,他们给了我很好的帮助。引用 :

调用 TransformProcessType 时不显示菜单栏的原因是您的应用程序已经是活动应用程序(即 [[NSRunningApplication currentApplication] isActive] 返回 YES),并且在以下情况下显示应用程序的菜单栏应用程序已激活

这是他们的解决方法:

- (void)transformStep1 {
    for (NSRunningApplication * app in [NSRunningApplication runningApplicationsWithBundleIdentifier:@"com.apple.finder"]) {
        [app activateWithOptions:NSApplicationActivateIgnoringOtherApps];
        break;
    }
    [self performSelector:@selector(transformStep2) withObject:nil afterDelay:0.1];
}

- (void)transformStep2
{
    ProcessSerialNumber psn = { 0, kCurrentProcess }; 
    (void) TransformProcessType(&psn, kProcessTransformToForegroundApplication);

    [self performSelector:@selector(transformStep3) withObject:nil afterDelay:0.1];
}

- (void)transformStep3
{
    [[NSRunningApplication currentApplication] activateWithOptions:NSApplicationActivateIgnoringOtherApps];
}

I asked Apple for help and they helped me very well. Quote :

The reason why the menu bar isn't show when you call TransformProcessType is that your app is already the active app (that is, [[NSRunningApplication currentApplication] isActive] returns YES) and the menu bar for an app is shown when the app is activated

This is their workaround :

- (void)transformStep1 {
    for (NSRunningApplication * app in [NSRunningApplication runningApplicationsWithBundleIdentifier:@"com.apple.finder"]) {
        [app activateWithOptions:NSApplicationActivateIgnoringOtherApps];
        break;
    }
    [self performSelector:@selector(transformStep2) withObject:nil afterDelay:0.1];
}

- (void)transformStep2
{
    ProcessSerialNumber psn = { 0, kCurrentProcess }; 
    (void) TransformProcessType(&psn, kProcessTransformToForegroundApplication);

    [self performSelector:@selector(transformStep3) withObject:nil afterDelay:0.1];
}

- (void)transformStep3
{
    [[NSRunningApplication currentApplication] activateWithOptions:NSApplicationActivateIgnoringOtherApps];
}
冰葑 2024-12-14 02:10:21

这是我让它发挥作用的方法。

BOOL MakeAppForeground()
{
    BOOL bSuccess = TranformAppToState(kProcessTransformToForegroundApplication);

    if(bSuccess)
    {
         bSuccess = (SetSystemUIMode(kUIModeNormal, 0) == 0);
        [NSApp activateIgnoringOtherApps:YES];
    }

    return bSuccess;
}

BOOL MakeAppBackground()
{
    return TranformAppToState(kProcessTransformToBackgroundApplication);
}

BOOL TranformAppToState(ProcessApplicationTransformState newState)
{
    ProcessSerialNumber psn = { 0, kCurrentProcess };
    OSStatus transformStatus = TransformProcessType(&psn, newState);

    if((transformStatus != 0))
    {
        NSError *error = [NSError errorWithDomain:NSOSStatusErrorDomain code:transformStatus userInfo:nil];
        NSLog(@"TranformAppToState: Unable to transform App state. Error - %@",error);
    }

    return (transformStatus == 0);
}

Here is how I made it working.

BOOL MakeAppForeground()
{
    BOOL bSuccess = TranformAppToState(kProcessTransformToForegroundApplication);

    if(bSuccess)
    {
         bSuccess = (SetSystemUIMode(kUIModeNormal, 0) == 0);
        [NSApp activateIgnoringOtherApps:YES];
    }

    return bSuccess;
}

BOOL MakeAppBackground()
{
    return TranformAppToState(kProcessTransformToBackgroundApplication);
}

BOOL TranformAppToState(ProcessApplicationTransformState newState)
{
    ProcessSerialNumber psn = { 0, kCurrentProcess };
    OSStatus transformStatus = TransformProcessType(&psn, newState);

    if((transformStatus != 0))
    {
        NSError *error = [NSError errorWithDomain:NSOSStatusErrorDomain code:transformStatus userInfo:nil];
        NSLog(@"TranformAppToState: Unable to transform App state. Error - %@",error);
    }

    return (transformStatus == 0);
}
呆橘 2024-12-14 02:10:21

这是我的解决方案,它是在“首选项”窗口中单击复选框时触发的。唯一的副作用是应用程序窗口的短暂闪烁:

- (void) hideDockIcon:(bool) hide
{
    ProcessSerialNumber psn = { 0, kCurrentProcess };
    ProcessApplicationTransformState state = hide ? kProcessTransformToUIElementApplication : kProcessTransformToForegroundApplication;
    OSStatus err = TransformProcessType(&psn, state);
    
    if (err) {
        NSError *error = [NSError errorWithDomain:NSOSStatusErrorDomain code:err userInfo:nil];
        NSLog(@"TransformProcessType failed: %@", error);
    }
}

- (void) toggleDockIcon
{
    [NSApp hide:self];
    dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(0.1 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{
        [self hideDockIcon:self.preferences.hideDockIcon];
        dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(0.1 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{
            [NSApp activateIgnoringOtherApps:YES];
        });
    });
}

Here is my solution, which is triggered on checkbox click in Preferences window. The only side effect is short flashing of the app's windows:

- (void) hideDockIcon:(bool) hide
{
    ProcessSerialNumber psn = { 0, kCurrentProcess };
    ProcessApplicationTransformState state = hide ? kProcessTransformToUIElementApplication : kProcessTransformToForegroundApplication;
    OSStatus err = TransformProcessType(&psn, state);
    
    if (err) {
        NSError *error = [NSError errorWithDomain:NSOSStatusErrorDomain code:err userInfo:nil];
        NSLog(@"TransformProcessType failed: %@", error);
    }
}

- (void) toggleDockIcon
{
    [NSApp hide:self];
    dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(0.1 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{
        [self hideDockIcon:self.preferences.hideDockIcon];
        dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(0.1 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{
            [NSApp activateIgnoringOtherApps:YES];
        });
    });
}
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文