Mac OSX Build and Run!

OSX上でのプログラミングの初歩について、情報共有ができればと思います。

可愛い実

散歩してたら小さくて赤い可愛い実がありました。何の実なのか??P1000021.jpg

スポンサーサイト

Cocoa Fundationクラス

以下はCocoa Fundationクラスの備忘録です。

Fundationクラス


[値オブジェクトValue Objects]値用のオブジェクト指向ストレージ
さまざまな種類のデータをカプセル化し、そのデータへのアクセスと、データに対する各種の操作を可能とする。
・NSDataクラス はバイトストリーム用
・NSValue と NSNumber クラスはスカラー値の配列用
・NSDate、NSCalendarDate、及び NSTimeZone クラスは日付と時刻を格納



[文字列 NSString]文字列用の値オブジェクト
特定のエンコーディングでのヌルで終了するバイト配列
・多数のエンコーディングの間で文字列のエンコーディングを変換。
・文字列の検索、結合、比較のメソッド
・ファイルシステムパスの操作のメソッド
・NSScanner オブジェクトはNSString オブジェクトの数字と単語を解析。
・NSCharacterSet は、NSString および NSScanner のさまざまなメソッドによって使われる文字セットを表わす



[コレクション]値オブジェクトを特定の順序付けスキームで格納し、供給。
・NSArray はゼロから始まるインデックスを使用
・NSDictionary はキーと値のペアを使用
・NSSet は順序のないオブジェクトストレージ
・NSEnumeratorはコレクションの要素を順序どおりにアクセス。



[オペレーティングシステムサービス]
オペレーティングシステムの様々な低レベルサービスにアクセス。
・NSProcessInfoはアプリケーションが動作する環境を問い合わせ。
・NSHost はネットワーク上のホストシステムの名前とアドレスを得る。
・NSTimer オブジェクトはほかのオブジェクトに一定の間隔でメッセージを送信。
・NSRunLoop はアプリケーションや他の種類のプログラムの入力ソースを管理。
・NSUserDefaults は、グローバルな(ホスト単位の)デフォルト値とユーザ単位のデフォルト値(環境設定)からなるシステムデータベースとのプログラムインタフェースを提供

○ファイルシステムと URL
・NSFileManager はファイルの作成、名前の変更、削除、移動といったファイル操作。
・NSFileHandle は低レベルのファイル操作(ファイル内でのシーク等)
・NSBundle はバンドルに格納されているリソースを見つけて、その一部(nib ファイルやコードなど)を動的にロード。
・NSURL と NSURLHandle を使うと、データの URL ソースの表示、アクセス、管理ができる。

○プロセス間通信
・クラスのほとんどは、さまざまな種類のシステムポート、ソケット、ネームサーバを表す。
・低レベルの IPC を実装するのに役立つ。
・NSPipe は BSD パイプでプロセス間の単方向通信チャンネルを表す。

○スレッド化とサブタスク
・NSThread により、マルチスレッドのプログラムを作成できる。
・ロッククラスにより、競合するスレッドのプロセスリソースへのアクセスを制御するメカニズムが使用できる。
・NSTask は、作業を実行する子プロセスを生成し、その進捗状況を監視できる。



表示色数を得る。 System color

FBの関数で表示色数を得る。

window 1,"System color"

print 2^(system(_crntDepth)-8)" color"//アルファーチャンネルを除く。
print system(_crntDepth)" bit color"//フルカラーなら8bitx4byte(a,R,G,B)

do
handleevents
until gFBquit

FB Tips : OSXで拡張子を有効にする方法

FutureBASIC Tips OSXで拡張子を有効にする方法

FB でファイルを作成した場合は、ファイルにリソース情報としてクリエータとタイプ情報が付加されています。指定が無い場合には、クリエータ:TEXTとタイプ:ttxtとなります。OSXではクリエーター情報がある場合には拡張子が有効とならず.htmlとしてもテキストエデターとアプリケーションが対応してしまう問題があります。
DEF OPEN ""として逆に指定を消すことができればいいのですがこれはDEF OPEN "TEXTttxt"と同じ結果になってしまいます。

