As the property frame itself manages some state global to all property pages, the IPropertyPageSite pointer passed to IPropertyPage::SetPageSite provides each page with access to this information:
interface IPropertyPageSite : IUnknown
{
HRESULT OnStatusChange(DWORD flags);
HRESULT GetLocaleID(LCID *pLocaleID);
HRESULT GetPageContainer(IUnknown **ppUnk);
HRESULT TranslateAccelerator(LPMSG pMsg);
};
The first global state in the frame is the locale identifier that the client originally passed to OleCreatePropertyFrame. A property page retrieves this identifier through IPropertyPageSite::GetLocaleID and uses it to determine the language of the text returned through IPropertyPage::GetPageInfo and the localization of the controls in the page itself.
The other important global state is whether or not the Apply Now button is enabled. Initially the button is disabled. To enable it, the page first calls IPropertyPageSite::OnStatusChange, in response to which the frame calls IPropertyPage::IsPageDirty. If the latter function returns S_OK, the frame enables the button, allowing calls to IPropertyPage::Apply. Through this interaction, the user knows when there is a change to make permanent. It is the responsibility of a page to call OnStatusChange when changes occur and to implement its own IsPageDirty member properly. OnStatusChange itself takes either the flag PROPPAGESTATUS_DIRTY to indicate that a change has occurred or the flag PROPPAGESTATUS_VALIDATE to indicate that now is a good time to perform data validation.
Of the other two functions, GetPageContainer currently has no defined functionality. It could be used to retrieve an interface for the property sheet frame as a whole, but as yet the frame has no defined interface, so this function will always fail. TranslateAccelerator, on the other hand, works in conjunction with the function of the same name in IPropertyPage. The protocol here is that the frame first notifies the current page of a keystroke by calling IPropertyPageFrame::TranslateAccelerator. If the page does not want to override a key that the frame usually processes, it should call the page site's TranslateAccelerator for that key and then process it normally. In short, the site gives the page the ability to preprocess keys before eating them.