Mac OS X Programming讀書筆記4 - Windows

ATField發表於2007-03-06

Chapter 4 Windows

1 Window Update

1.     可以呼叫ShowWindowHideWindow來顯示/隱藏視窗。

2.     DrawString作用是在當前Graphics Pen位置顯示字串

3.     MoveTo移動當前Graphics Pen

Window繪圖的時候傳送Update事件:

EventTypeSpec windowEvent = { kEventClassWindow,

kEventWindowDrawContent };

 

下面程式碼安裝一個Update事件處理函式:

EventTargetRef target;

 

EventHandlerUPP handlerUPP;

EventTypeSpec windowEvent = { kEventClassWindow,

       kEventWindowDrawContent };

 

target = GetWindowEventTarget( window );

handlerUPP = NewEventHandlerUPP( WindowEventHandler );

InstallEventHandler( target, handlerUPP, 1, &windowEvent,

       (void *)window, NULL );

 

Update事件處理函式可以這麼寫:

pascal OSStatus WindowEventHandler( EventHandlerCallRef handlerRef,

       EventRef event, void *userData)

{

       OSStatus result = eventNotHandledErr;

       UInt32 eventKind;

       WindowRef window;

       window = ( WindowRef )userData;

       eventKind = GetEventKind( event );

       if ( eventKind == kEventWindowDrawContent )

       {

              UpdateWindow( window );

       }

       return result;

}

 

UpdateWindow中必須首先呼叫SetPortWindowPort用來指定當前繪圖所用的Port(這名字還真怪)。Port是用來定義一個繪圖環境的(類似Windows中的裝置上下文DC)。每個視窗都有一個Port。螢幕也被認為是一個Port。如果不呼叫SetPortWindowPort,程式的行為將無法預測。

void UpdateWindow( WindowRef window )

{

       SetPortWindowPort( window );

       // code to draw the contents of the window goes here

}

 

一個完整的UpdateWindow示例如下:

void UpdateWindow( WindowRef window )

{

       FMFontFamily fontFamily;

 

       SetPortWindowPort( window );

 

       fontFamily = FMGetFontFamilyFromName( "/pTimes" );

       TextFont( fontFamily );

       TextFace( bold + italic );

       TextSize( 24 );

       MoveTo( 30, 60 );

       DrawString( "/pThis is drawn from code!" );

}

 

/p表示字串為一個Pascal String

2 Associating Information with Windows

Mac OS X中可以把資料和Window相關聯起來,所呼叫的函式為SetWindowPropertyGetWindowProperty

SetWindowProperty的原型如下:

OSStatus SetWindowProperty( WindowRef window,

       PropertyCreator propertyCreator,

       PropertyTag propertyTag,

       UInt32 propertySize,

       void * propertyBuffer );

1.     PropertyCreate propertyCreatorApplicationSignature,四個Char組成。可以傳0

2.     PropertyTag propertyTag:四個CharProperty的標記

3.     Uint32 propertySizeproperty的大小(位元組數)

4.     Void *propertyBuffer:指向實際資料

GetWindowProperty的原型如下:

OSStatus GetWindowProperty( WindowRef window,

       PropertyCreator propertyCreator,

       PropertyTag propertyTag,

       UInt32 bufferSize,

       UInt32 * actualSize,

       void * propertyBuffer );

1.     PropertyCreate propertyCreatorApplicationSignature,四個Char組成。可以傳0

2.     PropertyTag propertyTag:四個CharProperty的標記

3.     Uint32 propertySizeproperty的大小(位元組數)

4.     Uint32 *actualSize:實際大小,可傳NULL

5.     Void *propertyBuffer:指向實際資料

舉例如下:

UInt32 windowNumber = 99;

WindowRef window;

UInt32 theNumber;

...

err = CreateWindowFromNib( nibRef, CFSTR("MainWindow"), &window );

...

// associate the data (99) in variable windowNumber with a window:

SetWindowProperty( window, 0, 'test', sizeof( UInt32 ),

       &windowNumber );

...

// retrieve the data (99) from the window and store it in theNumber:

GetWindowProperty( window, 0, 'test', sizeof( UInt32 ),

       NULL, &theNumber );

 

如何將Structurewindow相關聯呢?

1.     定義下面這個Structure

typedef struct

{

       UInt32 number;

       Str255 string;

} WindowData, **WindowDataHandle;

 

2.     建立一個Handle,相當於分配一塊記憶體,大小為sizeof(WindowData)

WindowDataHandle windDataHndl;

windDataHndl = ( WindowDataHandle )NewHandle( sizeof( WindowData ) );

 

3.     Handle所指向的資料賦值。注意WindowDataHandle是指標的指標(為什麼是指標的指標呢?因為NewHandle建立的是一塊可重定位的記憶體)

UInt32 theNumber = 5;

(**windDataHndl).number = theNumber;

 

Str255 theString = "/pCopyright (c) 2001"

numBytes = theString[0] + 1;

BlockMoveData( theString, (**windDataHndl).string, numBytes );

 

Str255本質上其實是一個陣列,最多可以Hold255個字元。第一個元素是String大小(Pascal String正是這樣),所以theString[0] + 1可以獲得實際大小

4.     之後呼叫SetWindowProperty(我覺得這裡似乎錯了,應該是sizeof(WindowDataHandle),而不是sizeof(WindowData),待驗證)

SetWindowProperty(window, 0, 'test', sizeof(WindowData),

       &windDataHndl);

 

5.     如果要獲得Property,可以呼叫GetWindowProperty(我覺得這裡似乎錯了,應該是sizeof(WindowDataHandle),而不是sizeof(WindowData),待驗證)

GetWindowProperty( window, 0, 'test', sizeof( WindowData ),

       NULL, &windDataHndl );

 

BTW,這本書我越看下去越覺得爛。。。。)

 

相關文章