| Starting with Mac OS X 10.2, aka Jaguar, a new set of APIs has been introduced to deal with all the User Interface elements (menus, windows, controls, etc.). Although these APIs are C-based, they are object-oriented in the spirit, and all the "classes" derive from the base class which is HIObject. HIView is a class which is providing all the functionalities, and more, previously offered by the Control Manager.
From a programming point of view, HIViews are Controls, and Controls are HIViews, which means that all the Control Manager APIs can be used on HIViews, and the HIView APIs can be used on Controls. The compiler will accept HIViewRefs and ControlRefs as the same.
This technote will provide some clarification on the similar APIs and similar behaviors and will be of interest to all the developers who wish to base their program's User Interface on the new HIToolbox model. Some behaviors depend on the compositing attribute of the owning window so the distinction is being made in those cases.
All the comparisons are valid only on Mac OS X 10.2 and later. [Oct 29, 2003] |
Similar APIsBack to top
GetRootControl/CreateRootControl vs. HIViewGetRoot Regardless of whether the kWindowCompositingAttribute is set on the window, HIViewGetRoot always returns the Root View of the window which represents the total structure of the window and which is where all the standard window widgets (close, minimize, zoom buttons, resize control, and so on) live.
If the kWindowCompositingAttribute is set on the window, CreateRootControl returns an errRootAlreadyExists error, and GetRootControl actually returns the Content View of the window which might also be found using HIViewFindByID :
Listing 1. Getting the Content View.
|
GetRootControl(theWindow, &theContentView);
// or
HIViewFindByID(HIViewGetRoot(theWindow),
kHIViewWindowContentID,
&theContentView);
|
If the kWindowCompositingAttribute is not set on the window, GetRootControl returns the Root Control (not to be confused with the Root View, see above) which is a child of the window's Content View, but only if CreateRootControl had been called previously, either directly or implicitly though any call to a CreateFooControl API, else GetRootControl returns an errNoRootControl error. Back to top
EmbedControl vs. HIViewAddSubview Apart from the fact that the parameters parent/child are reversed, those APIs are not interchangeable. HIViewAddSubview can be used with container controls or HIVIiews which have been created outside of a window (usually passing NULL as window parameter in the creation API), whereas EmbedControl will only succeed if the container control is already embedded in a window (compositing or not). If the container control is not embedded in a window, EmbedControl will return an errInvalidWindowRef error. Since the compositing model and the HIView model have been designed in concert, it is advised to use EmbedControl only in non-compositing windows and HIViewAddSubview only in compositing windows. Back to top
GetSuperControl vs. HIViewGetSuperview There is no conceptual difference between those two APIs except for the fact that the parameters/return values are set up in a different way. If the window is compositing, those APIs always return the same parent. If the window is non-compositing, the only exception to that rule is to ask for the parent of the Root Control: GetSuperControl returns a NULL parent and a paramErr error, whereas HIViewGetSuperview returns a view whose parent is the Root View. Back to top
ShowControl/HideControl vs. HIViewSetVisible In a non-compositing window, all three APIs will cause immediate drawing. In a compositing window, all three APIs will invalidate the control/view region. Back to top
SetControlVisibility vs. HIViewSetVisible In a compositing window, both APIs will invalidate the control/view region, regardless of the value of the last parameter (Boolean inDoDraw ) of SetControlVisibility . In a non-compositing window, HIViewSetVisible will cause immediate drawing and so will SetControlVisibility unless its last parameter (Boolean inDoDraw ) is set to false . Back to top
IsControlVisible vs. HIViewIsVisible Those two APIs are identical. Back to top
GetControlBounds vs. HIViewGetBounds Apart from the fact that GetControlBounds returns a QuickDraw Rect whereas HIViewGetBounds returns a HIRect (which is a Core Graphics CGRect ), the behavior of these APIs depend on the compositing attribute of the window: if the window is non-compositing, both APIs work in the window's coordinate system whereas, if the window is compositing, GetControlBounds works in the view's parent's coordinate system and HIViewGetBounds works in the view's coordinate system (thus, unless the HIView's origin has been changed with HIViewSetBoundsOrigin (which most developers won't need), the HIRect 's origin will always be 0,0.). Back to top
GetControlBounds vs. HIViewGetFrame Apart from the fact that GetControlBounds returns a QuickDraw Rect whereas HIViewGetBounds returns a HIRect (which is a Core Graphics CGRect ), the behavior of these APIs depend on the compositing attribute of the window: if the window is non-compositing, both APIs work in the window's coordinate system whereas, if the window is compositing, they both work in the view's parent's coordinate system.
If the parent of the view is the window's Content View, then GetControlBounds and HIViewGetFrame will return the same rectangle except for the format difference. Back to top
SetControlBounds vs. HIViewSetFrame Apart from the fact that SetControlBounds accepts a QuickDraw Rect parameter whereas HIViewSetFrame accepts a HIRect parameter (which is a Core Graphics CGRect ), the behavior of these APIs depend on the compositing attribute of the window: if the window is non-compositing, both APIs work in the window's coordinate system whereas, if the window is compositing, they both work in the view's parent's coordinate system.
If the parent of the view is the window's Content View, then SetControlBounds and HIViewSetFrame will set the view/control to the same rectangle except for the format difference. Back to top
MoveControl/SizeControl vs. HIViewSetFrame Apart from the fact that MoveControl and SizeControl accept SInt16 parameters (QuickDraw coordinates) whereas HIViewSetFrame accepts a HIRect parameter (which is a Core Graphics CGRect ), the behavior of these APIs depend on the compositing attribute of the window: if the window is non-compositing, both APIs work in the window's coordinate system whereas, if the window is compositing, they both work in the view's parent's coordinate system
If the parent of the view is the window's Content View, then MoveControl and HIViewSetFrame will place the view/control at the same point except for the format difference. Back to top
MoveControl vs. HIViewPlaceInSuperviewAt Apart from the fact that MoveControl accepts SInt16 parameters (QuickDraw coordinates) whereas HIViewPlaceInSuperviewAt accepts float parameters (Core Graphics coordinates), the behavior of these APIs depend on the compositing attribute of the window: if the window is non-compositing, both APIs work in the window's coordinate system whereas, if the window is compositing, they both work in the view's parent's coordinate system.
If the parent of the view is the window's Content View, then MoveControl and HIViewPlaceInSuperviewAt will place the view/control at the same point except for the format difference. Back to top
FindControl/FindControlUnderMouse vs. HIViewGetViewForMouseEvent It is much easier and highly recommended to let the window's StandardHandler (adding the kWindowStandardHandlerAttribute in the WindowAttributes parameter of CreateNewWindow ) deal with the mouse events, but if you must... HIViewGetViewForMouseEvent allows the parent views to catch clicks on their subviews; there is a similar mechanism for FindControl and FindControlUnderMouse involving SetControlSupervisor but it's NOT recommended since it is very complex to implement a fully correct behavior. Apart from those remarks and the fact that the parameters and return values are not set up the same way for those 3 APIs, it's also worthwhile to note that FindControl and FindControlUnderMouse start at the window level, whereas HIViewGetViewForMouseEvent can start at any level in the HIView hierarchy. Back to top
TestControl vs. HIViewGetPartHit Apart from the fact that the parameters and return values are not set up the same way, those APIs are similar. Back to top
TrackControl/HandleControlClick vs. HIViewClick While TrackControl and HandleControlClick are using the same approach to dealing with clicks _ passing them, with or without modifiers, to the control implementation code, with or without a control action call back, and then returning the ControlPartCode to the caller code for it to act upon _ HIViewClick passes the full event to the HIView and let it deal entirely with it. There is no call back since, if you want a different (or just augmented) behavior than standard, you can just override the appropriate message (kEventControlTrack ), and if you have to act upon the way the mouse button was released (in a valid part or nor), you simply override the appropriate message (kEventControlHit ). If you were using a callback by passing a ControlActionUPP to TrackControl or HandleControlClick and wish to now use HIViewClick but prefer to keep this callback code (instead of using the overriding mechanism described above), you can associate this ControlActionUPP with the control via SetControlAction . Back to top
GetBestControlRect vs. HIViewGetSizeConstraints Those APIs complement each other since the best (or optimal) bounds might be different than the minimum or maximum bounds that the control/view can support, and all these informations may be needed by the container to handle a size adjustment. Back to top
SetKeyboardFocus vs. HIViewSetFirstSubViewFocus/HIViewSetNextFocusSetKeyboardFocus is active while HIViewSetFirstSubViewFocus and HIViewSetNextFocus are passive. When you call SetKeyboardFocus , you set the focus to the specified control right away, whereas when you call HIViewSetFirstSubViewFocus , you just request that, whenever, later, the focus will be advanced to the specified parent view, the focus should be set at that time to the specified subview. When you call HIViewSetNextFocus , you just request that, whenever, later, the focus will be lost by the specified view, it will be advanced to the specified next view.
Back to top
AdvanceKeyboardFocus/ReverseKeyboardFocus vs. HIViewAdvanceFocus First, AdvanceKeyboardFocus and ReverseKeyboardFocus are looking for the next focusable element at the window level whereas HIViewAdvanceFocus is looking for the next focusable element within the specified view hierarchy (which can also be the window level if you pass the root view or content view of the window). The next focusable element is determined in both cases by its graphic position and its hierarchical level unless there has been a specific focus request (HIViewSetFirstSubViewFocus and/or HIViewSetNextFocus ). Second, HIViewAdvanceFocus can both advance and reverse depending on the EventModifiers parameter.
Third, AdvanceKeyboardFocus and ReverseKeyboardFocus do not work in compositing windows, you must use HIViewAdvanceFocus instead.HIViewAdvanceFocus may be enhanced in the future to allow tabbing between groups of controls based on the state of the EventModifiers parameter. Back to top
GetControlByID vs. HIViewFindByID Those APIs are similar apart from the fact that GetControlByID starts the search at the window level whereas HIViewFindByID can start the search at any hierarchical level. Calling HIViewFindByID starting in the root view or content view of the window will give the same result as calling GetControlByID . Back to top
GetControlFeatures vs. HIViewGetAttributesGetControlFeatures returns the features (as in kControlSupportsEmbedding , kControlSupportsFocus , etc.) of the control/view, whereas HIViewGetAttributes returns the attributes of the control/view (as in kHIViewSendCommandToUserFocus which is the only attribute defined in Mac OS X 10.2). Thus, typically, calling GetControlFeatures on the content view would return 0x20042 (supports embedding, idle, and getregion), whereas HIViewGetAttributes would return 0x0 . More attributes will probably be defined in later system releases.
Note:
In Mac OS X 10.3, a new API, HIViewGetFeatures , has been introduced. It returns the same features as GetControlFeatures except for those which have no or little meaning for HIViews. The features which have meaning have been renamed (ie. kHIViewAllowsSubviews instead of kControlSupportsEmbedding ).
|
Back to top
Similar BehaviorsBack to top
DisposeControl vs. CFRelease Since all HIViews are derived from the class HIObject which is CF-based, you can now use the CFRetain and CFRelease (among others) APIs on your HIViews. That means that you can free any HIView with either CFRelease or DisposeControl . It may be more readable to continue to use DisposeControl . In most cases, you don't have to call CFRelease or DisposeControl yourself since all Controls/HIViews will be freed when you dispose the window with, by the way, either DisposeWindow or CFRelease since it's also an HIObject . Back to top
CreateCustomControl vs. HIObjectCreate It is strongly advised to adopt the HIView model to create custom controls. It's easier and the way of the future. Back to top
SetControlSupervisor vs. kEventControlInterceptSubviewClick Those mechanisms allow an embedder control to respond to mouse-down events occurring in its embedded controls. For example, the radio group control intercepts all the clicks on the embedded radio controls so that it can better deal with the value setting/resetting of its children. SetControlSupervisor is an API, whereas kEventControlInterceptSubviewClick is just a Carbon Event message that you install on the embedder control/view. The latter mechanism is strongly preferred in Carbon. Back to top
CountSubControls/GetIndexedSubControl vs. HIViewGetFirstSubview/HIViewGetNextView or HIViewGetLastSubview/HIViewGetPreviousView All those APIs can be used to iterate over subcontrols or subviews.
|