
前回作成したリッチエディットは、コントロールに入力される文字すべてが最初に設定した文字書式で統一されていました。今回は、選択された部分の文字書式を自由に変えてみましょう。
前回説明した通り、文字の書式を設定をするには CHARFORMAT 構造体に書式情報を格納し、コントロールに EM_SETCHARFORMAT メッセージを送信します。
このとき、 EM_SETCHARFORMAT メッセージの wParam パラメータに 0x0001 (SCF_SELECTION) を指定すると、現在選択されている領域の文字書式を設定することができます。領域が選択されていない場合でも、現在のカーソル位置に次に入力される文字にはその書式が適用されます。
通常のWindows標準エディットコントロールでは、初期状態で 32K バイト未満、最大でも64Kバイト未満のテキストしか扱うことができませんでした。
リッチエディットコントロールでは、初期状態こそ標準エディットコントロールと同じ 32K バイトですが、テキストの上限サイズを設定し直すことで、はるかに多くのテキストを扱うことができるようになっているのです。
リッチエディットコントロールを作成した時点では、テキストサイズは 32K バイト未満となっているので EM_EXLIMITTEXT メッセージを送信して、テキストサイズの上限を増やします。
#define EM_EXLIMITTEXT 0x0435
EM_EXLIMITTEXT
wParam = 0;
lParam = cchTextMax;
cchTextMax パラメータには、新しく設定するテキストサイズをバイト単位で指定します。このパラメータに 0 を指定すると、 64K バイト未満のテキストが扱えるように設定されます。
今回は特に説明することはないので、さっそくスクリプトを書いてみましょう。
HSPウィンドウID2 を文字書式設定用のウィンドウとして使用します。「フォント変更」ボタンが押されたらこのウィンドウを表示して、「OK」ボタンが押されたらこのウィンドウを消して文字書式を実際に反映させます。
#include "llmod.as"
objsize winx, 24 : button "フォント変更", *lb_fontdialog
; RICHEDIT.DLLのロード
ll_libload hRtLib, "RICHED32.DLL"
; リッチエディットコントロールの作成
mref bmscr, 67 ; 描画中ウィンドウのBMSCR構造体
classname = "RichEdit"
pm.0 = 0
getptr pm.1, classname
pm.2 = 0
pm.3 = 0x50A00044 ; WS_CHILD | WS_VISIBLE | WS_BORDER
; | WS_VSCROLL | ES_MULTILINE
; | ES_AUTOVSCROLL
pm.4 = 0, 24, winx, winy-24
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
pm.3 = 10 * 1024 * 1024 ; 10Mバイトに設定
sendmsg pm
; デフォルトの書式
fontname = "MS ゴシック" ;フォント名
fontsize = 16 ; フォントの高さ(ピクセル単位)
clr = 0, 0, 0 ; 文字色(赤, 緑, 青)
fbold = 0 ; 1 のとき太字
fitalic = 0 ; 1 のときイタリック体
fudline = 0 ; 1 のとき下線付き
fstkout = 0 ; 1 のとき取り消し線付き
; 書式設定ウィンドウ
screen 2, 300, 300, 2 ; 非表示で作成
pos 20, 10 : mes "フォント名"
input fontname, 180, 24
pos 20, 60 : mes "フォントサイズ(ピクセル)"
input fontsize , 50, 24
pos 20, 110 : mes "フォントの色"
pos 30, 130 : mes "赤" : input clr.0, 50, 24
pos 100, 130 : mes "緑" : input clr.1, 50, 24
pos 170, 130 : mes "青" : input clr.2, 50, 24
objsize 100
pos 20, 180
chkbox "太字", fbold
chkbox "イタリック", fitalic
chkbox "下線", fudline
chkbox "取り消し線", fstkout
pos 160, 200 : button "OK", *lb_fontchange
pos 160, 240 : button "キャンセル", *lb_cansel
goto *lb_fontchange ; デフォルトの書式を反映させる
*lb_fontdialog
; 「フォント変更」ボタンが押されたとき
gsel 2, 1 ; 設定ウィンドウ表示
stop
*lb_fontchange
; デフォルト書式の設定 /「OK」ボタンが押されたとき
gsel 2, -1 ; 設定ウィンドウ非表示
fstyle = 0
if fbold : fstyle += 1 ; CFE_BOLD
if fitalic : fstyle += 2 ; CFE_ITALIC
if fudline : fstyle += 4 ; CFE_UNDERLINE
if fstkout : fstyle += 8 ; CFE_STRIKEOUT
; 文字書式を設定
; RichEditのデバイスコンテキスト取得
pm = hEdit
dllproc "GetDC", pm, 1, D_USER
hdcEdit = stat
; RichEditのy方向の1インチ当たりのピクセル数を取得
pm = hdcEdit, 90 ; LOGPIXELSY
dllproc "GetDeviceCaps", pm, 2, D_GDI
pxl = stat ; 1インチ当たりのピクセル数
; デバイスコンテキスト解放
pm = hEdit, hdcEdit
dllproc "ReleaseDC", pm, 2, D_USER
; CHARFORMAT 構造体
cfm.0 = 60
cfm.1 = 0xE800000F ; CFM_BOLD | CFM_ITALIC | CFM_UNDERLINE
; | CFM_STRIKEOUT | CFM_CHARSET
; | CFM_FACE | CFM_SIZE | CFM_COLOR
cfm.2 = fstyle
cfm.3 = fontsize*1440/pxl ; 文字高( pixel → twip に変換)
cfm.5 = clr.0 | (clr.1<<8) | (clr.2<<16) ; 文字色(0x00BBGGRR の形に)
poke cfm, 24, 128 ; SHIFTJIS_CHARSET
poke cfm, 26, fontname ; フォント名
; EM_SETCHARFORMATメッセージ送信
pm = hEdit, 0x0444
pm.2 = 0x0001 ; SCF_SELECTION
getptr pm.3, cfm ; CHARFORMAT構造体のアドレス
sendmsg pm
if stat == 0 : dialog "書式の設定に失敗しました。", 1, "エラー"
stop
*lb_cansel
;「キャンセル」ボタンが押されたとき
gsel 2, -1 ; 設定ウィンドウ非表示
stop