【OSXで拡張子を有効にする方法】

DEF OPEN "-------"として該当するクリエータやタイプに一致しない様に指定することで、OSX上で拡張子が有効になります。例えば.htmlのファイルならサファリのアイコンになります。

他にも良い方法があるかとは思いますが、ご参考まで。
by lightchaos

Javaアプレット

Xcodeを使ってMandelbrotのJavaアプレットを動かしてみました。

Javaは計算→表示用のアプレットソースコードが公開されていることが多いのでコードを入手したら、後はコピペすれば直ぐ試せるのが利点です。

Mandelbrot.jpg


尚、このサンプルはねこいりねこさんのところから頂いて来ました。

carbon core フレームワーク一覧

以下はcarbon core フレームワーク一覧の一部です。

まずはMacTypes.hを見よう!
File: CarbonCore/MacTypes.h
Contains: Basic Macintosh data types.




File: CarbonCore/AIFF.h
Contains: Definition of AIFF file format components.

File: CarbonCore/Aliases.h
Contains: Alias Manager Interfaces.

File: CarbonCore/AVLTree.h
Contains: Interfaces for AVL balanced trees.

File: CarbonCore/CarbonCore.h
Contains: Master include for CarbonCore private framework

File: CarbonCore.r
Contains: Master include for CarbonCore private framework

File: CarbonCore/CodeFragments.h
Contains: Public Code Fragment Manager Interfaces.

File: CodeFragments.r
Contains: Public Code Fragment Manager Interfaces.

File: CarbonCore/Collections.h
Contains: Collection Manager Interfaces

File: Collections.r
Contains: Collection Manager Interfaces

File: CarbonCore/Components.h
Contains: Component Manager Interfaces.

File: Components.r
Contains: Component Manager Interfaces.

File: CarbonCore/ConditionalMacros.h
Contains: Set up for compiler independent conditionals

File: ConditionalMacros.r
Contains: Set up for compiler independent conditionals

File: CarbonCore/DateTimeUtils.h
Contains: International Date and Time Interfaces (previously in TextUtils)

File: CarbonCore/Debugging.h
Contains: Macros to handle exceptions and assertions.

File: CarbonCore/Devices.h
Contains: Device Manager Interfaces.

ファインターを消すスクリプト

たまたま見つけた「ファインターを消すスクリプト」を何気なくOSXで起動すると、デスクトップのファイル、ホルダー、ドライブの全て消え、「ファインターをスタートするスクリプト」も全て消え去り、壁紙だけが表示しただけとなったので少し慌ててしまいました。(汗)
しばし、目が点!

ま、Dockからファインダーが起動できて良かった。(笑)当たり前なことだけど、ファインダーの大切さを今更実感じたlightchaosでした。何やってるんだろ!?なんてね。

イベント削除

ToolBoxでは以下の様に指定されます。

FlushEvents
システムイベントキューからローレベルのイベントを削除します。

void FlushEvents (
EventMask whichMask,
EventMask stopMask
);

イベントマスク定数は以下の通りです。
enum {
mDownMask = 1 << mouseDown,
mUpMask = 1 << mouseUp,
keyDownMask = 1 << keyDown,
keyUpMask = 1 << keyUp,
autoKeyMask = 1 << autoKey,
updateMask = 1 << updateEvt,
diskMask = 1 << diskEvt,
activMask = 1 << activateEvt,
highLevelEventMask = 0x0400,
osMask = 1 << osEvt,
everyEvent = 0xFFFF
};
typedef UInt16 EventMask;

Cocoa 用構造体

NSGeometry.hに以下の基本的な構造体があります。Carbonでは値が整数で表現されていましたが、Cocoaでは浮動小数点で指定されています。

typedef struct _NSPoint {
float x;
float y;
} NSPoint;

