さっそくスクリプトを書いてみましょう。
リッチエディットコントロールの操作部分は、モジュール命令を定義してそれを使うことにします。
#include "llmod.as"
#include "xdim.as"
#module ;#### リッチエディットコントロール作成モジュール ########
;===============================================================
; リッチエディットコントロールの作成
; CreateRichEdit n1, n2, n3, n4, n5
; n1 : x座標
; n2 : y座標
; n3 : 幅
; n4 : 高さ
; n5 : テキスト上限サイズ( 0 のとき 64KB)
; stat : リッチエディットコントロールのハンドルが返る
;===============================================================
#deffunc CreateRichEdit int, int, int, int, int
mref cx, 0 ; x位置
mref cy, 1 ; y位置
mref sx, 2 ; 幅
mref sy, 3 ; 高さ
mref maxsize, 4 ; テキスト上限サイズ
mref bmscr, 67 ; 描画中ウィンドウのBMSCR構造体
mref stt, 64 ; stat
; RICHEDIT.DLLのロード
ll_libload@ hdllRichEd, "RICHED32.DLL"
; リッチエディットコントロールの作成
classname = "RichEdit"
pm.0 = 0
getptr pm.1, classname
pm.2 = 0
pm.3 = 0x50B020C4 ; WS_CHILD | WS_VISIBLE | WS_BORDER
; | WS_VSCROLL | WS_HSCROLL
; | ES_MULTILINE | ES_AUTOVSCROLL
; | ES_AUTOHSCROLL | ES_DISABLENOSCROLL
pm.4 = cx, cy, sx, sy
pm.8 = bmscr.13 ; 描画中HSPウィンドウのハンドル
pm.9 = 0xFF00 ; コントロールID (大きめに指定)
_get_instance pm.10 ; インスタンスハンドル取得
pm.11 = 0
dllproc "CreateWindowExA", pm, 12, D_USER@
hEdit = stat ; リッチエディットのハンドル
; テキストサイズの上限の設定
; EM_EXLIMITTEXT メッセージ送信
pm = hEdit, 0x0435, 0, maxsize
sendmsg pm
stt = hEdit
return
;===============================================================
; 背景色を設定
; RichEditBkColor n1, n2
; n1 : リッチエディットコントロールのハンドル
; n2 : 背景色のRGB値
;===============================================================
#deffunc RichEditBkColor int, int
mref hEdit, 0 ; リッチエディットコントロールのハンドル
mref bkclr, 1 ; 背景色
; EM_SETBKGNDCOLOR メッセージ送信
pm = hEdit, 0x0443, 0, bkclr
sendmsg pm
return
;===============================================================
; リッチエディットコントロールの内容をファイルに保存
; RichEditSaveFile n1, s2, n3
; n1 : リッチエディットコントロールのハンドル
; s2 : ファイル名
; n3 : データ形式(1:テキスト 2:RTF)
; stat : 0:成功, 1:ファイルオープン失敗, 2:書き込み失敗
;===============================================================
#deffunc RichEditSaveFile int, str, int
mref hEdit, 0 ; リッチエディットコントロールのハンドル
mref setfilename, 33 ; ファイル名
mref fmt, 2 ; EM_STREAMOUTの wParam 値
mref stt, 64 ; stat
sdim filename, 260
filename = setfilename ; いったん別の変数に移す
; コールバック関数のコード
xdim fnRESaveProc, 9
fnRESaveProc.0 = $1024448b, $0c244c8b, $0824548b, $8b50006a, $510c2444
fnRESaveProc.5 = $51088b52, $f70450ff, $40c01bd8, $000010c2
; ファイルをオープン(作成)する
pm = 0, $40000000, 0, 0, 2, 0, 0
getptr pm.0, filename ; ファイル名文字列のアドレス
dllproc "CreateFileA", pm, 7, D_KERNEL@
hFile = stat
if hFile == -1 : stt = 1 : return
; 内部構造体(ファイルハンドルおよび ReadFile 関数のアドレス)
savedata = hFile
dll_getfunc savedata.1, "WriteFile", D_KERNEL@
; EDITSTREAM 構造体
getptr edstream.0, savedata ; 内部構造体のアドレス
edstream.1 = 0
getptr edstream.2, fnRESaveProc ; コールバック関数のアドレス
; EM_STREAMOUT メッセージ送信
pm = hEdit, 0x044A, fmt
getptr pm.3, edstream
sendmsg pm
; ハンドルをクローズ
dllproc "CloseHandle", hFile, 1, D_KERNEL@
if edstream.1 : stt = 2 : else : stt = 0
return
return
;===============================================================
; ファイルの内容をリッチエディットコントロールに読み込む
; RichEditLoadFile n1, s2, n3
; n1 : リッチエディットコントロールのハンドル
; s2 : ファイル名
; n3 : データ形式(1:テキスト 2:RTF)
; stat : 0:成功, 1:ファイルオープン失敗, 2:読み込み失敗
;===============================================================
#deffunc RichEditLoadFile int, str, int
mref hEdit, 0 ; リッチエディットコントロールのハンドル
mref setfilename, 33 ; ファイル名
mref fmt, 2 ; EM_STREAMOUTの wParam 値
mref stt, 64 ; stat
sdim filename, 260
filename = setfilename ; いったん別の変数に移す
; コールバック関数のコード
xdim fnRELoadProc, 9
fnRELoadProc.0 = $1024448b, $0c244c8b, $0824548b, $8b50006a, $510c2444
fnRELoadProc.5 = $51088b52, $f70450ff, $40c01bd8, $000010c2
; ファイルをオープンする
pm = 0, $80000000, 0, 0, 3, 0, 0
getptr pm.0, filename
dllproc "CreateFileA", pm, 7, D_KERNEL@
hFile = stat
if hFile == -1 : stt = 1 : return
; 内部構造体(ファイルハンドルおよび ReadFile 関数のアドレス)
loaddata = hFile
dll_getfunc loaddata.1, "ReadFile", D_KERNEL@
; EDITSTREAM 構造体
getptr edstream.0, loaddata ; 内部構造体のアドレス
edstream.1 = 0
getptr edstream.2, fnRELoadProc ; コールバック関数のアドレス
; EM_STREAMIN メッセージ送信
pm = hEdit, 0x0449, fmt
getptr pm.3, edstream
sendmsg pm
; ハンドルをクローズ
dllproc "CloseHandle", hFile, 1, D_KERNEL@
if edstream.1 : stt = 2 : else : stt = 0
return
;===============================================================
; EM_SETMODIFY メッセージの送信
; RichEditFontDialog n1
; n1 : リッチエディットコントロールのハンドル
; stat : 0:成功, 1:失敗
;===============================================================
#deffunc RichEditFontDialog int
mref hEdit, 0 ; リッチエディットコントロールのハンドル
mref stt, 64 ; stat
if hdllComdlg == 0 {
; COMDLG32.DLLのロード
ll_libload@ hdllComdlg, "COMDLG32.DLL"
}
; CHOOSEFONT 構造体を変数 chfont にとる
; LOGFONT 構造体を変数 logfont にとる
mref bmscr, 67 ; HSPウィンドウのBMSCR構造体取得
; CHOOSEFONT 構造体
chfont.0 = 60 ; 構造体サイズ(=60)
chfont.1 = bmscr.13 ; ウィンドウハンドル
getptr chfont.3, logfont ; LOGFONT 構造体アドレス
chfont.5 = 0x01000141 ; CF_SCREENFONTS | CF_INITTOLOGFONTSTRUCT
; | CF_EFFECTS | CF_NOVERTFONTS
; フォント選択ダイアログボックスの表示
getptr pm, chfont
dllproc "ChooseFontA", pm, 1, hdllComdlg
if stat == 0 : stop ; キャンセルされた
; CHARFORMAT 構造体を変数 charfmt にとる
dim charfmt, 16
charfmt.0 = 60 ; 構造体サイズ
charfmt.1 = 0xE800000F ; CFM_BOLD | CFM_ITALIC | CFM_UNDERLINE
; | CFM_STRIKEOUT | CFM_FACE | CFM_COLOR
; | CFM_SIZE
charfmt.2 = 0
if (chfont.12 & 0x0100) { ; BOLD_FONTTYPEタイプを持つ場合
charfmt.2 = charfmt.2 | 0x0001 ; CFE_BOLDを加える(太字)
}
if (chfont.12 & 0x0200) { ; ITALIC_FONTTYPEタイプを持つ場合
charfmt.2 = charfmt.2 | 0x0002 ; CFE_ITALICを加える(イタリック体)
}
if (logfont.5 & 0x0000FF00) { ; lfUnderlineが指定されている場合
charfmt.2 = charfmt.2 | 0x0004 ; CFE_UNDERLINEを加える(下線)
}
if (logfont.5 & 0x00FF0000) { ; lfStrikeOutが指定されている場合
charfmt.2 = charfmt.2 | 0x0008 ; CFE_STRIKEOUTを加える(打ち消し線)
}
charfmt.3 = chfont.4 * 2 ; サイズ変換(1/10 point → twip)
charfmt.5 = chfont.6 ; 文字色
peek t, logfont, 23 ; LOGFONT からキャラクタセット取得
poke charfmt, 24, t ; CHARFORMAT にキャラクタセット設定
peek t, logfont, 27 ; LOGFONT からピッチ・ファミリ値取得
poke charfmt, 25, t ; CHARFORMAT にピッチ・ファミリ値設定
sdim fontname, 32
peek fontname, logfont, 28 ; LOGFONT からフォント名取得
poke charfmt, 26, fontname ; CHARFORMAT にフォント名設定
; EM_SETCHARFORMAT メッセージ送信
pm = hEdit, 0x0444
pm.2 = 0x0001 ; SCF_SELECTION
getptr pm.3, charfmt ; CHARFORMAT構造体のアドレス
sendmsg pm
if stat : stt = 0 : else : stt = 1
return
#global ;############# モジュール終わり ########################
#define SF_TEXT 1
#define SF_RTF 2
objsize winx/5, 24
pos 0, 0 : button "Open as RTF", *lb_open ; ID = 0
pos winx/5, 0 : button "Open as Text", *lb_open ; ID = 1
pos winx*2/5, 0 : button "Save as RTF", *lb_save ; ID = 2
pos winx*3/5, 0 : button "Save as Text", *lb_save ; ID = 3
pos winx*4/5, 0 : button "Font", *lb_chfont ; ID = 4
CreateRichEdit 0, 24, winx, winy-24
hEdit = stat
if hEdit == 0 : dialog "リッチエディットの作成に失敗", 1 : end
stop
*lb_open
if stat == 0 {
fmt = SF_RTF : ext = "rtf" : type = "RTF"
} else {
fmt = SF_TEXT : ext = "txt" : type = "テキスト"
}
dialog ext, 16, type+"ファイル"
if stat == 0 : stop
RichEditLoadFile hEdit, refstr, fmt
if stat {
if stat == 1 {
dialog "ファイルをオープンできませんでした。", 1
} else {
dialog "読み込み時にエラーが発生しました。", 1
}
}
stop
*lb_save
if stat == 2 {
fmt = SF_RTF : ext = "rtf" : type = "RTF"
} else {
fmt = SF_TEXT : ext = "txt" : type = "テキスト"
}
dialog ext, 17, type+"ファイル"
if stat == 0 : stop
RichEditSaveFile hEdit, refstr, fmt
if stat {
if stat == 1 {
dialog "ファイルをオープンできませんでした。", 1
} else {
dialog "書き込み時にエラーが発生しました。", 1
}
}
stop
*lb_chfont
RichEditFontDialog hEdit
stop