RESaveProc

リッチエディットコントロールのファイル保存用の EditStreamCallback コールバック関数のサンプルコードです。

関数コード

関数のマシン語コードは以下のとおりです。スクリプトで以下のコードをそのまま記述し、この変数のアドレスを関数アドレスとして使用します。(実行には xdim.as が必要)

xdim fnRESaveProc, 9
fnRESaveProc.0 = $1024448b, $0c244c8b, $0824548b, $8b50006a, $510c2444
fnRESaveProc.5 = $51088b52, $f70450ff, $40c01bd8, $000010c2

使用方法

リッチエディットコントロールに EM_STREAMOUT メッセージを送信する際に、 EDITSTREAM 構造体のメンバを以下のように設定しておく必要があります。

dwCookie メンバには、 GENERIC_WRITE アクセスを持つファイルハンドルと、 WriteFile 関数のアドレスを順に格納した変数のアドレスを指定しておく必要があります。これらはコールバック関数の中で使用されるもので、以下のように定義付けられた内部構造体になっています。

typedef struct {
    HANDLE hFile;          // ファイルハンドル
    FARPROC pfnWriteFile;  // WriteFile 関数のアドレス
} RESAVEDATA;

hFile メンバには GENERIC_WRITE アクセスを持つファイルハンドルを格納してください。また、 pfnCallback メンバには、 WriteFile 関数のアドレスを格納してください。

《サンプルモジュール》 リッチエディット保存モジュール

モジュール定義命令
RichEditSaveFile n1, s2, n3
n1 :リッチエディットコントロールのハンドル
s2 :ファイル名
n3EM_STREAMOUTwParam の値
機能

リッチエディットに EM_STREAMOUT を送信し、内容をファイルに保存します。

実行後の stat

0 :正常に保存されました。

1 :ファイルのオープンに失敗しました。

2 :ファイルの書き込みに失敗しました。

    #include "xdim.as"

    #module

    #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

    #global

このコールバック関数のソースコード

#include 

typedef struct {
    HANDLE hFile;
    FARPROC pfnWriteFile;
} RESAVEDATA;

DWORD CALLBACK RESaveProc(
    DWORD   dwCookie,
    LPBYTE  pbBuffer,
    LONG    cb,
    LONG    *pcb
    )
{
    RESAVEDATA *pData = (RESAVEDATA *)dwCookie;
    // コールバック関数の引数をそのまま WriteFile 関数に渡します。
    if (pData->pfnWriteFile(pData->hFile, pbBuffer, cb, pcb, NULL) != FALSE)
        return 0;
    else
        return 1;
}