typedef struct _NSSize {
float width; /* should never be negative */
float height; /* should never be negative */
} NSSize;

typedef struct _NSRect {
NSPoint origin;
NSSize size;
} NSRect;


☆値を構造体に設定するには以下の関数があります。
FOUNDATION_STATIC_INLINE NSPoint NSMakePoint(float x, float y) {
NSPoint p;
p.x = x;
p.y = y;
return p;
}

FOUNDATION_STATIC_INLINE NSSize NSMakeSize(float w, float h) {
NSSize s;
s.width = w;
s.height = h;
return s;
}

FOUNDATION_STATIC_INLINE NSRect NSMakeRect(float x, float y, float w, float h) {
NSRect r;
r.origin.x = x;
r.origin.y = y;
r.size.width = w;
r.size.height = h;
return r;
}

☆使用例
- (id)initWithFrame:(NSRect)frame {
[super initWithFrame:frame];
// First, we set default values for the various parameters.
center.x = frame.size.width / 2;
center.y = frame.size.height / 2;

Classic Events+nib

オリジナルのプログラムはMac techからの転載です。
Classic Eventsとリソースファイル組み合わせでしたが、Classic Events+nibとしています。このサンプルプロジェクトはCW用からXcode用にコンバートしたものです。当初、nibファイルではウインドウ内でイベントが生じないので原因を調べたところInterface builderで標準イベント処理を行わない様に設定する必要があることが分かりました。
(完全非保証のコードです。自己責任でのみ使用可能です。)

// *******************************************************************************************
// LowEvents.c CLASSIC EVENT MODEL
// *******************************************************************************************
//
// This program contains a main event loop function, together with subsidiary functions which
// perform nominal handling only of low-level and Operating System events. It opens a window
// in which the types of all received low-level and Operating System events are displayed. It
// terminates when the user clicks the window's close box.
//
// Event handling is only nominal in this program because its main purpose is to demonstrate
// the basics of an application's main event loop. Programs in later chapters demonstrate
// the full gamut of individual event handling.
//
// The program utilises the following resources:
//
// ・ A 'plst' resource.
//
// ・ A 'WIND' resource (purgeable).
//
// ・ A 'SIZE' resource with the acceptSuspendResumeEvents, canBackground,
// doesActivateOnFGSwitch, and isHighLevelEventAware flags set.
//
// ☆main.nibで作ったウインドウからマウスイベントが生じない訳は、標準ハンドラーに渡されてしまうからです。
//     従って標準ハンドラーの処理をIBで解除すればウインドウ内のマウスイベント等が得られます。
// *******************************************************************************************

// ノノノノノノノノノノノノノノノノノノノノノノノノノノノノノノノノノノノノノノノノノノノノノノノノノノノノノノノノノノノノノノノノノノノノノノノノノノノノノノノノノノ includes

#include

// ノノノノノノノノノノノノノノノノノノノノノノノノノノノノノノノノノノノノノノノノノノノノノノノノノノノノノノノノノノノノノノノノノノノノノノノノノノノノノノノノノノノ defines

//#define rWindowResource 128

#define topLeft(r) (((Point *) &(r))[0])
#define botRight(r) (((Point *) &(r))[1])

// ノノノノノノノノノノノノノノノノノノノノノノノノノノノノノノノノノノノノノノノノノノノノノノノノノノノノノノノノノノノノノノノノノノノノノノノノノノ global variables

Boolean gDone;
RgnHandle gCursorRegionHdl;

// ノノノノノノノノノノノノノノノノノノノノノノノノノノノノノノノノノノノノノノノノノノノノノノノノノノノノノノノノノノノノノノノノノノノノノノノ function prototypes

int main(int argc, char* argv[]);
void doPreliminaries (void);
//void doNewWindow (void);
void eventLoop (void);
void doEvents (EventRecord *);
void doMouseDown (EventRecord *);
void doUpdate (EventRecord *);
void doOSEvent (EventRecord *);
void drawEventString (Str255);
void doAdjustCursor (WindowRef);

// ************************************************************************************** main


int main(int argc, char* argv[])
{
IBNibRef nibRef;
WindowRef windowRef;

OSStatus err;

err = CreateNibReference(CFSTR("main"), &nibRef);
require_noerr( err, CantGetNibRef );

err = SetMenuBarFromNib(nibRef, CFSTR("MenuBar"));
require_noerr( err, CantSetMenuBar );

err = CreateWindowFromNib(nibRef, CFSTR("MainWindow"), &windowRef);
require_noerr( err, CantCreateWindow );

DisposeNibReference(nibRef);
//----------------------------------------------
doPreliminaries();
SetPortWindowPort(windowRef);
TextSize(10);
//UseThemeFont(kThemeSystemFont,smSystemScript);

ShowWindow( windowRef );

eventLoop();

//----------------------------------------------
//RunApplicationEventLoop();

CantCreateWindow:
CantSetMenuBar:
CantGetNibRef:
return err;
}

// *************************************************************************** doPreliminaries

void doPreliminaries(void)
{
MoreMasterPointers(48);

InitCursor();
FlushEvents(everyEvent,0);
}

// ********************************************************************************* eventLoop

void eventLoop(void)
{
EventRecord eventStructure;
Boolean gotEvent;

gDone = false;
gCursorRegionHdl = NewRgn();
doAdjustCursor(FrontWindow());

while(!gDone)
{
gotEvent = WaitNextEvent(everyEvent,&eventStructure,100,gCursorRegionHdl);
if(gotEvent)
doEvents(&eventStructure);
else
{
if(eventStructure.what == nullEvent)
drawEventString("?p nullEvent");
}
}
}

// ********************************************************************************** doEvents

void doEvents(EventRecord *eventStrucPtr)
{
switch(eventStrucPtr->what)
{
case mouseDown:
drawEventString("?p mouseDown");
doMouseDown(eventStrucPtr);
break;

case mouseUp:
drawEventString("?p mouseUp");
break;

case keyDown:
drawEventString("?p keyDown");
break;

case autoKey:
drawEventString("?p autoKey");
break;

case updateEvt:
drawEventString("?p updateEvt");
doUpdate(eventStrucPtr);
break;

case activateEvt:
drawEventString("?p activateEvt");
break;

case osEvt:
drawEventString("?p osEvt - ");
doOSEvent(eventStrucPtr);
break;
}
}

// ******************************************************************************* doMouseDown

void doMouseDown(EventRecord *eventStrucPtr)
{
WindowPartCode partCode;
WindowRef windowRef;

partCode = FindWindow(eventStrucPtr->where,&windowRef);

switch(partCode)
{
case inContent:
if(windowRef != FrontWindow())
SelectWindow(windowRef);
break;

case inDrag:
DragWindow(windowRef,eventStrucPtr->where,NULL);
doAdjustCursor(windowRef);
break;

case inGoAway:
if(TrackGoAway(windowRef,eventStrucPtr->where))
gDone = true;
break;
}
}

// ********************************************************************************** doUpdate

void doUpdate(EventRecord *eventStrucPtr)
{
BeginUpdate((WindowRef) eventStrucPtr->message);
EndUpdate((WindowRef) eventStrucPtr->message);
}

// ********************************************************************************* doOSEvent

void doOSEvent(EventRecord *eventStrucPtr)
{
Cursor arrow;

switch((eventStrucPtr->message >> 24) & 0x000000FF)
{
case suspendResumeMessage:
if((eventStrucPtr->message & resumeFlag) == 1)
{
SetCursor(GetQDGlobalsArrow(&arrow));
DrawString("?pResume");
}
else
DrawString("?pSuspend");
break;

case mouseMovedMessage:
doAdjustCursor(FrontWindow());
DrawString("?pMouse-moved");
break;
}
}

// *************************************************************************** drawEventString

void drawEventString(Str255 eventString)
{
WindowRef windowRef;
RgnHandle tempRegion;
Rect portRect;

windowRef = FrontWindow();
tempRegion = NewRgn();

GetWindowPortBounds(windowRef,&portRect);
ScrollRect(&portRect,0,-15,tempRegion);
DisposeRgn(tempRegion);

MoveTo(8,340);
DrawString(eventString);
}

// **************************************************************************** doAdjustCursor

void doAdjustCursor(WindowRef windowRef)
{
RgnHandle myArrowRegion;
RgnHandle myIBeamRegion;
Rect cursorRect;
Point mousePt;
Cursor arrow;

myArrowRegion = NewRgn();
myIBeamRegion = NewRgn();
SetRectRgn(myArrowRegion,-32768,-32768,32767,32767);

GetWindowPortBounds(windowRef,&cursorRect);
SetPortWindowPort(windowRef);
LocalToGlobal(&topLeft(cursorRect));
LocalToGlobal(&botRight(cursorRect));

RectRgn(myIBeamRegion,&cursorRect);
DiffRgn(myArrowRegion,myIBeamRegion,myArrowRegion);

GetGlobalMouse(&mousePt);
if(PtInRgn(mousePt,myIBeamRegion))
{
SetCursor(*(GetCursor(iBeamCursor)));
CopyRgn(myIBeamRegion,gCursorRegionHdl);
}
else
{
SetCursor(GetQDGlobalsArrow(&arrow));
CopyRgn(myArrowRegion,gCursorRegionHdl);
}

DisposeRgn(myArrowRegion);
DisposeRgn(myIBeamRegion);
}

// *******************************************************************************************

ToolBox 構造体

Carbonでよく使う構造体です。

☆矩形
struct Rect {
short top;
short left;
short bottom;
short right;
};

☆ポイントの位置
struct Point {
short v;
short h;
};

☆カラー
struct RGBColor {
unsigned short red;
unsigned short green;
unsigned short blue;
};

☆領域
struct MacRegion {
UInt16 rgnSize;
Rect rgnBBox;
};

☆カラーグラフィック操作用の描画環境
struct CGrafPort {
short device;
PixMapHandle portPixMap;
short portVersion;
Handle grafVars;
short chExtra;
short pnLocHFrac;
Rect portRect;
RgnHandle visRgn;
RgnHandle clipRgn;
PixPatHandle bkPixPat;
RGBColor rgbFgColor;
RGBColor rgbBkColor;
Point pnLoc;
Point pnSize;
short pnMode;
PixPatHandle pnPixPat;
PixPatHandle fillPixPat;
short pnVis;
short txFont;
StyleField txFace;
short txMode;
short txSize;
Fixed spExtra;
long fgColor;
long bkColor;
short colrBit;
short patStretch;
Handle picSave;
Handle rgnSave;
Handle polySave;
CQDProcsPtr grafProcs;
};

Inside Macintosh

以下はCarbon以前のToolBox資料へのリンクです。参考まで、Pascalなのが。。

Imaging With QuickDraw

Macintosh Toolbox Essentials

Text

Editor mi

Editor miとは旧姓みみかきエディトと呼ばれたテキストエディターです。
OSX対応版ではmiとなった様です。

結構便利なので私は気に入っています。
例えば、xxxx.basと言うテキストサンプルを入手してFutureBASICにコンバートしようとするが、FBのエディターではファイルタイプの指定がない為開けないことがあります。こんな時にファイルを読み込み、オプション→クリエータタイプで指定することができます。

mimikakiへのリンク


尚、Develop Memoにはカーボンやココアのメモがあったりします。

macintosh-c

Mactechにはmacintosh-C Carbonと言う本のOnline版(HTML version)
が公開されており、PDFとソースコード(CW用)もダウンロード可能です。

macintosh-c

CW→Xcodeも可能だと思います。

ウインドウ表示関数

☆ShowWindow( window ); は非表示のウインドウを表示する関数です。
前回の解説にあった以下のnibファイルのウインドウ参照(&windowを)指定しています。

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

void ShowWindow (
WindowRef window
);


typedef WindowPtr WindowRef;

typedef struct OpaqueWindowPtr * WindowPtr;


☆MacWindows.hのヘッダーに記載されています。


☆ウインドウを非表示にする。
void HideWindow (
WindowRef window
);



☆ウインドウを選択する。
void SelectWindow (
WindowRef window
);
一度消したウインドウを再表示するにはこの関数とセットで使用します。

ウインドウ関連の関数

CreateNibReferenceについて

☆CreateNibReference
現行のバンドルでnibファイルへの参照を作ります。

err = CreateNibReference(CFSTR("main"), &nibRef);
mainはmain.nibファイルを示しています。指定には.nibは不要です。

OSStatus CreateNibReference (
CFStringRef inNibName,
IBNibRef * outNibRef
);

CFStringRef

CFStringオブジェクトへの参照

typedef const struct __CFString *CFStringRef;

typedef struct OpaqueIBNibRef * IBNibRef;
nibファイルへの参照

main.nib.jpg



err = SetMenuBarFromNib(nibRef, CFSTR("MenuBar"));

アプリケーションで使用するメニューバーがある時にはnibファイルからメニューバーを取り出します。(解凍)
以下の画像にあるMenuBarが使用されます。

OSStatus SetMenuBarFromNib (
IBNibRef inNibRef,
CFStringRef inName
);


err = CreateWindowFromNib(nibRef, CFSTR("MainWindow"), &window);
nibファイルからウインドウを取り出します。(解凍)
以下の画像にあるMainWindowが使用されます。

OSStatus CreateWindowFromNib (
IBNibRef inNibRef,
CFStringRef inName,
WindowRef *outWindow
);

typedef WindowPtr WindowRef;

typedef struct OpaqueWindowPtr * WindowPtr;

尚nibファイルの修正はインターフェースビルダーで行います。

main.nib2.jpg


DisposeNibReference(nibRef);
nibファイルへの参照を破棄します。(一度取り出した後は参照は不要なので破棄します。)

void DisposeNibReference (
IBNibRef inNibRef
);

Carbon雛形

Carbonで使用される構造体について。

#include文の後に記載が無いのはブログの予約語とバッテイングしているため表示されない様です。

☆Interface Builder Services Data Types

- IBNibRef

nibファイルへの参照.

typedef struct OpaqueIBNibRef * IBNibRef;

OpaqueIBNibRefの構造体は公開されていません。


☆WindowRef

typedef WindowPtr WindowRef;


☆WindowPtr

typedef struct OpaqueWindowPtr * WindowPtr;

OpaqueWindowPtrの構造体は公開されていません。

☆OSStatus
カーボンでは関数の戻り値の状態をコード化した数値を使用します。
関数が問題なく実行されれば0を還します。

typedef SInt32 OSStatus;
32ビットの符号付き整数の値をとります。

RunApplicationEventLoop();

Carbonでの新しいイベントループ処理であるRunApplicationEventLoop();
を使うと従来のWaitNextEventとは違ったイベント処理を行う必要があります。
以下はXcodeでの新規プロジェクトを作った時にできる雛形です。
(尚、コメントは削除してあります。)

//
// main.
// PROJECTNAME
//
// Created by FULLUSERNAME on DATE.
// Copyright ORGANIZATIONNAME YEAR. All rights reserved.
//

#include

int main(int argc, char* argv[])
{
IBNibRef nibRef;
WindowRef window;

OSStatus err;

err = CreateNibReference(CFSTR("main"), &nibRef);
require_noerr( err, CantGetNibRef );

err = SetMenuBarFromNib(nibRef, CFSTR("MenuBar"));
require_noerr( err, CantSetMenuBar );

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

DisposeNibReference(nibRef);

ShowWindow( window );

RunApplicationEventLoop();

CantCreateWindow:
CantSetMenuBar:
CantGetNibRef:
return err;
}