/*
EBminiSearch.txc
ebmini書籍検索 for WZ Editor 5.0
(c) 2005-2009 Kiichiro Kawano
無保証です。自身の責任のもとでご利用ください。
◎ebminiのセットアップ
ebmini.exeと必要なDLL、検索用バッチファイルをパスの通ったディレクトリに
置き、設定ファイルを任意のディレクトリに置く。バッチファイルと設定ファイル
中でパスを指定している部分(EBMINI_CFGFILEとBookPathの行)は、実際の環境に
合わせて書き換える。
◎マクロの割り当て
タイトルコメントに★のついている以下の関数が直接呼び出せる関数なので、必要な
ものをキーなどに割り当てる。
・config
設定ダイアログを開く。
・reference
現在のカーソル位置より後方にある最初の参照リンクを辿る。
・back/forward
検索結果のヒストリを一つ前へ戻る/先へ進む。
・main
メイン関数。デフォルトの書籍を選択して起動。
・book01〜
番号の書籍を直接指定した状態で起動。
※book01以降は、関数を複製して数字の部分を書き換えることで、特定の書籍を
直接指定して起動する関数を追加可能。
◎マクロの設定
設定ダイアログで以下の設定をする。
○書籍一覧
編集コマンドで任意の番号に書籍データを割り当てる。
・書籍名
書籍の名前を指定。
・検索用コマンド名
検索用バッチファイルのファイル名を指定。
・参照リンクのID文字列
ebmini用設定ファイルの%BeginReferenceや%EndReferenceの項目に記述した、
各書籍の参照リンク内に表示するID文字列を指定。
reference関数で参照リンクを辿るのに必要。
(串刺し検索用の設定の場合はそれ自体にID文字列を指定する必要はないが、
検索結果から各書籍の参照リンクを辿るためには、各書籍を単体で検索する
設定も別に作っておく必要あり)
・IMEの状態
起動時のIMEの挙動を指定。
○コマンドインタプリタ
使用するコマンドインタプリタと実行時のウインドウの状態を指定する。
※実行時のウインドウについて
SW_HIDEやSW_MINIMIZEを指定すると、コマンドインタプリタのウインドウを表に
出さずに実行することができる。
ただ、コマンドインタプリタにcommand.comを使う場合はウインドウが表にないと
速度が大幅に低下することがあるらしい(WindowsMeで発生。9X系固有の現象か)
ので、SW_SHOWNORMALを指定して表に出したほうがいいかもしれない。
ウインドウが目障りな場合は、command.comのプロパティでフォントサイズ2×4
などを選ぶとウインドウが小さくなるので、その状態で画面の右下あたりに
出るようにしておくとあまり目立たなくなる。
◎作業ファイル
検索結果とヒストリ用のファイルはテンポラリディレクトリに溜まる仕様。
以下のファイルを削除すればクリアできる。
ヒストリ情報 EBminiSearch.wz.histinfo.txt
ヒストリデータ EBminiSearch.wz.histdata.txt
検索結果 ebdata-wz-????????????.ebr(?は数字)
*/
#include <windows.h>
extern "user32.dll" {
BOOL WINAPI SetForegroundWindow(HWND hWnd);
}
//. グローバル変数
//.. 書籍テーブル
#define BOOK_MAX 40
typedef struct {
txstr szBookName; // 書籍名
txstr szCommand; // 検索用バッチコマンド名
txstr szReferenceId; // 参照リンクのID
int iImeState; // 検索ダイアログオープン時のIMEの状態
} BOOK_STRUCT;
BOOK_STRUCT g_book_table[BOOK_MAX + 1];
permanent int p_iDefaultBookNumber = 1;
mchar *g_pszImeStateChoice[] = {
"変更しない",
"OFFにする",
"ONにする",
NULL,
};
#define IME_STATE_NOCHANGE 0
#define IME_STATE_OFF 1
#define IME_STATE_ON 2
//.. 本文の表示選択肢
mchar *g_pszTextViewChoice[] = {
"非表示",
"標準",
"20項目",
"256項目",
"最大",
NULL,
};
mchar *g_pszTextView[] = {
"-",
"+",
"20",
"256",
"max",
};
int g_iTextViewIndex;
permanent int p_iTextViewIndex = 1;
//.. 見出し一覧の表示選択肢
mchar *g_pszListViewChoice[] = {
"非表示",
"20項目",
"256項目",
"最大",
NULL,
};
mchar *g_pszListView[] = {
"-",
"20",
"256",
"max",
};
int g_iListViewIndex;
permanent int p_iListViewIndex = 1;
//.. 使用するコマンドインタプリタ選択肢
mchar *g_pszCmdShellChoice[] = {
"cmd.exe(WindowsXP系)",
"command.com(Windows9X系)",
NULL,
};
mchar *g_pszCmdShell[] = {
"cmd.exe /c",
"command.com /e:4096 /c",
};
permanent int p_iCmdShellIndex = 0;
//.. 実行時のウインドウの状態選択肢
mchar *g_pszCmdShowChoice[] = {
"SW_SHOWNORMAL(通常のウインドウ)",
"SW_MINIMIZE(最小化)",
"SW_HIDE(非表示)",
NULL,
};
int g_iCmdShow[] = {
SW_SHOWNORMAL,
SW_MINIMIZE,
SW_HIDE,
};
permanent int p_iCmdShowIndex = 0;
//.. その他
mchar *g_pszConfigFileName = "EBminiSearch.ini"; // 設定ファイル名
int g_iTargetBookNumber; // 検索する書籍
BOOL g_fUseClipBoard; // クリップボードから検索語を取得するかどうか
mchar g_szResultFileName[] = "ebdata-wz-";
// 検索結果ファイル名の固定部分
// これに日付を加えたものが検索結果ファイル名となる
mchar g_szResultFileExt[] = ".ebr";
// 検索結果ファイル拡張子
// 結果ファイル専用の設定を作る場合は、ここで指定した拡張子を登録する
mchar g_szHistInfoFile[] = "EBminiSearch.wz.histinfo.txt";
// 検索結果ヒストリの行数と現在位置を記録するファイルの名前
mchar g_szHistDataFile[] = "EBminiSearch.wz.histdata.txt";
// 検索結果ヒストリを記録するファイルの名前
//. サブ関数
//.. クリップボード取得
void get_clipboard(txstr szClipBoardString)
{
TX *temp_text;
temp_text = textnew();
txPaste(temp_text);
txSelect(temp_text);
txJumpFileTop(temp_text);
txGetWord(temp_text, szClipBoardString);
textclose(temp_text);
}
//.. 検索語内の文字を変換
struct {
mchar *pszOrg;
mchar *pszNew;
}
g_conv_table[] = {
{ "\\", "\\\\" },
{ "!", "" },
{ "\"", "" },
{ "'", "" },
{ ",", "" },
{ "-", "" },
{ ".", "" },
{ "?", "" },
{ "__", "" },
{ "_", "" },
{ "~", "" },
{ "・", "" },
{ NULL, NULL }
};
void conv_search_word(txstr szSearchWord)
{
txstr szNewWord = "";
mchar *psz;
int i;
psz = szSearchWord;
while (*psz) {
BOOL fConverted = FALSE;
for (i = 0; g_conv_table[i].pszOrg != NULL; ++i) {
if (strncmp(psz, g_conv_table[i].pszOrg, strlen(g_conv_table[i].pszOrg)) == 0) {
szNewWord += g_conv_table[i].pszNew;
psz += strlen(g_conv_table[i].pszOrg);
fConverted = TRUE;
break;
}
}
if (!fConverted) {
szNewWord += chartostr(*psz);
++psz;
}
}
szSearchWord = szNewWord;
}
//.. 文字列から単語を取得
// pszStr先頭部分のスペース・タブはスキップ
// 以降の文字列を次に半角空白文字が出現するか'\0'に達するまでpszBuffにコピー
// 半角空白文字または'\0'を指すポインタを返す
mchar *getword_by_space(mchar *pszBuff, mchar *pszStr)
{
mchar *psz1, *psz2;
psz1 = strGetWordTop(pszStr);
psz2 = pszBuff;
while (*psz1) {
if (isspace(*psz1))
break;
*psz2++ = *psz1++;
}
*psz2 = '\0';
return psz1;
}
//.. 区切り文字列を指定して単語を取得
// pszStr先頭部分のスペース・タブはスキップ
// 以降の文字列を指定した区切り文字列が出現するか'\0'に達するまでpszBuffにコピー
// 区切り文字列の次の文字または'\0'を指すポインタを返す
mchar *getword_by_delim(mchar *pszBuff, mchar *pszStr, mchar *pszDelim)
{
mchar *psz1, *psz2;
psz1 = strGetWordTop(pszStr);
psz2 = pszBuff;
while (*psz1) {
if (strncmp(psz1, pszDelim, strlen(pszDelim)) == 0)
break;
*psz2++ = *psz1++;
}
*psz2 = '\0';
psz1 += strlen(pszDelim);
return psz1;
}
//.. 子プロセスの起動(終了待ちあり)
BOOL ChildExec32(mchar *pszCmdLine, int nCmdShow, DWORD dwTimeout)
{
PROCESS_INFORMATION processinfo;
STARTUPINFO startinfo;
memset(&startinfo, 0, sizeof(startinfo));
startinfo.cb = sizeof(startinfo);
startinfo.dwFlags = STARTF_USESHOWWINDOW;
startinfo.wShowWindow = nCmdShow;
BOOL ret = TRUE;
if (!CreateProcess(NULL, pszCmdLine, NULL, NULL, FALSE, 0, NULL, NULL, &startinfo, &processinfo)) {
ret = FALSE;
}
else {
if (WaitForSingleObject(processinfo.hProcess, dwTimeout) == WAIT_TIMEOUT) {
ret = FALSE;
}
CloseHandle(processinfo.hThread);
CloseHandle(processinfo.hProcess);
}
return ret;
}
//. 設定
//.. 設定の読み込み
void config_read()
{
int i;
txstr szConfigFilePath;
TX *cfg_text;
mchar szpara[MAXPARASIZE];
txstr szstr;
mchar *psz1;
for (i = 1; i <= BOOK_MAX; ++i)
structClear(g_book_table[i]);
pathFullConfig(szConfigFilePath, g_pszConfigFileName);
if (fileIsExist(szConfigFilePath)) {
cfg_text = textopen(szConfigFilePath);
do {
txGetParaEx(cfg_text, szpara, MAXPARASIZE);
psz1 = getword_by_delim(szstr, szpara, ",");
i = atoi(szstr);
if (1 <= i && i <= BOOK_MAX) {
psz1 = getword_by_delim(szstr, psz1, ",");
g_book_table[i].szBookName = szstr;
psz1 = getword_by_delim(szstr, psz1, ",");
g_book_table[i].szCommand = szstr;
psz1 = getword_by_delim(szstr, psz1, ",");
g_book_table[i].szReferenceId = szstr;
psz1 = getword_by_delim(szstr, psz1, ",");
g_book_table[i].iImeState = atoi(szstr);
switch (g_book_table[i].iImeState) {
case IME_STATE_NOCHANGE:
case IME_STATE_OFF:
case IME_STATE_ON:
break;
default:
g_book_table[i].iImeState = IME_STATE_NOCHANGE;
break;
}
}
} while(txNextPara(cfg_text));
textclose(cfg_text);
}
else {
statprintf("設定ファイルは未作成です");
}
}
//.. 設定の書き込み
void config_write()
{
TX *cfg_text;
int i;
txstr szConfigFilePath;
cfg_text = textnew();
for (i = 1; i <= BOOK_MAX; ++i) {
if (g_book_table[i].szBookName != "") {
txInsertf(cfg_text, "%d,%s,%s,%s,%d\n",
i,
g_book_table[i].szBookName,
g_book_table[i].szCommand,
g_book_table[i].szReferenceId,
g_book_table[i].iImeState
);
}
}
pathFullConfig(szConfigFilePath, g_pszConfigFileName);
txSaveTo(cfg_text, szConfigFilePath);
textclose(cfg_text);
}
//.. 項目の編集ダイアログ
void itemedit_dialog(int index)
{
int i;
txstr sz1;
// IME関係の選択肢を文字列ブロックで作成
HSTRBLK sb_ime;
sb_ime = sbNewAlloc(1024);
for (i = 0; g_pszImeStateChoice[i] != NULL; ++i)
sbAdd(sb_ime, g_pszImeStateChoice[i]);
HDIALOG hd;
sprintf (sz1, "項目%02dの編集", index);
hd = dialog(sz1);
dialogTxstr(hd, "書籍名(&B):", 20, g_book_table[index].szBookName, 40);
dialogTxstr(hd, "検索用コマンド名(&C):", 20, g_book_table[index].szCommand, 40);
dialogTxstr(hd, "参照リンクのID文字列(&R):", 20, g_book_table[index].szReferenceId, 40);
dialogControlStrblk(hd, sb_ime);
dialogChoice(hd, "IMEの状態(&I):", 20, &g_book_table[index].iImeState, 20, NULL);
dialogSetPosY(hd, dialogGetPosY(hd) + 10);
dialogSetPosX(hd, dialogGetPosX(hd) + 150);
dialogSetH(hd);
dialogOK(hd, 12);
dialogCancel(hd, 12);
dialogOpen(hd);
sbDelete(sb_ime);
}
//.. ★設定ダイアログ
void config(TX *text)
{
TX *booklist_text;
int iBookNumber;
int i;
BOOK_STRUCT item_temp;
booklist_text = textnew();
// コマンドインタプリタ関係の選択肢を文字列ブロックで作成
HSTRBLK sb_cmdshell, sb_cmdshow;
sb_cmdshell = sbNewAlloc(1024);
for (i = 0; g_pszCmdShellChoice[i] != NULL; ++i)
sbAdd(sb_cmdshell, g_pszCmdShellChoice[i]);
sb_cmdshow = sbNewAlloc(1024);
for (i = 0; g_pszCmdShowChoice[i] != NULL; ++i)
sbAdd(sb_cmdshow, g_pszCmdShowChoice[i]);
config_read();
iBookNumber = 1;
for (;;) {
// 書籍一覧を裏テキストに作成
txDeleteText(booklist_text);
for (i = 1; i <= BOOK_MAX; ++i)
txInsertf(booklist_text, "%02d: %s\n", i, g_book_table[i].szBookName);
txJumpNpara(booklist_text, iBookNumber);
HDIALOG hd;
int id;
int id_edit, id_delete, id_up, id_down;
hd = dialog("EBminiSearchの設定");
dialogList(hd, "書籍一覧(&B)", booklist_text, 50, 20);
dialogLFV(hd);
dialogSetPosY(hd, dialogGetPosY(hd) + 12);
id_edit = dialogCmd(hd, "編集(&E)", 10);
id_delete = dialogCmd(hd, "消去(&D)", 10);
id_up = dialogCmd(hd, "↑(&[)", 10);
id_down = dialogCmd(hd, "↓(&])", 10);
dialogLF(hd);
dialogHeadline(hd, "コマンドインタプリタ", 60);
dialogControlStrblk(hd, sb_cmdshell);
dialogChoice(hd, "使用コマンド(&C):", 20, &p_iCmdShellIndex, 35, NULL);
dialogControlStrblk(hd, sb_cmdshow);
dialogChoice(hd, "実行時のウインドウ(&W):", 20, &p_iCmdShowIndex, 35, NULL);
dialogSetPosY(hd, dialogGetPosY(hd) + 10);
dialogSetPosX(hd, dialogGetPosX(hd) + 140);
dialogSetH(hd);
dialogOK(hd, 12);
dialogCancel(hd, 12);
id = dialogOpen(hd);
if (id == 0) {
break;
}
else if (id == IDOK) {
config_write();
break;
}
else if (id == id_edit) {
iBookNumber = booklist_text->npara;
itemedit_dialog(iBookNumber);
}
else if (id == id_delete) {
iBookNumber = booklist_text->npara;
structClear(g_book_table[iBookNumber]);
}
else if (id == id_up) {
iBookNumber = booklist_text->npara;
if (iBookNumber > 1) {
i = iBookNumber - 1;
item_temp = g_book_table[iBookNumber];
g_book_table[iBookNumber] = g_book_table[i];
g_book_table[i] = item_temp;
iBookNumber = i;
}
}
else if (id == id_down) {
iBookNumber = booklist_text->npara;
if (iBookNumber < BOOK_MAX) {
i = iBookNumber + 1;
item_temp = g_book_table[iBookNumber];
g_book_table[iBookNumber] = g_book_table[i];
g_book_table[i] = item_temp;
iBookNumber = i;
}
}
}
textclose(booklist_text);
sbDelete(sb_cmdshell);
sbDelete(sb_cmdshow);
}
//. 検索
//.. 指定したもの以外で閲覧中の検索結果ファイルを閉じる
void close_prev_results(mchar *pszResultFile)
{
HWND temp_hwnd = GetWindowDesktopChild();
mchar szBuff[CCHPATHNAME];
while (temp_hwnd) {
GetWindowText(temp_hwnd, szBuff, CCHPATHNAME);
if (strstr(szBuff, g_szResultFileName) != NULL && strstr(szBuff, g_szResultFileExt) != NULL) {
if (strstr(szBuff, pszResultFile) == NULL)
PostMessage(temp_hwnd, WM_CLOSE, 0, 0);
}
temp_hwnd = GetWindow(temp_hwnd, GW_HWNDNEXT);
}
}
//.. コマンド実行&結果オープン
void search_exec(mchar *pszSearchCmd, mchar *pszSearchMethod, mchar *pszSearchInput)
{
// 検索結果ファイルのパスを設定
txstr szResultPath;
txstr szResultFile;
GetTempPath(CCHPATHNAME, szResultPath);
pathSetDir(szResultPath);
sprintf(szResultFile, "%s%02d%02d%02d%02d%02d%02d%s",
g_szResultFileName,
timeGetYear() % 100, timeGetMonth(), timeGetDay(),
timeGetHour(), timeGetMinute(), timeGetSecond(),
g_szResultFileExt
);
szResultPath += szResultFile;
// 検索コマンド実行
txstr szCmdLine;
sprintf(szCmdLine, "%s %s %s %s %s %s %s",
g_pszCmdShell[p_iCmdShellIndex],
pszSearchCmd,
szResultPath,
pszSearchMethod,
g_pszTextView[g_iTextViewIndex],
g_pszListView[g_iListViewIndex],
pszSearchInput
);
// information("%s\n%d\n", szCmdLine, strlen(szCmdLine));
ChildExec32(szCmdLine, g_iCmdShow[p_iCmdShowIndex], 60000);
// 検索結果をオープン
TX *result_text = textFrameOpenEx(szResultPath, "/v /j1");
SetForegroundWindow(result_text->hwndbase);
// ↑小窓からの起動時などに開かれたWZが裏へ行ってしまう場合があるようなので、
// 表へもってくる
// ヒストリへの書き込み
txstr szHistInfoPath, szHistDataPath;
txstr sztemp;
GetTempPath(CCHPATHNAME, sztemp);
pathSetDir(sztemp);
szHistInfoPath = sztemp + g_szHistInfoFile;
szHistDataPath = sztemp + g_szHistDataFile;
TX *histinfo_text, *histdata_text;
int iHistFileMax, iHistFileCurrent;
txstr szpara;
mchar *psz1;
iHistFileMax = 0;
iHistFileCurrent = 0;
if (!fileIsExist(szHistInfoPath) || !fileIsExist(szHistDataPath)) {
histinfo_text = textnew();
histdata_text = textnew();
}
else {
histinfo_text = textopen(szHistInfoPath);
txGetPara(histinfo_text, szpara);
psz1 = strGetWordTop(szpara);
iHistFileMax = atoi(psz1);
while (!isspace(*psz1) && (*psz1 != '\0'))
++psz1;
iHistFileCurrent = atoi(psz1);
if (iHistFileCurrent > iHistFileMax)
iHistFileCurrent = iHistFileMax;
histdata_text = textopen(szHistDataPath);
}
if (iHistFileCurrent > 0) {
txJumpNpara(histdata_text, iHistFileCurrent);
txNextPara(histdata_text);
}
txInsert(histdata_text, szResultPath);
txInsert(histdata_text, "\n");
txSelectEx(histdata_text, CLIP_CHAR);
txJumpFileEnd(histdata_text);
txSelectDelete(histdata_text);
++iHistFileCurrent;
iHistFileMax = iHistFileCurrent;
txDeleteText(histinfo_text);
txInsertf(histinfo_text, "%d\t%d\n", iHistFileMax, iHistFileCurrent);
txSaveTo(histinfo_text, szHistInfoPath);
txSaveTo(histdata_text, szHistDataPath);
textclose(histinfo_text);
textclose(histdata_text);
// 以前に検索したときの検索結果ファイルが開かれていたら閉じる
close_prev_results(szResultFile);
}
//.. 検索ダイアログ
void search_main(TX *text)
{
int i;
txstr szstr;
// 選択肢表示用文字列ブロックの初期化
HSTRBLK sb_booklist, sb_textview, sb_listview;
sb_booklist = sbNewAllocEx(4096);
sb_textview = sbNewAlloc(1024);
sb_listview = sbNewAlloc(1024);
config_read();
// 検索語の初期値をセット
txstr szSearchWord = "";
if (g_fUseClipBoard)
get_clipboard(szSearchWord);
// 検索語の入力
HDIALOG hd;
BOOL fImeOld;
int id;
int id_set_view_default, id_set_book_default;
int id_Zenpou, id_Kouhou, id_Phrase, id_Menu, id_Copyright;
for (;;)
{
hd = dialog("ebminiで検索");
dialogControlID(hd, 100);
dialogSetFocus(hd, 100);
dialogControlHist(hd, HIST_SEARCH);
dialogTxstr(hd, "検索(&S):", 10, szSearchWord, 40);
g_iTextViewIndex = p_iTextViewIndex;
sbDelAll(sb_textview);
for (i = 0; g_pszTextViewChoice[i] != NULL; ++i) {
szstr = g_pszTextViewChoice[i];
if (i == p_iTextViewIndex)
szstr += "*";
sbAdd(sb_textview, szstr);
}
dialogControlStrblk(hd, sb_textview);
dialogChoice(hd, "本文表示(&T):", 10, &g_iTextViewIndex, 15, NULL);
g_iListViewIndex = p_iListViewIndex;
sbDelAll(sb_listview);
for (i = 0; g_pszListViewChoice[i] != NULL; ++i) {
szstr = g_pszListViewChoice[i];
if (i == p_iListViewIndex)
szstr += "*";
sbAdd(sb_listview, szstr);
}
dialogControlStrblk(hd, sb_listview);
dialogChoice(hd, "一覧表示(&L):", 10, &g_iListViewIndex, 15, NULL);
id_set_view_default = dialogCmd(hd, "現在の表示形式をデフォルトにする(&V)", 35);
dialogSetPosY(hd, dialogGetPosY(hd) + 10);
dialogHeadline(hd, "書籍の選択", 55);
int iBookIndex;
iBookIndex = g_iTargetBookNumber - 1;
sbDelAll(sb_booklist);
for (i = 1; i <= BOOK_MAX; ++i) {
sprintf(szstr, "%02d: ", i);
szstr += g_book_table[i].szBookName;
if (i == p_iDefaultBookNumber)
szstr += "*";
sbAdd(sb_booklist, szstr);
}
dialogControlStrblk(hd, sb_booklist);
dialogChoice(hd, "書籍(&B):", 10, &iBookIndex, 40, NULL);
id_set_book_default = dialogCmd(hd, "現在の書籍をデフォルトにする(&D)", 35);
dialogLFV(hd);
id_Zenpou = dialogCmdDefault(hd, "前方(&W)", 12);
id_Kouhou = dialogCmd(hd, "後方(&E)", 12);
id_Phrase = dialogCmd(hd, "フレーズ(&P)", 12);
id_Menu = dialogCmd(hd, "メニュー(&M)", 12);
id_Copyright = dialogCmd(hd, "著作権(&R)", 12);
dialogCancel(hd, 12);
fImeOld = wndImeGetOpen(text->hwndtext);
if (g_book_table[g_iTargetBookNumber].iImeState == IME_STATE_OFF)
wndImeSetOpen(text->hwndtext, FALSE);
else if (g_book_table[g_iTargetBookNumber].iImeState == IME_STATE_ON)
wndImeSetOpen(text->hwndtext, TRUE);
id = dialogOpen(hd);
wndImeSetOpen(text->hwndtext, fImeOld);
g_iTargetBookNumber = iBookIndex + 1;
if (id == id_set_book_default) {
p_iDefaultBookNumber = g_iTargetBookNumber;
}
else if (id == id_set_view_default) {
p_iTextViewIndex = g_iTextViewIndex;
p_iListViewIndex = g_iListViewIndex;
}
else {
break;
}
}
sbDelete(sb_booklist);
sbDelete(sb_textview);
sbDelete(sb_listview);
if (id != 0) {
// txSetSearchContinue(text, szSearchWord, SEARCH_FORWARD);
txSetSearchContinue(text, ".■", SEARCH_FORWARD);
conv_search_word(szSearchWord);
// コマンドライン用データのセットアップ
txstr szSearchMethod;
txstr szSearchInput;
txstr szword;
mchar *psz1;
if (id == id_Zenpou || id == id_Kouhou || id == id_Phrase) {
if (id == id_Zenpou) szSearchMethod = "w";
else if (id == id_Kouhou) szSearchMethod = "e";
else if (id == id_Phrase) szSearchMethod = "p";
szSearchInput = "";
psz1 = szSearchWord;
for (;;) {
psz1 = getword_by_space(szword, psz1);
if (szword == "")
break;
szSearchInput += ("-s\"" + szword + "\"");
szSearchInput += " ";
}
}
else if (id == id_Menu) {
szSearchMethod = "M";
szSearchInput = "-s\"dummy\"";
}
else if (id == id_Copyright) {
szSearchMethod = "C";
szSearchInput = "-s\"dummy\"";
}
// 検索を実行
search_exec(g_book_table[g_iTargetBookNumber].szCommand, szSearchMethod, szSearchInput);
}
}
//.. ★参照リンクを検索
void reference(TX *text)
{
g_iTextViewIndex = p_iTextViewIndex;
g_iListViewIndex = p_iListViewIndex;
// 現在のカーソル位置より後方にある最初の参照リンクを探す
if (txSearchEx(text, ">", SEARCH_FORWARD) == 0) {
statprintf("参照リンクが見つかりません");
}
else if (txSearchEx(text, "<", SEARCH_PREV) == 0) {
statprintf("参照リンクが見つかりません");
}
else {
txRight(text);
int iTargetBook;
txstr szSearchMethod;
txstr szSearchInput;
int i;
txstr szpos;
// 参照リンクのIDをチェック
iTargetBook = 0;
for (i = 1; i <= BOOK_MAX; ++i) {
if (g_book_table[i].szReferenceId == "")
continue;
if (txCmpCur(text, g_book_table[i].szReferenceId) != 0) {
iTargetBook = i;
break;
}
}
if (iTargetBook == 0) {
statprintf("無効な参照リンクです");
}
else {
// 参照位置を取得
txSetUndispEx(text);
txSearchEx(text, "|", SEARCH_FORWARD);
txRight(text);
txSelectEx(text, CLIP_CHAR);
txSearchEx(text, ">", SEARCH_FORWARD);
txGetWord(text, szpos);
txSelectQuit(text);
txSetDispEx(text);
szSearchMethod = "l";
szSearchInput = "-s" + szpos;
// 検索を実行
search_exec(g_book_table[iTargetBook].szCommand, szSearchMethod, szSearchInput);
}
}
}
//.. ヒストリ移動操作
#define HIST_MOVE_BACK 1
#define HIST_MOVE_FORWARD 2
void hist_move(int iDirection)
{
txstr szHistInfoPath, szHistDataPath;
txstr sztemp;
GetTempPath(CCHPATHNAME, sztemp);
pathSetDir(sztemp);
szHistInfoPath = sztemp + g_szHistInfoFile;
szHistDataPath = sztemp + g_szHistDataFile;
if (!fileIsExist(szHistInfoPath)) {
statprintf("エラー:ヒストリ情報ファイルが存在しません");
}
else if (!fileIsExist(szHistDataPath)) {
statprintf("エラー:ヒストリデータファイルが存在しません");
}
else {
TX *histinfo_text;
int iHistFileMax, iHistFileCurrent;
txstr szpara;
mchar *psz1;
histinfo_text = textopen(szHistInfoPath);
txGetPara(histinfo_text, szpara);
psz1 = strGetWordTop(szpara);
iHistFileMax = atoi(psz1);
while (!isspace(*psz1) && (*psz1 != '\0'))
++psz1;
iHistFileCurrent = atoi(psz1);
if (iHistFileMax == 0 || iHistFileCurrent == 0 || iHistFileCurrent > iHistFileMax) {
statprintf("エラー:ヒストリ情報ファイルの内容に異常があります");
}
else {
if (iDirection == HIST_MOVE_BACK && iHistFileCurrent == 1) {
statprintf("これ以上戻れません");
}
else if (iDirection == HIST_MOVE_FORWARD && iHistFileCurrent == iHistFileMax) {
statprintf("これ以上進めません");
}
else {
iHistFileCurrent += ((iDirection == HIST_MOVE_BACK) ? -1 : 1);
TX *histdata_text;
txstr szResultPath;
histdata_text = textopen(szHistDataPath);
txJumpNpara(histdata_text, iHistFileCurrent);
txGetPara(histdata_text, szResultPath);
textclose(histdata_text);
TX *result_text = textFrameOpenEx(szResultPath, "/v");
SetForegroundWindow(result_text->hwndbase);
txDeleteText(histinfo_text);
txInsertf(histinfo_text, "%d\t%d\n", iHistFileMax, iHistFileCurrent);
txSaveTo(histinfo_text, szHistInfoPath);
// 以前の検索結果ファイルを閉じる
close_prev_results(pathGetFileName(szResultPath));
}
}
textclose(histinfo_text);
}
}
//.. ★戻る
void back(TX *text)
{
hist_move(HIST_MOVE_BACK);
}
//.. ★進む
void forward(TX *text)
{
hist_move(HIST_MOVE_FORWARD);
}
//. ★メイン関数
// デフォルトの書籍を選択して起動
// _clipboardは小窓割り当て用
void main(TX *text)
{
g_iTargetBookNumber = p_iDefaultBookNumber;
g_fUseClipBoard = FALSE;
search_main(text);
}
void main_clipboard(TX *text)
{
g_iTargetBookNumber = p_iDefaultBookNumber;
g_fUseClipBoard = TRUE;
search_main(text);
}
//. ★書籍を直接指定して起動する関数
// _clipboardは小窓割り当て用
void book01(TX *text)
{
g_iTargetBookNumber = 1;
g_fUseClipBoard = FALSE;
search_main(text);
}
void book01_clipboard(TX *text)
{
g_iTargetBookNumber = 1;
g_fUseClipBoard = TRUE;
search_main(text);
}
void book02(TX *text)
{
g_iTargetBookNumber = 2;
g_fUseClipBoard = FALSE;
search_main(text);
}
void book02_clipboard(TX *text)
{
g_iTargetBookNumber = 2;
g_fUseClipBoard = TRUE;
search_main(text);
}
void book03(TX *text)
{
g_iTargetBookNumber = 3;
g_fUseClipBoard = FALSE;
search_main(text);
}
void book03_clipboard(TX *text)
{
g_iTargetBookNumber = 3;
g_fUseClipBoard = TRUE;
search_main(text);
}
void book04(TX *text)
{
g_iTargetBookNumber = 4;
g_fUseClipBoard = FALSE;
search_main(text);
}
void book04_clipboard(TX *text)
{
g_iTargetBookNumber = 4;
g_fUseClipBoard = TRUE;
search_main(text);
}