REALbasic プログラミング覚え書き
ほとんど自分のためのページです。
「EditField内のテキストをプリンターで印刷する方法。」を加えました。
目 次
-
EditField内のテキストをプリンターで印刷する方法。
Editfieldなどのテキスト画面のイメージをそのままプリンターで印字するための簡単な方法がぜひほしいのですが、英数文字と日本語文字などフォントの違いとバイトの違いが混在したテキストの印字幅を判別してプリントアウトするための単純な命令は現在までのところないようです。このためテキストの印字に関しては自前のルーチンが必要です。このための手順をまとめてみました。
- 使用しているプリンターにより、解像度が違うので、はじめに使用しているプリンタードライバーから、縦横のピクセル数の情報を取得します。このためには「p=New PrinterSetup」で印刷設定画面を開きます。
- 全部の文章から改行から改行までの文を取り出す。これには「countfields(@,chr(13))」「nthfield(@,chr(13),n)」を利用します。
- 抜き出した文の長さをピクセル単位で調べます。これには「graphics.stringwidth(@)」を利用します。
- その長さが、用紙幅以内であれば印字する。これには「dim g as graphics」「g = OpenPrinterDialog()」「g.drawstring @,m,n」を使います。nには縦方向のピクセル数を「g.textheight」を利用して与えます。
- その長さが、用紙幅以上であれば、用紙幅で分割して印字する。
- 用紙の縦の長さを越えた場合は、次のページに印刷する。これには「g.nextpage」を使います。
とりあえずサンプルを作ってみました。プリンターの違いによる確認をしていませんので、ColorSW2400以外では表示部分に手直しが必要かもしれません。メニューから使いやすいように、はじめの印字位置と文字サイズを引数としたサブルーチンにまとめましたので、そのまま後から利用しやすいと思います。
ソースプログラム「tips20」のみです。REALbasic最新バージョンが必要です。30 kバイト
-
他のアプリケーションを起動する方法。LaunchとListboxの使い方。
自分で作った、アプリケーションから他のアプリケーションを実行することはほとんどありません。
でも使い慣れたワープロで作った文書が、他のアプリケーションから簡単に参照することができれば、つまりHTMLのリンクのように、文書の一部をクリックすると、使い慣れたアプリケーションで作った表や絵の入った文書そのものが直接読めると便利かな、と考えました。(クラリスの文書内から、他のクラリスで作った文書にリンクをかける方法がないかと試してみましたが見つかりませんでした。Office98のマック版では、Excelから文書にリンクをかけることが出来ます。)
同じフォルダー内にある、クラリスの文書ファイルを表示し、ファイル名をダブルクリックすると、クラリスの文書が開くものを作りましたが、サンプルはSimpleText の文書を開くものにしています。
クラリスの文書を「MacCreator」が「CWKJ」で判別していますので、この部分をシンプルテキストなら「ttxt」のように自分のよく使っているワープロの「MacCreator」に変更してみてください。
また、文書の情報を、あらかじめComment 欄に書き込んでインデックス代わりに使おうと思いまして、Comment 欄を表示してみました。
まず、「launch」するためのファイルの情報(folderitem)を取得します。
PushButton1:Action に
dim f , g As folderitem
dim m,n as integer
//listbox1の初期化
listbox1.deleteAllRows
//
//カレント(現在の)フォルダの情報を「f」に代入。
f = GetFolderItem(" ")
//このとき「f」のフォルダー名「f.name」は「""」です。
//これでカレント(現在の)フォルダの情報が「g」に
//入ります。
g = f.parent
for n=1 to g.count
//クラリスの書類を表示する
//ここ「"CWKJ"」を変更すれば違う書類が選択できます。
//SimpleTextでは「"ttxt"」です。
if g.item(n).maccreator="CWKJ" then
listbox1.addrow g.item(n).name
end if
next
exception
以上、PushButton1:Action
次は、ListBoxに書き出したファイルをダブルクリックで開く部分です。
ListBox1:DoubleClickに
dim f,g,launchfile as folderitem
dim n as integer
f = GetFolderItem(" ")
g = f.parent
for n=1 to g.count
//ダブルクリックしたファイル名と同じ
//ファイル名を探します
if g.item(n).name=me.text then
launchfile=g.item(n)
end if
next
//ダブルクリックしたファイルを実行します
//単に、これだけです。
launchfile.launch
//「exception」は、ファイル操作でのおまじないです。
exception
以上、ListBox1:DoubleClick に書き込みます。
ソースプログラム「tips19」のみです。REALbasic最新バージョンが必要です。30 kバイト
アイコンにファイルをドロップする方法。
保存したメールや、ウエッブページのテキストフィルを整理する場合に、どうしてもシンプルテキストが顔を出してしまいます。日頃使っている、昔のフリーウエアバージョンの「Jedit」に統一したいので、まずテキストファイルのクリエイタータイプを変更するものを作ってみました。
ResEditで十分なのでしょうが、たくさんのテキストフィルを、アイコンに重ねて1度に全部のテキストフィルのクリエイタータイプを変更してしまうものにしました。初期値では「Jedit」用に変更しますが、自分の使っているエディターのクリエタータイプに設定が変更できます。(「ChangeCreator」です。)
次に、たくさんのテキストフィルを1つのファイルにまとめてつなぐことを考えてみます。たくさんのテキストフィルを選択してアイコンに重ねてもよいし、フォルダー丸ごと、アイコンに重ねてもフォルダー内のテキストファイルだけを選んで、結合してしまうようにしました。(「TextConnect」です。)
使いやすさを考えると、アイコンにファイルをドロップ出来る方が良いのですが、アプリケーションを開いた後からのテキストクリッピングやピクチャーのドロップとは勝手が違います。
アイコンにファイルをドロップするには、Application Class のイベント「OpenDocument」が必要となります。さらにドロップを受け付ける、File Typeの設定とBuildするときの設定も必要となります。
アイコンにドロップされたファイルを受け取るための手順です。
- fileメニューより「New Class」を選び、propertiesのSuperの欄をApplicationとします。これで、ProjectウィンドウにClass1が作られます。このClass1をダブルクリックしてClass1のエディターを開き、EventsのOpenDocumentにコードを書き込みます。OpenDocumentでは。ドロップされたfolderitemが変数「item」で取り込めます。
- 次は、ファイルタイプの設定です。Editメニューから、File Typesを選び、Nameは「何でもよし」、Mac Creatorは「????」、MacTypeは「????」、Extensionは「なし」、そしてDocument Iconにチェックを入れる。全てのタイプのファイルを受け付ける設定です。MacTypeを「fold」にしたものを追加すると、フォルダーも受け付けます。これで、タイプセッティングが終了します。
- 最後に、Buildするときの設定です。Buildする前に、Edit メニューのProject SettingsでMac Creator を「????」以外のものにします。例えば「KOKf」などに。それから、Buildします。
頻繁にBuildを行うとドロップを受け付けないアプリケーションが作られることがあります。そのときは1度REALbasicを終了させてBuildしてみて下さい。
EditFieldにドロップされたファイルを受け取るための手順です。
- EditFieldのOpenにファイルのドロップを受け付ける命令を書きます。
//ファイルタイプはEditメニューのFile Types
//で設定しておく必要あり。
//Nameは「any」
//Mac Type , Mac Creator共に「????」
Me.AcceptFileDrop( "any" )
- EditFieldのDropObjectに受け取ったファイルをどのように使うのかをプログラムします。サンプルでは、Module1のサブルーチン「connect」に受け取ったファイルの情報を持って飛びます。
//複数のファイルがドロップされた時の
//処理です
do
connect obj.folderitem
loop until not obj.NextItem
サンプルの「TextConnect」は、Mac Creatorに関わらず、MacTypeが「TEXT」であれば、全て付け加えて1つのファイルにします。フォルダー内にあるテキストファイルもフォルダーごと受け付けます。書き出しもできますが、印刷機能は付けておりません。
もう1つのサンプル「ChangeCreator」は、フォルダーの認識はしません。それ以外のファイルは、ドロップできます。そのうちMacTypeが「TEXT」のファイルのMac Creatorを「Jedit」用に変更します。MacTypeが「TEXT」のファイル以外は、MacTypeとMac Creatorを表示するだけですので、MacTypeとMac Creatorを知りたいときにも使えます。
ソースプログラム「tips18」のみです。REALbasic最新バージョンが必要です。30 kバイト
グラフ計算機。
xーyの関数をプロットする普通のプログラムです。Buildしても役に立ちません。なぜなら、関数の変更が、プログラム中でないとできないからです。でも、自分で使う分には、こちらの方が汎用性??があって使いやすいようです。
ソースプログラム「tips17」のみです。REALbasic最新バージョンが必要です。30 kバイト
数値データのファイルへの書き出しと読み込み。
数値データのファイルへの書き出しと読み込む方法
プログラムの初期条件などを、実行中に変更したとき、どうしてもファイルの入出力は避けて通れません。たくさんの数値データを効率良く保存するには、Binaryで処理するのが一般的です。しかしながら、内容の確認が簡単に行なえるのは、Textファイルで、頻繁にファイルの書き込みや読み込みをするのでなければ、Textファイルで十分です。なんといっても自分で使う分には、エディターで直接ファイルの変更が可能なことがメリットです。
ファイルの、入出力の方法です。
アプリケーションと同じフォルダーにデータファイルを作ることにします。
まず、データの書き込みです。
dim n as integer
//ファイル全般の情報を持つ引き出し「FolderItem」の名前「file 」を定義する
Dim file As FolderItem
//書き込むテキストデータの操作「TextOutputStream」を受け持つ変数「dataStream」を定義する。
Dim dataStream As TextOutputStream
//保存ダイアログでファイル名を決める場合
//file=GetSaveFolderItem("application/text","pre")
//
//ファイル全般の情報を持つ引き出し「FolderItem」(名前は「file 」)の中に
//保存ファイル名「pre」の情報を入れる。
file=GetFolderItem("pre")
//ファイル全般の情報を持つ引き出し「FolderItem」(名前は「file 」)の中に
//書き込むテキストデータを入れる領域を確保した情報を「dataStream」にしまう。
dataStream=file.CreateTextFile
//デター区切り記号を「,」に指定する
dataStream.delimiter =","
//ここでは0から30までの数値データを書き込んでみます。
for n=0 to 30
//「dataStream.WriteLine」がデータを1個づつ書き込む書式です
dataStream.WriteLine str(n)
next
//閉じます。
dataStream.Close
//file.maccreator="JEDT"
これで、名前が「per」のTEXTファイルが、アプリケーションと同じフォルダーに出来ます。
これを、エディター(シンプルテキストなど)で開いてみると、次のようになっているはずです。
「0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,2526,27,28,29,30」
さて次は、この書き出した数値データファイルを読み込んで使う方法です。
dim n,lendata as integer
dim alldata,onedata as string
Dim file As FolderItem
Dim dataStream As TextinputStream
//開くファイルの名前が「per」に決まっている場合。
file=GetFolderItem("pre")
//選択したフォルダアイテムを「text」ファイルとして開く
dataStream=file.openasTextFile
//1度に全部読み込む
alldata= dataStream.readall
//読み込んだ文字列の「,」で区切られた総数を調べる。
lendata=countfields(alldata,",")
//区切り文字「,」ごとにデータをばらす
for n=1 to lendata
listbox1.addrow nthfield(alldata,",",n)
next
dataStream.Close
ソースプログラム「tips16」のみです。REALbasic最新バージョンが必要です。30 kバイト
NewCanvasClassの作り方。
NewClassの作り方
1 新しいプロジェクトファイルを開く。
2 File メニューから「New Class」を選択して、PropertiesウインドウのSuperの欄からベースとするクラス(ここではCanvas)を選択します。
3 デフォルトで「Class1」と名前がついたウィンドウが現れます。ここに、例えば。
Events:Paint に
me.graphics.foreColor=rgb(200,100,50)
me.graphics.fillrect 0,0,me.width,me.height
me.graphics.foreColor=rgb(0,0,0)
me.graphics.drawstring "NewClass",0,10
Events:MouseDown に
dpx=x
dpy=y
return true
Events:MouseDrag に
me.top=me.top+(y-dpy)
me.left=me.left+(x-dpx)
EditメニューのNew Propertyで
dpx as integer
dpy as integer
以上のようにプログラムします。
4 この新しいCanvasクラスは、プログラム実行中に、マウスで自由に移動できるCanvasです。
5 この新しいCanvasクラスは、プロジェクトウインドウにあるClass1のアイコンを、デスクトップにドラッグすると、小さなアイコンのついた独立したファイルになります。後からはこのファイルを、プロジェクトウインドウに持って来るだけでいつでも使えます。
NewClassの使い方
1 新しいプロジェクトファイルを開きます。
2 NewClassの小さなアイコンをプロジェクトウインドウにドラッグします。
3 NewClassが「Canvasクラス」をベースに作られたものであればCanvasを、他のクラスをベースに作られたものであれば、そのクラスのアイコンをツールボックスからメインウインドにドラッグします。通常のCanvasのように、配列も作ることができます。
4 ドラッグしたCanvasのPropertiesウインドウのSuperの欄でNewClassの名前を選択します。
5 後は、このNewClassの内部変数や初期値などを、「NewClass名」.「変数名」の形で変更できます。もちろん、BackDropに任意のPICTを張り付けることもできます。
ソースプログラム「tips15」のみです。REALbasic最新バージョンが必要です。30 kバイト
各コントロール類の配列の使い方。
ツールボックス内にある、PushButton や StaticText や Canvas.....などのコントロールを複数同じような使い方をする場合。変数と同様、コントロールも配列にすることができます。コントロールの配列を使うと、プログラムの長さは短くなり、後から、いくつかのコントロールを付け加える場合に、とても簡単にプログラムを変更できます。しかし、このコントロールの配列には、少々くせがありまして、注意が必要です。
コントロールの配列の定義法
例えば、Canvas コントロールの場合。ツールボックスからCanvas コントロールをドラッグします。このCanvas コントロールのpropertiesウインドウの「Name」欄がCanvas1となっているのを確認します。変更してもかまいませんが。そのときは「Name」欄の名前を覚えておきます。
次に、ツールボックスから2つめのCanvas コントロールをドラッグします。このCanvas コントロールのpropertiesウインドウの「Name」欄を1つめと同じ名前 Canvas1 に変更します。この後、「Name」欄以外の場所をクリックすると、ダイアログボックスが出てきます。英文で、配列にしますか?と訪ねてきますので、「Yes」を選択すると、Canvas コントロールの配列が出来上がります。さらにツールボックスから3つめのCanvas コントロールをドラッグし、同様に同じ名前にしてCanvas コントロールの配列をいくつでも作ることができます。
例えば、このようにして作った3つのCanvas コントロールを用意し、
Canvas1():MouseDownに次のようなプログラムを書きます。
Window1.Canvas1.MouseDown:
Function MouseDown(Index As Integer, X As Integer, Y As Integer) As Boolean
dim n as integer
canvas1(index).graphics.drawstring str(index),0,10
for n=0 to 2
select case index
case 0
canvas1(0).graphics.drawstopicon 50,50
case 1
canvas1(1).graphics.drawcautionicon 50,50
case 2
canvas1(2).graphics.drawnoteicon 50,50
end select
next
End Function
はじめの「canvas1(index).graphics.drawstring str(index),0,10」は、indexの数(Canvas コントロールの配列の数)だけ、for〜next ループのようにくり返しますので、それぞれのCanvas をクリックすると、配列のindex(要素)の数字をそれぞれのCanvas内に描きます。Canvas コントロールの配列の数がたくさんある場合はとても便利ですね。
ただし、類似性のある単純な操作ではなく、それぞれのCanvas コントロールで別々のアクションを行う場合は、後半のfor〜next 文でくくられたような操作が必要になります。select case 文が使いやすそうです。
また、大切なことですが、カウンターやフラッグを使う場合は、それらも配列変数として、コントロールの配列の数だけ用意しておく必要があります。そうしなければ、コントロールの配列の中に、1だけ増やすカウンターを入れると、コントロールの配列の数だけカウンターが順番に進んでしまいます。
コントロールの配列のサンプルとして、スロットマシーンを作ってみました。メニューにも配列を使っています。「1」「2」「3」と「esc」キーおよび「return」キーでも遊べます。
ソースプログラム「tips14」のみです。REALbasic最新バージョンが必要です。30 kバイト
SpriteSurface Controlの使い方。
変数の定義
EditメニューのNewPropertyで「Picture型」のback01〜ball02、「Sprite型」のSprite01とSprite02を定義します。
本来、PICT画像などの細かい図形を簡単に、動かすことのできることが、SpriteSurfaceの目的なので、プログラムで図形を描く必要はなく、可愛いキャラクターのPICTファイルがあれば、名前をball01.pictやBall02.pict等に変更して、そのまま、Project ウインドウにドラッグ&ドロップします。
今回のSampleでは、PICTファイルを付属させてsampleの容量を大きくしたくなかったため、Events:Paint にて、適当な図形(StopとCautionアイテム2つ、背景2つ)を描いています。
PushButton:Action にSpriteSurface1を開くためのプログラムを書く。
//SpriteSurface1に新しいパーツを登録する。
//「NewSprite(ball01,100,200)」の各パラメータは
//(picture型変数名、表示位置X、表示位置Y)
Sprite01=SpriteSurface1.NewSprite(ball01,100,100)
Sprite02=SpriteSurface1.NewSprite(ball02,200,200)
//「group」はSpriteSurface1のイベント collision (衝突)を
//有効にする書式
Sprite01.group=1
Sprite02.group=2
//「priority」は前面後面の優先順位
//Sprite01.priority=1
//Sprite02.priority=2
spriteSurface1.backdrop=back01
SpriteSurface1.Run
//SpriteSurface1がCloseされると
//ここ「SpriteSurface1.Run」直後に処理が戻って来る。
if Sprite01.image<>nil then
Sprite01.image=nil
end if
if Sprite02.image<>nil then
Sprite02.image=nil
end if
「Sprite01.group=1」の「1」の数字は、正の整数であれば SpriteSurface1のイベント collision (衝突)を有効にします。
Sprite01とSprite02のgroupの数字を同じにすると、衝突を感知しなくなります。これは、たくさんの、Sprite型のパーツを画面上に表示したとき、衝突させたいものとさせたくないものを区別できるようにするものです、また、イベント collisionでどの2つのSpriteが衝突したのかを、groupの数字から知ることができます。
「SpriteSurface1.Run」でSpriteSurface1の画面が開きます。この画面では、通常の、MouseDownなどのイベントが使えなくなります。
MouseDownはSpriteSurface1 を閉じるための専用の手段として使えるだけです。早くマウスが使えるように、イベントを追加してほしいものです。
「SpriteSurface1.close」だけでは、SpriteSurface1に配置した、パーツは残ったままですので、再度「SpriteSurface1.Run」を実行すると、2重に表示されてしまいます。「SpriteSurface1.Run」以下は、これらのパーツを消去するためのものです。
SpriteSurface1:NextFrameにキーアクションのプログラムを書く。
NextFrameイベントでは、1秒間当たりSprite Surface1のProperties画面のFrame Speedで決められた枚数だけ、SpriteSurfaceを書き直します。
また、Sprite Surfaceでは、キーボードからのキー入力を監視していますので、キーの操作でパーツを動かすプログラムが簡単に書けます。
例えば、
//キーボードでコントロールします。
//「7c」は「右矢印キー」
if Me.KeyTest(&h7c) Then
Sprite01.x=Sprite01.x+5
end if
この例は、Keycode「&h7c」に対応する、Keyboard上のキーが押されたとき、「Me.KeyTest(&h7c)」がtrue となるので、Sprite01の水平方向の位置を、右に5 ずらします。Keycode「&h7c」に対応するキーは「右向き矢印」キーです。
SpriteSurface1:Collisionに衝突時のプログラムを書く。
衝突が起ったときは、衝突した2つのパーツ、正確にはSpriteが「s1」と「s2」に代入されます。どのSpriteとどのSpriteとが衝突したかは、「Sprite.gorup」の値を調べてみれば分かりますね。下の例は、衝突したらお互いに逃げるようにしたものです。
if s2.x >s1.xthen
s1.x=s1.x-2
s2.x=s2.x+2
end if
if s1.y<s2.y then
s1.y=s1.y-2
s2.y=s2.y+2
end if
sampleに対戦型のゲーム?を用意してみました。
ソースプログラム「tips13」のみです。REALbasic最新バージョンが必要です。30 kバイト
キーボードからの入力に必要となるkeycode一覧表
Apple keyboad2です。例えば「上向きの矢印キー」は「7e」ですから SpriteSurface Control内での keytest(&h7e) やKeyboard Control内で Keyboard.AsyncKeyDown(&h7e) のように使います。
通常のキー入力の監視はKeyDown イベントで行いますが、for〜next等のループ内では、KeyDown イベントではキー入力の監視が1回1回行われません。そこで、通常の画面では Keyboard.AsyncKeyDown( )、SpriteSurface の画面ではkeytest( )を使います。
また、アスキーコードは、KeyDown イベント内でのキー入力の監視や特殊文字を画面に表示するときに使うことが多いようです。
[esc]-(35) [1]-(12) [2]-(13) [3]-(14) [4]-(15) [5]-(16) [6]-(17) [7]-(1a) [8]-(1c) [9]-(19) [0]-(1d) [-]-(1b) [^]-(18) [\]-(5d) [delete]-(33) [tab]-(30) [Q]-(0c) [W]-(0d) [E]-(0e) [R]-(0f) [T]-(11) [Y]-(10) [U]-(20) [I]-(22) [O]-(1f) [P]-(23) [@]-(21) [[]-(1e) [return]-(24) [control]-(3b) [A]-(00) [S]-(01) [D]-(02) [F]-(03) [G]-(05) [H]-(04) [J]-(26) [K]-(28) [L]-(25) [;]-(29) [:]-(27) []]-(2a) [shift]-(38) [Z]-(06) [X]-(07) [C]-(08) [V]-(09) [B]-(0b) [N]-(2d) [M]-(2e) [,]-(2b) [.]-(2f) [/]-(2c) [_]-(5e) [caps lock]-(39) [option]-(3a) [command]-(37) [英数]-(66) [space]-(31) [かな]-(68) [enter]-(34) [左]-(7b) [右]-(7c) [下]-(7d) [上]-(7e)
[clear]-(47) [=]-(61) [/]-(4b) [*]-(43) [7]-(59) [8]-(5b) [9]-(5c) [-]-(4e) [4]-(56) [5]-(57) [6]-(58) [+]-(45) [1]-(53) [2]-(54) [3]-(55) [0]-(52) [,]-(5f) [.]-(41) [enter]-(4c)
キーボードの種類によって少しコードが違います。調べるためのサンプルを用意しました。
ソースプログラム「tips12」のみです。REALbasic最新バージョンが必要です。30 kバイト
Picture をマウスでDrag & Dropする方法
EditFieldでは、PropertiesのMultiLineにチェックを入れるだけで、テキストのドラッグ&ドロップが出来るようになりますから、特別のプログラムは必要ありません。しかし、図形のドラッグ&ドロップでは、どの図形をドラッグするのか、またどこにドロップするかを指定する作業が必要となります。
Canvas1に描いた、あるいは張り付けたPicture(「p1」)をCanvas2の「p2」にドラッグするためには、以下の手順が必要です。
送り出す側のCanvas1.MouseDown: に
dim l,t,w,h as integer
dim d as dragitem
l=canvas1.left
t=canvas1.top
w=canvas1.width
h=canvas1.height
d=newdragitem(l,t,w,h)
d.picture=p1
d.drag
受け取る側の.Canvas2.Open: に
me.acceptpicturedrop
さらにCanvas2.DropObject: に
p2=obj.picture
canvas2.graphics.drawpicture p2,0,0
このようになります。
「d.drag」がドラッグを許可する命令。
「me.acceptpicturedrop」がドロップを許可する命令となります。「me」はこのコードを書き込んだコントロール自身、つまりCanvas2を表します。
ドロップを許可された、コントロールには、他のDrag&Dropに対応しているアプリケーション例えば、アップルメニューにあるスクラップブックなどからの、ドロップが可能になります。また、ドラッグを許可されたDragitemは、他のDrag&Dropに対応しているアプリケーションにドロップできます。もちろんディスクトップにドロップすると、ピクチャクリッピングとなります。
単純なサンプルと、配列を使ったサンプルを用意しました。
ソースプログラム「tips11」のみです。REALbasic最新バージョンが必要です。30 kバイト
Picture をメニューからCopy & Paste & Cut & Clearする方法
新しいクラスを使ったものではありませんが、Rectangleの配列を使って、ON OFF のボタンを作ってみました。Canvas や NewPicture の配列を一緒に使うと、好きな絵を張り付けたボタンが作れそうだったので、試してみました。配列に関する不安定さは相変わらずです。Debug の途中で配列に関するエラーが出たときには、迷わずに再起動を行って下さい。Rectangle や Canvas などの各コントロールの配列の作り方は、2番目のコントロールを配置した後、その Properties ウィンドウの Name 欄を1番目のコントロールと同じ名前に変更します。すると、「配列にしますか」との確認のダイアログが表れますので、「OK」とすれば、配列になります。後はこのコントロールを、必要な数だけ複製します。各コントロールの配列の「Open」などのイベントでは「Index」が定義されています。イベント内で配列の数だけ「Index」が自動的にループするので、「Select Case」文が使いやすいようです。
「ClipBoard」を使っての図形のコピーやペーストでは、コピーには、コピーする図形の指定、ペーストするには図形を張り付ける位置を指定する作業が必要となるので、EditFieldのように標準では図形のコピー&ペーストはサポートされていません。
クラリスや他のアプリケーションで描いた図形や、メニューの「情報をみる」で表示されるアイコンの図形などをクリップボードにコピーます。それをREALbasicで作ったアプリにペーストするには、以下のコードを、PushButtonのActionや、Menu HandlersのEditPasteに書き込んで使います
dim c1 as clipboard
dim p1 as picture
c1 = new clipboard
if c1.pictureavailable then
p1=c1.picture
graphics.drawpicture p1,0,0
end if
c1.Close
クリップボードに文字が入っている場合は「c1.textavailable」がtrueとなり、画像が入っている場合は「c1.pictureavailable」がtrueとなります。
「c1.Close」は必ず必要です。
メニューの「Copy」「 Paste 」「Cut 」「Clear」がPICTで使えるサンプルを付けました。
ソースプログラム「tips10」のみです。REALbasic最新バージョンが必要です。30 kバイト
New Classを使って、結果として戻り値を複数もつサブルーチンの作り方。
(「吉野 孝 さん(yoshino@eee.kagoshima-u.ac.jp)より教えていただきました」)
例えば、点(x1,y1)を原点のまわりにθ(=th)だけ回転させた点(x2,y2)を求めるために、サブルーチンの引数としてx1,y1,thを送り込み、結果(戻り値)としてx2,y2の2つがほしいとします。
1 「Project」ウインドウの状態で、「File」メニューから「New Class」を選びます。
2 Class1というウインドウが出ますので、その状態で「Edit」メニューの「New Property」を選びます。ここで「x2 as double」,「y2 as double」を繰り返し定義します。Class1での定義はこれだけです。
3 次にModule1にサブルーチンを書き込みます。
「Project」ウインドウの状態で、「File」メニューから「New Module」を選びます。
4 Module1というウインドウが出ますので、その状態で「Edit」メニューの「New Method」を選びます。入力ウインドウが出ますので、
Procedure nameには、「rotate」
Parameters には 「 x1 as double,y1 as double,th as double」
Return Type には 「class1」と入力します。
5 Module1というウインドウ上部のMethodsの欄には「rotate」があります、これをクリックすると。
Function rotate(x1 as double,y1 as double,th as double) as class1
|
End Function
となっていますのでここにサブルーチンの本体を書きます。
//
Function rotate(x1 as double,y1 as double,th as double) as class1
dim a as class1
a=new class1
a.x2=(cos(th))*x1-(sin(th))*y1
a.y2=(sin(th))*x1+(cos(th))*y1
return a
End Function
//
「a」と名付けたclass1の中で定義した x2 , y2 は、それぞれ a.x2 , a.y2 の形で使うことの出来るグローバル変数となりますので。いわばグローバル変数のグループ化?が出来ることになります。
6 「Project」ウインドウからWindow1をダブルクリックして、Window1のウインドウ内にPushbuttonを配置して、その中で
//
Sub Action()
dim x1.y1.th as double
dim b as class1
b=new class1
x1=2
y1=3
th=3.14
b=rotate(x1,y1,th)
statictext1.text="b.x2="+str(b.x2)
statictext2.text="b.y2="+str(b.y2)
End Sub
//
のようにして使います。
つまり、サブルーチンの戻り値の型を、新しく作ったClass1とすることによって、戻り値はクラス1つでも、そのクラスにある変数は全て戻り値として使えることになります。
ソースプログラム「tips9」のみです。REALbasic最新バージョンが必要です。30 kバイト
戻り値のあるサブルーチンと、無いサブルーチンの使い方。
戻り値のあるサブルーチンは、「Function 〜 End Function」の形式になります。
このサブルーチンを呼び出すときは、他のMethodと違って
「サブルーチン名」「(」「第1パラメータ」「、」「第2パラメータ」「、」「第3パラメータ」「)」のように使います。またこのサブルーチン自身が戻り値の型で値を持っていますから、これを他の変数やプロパティに代入する形を取ります。
例えば Code Browser(Window1)のウィンドウ内で、EditメニューからNew Methodを選びます。これで開いたダイアログ内で「Procedure name」の欄にサブルーチンの名前、例えば「Sub1」、「Parameters」の欄に引数の型宣言、例えば「x1 as double,y1 as double」,「Return Type」の欄で「double」を選択します。
するとWindow1のイベントの欄(OpenやCloseなどがはじめから書かれている欄)に新しくSub1がつけ加えられます。これをダブルクリックすると、
Function sub1(x as double,y1 as double) as double
|
End Function
と表示されたウインドが開きますので、
dim z1 as double
z1=x1*x1+y1*y1
return z1
と書き込みます。これでx1の二乗とy1の二乗を計算するサブルーチンが出来上がりました。
これを、使うには、次のように型を合わせて使います。
例えば
statictext1.text=str(sub1(5,23))
あるいは
statictext1.text=str(sub1(val(editfield1.text),val(editfield2.text)))
などのようになります。
戻り値のないサブルーチンは、「Sub 〜 End Sub」の形式になります。
作り方はほとんど同じですが、「Return Type」の欄ではなにも選択しません。
このサブルーチンを呼び出すときは、他のMethodと同じように 「サブルーチン名」「半角スペース」「第1パラメータ」「、」「第2パラメータ」「、」「第3パラメータ」のように使います。
ソースプログラム「tips8」のみです。REALbasic最新バージョンが必要です。30 kバイト
NewPictureに描いた図形などをPICTファイルに保存する方法。
NewPictureに描いた図形などをPICTファイルに保存するには以下のようにします。
dim p1 as picture
dim f1 as folderitem
//絵を描く領域をCanvas1と同じ大きさに指定します。
//「32」は32ビットカラーです。
p1=newpicture(canvas1.width,canvas1.height,32)
//今作った「p1」に点(10,10)と点(50,50)を対角線とする
//四角形を描きます(まだ表示はされません)。
p1.graphics.drawrect 10,10,50,50
//Canvas1に「p1」を表示します。
canvas1.graphics.drawpicture p1,0,0
//ファイルのいろいろな情報を持つ「folderitem」f1
//に保存する場所と名前を確保したことを宣言します。
//以下の書式でマックの標準のSaveダイアログが出ます。
//「""」はファイルタイプの指定です。
//「"New.pict"」はデフォルトの名前です。
f1=getsavefolderitem("","New.pict")
//キャンセルボタンが押されたときの処理です。
if f1=nil then
return
end if
//「p1」をPICT形式で保存する書式です。
f1.saveaspicture p1
これで「New.pict」と名前の付いたPICT形式のファイルが出来ます。
サンプルには保存したPICTファイルを読み込む書式も入れています。
ソースプログラム「tips7」のみです。REALbasic最新バージョンが必要です。30 kバイト
マックの標準オープンダイアログを開いて、PICTファイルを読み込む方法。
オープンダイアログからPICTファイルを選択してWindow1に張り付けるためのには
まず、EditのFile Type..を開き、Addを押して、
NameをPICT1 (好きな名前に)、
Creatorをttxt、
Mac TypeをPICT(必ず大文字です)、
Extentionは何も書かない。
このような準備が必要です。
オープンダイアログからPICTファイルを選択して読み込む書式は以下のようになります。
dim item as FolderItem
item=GetOpenFolderItem("PICT1")
//キャンセルボタンが押されたとき(nil)の処理
if item=nil then
return
end if
pic1=item.OpenAsPicture
(pic1は pic1 as picture)
次は、読み込んだPICTファイルをWindow1の背景画として表示する書式です。
backdrop=pic1
読み込んだPICTファイルをWindow1に描画する書式です。
Graphics.DrawPicture pic1,0,20
どういう訳かこのメソッドが終わると1度目はRefreshされてしまいます。同一の絵を2度選択するとWindowの1部がクリアーされてしまいます。原因不明。
これを回避するにはpic1をグローバル変数として、他のボタンなどから
Graphics.DrawPicture pic1,0,20 とすれば良いようです。
サンプルには読み込んだPICTファイルのサイズにWindowのサイズをそろえる書式も入れています。
ソースプログラム「tips6」のみです。REALbasic最新バージョンが必要です。30 kバイト
グラフィックをプリンターで印刷する方法と、画面をドラッグ&ドロップする方法。
REALbasicではWindowやDialogに直接表示してしまった画面は、そのままでは、プリンターに印刷できません。プリンターに印刷したいものは、WindowやDialogに直接表示せずに「NewPicture」に表示させます。
NewPictureの宣言と、マックの標準のプリントダイアログを表示する宣言です。
Dim g1 as Graphics
Dim P as Picture
P = NewPicture(Canvas1.width, Canvas1.height,8)
//この間に、文字や図形などを「NewPicture」に書き込みます。
//例えば、P.graphics.drawrect 10,10,50,50
// P.graphics.drawoval 20,20,30,30
// P.graphics.drawpicture pict1,0,0
// PICT形式のファイル「pict1」を用意しておけば、これも
// 表示できます。
// Canvas1.graphics.DrawPicture P,0,0
g1 = OpenPrinterDialog()
このときマックの標準のファイル選択のダイアログの場合と同様にキャンセルボタンが押されたときの処理は忘れずにしておきます。
以下のように
if g1=nil then
return
end if
印刷は
g1.DrawPicture P,0,0
のようにします。
CanvasのMouseDownに以下のコードをつけ加えると、この画面を、ドラッグ&ドロップできます。
dim dr as dragitem
dr=newdragitem(me.left,me.top,me.width,me.height)
dr.picture=p
dr.drag
デスクトップにドラッグすると、ピクチャクリッピングになります。クラリスなどにはそのままドラッグ&ドロップできます。
ソースプログラム「tips5b」のみです。REALbasic最新バージョンが必要です。30 kバイト
「NewPicture」を使って、画面のちらつきをおさえる方法。
Canvasに毎回表示をしないPictureを開き、このPictureに画面を書き込んでおき、
必要なときに、CanvasにこのPictureの画面を表示する。この方法で画面のちらつきはほとんど収まりますが、表示速度の必要なプログラムでは、遅くなります。この方法はPICT画面を読み込んでグラフィックの塗りつぶしに使う方法と同じですが、色指定がきっちり出来るメリットがあります。グラフィック画面をプリンターでプリントアウトする必要がある場合はこのPictureを利用します。
下の2行がNewPictureの宣言です。
Dim P as Picture
P = NewPicture(Canvas1.width, Canvas1.height,8)
上の行の第3パラメータは、1、2、4、8、16、32の値を指定するカラーモードです。32(bit)を指定した大きな画面では、実行時にメモリーを食いますので注意が必要です。
以下このPictureにやりたい操作をする。
例えば、
P.graphics.Drawrect 10,10,50,50
P.graphics.Drawstring "書き込み",0,0
など
このままでは、何も表示されません。下の書式でこのPicture画面「P」が表示されます。
Canvas1.graphics.DrawPicture P,0,0
基本サンプル「tips4」と応用サンプル「tips4c」(時計)を用意しました。
ソースプログラム「tips4」のみです。REALbasic最新バージョンが必要です。30 kバイト
ソースプログラム「tips4c」のみです。REALbasic最新バージョンが必要です。30 kバイト
色とRGB関数の関係とプログラム実行中でのカラー微調整の方法。
graphicsでの色指定は graphics.forecolor=rgb(100,200,200) のようにrgb関数を使います。赤色、緑色、青色の順に0から255までの数値で指定します。REALbasic(旧名 CrossBasic)にはColorTableが付いており、rgbの%表示が選択できますのでその%を0から255までの数値に読み換えれば、rgb関数がわかります。しかしアプリケーションを走らせている状態で自由に色を変更したいとき、数字では色のイメージがとれません。そこで少し変更すれば、メニューに組み込める、色変更のためのプログラムを作りました。色の違いが比較しやすいように、Dialogがいくつでも開けるようにしました。また16進での表現もつけ加えましたので、シンプルテキストでホームページを作っている方には便利です。(いまだにシンプルテキストでホームページを作っているのは私ぐらいなものでしょうか?)
表示色を変更するための、標準のカラーピッカーを呼び出せるプラグインを公開されている方もいらっしゃいます。
ソースプログラム「tips1」のみです。REALbasic最新バージョンが必要です。30 kバイト
WindowとDialog間の変数の受け渡し方法。「self」の使い方。
WindowとDialog間の変数の受け渡し方法には、変数の定義を、Moduleで行う方法と、「self」を使う方法があります。Moduleでは変数やサブルーチンが、WindowとDialog間共通で使えます。「self」を使う方法では、Dialog1からWindow1にある各種コントロールを自由に使うことができます。ですから変数の受け渡しと云うより、各種コントロールに変数をテキストや数字で送り込むという使い方ができます。「self」の使い方と動作にはまだ馴染めませんが、基本的には、はじめのWindow1をメインのウインドウにして、その他のウインドウ(Dialog)はその補助に使うというのが、REALbasicやその他のオブジェクト指向の言語の考え方のようです。
- Window1側の準備。
Dialog1を開くときに、
dim d1 as dialog1
d1= new dialog1
d1.w1= self
とします。
「w1」は、Dialog1の中で「w1 as window1」として、後から定義するので、「d1.w1= self」の意味は、w1(window1)つまり自分自身を表す変数の領域を確保しておくという意味でしょう。
- Dialog1側の準備。
Dialog1の中でEditメニューのNew Propertyで「w1 as window1」の宣言をしておきます。
- Dialog1からの使い方。
w1.statictext1.text=editfield1.text
w1.progressbar1.value=progressbar1.value
w1.listbox1.addrow editfield1.text
w1.canvas1.graphics.forecolor=rgb(50,scrollbar1.value,50)
w1.canvas1.graphics.fillrect 20,20,30,30
w1.canvas1.graphics.drawrect 10,10,50,50
のようになります。
「w1.statictext1.text=editfield1.text」はDialog1にあるeditfield1に書き込まれたテキストを、Window1にあるstatictext1に代入する、という意味です。
- Window1からDialog1に値を送り込むには特別に準備はいりません。Window1にあるeditfield1に書き込まれたテキストをDialog1にあるstatictext1やscrollbar1やprogressbar1に代入するには、Window1から次のようにします。
dim d1 as dialog1
d1= new dialog1
d1.statictext1.text=editfield1.text
d1.scrollbar1.value=val(editfield1.text)
d1.progressbar1.value=val(editfield1.text)
いくつかのコントロール(statictextやpushbuttonなど)を含んだサンプルを作っています。
ソースプログラム「tips2」のみです。REALbasic最新バージョンが必要です。30 kバイト
リンゴマークなどの特殊文字や矢印キーを使うためのアスキーコードを調べる方法。
Window1のKeyDownはキーボードから押されたキーを読みとるメソッドです。アルファベットのキーが押されたときはそのままの文字を返しますから問題ありませんが、矢印のキーやtabキーなどはアスキーコードを調べる必要があります。またリンゴマークなどの特殊文字もアスキーコードを調べておくといつでも使えて便利です。矢印キーでCanvas上の点を動かすサンプルです。
ソースプログラム「tips3」のみです。REALbasic最新バージョンが必要です。30 kバイト
ソースコードについての質問やご意見がありましたら以下のアドレスまでご連絡下さい。
koko-@mx2.tiki.ne.jp