Is there a getControlFromId?

Discussion in 'Mac Programming' started by resander, May 10, 2008.

  1. resander macrumors newbie

    Joined:
    Apr 12, 2008
    #1
    In Windows, a dialogbox is a window containing control gui
    elements that are uniquely identified by int constants.
    The int constants are typically generated by the GUI
    builder/editor but can also be specified in programs.

    An important API function finds a control handle
    from a control (from MSDN doc):

    GetDlgItem

    The GetDlgItem function retrieves a handle to a control
    in the specified dialog box.

    HWND GetDlgItem(
    HWND hDlg, // handle to dialog box
    int nIDDlgItem // control identifier
    );
    Parameters
    hDlg
    [in] Handle to the dialog box that contains the control.
    nIDDlgItem
    [in] Specifies the identifier of the control to be retrieved.

    Is there a corresponding function in Cocoa? OR how would
    one find the handle of a Cocoa control in a Cocoa
    dialogbox?
     
  2. robbieduncan Moderator emeritus

    robbieduncan

    Joined:
    Jul 24, 2002
    Location:
    London
    #2
    The simplest way is to add an outlet for that control and connect it in IB.

    All controls do have an Integer tag which you can retrieve from a control via the obvious method. The tags can be searched by the containing view. As all NSWindows contains a single top level view there is a clear solution which is obvious in the documentation. But there is no requirement for tags to be unique. Unless you set them all yourself they'll all be 0.

    I would suggest you stop thinking about how you would do things in an archaic paradigm (Win32) and simply learn to use Cocoa correctly.
     
  3. Eraserhead macrumors G4

    Eraserhead

    Joined:
    Nov 3, 2005
    Location:
    UK
    #3
    Definitely, if you haven't already I suggest you pre-order Aaron Hillegass' book (the new edition for Leopard is due out in a week).

    Just to note, it is basically essential for any Mac application to follow the user interface guidelines. On Windows it may be acceptable to have a mish-mash of different interfaces, but it isn't so on the Mac, you need to make your application work in a similar way to other applications to make the learning curve as small as possible.
     
  4. resander thread starter macrumors newbie

    Joined:
    Apr 12, 2008
    #4
    Many thanks for your replies.

    I will buy Aaron Hillegass' book from Amazon when it becomes available. I have looked for other books, but most of them are old and probably out of date, so I have decided against buying any.

    I am familiar with the Apple user interface guidelines and other guidelines too, so my interfaces are clean enough to be let into the Mac world.

    As a ragged old Windowser with a lot (200K lines) of existing Win32 code to convert I need to find and exploit conceptual and real one-to-one correspondencies between Win32 and Cocoa and as far as possible, just mechanically convert from Win32 to Cocoa. There is not enough time and resources to start from scratch. A listbox is a listbox and it should not be difficult to make it show on the screen using any GUI product (even the archaic ones!)

    Many people converting from Windows would want to ask similar questions and I think most would face the same steep Cocoa learning curve as I do. A convert-from-Windows forum would be useful.

    I am familiar with other GUIs, e.g. Mosaic, Java's, Javascript's, QT and I have been able to get off the ground within a day or two of reading their documentation. Not so with Cocoa.

    Cocoa supports the same GUI elements as other GUI products and yet it is a lot harder to learn. Why is this?
     
  5. robbieduncan Moderator emeritus

    robbieduncan

    Joined:
    Jul 24, 2002
    Location:
    London
    #5
    I would say it's significantly easier to learn as long as you try and use it as Cocoa, not as Win32. Cocoa is a generation newer than the paradigm you are trying to use and the API is designed from the ground up to support an elegant form of programming that even asking how to find an element by ID (or tag in Cocoa terms) tells me you are simply ignoring.

    You are basically trying to write an elegant novel in English by converting at a word-to-word, not meaning-to-meaning, level from French.
     
  6. Gelfin macrumors 68020

    Gelfin

    Joined:
    Sep 18, 2001
    Location:
    Denver, CO
    #6
    I'm also a longtime professional Windows programmer who picked up Cocoa programming on the side a while back.

    I can confirm what the other posters are trying to tell you: your assumption that building a Cocoa application must have an underlying 1:1 correspondence with the things you have done in Win32 is exactly what is holding you back and making Cocoa seem hard. I understand the time and resource constraints all too well, but you're doing yourself no favors by trying to shoehorn assumptions about your existing code base into Cocoa prematurely.

    What's likely going to happen is that when the Cocoa approach clicks with you, you will realize you haven't been separating functional code from UI code nearly as well as you thought you had. XCode/IB may be the first development platform you've ever encountered where that distinction is more than just academic.
     
  7. resander thread starter macrumors newbie

    Joined:
    Apr 12, 2008
    #7
    In the world of the Win32 API, getting a control handle from a control ID is essential and that is the reason I asked the question.

    Consider a GUI with a list control showing geographical region names and other controls showing delivery information for these regions. When the user
    selects a region name in the list control the other controls should immediately reflect the corresponding delivery information. In Windows, the event handler for 'selection-changed' in the list control has to know about the handles of the other controls in order to be able to change them. To get a handle the api function GetDlgItem has to be called with the ID as a parameter. Does your response imply that things are done differently in Cocoa for this example, or does it imply I should not have asked such an elementary question.

    Language is for communication and even if I translate 'egg and chips' word for word to the dismay of a French waiter he is likely to understand it and bring the food. It would work and I would not go hungry. I might have some difficulty ordering 'toad in the hole' though as a beginner of the French language, so that would have to wait until I have mastered the foreign tongue which, like Cocoa, is likely to take some time.
     
  8. Eraserhead macrumors G4

    Eraserhead

    Joined:
    Nov 3, 2005
    Location:
    UK
    #8
    I'm sure you can do it in Cocoa. You can use probably viewWithTag: to get the subview with a specific tag, the thing is that no-one ever codes Cocoa like that.

    You need to rewrite the UI code from the ground up. Lay out the interface in Interface Builder and use IBOutlet's to connect to the interface elements. Then call IBActions from the interface elements to call the cross platform logic code.

    I think you want to write Arabic, but you are insisting on writing left to right, whereas Arabic is written right to left would be a better analogy.
     
  9. Catfish_Man macrumors 68030

    Catfish_Man

    Joined:
    Sep 13, 2001
    Location:
    Portland, OR
    #9
    IBOutlets are what you would use for this case. You just hook the outlet up to the control, and then treat it like any other ivar.

    So in your code you have something like...

    Code:
    @interface Controller
    {
        IBOutlet NSTextField label;
    }
    
    //See NSTableView delegate documentation
    - (void)tableViewSelectionDidChange:(NSNotification *)aNotification;
    @end
    
    @implementation Controller
    - (void)tableViewSelectionDidChange:(NSNotification *)aNotification
    {
        /*
            Get a string to set the label to any way you choose; getting the selected row index would be [[aNotification object] selectedRow] for example
        */
        [label setStringValue: theStringWeGot];
    }
    @end
    
    Then in interface builder you just hook up your table delegate and the label outlet to an instance of Controller :)

    This is the manual non-bindings way. Bindings change the paradigm even more and use less code, so I'm not going to try to explain them at the moment. There's lots of tutorials.
     
  10. resander thread starter macrumors newbie

    Joined:
    Apr 12, 2008
    #10
    Thanks for the advice, which I think might be useful to other people contemplating converting Windows programs. I still think a forum addressing migration from Windows would be useful.

    I started by making an inventory of Cocoa features that correspond closely to what I am used to in Windows and that am using frequently. There would appear to be a near one-to-one correspondence. If this turns out to be true and IF it is quicker to convert one-to-one and the converted result would look and behave exactly like a Cocoa GUI that has been developed using the Interface Builder, then I would be pragmatic and use the one-to-one approach. This is a one-off conversion of very large programs written several years ago, so I am not too worried about it being Cocoa with impurities.

    I will continue to develop Windows programs. It would make sense to structure the GUI of these so that conversion to pure Cocoa would be easier. At this stage I am not able to suggest any rules or design patterns for this, but I am sure that competent Windows and Cocoa programmers will be able to do so at the drop of a hat.
    Contributions welcome.

    In the meantime I shall continue practising writing Arabic backwards!
     

Share This Page