クイックポップアップ検索、スペルチェック(Wz Editor)

Wz Editor上でキャレットのある位置の単語のクイックポップアップ検索、および簡単なスペルチェックを行う機能です。
辞書に登録されていない単語があるとそこへジャンプします。
動詞の変化形なども考慮します。
PDICU.exeが起動されていない場合は自動的に起動されます。

スペルチェックのDDEはまだ未完成であり、性能・機能ともに改善する予定です。
例えば、大文字で始まる単語は無視するとか・・・

Wzのバージョンは3.00Dで動作確認。Ver.4.0で動作するかどうかは?です。

pdic.Popup
pdic.SpellCheck
pdic.RecordDialog

という名前でマクロを登録してください。最後のマクロを単語登録のダイアログを表示します。(おまけ)

ファイル名:pdic.c

#include <windows.h>
#include "winregtx.h"

BOOL OpenPDIC( );
void ClosePDIC();
void SpellCheck();
void RecordDialog();
void Popup();
BOOL StartPDIC();

void main()
{
    SpellCheck();
}

#include "ddewz.h"

// PDICの起動、DDEの確立、辞書のオープン
BOOL OpenPDIC( )
{
    if ( !ddeConnect( "PDICU", "Dictionary" ) ){
        if ( !StartPDIC() ){
            return FALSE;
        }
        if ( !ddeConnect( "PDICU", "Dictionary" ) ){
            attention("DDEリンク失敗しました");
            return FALSE;
        }
    }

//    ddePoke( "SetAnsi", "" );    // 文字列の文字コードをANSI(ShiftJIS)にする PDIC Ver.5.1.x以降は不要

    if ( !ddePoke( "Open", "" ) ){
        ddeDisconnect();
        attention( "Open失敗です" );
        return FALSE;
    }
    return TRUE;
}
// 辞書のクローズ、DDEの終了
void ClosePDIC()
{
    ddePoke( "Close", "" );

    ddeDisconnect();
}

void SpellCheck()
{
    if ( !OpenPDIC() ){
        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();
}

// 登録ダイアログボックスを表示 //
void _RecordDialog( 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( )
{
    if ( !OpenPDIC() ){
        return;
    }
    DWORD adr0 = txGetAddress( text );
    int ly0 = text->ly;
    txJumpWordTop(text);
    // 登録語の取得
    txstr line;
    txGetWord( text, line );
    // 表示を元に戻す
    txJumpAddress(text,adr0);
    txSetLy(text,ly0);
    // 登録ダイアログボックスを表示 //
    _RecordDialog( line );

    ClosePDIC();
}

void Popup()
{
    if ( !OpenPDIC() ){
        return;
    }
    DWORD adr0 = txGetAddress( text );
    int ly0 = text->ly;
    txJumpWordTop(text);
#if 0
    txLeft(text);
    WORD 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();
}

BOOL StartPDIC()
{
    HKEY hKey;
    if ( RegOpenKey( HKEY_CURRENT_USER, "SOFTWARE\\ReliefOffice\\PDIC2\\Common", &hKey ) != ERROR_SUCCESS ){
        attention("PDICU.exeが見つかりません(1)");
        return FALSE;
    }
    char pdic[ 256 + 20 ];
    DWORD type;
    LONG size = sizeof(pdic);
    if ( RegQueryValueEx( hKey, "Path", NULL, &type, pdic, &size ) != ERROR_SUCCESS ){
        RegCloseKey( hKey );
        attention("PDICU.exeが見つかりません(2)");
        return FALSE;
    }
    RegCloseKey( hKey );

    strcat(pdic, "\\PDICU.exe");

    // PDICの実行(最小化で起動)
    int r = WinExec( pdic, SW_SHOWMINNOACTIVE );
//★ 辞書グループを指定したい場合は代わりに次のようにする
//    strcat( pdic, " -d GroupName" );
//    WinExec( pdic, SW_SHOWMINNOACTIVE );
    if ( r <= 31 ){
        attention("PDICU.exeが起動できません.");
        return FALSE;
    }
    return TRUE;
}