とぴやまのブログ(アーカイブ)

元はてなダイアリー

PDICW32 DDE使用例 スペルチェック Wz Editor の WZ5版

英辞郎 第二版に同梱されている PDIC for Win32 のヘルプファイルを眺めていたら WZ EDITOR 用のスペルチェックマクロが書かれているのを発見しました。しかしながら 今更 Ver 3.x用…。という訳で Version.5 用に改造してみました。ファイル名を "splchk5.txc" として保存してコンパイルしてください。「WM_COPYDATAによる方法」の部分は削除しました。
マクロ名と機能は次の通りです。

splchk5.main
スペルチェックを実行
splchk5.popup
ポップアップ検索
splchk5.RecordDialog
単語登録
#include <windows.h>
extern "ADVAPI32.DLL" RegOpenKeyA;
extern "ADVAPI32.DLL" RegQueryValueA;
extern "ADVAPI32.DLL" RegCloseKey;
BOOL StartPDIC(TX* text);
BOOL OpenPDIC(TX* text);
void ClosePDIC(TX* text);

// PDICの起動、DDEの確立、辞書のオープン
BOOL OpenPDIC(TX* text)
{
    if ( !ddeConnect( "PDICW", "Dictionary" ) ){
        if ( !StartPDIC(text) ){
            return FALSE;
        }
        if ( !ddeConnect( "PDICW", "Dictionary" ) ){
            attention("DDEリンク失敗しました");
            return FALSE;
        }
    }
    if ( !ddePoke( "Open", "" ) ){
        ddeDisconnect();
        attention( "Open失敗です" );
        return FALSE;
    }
    return TRUE;
}
// 辞書のクローズ、DDEの終了
void ClosePDIC(TX* text)
{
    ddePoke( "Close", "" );

    ddeDisconnect();
}

void main(TX* text)
{
    if ( !OpenPDIC(text) ){
        return;
    }
    txSetUndisp(text);
    DWORD adr0 = txGetAddress( text );
    int ly0 = text->ly;
    int lx0 = text->lx;
    txJumpWordTop(text);
    BOOL found = FALSE;
    for(;!found;){
        // 検索語の取得
        txstr line;
        txGetParaRear( text, line );
        // スペルチェックの初期化
        ddePoke( "SpellCheck", line );
        // チェック
        mchar *loc;
        ddeRequest( "SpellCheck", &loc );
        if ( loc[0] ){
            found = TRUE;
            // その単語へジャンプ //
            int l = atoi( loc );
            memFree( loc );
            txJumpLx( text, l+lx0 );
#if 0
            // 見つからなかった単語を選択 //
            txSelectEx( text, CLIP_CHAR );
            ddeRequest( "SpellCheckLength", &loc );
            l += atoi( loc );
            memFree( loc );
            txJumpLx( text, l+lx0 );
#endif
            break;
        }
        memFree( loc );
        if ( !txNextPara( text ) )
            break;
        lx0 = 0;
    }
    if ( !found ){
        // 表示を元に戻す
        txJumpAddress(text,adr0);
        txSetLy(text,ly0);
    }
    txSetDisp(text);
    ClosePDIC(text);
}

// 登録ダイアログボックスを表示 //
void _RecordDialog(TX* text, const char *word )
{
    // 表示座標を求める
    RECT rc;
    GetWindowRect( text->hwndtext, &rc );
    char buf[20];
    wsprintf( buf, "%d,%d", rc.left+text->x, rc.top + (text->ly+1) * text->cyLine );
    ddePoke( "DialogPoint", buf );

    ddePoke( "RecordDialog", word );

    //★ 辞書選択を必ず表示させたい場合はこちらを有効に
    // ddePoke( "RecordSelDialog", word );
}
// カーソル位置の単語を登録する(日本語訳入力ダイアログボックスつき) //
void RecordDialog(TX* text)
{
    if ( !OpenPDIC(text) ){
        return;
    }
    DWORD adr0 = txGetAddress( text );
    int ly0 = text->ly;
    txJumpWordTop(text);
    // 登録語の取得
    txstr line;
    txGetWord( text, line );
    // 表示を元に戻す
    txJumpAddress(text,adr0);
    txSetLy(text,ly0);
    // 登録ダイアログボックスを表示 //
    _RecordDialog(text, line );

    ClosePDIC(text);
}

void Popup(TX* text)
{
    if ( !OpenPDIC(text) ){
        return;
    }
    DWORD adr0 = txGetAddress( text );
    int ly0 = text->ly;
    txJumpWordTop(text);
#if 0
    txLeft(text);
    TXCHAR code = txGetChar(text);
    if ( ((code>='A') && (code<='Z'))
        || ((code>='a') && (code<='z'))
        || (code=='\'') )
    {
        txRight(text);
        txLeftWord(text);
    } else {
        txRight(text);
    }
#endif
    // 検索語の取得
    txstr line;
    txGetLineRear( text, line );
    // 表示を元に戻す
    txJumpAddress(text,adr0);
    txSetLy(text,ly0);
    // 表示座標を求める
    RECT rc;
    GetWindowRect( text->hwndtext, &rc );
    char buf[20];
    wsprintf( buf, "%d,%d", rc.left+text->x, rc.top + (text->ly+1) * text->cyLine );
    ddePoke( "PopupSearchPoint", buf );
    // 検索!
//    ddePoke( "PopupSearchConfig", "h0" );
    ddePoke( "PopupSearch", line );

    ClosePDIC(text);
}

BOOL StartPDIC(TX* text)
{
    HKEY hKey;
    if ( RegOpenKey( HKEY_LOCAL_MACHINE,
                    "SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\App Paths\\PDICW32.EXE",
                    &hKey ) != ERROR_SUCCESS ){
        attention("PDICW32.EXEが見つかりません");
        return FALSE;
    }
    char pdic[ 256 + 20 ];
    LONG size = sizeof(pdic);
    if ( RegQueryValue( hKey, "", pdic, &size ) != ERROR_SUCCESS ){
        RegCloseKey( hKey );
        attention("PDICW32.EXEが見つかりません");
        return FALSE;
    }
    RegCloseKey( hKey );

    // PDICの実行(アイコン状態で起動)
    UINT r = WinExec( pdic, SW_MINIMIZE );
//★ 辞書グループを指定したい場合は代わりに次のようにする
//        strcat( pdic, " -d GroupName" );
//        WinExec( pdic, SW_MINIMIZE );
    if ( r <= 31 ){
        attention("PDICW32.EXEが起動できません.");
        return FALSE;
    }
    return TRUE;
}