RTFの保存・読み込みをしてみる ACT-2

サンプルスクリプト

さっそくスクリプトを書いてみましょう。

リッチエディットコントロールの操作部分は、モジュール命令を定義してそれを使うことにします。

サンプルスクリプト main.as

    #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