home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
DOS/V Power Report 1999 March
/
VPR9903A.BIN
/
APUPDATE
/
VC
/
Tx300d
/
TX300D.LZH
/
STDLIB.C
< prev
next >
Wrap
C/C++ Source or Header
|
1997-06-15
|
94KB
|
3,879 lines
// WZ EDITOR 標準機能 TX-Cライブラリ関数群
// Copyright 1995-96 TY
// 従来の小物TLLをまとめました。
#ifdef __TXC__
#include <windows.h>
#pragma HEADER+
#else
#include "tx.h"
#include <memory.h>
#include <string.h>
#include <stdio.h>
#include <stdlib.h>
#include <ctype.h>
#endif
#include "_filer.h"
#include <windowsx.h>
#ifndef __NOTX__
//##text.c
//{###表示}
//1.97 static変数を止めtext->addressUndisp,lxUndispへ
void TXAPIBASE txSetUndispEx(tx *text)
{
// カーソル位置・画面上のカーソルy座標を保存する、txSetUndisp
txSetUndisp(text);
}
BOOL TXAPIBASE txSetDispEx(tx *text)
{
// カーソル位置・画面上のカーソルy座標を保存する、txSetDisp
// 全表示したかどうか返す
UNDISPCONTEXT* context = txGetUndispContextPre(text);
if (context) {
txJumpAddress(text,context->address);
txSetLy(text,context->ly);
}
return txSetDisp(text);
}
void TXAPIBASE txSetUndispExSilent(tx *text)
{
// マウスカーソルの形状を変更しないtxSetUndispEx
// txSetUndispExSilentしたら必ずtxSetDispExSilentを実行してください。
//2.99 970318 new
text->fNoCursor++;
txSetUndispEx(text);
}
BOOL TXAPIBASE txSetDispExSilent(tx *text)
{
// マウスカーソルの形状を変更しないtxSetDispEx
// 全表示したかどうか返す
//2.99 970318 new
BOOL ret = txSetDispEx(text);
text->fNoCursor--;
return ret;
}
void TXAPIBASE txSetUndispSilent(TX* text)
{
// マウスカーソルの形状を変更しないtxSetUndisp
// txSetUndispSilentしたら必ずtxSetDispSilentを実行してください。
//2.99 970314 new
text->fNoCursor++;
txSetUndisp(text);
}
BOOL TXAPIBASE txSetDispSilent(TX* text)
{
// マウスカーソルの形状を変更しないtxSetDisp
// 全表示したかどうか返す
//2.99 970314 new
BOOL ret = txSetDisp(text);
text->fNoCursor--;
return ret;
}
BOOL TXAPI txSetDispExJump(tx *text,BOOL fJump)
{
// txSetDispExと同じだが、fJumpが真のときだけカーソル位置を戻す
// y座標は常に戻す
UNDISPCONTEXT* context = txGetUndispContextPre(text);
if (context) {
if (fJump) txJumpAddress(text,context->address);
txSetLy(text,context->ly);
}
return txSetDisp(text);
}
void TXAPI txSetUndispEdit(tx *text)
{
// textが編集されてもカーソル位置が変わりにくいtxSetUndisp
// 無事カーソル位置をコンテキストに保存できたか返す
// テキストの論理行数が変わらないときに使えます。
//1.97で追加
txSetUndisp(text);
}
BOOL TXAPI txSetDispEdit(tx *text)
{
// textが編集されてもカーソル位置が変わりにくいtxSetDisp
// 全表示したかどうか返す
//1.97で追加
UNDISPCONTEXT* context = txGetUndispContextPre(text);
if (context) {
txJumpPara(text,context->npara);
txJumpParaIch(text,context->ich);
txSetLy(text,context->ly);
}
return txSetDisp(text);
}
void TXAPI txFlushUI(TX* text)
{
// キー、メニュー、ツールバーの設定をフラッシュする
//2.00E4で追加
// menu
SendMessage(text->hwndbase,WM_TXFLUSHMENU,0,0);
// key
if (txGetViewmode(text)) {
//1.99K
// viewmodeではキーは変えない
} else if (text->fNoFlushKey) {
//2.00E
} else {
text->share->fKeyInited = FALSE;// shareのキャッシングを無効化する
txKeyLoad(text);
}
// toolbar
#if 1//2.96A 970214 ツールバーはフレームウィンドウの設定に左右される
txFlushToolbar(txGetFrame(text));
#else
txFlushToolbar(text);
#endif
}
//{###情報取得}
#ifdef __TXC__
int TXAPIBASE TXHIGH txGetParaRear(TX* text,txstr szbuff)
{
// カーソル位置から段落の終わりまでの内容をszbuffに取得
// 表示行が、改行・EOFで終わる場合、その手前までの文字列を取得
//{#RET}取得したバイト数を返す
//3.00A2 970505 new
return txOp(text,TXOP_GETPARAREAREX,(mchar*)szbuff,cchtxstr(szbuff));
}
int TXAPIBASE TXHIGH txGetParaFront(TX* text,txstr szbuff)
{
// 段落先頭からカーソル位置の手前までの内容をszbuffに入れる
// szbuffに取得した文字列のバイト数を返す
// szbuffのサイズが足りない時は、szbuffに収まる分の内容を入れる。
// この場合次の様に、カーソル位置の手前の内容をszbuffに入れる。
// abcdefghijklmnopqrstuvwxyz
// ^カーソル
// szbuffのサイズ=4 -> szbuff="nop"
// szbuffのサイズ=8 -> szbuff="jklmnop"
//3.00A2 970505 new
return txOp(text,TXOP_GETPARAFRONTEX,(mchar*)szbuff,cchtxstr(szbuff));
}
int TXAPI TXHIGH txGetCharType(TX* text,mchar *p)
{
// pが示す文字のタイプを返す
// text->fCurWesternが真なら欧文動作する
// CT_SPACE (0x00-0x20),全角スペース(0x8140)
// CT_SYMBOL '$','_'を除く英記号
// 全角記号(0x8152-0x815Bを除く)
// CT_KATA 半角カタカナ
// CT_HIRA 全角ひらがな
// CT_KANJI 上記以外の全角文字
// CT_CHAR 上記以外の半角文字
// CT_LF
// CT_EOF
//3.00B1 970522 new
return txOp(text,TXOP_GETCHARTYPE,p,0);
}
#endif
TXCHAR TXAPIBASE TXHIGH txGetCharPrev(TX* text)
{
// カーソル位置の1文字前の文字コードを返す
// 不明な場合は0を返す
//2.99C 970325 new
if (text->cur0) {
mchar* p = text->buff + text->cur0;
//information("%d",txIsCharTop(text,text->cur0 - 1));
if (text->cur0 == 1) {
return p[-1];
}
if (
p[-1] == CHAR_LF &&
p[-2] == CHAR_CR
) {
return CHAR_CRLF;
} else if (txIsCharTop(text,text->cur0 - 1)) {
return p[-1];
} else {
return MAKEWORD(p[-1],p[-2]);
}
}
return 0;
}
int TXAPI pointsFromDisplayPixel(int pixel)
{
// ディスプレイピクセル単位をポイント数に変換
//2.99 970316 new
HDC hic = CreateIC("display",NULL,NULL,NULL);
int ret = pixel;
if (hic) {
long logPixelsX = GetDeviceCaps(hic,LOGPIXELSX);
ret = (pixel * 72L) / logPixelsX;
DeleteDC(hic);
}
return ret;
}
int TXAPI pointsToDisplayPixel(int points)
{
// ポイント数をディスプレイピクセル単位に変換
//2.99B 970322 new
HDC hic = CreateIC("display",NULL,NULL,NULL);
int ret = points;
if (hic) {
long logPixelsX = GetDeviceCaps(hic,LOGPIXELSX);
ret = (points * logPixelsX) / 72L;
DeleteDC(hic);
}
return ret;
}
#ifdef __TXC__
//{###検索・置換}
int TXAPI TXHIGH txSearch(tx *text,mchar *find)
{
// findをカーソル位置の次から検索
// このAPIは旧バージョンとの互換性のために存在しています。
// 新しいマクロではtxSearchExを使って下さい。
// 検索ヒストリは変更しません
// 検索オプションはtext->searchmodeを参照します
// text->searchmodeは「検索|検索」を実行すると変化するので注意してください
//{#RET}見つかればカーソルを移動し0以外の値、
// 見つからなければ0を返す
return txSearchEx(text,find,text->searchmode);
}
int TXAPI TXHIGH txSearchPrev(tx *text,mchar *find)
{
// findをカーソル位置からテキスト先頭まで検索
// このAPIは旧バージョンとの互換性のために存在しています。
// 新しいマクロではtxSearchExを使って下さい。
// ※txSearchContinuePrevには影響しません。
// 検索オプションはtext->searchmodeを参照します
// text->searchmodeは「検索|検索」を実行すると変化するので注意してください
//{#RET}見つかればカーソルを移動し0以外の値、
// 見つからなければ0を返す
return txSearchEx(text,find,text->searchmode|SEARCH_PREV);
}
//{###ファイル}
BOOL TXAPI TXHIGH txSwap1(tx *text)
{
// 後方をloadする必要があればloadする。loadしたかどうかを返す。
//2.99D 970329 new
return txOp(text,TXOP_TXSWAP1,0,0);
}
BOOL TXAPI TXHIGH txSwap2(tx *text)
{
// 前方をloadする必要があればloadする。loadしたかどうかを返す。
//2.99D 970329 new
return txOp(text,TXOP_TXSWAP2,0,0);
}
//{###情報取得}
int TXAPI systemfontGetCx(void)
{
// システムフォントの平均幅をディスプレイピクセル単位で返す
//2.99 970316 new
TEXTMETRIC tm;
{
HDC hic = CreateIC("display",NULL,NULL,NULL);
HFONT hfont0 = SelectObject(hic,GetStockObject(GetSystemFontNo()));
GetTextMetrics(hic,&tm);
SelectObject(hic,hfont0);
DeleteDC(hic);
}
return tm.tmAveCharWidth;
}
int TXAPI systemfontGetCy(void)
{
// システムフォントの高さをディスプレイピクセル単位で返す
//2.99 970316 new
TEXTMETRIC tm;
{
HDC hic = CreateIC("display",NULL,NULL,NULL);
HFONT hfont0 = SelectObject(hic,GetStockObject(GetSystemFontNo()));
GetTextMetrics(hic,&tm);
SelectObject(hic,hfont0);
DeleteDC(hic);
}
return tm.tmHeight;
}
BOOL TXAPI pathGetExtGroup(mchar* szext,mchar szGroup[CCHWORD])
{
// 拡張子szextの属する設定名をszGroupに返す
//2.99 970318 new
return txOp(text1,TXOP_PATHGETEXTGROUP,(LPARAM)szext,(LPARAM)szGroup);
}
//## undo clear
BOOL TXAPI txUndoClear(TX* text)
{
//2.99 970316 new
return txOp(text,TXOP_UNDOCLEAR,0,0);
}
//## plugatr API
LPVOID TXAPI plugatrNewEx(TX* text,int modePlug,UINT cbEx)
{
return (LPVOID)txOp(text,TXOP_PLUG_NEWEX,modePlug,cbEx);
}
LPVOID TXAPI plugatrNew(TX* text,int modePlug)
{
return (LPVOID)txOp(text,TXOP_PLUG_NEW,modePlug,0);
}
void TXAPI plugatrDelete(TX* text,TYP typ)
{
txOp(text,TXOP_PLUG_DELETE,typ,0);
}
TYP TXAPI plugatrGetTyp(TX* text,LPVOID plugatr)
{
return (TYP)txOp(text,TXOP_PLUG_GETTYP,plugatr,0);
}
LPVOID TXAPI plugatrRead(TX* text,TYP typ)
{
return (LPVOID)txOp(text,TXOP_PLUG_READ,typ,0);
}
int TXAPI plugatrGetModePlug(TX* text,TYP typ)
{
return (int)txOp(text,TXOP_PLUG_GETMODEPLUG,typ,0);
}
UINT TXAPI plugatrGetSize(LPVOID plug)
{
return (UINT)txOp(text,TXOP_PLUG_GETSIZE,plug,0);
}
//## plugatr uty
void TXAPI txFlushTableAll(TX* text)
{
// すべての表をフラッシュ
//2.99C 970323 new
txOp(text,TXOP_TABLEFLUSHALL,0,0);
}
BOOL TXAPI txFlushTable(TX* text)
{
// カーソル行の表や桁揃えの幅をフラッシュして表示
// フラッシュしたかどうか返す
//2.99C 970323 WZ.EXE -> macro
//1.90 new
return txOp(text,TXOP_PLUGTAB_FLUSHCUR,0,0);
}
int TXAPI txGetCurPlugmode(TX* text)
{
//2.97A 970301 new
if (text->editmode == 0) {//2.99C 970324
return 0;
} else {
CHARATR charatr;
charatrRead(text,txGetAddress(text),&charatr);
if (charatr.fLink) {
return plugatrGetModePlug(text,charatrGetPlug(charatr));
}
return 0;
}
}
LPVOID TXAPI txGetCurPlug(TX* text)
{
//2.97A 970301 new
if (text->editmode == 0) {//2.99C 970324
return NULL;
} else {
CHARATR charatr;
charatrRead(text,txGetAddress(text),&charatr);
if (charatr.fLink) {
return plugatrRead(text,charatrGetPlug(charatr));
}
return NULL;
}
}
PLUGTAB* TXAPI txIsCurParaIncludeTable(TX* text)
{
//2.97A 970301 new
return txOp(text,TXOP_PLUGTAB_CURPARA,0,0);
}
#endif
BOOL TXAPI txInsertPlug(TX* text,LPVOID plug)
{
//2.97A 970301 new
TYP typ = plugatrGetTyp(text,plug);
CHARATR_LINK charatr;
structClear(charatr);
charatr.fLink = TRUE;
charatr.ibitmap = typ;
txCurInsertChar(text,CHAR_PLUG);
charatrWrite(text,txGetAddress(text),(LPVOID)&charatr);
txInsert(text,"");//2.97A 970303 flush CHAR_PLUG
txRight(text);
return TRUE;
}
int TXAPI txGetCurPlugTag(TX* text)
{
//2.97A 970301 new
PLUGHTMLTAG *plug = txGetCurPlug(text);
if (plug && plug->head.modePlug == PLUG_HTML_TAG) {
return plug->tag;
}
return 0;
}
TXBASE_CONTEXT* TXAPI hwndbaseGetContext(HWND hwndbase)
{
//2.93
// 別プロセスのWZのhwndbaseのTXBASE_CONTEXTにはアクセスできないことに注意!
return (LPVOID)GetWindowLong(hwndbase,0);
}
IFILE TXAPI txGetLineTop(tx *text)
{
// 表示行の行頭のテキストアドレスを返す。
//2.90で追加
if (text->fHigh) return text->temp1 + text->cur0;//1.99D
return text->temp1 + text->cury;
}
IFILE TXAPI txGetLineTail(tx *text)
{
// 次の表示行頭のテキストアドレスを返す。
//2.90で追加
if (text->fHigh) return text->temp1 + text->cur0;//1.99D
{
IBUFF off = text->cury + text->curysize + (text->cur - text->cur0);
if (off == text->sizebuff && !txIsSwap1(text)) {//EOF
return text->temp1 + text->cury + text->curysize - 1;
}
return text->temp1 + text->cury + text->curysize;
}
}
BOOL TXAPI articleMatch(PARAFORM_ARTICLE* article1,PARAFORM_ARTICLE* article2)
{
//2.90
if (article1->fArticleNum && article2->fArticleNum) {
mchar* p1 = article1->szArticle;
mchar* p2 = article2->szArticle;
BOOL ret = TRUE;
while(1) {
if (isdigit(*p1)) {
p1++;
while(isdigit(*p1)) p1++;
}
if (isdigit(*p2)) {
p2++;
while(isdigit(*p2)) p2++;
}
if (*p1 == *p2) {
if (*p1 == 0) break;
p1++;
p2++;
} else {
ret = FALSE;
break;
}
}
return ret;
} else {
if (article1->lchArticle != article2->lchArticle) return FALSE;
return !strcmp(article1->szArticle,article2->szArticle);
}
}
BOOL TXAPIBASE txIsLineParaTop(tx *text)
{
// カレント表示行が、論理行の先頭行か返す
mchar c;
if (text->fHigh) return FALSE;
if (text->cury == 0) return TRUE;
c = text->buff[text->cury-1];
if (c == 0x0A || c == 0x1A || c == 0x0C) return TRUE;
return FALSE;
}
BOOL TXAPIBASE txIsCurParaTop(tx *text)
{
// カーソル位置が、論理行の先頭行か返す
mchar c;
if (text->cur0 == 0) return TRUE;
c = text->buff[text->cur0-1];
if (c == 0x0A || c == 0x1A || c == 0x0C) return TRUE;
return FALSE;
}
BOOL TXAPIBASE txIsCurLineTop(tx *text)
{
// カーソル位置が、表示行の行頭か返す
//2.90で追加
mchar c;
return (text->cur0 == text->cury);
}
NLINE TXAPI txGetNlineModal(tx *text)
{
// テキストのカーソル行の行番号を返します
// text->fLineDが真なら表示行番号、偽なら論理行番号を返します
//1.00Cで追加
if (text->fLineD) {
return text->nline;
} else {
return text->npara;
}
}
#ifdef __TXC__
TX* txFromHwndbase(HWND hwnd)
{
return (TX*)txOp(NULL,TXOP_TXFROMHWNDBASE,hwnd,NULL);
}
#endif
TX* TXAPI txGetFrame(TX* text)
{
//2.93
//2.96 970205 改良
// textがダイアログ中のコントロールの場合、従来はtext1を返したが
// 正しく、対象の(textの親ウィンドウなどの)textFrameを返す様にした。
if (text->fFrame) return text;
if (text->text2 && text->text2->fFrame) return text->text2;//2.93
#if 1//2.96 970205
return txFromHwndbase(text->hwndbase);
#else
return text1;
#endif
}
TX* TXAPI txGetFrameNow(void)
{
// 現在フォーカスのあるtextの、大元のtextを返す
// 高速オープンONのときは、従来のtext1の代わりに使用する
//2.99C 970324 new
return txGetFrame(textf);
}
BOOL TXAPI autosaveGetFileName(tx* text,mchar szfilename[CCHPATHNAME])
{
// オートセーブ先のファイル名を返します。
// オートセーブするかどうかの最低限のチェックも行います。
// 正常にファイル名をセットしたか返します。
if (text->fAutoSave && text->fFrame) { //2.95 970131 text==text1 -> text->fFrame
if (text->autosaveDevice == AUTOSAVE_NOTFD) {
if (pathGetDriveType(text->szfilename) == DRIVE_REMOVABLE) return FALSE;
}
if (
text->szfilename[0] &&
!text->ftxuiSaveNamed //2.00E 無題ファイルを保存すると$~nonameが削除されなかった
) {
if (text->autosaveMode == AUTOSAVE_OVERWRITE) {
strcpy(szfilename,text->szfilename);
} else {
mchar* pfilename = pathGetFileName(text->szfilename);
mchar* dst;
strcpy(szfilename,text->szfilename);
dst = pathGetFileName(szfilename);
*dst++ = '$';
*dst++ = '~';
#ifdef __FLAT__
strcpy(dst,pfilename);
#else
{
mchar* pext = pathGetExt(text->szfilename);
strcpylenmax(dst,pfilename,pext - pfilename,7);
dst += strlen(dst);
strcpy(dst,pext);
}
#endif
}
} else {
#if 1//2.98 970307 "$~noname"があちこちにできたので、WZフォルダに作るようにした
// ネットワーク版の場合はユーザフォルダに作る。
// ネットワーク環境では、"$~noname"があちこちにできるのは、セキュリティ上よくない。
#if 1//2.99C 970326 無題ファイルのオートセーブがおかしかった
pathFullConfig(szfilename,"$~noname");
#else
mchar szfilename[CCHPATHNAME];
pathFullConfig(szfilename,"$~noname");
#endif
#else
driveGetCurDir(0,szfilename);
pathSetDir(szfilename);
pathSetFileName(szfilename,"$~noname");
#endif
}
//information(szfilename);
return TRUE;
} else {
return FALSE;
}
}
IFILE TXAPI txGetAddressSelectTop(tx *text)
{
// 範囲の先頭アドレスを取得
// 選択中でないときはカーソル位置のアドレスを返す
if (text->fClip && txFlushSelectNow(text)) {
if (text->cliptopnow <= text->clipendnow) {
return text->cliptopnow;
} else {
return text->clipendnow;
}
} else {
return txGetAddress(text);
}
}
IFILE TXAPI txGetAddressSelectEnd(tx *text)
{
// 範囲の末尾アドレスを取得
// 選択中でないときはカーソル位置のアドレスを返す
if (text->fClip && txFlushSelectNow(text)) {
if (text->clipendnow >= text->cliptopnow) {
return text->clipendnow;
} else {
return text->cliptopnow;
}
} else {
return txGetAddress(text);
}
}
BOOL TXAPI txIsSelectPrev(TX* text)
{
// カーソル位置が範囲選択開始位置より手前にあるときTRUEを返す
//2.97A 970302 new
if (text->fClip && txFlushSelectNow(text)) {
if (text->clipendnow < text->cliptopnow) return TRUE;
}
return FALSE;
}
IFILE TXAPI txGetAddressCurscreen(TX* text)
{
// スクリーントップに表示されている表示行の頭のアドレスを返す
//2.97A 970302 new
return txOp(text,TXOP_GETADDRESSCURSCREEN,0,0);
}
BOOL TXAPI txSetLyCurscreen(TX* text,IFILE adrCurscreen)
{
// 現在のカーソル位置を変えずに、スクリーントップがadrCurscreenになるように
// lyを設定する。lyが設定できない場合は、ly=0としてFALSEを返す。
return txOp(text,TXOP_SETLYCURSCREEN,adrCurscreen,0);
}
int TXAPI txGetModeClipboard(TX* text)
{
// クリップボードのモードを返す
//2.00Eで追加
if (text->fBinedit) {
return CLIPBOARD_TS;
} else {
return text->modeClipboard;
}
}
mchar* TXAPI txGetTitleFilename(TX* text)
{
// タイトルバーに表示するファイル名を返す
//2.00Eで追加
if (text->szfilename[0]) {
if (text->fDispPathFull) {
return text->szfilename;
} else {
return pathGetFileName(text->szfilename);
}
} else if (text->mail) {//2.90
return text->mail->szCaption;
} else {
return "(無題)";
}
}
//{###ファイル}
TX* TXAPI txAllocText(DWORD mode)
{
// text構造体を確保し、txInitText,txSetFileName(text,NULL)して返す
// modeにはTXALLOC_XXXが指定できる。
//2.99 970316 new
BOOL fUndo = ((mode & TXALLOC_UNDO) != 0);
UINT size = sizeof(TX) + fUndo * 2 * sizeof(TX);
TX* text = malloc(size);
TX* p = text + 1;
if (text) {
txInitText(text);
text->fTxAllocText = TRUE;
txSetFileName(text,NULL);// 標準設定を読込む
if (fUndo) {//2.90
text->fEnableUndo = TRUE;
text->fUndoAlloced = TRUE;//2.99E 970403
text->ttextUndo = (LPVOID)p;
txInitText(&text[1]);
txInitText(&text[2]);
p += sizeof(TX) * 2;
}
return text;
}
return NULL;
}
void TXAPI txFreeText(TX* text)
{
// txAllocTextで得たtextをtxCloseして解放する
//2.99 970316 new
if (text && text->fTxAllocText) {
text->fTxAllocText = FALSE;
txClose(text);
free(text);
}
}
TX* TXAPIBASE textopen(mchar* szfilename)
{
// szfilenameのファイルをオープンする。
// ファイルの内容を読み込んだtextを返す
// 失敗したらNULLを返す
// テキストを使い終わったら必ずtextcloseしてtextを閉じて下さい。
// szfilenameにはNULLも指定できます。NULLを指定すると空の新規テキストを開きます。
//2.99B 970322 new
TX* text = txAllocText(0);
if (text) {
txSetFileName(text,szfilename);
if (txOpenText(text)) {
return text;
}
txFreeText(text);
}
return NULL;
}
void TXAPIBASE textclose(TX* text)
{
// textopenで開いたテキストを閉じる
// textにはNULLも指定できます
//2.99B 970322 new
txFreeText(text);
}
BOOL TXAPI forksw(mchar* szfilename,mchar* sw)
{
// forkと同じですが、起動オプションをswで指定できます。
//2.94 970123 新規API
TXFORKRESULT result;
if (forkex(szfilename,sw,0,&result)) return TRUE;
if (result.text) return TRUE;
return FALSE;
}
BOOL TXAPI fork(mchar* szfilename)
{
// szfilenameのファイルをオープンします。
// 返り値が「真」なら、szfilenameの窓がアクティブになり、text変数は、s
// zfilenameのテキストを示します。
// 返り値が「偽」なら、オープン失敗です。
// [詳細]
// szfilenameにスイッチ指定を含むことはできません。
// 空白を含むファイル名もszfilenameにそのまま指定できます。
// szfilenameは""で括ってあっても構いません。
// szfilenameがNULLまたは""なら、新規ファイルを開きます。
// szfilenameが既にオープンされていたら、その窓をアクティブにします。
// 高速オープンのロジックを使って、必ず、このAPIを呼び出したWZプロセス内で
// szfilenameをオープンします。
// 高速オープン未対応のTXEからこのAPIを呼び出すと必ず失敗します。
// ★WZ3.00,3.00Aにおける注意
// オープンが成功した場合、textにアクセスするにはsleep(1000)のよう
// に一定時間待つ必要があります。待ち時間はマシンに依存します。
// この制限は将来解除したいと考えています。
// ★WZ3.00Bからsleepで待つ必要がなくなりました。
//2.94 970123 新規API
return forksw(szfilename,NULL);
}
BOOL TXAPI forkstd(mchar* szfilename,mchar* sw)
{
// forkswと同じですが、高速オープンできない場合、
// すなわち、WZを起動する場合または別プロセスのWZで高速オープンする場合も、
// ファイルのオープンを行います。
//2.94 970123 新規API
return forkex(szfilename,sw,TXFORK_FORKWZ_ENABLE,NULL);
}
BOOL TXAPIBASE txOpenFork(TX* text,mchar* szfilenamesw)
{
// 新しくテキストウィンドウを開き、szfilenameをオープン
// szfilenameには、次の様にファイル名に続けてスイッチを指定できます
// a:\wz\readme.txt /J100
// 空白を含むファイルは、次のように""で括ってください。
// "a:\wz editor\readme.txt" /J100
//3.00 複数のファイルを指定することはできなくなりました。
//2.94 970123 EXEから移動
//3.00A2 970507 txOpenForkは必ず別プロセスのテキストを開く様に仕様変更
// 既に指定したファイルが開かれている場合で、そのファイルが現在のプロセス内で
// 開かれている場合は、ファイルのプロセスと現在のプロセスは同じです。
#if 1///3.00A2 970507
return forkex(szfilenamesw,NULL,TXFORK_OLDARG|TXFORK_FORKWZ,NULL);
#else
return forkex(szfilenamesw,NULL,TXFORK_OLDARG|TXFORK_FORKWZ_ENABLE,NULL);
#endif
}
BOOL TXAPIBASE txOpenForkFast(TX* text,mchar* szfilenamesw)
{
// txOpenForkと同じですが、高速オープンできる場合は高速オープンします。
// 高速オープンできない場合は、別プロセスでオープンします。
// WZ3.00無印の旧txOpenForkの仕様と同じです。
//3.00A2 970507 new
return forkex(szfilenamesw,NULL,TXFORK_OLDARG|TXFORK_FORKWZ_ENABLE,NULL);
}
BOOL TXAPI txOpenForkEx(TX* text,mchar* szfilenamesw)
{
// textが新規テキストなら、それを閉じてからtxOpenFork
// そうでなければ、txOpenFork
// スイッチも指定できます
//2.94 970123 EXEから移動
//3.00A2 970507 txOpenForkExは必ず別プロセスのテキストを開く様に仕様変更
// 既に指定したファイルが開かれている場合で、そのファイルが現在のプロセス内で
// 開かれている場合は、ファイルのプロセスと現在のプロセスは同じです。
#if 1///3.00A2 970507
return forkex(szfilenamesw,NULL,TXFORK_OLDARG|TXFORK_FORKWZ|TXFORK_CLOSE_NULL,NULL);
#else
return forkex(szfilenamesw,NULL,TXFORK_OLDARG|TXFORK_FORKWZ_ENABLE|TXFORK_CLOSE_NULL,NULL);
#endif
}
BOOL TXAPI txOpenForkExFast(TX* text,mchar* szfilenamesw)
{
// txOpenForkExと同じですが、高速オープンできる場合は高速オープンします。
// WZ3.00無印の旧txOpenForkExの仕様と同じです。
//3.00A2 970507 new
return forkex(szfilenamesw,NULL,TXFORK_OLDARG|TXFORK_FORKWZ_ENABLE|TXFORK_CLOSE_NULL,NULL);
}
HWND TXAPIBASE txOpen(TX* text,mchar* szfilenamesw)
{
// 新しくテキストウィンドウを開き、szfilenameを読み込みます。
// 新規ファイルを開く時は、szfilenameに""を指定してください。
// szfilenameには、次の様にファイル名に続けてスイッチを指定できます
// a:\wz\readme.txt /J100
// 空白を含むファイルは、次のように""で括ってください。
// "a:\wz editor\readme.txt" /J100
// ファイルを複数指定することはできません。
// テキストウィンドウがオープンされて
// キー入力待ち状態になるまで待ってから、テキストウィンドウの
// ウィンドウハンドル(text->hwndbaseに相当)を返します。
// 既にszfilenameのテキストウィンドウがオープンされていたら、
// 新しいテキストウィンドウは開かずに、オープンされているテキストウィンドウを
// アクティブウィンドウにして、そのウィンドウハンドルを返します。
// 失敗すれば、NULLを返します
//1.01Aで追加
//2.94 970123 EXEから移動
//3.00A2 970507 txOpenは必ず別プロセスのテキストを開く様に仕様変更。
// 既に指定したファイルが開かれている場合で、そのファイルが現在のプロセス内で
// 開かれている場合は、ファイルのプロセスと現在のプロセスは同じです。
#if 1///3.00A2 970507
TXFORKRESULT result;
if (forkex(szfilenamesw,NULL,TXFORK_OLDARG|TXFORK_FORKWZ|TXFORK_SYNC,&result)) {
return result.hwnd;
}
if (result.fAlrearyOpen) return result.hwnd;//3.00B1 970612 txOpenで既にファイルがオープンされていたときそのhwndが返らなかった
return NULL;
#else
TXFORKRESULT result;
if (forkex(szfilenamesw,NULL,TXFORK_OLDARG|TXFORK_FORKWZ_ENABLE|TXFORK_SYNC,&result)) {
return result.hwnd;
}
return NULL;
#endif
}
HWND TXAPI txOpenFast(TX* text,mchar* szfilenamesw)
{
// txOpenと同じですが、高速オープンできる場合は高速オープンします。
// 高速オープンできない場合は、別プロセスでオープンします。
// WZ3.00無印の旧txOpenの仕様と同じです。
// 3.00Aでは、高速オープンした場合は、次のプログラムはハングする危険があります。
// HWND hwnd = txOpenFast(text,szfilename);
// wndtxCall(hwnd,szcmd);
// この場合は、次の様にsleepを入れて下さい。
// HWND hwnd = txOpenFast(text,szfilename);
// sleep(1);
// wndtxCall(hwnd,szcmd);
// 3.00Bでは上記の制限は解消されました。
//3.00A2 970507 new
TXFORKRESULT result;
if (forkex(szfilenamesw,NULL,TXFORK_OLDARG|TXFORK_FORKWZ_ENABLE|TXFORK_SYNC,&result)) {
return result.hwnd;
}
if (result.fAlrearyOpen) return result.hwnd;//3.00B1 970612 txOpenで既にファイルがオープンされていたときそのhwndが返らなかった
return NULL;
}
BOOL TXAPI txInit(TX* text,mchar* szfilename)
{
// 次のプログラムと等価
// txInitText(text);
// txSetFileName(text,szfilename);
// return txOpenText(text);
//2.00Eで追加
txInitText(text);
txSetFileName(text,szfilename);
return txOpenText(text);
}
void TXAPI txInitTextBinary(tx* text)
{
// txInitTextの様にtext構造体を初期化する。
// バイナリ用として初期化する
// この後、txSetFileNameすると意味がなくなる。
txInitText(text);
text->fNoConfig = TRUE;
text->fAppendEof = FALSE;
text->fBinary = TRUE;
txOpenText(text);
txSetHigh(text);
}
void TXAPI txOpenTextBinary(tx* text,mchar* szfilename,UINT cbRecord,UINT cbHeader)
{
// txInitTextの様にtext構造体を初期化する。
// バイナリ用として初期化する
// この後、txSetFileNameすると意味がなくなる。
// cbRecord,cbHeaderは最大32KB程度まで。
txInitText(text);
text->fNoConfig = TRUE;
text->fAppendEof = FALSE;
text->fBinary = TRUE;
text->fTempMem = TRUE;//2.97 970216 WZ32でテンプラリ作成だと、linkatrが大きいと表示が異様に遅くなる。WZ16は仕方ない。
if (szfilename) {
strcpy(text->szfilename,szfilename);
}
txOpenText(text);
txSetHigh(text);
//
text->cbRecord = cbRecord;
text->cbHeader = cbHeader;
}
void TXAPI txInitTextText(tx* text)
{
// txInitTextの様にtext構造体を初期化する。
// テキスト用(Eofつけない)として初期化する
// この後、txSetFileNameすると意味がなくなる。
txInitText(text);
text->fNoConfig = TRUE;
text->fAppendEof = FALSE;
txOpenText(text);
}
#define SIZEBUFF 1024
// カーソル位置にsizeバイトの0を挿入
static BOOL txInsertBytes(tx *text,IFILE size)
{
BYTE buff[SIZEBUFF];
memset(buff,0,sizeof(buff));
while(size) {
IMEM len = SIZEBUFF;
if (size < len) len = size;
txInsertBuff(text,buff,len);
size -= len;
}
return TRUE;
}
// テキストサイズをsizeバイト拡大
// 拡大によってできた領域は0で埋められる
static BOOL txExpand(tx *text,IFILE size)
{
txJumpFileEnd(text);
return txInsertBytes(text,size);
}
IFILE TXAPI txRecordGetAddress(tx* text,TXRECORD irecord)
{
return text->cbHeader + irecord * text->cbRecord;
}
// ヘッダエリアを確保
static BOOL txHeaderAlloc(TX* text)
{
IFILE size = txGetTextSize(text);
IFILE address = text->cbHeader;
if (address > size) return txExpand(text,address - size);
return TRUE;
}
BOOL TXAPI txHeaderRead(TX* text,LPVOID pHeader)
{
if (!txHeaderAlloc(text)) {
memset(pHeader,0,text->cbHeader);
return FALSE;
}
txJumpFileTop(text);
memcpy(pHeader,text->buff + text->cur,text->cbHeader);
return TRUE;
}
BOOL TXAPI txHeaderWrite(TX* text,LPVOID pHeader)
{
if (!txHeaderAlloc(text)) return FALSE;
text->fEdit = TRUE;
txJumpFileTop(text);
memcpy(text->buff + text->cur,pHeader,text->cbHeader);
return TRUE;
}
static BOOL txRecordIsExist(tx* text,TXRECORD irecord)
{
if (!text) return FALSE;
#if 1//1.93
{
IFILE size = txGetTextSize(text);
IFILE address = txRecordGetAddress(text,irecord);
if (address < size) return TRUE;
}
return FALSE;
#else
{
IFILE size = txGetTextSize(text);
IFILE address = txRecordGetAddress(text,irecord);
if (address > size) return FALSE;
}
return TRUE;
#endif
}
static void myerror(int line)
{
attention("err stdlib %d",line);
}
static BOOL txRecordExpand(tx* text,TXRECORD irecord)
{
// レコード数をirecordまで拡大
if (!text) return FALSE;
if ((long)irecord < 0) {
// irecordがマイナス値になっている
myerror(__LINE__);
return FALSE;
}
{
IFILE size = txGetTextSize(text);
IFILE address = txRecordGetAddress(text,irecord);
if (address > size) return txExpand(text,address - size);
}
return TRUE;
}
BOOL TXAPI txRecordSeek(tx* text,TXRECORD irecord)
{
// レコード数をirecordまで拡大してtxJumpAddressする
if (txRecordExpand(text,irecord)) {
txJumpAddress(text,txRecordGetAddress(text,irecord));
return TRUE;
}
return FALSE;
}
BOOL TXAPI txRecordIsInsideBuff(tx* text)
{
// textやpRecordがNULLならFALSEを返す
// irecordのレコードが存在しないときもNULLを返す
// うまくいったらカーソルをレコード先頭に設定し、レコード先頭のテキストバッファアドレスを返す
//1.98で追加
UINT cbRecord = text->cbRecord;
if (text->sizebuff - text->cur >= cbRecord) return TRUE;
return FALSE;
}
LPVOID TXAPI txRecordReadP(tx* text,TXRECORD irecord)
{
// textやpRecordがNULLならFALSEを返す
// irecordのレコードが存在しないときもNULLを返す
// うまくいったらirecordを指すメモリポインタを返します。
// 返せない時はNULLを返します。
//2.97 970216 仕様変更
if (!text) return NULL;
if (!txRecordIsExist(text,irecord)) return NULL;
txRecordExpand(text,irecord + 1);
#if 1//2.97 970216
{
IFILE adr = txRecordGetAddress(text,irecord);
IMEM cbGap = text->cur - text->cur0;
if (text->temp1 <= adr && adr + text->cbRecord <= text->temp1 + text->sizebuff - cbGap) {
// テキストバッファ内にある
IMEM off = (adr - text->temp1);
if (off < text->cur0) {
if (off + text->cbRecord <= text->cur0) {
return text->buff + off;
} else {
// gapにまたがるときは、従来ルーチンを使用
}
} else {
return text->buff + off + cbGap;
}
}
txJumpAddress(text,adr);
if (text->sizebuff - text->cur >= text->cbRecord) return text->buff + text->cur;
return NULL;
}
#else
txJumpAddress(text,txRecordGetAddress(text,irecord));
return text->buff + text->cur;
#endif
}
BOOL TXAPI txRecordReadEx(tx* text,TXRECORD irecord,UINT offset,LPVOID pMem,UINT cbMem)
{
// レコードのoffsetオフセットからcbMemサイズの内容をpMemにロードする
// textやpMemがNULLならFALSEを返す
// irecordのレコードが存在しないときは、pMemを0で初期化しTRUEを返します
if (!text || !pMem) return FALSE;
if (!txRecordIsExist(text,irecord)) {
memset(pMem,0,cbMem);
return TRUE;
}
txRecordExpand(text,irecord + 1);
#if 1//2.97 970216 txJumpAddressの使用を控えて高速化 for linkatr
{
mchar* p = txRecordReadP(text,irecord);
if (p) {
memcpy(pMem,p + offset,cbMem);
return TRUE;
} else {
LPBYTE pRecord = malloc(text->cbRecord);
BOOL ret = FALSE;
if (pRecord) {
if (txRecordRead(text,irecord,pRecord)) {
memcpy(pMem,pRecord + offset,cbMem);
ret = TRUE;
}
free(pRecord);
}
return ret;
}
}
#else
txJumpAddress(text,txRecordGetAddress(text,irecord));
if (txRecordIsInsideBuff(text)) {
memcpy(pMem,text->buff + text->cur + offset,cbMem);
} else {
LPBYTE pRecord = malloc(text->cbRecord);
BOOL ret = FALSE;
if (pRecord) {
if (txRecordRead(text,irecord,pRecord)) {
memcpy(pMem,pRecord + offset,cbMem);
ret = TRUE;
}
free(pRecord);
}
return ret;
}
return TRUE;
#endif
}
BOOL TXAPI txRecordRead(tx* text,TXRECORD irecord,LPVOID pRecord)
{
// textやpRecordがNULLならFALSEを返す
// irecordのレコードが存在しないときは、pRecordを0で初期化しTRUEを返します
if (!text || !pRecord) return FALSE;
if (!txRecordIsExist(text,irecord)) {
memset(pRecord,0,text->cbRecord);
return TRUE;
}
txRecordExpand(text,irecord + 1);
#if 1//2.97 970216 txJumpAddressの使用を控えて高速化 for linkatr
{
IFILE adr = txRecordGetAddress(text,irecord);
IMEM cbGap = text->cur - text->cur0;
if (text->temp1 <= adr && adr + text->cbRecord <= text->temp1 + text->sizebuff - cbGap) {
IMEM off = (adr - text->temp1);
if (off < text->cur0) {
if (off + text->cbRecord <= text->cur0) {
memcpy(pRecord,text->buff + off,text->cbRecord);
return TRUE;
} else {
UINT cb = text->cur0 - off;
memcpy(pRecord,text->buff + off,cb);
memcpy((LPBYTE)pRecord + cb,text->buff + text->cur,text->cbRecord - cb);
return TRUE;
}
} else {
memcpy(pRecord,text->buff + off + cbGap,text->cbRecord);
return TRUE;
}
}
txJumpAddress(text,adr);
if (txRecordIsInsideBuff(text)) {
memcpy(pRecord,text->buff + text->cur,text->cbRecord);
} else {
UINT cb = text->sizebuff - text->cur;
memcpy(pRecord,text->buff + text->cur,cb);
if (!txSwapNext(text)) return FALSE;
memcpy((LPBYTE)pRecord + cb,text->buff + text->cur,text->cbRecord - cb);
}
return TRUE;
}
#else
txJumpAddress(text,txRecordGetAddress(text,irecord));
if (txRecordIsInsideBuff(text)) {
memcpy(pRecord,text->buff + text->cur,text->cbRecord);
} else {
UINT cb = text->sizebuff - text->cur;
memcpy(pRecord,text->buff + text->cur,cb);
if (!txSwapNext(text)) return FALSE;
memcpy((LPBYTE)pRecord + cb,text->buff + text->cur,text->cbRecord - cb);
}
return TRUE;
#endif
}
BOOL TXAPI txRecordWriteEx(tx* text,TXRECORD irecord,UINT offset,LPVOID pMem,UINT cbMem)
{
// レコードのoffsetオフセットからcbMemサイズの内容をpMemにセットする
// textやpMemがNULLならFALSEを返す
// irecordのレコードが存在しないときは、pMemを0で初期化しTRUEを返します
if (!text || !pMem) return FALSE;
txRecordExpand(text,irecord + 1);
txJumpAddress(text,txRecordGetAddress(text,irecord));
text->fEdit = TRUE;
if (txRecordIsInsideBuff(text)) {
memcpy(text->buff + text->cur + offset,pMem,cbMem);
} else {
LPBYTE pRecord = malloc(text->cbRecord);
BOOL ret = FALSE;
if (pRecord) {
if (txRecordRead(text,irecord,pRecord)) {
memcpy(pRecord + offset,pMem,cbMem);
if (txRecordWrite(text,irecord,pRecord)) {
ret = TRUE;
}
}
free(pRecord);
}
return ret;
}
return TRUE;
}
BOOL TXAPI txRecordWrite(tx* text,TXRECORD irecord,LPVOID pRecord)
{
// textやpRecordがNULLならFALSEを返す
// irecordまでで存在しないレコードがあるときは、その部分のデータは0で初期化されます。
if (!text || !pRecord) return FALSE;
txRecordExpand(text,irecord + 1);
txJumpAddress(text,txRecordGetAddress(text,irecord));
text->fEdit = TRUE;
if (txRecordIsInsideBuff(text)) {
memcpy(text->buff + text->cur,pRecord,text->cbRecord);
} else {
UINT cb = text->sizebuff - text->cur;
memcpy(text->buff + text->cur,pRecord,cb);
if (!txSwapNext(text)) return FALSE;
memcpy(text->buff + text->cur,(LPBYTE)pRecord + cb,text->cbRecord - cb);
}
return TRUE;
}
BOOL TXAPI txRecordInsert(tx* text,TXRECORD irecord,TXRECORD nrecord)
{
if (!text) return FALSE;
text->fEdit = TRUE;
txRecordExpand(text,irecord);
txJumpAddress(text,txRecordGetAddress(text,irecord));
txInsertBytes(text,(DWORD)nrecord * text->cbRecord);
return TRUE;
}
BOOL TXAPI txRecordDelete(tx* text,TXRECORD irecord,TXRECORD nrecord)
{
if (!text) return FALSE;
if (!txRecordIsExist(text,irecord)) return TRUE;//1.90
text->fEdit = TRUE;
txRecordExpand(text,irecord);
txJumpAddress(text,txRecordGetAddress(text,irecord));
txDeleteBytes(text,(DWORD)nrecord * text->cbRecord);
return TRUE;
}
TXRECORD TXAPI txRecordGetCount(tx* text)
{
if (!text) return 0;
{
IFILE size = txGetTextSize(text);
if (size <= text->cbHeader) return 0;
return (size - text->cbHeader) / text->cbRecord;
}
}
TXRECORD TXAPI txRecordAdd(tx* text,LPVOID pRecord)
{
// 追加したレコード番号を返す
// 追加できなかったらTXRECORD_ERRORを返す
if (!text) return TXRECORD_ERROR;
{
TXRECORD i = txRecordGetCount(text);
txRecordWrite(text,i,pRecord);
return i;
}
}
BOOL TXAPI txRecordConvertSize(TX* text,UINT cbRecordOld)
{
// レコードのサイズをcbRecordOldから現在の値に変更します。
// 拡大の場合は、レコードの末尾に0を追加して拡大します
// 縮小の場合は、レコードの末尾をカットします
//2.00D で追加
TXRECORD n;
TXRECORD i;
BOOL ret = FALSE;
UINT cbRecordNew = text->cbRecord;
//
text->cbRecord = cbRecordOld;
n = txRecordGetCount(text);
if (cbRecordNew > cbRecordOld) {
// 拡大
IFILE ifile = text->cbHeader + cbRecordOld;
UINT cbExpand = cbRecordNew - cbRecordOld;
LPBYTE p = memAllocZeroinit(cbExpand);
if (p) {
for (i = 0;i < n;i++) {
txJumpAddress(text,ifile);
txInsertBuff(text,p,cbExpand);
ifile += cbRecordNew;
}
memFree(p);
ret = TRUE;
}
} else if (cbRecordNew < cbRecordOld) {
// 縮小
IFILE ifile = text->cbHeader + cbRecordNew;
UINT cbReduce = cbRecordOld - cbRecordNew;
for (i = 0;i < n;i++) {
txJumpAddress(text,ifile);
txDeleteBytes(text,cbReduce);
ifile += cbRecordNew;
}
ret = TRUE;
}
text->cbRecord = cbRecordNew;
return ret;
}
//{###範囲選択}
static IFILE _curwalkstart;
static int _lywalkstart; //1.00C
static int _fselectjump; //1.00C
static BOOL txIsWalkable(tx *text)
{
if (
text->fClip == CLIP_CHAR ||
text->fClip == CLIP_LINE ||
text->fClip == CLIP_PARA ||
text->fClip == CLIP_ALL || //1.00B すべて選択に対応
text->fClip == CLIP_WORD ||
text->fClip == CLIP_SENTENCE
) {
return TRUE;
}
return FALSE;
}
BOOL TXAPIBASE txWalkStart(tx *text)
{
// 範囲内walkを開始します
// この関数を呼び出してからtxIsWalking(text)が真の間まで、
// カーソルをテキスト後方に動かして範囲内のwalkができます
if (!txIsWalkable(text)) return FALSE;
_lywalkstart = text->ly;
_fselectjump = FALSE;
txSetUndisp(text);
if (text->fClip == CLIP_ALL) {//1.00B すべて選択に対応
_curwalkstart = txGetAddress(text);
txJumpFileTop(text);
} else {
#if 1//1.00F
txFlushSelectNow(text);
if (text->clipendnow > text->cliptopnow) {
_fselectjump = TRUE;
txSelectJump(text);
} else {
txSelectToChar(text);
}
_curwalkstart = txGetAddress(text);
#else
if (text->temp1 + text->cur0 > text->cliptop) {
_fselectjump = TRUE;
txSelectJump(text);
}
txFlushCurSelect(text);
_curwalkstart = txGetAddress(text);
#endif
}
return TRUE;
}
BOOL TXAPIBASE txIsWalking(tx *text)
{
// カーソルが範囲内にあるか返します
if (text->fClip == CLIP_ALL) return !txIsCurEof(text);//1.00B すべて選択に対応
return text->temp1 + text->cur0 < text->cliptop;
}
BOOL TXAPIBASE txWalkEnd(tx *text)
{
// 範囲内walkを終わります
// カーソル位置を、範囲の先頭にセットします
if (!txIsWalkable(text)) return FALSE;
text->ly = _lywalkstart;
txJumpAddress(text,_curwalkstart);
if (_fselectjump) txSelectJump(text);
txSetDisp(text);
return TRUE;
}
BOOL TXAPIBASE txWalkStartPrev(tx *text)
{
// 前方範囲内walkを開始します
// この関数を呼び出してからtxIsWalkingPrev(text)が真の間まで、
// カーソルをテキスト前方に動かして範囲内のwalkができます
if (!txIsWalkable(text)) return FALSE;
_lywalkstart = text->ly;
_fselectjump = FALSE;
if (text->fClip == CLIP_ALL) {//1.00B すべて選択に対応
_curwalkstart = txGetAddress(text);
txJumpFileTop(text);
} else {
txSetUndisp(text);
#if 1//1.00F
txFlushSelectNow(text);
if (text->clipendnow < text->cliptopnow) {
_fselectjump = TRUE;
txSelectJump(text);
} else {
txSelectToChar(text);
}
_curwalkstart = txGetAddress(text);
#else
if (text->temp1 + text->cur0 < text->cliptop) {
_fselectjump = TRUE;
txSelectJump(text);
}
txFlushCurSelect(text);
_curwalkstart = text->cliptop;
#endif
}
return TRUE;
}
BOOL TXAPIBASE txIsWalkingPrev(tx *text)
{
// カーソルが前方範囲内にあるか返します
if (text->fClip == CLIP_ALL) {//1.00B すべて選択に対応
return (txGetAddress(text) != 0);
}
return text->temp1 + text->cur0 > text->cliptop;
}
BOOL TXAPI txkeySelectWin(TX* text)
{
//2.95 970125
if (text->modeEditor == ME_WIN) {
if (
(text->fKeyVkShift == 0 && GetKeyState(VK_SHIFT) < 0) ||
text->fKeyVkShift == 2
) {
if (text->fClip && text->fClipMouse) {
// 既に選択中
} else {
if (text->modeKeyClip == MC_WZ) {
txSelectEx(text,CLIP_WZ);
} else if (text->modeKeyClip == MC_VZ) {
txSelectEx(text,CLIP_VZ);
} else {
txSelectEx(text,CLIP_CHAR);
}
text->fClipMouse = TRUE;
}
return TRUE;
} else {
//2.96 970202 txkeyJumpLineTopでSHIFTが押されていないとき選択が解除されてなかった
if (text->fClip && text->fClipMouse) {
txSelectQuit(text);
}
}
}
return FALSE;
}
//{###編集}
int TXAPI txkeyOverWriteChar(TX* text,TXCHAR ch)
{
//2.96 970209 新API
if (text->fClipMouse) txSelectDelete(text);//2.96 970209
if (txGetFreeCursor(text)) txInsertSpaceFreeCursor(text);//1.01A
return txOverWriteChar(text,ch);
}
int TXAPI txkeyInsert(TX* text,mchar* szstr)
{
//2.96 970209 新API
if (text->fClipMouse) txSelectDelete(text);//2.96 970209
if (txGetFreeCursor(text)) txInsertSpaceFreeCursor(text);//1.01A キーボードマクロ再生時に、フリーカーソルが効かなかった
return txInsert(text,szstr);
}
//{###カット&ペースト}
//2.00E7 プライベートテキストスタックのカットアンドペースト系コマンド(txPrivateXXX)追加
//2.98 970305 edit.cから移動
BOOL TXAPIBASE txPrivatePop(tx *text)
{
// プライベートテキストスタックからポップ
// カーソルは移動しません
//2.00E7で追加
BOOL ret = txClipPaste(text,HCLIP_PRIVATE,FALSE,0);
clipDeleteTop(HCLIP_PRIVATE);
return ret;
}
BOOL TXAPIBASE txPrivatePopJump(TX* text)
{
// プライベートテキストスタックからポップ
// カーソルを、ペーストしたバイト数、移動します。
//3.00A2 970506 new
BOOL ret = txClipPaste(text,HCLIP_PRIVATE,TRUE,0);
clipDeleteTop(HCLIP_PRIVATE);
return ret;
}
BOOL TXAPIBASE txPrivateDeleteTop(TX* text)
{
// プライベートテキストスタックの先頭を削除
//2.92で追加
return clipDeleteTop(HCLIP_PRIVATE);
}
BOOL TXAPIBASE txPrivatePaste(tx *text)
{
// プライベートテキストスタックからペースト
// カーソルを、ペーストしたバイト数、移動します。
//2.00E7で追加
return txClipPaste(text,HCLIP_PRIVATE,TRUE,0);
}
void TXAPIBASE txPrivateClear(tx *text)
{
// プライベートテキストスタックをクリア
//2.00E7で追加
clipClear(HCLIP_PRIVATE);
}
BOOL TXAPIBASE TXHIGH txPrivatePush(tx *text)
{
// 範囲内をプライベートテキストスタックへプッシュ
//2.00E7で追加
if (text->fClip) {
return txClipSelectCopy(text,HCLIP_PRIVATE);
} else {
return FALSE;
}
}
//{###ジャンプ}
void TXAPIBASE txJumpSelectTop(tx *text)
{
// 範囲の先頭へジャンプ
if (text->temp1 + text->cur0 > text->cliptop) {
txSelectJump(text);
}
}
void TXAPIBASE txJumpSelectEnd(tx *text)
{
// 範囲の末尾へジャンプ
if (text->temp1 + text->cur0 < text->cliptop) {
txSelectJump(text);
}
}
int TXAPIBASE txJumpNpara(TX* text,NPARA npara)
{
// テキストのnpara段落の、段落の先頭へジャンプ
//2.00Bで追加
int ret = txJumpPara(text,npara);
txJumpParaTop(text);
return ret;
}
//{###マクロ}
DWORD TXAPIBASE call(mchar *szmacro)
{
// マクロを呼び出す。返り値を返す。
// szmacroは大文字小文字を区別しません
// 例:call("launcher");
// 例:call("launcher.root");
// 参考:callは、マクロを通常の関数呼び出しで呼び出すのではなく、新しく
// マクロコンテキストを作成して、このコンテキスト上でマクロを実行します。
// マクロの実行が終るとコンテキストは終了し、callの次の命令の実行に戻ります。
DWORD ret = 0;
// ロジックはcallmacroと同じ
if (strchr(szmacro,'(')) {
// 引数つき
macroCallStr(szmacro,&ret);
} else {
// 引数なし
// textfを引数として渡して呼び出す
extern tx *textf;
macroCall(szmacro,&ret,1,textf);
}
return ret;
}
#ifdef __TXC__
//{###情報取得}
UINT TXAPI txFormChar(TX* text,mchar* str,UINT offset)
{
// strからoffsetバイト目に最も近い文字の先頭のオフセットを返す
//2.99C 970325 new
return txOp(text,TXOP_TXFORMCHAR,(LPARAM)str,(LPARAM)offset);
}
BOOL TXAPI txIsCharTop(TX* text,IBUFF off)
{
// offが文字の先頭かどうか返す
//2.99C 970325 new
return txOp(text,TXOP_TXISCHARTOP,off,0);
}
int TXAPI txGetWordWhole(TX* text,txstr str)
{
// 範囲選択されているとき(txIsClipInPara=真のとき)はtxGetWordと同じ
// そうでなければカーソル位置の単語を取得
// txGetWordと異なるのは、txGetWordは単語の途中にカーソルがあるときは
// カーソル位置から単語の終わりまでを取得するが、txGetWordWholeは、
// 単語の始まりから終わりまでを取得する
//3.00B1 970612 new
if (txIsClipInPara(text)) return txGetWord(text,str);
//
text->fUndisp++;
txSelectEx(text,CLIP_WORD);
int ret = txGetWord(text,str);
txSelectQuit(text);
text->fUndisp--;
return ret;
}
int TXAPI txGetWordEx(TX* text,txstr str)
{
// txGetWordと同じです。
#if 1///3.00A 970428 txGetWordEx=txGetWordとした
return txGetWord(text,str);
#else
// 単語をstrに取得する
// 1行内の範囲選択中なら、範囲内の文字をstrに取得
//{#RET}取得したバイト数を返す
// txGetWordは検索で見つけて選択されている時は選択中とみなさないが、
// このAPIは選択中とみなす。
//2.99C 970324 new
if (text->fClipSearch) {
BOOL fClipSearch0 = text->fClipSearch;
text->fClipSearch = FALSE;
int ret = txGetWord(text,str);
text->fClipSearch = fClipSearch0;
return ret;
} else {
return txGetWord(text,str);
}
#endif
}
//{###マクロ}
BOOL TXAPI txVarSet(TX* text,mchar* szName,DWORD data)
{
// textローカル変数
// 変数名szName、値dataをセット
// 変数名に、'@'文字は使わないで下さい。
// 変数名の長さは最大40文字程度です。変数名が長すぎるとFALSEを返します。
// セットできたかどうか返す
// 3.00B以降ではtextローカル変数はメモリの許す限り使えます。WZ16では1400個まで使えます。
// 3.00,3.00Aでは、textローカル変数は255個使用可能です。
// textローカル変数が満杯になったら、古い変数から順に忘れていきます(ガベージコレクト)
// 大事な変数は、txVarSetNogarbageを使ってガベージコレクトの対象から外せます。
return txOp(text,TXOP_VARSET,(LPARAM)szName,data);
}
DWORD TXAPI txVarGet(TX* text,mchar* szName)
{
// textローカル変数
// 変数名szNameの値をゲット
// ゲットできなれけば0を返す
return txOp(text,TXOP_VARGET,(LPARAM)szName,0);
}
BOOL TXAPI txVarIsExist(TX* text,mchar* szName)
{
// textローカル変数
// 変数名szNameの変数が存在するかどうか返す
return txOp(text,TXOP_VARISEXIST,(LPARAM)szName,0);
}
BOOL TXAPI txVarSetNogarbage(TX* text,mchar* szName,BOOL fNoGarbage)
{
// textローカル変数
// 変数名szNameの変数はガベージコレクトの対象にしない
#if 1//3.00B2 970615 txVarSetNogarbageは使われなくなりました
return FALSE;
#else
return txOp(text,TXOP_VARSETNOGARBAGE,(LPARAM)szName,fNoGarbage);
#endif
}
//{###設定}
void TXAPI txInitConfig(TX* text)
{
// textの設定をシステム既定値にする
// 折り返し幅はMAXWIDTH、書式文字列は標準の設定の初期値、
// 縦書きやバイナリ無効、タブサイズ8、フォントサイズはシステムフォントサイズ
// フォントはMSゴシックかMSPゴシック、プロポーショナルOFF、行番号や
// アンダーライン、制御文字表示オフ、色は標準の色、オートセーブOFF
// バックアップOFF、キー配列は標準のキー配列、行間1など。
//2.99B 970322 new
txConfigOp(text,TXCONFIGOP_TXINITCONFIG,0);
}
//{###編集}
int TXAPIBASE txInsertf(tx *text,mchar *_format,...)
{
// printfの書式の使えるtxInsert
// CCHLINE文字を越える内容を挿入することはできません
mchar buff[CCHLINE];
if (_format) {
vsprintf(buff,_format,(void*)(&_format + 1));
} else {
buff[0] = 0;
}
return txInsert(text,buff);
}
#endif // __TXC__
BOOL TXAPIBASE txCurInsertReturn(TX* text)
{
// 改行を挿入し、カーソルを進めない
//2.99C 970326 new
return txCurInsertBuff(text,"\x0D\x0A",2);
}
int TXAPI txInsertLine(TX *text,mchar *_format,...)
{
// txInsertfと同じですが、改行コードを追加して挿入します
//2.90
mchar buff[CCHLINE];
if (_format) {
vsprintf(buff,_format,(void*)(&_format + 1));
} else {
buff[0] = 0;
}
txInsert(text,buff);
return txInsertReturn(text);
}
//2.00E2 tFontstyle[i]を返す。印刷スタイル使用に対応
FONTSTYLE* txGetFontstyleI(TX* text,int i)
{
LPRINT* lp = text->lp;
FONTSTYLE* fs = NULL;
if (i == FONTTX_MARGIN) {
// lp
fs = &lp->fontstyleMargin;
} else if (
text->lp && //2.99E 970403 txInitText変更の影響
txGetUsePrintFontstyle(text) && FONTTX_BODY <= i && i <= FONTTX_H6
) {
//2.00D
fs = &lp->tFontstyle[i - FONTTX_BODY];
} else if (text->tFontstyle) {
// text
fs = text->tFontstyle + i;
}
return fs;
}
int TXAPI paraatrGetAlign(TX* text,PARAATR* paraatr)
{
#if 1 //1.99G 左寄せが、ALIGN_NONEとALIGN_LEFTの2種類あって、
// 混乱していた。左寄せを<CENTER>としていたりしていた。
// ALIGN_NONEは返さず代わりにALIGN_LEFTを返すようにした。
int ret = paraatr->modeAlign;
if (paraatr->modeTitle) {
#if 1//2.00E2
FONTSTYLE* fs = txGetFontstyleI(text,FONTTX_H1 + paraatr->modeTitle - 1);
#else
FONTSTYLE* fs = &text->tFontstyle[FONTTX_H1 + paraatr->modeTitle - 1];
#endif
if (fs->modeAlign) {
ret = fs->modeAlign;
}
}
if (ret) return ret;
return ALIGN_LEFT;
#else
if (paraatr->modeTitle) {
FONTSTYLE* fs = &text->tFontstyle[FONTTX_H1 + paraatr->modeTitle - 1];
if (fs->modeAlign) {
return fs->modeAlign;
}
}
return paraatr->modeAlign;
#endif
}
int TXAPI paraatrGetNest(TX* text,PARAATR* paraatr)
{
if (text->fHTML) {
// lcxIndentRightは、TAG_BLOCKQUOTE対応の為
return (paraatr->lcxIndent - paraatr->lcxIndentRight) / LCXINDENT_STD;
} else {
if (text->tabsize) {
return paraatr->lcxIndent / text->tabsize;
}
}
return 0;
}
int TXAPI paraatrGetArticle(TX* text,PARAATR* paraatr)
{
switch(paraatr->modeArticle) {
case ARTICLE_AUTO: {
int nest = paraatrGetNest(text,paraatr);
if (nest <= 1) return ARTICLE_DISC;
if (nest == 2) return ARTICLE_CIRCLE;
if (nest == 3) return ARTICLE_SQUARE;
break;
}
case ARTICLE_ALL: {
return ARTICLE_DISC;
}
}
return paraatr->modeArticle;
}
BOOL TXAPIBASE txInsertText(TX* text,TX* textInsert)
{
//1.97 カーソル位置にtextInsertを挿入する
#if 1//2.00E 長時間wzlockするには問題がある様で、高速/詳細モードのファイルを3つ以上プロジェクトなどで一斉に開くとハングアップした
txSetUndisp(textInsert);
txSelectAll(textInsert);
txClipSelectCopy(textInsert,HCLIP_PRIVATE);
txClipPaste(text,HCLIP_PRIVATE,TRUE,CLIP_CHAR);
clipDeleteTop(HCLIP_PRIVATE);
txSelectQuit(textInsert);
txSetDisp(textInsert);
return TRUE;
#else
wzlock(LOCK_CLIPTS);
txSetUndisp(textInsert);//1.99C
#if 1 // txSelectAllのバグが直った
txSelectAll(textInsert);
#else
txSelectQuit(textInsert);
txJumpFileTop(textInsert);
txSelect(textInsert);
txJumpFileEnd(textInsert);
#endif
txSelectTsPush(textInsert);
txClipPaste(text,HCLIP_TS,TRUE,CLIP_CHAR);
clipDeleteTop(HCLIP_TS);
wzunlock(LOCK_CLIPTS);
//
txSelectQuit(textInsert);//1.99C
txSetDisp(textInsert);//1.99C
return TRUE;
#endif
}
BOOL TXAPIBASE txInsertTextSelect(TX* text,TX* textInsert)
{
// カーソル位置にtextInsertの範囲選択部分を挿入する
// textInsertが範囲選択されていないときはtxInsertTextと同じ
//2.00Bで追加
if (textInsert->fClip) {
#if 1 //2.00E wzlockをしない
txClipSelectCopy(textInsert,HCLIP_PRIVATE);
txClipPaste(text,HCLIP_PRIVATE,TRUE,CLIP_CHAR);
clipDeleteTop(HCLIP_PRIVATE);
return TRUE;
#else
wzlock(LOCK_CLIPTS);
txSelectTsPush(textInsert);
txClipPaste(text,HCLIP_TS,TRUE,CLIP_CHAR);
clipDeleteTop(HCLIP_TS);
wzunlock(LOCK_CLIPTS);
return TRUE;
#endif
} else {
return txInsertText(text,textInsert);
}
}
BOOL TXAPI TXCMD txTsPopJump(tx *text)
{
// テキストスタックからポップ
// カーソルを貼り付けしたデータの末尾の次の文字へ移動します
//2.00Bで追加
BOOL ret = FALSE;
wzlock(LOCK_CLIPTS);
ret = txClipPaste(text,HCLIP_TS,TRUE,CLIP_CHAR);
clipDeleteTop(HCLIP_TS);
wzunlock(LOCK_CLIPTS);
return ret;
}
//{###情報取得}
BOOL TXAPI paraatr2Read(TX* text,NLINE npara,PARAATR2* paraatr2)
{
//2.90
if (!text->txparaatr2) {
memset(paraatr2,0,sizeof(PARAATR2));
return TRUE;
}
return txRecordRead(text->txparaatr2,npara,paraatr2);
}
BOOL TXAPI paraatr2Write(TX* text,NLINE npara,PARAATR2* paraatr2)
{
//2.90
return txRecordWrite(text->txparaatr2,npara,paraatr2);
}
//1.90 WZ.EXE内で使えるようにした
int TXAPI TXHIGH txCmpCur(tx *text,mchar *szstr)
{
// カーソル位置が文字列szstrと等しいか返す
// 等しければszstrの長さ、等しくなければ0を返す
// 比較できない場合もある。この場合は0を返す
int len = strlen(szstr);
if (text->cur + len <= text->sizebuff) {//1.90
if (!memcmp(text->buff + text->cur,szstr,len)) return len;
}
return 0;
}
int TXAPI TXHIGH txCmpCurI(tx *text,mchar *szstr)
{
// カーソル位置が文字列szstrと等しいか返す
// 等しければszstrの長さ、等しくなければ0を返す
// 比較できない場合もある。この場合は0を返す
// 英大/小を区別しないで調べる
//2.92で追加
int len = strlen(szstr);
if (text->cur + len <= text->sizebuff) {//1.90
if (!strnicmp(text->buff + text->cur,szstr,len)) return len;
}
return 0;
}
int TXAPI TXHIGH txCmpCurLen(tx *text,mchar *szstr,int lch)
{
// カーソル位置が長さlchの文字列szstrと等しいか返す
// 等しければlch、等しくなければ0を返す
// 比較できない場合もある。この場合は0を返す
//1.95で追加
if (text->cur + lch <= text->sizebuff) {//1.90
if (!memcmp(text->buff + text->cur,szstr,lch)) return lch;
}
return 0;
}
int TXAPI TXHIGH txCmpCurLenI(tx *text,mchar *szstr,int lch)
{
// カーソル位置が長さlchの文字列szstrと等しいか返す
// 等しければlch、等しくなければ0を返す
// 比較できない場合もある。この場合は0を返す
// 英大/小を区別しないで調べる
//2.92で追加
if (text->cur + lch <= text->sizebuff) {//1.90
if (!strnicmp(text->buff + text->cur,szstr,lch)) return lch;
}
return 0;
}
//1.90 WZ.EXE内で使えるようにした
int TXAPI TXHIGH txCmpCurPrev(tx *text,mchar *szstr)
{
// カーソル位置の手前の文字列が文字列szstrと等しいか返す
// 等しければszstrの長さ、等しくなければ0を返す
// 比較できない場合もある。この場合は0を返す
//1.90 で追加
int len = strlen(szstr);
if (text->cur0 >= len) {
if (!memcmp(text->buff + text->cur0 - len,szstr,len)) return len;
}
return 0;
}
//{###情報取得}
BOOL TXAPI txIsSwap1(tx *text)
{
// テキストバッファスワップ
// txSwap1でスワップするデータがあるか返す
if (text->temp2 > 0 || !text->fReadAll) return TRUE;
return FALSE;
}
BOOL TXAPI txIsSwap2(tx *text)
{
// テキストバッファスワップ
// txSwap2でスワップするデータがあるか返す
if (text->temp1 > 0) return TRUE;
return FALSE;
}
BOOL TXAPI txIsBinary(tx *text)
{
// テキストがバイナリファイルか調べる
// text->fOpenが真ならファイルの内容も調べ、
// コントロールコードが入っていたらTRUEを返す
// text->fOpenが偽ならファイルの拡張子を調べる
#define BINCHECKSIZE 200
long size = text->sizebuff - text->cur;
mchar *p = text->buff + text->cur;
// 開いた後だとファイル名でチェックしても遅い
// 拡張子でチェック
{
mchar *szext = pathGetExt(text->szfilename);
if (!stricmp(szext,".exe")) return TRUE;
if (!stricmp(szext,".com")) return TRUE;
if (!stricmp(szext,".bmp")) return TRUE;
if (!stricmp(szext,".wri")) return TRUE;
if (!stricmp(szext,".rec")) return TRUE;
if (!stricmp(szext,".hlp")) return TRUE;
if (!stricmp(szext,".ico")) return TRUE;
if (!stricmp(szext,".lch")) return TRUE;
if (!stricmp(szext,".tll")) return TRUE;
if (!stricmp(szext,".txm")) return TRUE;//1.00C
if (!stricmp(szext,".txe")) return TRUE;//1.00C
if (!stricmp(szext,".3ll")) return TRUE;//1.00H3
if (!stricmp(szext,".3xm")) return TRUE;//1.00H3
if (!stricmp(szext,".3xe")) return TRUE;//1.00H3
if (!strnicmp(szext,".~",2)) return TRUE; // TX-UNDO
}
if (text->fOpen) {
// 開いてチェック
if (size > BINCHECKSIZE) {
size = BINCHECKSIZE;
} else {
p = text->buff;
size = text->cur0;
if (size > BINCHECKSIZE) size = BINCHECKSIZE;
}
//printf("%u,%u\n",size,(p - text->buff));
while(size > 0) {
mchar c = *p++;
size--;
if (iskanji(c)) {
c = *p++;
size--;
if (!iskanji2(c)) return TRUE;
} else if (
isspace(c) ||
c == 0x1B ||
' ' <= c
) {
// OK
} else {
return TRUE;
}
}
}
return FALSE;
}
BYTE TXAPI txGetCharW(tx *text,IBUFF off)
{
// off(text->cur0 <= off < text->sizebuff)の文字の幅(1or2)を返す
//2.00B GetCharW -> txGetCharWに名称変更
mchar c = text->buff[off];
if (!text->buff) return 0;
if (text->fBinedit) return 1;
if (iskanji(c) && !text->fCurWestern) return 2;
return 1;
}
BYTE TXAPI TXHIGH txGetCharSize(tx *text,IBUFF off)
{
// offの文字のバイト数を返す
// EOFなら0を返す
//2.00B GetCharSize -> txGetCharSizeに名称変更
if (!text->buff) return 0;
{
mchar c = text->buff[off];
if (c == 0x1A && off + 1 == text->sizebuff && !txIsSwap1(text)) {
// EOF
return 0;
} else {
if (text->fBinedit) return 1;
if (
(iskanji(c) && !text->fCurWestern) ||
(c == 0x0D && text->buff[off + 1] == 0x0A)
) {
if (off + 1 < text->sizebuff) {
return 2;
}
}
return 1;
}
}
}
BOOL TXAPI txGetFreeCursor(TX* text)
{
// フリーカーソルがONかどうか返します
//2.00Eで追加
return (text->modeFreeCursor == 1 && !text->fBinedit);
}
BOOL TXAPIBASE TXHIGH_THROUGH txIsCurFree(tx *text)
{
// カーソルがフリー領域内にあるかどうか返します。
//1.00H4 仕様変更。以前は、フリーカーソルが"off","VZ"のときは必ずFALSEを返して
// いましたが、カーソルがtxJumpLineTailした状態にあるときはTRUEを返します。
if (text->fHigh) return FALSE;//1.00B 行末でhelpをtxAnkToJankするとhelppになっていた
#if 1//1.00H4 フリーカーソルオフで、折り返しのある表示でtxJumpLineTailしてtxRightWordするとおかしくなった
if (text->cur0 - text->cury == text->curysize) return TRUE;
if (!txGetFreeCursor(text)) return FALSE;
#else
if (!txGetFreeCursor(text)) return FALSE;
if (text->cur0 - text->cury == text->curysize) return TRUE;
#endif
{
int size = txGetCharSize(text,text->cur);
if (size == 0 || text->cur0 - text->cury + size == text->curysize) {
if (text->lfEditProp) {//1.91A lfProp->lfEditProp
//1.01A プロポーショナル時のフリーカーソル判別が間違っていた
int xtail = txGetXLineTail(text);
if (text->x >= xtail) return TRUE;
} else {
//1.00C EOF行のフリーカーソル動作改善
int lxtail = txGetLxLineTail(text);
if (text->lx >= lxtail) return TRUE;
}
}
}
return FALSE;
}
//{###編集}
//1.90
// text->lfEditPropが真なら必ずNULL以外の値を返す。
// そうでなければNULLを返すこともある
LPBYTE TXAPI txGetTcxcharStd(tx* text)
{
if (text->editmode == 2) {
return text->tfonttx[FONTTX_BODY].tcxChar;
} else {
return text->tfonttx[FONTTX_TEXT].tcxChar;
}
}
int TXAPI txGetIfonttxStd(TX* text)
{
//2.99D 970329 new
if (text->editmode == 2) {
return FONTTX_BODY;
} else {
return FONTTX_TEXT;
}
}
FONTTX* TXAPI txGetFonttxStd(tx* text)
{
if (!text->tfonttx) return NULL;
if (text->editmode == 2) {
return &text->tfonttx[FONTTX_BODY];
} else {
return &text->tfonttx[FONTTX_TEXT];
}
}
int TXAPI TXHIGH_THROUGH txInsertSpaceFreeCursor(tx *text)
{
// 表示行末以降、カーソル位置までスペース挿入
if (text->fHigh) return FALSE;//1.99D
if (txIsCurFree(text)) {//1.00C EOF行のフリーカーソル動作改善
int len;
mchar buff[CCHLINE];
if (text->lfEditProp) {
//1.00H6
int xTail = txGetXLineTail(text);
LPBYTE tcxChar = txGetTcxcharStd(text);
if (!tcxChar) return FALSE;//1.97
len = (text->x - xTail) / tcxChar[0x20];
if (len == 0 && txIsCurEof(text)) {
//EOF上で文字挿入すると半角スペースも一つ入っちゃう
return FALSE;
}
} else {
int lxtail = txGetLxLineTail(text);
len = text->lx - lxtail;
}
if (txIsLineReturn(text)) {
//1.00H3
text->fNomoveBase++;
text->fUndispCursor++;
txJumpLineEnd(text);
text->fNomoveBase--;
text->fUndispCursor--;
len++;
if (len >= 0) {
memset(buff,' ',len);
buff[len] = 0;
txInsert(text,buff);
}
return len;
} else {
#if 1 //1.00F 右方向キーを押し続けてフリー域に入って文字を挿入すると、
//行末文字の前に挿入されてしまっていた。行末に入るようにした。
if (text->cur0 - text->cury < text->curysize) {
txRight(text);
return TRUE;
}
return FALSE;
#else
if (len >= 0) {
memset(buff,' ',len);
buff[len] = 0;
txInsert(text,buff);
}
#endif
}
}
return 0;
}
//{###情報取得}
BOOL TXAPIBASE txIsLineLf(tx *text)
{
// カーソル位置の表示行が改行で終わっているかどうか返します。
// txIsLineReturnと異なりEOF行の場合はFALSEを返します。
//{#RET}CR+LF・LFなら真、そうでなければ偽を返します
//1.00Dで追加
if (text->fHigh) return FALSE;//1.99D
{
int len = text->curysize - (text->cur0 - text->cury);
if (len > 0) {
mchar c = text->buff[text->cur + len - 1];
if (c == 0x0A) return TRUE;
return FALSE;
}
if (text->curysize > 0) {
mchar c = text->buff[text->cur0 - 1];
if (c == 0x0A) return TRUE;
return FALSE;
}
return FALSE;
}
}
BOOL TXAPIBASE txIsClipInPara(tx *text)
{
// 論理行一行内の範囲選択中ならTRUEを返す
if (
text->fClip == CLIP_CHAR ||
text->fClip == CLIP_WORD ||
text->fClip == CLIP_LINE ||
text->fClip == CLIP_PARA
) { //1.00E 以前はif(text->fClip)で判定してたが、CLIP_ALLのとき誤動作する
#if 1//1.99E CLIP_PARAの時に変だったので全面変更
if (text->fBinedit) {
//2.00E バイナリ編集時は選択範囲が16バイト以下ならTRUEを返す
return (txGetAddressSelectEnd(text) - txGetAddressSelectTop(text) <= 16);
} else {
IFILE paratop = txGetParaTop(text);
IFILE paraend = txGetParaEnd(text);
txFlushSelectNow(text);
{
IFILE cliptop = text->cliptopnow;
IFILE clipend = text->clipendnow;
if (cliptop > clipend) {
cliptop = text->clipendnow;
clipend = text->cliptopnow;
}
return (paratop <= cliptop && clipend <= paraend);
}
}
#else
IFILE paratail = text->cliptopparatail;
//1.99A EOF行でFALSEを返していて、txGetWordなどに影響していた
// cliptopparatailは次の段落の先頭を差すが、EOF行では段落末を差すため
if (paratail == txGetTextSize(text)) {
paratail++;
}
//
if (text->cliptoppara <= text->temp1 + text->cur0 && text->temp1 + text->cur0 < paratail) {//1.00F
return TRUE;
}
//1.00C SelectVzで文字選択モードから行選択モードに移る際、カーソルがフリーカーソル域にあるとおかしかった
if (txIsCurFree(text) && text->temp1 + text->cur0 < paratail) return TRUE;//1.00F
#endif
}
return FALSE;
}
int TXAPI GetSystemFontNo(void)
{
// 定義済みのシステムフォントの番号を返す
//2.00Eで追加
if (_fwin40/* && _platform == WINDOWS95 2.98A */) {
#ifdef __FLAT__
return DEFAULT_GUI_FONT;
#endif
}
return SYSTEM_FONT;
}
//{###検索・置換}
BOOL TXAPI TXHIGH txSearchPara(tx *text,mchar *szfind)
{
// カーソル行も検索範囲に含めて行単位の検索をします
// 行の頭がszfindと一致したら、カーソルを行頭にセットしてTRUEを返します
// 次候補を検索するには、txNextParaしてから呼び出して下さい
// 大文字小文字区別あり、全角半角区別ありで検索します。
#if 1//1.92
return txSearchEx(text,szfind,SEARCH_NOESC|SEARCH_CUR|SEARCH_PARATOP);
#else
static searcharg arg;
{
static BOOL finit;
if (!finit) {
finit = TRUE;
arg.sizeStruct = sizeof(arg);
arg.fSearchSenseCase = TRUE;
arg.fSearchSenseZenhan = TRUE;
arg.fSearchEscapeNo = TRUE;
arg.fSearchCur = TRUE;
}
}
txJumpParaTop(text);
#if 1
arg.szFind = szfind;
while(1) {
if (!txSearchArg(text,&arg)) return FALSE;
if (txGetParaTop(text) == txGetAddress(text)) return TRUE;
if (!txNextPara(text)) return FALSE;
}
#else
while(1) {
if (!strncmp(text->buff + text->cur,szfind,len)) return TRUE;
if (!txNextPara(text)) return FALSE;
}
#endif
#endif
}
//{###時間}
//現在時間を調べたりする機能を提供します。
void TXAPIBASE wait(DWORD ms)
{
// msミリ秒何もしません。
DWORD tm0 = GetCurrentTime();
while(GetCurrentTime() - tm0 < ms);
}
#ifdef __TXC__
//##time.c
DWORD TXAPI wtmGetNow(void)
{
// Windows時間を返す
return GetCurrentTime();
}
void TXAPI itimeGetNow(TIME *time)
{
// 現在時刻をtimeに得る
//1.00Cで追加
timeGet(time);
}
void TXAPI itimeToTm(TIME *time,TM *tm)
{
// time(整数)をtm(年月日時分秒)に変換する
//1.00Cで追加
timeGetLocal(tm,time);
}
void TXAPI itimeFromTm(TIME *time,TM *tm)
{
// tm(年月日時分秒)をtime(整数)に変換する
//1.00Cで追加
TIME timeWork = -1;
timeGetLocal(tm,&timeWork);
*time = timeWork;
}
TIME _time;
TM _tm;
static void time()
{
timeGet(&_time);
timeGetLocal(&_tm,&_time);
}
int TXAPIBASE timeGetYear(void)
{
// 年を返す
time();
return _tm.tm_year;
}
int TXAPIBASE timeGetMonth(void)
{
// 月を返す
time();
return _tm.tm_mon+1;
}
int TXAPIBASE timeGetDay(void)
{
// 日を返す
time();
return _tm.tm_mday;
}
int TXAPIBASE timeGetDayofweek(void)
{
// 曜日を返す(日曜が0)
time();
return _tm.tm_wday;
}
mchar TXAPIBASE *timeGetYoubi(void)
{
// 文字列で曜日を返す(日曜が"日")
static mchar *szwday[] = {"日","月","火","水","木","金","土",};
return szwday[timeGetDayofweek()];
}
int TXAPIBASE timeGetHour(void)
{
// 時を返す
time();
return _tm.tm_hour;
}
int TXAPIBASE timeGetMinute(void)
{
// 分を返す
time();
return _tm.tm_min;
}
int TXAPIBASE timeGetSecond(void)
{
// 秒を返す
time();
return _tm.tm_sec;
}
//##beep.c
//{###音}
//ビープ音を鳴らします。
void TXAPIBASE beep(void)
{
// 標準ビープサウンドを再生します
#if 1
//2.90 音が鳴らないPCがある
MessageBeep(MB_OK);
#else
MessageBeep(-1);
#endif
}
void TXAPI beepAsterisk(void)
{
// アスタリスクビープサウンドを再生します
MessageBeep(MB_ICONASTERISK);
}
void TXAPI beepExclamation(void)
{
// 絶叫ビープサウンドを再生します
MessageBeep(MB_ICONEXCLAMATION);
}
void TXAPI beepHand(void)
{
// HANDビープサウンドを再生します
MessageBeep(MB_ICONHAND);
}
void TXAPI beepQuestion(void)
{
// ?ビープサウンドを再生します
MessageBeep(MB_ICONQUESTION);
}
void TXAPI beepDefault(void)
{
// デフォルトのビープサウンドを再生します
MessageBeep(MB_OK);
}
//##dat.c
//{###ファイル操作}
#export
#ifdef __FLAT__//1.00F datReadNumI etc追加
#define datReadNumI datReadNum
#define datWriteNumI datWriteNum
#else
#define datReadNumI datReadNumW
#define datWriteNumI datWriteNumW
#endif
#endexport
BOOL TXAPI fileWriteStr(HFILE hf,mchar *sz)
{
int len = strlen(sz);
return (_lwrite(hf,sz,len) == len);
}
BOOL TXAPI fileWriteNum(HFILE hf,int num)
{
mchar buff[20];
int len;
sprintf(buff,"%d",num);
len = strlen(buff);
return (_lwrite(hf,buff,len) == len);
}
BOOL TXAPI datReadNum(mchar *szRecord,mchar *szName,int *num)
{
#include "dat.ci"
}
BOOL TXAPI datReadNumW(mchar *szRecord,mchar *szName,WORD *num)
{
#include "dat.ci"
}
BOOL TXAPI datReadNumB(mchar *szRecord,mchar *szName,BYTE *num)
{
#include "dat.ci"
}
// szDst:mchar[CCHPATHNAME]
BOOL TXAPI datRead(mchar *szRecord,mchar *szName,mchar *szDst)
{
mchar *p = szRecord;
int len = strlen(szName);
if (!memcmp(p,szName,len) && p[len] == '=') {
p += len + 1;
while(1) {
if (*p < ' ') {
*szDst = 0;
break;
}
*szDst++ = *p++;
}
return TRUE;
}
return FALSE;
}
void TXAPI datWrite(HFILE hf,mchar *szName,mchar *szData)
{
if (szName[0] == '[' && szData == NULL) {
fileWriteStr(hf,szName);
} else {
fileWriteStr(hf,szName);
_lwrite(hf,"=",1);
fileWriteStr(hf,szData);
}
fileWriteStr(hf,"\n");
}
void TXAPI datWriteNum(HFILE hf,mchar *szName,int data)
{
mchar buff[20];
fileWriteStr(hf,szName);
sprintf(buff,"=%d\n",data);
fileWriteStr(hf,buff);
}
//
// for C program
//
void TXAPI datWriteNumC(HFILE hf,mchar *szName,int data)
{
mchar buff[20];
fileWriteStr(hf,szName);
sprintf(buff," = %d;\n",data);
fileWriteStr(hf,buff);
}
void TXAPI datWriteStrC(HFILE hf,mchar *szName,mchar *szData)
{
mchar buff[250];
sprintf(buff,"strcpy(%s,\\\"%s\");\n",szName,szData);
_lwrite(hf,buff,strlen(buff));
}
#endif// __TXC__
#endif// __NOTX__
//##str.c
//{###文字列操作}
mchar * TXAPIBASE strGetWordTop(mchar *szStr)
{
// 文字列szStrの先頭部分のスペース・タブをスキップし、
// その次の文字のポインタを返します
// スキップ中にNULL文字が現れたら、NULL文字へのポインタを返します
while(*szStr == '\t' || *szStr == ' ') szStr++;
return szStr;
}
int TXAPIBASE strGetWordLen(mchar *szStr)
{
// 文字列szStrのスペース・タブまでの文字列のバイト数を返します
// ""内、0x0C-0x0C内のデリミタは無視する
//2.00Eから、()内,[]内のデリミタは無視しない
mchar *p = szStr;
BOOL fdq = FALSE;
BOOL fff = FALSE;
int nBrace = 0;
int len = 0;
while(1) {
mchar c = p[len];
if (iskanji(c)) {//1.00B '['や']'が漢字2バイト目にマッチすることがある
if (p[len + 1]) {
len += 2;
} else {
break;
}
#if 1//1.00F ""内、0x0C..0x0C内のデリミタも無視する
} else if (c == '"') {
fdq ^= 1;
len++;
} else if (c == 0x0C) {
fff ^= 1;
len++;
#endif
#if 0//2.00E5 // ファイル名に閉じていない()や[]が使えなかった
} else if (c == '(' || c == '[') {
nBrace++;
len++;
} else if (c == ')' || c == ']') {
nBrace--;
len++;
#endif
} else if (c == '\t' || c == ' ') {
if (nBrace || fdq || fff) {
len++;
} else {
break;
}
} else if (c < ' ') {
break;
} else {
len++;
}
}
return len;
}
int TXAPI strGetLineLen(mchar *szStr)
{
// 文字列szStrの改行までの文字列のバイト数を返します
mchar *p = szStr;
int len = 0;
while(1) {
mchar c = p[len];
if (c == 0x0D || c == 0x0A || c == 0) {
break;
} else {
len++;
}
}
return len;
}
mchar * TXAPI strGetWord(mchar szbuff[CCHPATHNAME],mchar *szstr)
{
// strGetWordLen(strGetWordTop(szStr))して、結果をszbuffにコピーします
// szbuffに入りきらなければ、szbuff[0] = 0とします
// szStrの次の語を指すポインタを返します(先頭にスペースがついています)
mchar* top = strGetWordTop(szstr);
int len = strGetWordLen(top);
if (len >= CCHPATHNAME) {
szbuff[0] = 0;
} else {
memcpy(szbuff,top,len);
szbuff[len] = 0;
}
return top + len;
}
int TXAPI strNum(mchar *p,int *num)
{
// 文字列pの先頭が数字列なら、数値に変換して*numに代入します
// 変換した文字数を返します。
// 変換しなかった場合は、*numに0を代入します
int len = 0;
*num = 0;
while(1) {
mchar c = p[len];
if (isdigit(c)) {
*num *= 10;
*num += c - '0';
len++;
} else {
return len;
}
}
}
mchar * TXAPI strGetLast(mchar *szstr)
{
// 文字列szstrの最後の文字へのポインタを返す
// szstrが0なら、0を返す
// szstrが""なら、""へのポインタを返す
mchar *p = szstr;
mchar *p0 = p;
mchar c;
if (!p) return NULL;
while(c = *p) {
p0 = p;
if (iskanji(c)) {
p += 2;
} else {
p++;
}
}
return p0;
}
int TXAPI strGetCharSize(mchar *szstr)
{
// szstr位置の文字のバイト数を返します
// 文字が0(ヌル文字)なら、0、漢字なら2、それ以外は1を返します
if (iskanji(szstr[0]) && szstr[1]) return 2;
if (szstr[0]) return 1;
return 0;
}
int TXAPI _hextoint(int c)
{
if (isdigit(c)) {
return c - '0';
} else if ('A' <= c && c <= 'F') {
return c - 'A' + 10;
} else if ('a' <= c && c <= 'f') {
return c - 'a' + 10;
}
return 0;
}
// 16進2桁をintに変換。szhexが2桁ない場合は-1を返す
//1.00C 検索/置換/タイトル文字列で、「\x16進数2桁」で制御文字を指定できるようにした
int TXAPI hextoint(mchar *szhex)
{
if (szhex[0] && szhex[1]) {
return _hextoint(szhex[0]) * 16 + _hextoint(szhex[1]);
}
return -1;
}
mchar * TXAPI strfromesc(mchar *szstr)
{
// szstr内の\によるエスケープ文字を通常文字に変換します。
// '\s'->' '、'\t'->タブ、'\n'->改行、'\X'->Xに変換します。
//1.92 '\xXX'->16進データに変換します。
// szstrを返します
mchar *src = szstr;
mchar *dst = szstr;
int c;
while(c = *src++) {
if (iskanji(c)) {
*dst++ = c;
*dst++ = *src++;
} else if (c == '\\') {
c = *src++;
if (c == 's') {
*dst++ = ' ';
} else if (c == 't') {
*dst++ = '\t';
} else if (c == 'n') {
*dst++ = 0x0D;
*dst++ = 0x0A;
} else if (c == 'x' || c == 'X') {
int d = hextoint(src);
if (d == -1) break;
*dst++ = d;
src += 2;
} else {
*dst++ = c;
}
} else {
*dst++ = c;
}
}
*dst = 0;
return szstr;
}
static int inttohex(int c)
{
if (c >= 10) return c - 10 + 'A';
return c + '0';
}
mchar * TXAPI strtoesc(mchar *szstr)
{
// スペースなどを\によるエスケープ文字に変換します
// ' '->'\s'、タブ->'\t'、改行(CR+LF)->'\n'に変換します。
//1.92 "0x01" - "0x1F"は"\x01" - "\x1F"に変換します。
//3.00B1 970612 "\"は"\\"に変換します。
// szstrを返します
// 文字列の長さが長くなりますので、szstrのバッファサイズは十分な大きさをとって下さい
mchar *src = szstr;
mchar szbuff[CCHLINE];
mchar *dst = szbuff;
int c;
while(c = *src++) {
if (iskanji(c)) {
*dst++ = c;
*dst++ = *src++;
} else if (c == '\\') {//3.00B1 970612
*dst++ = '\\';
*dst++ = '\\';
} else if (c == ' ') {
*dst++ = '\\';
*dst++ = 's';
} else if (c == '\t') {
*dst++ = '\\';
*dst++ = 't';
} else if (c == 0x0D && *src == 0x0D) {
*dst++ = '\\';
*dst++ = 'n';
src++;
} else if (c < 0x20) {
*dst++ = '\\';
*dst++ = 'x';
*dst++ = inttohex(c / 16);
*dst++ = inttohex(c & 0x0F);
} else {
*dst++ = c;
}
}
*dst = 0;
strcpy(szstr,szbuff);
return szstr;
}
int TXAPI formstrex(mchar *str,BOOL fCurWestern)
{
//文字列strの終わりが漢字第1バイトやCR+LFの第1バイトで切れていたら、それを削除する
//fCurWesternがTRUEなら、漢字は英字2文字として扱います。
//調整後の文字列の長さを返す
//2.00Bで追加
mchar *p = str;
while(1) {
if (iskanji(*p) && !fCurWestern) {
if (p[1]) {
p += 2;
} else {
*p = 0;
break;
}
} else if (*p == 0x0D) {
if (p[1] == 0x0A) {
p += 2;
} else {
*p = 0;
break;
}
} else if (*p) {
p++;
} else {
break;
}
}
return p - str;
}
int TXAPI formstr(mchar *str)
{
//文字列strの終わりが漢字第1バイトやCR+LFの第1バイトで切れていたら、それを削除する
//調整後の文字列の長さを返す
//1.00Cで追加 txGetWordなどでバッファがあふれて、改行コードや漢字が途中で切れることがあったのを修正
//1.97 TX-Cのライブラリにも追加
return formstrex(str,FALSE);
}
static UINT formchar2(mchar* str,UINT off)
{
while (off--) {
if (str[off] < 0x40) return off;
}
return 0;
}
UINT TXAPI formchar(mchar *str,UINT offset)
{
// 文字列topのオフセットoffsetが文字の第1バイトであるかどうかを調べます
// 第1バイトであればoffsetをそのまま返します
// そうでなければoffset未満でoffsetに最も近い文字の第1バイトのオフセットを返します
//2.00Bで追加
if (offset) {
UINT off,off0;
#if 1//1.00F2 formchar 高速化
off = formchar2(str,offset);
#else
off = 0;
#endif
while(1) {
mchar c = str[off];
off0 = off;
if (iskanji(c)) {
off++;
if (iskanji2(str[off])) {
off++;
}
} else if (c == 0x0D) {
off++;
if (str[off] == 0x0A) {
off++;
}
} else {
off++;
}
if (off > offset) {
return off0;
}
}
} else {
return 0;
}
}
mchar * TXAPI strcpymax(mchar *szdst,mchar *szsrc,int lchmax)
{
// szdstにszstrを最大lchmax-1文字コピーする
// コピー後、szdstの末尾にヌルターミネータを追加する
// szdstを返す
int lch = strlen(szsrc);
if (lch >= lchmax) {
lch = lchmax - 1;
memcpy(szdst,szsrc,lch);
szdst[lch] = 0;
formstr(szdst);//1.97
} else {
memcpy(szdst,szsrc,lch);
szdst[lch] = 0;
}
return szdst;
}
int TXAPI strmatchplain(mchar *szstr,mchar *szid)
{
// szstrの先頭がszidならszidの長さ、そうでなければ0を返す
// szidの\も特別扱いせずに比較
//3.00B1 970612 new
int lch = strlen(szid);
if (!strncmp(szstr,szid,lch)) return lch;
return 0;
}
int TXAPI strimatchplain(mchar *szstr,mchar *szid)
{
// szstrの先頭がszidならszidの長さ、そうでなければ0を返す
// szidの\も特別扱いせずに比較
// 大小文字は区別しないで比較
//3.00B1 970612 new
int lch = strlen(szid);
if (!strnicmp(szstr,szid,lch)) return lch;
return 0;
}
int TXAPI strmatch(mchar *szstr,mchar *szid)
{
// szstrの先頭がszidならszidの長さ、そうでなければ0を返す
// szidの\tはタブ、\sは空白、\xはxとして比較
// マッチしたszstrの長さを返す
int len = 0;
while(1) {
mchar c1 = *szstr++;
mchar c2 = *szid++;
if (c2 == 0) return len;
if (c1 == 0) return 0;
if (c2 == '\\') {
c2 = *szid++;
if (
(c1 == c2) ||
(c1 == '\t' && c2 == 't') ||
(c1 == ' ' && c2 == 's')
) {
// OK
} else {
return 0;
}
} else if (c1 != c2) {
return 0;
} else if (iskanji(c1)) {
c1 = *szstr++;
c2 = *szid++;
if (c1 != c2) return 0;
len++;
}
len++;
}
}
int TXAPI strimatch(mchar *szstr,mchar *szid)
{
// strmatchと同じですが、
// 大小文字は区別しないで比較
int len = 0;
while(1) {
mchar c1 = *szstr++;
mchar c2 = *szid++;
if (c2 == 0) return len;
if (c1 == 0) return 0;
if (c2 == '\\') {
c2 = *szid++;
if (
(c1 == c2) ||
(c1 == '\t' && c2 == 't') ||
(c1 == ' ' && c2 == 's')
) {
// OK
} else {
return 0;
}
} else if (toupper(c1) != toupper(c2)) {
return 0;
} else if (iskanji(c1)) {
c1 = *szstr++;
c2 = *szid++;
if (c1 != c2) return 0;
len++;
}
len++;
}
}
int TXAPI strisid(mchar *szstr,mchar *szid)
{
// szstrの先頭がszidと等しく、デリミタが続いている場合、
// マッチしたszstrの長さを返します。
// 例:strcmpid("abcd","abc")は0
// 例:strcmpid("abcd aaa","abcd")は4
// そうでなければ0を返します。
int len = strlen(szid);
if (!strncmp(szstr,szid,len)) {
mchar c = szstr[len];
if (isspace(c) || c == 0) return len;
}
return 0;
}
mchar * TXAPIBASE strcpylen(mchar *dst,mchar *src,int len)
{
// srcからdstにlenバイトの文字をコピーします。
// dst[len] = 0として、dstを返します。
memcpy(dst,src,len);
dst[len] = 0;
return dst;
}
mchar * TXAPI strcpylenmax(mchar *dst,mchar *src,int len,int lcxmax)
{
// strcpylenと同じですが、
// lenがlchmax以上なら最大lchmax-1文字コピーし、
// 末尾にヌルターミネータを追加します。
if (len >= lcxmax) {
len = lcxmax - 1;
memcpy(dst,src,len);
dst[len] = 0;
formstr(dst);//1.97
} else {
memcpy(dst,src,len);
dst[len] = 0;
}
return dst;
}
mchar * TXAPI strsetlen(mchar *dst,BYTE c,int len)
{
// dstにcをlen個セットします。
// dst[len] = 0として、dstを返します。
memset(dst,c,len);
dst[len] = 0;
return dst;
}
int TXAPI strsize(mchar *szstr)
{
// strlen(szstr) + 1を返します
return (strlen(szstr) + 1) * sizeof(mchar);
}
int TXAPI strlensize(mchar *szstr)
{
// strlen(szstr)を返します
return strlen(szstr) * sizeof(mchar);
}
mchar* TXAPI strskiptab(mchar* szstr,int n)
{
// szstrのn個目のタブの次の文字へのポインタを返します
// nに負の値を指定すると、szstrの最後のタブ文字の次の文字へのポインタを返します
// タブ文字が見つからなければ、szstrのNULL文字へのポインタを返します
//1.90で新設
mchar* p = szstr;
if (n < 0) {
mchar*p1;
while(p1 = strchr(p,'\t')) {
p = p1 + 1;
}
} else {
while(n--) {
mchar*p1 = strchr(p,'\t');
if (p1) {
p = p1 + 1;
} else {
break;
}
}
}
if (p != szstr) return p;
p += strlen(p);
return p;
}
#ifdef __TXC__
// txstr support
mchar* TXAPIBASE txstrcpylen(txstr dst,mchar *src,int len)
{
// strcpylenのtxstr版
// srcからdstにlenバイトの文字をコピーします。
// dst[len] = 0として、dstを返します。
//2.90で追加
strcpylenmax(dst,src,len,cchtxstr(dst));
return (mchar*)dst;
}
friend txstr _strmid(txstr dst,mchar *str,int sizeoffset,int size)
{
int len = strlen(str);
if (sizeoffset >= len) {
dst = "";
return dst;
}
if (sizeoffset + size > len) size = len - sizeoffset;
memcpy((mchar *)dst,&str[sizeoffset],size);
dst[size] = 0;
return dst;
}
friend txstr _strleft(txstr dst,mchar *str,int sizeleft)
{
int len = strlen(str);
if (sizeleft >= len) {
dst = str;
} else {
memcpy((mchar *)dst,(mchar *)str,len);
dst[sizeleft] = 0;
}
return dst;
}
friend txstr _inttostr(txstr dst,int num)
{
sprintf(dst,"%d",num);
return dst;
}
friend txstr _chartostr(txstr dst,int ch)
{
sprintf(dst,"%c",ch);
return dst;
}
mchar *strright(mchar *str,int sizeright)
{
mchar *p = ((mchar *)str);
int size = strlen(p);
if (sizeright < size) {
return p + size - sizeright;
} else {
return p;
}
}
mchar *strrear(mchar *str,int sizeleft)
{
return ((mchar *)str) + sizeleft;
}
#endif//__TXC__
//##hfile.c
#ifdef __TXC__
#export
#ifndef SEEK_SET
#define SEEK_SET 0
#define SEEK_CUR 1
#define SEEK_END 2
#endif
#endexport
#endif
//{###ファイル操作}
//ファイルを直接読み書きする機能を提供します。
//##hfile based
HFILE TXAPI hfileOpen(mchar *szfilename)
{
// szfilenameのファイルを読込みモードでオープンし、ファイルハンドルを返します。
// ファイル操作が終わったらhfileCloseしてください。
return _lopen(szfilename,OF_READ);
}
HFILE TXAPI hfileOpenWrite(mchar *szfilename)
{
// szfilenameのファイルを読み書きモードでオープンし、ファイルハンドルを返します。
// ファイル操作が終わったらhfileCloseしてください。
//2.96A 970213 新API
return _lopen(szfilename,OF_READWRITE);
}
HFILE TXAPI hfileCreate(mchar *szfilename)
{
// szfilenameのファイルを作成し、ファイルハンドルを返します。
// ファイル操作が終わったらhfileCloseしてください。
return _lcreat(szfilename,0);
}
BOOL TXAPI hfileClose(HFILE hfile)
{
// ファイルをクローズします
if (_lclose(hfile)) return FALSE;
return TRUE;
}
#ifdef __TXC__
long TXAPI hfileRead(HFILE hfile,LPVOID pmem,long size)
{
// ファイルからsizeバイト、pmemにロードします。
// ロードしたバイト数を返します。
//1.00Dで65535バイト以上ロードできるように改良 aaa
return _hread(hfile,pmem,size);
}
long TXAPI hfileWrite(HFILE hfile,LPVOID pmem,long size)
{
// ファイルにsizeバイト、pmemの内容を書き込みます。
// 書き込んだバイト数を返します。
//1.00Dで65535バイト以上書き込みできるように改良
return _hwrite(hfile,pmem,size);
}
LONG TXAPI hfileSeek(HFILE hfile,LONG lOffset,int nOrigin)
{
// 読み書きする位置を変更します。
// nOriginにSEEK_SETを指定すると、先頭からlOffsetバイト目に、
// nOriginにSEEK_CURを指定すると、現在位置+lOffsetに、
// nOriginにSEEK_ENDを指定すると、ファイル末尾+lOffsetバイトに、変更します。
return _llseek(hfile,lOffset,nOrigin);
}
#endif
BOOL TXAPI hfileCopy(HFILE hfDst,HFILE hfSrc,DWORD size)
{
// hfSrcからhfDstにsizeバイトコピーします。
// sizeバイトコピーできたかどうか返します。
LPBYTE buff = memAlloc(32768);
BOOL ret = TRUE;
if (buff) {
while(size) {
WORD sizeRead = 32768; // 32kずつ読む
if ((DWORD)sizeRead > size) sizeRead = (WORD)size;
if (_lread(hfSrc,buff,sizeRead) != sizeRead) ret = FALSE;
if (_lwrite(hfDst,buff,sizeRead) != sizeRead) ret = FALSE;
size -= sizeRead;
}
memFree(buff);
} else {
ret = FALSE;
}
return ret;
}
#ifdef __TXC__
extern "tx" {
#endif
DOSFILETIME _hfileDate(HFILE hfile,DOSFILETIME date);
#ifdef __TXC__
}
#endif
DOSFILETIME TXAPI hfileGetDate(HFILE hfile)
{
// ファイルの日付を返します。
// 返り値の下位WORD:時間(bit0-4:秒数/2,bit5-10:分,bit11-15:時)
// 返り値の上位WORD:日付(bit0-4:日,bit5-8:月,bit9-15:年-1980)
//2.00B WZ32でもサポート
return _hfileDate(hfile,0);
}
DOSFILETIME TXAPI hfileSetDate(HFILE hfile,DOSFILETIME date)
{
// ファイルの日付を設定します。
// dateにはhfileGetDateで返された日付を指定できます。
// または次の様に指定します。
// dateの下位WORD:時間(bit0-4:秒数/2,bit5-10:分,bit11-15:時)
// dateの上位WORD:日付(bit0-4:日,bit5-8:月,bit9-15:年-1980)
//2.00B WZ32でもサポート
return _hfileDate(hfile,date);
}
//##filename based
BOOL TXAPI fileRename(mchar *_szsrc,mchar *_szdst)
{
// szsrcのファイル名をszdstに変更します。
// ファイル名は""でくくってあっても構いません。
mchar szsrc[CCHPATHNAME];
mchar szdst[CCHPATHNAME];
//1.00H2
strcpy(szsrc,_szsrc);
pathFormLong(szsrc);
strcpy(szdst,_szdst);
pathFormLong(szdst);
if (rename(szsrc,szdst)) return FALSE;
return TRUE;
}
BOOL TXAPI fileDelete(mchar *_szfilename)
{
// ファイルを削除します。
// ファイル名は""でくくってあっても構いません。
mchar szfilename[CCHPATHNAME];
strcpy(szfilename,_szfilename);
pathFormLong(szfilename);//1.00H2
if (remove(szfilename)) return FALSE;
return TRUE;
}
BOOL TXAPI fileCopy(mchar *_szsrc,mchar *_szdst)
{
// szsrcのファイルをszdstにコピーします。コピーできたか返します。
// 同じファイルにコピーする場合は、コピーせずTRUEを返します。
// ファイル名は""でくくってあっても構いません。
// szdstにはパスではなくてファイル名を指定してください。
mchar szsrc[CCHPATHNAME];
mchar szdst[CCHPATHNAME];
strcpy(szsrc,_szsrc);
pathFormLong(szsrc);
strcpy(szdst,_szdst);
pathFormLong(szdst);
//information("[%s][%s]",szsrc,szdst);
if (!stricmp(szsrc,szdst)) return TRUE;//srcとdstが同じ
#ifdef __FLAT__
return CopyFile(szsrc,szdst,FALSE);
#else
#if 1//2.00E szsrcが存在しない場合、0バイトのサイズのszdstファイルを作ってしまっていた
{
BOOL ret = FALSE;
HFILE hfsrc = HFILE_ERROR;
HFILE hfdst = HFILE_ERROR;
hfsrc = _lopen(szsrc,OF_READ);
if (hfsrc != HFILE_ERROR) {
hfdst = _lcreat(szdst,0);
if (hfdst != HFILE_ERROR) {
DWORD time = hfileGetDate(hfsrc);
IFILE cbFile = _llseek(hfsrc,0,SEEK_END);
_llseek(hfsrc,0,SEEK_SET);
ret = hfileCopy(hfdst,hfsrc,cbFile);
hfileSetDate(hfdst,time);
}
}
if (hfdst != HFILE_ERROR) _lclose(hfdst);
if (hfsrc != HFILE_ERROR) _lclose(hfsrc);
return ret;
}
#else
hfdst = _lcreat(szdst,0);
hfsrc = _lopen(szsrc,OF_READ);
if (hfdst != HFILE_ERROR && hfsrc != HFILE_ERROR) {
DWORD time = hfileGetDate(hfsrc);
IFILE cbFile = _llseek(hfsrc,0,SEEK_END);
_llseek(hfsrc,0,SEEK_SET);
ret = hfileCopy(hfdst,hfsrc,cbFile);
hfileSetDate(hfdst,time);
}
if (hfdst != HFILE_ERROR) _lclose(hfdst);
if (hfsrc != HFILE_ERROR) _lclose(hfsrc);
return ret;
#endif
#endif
}
#include "_filer.h"
#ifdef __TXC__
#export
#ifdef __FLAT__
#ifdef __TXC__
extern "stdlib" {//2.00E "hfile"->"stdlib" WZ32でfileAtrが使えなかった
unsigned _cdecl fileAtr(UCHAR* path,WORD* atr,BOOL fset);
}
#endif
#endif
#endexport
#ifdef __FLAT__
unsigned _cdecl fileAtr(UCHAR* path,WORD* atr,BOOL fset)
{
if (fset) {
DWORD atr32 = 0;
if (*atr & FA_ARCH) atr32 |= FILE_ATTRIBUTE_ARCHIVE;
if (*atr & FA_DIREC) atr32 |= FILE_ATTRIBUTE_DIRECTORY;
if (*atr & FA_HIDDEN) atr32 |= FILE_ATTRIBUTE_HIDDEN;
if (*atr & FA_RDONLY) atr32 |= FILE_ATTRIBUTE_READONLY;
if (*atr & FA_SYSTEM) atr32 |= FILE_ATTRIBUTE_SYSTEM;
return !SetFileAttributes(path,atr32);
} else {
DWORD atr32 = GetFileAttributes(path);
*atr = 0;
if (atr32 == 0xFFFFFFFF) return 1;
if (atr32 & FILE_ATTRIBUTE_ARCHIVE) *atr |= FA_ARCH;
if (atr32 & FILE_ATTRIBUTE_DIRECTORY) *atr |= FA_DIREC;
if (atr32 & FILE_ATTRIBUTE_HIDDEN) *atr |= FA_HIDDEN;
if (atr32 & FILE_ATTRIBUTE_READONLY) *atr |= FA_RDONLY;
if (atr32 & FILE_ATTRIBUTE_SYSTEM) *atr |= FA_SYSTEM;
return 0;
}
}
#endif
#endif
#ifndef __NOTX__
//##imetx.c
//{###IME制御}
//IME(かな漢字変換プログラム)を制御します。
#ifdef __TXC__
#ifdef __FLAT__
extern "user32.dll" {
#include <ime.h>
BOOL WINAPI WINNLSEnableIME( HWND, BOOL );
}
#else
extern "winnls.dll" {
#include <ime.h>
BOOL WINAPI WINNLSEnableIME( HWND, BOOL );
}
#endif
#endif
WORD TXAPI imeSend(UINT fnc,WPARAM wParam,LPARAM lParam1,LPARAM lParam2,LPARAM lParam3)
{
// SendIMEMessageExします。SendIMEMessageExの返り値を返します。
//1.00F 以前まではSendIMEMessageして、その返り値を返していましたが仕様変更しました。
SHARE *sh = text1->share;
#ifdef __FLAT__
IMESTRUCT *lpIme = (IMESTRUCT*)text1->lpIme;
#else
IMESTRUCT *lpIme = (IMESTRUCT*)sh->lpIme;
#endif
if (!lpIme) return 0;//1.99A この場合あり。
memset(lpIme,0,sizeof(IMESTRUCT));
lpIme->fnc = fnc;
lpIme->wParam = wParam;
lpIme->lParam1 = lParam1;
lpIme->lParam2 = lParam2;
lpIme->lParam3 = lParam3;
#ifdef __FLAT__
return SendIMEMessageEx(textf->hwndtext,(LPARAM)GlobalPtrHandle(lpIme));
#else
if (textf->hwndtext2 && textf->fFocus2) {//3.00B1 970612 WZ16で多重化時に下の窓でIMEの変換中文字列が表示されなかった
return SendIMEMessageEx(textf->hwndtext2,GlobalPtrHandle(lpIme));
} else {
return SendIMEMessageEx(textf->hwndtext,GlobalPtrHandle(lpIme));
}
#endif
}
//1.91A imeSetPosは廃止されました
//1.00F imeSetFontは廃止されました
BOOL TXAPIBASE imeGetOpen(void)
{
// IMEがONになっているかどうか返します。
return imeSend(IME_GETOPEN,0,0,0,0);//1.00F
}
void TXAPIBASE imeSetOpen(BOOL fOpen)
{
// IMEをON/OFFします。
imeSend(IME_SETOPEN,fOpen,0,0,0);
// IMEが死んだようになるのの対策
if (fOpen && !imeGetOpen()) {
#ifdef __FLAT__
#else
WINNLSEnableIME(NULL,TRUE);
#endif
}
}
#ifdef __TXC__
#export
#ifdef __TXC__
#endexport
imeOn
{
//IMEをONにします。
//IMEをキー操作でONにしても、ONにならないときに
//このコマンドを実行してみてください
//1.00Cで追加
imeSetOpen(TRUE);
}
imeOff
{
//IMEをOFFにします。
//1.00Cで追加
imeSetOpen(FALSE);
}
//##単語登録
HWND GetFocusEx(void)
{
HWND hwnd = GetFocus();
return (hwnd != NULL) ? hwnd : GetDesktopWindow();
}
WORD imeWordRegister(mchar* pszWord, mchar* pszYomi)
{
HGLOBAL hIme = GlobalAlloc(GHND | GMEM_SHARE | GMEM_ZEROINIT, sizeof (IMESTRUCT));
IMESTRUCT* pIme = (IMESTRUCT*)GlobalLock(hIme);
pIme->fnc = IME_ENTERWORDREGISTERMODE;
HGLOBAL hWord = GlobalAlloc(GHND | GMEM_SHARE, strlen(pszWord) + 1);
mchar* pWord = (mchar*)GlobalLock(hWord);
strcpy(pWord, pszWord);
GlobalUnlock(hWord);
pIme->lParam1 = (LPARAM)hWord;
HGLOBAL hYomi = GlobalAlloc(GHND | GMEM_SHARE, strlen(pszYomi) + 1);
mchar* pYomi = (mchar*)GlobalLock(hYomi);
strcpy(pYomi, pszYomi);
GlobalUnlock(hWord);
pIme->lParam2 = (LPARAM)hYomi;
GlobalUnlock(hIme);
HWND hwnd = GetFocusEx();
WORD r = (WORD)SendIMEMessageEx(hwnd, (LPARAM)hIme);
GlobalFree(hIme);
GlobalFree(hWord);
GlobalFree(hYomi);
return r;
}
BOOL TXCMDBASE imeRegWord(TX* text)
{
// 日本語入力辞書への単語登録
// 日本語入力システム(IME)の辞書ユーティリティを起動し、選択範囲の
// 文字列(漢字)を複写します。
// Thanks dieさん
//1.00H2 でimereg.cから移動
txstr szword(128);
txGetWord(text,szword);
imeWordRegister(szword,"");
return TRUE;
}
//{###ウィンドウ}
HWND TXAPIBASE isopen(mchar* szfilename)
{
// szfilenameがオープンされていれば、そのhwndbaseを返します
//2.92
return (HWND)txOp(text,TXOP_ISOPEN,(LPARAM)szfilename,NULL);
}
void TXAPI exit(void)
{
// 現在のウィンドウを閉じます
// ウィンドウが全部閉じられると、WZの実行を終了します。
//2.94 970123 新規API
txQuit(textf);
}
//{###検索・置換}
BOOL TXAPI txJumpURL(TX* text)
{
// カーソル位置にURL、E-Mailアドレス、"ファイル名"があればジャンプ
// カーソル位置になければ、行頭からこれらがあるか調べ、あればジャンプ
// ジャンプしたかどうかを返す
return (BOOL)txOp(text,TXOP_TXJUMPURL,NULL,NULL);
}
#export
#endif
#endexport
#endif
//##ヘルプ
//{###ヘルプ}
//1.99G
BOOL TXAPI WinHelpWz(mchar* szfilename,UINT fuCommand,LPARAM dwData)
{
mchar _szfilename[CCHPATHNAME];
if (
szfilename == NULL ||
szfilename[0] == 0 ||
pathEquFileName(szfilename,"wz") //2.00B WZ16でツールバーの[?]ボタンでヘルプが表示されなかった
) {
szfilename = _szfilename;
szfilename[0] = 0;
#if 1//1.99G NT3.5はwz16.hlpを使用
#if 1//2.99B 970322 NT4.0はwz16.hlpを使用
if ((_fwin40 && _platform == WINDOWS95) || _fwinnt351) {
pathSetFileName(szfilename,"wz:\\wz.hlp");
} else {
pathSetFileName(szfilename,"wz:\\wz16.hlp");
}
#else
if (_fwin40 || _fwinnt351) {
pathSetFileName(szfilename,"wz:\\wz.hlp");
} else {
pathSetFileName(szfilename,"wz:\\wz16.hlp");
}
#endif
#else
#ifdef __FLAT__
pathSetFileName(szfilename,"wz:\\wz.hlp");
#else
pathSetFileName(szfilename,"wz:\\wz16.hlp");
#endif
#endif
}
if (fuCommand == HELP_CONTENTS && _fwin40) {
//1.99G Windows95では目次を開く為にWinHelpを起動する。
mchar szbuff[20 + CCHPATHNAME];
strcpy(szbuff,"winhelp ");
strcat(szbuff,szfilename);
return (WinExec(szbuff,SW_SHOW) >= 32);
} else {
//information(szfilename);
return WinHelp(textf->hwndbase,szfilename,fuCommand,dwData);//2.95 970128 text1->textf
}
}
#ifdef __TXC__
//{###文字列ブロック}
//##history
// 1996.12.2 start
static mchar _szfilename[] = "wzhist.dat";
static mchar _szhead[] = "..\x08\x08[";
HSTRBLK TXAPI historyOpen(mchar* szName,int cbHistbuff)
{
// szNameのヒストリを開く。
// szNameに、'[',']',改行は使えない。
HSTRBLK sb = sbNewAlloc(cbHistbuff);
if (sb) {
mchar szfilename[CCHPATHNAME];
pathFullConfig(szfilename,_szfilename);
TX _text;
TX* text = &_text;
if (txInit(text,szfilename)) {
if (txSearchEx(text,_szhead+szName+"]",SEARCH_CUR)) {
// テキストのトップがヒストリのトップになるように逆順に
//出力。
txstr szline;
txNextPara(text);
NPARA nparaEnd = text->npara;
NPARA nparaTop = 1;
while(1) {
txGetPara(text,szline);
if (!strncmp(szline,_szhead,strlen(_szhead))) {
nparaTop = text->npara - 1;
break;
}
if (!txNextPara(text)) {
nparaTop = text->npara;
break;
}
}
for (NPARA npara = nparaTop;npara >= nparaEnd;npara--) {
txJumpNpara(text,npara);
txGetPara(text,szline);
if (szline[0]) sbAdd(sb,szline);
}
}
txClose(text);
}
}
return sb;
}
void TXAPI historyClose(mchar* szName,HSTRBLK sb)
{
// szNameのヒストリを開じる。sbも破棄する。
// szNameに、'[',']',改行は使えない。
if (sb) {
mchar szfilename[CCHPATHNAME];
pathFullConfig(szfilename,_szfilename);
TX _text;
TX* text = &_text;
if (txInit(text,szfilename)) {
if (txSearchEx(text,_szhead+szName+"]",SEARCH_CUR)) {
txSelectEx(text,CLIP_CHAR);
txstr szline;
txNextPara(text);
while(1) {
int lch = txGetPara(text,szline);
if (!strncmp(szline,_szhead,strlen(_szhead))) break;
if (!txNextPara(text)) break;
}
txSelectDelete(text);
}
// ヒストリのトップが、テキストのトップになるように逆順に出
//力。
{
txInsertLine(text,"%s%s]",_szhead,szName);
int n = sbGetCount(sb);
for (int i = n;--i >= 0;) {
mchar* sz = sbRead(sb,i);
if (sz[0]) txInsertLine(text,sz);
}
}
txSave(text);
txClose(text);
}
sbDelete(sb);
}
}
#endif// __TXC__
#endif// __NOTX__