home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
DOS/V Power Report 1998 September
/
VPR9809B.ISO
/
APUPDATE
/
VC
/
Tx300d
/
TX300D.LZH
/
STD.C
< prev
next >
Wrap
C/C++ Source or Header
|
1997-06-13
|
65KB
|
2,708 lines
// WZ EDITOR 標準機能 TX-C標準ライブラリ関数群
// Copyright 1995-96 TY
#ifdef __TXC__
#pragma HEADER+
#include <windows.h>
#include <windowsx.h>
#else
#define __CC_STD // 自分自身のコンパイルフラグをセット
#include "..\tx.h"
#include <string.h>
#include <stdio.h>
#include <stdlib.h>
#include <ctype.h>
#endif
//{###情報取得}
#ifdef __TXC__
#export
#define WIN16 1
#define WIN32S 2
#define WINDOWS95 3
#define WINDOWSNT 4
#ifdef __TXC__
extern "std" {
#endif
// TX-C:外部にexportする静的変数は、初期化済みデータ(static)でないといけない
// bssではだめ。
extern BYTE _platform; // GetWindowsPlatform()の値と同じ
extern BYTE _fwin40; // is Windows4.0(Windows95) ?
extern BYTE _fwinnt351; // is WindowsNT3.51 ?
extern BYTE _fpsh; // プロパティーシートを使う?
#ifdef __TXC__
}
#endif
#define IsPropSheet() (_fwin40 || _fwinnt351)
#endexport
#endif
BYTE _platform = 0;
BYTE _fwin40 = FALSE;
BYTE _fwinnt351 = FALSE; //1.99A
BYTE _fpsh = FALSE; //2.00B
int TXAPI GetWindowsPlatform(void)
{
// 現在動作中のWindowsのプラットフォームを返します。
// WIN16,WIN32S,WINDOWS95,WINDOWSNTのどれかを返します。
//1.00Fで追加
#ifdef __FLAT__
if (!_platform) {
DWORD dwVersion = GetVersion();
if (dwVersion < 0x80000000) {
_platform = WINDOWSNT;
if (LOBYTE(LOWORD(dwVersion)) >= 4) {//2.00E WinNT4.0対応
_fwin40 = TRUE;
_fpsh = TRUE;
} else {
_fwinnt351 = (HIBYTE(LOWORD(dwVersion)) == 0x33);
if (_fwinnt351) {
_fpsh = TRUE;
}
}
} else if (LOBYTE(LOWORD(dwVersion)) < 4) {
_platform = WIN32S;
} else {
_platform = WINDOWS95;
_fwin40 = TRUE;
_fpsh = TRUE;
}
}
return _platform;
#else
_platform = WIN16;
return _platform;
#endif
}
#ifndef __NOTX__
int TXAPI getversion(void)
{
// WZのバージョン番号を返します。
// 1.00Cなら0x1003を返します。
// 1.00Cで追加しました。
// 1.00/1.00A/1.00BでこのAPIを呼び出すとダイナミックリンクエラーになります。
// 1.00/1.00A/1.00Bかどうかを判定するには次のようにしてください。
// if (iswz100AB()) {//1.00/1.00A/1.00B}
return SendMessage(text1->hwndbase,WM_COMMAND,IDM_TXGETVERSION,0);
}
int TXAPI textSearch(HWND hwnd)
{
//1.00H4 リストから探す。見つからなければ-1を返す
#ifdef __TXC__
SHARE *sh = text->share;
#endif
int ret = -1;
int i;
wzlock(LOCK_WZPROCESS);
for (i = 0;i < sh->nOpen;i++) {
if (sh->tWzprocess[i].hwnd == hwnd) {
ret = i;
break;
}
}
wzunlock(LOCK_WZPROCESS);
//2.00B search.otherUpなどが実行されなかった
// "return i;"になってた
return ret;
}
BOOL TXAPI textSetProcessMode(HWND hwnd,DWORD modeProcess)
{
//1.00H5 hwndの窓のmodeProcessを設定
BOOL ret = FALSE;
int i;
#if 1//1.99C 先にロックしないとまずいんでは?
wzlock(LOCK_WZPROCESS);
i = textSearch(hwnd);
#else
i = textSearch(hwnd);
wzlock(LOCK_WZPROCESS);
#endif
if (i != -1) {
#ifdef __TXC__
SHARE *sh = text->share;
#endif
sh->tWzprocess[i].modeProcess = modeProcess;
ret = TRUE;
}
wzunlock(LOCK_WZPROCESS);
return ret;
}
DWORD TXAPI textGetProcessMode(HWND hwnd)
{
//1.00H5 hwndの窓のmodeProcessを返す
// hwndが見つからなければ0を返す
DWORD ret = 0;
int i;
wzlock(LOCK_WZPROCESS);
i = textSearch(hwnd);
if (i != -1) {
#ifdef __TXC__
SHARE *sh = text->share;
#endif
ret = sh->tWzprocess[i].modeProcess;
}
wzunlock(LOCK_WZPROCESS);
return ret;
}
//{###ファイル名・パス名}
void TXAPI pathGetWzexeFilename(mchar szfilename[CCHPATHNAME])
{
// szfilenameにWZ.EXEのフルパスをセットする。
// 2.90で追加。
if (text1->fWzc) {
#ifdef __FLAT__
GetModuleFileName(text1->hInstance,szfilename,CCHPATHNAME);
pathSetFileName(szfilename,"wzeditor.exe");
#endif
} else {
if (text1->hInstanceParent) {
GetModuleFileName(text1->hInstanceParent,szfilename,CCHPATHNAME);
} else {
GetModuleFileName(text1->hInstance,szfilename,CCHPATHNAME);
}
}
}
//{###コマンドライン}
//1.00H3
// ここでPROCESS_INFORMATIONを使って、TXAPIとするのはだめ。
// <windows.h>が#includeされてないとstd.txhでエラーになっちゃう。
// マクロで、__DEV__を参照しても駄目。
// __DEV__を変更しても、コンパイルされないで出荷されちゃうゾ
BOOL TXAPIBASE wzExec(LPBYTE _szarg)
{
#if 1//3.00B1 970613 wzExec:長い引数に対応
#ifdef __FLAT__
BOOL ret = FALSE;
mchar szmodulename[CCHPATHNAME];
mchar* szarg = NULL;
pathGetWzexeFilename(szmodulename);
//
szarg = malloc(strlen(_szarg) + 10);
if (szarg) {
PROCESS_INFORMATION processinfo;
STARTUPINFO startinfo;
//
szarg[0] = ' '; // 先頭は必ず空白を渡さないといけない
strcpy(szarg + 1,_szarg);
//
memset(&startinfo,0,sizeof(startinfo));
startinfo.cb = sizeof(startinfo);
//
ret = CreateProcess(
szmodulename,
szarg,
NULL,
NULL,
FALSE,
0,
NULL,
NULL,
&startinfo,
&processinfo
);
free(szarg);
}
return ret;
#else
BOOL ret = FALSE;
mchar* szarg = malloc(CCHPATHNAME + strlen(_szarg) + 10);
if (szarg) {
mchar *p = szarg;
GetModuleFileName(text1->hInstance,p,CCHPATHNAME);
p += strlen(p);
*p++ = ' ';
strcpy(p,_szarg);
if (WinExec(szarg,SW_SHOWNORMAL) < 32) {//2.00E SW_SHOW->SW_SHOWNORMAL
#ifdef __TXC__
attention("コマンド(%s)が起動できません。\nメモリ不足の可能性があります",szcmd);
#else
attention(rcString(12),szarg);
#endif
} else {
ret = TRUE;
}
free(szarg);
}
return ret;
#endif
#else
#ifdef __FLAT__
mchar szmodulename[CCHPATHNAME];
mchar szarg[CCHPATHNAME];
PROCESS_INFORMATION processinfo;
STARTUPINFO startinfo;
//
szarg[0] = ' '; // 先頭は必ず空白を渡さないといけない
strcpymax(szarg+1,_szarg,CCHPATHNAME-1);
//
memset(&startinfo,0,sizeof(startinfo));
startinfo.cb = sizeof(startinfo);
//
pathGetWzexeFilename(szmodulename);
return CreateProcess(
szmodulename,
szarg,
NULL,
NULL,
FALSE,
0,
NULL,
NULL,
&startinfo,
&processinfo
);
#else
mchar szcmd[CCHPATHNAME*2];
mchar *p = szcmd;
GetModuleFileName(text1->hInstance,p,CCHPATHNAME);
p += strlen(p);
*p++ = ' ';
strcpy(p,_szarg);
if (WinExec(szcmd,SW_SHOWNORMAL) < 32) {//2.00E SW_SHOW->SW_SHOWNORMAL
#ifdef __TXC__
attention("コマンド(%s)が起動できません。\nメモリ不足の可能性があります",szcmd);
#else
attention(rcString(12),szcmd);
#endif
return FALSE;
}
return TRUE;
#endif
#endif
}
#endif // __NOTX__
#ifndef __NOTX__
//{###文字列ブロック}
//複数の文字列をまとめて管理する機能を提供します。
//文字列の追加、削除、検索などができます。
//WZのヒストリー機能実現、キーワード管理に使われています。
//[1]文字列ブロック変数を用意
//HSTRBLK hsb;
//[2]sbNewで初期化
//[3]sbAdd,sbSearchなどで利用
//[4]sbDeleteで終了処理
#ifdef __TXC__
#export
#ifndef __HSTRBLK
#define __HSTRBLK
#if 1//1.99C _text.h16だとエラーが出た
typedef struct tagSTRBLK * HSTRBLK;
#else
#ifdef __CC_STD // 自分自身のコンパイル
typedef struct tagSTRBLK * HSTRBLK;
#else
DECLARE_HANDLE_TX(HSTRBLK);
#endif
#endif
// share構造体に置くためだけに、データ構造を公開する。
// ユーザーは、メンバを参照してはいけない。
typedef struct tagSTRBLK {
LPBYTE buff;
LPBYTE ptail;
WORD sizebuff; // buffのサイズ
WORD nstr; // 文字列数
// WORD bit field
WORD fSenseCase:1;
WORD fCustData:1;
WORD fShared:1;
WORD fstatic:1; // for internal
WORD fAlloc:1; //2.90 buff is allced by strblk
WORD reserved:11;
// WORD bit field end
LPBYTE pfound;
} STRBLK;
#endif
#endexport
#endif
#ifdef __FLAT__//SHAREのアドレスが変化しても対応できるように
#define SB_OFFSET (sb->fShared*(DWORD)(text1->share))
#define SB_LOCK wzlock(LOCK_HIST);
#define SB_UNLOCK wzunlock(LOCK_HIST);
#else
#define SB_OFFSET (0)
#define SB_LOCK
#define SB_UNLOCK
#endif
typedef STRBLK CONTEXTTX;//1.00F
#ifdef __TXC__
#if 1//1.93
#define MAXCONTEXTTX 120
#else
#define MAXCONTEXTTX 30
#endif
#else
#define MAXCONTEXTTX 10
#endif
#include "context.ci"
HSTRBLK TXAPI sbNewStatic(HSTRBLK sb,LPBYTE buff,WORD sizebuff)
{
// sbNewと同じだが、ハンドルを利用側で作成
// 次のように使用
// STRBLK _sb;
// HSTRBLK sb = sbNewStatic(&_sb,buff,sizebuff);
// sbAdd(sb,"abc");...
// sbAdd(&_sb,"abc");...//これでもOK
if (sb) {
SB_LOCK;
memset(sb,0,sizeof(CONTEXTTX));
sb->fstatic = TRUE;
sb->buff = sb->ptail = buff;
sb->sizebuff = sizebuff;
sb->fSenseCase = TRUE;
SB_UNLOCK;
}
return sb;
}
HSTRBLK TXAPI sbNewStaticShare(HSTRBLK sb,LPBYTE buff,WORD sizebuff)
{
SB_LOCK;
if (sbNewStatic(sb,buff,sizebuff)) {
#ifdef __FLAT__
sb->fShared = TRUE;
#endif
}
SB_UNLOCK;
return sb;
}
HSTRBLK TXAPI sbNew(LPBYTE buff,WORD sizebuff)
{
// 文字列バッファをbuffに、buffのサイズをsizebuffに指定してオープン
// ハンドルを返す
HSTRBLK sb = contextNew();
// dialog使っている時、ここでinformation等使うと、駄目みたい?
if (sb) {
sb->buff = sb->ptail = buff;
sb->sizebuff = sizebuff;
sb->fSenseCase = TRUE;
} else {
// attention("strblk:ハンドル不足");
}
return sb;
}
HSTRBLK TXAPI sbNewAlloc(WORD sizebuff)
{
// sizebuffサイズの文字列バッファサイズをアロケートし、ハンドルを返す。
//2.90 で追加
LPBYTE buff = malloc(sizebuff);
if (buff) {
HSTRBLK sb = contextNew();
if (sb) {
sb->buff = sb->ptail = buff;
sb->sizebuff = sizebuff;
sb->fSenseCase = TRUE;
sb->fAlloc = TRUE;
} else {
free(buff);
// attention("strblk:ハンドル不足");
}
return sb;
} else {
return NULL;
}
}
void TXAPI sbSetBuff(HSTRBLK sb,LPBYTE buff,WORD sizebuff)
{
// sbDelAll後、文字列バッファをbuffにセットし直す。
// 以前の文字列バッファの解放は行わない
//2.00Eで追加
if (sb) {
SB_LOCK;
sbDelAll(sb);
sb->buff = sb->ptail = buff;
sb->sizebuff = sizebuff;
SB_UNLOCK;
}
}
LPVOID TXAPI sbGetBuff(HSTRBLK sb)
{
// 文字列バッファを返す
//1.00Fで追加
return sb->buff;
}
BOOL TXAPI sbReverse(HSTRBLK sb)
{
// sbの内容を逆順にします。
//2.99C 970325 new
BOOL ret = FALSE;
HSTRBLK sbTmp = sbNewAlloc(sb->sizebuff);
if (sbTmp) {
int n = sbGetCount(sb);
int n0 = n;
int i;
for (i = 0;i < n;i++) {
sbAdd(sbTmp,sbRead(sb,i));
}
n = sbGetCount(sbTmp);
ret = (n == n0);
sbDelAll(sb);
for (i = n;i--;) {
sbAdd(sb,sbRead(sbTmp,i));
}
sbDelete(sbTmp);
}
return ret;
}
void TXAPI sbSetSenseCase(HSTRBLK sb,BOOL fSet)
{
// 大文字・小文字を区別するかどうか設定
// デフォルト:区別
// いつでも変更できます
SB_LOCK;
sb->fSenseCase = fSet;
SB_UNLOCK;
}
BOOL TXAPI sbGetSenseCase(HSTRBLK sb)
{
// 大文字・小文字を区別するかどうかの設定内容を返します
//1.96で追加
BOOL ret;
SB_LOCK;
ret = sb->fSenseCase;
SB_UNLOCK;
return ret;
}
void TXAPI sbSetCustData(HSTRBLK sb,BOOL fSet)
{
// CustDataを使うかどうかの設定
// デフォルト:使わない
// sbNew等の直後に呼び出してください。
//1.01A で追加
SB_LOCK;
sb->fCustData = fSet;
SB_UNLOCK;
}
BOOL TXAPI sbGetCustData(HSTRBLK sb)
{
// CustDataを持っているかどうか返す
//1.91A
BOOL ret;
SB_LOCK;
ret = sb->fCustData;
SB_UNLOCK;
return ret;
}
typedef struct {
// ヘッダID
WORD sizestruct;
UCHAR id[7];
// ヘッダ本体
WORD cbdata;
WORD nstr;
// WORD bit field
WORD fCustData:1;
WORD reserved:15;
// WORD bit field end
} SBHDR;
void TXAPI sbDelAll(HSTRBLK sb)
{
// すべて削除
SB_LOCK;
sb->ptail = sb->buff;
sb->nstr = 0;
SB_UNLOCK;
}
static BOOL _sbLoad(HSTRBLK sb,HFILE hf)
{
SBHDR head;
if (hf == HFILE_ERROR) return FALSE;
if (_lread(hf,&head,sizeof(head)) != sizeof(head)) return FALSE;
if (head.sizestruct != sizeof(head)) return FALSE;
if (strcmp(head.id,"strblk")) return FALSE;
if (head.cbdata > sb->sizebuff) return FALSE;
if (head.fCustData != sb->fCustData) return FALSE;//1.01A
if (_lread(hf,sb->buff + SB_OFFSET,head.cbdata) != head.cbdata) {
sbDelAll(sb);
return FALSE;
}
sb->nstr = head.nstr;
sb->ptail = sb->buff + head.cbdata;
return TRUE;
}
BOOL TXAPI sbLoad(HSTRBLK sb,HFILE hf)
{
// ファイルからロード
BOOL ret;
SB_LOCK;
ret = _sbLoad(sb,hf);
SB_UNLOCK;
return ret;
}
static BOOL _sbSave(HSTRBLK sb,HFILE hf)
{
SBHDR head;
if (hf == HFILE_ERROR) return FALSE;
head.sizestruct = sizeof(head);
strcpy(head.id,"strblk");
head.cbdata = sb->ptail - sb->buff;
head.nstr = sb->nstr;
head.fCustData = sb->fCustData;
if (_lwrite(hf,(void*)&head,sizeof(head)) != sizeof(head)) return FALSE;
if (_lwrite(hf,(void*)(sb->buff + SB_OFFSET),head.cbdata) != head.cbdata) return FALSE;
return TRUE;
}
BOOL TXAPI sbSave(HSTRBLK sb,HFILE hf)
{
// ファイルへセーブ
BOOL ret;
SB_LOCK;
ret = _sbSave(sb,hf);
SB_UNLOCK;
return ret;
}
mchar* TXAPI sbAdd(HSTRBLK sb,mchar *szstr)
{
// szstrを末尾に追加。追加結果の文字列ポインタを返す
mchar *ret = NULL;
SB_LOCK;
{
int sizestr = strsize(szstr);
if (sb->ptail - sb->buff + sizeof(WORD) + sizestr + sizeof(DWORD) > sb->sizebuff) {
// NG
} else {
*(WORD *)(sb->ptail + SB_OFFSET) = sizestr;sb->ptail += sizeof(WORD);
ret = sb->ptail + SB_OFFSET;
memcpy(ret,szstr,sizestr);
sb->ptail += sizestr;
if (sb->fCustData) {//1.01A
*(DWORD*)(sb->ptail + SB_OFFSET) = 0;
sb->ptail += sizeof(DWORD);
}
sb->nstr++;
}
}
SB_UNLOCK;
return ret;
}
int TXAPI sbiPreSearch(HSTRBLK sb,mchar *szstr)
{
// szstrを検索。見つけた位置(0から(sbGetCount-1))を返す
// 文字列の頭だけが一致すればOKとする。
int ret = -1;
SB_LOCK;
{
LPBYTE p = sb->buff + SB_OFFSET;
int sizestr = strlensize(szstr);
int i;
if (sb->fSenseCase) {
for (i = 0;i < sb->nstr;i++) {
int size = *(WORD *)p;p += sizeof(WORD);
size -= sizeof(mchar);
if (sizestr >= size && !memcmp(p,szstr,size)) {
sb->pfound = p - sizeof(WORD) - SB_OFFSET;
ret = i;
break;
}
p += size + sizeof(mchar);
if (sb->fCustData) p += sizeof(DWORD);//1.01A
}
} else {//2.00E4 !fSenseCaseに対応
for (i = 0;i < sb->nstr;i++) {
int size = *(WORD *)p;p += sizeof(WORD);
size -= sizeof(mchar);
if (sizestr >= size && !strnicmp(p,szstr,size)) {
sb->pfound = p - sizeof(WORD) - SB_OFFSET;
ret = i;
break;
}
p += size + sizeof(mchar);
if (sb->fCustData) p += sizeof(DWORD);//1.01A
}
}
}
SB_UNLOCK;
return ret;
}
int TXAPI sbiSearch(HSTRBLK sb,mchar *szstr)
{
// szstrを検索。見つけた位置(0から(sbGetCount-1))を返す
// 見つからなければ-1を返す
int ret = -1;
SB_LOCK;
{
LPBYTE p = sb->buff + SB_OFFSET;
int sizestr = strsize(szstr);
int i;
if (sb->fSenseCase) {
for (i = 0;i < sb->nstr;i++) {
int size = *(WORD *)p;p += sizeof(WORD);
if (sizestr == size && !memcmp(p,szstr,sizestr)) {
sb->pfound = p - sizeof(WORD) - SB_OFFSET;
ret = i;
break;
}
p += size;
if (sb->fCustData) p += sizeof(DWORD);//1.01A
}
} else {
for (i = 0;i < sb->nstr;i++) {
int size = *(WORD *)p;p += sizeof(WORD);
if (sizestr == size && !strnicmp(p,szstr,sizestr)) {
sb->pfound = p - sizeof(WORD) - SB_OFFSET;
ret = i;
break;
}
p += size;
if (sb->fCustData) p += sizeof(DWORD);//1.01A
}
}
}
SB_UNLOCK;
return ret;
}
BOOL TXAPI sbSearch(HSTRBLK sb,mchar *szstr)
{
// szstrを検索。見つかったかどうか返す
if (sbiSearch(sb,szstr) == -1) return FALSE;
return TRUE;
}
static void pfoundDelete(HSTRBLK sb)
{
SB_LOCK;
{
LPBYTE p = sb->pfound + SB_OFFSET;
int cbdel = sizeof(WORD) + *(WORD *)p;
if (sb->fCustData) cbdel += sizeof(DWORD);//1.01A
{
int cbmove = sb->ptail + SB_OFFSET - p;
if (cbmove) memcpy(p,p + cbdel,cbmove);
sb->ptail -= cbdel;
sb->nstr--;
}
}
SB_UNLOCK;
}
BOOL TXAPI sbDel(HSTRBLK sb,mchar *szstr)
{
// szstrを削除
BOOL ret = TRUE;
SB_LOCK;
{
int i = sbiSearch(sb,szstr);
if (i == -1) {
ret = FALSE;
} else {
pfoundDelete(sb);
}
}
SB_UNLOCK;
return ret;
}
// 自分自身の文字列が渡されることがあるので注意
mchar* TXAPI sbAddHist(HSTRBLK sb,mchar *szstr)
{
// szstrがすでにあれば、末尾に移動する
// なければ末尾に追加する
mchar *ret;
SB_LOCK;
{
// 追加する
ret = sbAdd(sb,szstr);
if (!ret) {
// 追加できなかった
// reduceする
LPBYTE p = sb->buff;
BOOL freduce = FALSE;
int sizereduce = sb->sizebuff / 3;
int i;
for (i = 0;i < sb->nstr;i++) {
int size = p - sb->buff;
if (size > sizereduce) {
int size = sb->ptail - p;
if (size > 0) {
freduce = TRUE;
memcpy(sb->buff + SB_OFFSET,p + SB_OFFSET,size);
sb->ptail = sb->buff + size;
sb->nstr -= i;
}
break;
}
p += sizeof(WORD) + *(WORD *)(p + SB_OFFSET);
if (sb->fCustData) p += sizeof(DWORD);//1.01A
}
if (!freduce) sbDelAll(sb);
//
ret = sbAdd(sb,szstr);
if (!ret) {
// 追加できなかった
sbDelAll(sb);
ret = sbAdd(sb,szstr);// これでも追加できないこともある
}
}
if (sbiSearch(sb,szstr) == -1) ret = NULL;
if (ret) {
if (ret == sb->pfound + sizeof(WORD) + SB_OFFSET) {
// OK
} else {
// 重複した
ret -= sizeof(WORD) + *(WORD *)(sb->pfound + SB_OFFSET);
if (sb->fCustData) ret -= sizeof(DWORD);//1.01A
pfoundDelete(sb);
}
}
}
SB_UNLOCK;
return ret;
}
int TXAPI sbGetCount(HSTRBLK sb)
{
// 文字列数を返す
int ret;
SB_LOCK;
ret = sb->nstr;
SB_UNLOCK;
return ret;
}
mchar* TXAPI sbRead(HSTRBLK sb,int istr)
{
// i番目(0から(sbGetCount-1))の文字列を返す
mchar *ret = NULL;
SB_LOCK;
if (0 <= istr && istr < sb->nstr) {
LPBYTE p = sb->buff + SB_OFFSET;
int i;
for (i = 0;i < istr;i++) {
p += sizeof(WORD) + *(WORD *)p;
if (sb->fCustData) p += sizeof(DWORD);//1.01A
}
ret = p + sizeof(WORD);
}
SB_UNLOCK;
return ret;
}
DWORD TXAPI sbReadCustdata(HSTRBLK sb,int istr)
{
// i番目(0から(sbGetCount-1))のCustDataを返す
// 読みだせなければ0を返す
//1.01A で追加
//2.95 970131 sbReadCustData -> sbReadCustdata
DWORD ret = 0;
if (sb->fCustData) {
mchar *p;
SB_LOCK;
p = sbRead(sb,istr);
if (p) ret = *(DWORD *)(p + *(WORD*)((LPBYTE)p - sizeof(WORD)));
SB_UNLOCK;
}
return ret;
}
BOOL TXAPI sbWriteCustdata(HSTRBLK sb,int istr,DWORD CustData)
{
// i番目(0から(sbGetCount-1))のCustDataをセットする
// セットできたかどうかを返す
//1.01A で追加
BOOL ret = FALSE;
if (sb->fCustData) {
mchar *p;
SB_LOCK;
p = sbRead(sb,istr);
if (p) {
*(DWORD *)(p + *(WORD*)((LPBYTE)p - sizeof(WORD))) = CustData;
ret = TRUE;
}
SB_UNLOCK;
}
return ret;
}
BOOL TXAPI sbDelI(HSTRBLK sb,int i)
{
// i番目(0から(sbGetCount-1))の文字列を削除
BOOL ret = FALSE;
SB_LOCK;
{
mchar *p = sbRead(sb,i);
if (p) {
sb->pfound = p - sizeof(WORD) - SB_OFFSET;
pfoundDelete(sb);
ret = TRUE;
}
}
SB_UNLOCK;
return ret;
}
mchar* TXAPI sbRead2(HSTRBLK sb,int istr,WORD *lchstr)
{
// i番目(0から(sbGetCount-1))の文字列を返す
// sizestrに文字列のサイズ(最後のNULLも含む)を返す
mchar *p;
SB_LOCK;
p = sbRead(sb,istr);
if (p) *lchstr = *(WORD *)((LPBYTE)p - sizeof(WORD)) - sizeof(mchar);
SB_UNLOCK;
return p;
}
int TXAPI sbiSearchPrev(HSTRBLK sb,mchar *szstr,int istr)
{
// istr-1から0までszstrを検索する
// 見つからなければ-1を返す
// szstrより長い文字列でも、先頭部分が一致すればOKとする
// 大文字・小文字は区別しない
int sizestr = strlensize(szstr);
SB_LOCK;
for (istr--;istr >= 0;istr--) {
if (!strnicmp(sbRead(sb,istr),szstr,sizestr)) {
SB_UNLOCK;
return istr;
}
}
SB_UNLOCK;
return -1;
}
int TXAPI sbiSearchNext(HSTRBLK sb,mchar *szstr,int istr)
{
// istr+1からnstr-1までszstrを検索する
// 見つからなければ-1を返す
// szstrより長い文字列でも、先頭部分が一致すればOKとする
// 大文字・小文字は区別しない
int sizestr = strlensize(szstr);
SB_LOCK;
for (istr++;istr < sb->nstr;istr++) {
if (!strnicmp(sbRead(sb,istr),szstr,sizestr)) {
SB_UNLOCK;
return istr;
}
}
SB_UNLOCK;
return -1;
}
BOOL TXAPI sbDelete(HSTRBLK sb)
{
// 破棄。不要になったら必ず呼んでください
if (!sb) return FALSE;
if (sb->fAlloc) free(sb->buff);//2.90
if (!sb->fstatic) return contextDelete(sb);
return TRUE;
}
HSTRBLK TXAPI sbFromHist(HANDLETX hist)
{
// histから、sbに変換。histがsbの場合はそのままhistを返す。
// 2.90 で追加。
if (hist && (DWORD)hist < MAXHIST) {
return &text1->share->hist[(int)hist];
}
return hist;
}
HANDLETX TXAPI sbToHist(HSTRBLK sb)
{
// sbからhistへ変換。sbがhistでなければ0を返す。
// 2.90 で追加。
int i;
if (sb) {
for (i = 1;i < MAXHIST;i++) {
if ((HANDLETX)&text1->share->hist[i] == sb) return (HANDLETX)i;
}
}
return 0;
}
//##整数テーブル
//2.90
#ifdef __TXC__
#export
#ifndef __INTTABLE
#define __INTTABLE
typedef struct {
int sizeTable;
int n;
DWORD* table;
} INTTABLE;
#endif
#endexport
#endif
BOOL TXAPI itInit(INTTABLE* it,DWORD* table,int cbTable)
{
// 次の様に使用
// INTTABLE it;
// DWORD table[5];
// itInit(&it,table,sizeof(table);
it->sizeTable = cbTable / sizeof(DWORD);
it->n = 0;
it->table = table;
return TRUE;
}
int TXAPI itiSearch(INTTABLE* it,DWORD val)
{
int i;
for (i = 0;i < it->n;i++) {
if (it->table[i] == val) return i;
}
return -1;
}
BOOL TXAPI itSearch(INTTABLE* it,DWORD val)
{
return (itiSearch(it,val) != -1);
}
BOOL TXAPI itAdd(INTTABLE* it,DWORD val)
{
if (it->sizeTable == it->n) return FALSE;
it->table[it->n] = val;
it->n++;
return TRUE;
}
BOOL TXAPI itDel(INTTABLE* it,DWORD val)
{
int i = itiSearch(it,val);
if (i != -1) {
memcpy(it->table+i,it->table+i+1,(it->n-i-1)*sizeof(DWORD));
it->n--;
return TRUE;
}
return FALSE;
}
BOOL TXAPI itDelAll(INTTABLE* it)
{
it->n = 0;
return TRUE;
}
#endif // __NOTX__
//{###文字操作}
//文字のタイプを返したり、各種変換機能を提供します。
#include "base.h"
#ifdef __TXC__
#export
#define _K1 0x01
#define _K2 0x02
#define _K12 (_K1|_K2)
#define _KANA 0x04
#define __ALP 0x08
#define __NUM 0x10
#define __LOW 0x20
#define __SPC 0x40
#ifdef __TXC__
extern "std" {//1.00C iskanjiが使えないことがあった
#endif
extern UCHAR tJctype[256];
#ifdef __TXC__
}
#endif
#define iskanji(c) (tJctype[(UCHAR)(c)]&_K1)
#define iskanji2(c) (tJctype[(UCHAR)(c)]&_K2)
#define iskana(c) (tJctype[(UCHAR)(c)]&_KANA)
#endexport
#endif
UCHAR tJctype[256] = {
0,0,0,0,0,0,0,0, // 00
0,__SPC,__SPC,__SPC,__SPC,__SPC,0,0, // 08
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, // 10
__SPC,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, // 20
__NUM,__NUM,__NUM,__NUM,__NUM,__NUM,__NUM,__NUM, // 30
__NUM,__NUM,0,0,0,0,0,0, // 38
_K2,_K2|__ALP,_K2|__ALP,_K2|__ALP, // 40
_K2|__ALP,_K2|__ALP,_K2|__ALP,_K2|__ALP, // 44
_K2|__ALP,_K2|__ALP,_K2|__ALP,_K2|__ALP, // 48
_K2|__ALP,_K2|__ALP,_K2|__ALP,_K2|__ALP, // 4C
_K2|__ALP,_K2|__ALP,_K2|__ALP,_K2|__ALP, // 50
_K2|__ALP,_K2|__ALP,_K2|__ALP,_K2|__ALP, // 54
_K2|__ALP,_K2|__ALP,_K2|__ALP,_K2, // 58
_K2,_K2,_K2,_K2, // 5C
_K2,_K2|__ALP|__LOW,_K2|__ALP|__LOW,_K2|__ALP|__LOW, // 60
_K2|__ALP|__LOW,_K2|__ALP|__LOW,_K2|__ALP|__LOW,_K2|__ALP|__LOW, // 64
_K2|__ALP|__LOW,_K2|__ALP|__LOW,_K2|__ALP|__LOW,_K2|__ALP|__LOW, // 68
_K2|__ALP|__LOW,_K2|__ALP|__LOW,_K2|__ALP|__LOW,_K2|__ALP|__LOW, // 6C
_K2|__ALP|__LOW,_K2|__ALP|__LOW,_K2|__ALP|__LOW,_K2|__ALP|__LOW, // 70
_K2|__ALP|__LOW,_K2|__ALP|__LOW,_K2|__ALP|__LOW,_K2|__ALP|__LOW, // 74
_K2|__ALP|__LOW,_K2|__ALP|__LOW,_K2|__ALP|__LOW,_K2, // 78
_K2,_K2,_K2,0, // 7C
_K2,_K12,_K12,_K12,_K12,_K12,_K12,_K12,_K12,_K12,_K12,_K12,_K12,_K12,_K12,_K12,//80
_K12,_K12,_K12,_K12,_K12,_K12,_K12,_K12,_K12,_K12,_K12,_K12,_K12,_K12,_K12,_K12,//90
//2.00E2 A0はiskanaではなくした
_K2,_K2|_KANA,_K2|_KANA,_K2|_KANA,_K2|_KANA,_K2|_KANA,_K2|_KANA,_K2|_KANA,// A0
_K2|_KANA,_K2|_KANA,_K2|_KANA,_K2|_KANA,_K2|_KANA,_K2|_KANA,_K2|_KANA,_K2|_KANA,// A8
_K2|_KANA,_K2|_KANA,_K2|_KANA,_K2|_KANA,_K2|_KANA,_K2|_KANA,_K2|_KANA,_K2|_KANA,// B0
_K2|_KANA,_K2|_KANA,_K2|_KANA,_K2|_KANA,_K2|_KANA,_K2|_KANA,_K2|_KANA,_K2|_KANA,// B8
_K2|_KANA,_K2|_KANA,_K2|_KANA,_K2|_KANA,_K2|_KANA,_K2|_KANA,_K2|_KANA,_K2|_KANA,// C0
_K2|_KANA,_K2|_KANA,_K2|_KANA,_K2|_KANA,_K2|_KANA,_K2|_KANA,_K2|_KANA,_K2|_KANA,// C8
_K2|_KANA,_K2|_KANA,_K2|_KANA,_K2|_KANA,_K2|_KANA,_K2|_KANA,_K2|_KANA,_K2|_KANA,// D0
_K2|_KANA,_K2|_KANA,_K2|_KANA,_K2|_KANA,_K2|_KANA,_K2|_KANA,_K2|_KANA,_K2|_KANA,// D8
_K12,_K12,_K12,_K12,_K12,_K12,_K12,_K12,_K12,_K12,_K12,_K12,_K12,_K12,_K12,_K12,//E0
_K12,_K12,_K12,_K12,_K12,_K12,_K12,_K12,_K12,_K12,_K12,_K12,_K12,0,0,0,//F0
};
#ifdef __TXC__
#export
#ifdef __TXC__
#endexport
int TXAPIBASE isalnum(TXCHAR c)
{
// cが半角英数字かどうか返す
// 全角対応(isalnum('A')は0を返す)
if (c < 0x100) {
return (tJctype[c] & (__ALP|__NUM));
}
return 0;
}
int TXAPIBASE isalpha(TXCHAR c)
{
// cが半角英字かどうか返す
// 全角対応(isalpha('A')は0を返す)
if (c < 0x100) {
return (tJctype[c] & __ALP);
}
return 0;
}
int TXAPIBASE isdigit(TXCHAR c)
{
// cが半角数字かどうか返す
// 全角対応(isdigit('0')は0を返す)
if (c < 0x100) {
return (tJctype[c] & __NUM);
}
return 0;
}
int TXAPIBASE islower(TXCHAR c)
{
// cが半角英小文字かどうか返す
// 全角対応(islower('a')は0を返す)
if (c < 0x100) {
return ((tJctype[c] & (__ALP|__LOW)) == (__ALP|__LOW));
}
return 0;
}
int TXAPIBASE isupper(TXCHAR c)
{
// cが半角英大文字かどうか返す
// 全角対応(isupper('A')は0を返す)
if (c < 0x100) {
return ((tJctype[c] & (__ALP|__LOW)) == __ALP);
}
return 0;
}
int TXAPIBASE isspace(TXCHAR c)
{
// cが半角空白文字かどうか返す
// cがスペース、タブ、復帰、改行、垂直タブ、改ページ
// (0x20,0x09-0x0D)なら真を返す
// 全角対応(isspace(' ')は0を返す)
if (c < 0x100) {
return (tJctype[c] & __SPC);
}
if (c == '\n') return TRUE; // CR+LF
return 0;
}
int TXAPIBASE isreturn(TXCHAR c)
{
// cが改行文字かどうか返す
// cが'\n'か0x0Aか0x1A(EOF)なら真を返す
// 全角対応
return (c == '\n' /* CR+LF */ || c == 0x0A || c == 0x1A);
}
int TXAPIBASE iseof(TXCHAR c)
{
// cがEOF文字(0x1A)なら真を返す
// 全角対応
return (c == 0x1A);
}
int TXAPIBASE iszenkaku(TXCHAR c)
{
// cが全角文字なら真を返す
if (c == '\n') return FALSE; // CR+LF
return (c >= 0x100);
}
TXCHAR TXAPIBASE toupper(TXCHAR c)
{
// cが半角英小文字なら、半角英大文字に変換して返す
// そうでなければcを返す
// 全角対応(toupper('a')は'a'を返す)
if (c < 0x100 && (tJctype[c] & (__ALP|__LOW)) == (__ALP|__LOW)) {
return c - 0x20;
} else {
return c;
}
}
TXCHAR TXAPIBASE tolower(TXCHAR c)
{
// cが半角英大文字なら、半角英小文字に変換して返す
// そうでなければcを返す
// 全角対応(tolower('A')は'A'を返す)
if (c < 0x100 && (tJctype[c] & (__ALP|__LOW)) == __ALP) {
return c + 0x20;
} else {
return c;
}
}
#export
#endif
#endexport
#endif
//{###文字列操作}
mchar* TXAPI strnext(mchar* szstr)
{
// szstrが差す文字の次の文字へのポインタを返します
// 漢字、2バイト目が0の漢字にも対応しています。
// szstrがヌル文字を差していればszstrをそのまま返します。
//1.90で新設
mchar c;
if (!szstr) return NULL;
c = *szstr;
if (iskanji(c) && szstr[1]) {
return szstr + 2;
}
if (c == 0) return szstr;
return szstr + 1;
}
mchar* TXAPI strprev(mchar* sztop,mchar* szstr)
{
// szstrが差す文字の前の文字へのポインタを返します
// sztopに文字列の先頭文字へのポインタを渡してください
// 漢字、2バイト目が0の漢字にも対応しています。
// szstrが文字列の先頭ならszstrをそのまま返します。
//3.00B1 970519 new
if (!szstr) return NULL;
if (szstr == sztop) return szstr;
{
mchar* p = sztop;
mchar* p0 = p;
while(1) {
mchar c = *p;
if (iskanji(c) && p[1]) {
p += 2;
} else {
p++;
}
if (c == 0) break;
if (p == szstr) break;
p0 = p;
}
return p0;
}
}
TXCHAR strread(mchar* szstr)
{
// *szstrが漢字ならMAKEWORD(szstr[1],szstr[0])、
// そうでなければ*szstrを返します。
//3.00B1 970519 new
mchar c = *szstr;
if (iskanji(c) && szstr[1]) {
return MAKEWORD(szstr[1],c);
}
return c;
}
//{###ファイル名・パス名}
//ファイル名、パス名文字列の操作機能を提供します。
//フルパス指定からファイル名や拡張子を取り出したりセットしたりできます。
#ifndef __TXC__
#include <string.h>
#include <stdlib.h>
#include <ctype.h>
#include "base.h"
#endif
#ifdef __TXC__
#export
// パス名・ファイル名の最大長('\0'を含む)
#define CCHPATHNAME32 260 //1.98 WZ32のCCHPATHNAME
#ifdef __FLAT__
#define CCHDRIVE 3 //1.00F ドライブ名の長さ
#define CCHFILENAME 256 // "12345678.123\"等も平気
#define CCHFILEEXT 256 // "."も含む拡張子の最大長
#define CCHPATHNAME 260 // ファイル名も含む長さ絶対パスの最大長
#define CCHSPATHNAME 260 //1.00F ファイル名も含む長さ絶対パスの最大長
#define CCHAPPNAME 64
#else
#define CCHDRIVE 3 //1.00F ドライブ名の長さ
#define CCHFILENAME 14 // "12345678.123\"等も平気
#define CCHFILEEXT 5 // "."も含む拡張子の最大長
#define CCHPATHNAME 145 // ファイル名も含む長さ絶対パスの最大長
#define CCHSPATHNAME 72 //1.00F そう長くはならない絶対パスの最大長(メモリ節約)
#define CCHAPPNAME 64
#endif
#ifdef __TXC__
extern "tx" {
#endif
BOOL TXAPI txfullpath(mchar *dst,mchar *src);
#ifdef __TXC__
}
#endif
#endexport
#endif
///#include "path.h"
#include "_filer.h"
mchar* TXAPIBASE pathGetExt(mchar *path)
{
// pathの拡張子へのポインタを返す
// path:"aaaa.bcd"や"aaaa."なら、'.'へのポインタを返す
// path:"aaaa"なら、'\0'(文字列ターミネータ)へのポインタを返す
//1.00F ディレクトリに拡張子が含まれていると誤動作していた
mchar *p0 = NULL;
mchar c;
for (;c = *path;) {
if (iskanji(c) && path[1]) {
//1.99I
path += 2;
} else {
if (c == '.') p0 = path;
if (c == '\\' || c == '/') p0 = NULL;//1.00F
path++;
}
}
if (p0) return p0;
return path;
}
mchar* TXAPIBASE pathSetExt(mchar *path,mchar *ext)
{
// pathの拡張子をextに設定する
// ext:".bcd"や"."や""のように指定する
//3.00A3 970508 pathのサイズは最低CCHPATHNAMEであることを仮定しています。これを
// オーバーしないように設定します
#if 1///3.00A3 970508
mchar* p = pathGetExt(path);
if (ext) {
if ((p - path) + strlen(ext) >= CCHPATHNAME) return path;
strcpy(p,ext);
} else {
*p = 0;
}
return path;
#else
if (ext) {
strcpy(pathGetExt(path),ext);
} else {
strcpy(pathGetExt(path),"");
}
return path;
#endif
}
BOOL TXAPIBASE pathIsExt(mchar *path,mchar *ext)
{
// pathの拡張子がextか返す
// pathGetExtの返り値とextをstricmpして結果を返す
// 一致でTRUE, 不一致でFALSEを返す
return !stricmp(pathGetExt(path),ext);
}
BOOL TXAPI pathEquFileName(mchar *path,mchar *name)
{
// pathの拡張子を除くファイル名がnameか返す
// 一致でTRUE, 不一致でFALSEを返す
//1.00Cで追加
mchar *p = pathGetFileName(path);
#if 1//2.96 970209 pathがNULLのときに必ずTRUEを返してしまっていた
mchar *pend = pathGetExt(path);
int lch = pend - p;
return (!strnicmp(p,name,lch) && lch == strlen(name));
#else
mchar *pend = pathGetExt(path);
return !strnicmp(p,name,pend - p);
#endif
}
mchar* TXAPIBASE pathGetFileName(mchar *path)
{
// pathのファイル名を返す
mchar *p = path;
mchar *name;
if (p[0] && p[1] == ':') p += 2;
name = p;
while(*p) {
if (iskanji(*p)) {
if (p[1]) {
p += 2;
} else {
break;
}
} else {
if (*p == '/' || *p == '\\') {
name = p + 1;
}
p++;
}
}
return name;
}
BOOL TXAPI pathIsAutosave(mchar *szfilename)
{
mchar*p = pathGetFileName(szfilename);
return (p[0] == '$' && p[1] == '~');
}
UINT TXAPI pathGetDriveType(mchar* szfilename)
{
// szfilenameのドライブのドライブタイプを返します。
// szfilenameはフルパスで指定してください。
if (isalpha(szfilename[0]) && szfilename[1] == ':') {//2.00B ドライブ名チェック強化
#ifdef __FLAT__
mchar szdrive[3];
strcpylen(szdrive,szfilename,2);
return GetDriveType(szdrive);
#else
int idrive = toupper(szfilename[0]) - 'A';
return GetDriveType(idrive);
#endif
}
return 0;
}
int TXAPI ispathsepa(mchar c)
{
// cがパスセパレータ'/'か'\'ならTRUE、そうでなければFALSEを返します。
return (c == '/' || c == '\\');
}
#ifndef __NOTX__
#ifdef __TXC__
#export
enum PATHMODE {PATH_RELATIVE,PATH_ABSOLUTE,PATH_ABSOLUTEDRIVE,PATH_URL};
#endexport
#endif
int TXAPI pathGetMode(mchar* szfilename)
{
// szfilenameのモードを返します。
// PATH_RELATIVE,PATH_ABSOLUTE,PATH_ABSOLUTEDRIVE,PATH_URLのいずれかを返します
//1.90で新設
if (strstr(szfilename,"//")) return PATH_URL;
if (szfilename[1] == ':') return PATH_ABSOLUTEDRIVE;
if (szfilename[0] == '\\' || szfilename[0] == '/') return PATH_ABSOLUTE;
return PATH_RELATIVE;
}
mchar* TXAPI pathSepa(mchar* szstr)
{
// szstrからパスセパレータ'/'と'\'を探し、最初に見つけたパスセパレータを返す
// なければNULLを返す
//1.90で新設
mchar c;
while(c = *szstr) {
if (ispathsepa(c)) return szstr;
if (iskanji(c) && szstr[1]) {
szstr += 2;
} else {
szstr++;
}
}
return NULL;
}
void TXAPI pathFlushSepa(mchar* szstr,int ch)
{
// szstrのパスセパレータをchにセットします
//1.90で新設
mchar*p = szstr;
while(p = pathSepa(p)) {
*p = ch;
p++;
}
}
int TXAPI pathCmp(mchar* szpath1,mchar* szpath2,int *plch)
{
// strcmpと同じ様にszpath1とszpath2を比較します。
// パスセパレータ'\'と'/'は、同一文字として比較します。
// plchがNULLでなければマッチした文字数をplchに返します。
//1.90で新設
//2.98 970307 "c:\wz"と"c:\wz\std"でも一致しまっていた
int d = 0;
mchar*p1 = szpath1;
mchar*p2 = szpath2;
while(1) {
mchar c1 = *p1;
mchar c2 = *p2;
if (c1 && c2) {
if (iskanji(c1)) {
if (iskanji(c2)) {
d = p1[1] - p2[1];
if (d != 0) break;
p1 += 2;
p2 += 2;
} else {
d = c1 - c2;
break;
}
} else if (iskanji(c2)) {
d = c1 - c2;
break;
} else if (c1 == '\\' || c1 == '/') {
if (c2 == '\\' || c2 == '/') {
p1++;
p2++;
} else {
d = c1 - c2;
break;
}
} else {
d = toupper(c1) - toupper(c2);
if (d != 0) break;
p1++;
p2++;
}
} else {
d = c1 - c2;
break;
}
}
if (plch) *plch = p1 - szpath1;
return d;
}
int TXAPI pathCmpN(mchar* szpath1,mchar* szpath2,int lch,int *plch)
{
// strncmpと同じ様にszpath1とszpath2を比較します。
// パスセパレータ'\'と'/'は、同一文字として比較します。
// plchがNULLでなければマッチした文字数をplchに返します。
//1.90で新設
mchar buff1[CCHPATHNAME];
mchar buff2[CCHPATHNAME];
strcpy(buff1,szpath1);
strcpy(buff2,szpath2);
buff1[lch] = 0;
buff2[lch] = 0;
return pathCmp(buff1,buff2,plch);
}
int TXAPI pathSetMode(mchar* szfilename,mchar* szbase,mchar* szaddress,int mode)
{
// szfilenameのモードを設定します。
// modeにはPATH_RELATIVE,PATH_ABSOLUTE,PATH_ABSOLUTEDRIVE,PATH_URLのいずれかを指定します。
// szbaseにはベースディレクトリ、szaddressには、PATH_URLの場合サーバとドネインを指定します。
//1.90で新設
//3.00A3 970508 szfilenameのサイズは最低CCHPATHNAMEであることを仮定しています。これを
// オーバーしないように設定します
mchar szabs[CCHPATHNAME];
mchar buff[CCHPATHNAME];
// setup szabs
strcpy(szabs,szfilename);
{
mchar* p = strstr(szabs,"//");
if (p) {
p = pathSepa(p+2);
if (p) {
strcpy(szabs,p);
}
}
}
strcpy(buff,szbase);
pathSetFileName(buff,szabs);
strcpy(szabs,buff);
// szfilenameにはszabsからドライブ名を除いたものをセット
if (szabs[1] == ':') {
strcpy(szfilename,&szabs[2]);
} else {
strcpy(szfilename,szabs);
}
//
switch(mode) {
case PATH_ABSOLUTEDRIVE: {
strcpy(szfilename,szabs);
break;
}
case PATH_ABSOLUTE: {
break;
}
case PATH_URL: {
#if 1//3.00A3 970508
strcpy(buff,"http://");
if (strlen(buff) + (szaddress ? strlen(szaddress) : 0) + strlen(szfilename) >= CCHPATHNAME) {
// overflow
} else {
if (szaddress) strcat(buff,szaddress);
strcat(buff,szfilename);
}
//
strcpy(szfilename,buff);
pathFlushSepa(szfilename,'/');
return TRUE;
#else
strcpy(buff,"http://");
if (szaddress) {
strcat(buff,szaddress);
}
strcat(buff,szfilename);
//
strcpy(szfilename,buff);
pathFlushSepa(szfilename,'/');
return TRUE;
#endif
}
case PATH_RELATIVE: {
mchar* p1 = (szbase[1] == ':') ? &szbase[2] : szbase;
mchar* p2 = (szabs[1] == ':') ? &szabs[2] : szabs;
mchar* dst = szfilename;
BOOL f = TRUE;
while(*p1 && *p2) {
p1++;
if (f) p2++;
{
mchar* p1a = pathSepa(p1);
mchar* p2a = p2;
if (f) {
p2a = pathSepa(p2);
if (!p2a) p2a = "";
}
if (!p1a) {
if ((dst - szfilename) + strlen(p2) >= CCHPATHNAME) break;//3.00A3 970508
strcpy(dst,p2);
dst += strlen(dst);
break;
}
if (f) {
int lch1 = p1a - p1;
int lch2 = p2a - p2;
if (lch1 == lch2 && !strnicmp(p1,p2,lch1)) {
// 一致
} else {
f = FALSE;
if ((dst - szfilename) + 3 >= CCHPATHNAME) break;//3.00A3 970508
strcpy(dst,"..\\");
dst += 3;
}
} else {
if ((dst - szfilename) + 3 >= CCHPATHNAME) break;//3.00A3 970508
strcpy(dst,"..\\");
dst += 3;
}
p1 = p1a;
if (f) p2 = p2a;
}
}
*dst = 0;
break;
}
default: {
return FALSE;
}
}
pathFlushSepa(szfilename,(textf->crSave == RETURNCODE_LF) ? '/' : '\\');//2.99C 970324 text1->textf
return TRUE;
}
mchar* TXAPI pathToWz(mchar *szpath)
{
// szpathがWZディレクトリ内を指すものであれば、wz:\形式に変換します。
// そうでなければ何もしません
// szpathを返します
//3.00A3 970508 szpathのサイズは最低CCHPATHNAMEであることを仮定しています。これを
// オーバーしないように設定します
if (szpath) {
int len = strlen(text1->szexedir);
if (!strnicmp(szpath,text1->szexedir,len)) {
// text1->szexedirは"wz:\"より絶対長いはずなので、szbuffをオーバーすることはない
mchar szbuff[CCHPATHNAME];
strcpy(szbuff,"wz:\\");
strcat(szbuff,szpath + len);
strcpy(szpath,szbuff);
}
}
return szpath;
}
#endif // __NOTX__
void TXAPI pathFlush(mchar* szstr)
{
// szstrに"..\"が含まれていたら適切に処理して取り除ければ取り除きます
//1.90で新設
int tsepa[100];
int nsepa = 0;
mchar*p = szstr;
while(*p) {
if (*p == '.' && p[1] == '.' && ispathsepa(p[2]) && nsepa >= 2) {
mchar* p0 = szstr+tsepa[nsepa-2];
nsepa -= 2;
strcpy(p0,&p[2]);
p = p0;
} else {
if (ispathsepa(*p)) {
if (nsepa == 100) break; // overflow
tsepa[nsepa++] = p - szstr;
}
p = strnext(p);
}
}
}
mchar* TXAPIBASE pathSetFileName(mchar *path,mchar *filename)
{
// pathのファイル名をfilenameに設定します
// filenameにドライブ名付き絶対パス、絶対パス、
// "wz:\","win:\"付きパスを指定することもできます
//1.90 "..\"に対応
//2.00B "%{date}","%{year}","%{month}","%{day}"で
// 現在の日付,年,月,日を指定できます。
// "windrive:\"付きパスを指定することもできます
// "..\"を含めることもできます
//3.00A3 970508 pathのサイズは最低CCHPATHNAMEであることを仮定しています。これを
// オーバーしないように設定します
if (!filename) {
strcpy(pathGetFileName(path),"");
} else {
mchar top = filename[0];
int lchFilename = strlen(filename);//3.00A3 970508
if (lchFilename + 2 >= CCHPATHNAME) return path;//3.00A3 970508
if (isalpha(top) && filename[1] == ':') {
// ドライブ名が付いている
strcpy(path,filename);
} else if (ispathsepa(top)) {
// 先頭が'\'だ。
if (isalpha(*path) && path[1] == ':') {
strcpy(path + 2,filename);
} else {
strcpy(path,filename);
}
#ifndef __NOTX__
} else if (!strnicmp(filename,"wz:\\",4)) {
// "wz:\"
strcpy(path,text1->szexedir);
if (strlen(path) + lchFilename >= CCHPATHNAME) return path;//3.00A3 970508
strcat(path,filename + 4);
} else if (!strnicmp(filename,"win:\\",5)) {
// "win:\"
GetWindowsDirectory(path,CCHPATHNAME);
if (strlen(path) + lchFilename >= CCHPATHNAME) return path;//3.00A3 970508
strcat(path,filename + 5);
} else if (!strnicmp(filename,"windrive:\\",10)) {
// "windrive:\"
GetWindowsDirectory(path,CCHPATHNAME);
if (strlen(path) + lchFilename >= CCHPATHNAME) return path;//3.00A3 970508
strcpy(path + 3,filename + 10);
#endif
} else {
#if 1//3.00A3 970508
mchar* p = pathGetFileName(path);
if ((p - path) + lchFilename >= CCHPATHNAME) return path;//3.00A3 970508
strcpy(p,filename);
#else
strcpy(pathGetFileName(path),filename);
#endif
}
}
pathFlush(path);//1.90
#ifndef __NOTX__
//2.00B
if (strchr(path,'%')) {
mchar* src = path;
TIME time;
TM tm;
timeGet(&time);
timeGetLocal(&tm,&time);
while(1) {
src = strchr(src,'%');
if (!src) break;
{
// 必ず置換後の方が文字列の長さが変わらないか短くなること
int len = 0;
if (len = strmatch(src,"%{date}")) {
sprintf(src,"%02d%02d%02d",tm.tm_year,tm.tm_mon + 1,tm.tm_mday);
} else if (len = strmatch(src,"%{year}")) {
sprintf(src,"%02d",tm.tm_year);
} else if (len = strmatch(src,"%{month}")) {
sprintf(src,"%02d",tm.tm_mon + 1);
} else if (len = strmatch(src,"%{day}")) {
sprintf(src,"%02d",tm.tm_mday);
}
if (len) {
int lenPrint = strlen(src);
strcpy(src + lenPrint,src + len);
src += len;
} else {
src++;
}
}
}
}
#endif
return path;
}
BOOL TXAPI pathGetFull(mchar *path)
{
// pathが絶対パスかどうか返します。
// pathの先頭部分が、"ドライブ名:\","ドライブ名:/","\\"かどうかで判断しています。
//2.00B UNC対応
if (isalpha(path[0]) && path[1] == ':' && (path[2] == '\\' || path[2] == '/')) return TRUE;
if (path[0] == '\\' && path[1] == '\\') return TRUE;
return FALSE;
}
BOOL TXAPI pathFormDir(mchar *path)
{
// pathの最後がパスセパレータで終わっていたら、取り除いてTRUEを返す
// そうでなければFALSEを返す
mchar *p = strGetLast(path);
if (ispathsepa(*p)) {
*p = 0;
return TRUE;
}
return FALSE;
}
#ifndef __NOTX__
void TXAPI pathSetDir(mchar *path)
{
// pathの最後がパスセパレータで終わっていなければ、パスセパレータを追加する
//3.00A3 970508 pathのサイズは最低CCHPATHNAMEであることを仮定しています。これを
// オーバーしないように設定します
mchar *p = strGetLast(path);
if (!ispathsepa(*p)) {
if (strlen(path) + 1 >= CCHPATHNAME) return;//3.00A3 970508
if (textf->crSave == RETURNCODE_LF) {//2.99C 970324 text1->textf
strcat(path,"/");
} else {
strcat(path,"\\");//1.00C pathSetDirプログラムミス
}
}
}
#endif// __NOTX__
//1.00H2
BOOL TXAPIBASE pathFormLong(mchar *path)
{
// pathが、["ファイル名"],["ファイル名],[ファイル名"]のときは、
// pathに[ファイル名]をセットしTRUEを返します。
// そうでなければFALSEを返します
BOOL ret = FALSE;
int len = strlen(path);
if (path[0] == '"') {
if (len >= 2 && path[len-1] == '"') len--;
strcpylen(path,&path[1],len-1);
return TRUE;
} else if (len && path[len-1] == '"') {
path[len-1] = 0;
return TRUE;
}
return FALSE;
}
//1.00H2
mchar* TXAPIBASE pathSetLong(mchar *path)
{
// pathを""で括ります。
// strlen(path)が最大2文字増加しますので、これに見合った長さのバッファのポインタを
// pathに指定してください。
// pathを返します
//3.00A3 970508 pathのサイズは最低CCHPATHNAMEであることを仮定しています。これを
// オーバーしないように設定します
mchar szbuff[CCHPATHNAME];
mchar *dst = szbuff;
int len = strlen(path);
if (len + 2 >= CCHPATHNAME) return path;//3.00A3 970508
*dst++ = '"';
strcpy(dst,path);dst += len;
*dst++ = '"';
*dst = 0;
strcpy(path,szbuff);
return path;
}
void TXAPI pathForm(mchar *path)
{
// pathをDOSのパス形式に変換
// "a:\wz\wz.exe" -> "a:\wz"
// "a:\abc" -> "a:\"
mchar *p;
pathSetFileName(path,0);
p = strGetLast(path);
if (*p == '\\' || *p == '/') {
if (strlen(path) == 3) return; // "a:\"はそのまま返す
*p = 0; // 末尾の"\"を除いて返す
}
}
#ifdef __NOTX__
// typedef struct find_t FILEFIND;
#define fileFindFirst _dos_findfirst
#define fileFindNext _dos_findnext
#define txfullpath(dst,src) _fullpath(dst,src,CCHPATHNAME)
#endif
BOOL TXAPI pathIsDirectory(mchar *path)
{
// pathがディレクトリかどうか返す
// pathがディレクトリでないか存在しなければFALSEを返す
//1.00Fで追加
#ifdef __FLAT__
{
BOOL ret = FALSE;
WIN32_FIND_DATA ffd;
HANDLE hfind = FindFirstFile(path,&ffd);
if (hfind != INVALID_HANDLE_VALUE) {
if (ffd.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) ret = TRUE;
FindClose(hfind);
}
return ret;
}
#else
{
FILEFIND find;
if (!fileFindFirst(path,FA_DIREC,&find)) {
if (find.attrib & FA_DIREC) return TRUE;
}
}
#endif
return FALSE;
}
BOOL TXAPI pathIsWild(mchar *path)
{
// pathが'*','?',を含んでいたらTRUEを返す
if (strchr(path,'*') || strchr(path,'?')) return TRUE;
return FALSE;
}
BOOL TXAPI pathIsFileName(mchar *path)
{
// パス指定がファイルかどうか返す
// pathが""だったり、'*','?',';'を含んでたり、
// ディレクトリだったらFALSEを返す
// そうでなければTRUEを返す
if (!path || !path[0]) return FALSE;
if (pathIsWild(path)) return FALSE;
if (strchr(path,';')) return FALSE;
{
mchar c = *strGetLast(path);
if (c == '\\' || c == '/' || c == ':') return FALSE;
}
if (pathIsDirectory(path)) return FALSE;
return TRUE;
}
BOOL TXAPI pathDirExist(mchar *path)
{
// pathのディレクトリが存在するか返す
// pathは、DOSのパス形式で指定
// pathが、"a:\"のようなドライブ指定なら、必ずTRUEを返す
// そうでなければ、実際にディレクトリがあるか調べる
if (!path || !path[0]) return FALSE;
if (isalpha(path[0]) && path[1] == ':' && path[2] == '\\' && path[3] == 0) return TRUE;
if (pathIsDirectory(path)) return TRUE;
return FALSE;
}
mchar* TXAPI pathSetFull(mchar *path)
{
// pathを絶対パスに変換
//3.00A3 970508 pathのサイズは最低CCHPATHNAMEであることを仮定しています。これを
// オーバーしないように設定します
mchar src[CCHPATHNAME];
mchar dst[CCHPATHNAME];
strcpy(src,path);
{
mchar *p = pathGetFileName(src);
if (*p == 0) {
// "xxx\"のように'\'で終わるなら"*.*"を追加。こうしないと駄目
pathSetFileName(src,"*.*");
}
}
if (txfullpath(dst,src)) {
strcpy(path,dst);
} else {
*path = 0;
}
return path;
}
BOOL TXAPI pathSearchExt(mchar *szdst,mchar *szenvext)
{
// szdstの拡張子を、szenvextリストにセットして検索する
// 見つかったかどうか返す
// szdstの拡張子を変更する
//3.00A3 970508 szdstのサイズは最低CCHPATHNAMEであることを仮定しています。これを
// オーバーしないように設定します
mchar *szext = pathGetExt(szdst);
int cchRemain = CCHPATHNAME - (szext - szdst);//3.00A3 970508
mchar *src = szenvext;
mchar *src0 = src;
BOOL fexit = FALSE;
if (szext[0] == '.' || !szenvext) {
OFSTRUCT of;
if (OpenFile(szdst,&of,OF_EXIST) != HFILE_ERROR) {
return TRUE;
}
return FALSE;
}
while(!fexit) {
int len;
src = strchr(src,';');
if (!src) src = strchr(src0,' ');
if (src == NULL) {
fexit = TRUE;
src = szenvext + strlen(szenvext);
}
len = src-src0;
#if 1//3.00A3 970508
strcpylenmax(szext,src0,len,cchRemain);
#else
mcharcpy(szext,src0,len);szext[len] = 0;
#endif
{
OFSTRUCT of;
if (OpenFile(szdst,&of,OF_EXIST) != HFILE_ERROR) {
return TRUE;
}
}
//
src++;
src0 = src;
}
return FALSE;
}
#ifndef __NOTX__
mchar* TXAPI pathEnvWalk(mchar* szenvpath,mchar* szdst)
{
//パス指定szenvpathを解析し、1つずつ取り出します。
//結果をszdstに返します。次に調べるべきパス指定を返します。
//なければNULLを返します。
//使い方:std.cのpathSearchを参考にしてください。
mchar *p = szenvpath;
if (!p) return NULL;
while(1) {
if (*p == ';' || *p == ' ') {
p++;
} else if (*p == 0) {
return NULL;
} else {
break;
}
}
{
mchar *p0 = p;
mchar c0 = 0;
mchar c;
int lchexedir = strlen(text1->szexedir) - 1;
szdst[0] = 0; // 初期化 for error時
for(;;c0 = c,p++) {
c = *p;
if (iskanji(c)) {
p++;
} else if (c == ';' || c == ' ' || c == 0) {
mchar *dst = szdst;
int len = p - p0;
if (len >= 3 && !strnicmp(p0,"wz:",3)) {
if (!(lchexedir + (len - 3) + 1 >= CCHPATHNAME)) {
mcharcpy(dst,text1->szexedir,lchexedir);dst+=lchexedir;
mcharcpy(dst,p0+3,len-3);dst+=len-3;
}
} else {
if (!(len + 1 >= CCHPATHNAME)) {
mcharcpy(dst,p0,len);dst+=len;
}
}
if (c0 != '\\' && c0 != '/') *dst++ = '\\';
*dst = 0;
return p;
}
}
}
}
BOOL TXAPI pathSearch(mchar *szdst,mchar *szpath,mchar *szenvpath,mchar *szenvext)
{
// szpathを検索し、szdstに結果を入れる
// ファイルが見つかったかどうかを返す
//3.00A3 970508 szdstのサイズは最低CCHPATHNAMEであることを仮定しています。これを
// オーバーしないように設定します
#ifndef __TXC__
TX* text = text1;
#endif
int lchPath = strlen(szpath);//3.00A3 970508
if (lchPath >= CCHPATHNAME) return FALSE;//3.00A3 970508
if (pathGetFull(szpath)) {
// フルパス
strcpy(szdst,szpath);
return pathSearchExt(szdst,szenvext);
} else if (!strnicmp(szpath,"wz:\\",4)) {
// フルパス(wz:\)
strcpy(szdst,text->szexedir);
if (strlen(szdst) + lchPath >= CCHPATHNAME) return FALSE;//3.00A3 970508
strcat(szdst,szpath+4);
return pathSearchExt(szdst,szenvext);
} else {
mchar *p = szenvpath;
while(1) {
p = pathEnvWalk(p,szdst);
if (!p) break;
if (strlen(szdst) + lchPath >= CCHPATHNAME) return FALSE;//3.00A3 970508
strcat(szdst,szpath);
if (pathSearchExt(szdst,szenvext)) return TRUE;
}
}
szdst[0] = 0;
return FALSE;
}
BOOL TXAPI pathIsIncluded(mchar *szfilename,mchar *szenvpath)
{
// szfilenameのファイルのディレクトリが、
// szenvpathのパス指定に含まれているか返します
// szfilenameにはフルパスを指定してください。
// ファイル名はダミーでもいいですから指定して下さい。
//{#EX}pathIsIncluded(\"a:\wz\std\apidb.c",\"a:\wz\std");はTRUEを返します
//1.00Cで追加
mchar szsrc[CCHPATHNAME];
strcpy(szsrc,szfilename);
pathSetFileName(szsrc,NULL);
{
mchar szdst[CCHPATHNAME];
mchar *p = szenvpath;
while(1) {
p = pathEnvWalk(p,szdst);
if (!p) return FALSE;
if (!stricmp(szsrc,szdst)) return TRUE;
}
}
}
#endif// __NOTX__
BOOL TXAPIBASE fileIsExist(mchar *_szfilename)
{
// szsrcのファイルが存在するかどうか返します。
// ファイル名は""でくくってあっても構いません。
mchar szfilename[CCHPATHNAME];
strcpy(szfilename,_szfilename);
pathFormLong(szfilename);//1.00H2
#if 1
{
//1.01A fileIsExist:ファイルが存在してもオープンできないときはFALSEを返していたのを修正
BOOL ret = FALSE;
#ifdef __FLAT__
WIN32_FIND_DATA ffd;
HANDLE hfind = FindFirstFile(szfilename,&ffd);
if (hfind != INVALID_HANDLE_VALUE) {
ret = TRUE;
FindClose(hfind);
}
#else
FILEFIND filefind;
if (!fileFindFirst(szfilename,FA_NORMAL,&filefind)) {
ret = TRUE;
}
#endif
return ret;
}
#else
{
HFILE hf = hfileOpen(szfilename);
if (hf != HFILE_ERROR) {
hfileClose(hf);
return TRUE;
}
}
return FALSE;
#endif
}
#ifndef __NOTX__
void TXAPI pathAuto(mchar* szfilename,mchar* szenvpath,mchar* szenvext)
{
// WZ Editorのパス検索と同じ機能を提供
if (szfilename && szfilename[0]) {
if (!textf->fNoTextPathSearch) {//2.99C 970324 text1->textf
#if 1 //2.99C 970323 szfilenameがフルパスでない時、たまたまカレントディレクトリに
// szfilenameがあったとき、そのまま返していたが、
// この場合もきちんとパス検索して、できるだけフルパスで返すようにした。
// ヒストリからファイルを選んでもファイルが開かなかったり、
// 2.99Bでtxe起動でマクロパス検索がパスされてtxeが起動しなかったりした。
BOOL fFullPath = pathGetFull(szfilename);
if (fFullPath && fileIsExist(szfilename)) {
// OK
} else {
BYTE path[CCHPATHNAME];
strcpy(path,szfilename);
if (fFullPath && pathSearchExt(path,szenvext)) {
strcpy(szfilename,path);
} else {
if (pathSearch(path,pathGetFileName(szfilename),szenvpath,szenvext)) {
strcpy(szfilename,path);
}
}
}
#else
if (!fileIsExist(szfilename)) {
BYTE path[CCHPATHNAME];
strcpy(path,szfilename);
if (pathSearchExt(path,szenvext)) {
strcpy(szfilename,path);
} else {
if (pathSearch(path,pathGetFileName(szfilename),szenvpath,szenvext)) {
strcpy(szfilename,path);
}
}
}
#endif
}
// 拡張子が"."のみなら、消去
{
mchar *szext = pathGetExt(szfilename);
if (szext[1] == 0) *szext = 0;
}
}
}
void TXAPI _wzpathAuto(mchar *szfilename,BOOL fSearchPath)
{
//2.92
if (textf->fNoTextPathSearch || !fSearchPath) {//2.99C 970324 text1->textf
// 拡張子が"."のみなら、消去
mchar *szext = pathGetExt(szfilename);
if (szext[1] == 0) *szext = 0;
} else {
pathAuto(szfilename,wzGetEnv(WZENV_PATH),wzGetEnv(WZENV_EXT));
}
}
void TXAPI wzpathAuto(mchar *szfilename)
{
// szfilenameに結果を返すので注意すること
// szfilenameにはCCHPATHNAME以上のサイズのメモリを渡すこと
// 絶対パスを返すわけではない
//2.92
_wzpathAuto(szfilename,TRUE);
}
//{###メニュー操作}
//メニューを作成し、コマンドを追加します。
//メニューは#winmenu命令を使って簡単につくれます。usermenu.txcを参考にしてください。
#ifdef __TXC__
HMENU TXAPI menuNew(void)
{
// 新しくメニューを作成し、メニューハンドルを返します。
return CreatePopupMenu();
}
void TXAPI menuTitle(HMENU hmenu,mchar *sztitle)
{
// メニューにタイトルを付けます。menuNewの直後に呼び出して下さい。
AppendMenu(hmenu,MF_STRING,0,"\t"+sztitle);
AppendMenu(hmenu,MF_SEPARATOR,0,NULL);
}
void TXAPI menuTxD(HMENU hmenu,mchar key,mchar *sztitle,mchar *szfunc)
{
// メニューにDOSスタイルのコマンドを追加します。
// sztitleにメニューに表示する文字列、szfuncにWZのコマンドを指定して下さい。
txstr szkey = "& \t";
szkey[1] = key;
menuTx(hmenu,szkey + sztitle,szfunc);
}
void TXAPI menuStr(HMENU hmenu,mchar *szStr,int id)
{
// メニューに文字列を追加します。
// szStrに文字列、idにメニューIDを指定して下さい。
AppendMenu(hmenu,MF_STRING,id,szStr);
}
void TXAPI menuSepa(HMENU hmenu)
{
// メニューにセパレータを追加します。
AppendMenu(hmenu,MF_SEPARATOR,0,NULL);
}
void TXAPI menuPopup(HMENU hmenu,mchar *szStr,HMENU hmenuPopup)
{
// メニューにポップアップメニューを追加します。
// szStrに文字列、hmenuPopupに追加するメニューのハンドルを指定して下さい。
AppendMenu(hmenu,MF_POPUP,(UINT)hmenuPopup,szStr);
}
void TXAPI menuDelete(HMENU hmenu)
{
// メニューを削除します。メニューを使い終わったら呼んで下さい。
DestroyMenu(hmenu);
}
void TXAPI menuHist(HMENU hmenu)
{
// メニューにファイルヒストリリストを追加します。
menuStr(hmenu,"",IDM_TXFILEHIST);
}
void TXAPI menuHistTab(HMENU hmenu)
{
// メニューにDOSスタイルのファイルヒストリリストを追加します。
menuStr(hmenu,"",IDM_TXFILEHISTTAB);
}
#endif // __TXC__
void TXAPI menuOpenMouse(HMENU hmenu)
{
// マウスカーソル位置にメニューを表示します
POINT point;
GetCursorPos(&point);
TrackPopupMenu(hmenu,TPM_LEFTBUTTON|TPM_RIGHTBUTTON|TPM_LEFTALIGN,point.x,point.y,0,textf->hwndbase,NULL);
}
void TXAPI menuOpen(HMENU hmenu)
{
// カーソル位置にメニューを表示します
// マウスでメニューが開かれた場合は、マウスカーソル位置にメニューを表示します
if (textf->fMenuOpenMouse) {
menuOpenMouse(hmenu);
} else {
POINT point;
if (textf->fListbox) {
// リストボックスモードではキャレットを生成していないので、
// GetCaretPosでマトモな位置を取得できない。
point.x = textf->cxChar * 4;
point.y = textf->ly * textf->cyLine;
} else {
GetCaretPos(&point);
}
if (textf->hwndtext2 && textf->fFocus2) {
//3.00B1 970612 ウィンドウ分割時、下の窓でShift+F10しても上の窓の位置にメニューが表示された
ClientToScreen(textf->hwndtext2,&point);
} else {
ClientToScreen(textf->hwndtext,&point);
}
if (_fwin40) {
// メニューの先頭項目が選択されるようにする
// VZとの互換性を高める
PostMessage(textf->hwndtext,WM_KEYDOWN,VK_DOWN,0);
}
TrackPopupMenu(hmenu,TPM_LEFTBUTTON|TPM_RIGHTBUTTON|TPM_LEFTALIGN,point.x,point.y,0,textf->hwndbase,NULL);
}
}
#ifdef __TXC__
void TXAPI menuDelAll(HMENU hmenu)
{
// メニューの内容を全て破棄します。
/// all delete
while(DeleteMenu(hmenu,0,MF_BYPOSITION));
}
#endif // __TXC__
#endif// __NOTX__
#ifdef __TXC__
#export
#ifdef __TXC__
#endexport
//{###メモリ操作}
//メモリブロックの割り当てや解放、コピー機能などを提供します。
LPVOID TXAPI memAlloc(DWORD cbsize)
{
// cbsizeバイトのグローバルメモリブロックを確保し、
// メモリブロックのポインタを返す
// 確保したメモリブロックの0クリアはしません
return GlobalAllocPtr(TXGMEM_MOVEABLE,cbsize);
}
LPVOID TXAPI memAllocZeroinit(DWORD cbsize)
{
// cbsizeバイトのグローバルメモリブロックを確保し、
// メモリブロックのポインタを返す
// 確保したメモリブロックの0クリアもします
//1.95で追加
return GlobalAllocPtr(TXGMEM_MOVEABLE|GMEM_ZEROINIT,cbsize);
}
void TXAPI memFree(LPVOID pmem)
{
// memAllocで確保したメモリブロックを解放する。
GlobalFreePtr(pmem);
}
LPVOID TXAPI memResize(LPVOID p,DWORD size)
{
// memAllocで確保したメモリブロックのサイズを変更する
//1.91A で追加
#ifdef __FLAT__
return GlobalReAlloc(p,size,GMEM_MOVEABLE);
#else
return GlobalReAllocPtr(p,size,0);
#endif
}
//{###ダイアログ}
static void _information(mchar *_format,void* arg)
{
// 情報メッセージボックスを出します
// printfと同じ書式指定でメッセージを表示します
if (_format) {//1.90
mchar buff[500];
vsprintf(buff,_format,arg);
//2.93 text1 -> textf
#ifdef __FLAT__//強制ACTIVE
wndtxSetActive(textf->hwndbase);
#endif
MessageBox(wndtxGetActive(textf->hwndbase),buff,"WZ",MB_ICONINFORMATION|MB_OK);
}
}
// %c,%ld,%d,%u,%s,%pだけ使える
void TXAPIBASE _cdecl information(mchar *_format,...)
{
// 情報メッセージボックスを出します
// printfと同じ書式指定でメッセージを表示します
// 表示できるメッセージの長さは最大500バイトです。
_information(_format,(void*)(&_format + 1));
}
// %c,%ld,%d,%u,%s,%pだけ使える
void TXAPIBASE _cdecl attention(mchar *_format,...)
{
// 警告メッセージボックスを出します
// printfと同じ書式指定でメッセージを表示します
// 表示できるメッセージの長さは最大500バイトです。
if (_format) {//1.90
mchar buff[500];
vsprintf(buff,_format,(void*)(&_format + 1));
//2.93 text1 -> textf
#ifdef __FLAT__//強制ACTIVE
wndtxSetActive(textf->hwndbase);
#endif
MessageBox(wndtxGetActive(textf->hwndbase),buff,"WZ",MB_ICONEXCLAMATION|MB_OK);
}
}
//{###ダイアログ}
// %c,%ld,%d,%u,%s,%pだけ使える
int TXAPIBASE _cdecl question(mchar *_format,...)
{
// 問い合わせメッセージボックスを出します
// printfと同じ書式指定でメッセージを表示します
// [はい]が選択されるとIDYES、
// [いいえ]が選択されるとIDNO、
// [キャンセル]が選択されるとIDCANCEL、を返します
// 表示できるメッセージの長さは最大500バイトです。
if (_format) {//1.90
mchar buff[500];
vsprintf(buff,_format,(void*)(&_format + 1));
//2.93 text1 -> textf
#ifdef __FLAT__//強制ACTIVE
wndtxSetActive(textf->hwndbase);
#endif
return MessageBox(wndtxGetActive(textf->hwndbase),buff,"WZ",MB_ICONQUESTION|MB_YESNOCANCEL);
} else {
return IDCANCEL;
}
}
//{###標準出力}
//stdoutウィンドウに文字列を出力します。
//マクロのデバッグなどに使えます。
//2.00B printf,printでは、必ず標準出力窓のテキストの末尾に文字列を出力するようにしました。
// %c,%ld,%d,%u,%s,%pだけ使える
int TXAPI _cdecl print(mchar *szstr)
{
// 標準出力に文字列を出力する
return txOp(text,TXOP_PRINT,(LPARAM)szstr,0);//2.96 970209
}
// %c,%ld,%d,%u,%s,%pだけ使える
int TXAPIBASE _cdecl printf(mchar *_format,...)
{
// 書式付き出力を行う
// 出力は標準出力先"stdout"テキストに行う
// 正常実行できた場合は、出力したバイト数(ヌルターミネータは除く)を返す
// 書式の指定はCと同じ。詳細はCの本を参照してください。
// %cで漢字も表示できます。
// %[-][0][n][,][l]{d|u|x|X|c|s|p}
// 例:printf("a = %3d,szstr = %s\n",a,szstr);
// ※100バイトを越えるような長いformatは指定できません
return txOp(text,TXOP_PRINTF,(LPARAM)_format,(LPARAM)(&_format + 1));//2.96 970209
}
//{###文字列操作}
// %c,%ld,%d,%u,%s,%pだけ使える
int TXAPIBASE _cdecl sprintf(mchar *buff,mchar *_format,...)
{
// printfと同じ様に、書式化された出力を文字列buffに
// 正常実行できた場合は、出力したバイト数(ヌルターミネータは除く)を返す
// 文字列バッファbuffの長さチェックはされないので、注意してください
vsprintf(buff,_format,(void*)(&_format + 1));
return strlen(buff);
}
//{###表示}
// %c,%ld,%d,%u,%s,%pだけ使える
void TXAPI _cdecl txDispInfo(PTEXT text,mchar *_format,...)
{
// ステータスバーに情報を表示
// formatはprintfと同じ様に指定
// textのhwndtextが画面に表示されていれば(表テキストであれば)、
// ステータスバーに表示します。txSetUndisp中でも、表示します。
// 表示されていなければ(裏テキストならば)、表示しません。
//1.00F "$b","$c"は廃止しました
if (!text->hwndtext) return;
text = txGetFrame(text);//3.00B1 970613 WZ FilerでもtxDispInfoできるようにした
mchar buff[500];
if (_format) {
vsprintf(buff,_format,(void*)(&_format + 1));
} else {
buff[0] = 0;
}
SendMessage(text->hwndbase,WM_TXSB_SETUPTEXT,HSL_INFO,(LPARAM)buff);
}
static void _statprintf(mchar* _format,void* arg)
{
mchar buff[500];
TX* text = txGetFrame(textf);
int fUndisp = text->fUndisp;
text->fUndisp = 0;
if (_format) {
vsprintf(buff,_format,arg);
} else {
buff[0] = 0;
}
SendMessage(text->hwndbase,WM_TXSB_SETUPTEXT,HSL_SIMPLE,(LPARAM)buff);
text->fUndisp = fUndisp;
}
void TXAPIC TXAPIBASE statprintf(mchar *_format,...)
{
// ステータスバーに情報を表示
// formatはprintfと同じ様に指定
// txSetUndisp中かどうかに関わらず、常に表示します。
//1.99Bで追加
_statprintf(_format,(void*)(&_format + 1));
}
void TXAPIC informationex(mchar* _format,...)
{
// ステータスバーに情報を表示
// ステータスバーが非表示ならinformationする
// formatはprintfと同じ様に指定
// txSetUndisp中かどうかに関わらず、常に表示します。
//2.92で追加
if (textf->fDispStatusbar) {//2.99C 970324 text1->textf
_statprintf(_format,(void*)(&_format + 1));
} else {
information(_format,(void*)(&_format + 1));
}
}
// %c,%ld,%d,%u,%s,%pだけ使える
void TXAPI _cdecl txDispSl(PTEXT text,int hsl,mchar *_format,...)
{
// hsl(HSL1からHSL3)に情報を表示
// formatはprintfと同じ様に指定
// 文字列の先頭部に"$c"を指定するとセンタリングして表示します。
mchar buff[500];
if (_format) {
vsprintf(buff,_format,(void*)(&_format + 1));
} else {
buff[0] = 0;
}
SendMessage(text->hwndbase,WM_TXSB_SETUPTEXT,hsl,(LPARAM)buff);
}
#export
#endif
#endexport
#endif // __TXC__
//{###文字操作}
BOOL TXAPIBASE txchIsKanji(TXCHAR c)
{
// cが全角文字かどうか返す
if (c < 0x100) return FALSE;
if (c == 0x0D0A) return FALSE;
return TRUE;
}
BOOL TXAPIBASE txchIsReturn(TXCHAR c)
{
// cが改行コード(0x0D0A,0x0A,0x1A)かどうか返す
if (c == 0x0A || c == 0x1A) return TRUE;
if (c == 0x0D0A) return TRUE;
return FALSE;
}
#ifdef __TXC__
//{###ウィンドウ操作}
//WZ特有のウィンドウ操作を行います。
BOOL TXAPI wndRegisterClass(mchar* szWndProc,txstr strClass)
{
// 簡易 RegisterClass
// 一般的なスタイルを持つウィンドウクラスを登録します。
// szWndProcには"マクロファイル名.ウィンドウプロシジャ名",
// strClassには、txstr型の変数を渡して下さい。wndRegisterClassがワーク用に
// 使います。利用側は変数の内容を変更してはいけません。
// ウィンドウが不要になったら、strClassを引数に指定してwndUnregisterClass
// してください。
// thanks dieさん
//2.96A 970211 仕様変更 strClassのフォーマット変更、返り値 void->BOOL:成功したかどうか返す
WNDCLASS wc;
structClear(wc);
wc.lpfnWndProc = macroMakeWndProc(szWndProc);
if (wc.lpfnWndProc) {
sprintf(strClass,"TX:%ld:%x:%s",wc.lpfnWndProc,(UINT)text->hwndbase,szWndProc);
wc.style = CS_HREDRAW | CS_VREDRAW;
wc.hInstance = text->hInstance;
wc.hIcon = LoadIcon(NULL, IDI_APPLICATION);
wc.hCursor = LoadCursor(NULL, IDC_ARROW);
wc.hbrBackground = (HBRUSH)(COLOR_WINDOW + 1);
wc.lpszClassName = strClass;
if (RegisterClass(&wc)) {
return TRUE;
} else {
macroFreeWndProc(wc.lpfnWndProc);
}
}
return FALSE;
}
void TXAPI wndUnregisterClass(txstr strClass)
{
// 簡易 UnregisterClass
// wndRegisterClassで登録したウィンドウクラスの登録を解除します。
// strClassには、wndRegisterClassに渡したstrClassを渡して下さい。
// thanks dieさん
//2.96A 970211 macroMakeWndProcで確保したリソースを解放するようにした
FARPROC lpfn = atoi(&strClass[3]);
macroFreeWndProc(lpfn);
UnregisterClass(strClass,text->hInstance);
}
#endif
#ifdef __TXC__
__new
{
GetWindowsPlatform();
}
#endif