|
Chapter 4 Windows
1 Window Update
1. 可以调用ShowWindow和HideWindow来显示/隐藏窗口。
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相关联起来,所调用的函数为SetWindowProperty和GetWindowProperty。
SetWindowProperty的原型如下:
OSStatus SetWindowProperty( WindowRef window,
PropertyCreator propertyCreator,
PropertyTag propertyTag,
UInt32 propertySize,
void * propertyBuffer );
| 1. PropertyCreate propertyCreator:Application的Signature,四个Char组成。可以传0
2. PropertyTag propertyTag:四个Char的Property的标记
3. Uint32 propertySize:property的大小(字节数)
4. Void *propertyBuffer:指向实际数据
GetWindowProperty的原型如下:
OSStatus GetWindowProperty( WindowRef window,
PropertyCreator propertyCreator,
PropertyTag propertyTag,
UInt32 bufferSize,
UInt32 * actualSize,
void * propertyBuffer );
| 1. PropertyCreate propertyCreator:Application的Signature,四个Char组成。可以传0
2. PropertyTag propertyTag:四个Char的Property的标记
3. Uint32 propertySize:property的大小(字节数)
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 );
|
如何将Structure和window相关联呢?
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,这本书我越看下去越觉得烂。。。。) |
|
|