Creating a Cocoa Window in code

  • Hello,

    I am trying to implement a new backend for a cross-platform GUI
    library using Cocoa, and for that I am trying to create a simple
    window using purely code. I read the docs and I see that I should
    create a NSWindow:

    http://developer.apple.com/documentation/Cocoa/Reference/ApplicationKit/Cla
    sses/NSWindow_Class/Reference/Reference.html#//apple_ref/occ/instm/NSWindow
    /initWithContentRect:styleMask:backing:defer
    :

    I created a simple application which should just create a simple
    window, but it crashes on startup. Xcode warns that NSWindow may not
    respond to the initWithContentRect message, but according to the docs
    it should. Any ideas what is missing to make this work?

    thanks, here is my initial code:

    #import <Cocoa/Cocoa.h>

    int main(int argc, char *argv[])
    {
      // Creates an autorelease pool
      NSAutoreleasePool* pool = [[NSAutoreleasePool alloc] init];

      // Loads the application
      NSApplicationLoad();

      // Creates a simple window
      NSRect MainWindowRect = NSMakeRect(300, 300, 300, 500);

      id MainWindow = [NSWindow initWithContentRect: MainWindowRect
                                    styleMask: NSTitledWindowMask ||
    NSClosableWindowMask || NSMiniaturizableWindowMask ||
    NSResizableWindowMask
                                      backing: NSBackingStoreBuffered
                                        defer: NO];

      // Call release method from object pool
      [pool release];

      return 0;
    }

    --
    Felipe Monteiro de Carvalho
  • You are not calling alloc, it should be

      id MainWindow = [[NSWindow alloc] initWithContentRect:
    MainWindowRect  etc etc...

    Matt

    On 18 Jan 2008, at 12:15, Felipe Monteiro de Carvalho wrote:

    > Hello,
    >
    > I am trying to implement a new backend for a cross-platform GUI
    > library using Cocoa, and for that I am trying to create a simple
    > window using purely code. I read the docs and I see that I should
    > create a NSWindow:
    >
    > http://developer.apple.com/documentation/Cocoa/Reference/ApplicationKit/Cla
    sses/NSWindow_Class/Reference/Reference.html#/

    > /apple_ref/occ/instm/NSWindow/
    > initWithContentRect:styleMask:backing:defer:
    >
    > I created a simple application which should just create a simple
    > window, but it crashes on startup. Xcode warns that NSWindow may not
    > respond to the initWithContentRect message, but according to the docs
    > it should. Any ideas what is missing to make this work?
    >
    > thanks, here is my initial code:
    >
    > #import <Cocoa/Cocoa.h>
    >
    > int main(int argc, char *argv[])
    > {
    > // Creates an autorelease pool
    > NSAutoreleasePool* pool = [[NSAutoreleasePool alloc] init];
    >
    > // Loads the application
    > NSApplicationLoad();
    >
    > // Creates a simple window
    > NSRect MainWindowRect = NSMakeRect(300, 300, 300, 500);
    >
    > id MainWindow = [NSWindow initWithContentRect: MainWindowRect
    > styleMask: NSTitledWindowMask ||
  • On Jan 18, 2008 12:23 PM, Matt Gough <matt.gough...> wrote:
    > You are not calling alloc, it should be
    >
    > id MainWindow = [[NSWindow alloc] initWithContentRect:
    > MainWindowRect  etc etc...

    Thanks! Not it doesn't crash, but it exits right after starting. Is
    there a method somewhere to enter a message loop to prevent imediate
    exit?

    Also, what shows the window? I can't find a show method, or something similar.

    thanks,
    --
    Felipe Monteiro de Carvalho
  • On 18 Jan 08, at 03:15, Felipe Monteiro de Carvalho wrote:
    > I am trying to implement a new backend for a cross-platform GUI
    > library using Cocoa, and for that I am trying to create a simple
    > window using purely code. I read the docs and I see that I should
    > create a NSWindow:
    >
    > I created a simple application which should just create a simple
    > window, but it crashes on startup. Xcode warns that NSWindow may not
    > respond to the initWithContentRect message, but according to the docs
    > it should. Any ideas what is missing to make this work?

    Compiler warnings are usually correct. When they aren't, it's
    generally a good idea to modify your code to avoid them.

    > id MainWindow = [NSWindow initWithContentRect: MainWindowRect

    The NSWindow class does not respond to that selector. Instances of the
    NSWindow class do, but you haven't allocated one.

    > styleMask: NSTitledWindowMask ||
    > NSClosableWindowMask || NSMiniaturizableWindowMask ||
    > NSResizableWindowMask

    Unrelated to your problem, but you're using the wrong operator here. A
    styleMask of 1 won't do you much good.

    > backing: NSBackingStoreBuffered
    > defer: NO];

    Also, this code won't display a window on screen, as there's no runloop.

    I get the sense you may not have worked with Cocoa much before. You
    should probably get comfortable with using the framework before you
    start trying to do weird things with it.
  • On Jan 18, 2008 12:26 PM, Andrew Farmer <andfarm...> wrote:
    >> backing: NSBackingStoreBuffered
    >> defer: NO];
    >
    > Also, this code won't display a window on screen, as there's no runloop.

    And how do I get a runloop? I see there is NSApplicationMain, but it
    crashes with the code bellow. Also, the docs say it will load the main
    nib file, but my project has no nib file.

    #import <Cocoa/Cocoa.h>

    int main(int argc, char *argv[])
    {
      // Creates an autorelease pool
      NSAutoreleasePool* pool = [[NSAutoreleasePool alloc] init];

      // Loads the application
      NSApplicationLoad();

      // Creates a simple window
      NSRect MainWindowRect = NSMakeRect(300, 300, 300, 500);

      id MainWindow = [[NSWindow alloc] initWithContentRect: MainWindowRect
          styleMask: NSTitledWindowMask | NSClosableWindowMask |
    NSMiniaturizableWindowMask | NSResizableWindowMask
            backing: NSBackingStoreBuffered
              defer: NO];

      NSApplicationMain(argc, (const char **)argv);

      // Call release method from object pool
      [pool release];

      return 0;
    }
    --
    Felipe Monteiro de Carvalho
  • On 18 Jan, 2008, at 06:26, Andrew Farmer wrote:

    >> styleMask: NSTitledWindowMask ||
    >> NSClosableWindowMask || NSMiniaturizableWindowMask ||
    >> NSResizableWindowMask
    >
    > Unrelated to your problem, but you're using the wrong operator here.
    > A styleMask of 1 won't do you much good.

    Felipe,

    Andrew alludes to you using the logical OR operator || here instead of
    the bitwise OR operator used to combine bitmasks:

    maskOne | maskTwo

    This page has a very clear, concise explanation of the bitwise
    operators:

    http://en.wikipedia.org/wiki/Bitwise_operation

    --
    m-s
  • Hi, thanks, I think I have it almost working! At least for a initial
    hello world. I managed to get to the message loop by calling NSApp
    run, but then there is no way to quit the application, so I added a
    simple menu too. I can't find anything wrong with my menu
    implementation, but when I select the Quit menu I get an error on the
    console:

    2008-01-18 13:45:06.743 cocoawindow[797] could not find associated
    NSMenu for -20213 (item:9)

    Any ideas? Here is my code, thanks:

    #import <Cocoa/Cocoa.h>

    void CreateApplicationMenu(NSMenu* menu)
    {
    NSString * applicationName = @"cocoawindow";
    NSMenuItem * item;

    item = [menu addItemWithTitle:[NSString stringWithFormat:@"%@ %@",
    NSLocalizedString(@"Quit", nil), applicationName]
                             action:@selector(terminate:)
        keyEquivalent:@"q"];
    [item setTarget:NSApp];
    }

    void CreateMenu(void)
    {
    NSMenu * mainMenu = [[[NSMenu alloc] initWithTitle:@"MainMenu"] autorelease];

    NSMenuItem * item;
    NSMenu * submenu;

    // The titles of the menu items are for identification purposes only
    and shouldn't be localized.
    // The strings in the menu bar come from the submenu titles,
    // except for the application menu, whose title is ignored at runtime.
    item = [mainMenu addItemWithTitle:@"Apple" action:NULL keyEquivalent:@""];
    submenu = [[[NSMenu alloc] initWithTitle:@"Apple"] autorelease];
    [NSApp performSelector:@selector(setAppleMenu:) withObject:submenu];
    CreateApplicationMenu(submenu);
    [mainMenu setSubmenu:submenu forItem:item];
    }

    int main(int argc, char *argv[])
    {
        // Creates an autorelease pool
        NSAutoreleasePool* pool = [[NSAutoreleasePool alloc] init];

        // Loads the application
        NSApplicationLoad();

        // Creates a simple window
        NSRect MainWindowRect = NSMakeRect(300, 300, 300, 500);

        NSWindow* MainWindow = [[NSWindow alloc] initWithContentRect: MainWindowRect
          styleMask: NSTitledWindowMask | NSClosableWindowMask |
    NSMiniaturizableWindowMask | NSResizableWindowMask
            backing: NSBackingStoreBuffered
              defer: NO];

        [MainWindow orderFrontRegardless];

        // Creates the application object

        [NSApplication sharedApplication];

        CreateMenu();

        // Enters main message loop

        [NSApp run];

        // Call release method from object pool
        [pool release];

        return 0;
    }

    --
    Felipe Monteiro de Carvalho
  • You have "MainMenu" specified for the main nib in the application
    target.

    Also:

    >> NSApplicationMain(argc, (const char **)argv);
    >>
    >> // Call release method from object pool
    >> [pool release];
    >>
    >> return 0;

    It's probably better to do this instead:

      // Call release method from object pool
      [pool release];

      return  NSApplicationMain(argc, (const char **)argv);

    --
    m-s

    On 18 Jan, 2008, at 06:44, Felipe Monteiro de Carvalho wrote:

    > On Jan 18, 2008 12:26 PM, Andrew Farmer <andfarm...> wrote:
    >>> backing: NSBackingStoreBuffered
    >>> defer: NO];
    >>
    >> Also, this code won't display a window on screen, as there's no
    >> runloop.
    >
    > And how do I get a runloop? I see there is NSApplicationMain, but it
    > crashes with the code bellow. Also, the docs say it will load the main
    > nib file, but my project has no nib file.
    >
    > #import <Cocoa/Cocoa.h>
    >
    > int main(int argc, char *argv[])
    > {
    > // Creates an autorelease pool
    > NSAutoreleasePool* pool = [[NSAutoreleasePool alloc] init];
    >
    > // Loads the application
    > NSApplicationLoad();
    >
    > // Creates a simple window
    > NSRect MainWindowRect = NSMakeRect(300, 300, 300, 500);
    >
    > id MainWindow = [[NSWindow alloc] initWithContentRect:
    > MainWindowRect
    > styleMask: NSTitledWindowMask | NSClosableWindowMask |
    > NSMiniaturizableWindowMask | NSResizableWindowMask
    > backing: NSBackingStoreBuffered
    > defer: NO];
    >
    > NSApplicationMain(argc, (const char **)argv);
    >
    > // Call release method from object pool
    > [pool release];
    >
    > return 0;
    > }
    > --
    > Felipe Monteiro de Carvalho
  • On Jan 18, 2008 1:54 PM, Michael Watson <mikey-san...> wrote:
    > You have "MainMenu" specified for the main nib in the application
    > target.

    A nib is platform specific. The whole point of the project is to
    implement a platform independent library, so adding nibs is against
    that objective. In other words: There is no nib on the project, just
    like there is no .rc windows resource.

    > return  NSApplicationMain(argc, (const char **)argv);

    That crashes the application. Maybe because there is no nib file.
    Anyway, this part of the application is changed on the last version,
    you quoted an old version.

    thanks,
    --
    Felipe Monteiro de Carvalho
  • On Jan 18, 2008, at 5:03 AM, Felipe Monteiro de Carvalho wrote:

    > A nib is platform specific. The whole point of the project is to
    > implement a platform independent library, so adding nibs is against
    > that objective.
    >
    This may be of some help:
    <http://lapcatsoftware.com/blog/2007/11/25/working-without-a-nib-part-6-work
    ing-without-a-xib/
    >

    mmalc
  • On Jan 18, 2008 3:00 PM, mmalc crawford <mmalc_lists...> wrote:

    Yes, I read it, but there is still something wrong with my code. In
    this latest version I have it almost working. Now the Quit button
    appears and also works. But I have 2 "Quit cocoawindow" buttons, with
    exactly the same name and shortcut key. One works, and the other
    doesn't =/ and I can't seam to find what is wrong.

    Any ideas? Here is my code, thanks:

    #import <Cocoa/Cocoa.h
    >

    void CreateApplicationMenu(NSMenu* menu)
    {
    NSString * applicationName = [NSLocalizedString(@"cocoawindow", @"The
    name of this application") retain];
    NSMenuItem * item;

    item = [menu addItemWithTitle:[NSString stringWithFormat:@"%@ %@",
    NSLocalizedString(@"About", nil), applicationName]
                             action:@selector(orderFrontStandardAboutPanel:)
        keyEquivalent:@""];
    [item setTarget:NSApp];

    [menu addItem:[NSMenuItem separatorItem]];

    item = [menu addItemWithTitle:NSLocalizedString(@"Preferences...", nil)
                             action:NULL
        keyEquivalent:@","];

    [menu addItem:[NSMenuItem separatorItem]];

    item = [menu addItemWithTitle:NSLocalizedString(@"Services", nil)
                             action:NULL
        keyEquivalent:@""];
    NSMenu * servicesMenu = [[[NSMenu alloc] initWithTitle:@"Services"]
    autorelease];
    [menu setSubmenu:servicesMenu forItem:item];
    [NSApp setServicesMenu:servicesMenu];

    [menu addItem:[NSMenuItem separatorItem]];

    item = [menu addItemWithTitle:[NSString stringWithFormat:@"%@ %@",
    NSLocalizedString(@"Hide", nil), applicationName]
                             action:@selector(hide:)
        keyEquivalent:@"h"];
    [item setTarget:NSApp];

    item = [menu addItemWithTitle:NSLocalizedString(@"Hide Others", nil)
                             action:@selector(hideOtherApplications:)
        keyEquivalent:@"h"];
    [item setKeyEquivalentModifierMask:NSCommandKeyMask | NSAlternateKeyMask];
    [item setTarget:NSApp];

    item = [menu addItemWithTitle:NSLocalizedString(@"Show All", nil)
                             action:@selector(unhideAllApplications:)
        keyEquivalent:@""];
    [item setTarget:NSApp];

    [menu addItem:[NSMenuItem separatorItem]];

    item = [menu addItemWithTitle:[NSString stringWithFormat:@"%@ %@",
    NSLocalizedString(@"Quit", nil), applicationName]
                             action:@selector(terminate:)
        keyEquivalent:@"q"];
    [item setTarget:NSApp];
    }

    void CreateMenu(void)
    {
    NSMenu * mainMenu = [[[NSMenu alloc] initWithTitle:@"MainMenu"] autorelease];

    NSMenuItem * item;
    NSMenu * submenu;

    // The titles of the menu items are for identification purposes only
    and shouldn't be localized.
    // The strings in the menu bar come from the submenu titles,
    // except for the application menu, whose title is ignored at runtime.
    item = [mainMenu addItemWithTitle:@"Apple" action:NULL keyEquivalent:@""];
    submenu = [[[NSMenu alloc] initWithTitle:@"Apple"] autorelease];
    [NSApp performSelector:@selector(setAppleMenu:) withObject:submenu];
    CreateApplicationMenu(submenu);
    [mainMenu setSubmenu:submenu forItem:item];

    [NSApp setMainMenu:mainMenu];
    }

    int main(int argc, char *argv[])
    {
        // Creates an autorelease pool
        NSAutoreleasePool* pool = [[NSAutoreleasePool alloc] init];

        // Loads the application
        NSApplicationLoad();

        // Creates a simple window
        NSRect MainWindowRect = NSMakeRect(300, 300, 300, 500);

        NSWindow* MainWindow = [[NSWindow alloc] initWithContentRect: MainWindowRect
          styleMask: NSTitledWindowMask | NSClosableWindowMask |
    NSMiniaturizableWindowMask | NSResizableWindowMask
            backing: NSBackingStoreBuffered
              defer: NO];

        [MainWindow orderFrontRegardless];

        // Creates the application object

        [NSApplication sharedApplication];

        CreateMenu();

        // Enters main message loop

        [NSApp run];

        // Call release method from object pool
        [pool release];

        return 0;
    }

    --
    Felipe Monteiro de Carvalho
previous month january 2008 next month
MTWTFSS
  1 2 3 4 5 6
7 8 9 10 11 12 13
14 15 16 17 18 19 20
21 22 23 24 25 26 27
28 29 30 31      
Go to today