テキストエディター

ロード・セーブができるものすごく簡単なエディターを作っていきましょう。

作成するメニューは「新規作成」「開く」「保存」「カット」「コピー」「貼り付け」「検索」「終了」です。

スクリーンショットは下記の通りです。

	title "無題"
	sdim buf,32001 ; 32000バイト+1(NULL分)
	objsize 80,20
	font "MS ゴシック",12
	objmode 2
	pos   0,20 : mesbox buf,winx,winy-20,5
	pos   0, 0 : button "新規作成",new
	pos  80, 0 : button "開く",open
	pos 160, 0 : button "保存",save
	pos 240, 0 : button "切り取り",cut
	pos 320, 0 : button "コピー",copy
	pos 400, 0 : button "貼り付け",past
	pos 480, 0 : button "検索",serch
	pos 560, 0 : button "終了",exit
	tmp=0 ; objsendstop

とりあえず見た目部分だけ入りました…。

ボタン作っただけでジャンプ先の処理がありませんがエラーを出さずビジュアル部分だけを

とりあえず確認した方は(私もこのタイプ)下記のようにすることでみることだけは問題なく出来るでしょう。

暫定的に「button "××",@」としておけば実行できるようになります。ボタン押すとエラーとなりますが。

初めに「sdim buf,32001」としているのは32000バイトまで編集可能にするためです。

なぜ+1されてるのかというと文字列の終端「NULL(ココではEOFではなくNULL)」文字を付加するためです。

この文字は自動で付加されますが確保したサイズ分使用してしまうと大変なことになりかねないので

あらかじめ編集可能サイズ+1バイト分確保するようにしましょう。

ただnoteloadではNULL分確保されていないようだが???

 

それでは必要な機能を追加していきましょう。まずは新規作成から。

もし今オブジェクトにデータが入っていて初期化したい時アナタはいつもどのようにしていますか?

buf=""なんてしていませんか?

確かにこの方法が一番手っ取り早いでしょう。

しかし何回か変数に別のデータを入れると入っているデータにゴミ(前回読み込んだデータ)が付いた

と言う経験をお持ちの方が少なくないはずです。私もHSPやりだした頃やっちゃいました(--;

どういうのかと、(この通りにしてもならないとは思いますがそのうちなります)

	1.データ1読み込む(内容:abcdefg)
	2.オブジェクトに「abcdefg」と表示される
	3.変数を初期化(?)する
	4.データ2読み込む(内容:xyz)
	5.オブジェクトに「xyz」と表示される…はずが「xyzdefg」と表示される

buf=""と言うのは初期化じゃないとしたら何をしてくれているのでしょう?

私も初めアレを訳す(?)と「bufを空にする」と言うことなんだと思ってました。

しかし実際は変数bufの0バイト目に終端記号文字を入れるだけのようでした。

もともとHSPの文字列表示はNULL以降にデータがあってもNULLまでしか読み込まないようになっています。

それでイイのですが、何らかの手違いで新しいNULLが入らずNULL以降のデータも表示されてしまいます。

ですのでmemsetで全バイトNULLで埋めて初期化してしまいましょう。

別にsdimを使用し再確保することでもイイのですがサイズを変更することがないのであれば

良くはわからないのですがmemsetの方がパソコンにとって優しい(?)ようです。

まぁ初期化の度に毎回今回の文字列の最後にNULL文字を足してやればゴミが付くことないはずですが…。

*new ; 新規作成
	title "無題"
	memset buf,0,32000 ; 変数bufの32000バイト分0(NULL)でクリアする
	objprm 0,buf
	stop

*exit
	end

コレで一番初め(起動直後の状態)に戻せました。

一応終了ボタンの処理も簡単だし先に入れておきました。

 

読み込みは下記の感じで。

*open
	dialog "txt",16
	if stat==0 : stop ; キャンセル・エラーで読み込み中止
	memset buf,0,32000
	title ""+refstr
	exist refstr ; ファイルのサイズがリミッターを超えていないかチェック
	if strsize > 32000 : dialog "32000バイトまで読み込みます" : size=32000 : else : size=strsize
	bload refstr,buf,size
	objprm 0,buf
	stop

コレでどんなサイズでも読み込みに対するエラーはでない…はずです。

32000バイト以上のものであれば32000バイトまでしか読み込みません。

多く確保しても9X系ではEDITコントロールに32KB(32765バイト?)までしかダメと聞いた様な気がします。

ですのでキリのよさそうな32000バイトまでとしてみたわけです。

HSP2.6以上であれば読み込みをnoteselを使ってnoteloadを使用しても構いません。

ただ上記のように32KB以上読み込んでも表示・編集できずに終わってしまうのなら意味がない気がします。

 

*save ; 保存
	dialog "txt",17
	if stat==0 : stop ; キャンセル・エラーで保存中止
	title ""+refstr ; タイトルバーを保存先パスに変更する
	strlen len,buf
	bsave refstr,buf,len ; 変数bufのサイズ(NULLまでのサイズ)分だけセーブする
	stop

保存は上記のような感じとなるでしょう。

しかしこのままだとダイアログに表示される「*.txt」の部分がユーザーによって消された場合面倒です。

ファイル名の最後4バイトを確認して「.txt」で間違いなければそのままで

違うなら「.txt」を最後につけるようにしてやればよいでしょう。

ただ判定がまた少し面倒ですね。大文字小文字が混ざっていればややこしいです。8通りあるかな?

判定用にだけ抜き出した部分だけ全部小文字にしてやるとか回避してあげましょう。

 

後はエディターにある当たり前の機能です。

一応どの機能もobjsendを使用しています。

TIPSを見ていただければobjsendについてはお分かりいただけると思います。

*cut
	objsend 0,$300,0,tmp,1 ; 切り取り
	stop

*copy
	objsend 0,$301,0,tmp,1 ; コピー
	stop

*past
	objsend 0,$302,0,tmp,1 ; 貼り付け
	stop

*serch
	word=""
	screen 2,200,35
	title ""
	gsel 2,2
	objsize 40,25
	pos 10,5 : input word,130,25,64
	pos 150,5 : button "検索",ok
	stop

*ok
	gsel 2,-1
	gsel 0
	objsel 0 ; 検索先のオブジェクトを選択しておく
	instr ichi,buf,word,0 ; ichiに検索する文字列の始まりのINDEXが入る(ない場合-1が入る)
	if ichi < 0 : dialog "「"+word+"」は存在しません" : stop
	strlen len,word ; 検索する文字列の文字数をlenに代入
	ichiend=len+ichi ; ichiend検索する文字列の終わりのINDEXが入る
	objsend 0,$b1,ichi,ichiend,1
	stop

検索で選択された文字列を別物に置き換えればそれで立派な「置換」の完成ですね。

ソレを追加してもまだ少し物足りませんね。

他のソフトにはない自分だけのオリジナル機能をつけてみてはいかがでしょう?

標準だけでは少し難しいですがDLLを使ってメニューバーやステータスバーを付けてみるのもいいでしょう。

本章のスクリプトはコチラから。

よい作品を作ってください。ではー。