home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
DOS/V Power Report 1999 March
/
VPR9903A.BIN
/
APUPDATE
/
VC
/
Tx300d
/
TX300D.LZH
/
FILER.C
< prev
next >
Wrap
C/C++ Source or Header
|
1997-10-17
|
93KB
|
3,652 lines
// WZ Filer
// Copyright 1995-97 TY
// Thanks to: y.mikomeさん/dieさん/千葉誠さん/熊谷武さん/m.osakoさん (古株順??)
//2.96 970211 従来のファイラーは、WZの高速オープンによる仕様変更の関係で動作
// しなくなりました。また、度々の改良でプログラムがぐにゅぐにゅなので新しく
// 作り直すことにしました。
//2.96A 970213 ファイラー改良
// アトリビュートの変更、日付の変更をサポート、WZ32での動作の高速化
// 上書きコピー確認 : キャンセル、すべて上書きボタン追加
// ファイルの複製
//2.99D 970401 ファイル|コピー(P) -> コピー(C) VZユーザに使いにくかった
// ファイラーは高速オープンの対象にはしない。
// ファイルオープンダイアログから起動されることもあるから。
#pragma TXE
#include <windows.h>
#include <windowsx.h>
#include "dialog.h"
#include "_filer.h"
// drive
#define IDM_DRIVETOP 100
#define IDM_DRIVEEND 199
// sort
#define IDM_SORTNAME 200
#define IDM_SORTEXT 201
#define IDM_SORTNEW 202
#define IDM_SORTOLD 203
#define IDM_SORTBIG 204
#define IDM_SORTSMALL 205
#define IDM_SORTDIR 206
#define SORT_N 7
// other
#define IDM_CMDLINE 1000
#define WZSC_HISTORYFIRST 2000
// display
permanent BOOL p_fDispToolbar = FALSE; // ツールバーを表示?
permanent BOOL p_fDispFunctionKey = TRUE; // ファンクションキーを表示?
permanent BOOL p_fDispStatusbar = TRUE; // ステータスバーを表示?
permanent BOOL p_fDispGene = FALSE; // 世代履歴ファイルも表示
permanent BOOL p_fDouble = FALSE; // ダブルウィンドウ?
permanent BOOL p_fDoubleH = FALSE; // ダブルウィンドウ:上下分割
permanent BOOL p_fDoubleSize = TRUE; // ダブルウィンドウ:サイズを拡大
permanent int p_rateDouble = 50; // ダブルウィンドウ時のfiler1の幅の比率
// file op.
permanent BOOL p_fConfirmOverwrite = FALSE; // 上書きコピー確認
permanent BOOL p_fConfirmDel = TRUE; // 削除時確認
permanent BOOL p_fConfirmCopy = TRUE; // copy時確認
// path
permanent BOOL p_fLong = defined(__FLAT__); // ロングファイル名モード
permanent txstr p_szBinExt = ".exe .com .lzh .dll"; // バイナリファイルの拡張子
permanent txstr p_szPath1;
permanent txstr p_szPath2;
permanent txstr p_szMask1;
permanent txstr p_szMask2;
// ui
permanent BOOL p_fDirJumpRoot = FALSE; // ディレクトリ移動後、..\へカーソル動かす
permanent BOOL p_fIconize = FALSE; // ファイルオープン/チャイルド操作後、アイコン化
permanent BOOL p_fMenuKey = TRUE; // 英字キー生押しでメニューオープン
permanent BOOL p_fEscClose = FALSE; // [ESC]で閉じる
permanent BOOL p_fSelectMove = FALSE; // スペースでカーソルを移動
//sort
permanent int p_modeSort = 3; // ソートモード
permanent int p_modeSort2 = 0; // ソートモード2
#if 0//3.00A3 970508
permanent int p_filer2modeSort = 3; //2.99B 970322 ダブル側のソートモード
permanent int p_filer2modeSort2 = 0; //2.99B 970322 ダブル側のソートモード2
#endif
// window
permanent BOOL p_fSaveWindowPos = TRUE; // ウィンドウ位置を保存
permanent int p_xWindow = 0; // ウィンドウ位置x
permanent int p_yWindow = 0; // ウィンドウ位置y
permanent int p_cxWindow = 400; // ウィンドウサイズx
permanent int p_cyWindow = 480; // ウィンドウサイズy
// font
permanent BOOL p_lfBold = TRUE; // 太字表示?
permanent txstr p_lfFaceName = "FixedSys"; // フォント名
permanent BYTE p_lfHeight = 10; // ポイント数
// color
permanent COLORREF p_rgbBack = RGB(0xFF,0xFF,0xFF);
permanent COLORREF p_rgbText = RGB(0,0,0);
permanent COLORREF p_rgbBlock = RGB(0xC0,0xDC,0xC0);
permanent COLORREF p_rgbBlockText = RGB(0,0,0);
permanent COLORREF p_rgbBinary = RGB(0x00,0x00,0x80);
permanent COLORREF p_rgbDirectory = RGB(0x00,0x80,0x00);
permanent COLORREF p_rgbReadonly = RGB(0x80,0x80,0x80);
permanent COLORREF p_rgbHidden = RGB(0xC0,0xC0,0xC0);
permanent COLORREF p_rgbSystem = RGB(0x80,0x00,0x80);
//2.99 970318 preview
#define DEFAULT_PREVIEW_RATE 70
static HWND _hwndPreview; //2.99 970317 preview dialog
static HWND _hwndPreviewPartition; //2.99 970318 partition filer,preview
permanent BOOL p_fPreview = TRUE; //2.99 970318
permanent int p_ratePreview = DEFAULT_PREVIEW_RATE;//2.99 970318 プレビュー時のMainWindowの比率
static BOOL _fPreviewDirty; //3.00B1 970613
// 一時設定
static BOOL _fViewMode = FALSE;
static BOOL _fReadOnly = FALSE;
static BOOL _fOpenClose = FALSE; // オープン後閉じる
static BOOL _fEscClose = FALSE;
static HWND _hwndParent = NULL;
static TX* _textFiler; // filer base text
// filer context
typedef struct {
TX* text; // text
// info window
HWND hwndInfo;
int cxInfo; //
int cyInfo; //
// env
mchar szPath[CCHPATHNAME]; // パス
mchar szMask[CCHPATHNAME]; // マスク
// status
int nSel; // 選択されたファイル数
int nSelDir; // 選択されたディレクトリ数
DWORD cbSel; // 選択されたファイルのファイルサイズの合計
DWORD cbDiskFree; // ドライブの空き容量
// sort
int modeSort; // ソートモード
int modeSort2; // ソートモード2
int nDir; // ディレクトリ数
int nFile; // ファイル数
int nDirFile; // ディレクトリ数+ファイル数
} FILER;
static FILER tFiler[2];
static FILER* filer1 = &tFiler[0];
static FILER* filer2 = &tFiler[1];
static HWND _hwndPartition;
static void filerGetCurFilename(FILER *filer,mchar szfilename[CCHFILENAME]);
static void cmdline(mchar* szcmdline,BOOL fMultiOpen);
static void previewFlush(void);
//## text op.
static BYTE* txGetBuffX(TX* text,IBUFF offset)
{
// textの現在行頭から、offsetバイト目のテキストバッファを取得する。
IBUFF cury = text->cury;
if (text->fHigh) {
cury = (IBUFF)(txGetParaTop(text) - text->temp1);
}
IBUFF offsetNow = text->cur0 - cury;
if (offset < offsetNow) {
return &text->buff[text->cury + offset];
} else {
IBUFF d = offset - offsetNow;
if (d >= text->sizebuff - text->cur) {
// EOFを越える場合はNULLを返す。
return NULL;
}
return &text->buff[text->cur + (offset - offsetNow)];
}
}
static int txGetCharX(TX* text,IBUFF offset)
{
// textの現在行頭から、offsetバイト目の文字を取得する。
// 漢字は考慮しない。
BYTE* p = txGetBuffX(text,offset);
if (p) return *p;
return 0;
}
//## 汎用op
static void my_chdir(mchar *szpath)
{
mchar buff[CCHPATHNAME];
strcpy(buff,szpath);
pathForm(buff);
driveSetCurDir(buff[0],buff);
}
//## filer basic
static FILER* filerGetFocus(void)
{
if (filer2->text == textf) return filer2;
return filer1;
}
static FILER* filerGetOther(FILER* filer)
{
if (p_fDouble) {
return (filer == filer1) ? filer2 : filer1;
} else {
return NULL;
}
}
static void filerDoCaption(FILER* filer)
{
BOOL fCd = FALSE;
txstr sz = filer->szPath;
pathSetFileName(sz,NULL);
{//2.98 970307 filer:カレントディレクトリを[]で括って表示
mchar szcd[CCHPATHNAME];
driveGetCurDir(sz[0],szcd);
pathSetDir(szcd);
//statprintf("%s %s %d",sz,szcd,pathCmp(szcd,sz,NULL));wait(500);
if (pathCmp(szcd,sz,NULL) == 0) {
fCd = TRUE;
}
}
sz += filer->szMask;
if (fCd) {
sz = "[" + sz;
sz += "]";
}
SetWindowText(_textFiler->hwndbase,"WZ Filer - " + sz);
}
static void DoCaption(void)
{
filerDoCaption(filerGetFocus());
}
static BOOL filerIsSelected(FILER* filer)
{
return (filer->nSel + filer->nSelDir);
}
static void filerChdir(FILER* filer)
{
// ドライブを変更したときに、以前に表示したパスが表示されるように、
// 現在のszPathをカレントディレクトリにセットするための関数。
// Windowsはプロセス毎にカレントディレクトリが保持されるから、これで良いだろう。
my_chdir(filer->szPath);
DoCaption();
}
//##WinFile
#ifndef __FLAT__
#include "appctrl.h"
static BOOL _fWinFileAlready;
HWND winfileOpen(void)
{
// ファイルマネージャを起動
static mchar szclass[] = "WFS_Frame";
_fWinFileAlready = FALSE;
HWND hwnd = FindWindow(szclass,0);
if (hwnd) { // すでに起動している
_fWinFileAlready = TRUE;
return hwnd;
}
if (WinExec("winfile.exe",SW_HIDE) < 32) return NULL;
// if (WinExec("winfile.exe",SW_SHOW) < 32) return NULL;
hwnd = FindWindow(szclass,0);
return hwnd;
}
void winfileClose(HWND hwnd)
{
if (!_fWinFileAlready) PostMessage(hwnd,WM_CLOSE,0,0);
}
static BOOL WaitWindowOpen(mchar* szcaption,mchar* szcaption2)
{
// szcaptionまたはszcaption2の窓が開くのを待つ。最大3秒待つ
DWORD msWait = 0;
while (1) {
if (apSearchWindow(szcaption)) break;
if (szcaption2 && apSearchWindow(szcaption2)) break;
sleep(100);
msWait += 100;
if (msWait > 3000) return FALSE;
}
return TRUE;
}
static BOOL WaitWindowClose(mchar* szcaption,mchar* szcaption2)
{
// szcaptionの窓が閉じるのを待つ
while (1) {
if (apSearchWindow(szcaption)) {
// Exist
} else if (szcaption2 && apSearchWindow(szcaption2)) {
// Exist
} else {
break;
}
sleep(800);
}
return TRUE;
}
#endif
static BOOL CommandWinFile(mchar* szcaption,WPARAM wParam)
{
#ifdef __FLAT__
return FALSE;
#else
BOOL ret = FALSE;
HWND hwnd = winfileOpen();
if (hwnd) {
sleep(500);
PostMessage(hwnd,WM_COMMAND,wParam,0);
if (WaitWindowOpen(szcaption,NULL)) {
WaitWindowClose(szcaption,NULL);
ret = TRUE;
}
winfileClose(hwnd);
}
return ret;
#endif
}
static BOOL availableWinFile(void)
{
#ifdef __FLAT__
attention("32bit版では実行できません");
return FALSE;
#else
DWORD version = GetVersion();
BYTE major = LOBYTE(LOWORD(version));
BYTE minor = HIBYTE(LOWORD(version));
if (major == 3 && minor <= 11) return TRUE;
attention("この環境では実行できません");
return FALSE;
#endif
}
//FWINDEV のVBの会議室では、複数ディスクの連続フォーマットで監視が落
//ちるので、 GetLastActivePopup を使う必要があるようなことを書いてあっ
//たが、特に必要ないみたい。
DiskFormat
{
// ディスクのフォーマット
if (!availableWinFile()) return FALSE;
return CommandWinFile("フロッピー ディスクのフォーマット",203);
}
DiskCopy
{
// ディスクコピー
if (!availableWinFile()) return FALSE;
return CommandWinFile("フロッピー ディスクのコピー",201);
}
// Windowsの供給元によって関連づけが違うみたい。
Associate
{
// 関連づけ
if (!availableWinFile()) return FALSE;
#ifndef __FLAT__
mchar* szcaption = "関連付けるプログラムの設定";
mchar* szcaption2 = "関連付けるアプリケーションの設定";
HWND hwnd = winfileOpen();
if (hwnd) {
sleep(500);
PostMessage(hwnd,WM_COMMAND,103,0); // 関連づけ
if (WaitWindowOpen(szcaption,szcaption2)) {
mchar szfilename[CCHFILENAME];
filerGetCurFilename(filerGetFocus(),szfilename);
mchar* szext = pathGetExt(szfilename);
if (szext[0] && szext[1]) {
apPostStr(&szext[1]);
}
WaitWindowClose(szcaption,szcaption2);
}
winfileClose(hwnd);
}
#endif
}
//## info window
static txstr _szClassInfo;
static const int cygapInfo = 2;
static void numstrcomma(long num,mchar szstr[20])
{
// numをカンマつきで13桁でszstrに文字列としてセットします
mchar *dst = szstr;
BOOL f = FALSE;
UCHAR c;
dst += 13;
c = num % 10;num /= 10;*--dst = c + '0';f = (!num);
if (!f) {c = num % 10;num /= 10;*--dst = c + '0';f = (!num);} else *--dst = ' ';
if (!f) {c = num % 10;num /= 10;*--dst = c + '0';f = (!num);} else *--dst = ' ';
if (!f) *--dst = ','; else *--dst = ' ';
if (!f) {c = num % 10;num /= 10;*--dst = c + '0';f = (!num);} else *--dst = ' ';
if (!f) {c = num % 10;num /= 10;*--dst = c + '0';f = (!num);} else *--dst = ' ';
if (!f) {c = num % 10;num /= 10;*--dst = c + '0';f = (!num);} else *--dst = ' ';
if (!f) *--dst = ','; else *--dst = ' ';
if (!f) {c = num % 10;num /= 10;*--dst = c + '0';f = (!num);} else *--dst = ' ';
if (!f) {c = num % 10;num /= 10;*--dst = c + '0';f = (!num);} else *--dst = ' ';
if (!f) {c = num % 10;num /= 10;*--dst = c + '0';f = (!num);} else *--dst = ' ';
if (!f) *--dst = ','; else *--dst = ' ';
if (!f) {c = num % 10;num /= 10;*--dst = c + '0';f = (!num);} else *--dst = ' ';
dst += 13;
*dst = 0;
}
static void infoSprint(FILER* filer,mchar szdst[80])
{
mchar szsize[20];
if (filer->nSel + filer->nSelDir) {
numstrcomma(
(filer->cbSel / 1024) + (filer->cbSel % 1024 > 0),
szsize
);
sprintf(szdst," %dfiles %sKB total ",filer->nSel+filer->nSelDir,strGetWordTop(szsize));
} else {
numstrcomma(filer->cbDiskFree / 1024,szsize);
sprintf(szdst," %dfiles %sKB free ",filer->nFile + filer->nDir,strGetWordTop(szsize));
}
}
static int infoGetCy(void)
{
#if 1//2.99B 970322
return systemfontGetCy() + cygapInfo * 2;
#else
TEXTMETRIC tm;
HDC hdc = GetDC(text->hwndbase);
SelectObject(hdc,GetStockObject(GetSystemFontNo()));
GetTextMetrics(hdc,&tm);
ReleaseDC(text->hwndbase,hdc);
// return tm.tmAveCharWidth;//cxSysChar
return tm.tmHeight + cygapInfo * 2;
#endif
}
LRESULT TXCALLBACK wndprocInfo(HWND hwnd,UINT message,WPARAM wParam,LPARAM lParam)
{
switch(message) {
case WM_PAINT: {
RECT r;
GetClientRect(hwnd,&r);
int cx = rectCx(&r);
int cy = rectCy(&r);
//
PAINTSTRUCT ps;
HDC hdc = BeginPaint(hwnd,&ps);
HFONT hfont0 = NULL;
HPEN hpen0 = NULL;
HBRUSH hbrush0 = NULL;
//
FILER *filer = filer1;
if (hwnd == filer2->hwndInfo) filer = filer2;
//
if (_fwin40) {
hpen0 = SelectObject(hdc,text1->hpenBtnFace);
} else {
hpen0 = SelectObject(hdc,text1->hpenWindowFrame);
}
hbrush0 = SelectObject(hdc,text1->hbrushBtnFace);
Rectangle(hdc,-1,-1,cx + 1,cy);
//
hfont0 = SelectObject(hdc,GetStockObject(GetSystemFontNo()));
SetTextColor(hdc,GetSysColor(COLOR_BTNTEXT));
SetBkColor(hdc,GetSysColor(COLOR_BTNFACE));
{
txstr sz;
sz += " ";
sz += filer->szPath;
pathSetFileName(sz,NULL);
sz += filer->szMask;
TextOut(hdc,0,2,sz,strlen(sz));
//
mchar szbuff[80];
infoSprint(filer,szbuff);
SIZE size;
GetTextExtentPoint(hdc,szbuff,strlen(szbuff),&size);
TextOut(hdc,cx - size.cx - 1,cygapInfo,szbuff,strlen(szbuff));
}
if (hfont0) SelectObject(hdc,hfont0);
if (hbrush0) SelectObject(hdc,hbrush0);
if (hpen0) SelectObject(hdc,hpen0);
EndPaint(hwnd,&ps);
return 0;
}
}
return DefWindowProc(hwnd,message,wParam,lParam);
}
static void filerDispInfo(FILER *filer)
{
InvalidateRect(filer->hwndInfo,NULL,FALSE);
SendMessage(filer->hwndInfo,WM_PAINT,0,0);
}
//##fileratr
static FILERATR _fileratr;
#define FILER_OFFSETBASE (FILER_LCXMASK + 1)
#define ID_FILENAME 1
#define ID_FILEEXT 2
#define ID_FILEDATE 3
#define ID_FILESIZE 5
#define ID_FILEDIRECTORY 7
// ファイル名 拡張子 日付 サイズ ディレクトリ
static BOOL _fbacksort[]={0, 0, 0, 1, 0, 1, 0, 1,};
static int _size[] = {0, 8, 3, 14,14, 13,13, 5,};
//
static int _offset[] = {0, 0, 9, 28,28, 13,13, 21,};
static int _offsetsort[]={0, 0, 0, 28,28, 13,13, 21,};
static int _sizesort[]= {0,12, 12, 14,14, 13,13, 5,};
static void fileratrInit(void)
{
_fileratr.fLong = p_fLong;
_fileratr.szexts = p_szBinExt;
if (_fileratr.fLong) {
_fileratr.iFileName = FILER_OFFSETBASE + 28;
_fileratr.lchLine = FILER_LCXMASK + CCHPATHNAME + 32;
_size[ID_FILENAME] = _size[ID_FILEEXT] = CCHPATHNAME;
} else {
_fileratr.iFileName = FILER_OFFSETBASE;
_fileratr.lchLine = FILER_LCXMASK + 44;
_size[ID_FILENAME] = 8;
_size[ID_FILEEXT] = 3;
}
{
_offset[ID_FILENAME] = 0;
if (_fileratr.fLong) {
_offset[ID_FILEDATE] = _offset[ID_FILEDATE+1] = 0;
_offset[ID_FILESIZE] = _offset[ID_FILESIZE+1] = _offset[ID_FILEDATE] + _size[ID_FILEDATE] + 1;
_offset[ID_FILEDIRECTORY] = _offset[ID_FILESIZE] + 8;
_offset[ID_FILEEXT] = _offset[ID_FILENAME] = _offset[ID_FILESIZE] + _size[ID_FILESIZE];
} else {
_offset[ID_FILEEXT] = _size[ID_FILENAME] + 1;
_offset[ID_FILESIZE] = _offset[ID_FILESIZE+1] = _offset[ID_FILEEXT] + _size[ID_FILEEXT] + 1;
_offset[ID_FILEDATE] = _offset[ID_FILEDATE+1] = _offset[ID_FILESIZE] + _size[ID_FILESIZE] + 2;
_offset[ID_FILEDIRECTORY] = _offset[ID_FILESIZE] + 8;
}
//
memcpy(_offsetsort,_offset,sizeof(_offsetsort));
_offsetsort[ID_FILEEXT] = _offsetsort[ID_FILENAME];
//
memcpy(_sizesort,_size,sizeof(_sizesort));
if (!_fileratr.fLong) {
_sizesort[ID_FILEEXT] = _sizesort[ID_FILENAME] = _size[ID_FILENAME] + 1 + _size[ID_FILEEXT];
}
}
#if 0
{
int i;
for (i = ID_FILENAME;i <= ID_FILEDIRECTORY;i++) {
information("%d",_offsetsort[i]);
}
}
#endif
}
//##sort
static mchar* filenameGetExt(mchar* szfilename)
{
// ファイル名から拡張子のポインタを返す。
// 拡張子がなければ、NULLを返す
// 汎用のpathGetExtは遅いので、その代わり
mchar* p0 = NULL;
mchar* p = szfilename;
while(1) {
mchar* p1 = strchr(p,'.');
if (!p1) {
if (p0) return p0;
return p + strlen(p);
}
p0 = p1;
p = p1 + 1;
}
}
// 拡張子でのソート時に、ファイル名でもソートする
// WZ32ではファイル名が小文字で表示されることもあるので、
// 大小文字を区別しないでソートする
int cmpkey(mchar* pstr1,mchar* pstr2,int size,LPARAM lCust)
{
if (_fileratr.fLong) {
mchar* szext1 = filenameGetExt(pstr1);
mchar* szext2 = filenameGetExt(pstr2);
int ret = stricmp(szext1,szext2);
if (ret != 0) return ret;
// ファイル名でソート
// pstr内を書き換えるとまずい
int len1 = szext1 - pstr1;
int len2 = szext2 - pstr2;
int len = len1;
if (len > len2) len = len2;
ret = strnicmp(pstr1,pstr2,len);
if (ret != 0) return ret;
return len1 - len2;
} else {
int ret = strnicmp(
pstr1 + _offset[ID_FILEEXT],
pstr2 + _offset[ID_FILEEXT],
_size[ID_FILEEXT]
);
if (ret != 0) return ret;
return strnicmp(
pstr1,
pstr2,
_size[ID_FILENAME]
);
}
}
//1.00F ソートオプションを2つまで指定できる
int cmpkey2(mchar* pstr1,mchar* pstr2,int size,LPARAM lCust)
{
FILER *filer = (FILER*)lCust;
int ret;
// key1
if (filer->modeSort) {
if (_fileratr.fLong && filer->modeSort == ID_FILEEXT) {
int off = _offset[ID_FILEEXT];
ret = stricmp(filenameGetExt(pstr1+off),filenameGetExt(pstr2+off));
} else {
ret = strnicmp(
pstr1 + _offset[filer->modeSort],
pstr2 + _offset[filer->modeSort],
_size[filer->modeSort]
);
}
if (ret != 0) {
if (_fbacksort[filer->modeSort]) return -ret;//1.00H
return ret;
}
}
// key2
if (_fileratr.fLong && filer->modeSort2 == ID_FILEEXT) {
int off = _offset[ID_FILEEXT];
ret = stricmp(filenameGetExt(pstr1+off),filenameGetExt(pstr2+off));
} else {
ret = strnicmp(
pstr1 + _offset[filer->modeSort2],
pstr2 + _offset[filer->modeSort2],
_size[filer->modeSort2]
);
}
if (_fbacksort[filer->modeSort2]) return -ret;
return ret;
}
static void _filerSort(FILER *filer)
{
// modeSortが変な値のときアプリケーションエラーになる
if (filer->modeSort > SORT_N) filer->modeSort = SORT_N;
if (filer->modeSort2 > SORT_N) filer->modeSort2 = SORT_N;
//
TX* text = filer->text;
int address = txGetAddress(text);
SORTARG arg;
//
text->fUndisp++;
txJumpFileEnd(text);
text->fEditable = TRUE;
//
memset(&arg,0,sizeof(arg));
arg.sizeStruct = sizeof(SORTARG);
arg.lchLine = _fileratr.lchLine;
arg.fNoSenseCase = TRUE;
//
if (filer->nDir) {
txJumpFileTop(text);
if (
txGetCharX(text,_fileratr.iFileName) == '.' &&
txGetCharX(text,_fileratr.iFileName + 1) == '.'//2.99B 970322
) {
// ".."はソートしない
arg.lineTop = 2;
} else {
arg.lineTop = 1;
}
arg.lineEnd = 1 + filer->nDir - 1;
// ディレクトリは必ず名前順でソートする
arg.iItem = FILER_OFFSETBASE + _offsetsort[ID_FILENAME];
arg.lchItem = _sizesort[ID_FILENAME];
arg.fBack = FALSE;
//information("%d %d %d",arg.lchLine,arg.iItem,arg.lchItem);
txSort(text,&arg);
}
arg.lineTop = 1 + filer->nDir;
arg.lineEnd = arg.lineTop + filer->nFile - 1;
if (filer->modeSort2 && filer->modeSort2 != filer->modeSort) {
// ソートオプションを2つ指定できるようにした
arg.iItem = FILER_OFFSETBASE;
arg.lchItem = _fileratr.lchLine ? (_fileratr.lchLine - 1 - arg.iItem) : 0;
arg.fBack = FALSE;
PMACROFUNC pfunc;
macroGetFuncAddress("cmpkey2",&pfunc);
arg.pfuncCmpKey = &pfunc;
arg.lCust = (LPARAM)filer;
txSort(text,&arg);
arg.pfuncCmpKey = NULL;
} else {
arg.iItem = FILER_OFFSETBASE + _offsetsort[filer->modeSort];
arg.lchItem = _sizesort[filer->modeSort];
arg.fBack = _fbacksort[filer->modeSort];
if (filer->modeSort == ID_FILEEXT) {
PMACROFUNC pfunc;
macroGetFuncAddress("cmpkey",&pfunc);
arg.pfuncCmpKey = &pfunc;
txSort(text,&arg);
arg.pfuncCmpKey = NULL;
} else {
txSort(text,&arg);
}
}
//
text->fEditable = FALSE;
text->fUndisp--;
txJumpAddress(text,address);
}
static void filerSort(FILER *filer)
{
tx *text = filer->text;
if (filer->modeSort || filer->modeSort2) {
_filerSort(filer);
txJumpPara(text,filer->nDir + 1);
txSetLy(text,filer->nDir + 1);
}
}
//##load
static void filerClearSel(FILER* filer)
{
filer->nFile = filer->nDir = filer->nSel = filer->nSelDir = 0;
filer->cbSel = 0;
}
static int filerAddPath(FILER* filer,mchar* szpath)
{
// filerのカーソル位置にszpathのファイルを検索して挿入
// 挿入したファイル数を返す。
// カーソル位置は変化しない。
// 表示は更新しない。
int ret = 0;
TX* text = filer->text;
NPARA npara = text->npara;
text->fUndisp++;
txJumpParaTop(text);
text->fEditable = TRUE;
_fileratr.fld = FLD_FILE | FLD_HIDDEN;
ret = _filerLoadDisk(text,szpath,&_fileratr);
if (ret) {
filer->nFile += ret;
filer->nDirFile += ret;
filerSort(filer);
}
txJumpNpara(text,npara);
text->fEditable = FALSE;
txJumpNpara(text,npara);
text->fUndisp--;
filerDispInfo(filer);
return ret;
}
#define FLP_NOMOVE 0
#define FLP_JUMPDIRTOP 1
#define FLP_JUMPFILETOP 2
static void filerLoadPath(FILER* filer,BOOL flpMode)
{
TX* text = filer->text;
BOOL fNeedLoadDir = TRUE;
NPARA npara = text->npara;
int ly = text->ly;
filerClearSel(filer);
text->fEditable = TRUE;
text->fUndisp++;
txDeleteText(text);
{
mchar *p = filer->szMask;
if (!p[0]) p = "*.*";
WORD fld = FLD_NORMAL | FLD_HIDDEN;
if (filer->modeSort) fld = FLD_FILE;
if (!p_fDispGene) fld |= FLD_NOUNDO;
while(*p) {
mchar* p1;
while(1) {
p1 = strchrs(p,"; ");
if (!p1) {
p1 = p + strlen(p);
break;
}
if (p1 != p) break;
p++;
}
mchar szmask[CCHWORD];
if (*p == '.') {
// '*'を追加
szmask[0] = '*';
strcpylenmax(szmask+1,p,p1 - p,cchof(szmask)-1);
} else {
sstrcpylen(szmask,p,p1 - p);
}
p = p1;
//
if (!filer->modeSort && !strcmp(szmask,"*.*")) fNeedLoadDir = FALSE;
pathSetFileName(filer->szPath,szmask);
_fileratr.fld = fld;
//information("%s %s",szmask,filer->szPath);
filer->nFile += _filerLoadDisk(text,filer->szPath,&_fileratr);
}
}
if (_fileratr.fLong) {
// 少なくともiFileName+1まで有功文字を入れておかないと、
// アプリエラーになる。
txInsert(text," 5 (End) ");
} else {
txInsert(text," 5 -------------- <End of Dir> --------------");
}
txJumpFileTop(text);
DoCaption();
//
if (fNeedLoadDir) {
_fileratr.fld = FLD_DIR | FLD_HIDDEN;
if (!p_fDispGene) _fileratr.fld |= FLD_NOUNDO;
filer->nDir = _filerLoadDisk(text,filer->szPath,&_fileratr);
if (flpMode) {
if (filer->nFile == 0 || flpMode == FLP_JUMPDIRTOP) {
txJumpFileTop(text);
} else {
txJumpPara(text,filer->nDir + 1);
}
}
} else {
if (flpMode) {
txJumpFileTop(text);
}
}
filer->nDirFile = filer->nFile + filer->nDir;
filerSort(filer);
//
filer->cbDiskFree = driveGetFree(filer->szPath[0]);
//
if (flpMode == 0) {
txJumpNpara(text,npara);
txSetLy(text,ly);
}
//
text->fUndisp--;
text->fEdit = FALSE;
text->fEditable = FALSE;
txDispAll(text);
filerDispInfo(filer);
previewFlush();//3.00A3 970508 パスを変えたときにプレビューを更新
}
static void filerSetFocus(FILER* filer)
{
SetFocus(filer->text->hwndtext);
}
static void filerInitPath(FILER* filer)
{
// カレントフォルダに初期化
driveGetCurDir(0,filer->szPath);
pathSetDir(filer->szPath);
strcpy(filer->szMask,"*.*");
}
//## path
static void _filerSetPath(FILER* filer,mchar *szpath,BOOL fcd)
{
// fcd:カレントディレクトリを見る?
if (szpath) {
if (pathGetFull(szpath)) {
strcpy(filer->szPath,szpath);
} else {
txstr sz = filer->szPath;
int drive = 0;
if (isalpha(szpath[0]) && szpath[1] == ':') { // ドライブ名付き
drive = szpath[0];
szpath += 2;
}
if (drive == 0 && !fcd) {
pathSetFileName(sz,"");
pathFormDir(sz);
} else {
driveGetCurDir(drive,sz);
pathFormDir(sz);
}
if (szpath[0] == '\\') {
sz[2] = 0;
sz += szpath;
} else {
sz += "\\";
sz += szpath;
}
//
sstrcpy(filer->szPath,sz);
}
if (!strchr(filer->szPath,'*') && !strchr(filer->szPath,'?')) {
if (pathIsDirectory(filer->szPath)) {
txstr sz = filer->szPath;
pathFormDir(sz);
sz += "\\";
sz += filer->szMask;
//
sstrcpy(filer->szPath,sz);
}
}
sstrcpy(filer->szMask,pathGetFileName(filer->szPath));
if (!filer->szMask[0]) strcpy(filer->szMask,"*.*");
#ifndef __FLAT__
if (filer->text->fDispPathLc) {
strlwr(filer->szPath);
strlwr(filer->szMask);
} else {
strupr(filer->szPath);
strupr(filer->szMask);
}
#endif
}
}
static void filerSetPath(FILER* filer,mchar *szpath)
{
mchar *name = pathGetFileName(szpath);
if (name == szpath) { // ファイル名のみ
_filerSetPath(filer,szpath,FALSE);
} else {
_filerSetPath(filer,szpath,TRUE);
}
filerLoadPath(filer,FLP_JUMPFILETOP);
filerDispInfo(filer);
}
static BOOL filerIsCurDirFile(FILER* filer)
{
// ".."の場合はFALSEを返す。
TX* text = filer->text;
// "."で始まるディレクトリは誤動作防止のため、ディレクトリ名とはみなさない
// ".."をディレクトリとみなすと、削除やコピーで、意外なディレクトリを削除したりコピーした。
if (txGetCharX(text,_fileratr.iFileName) == '.') {
#if 1//2.99B 970322 "."で始まるファイルが開けなかった
mchar c = txGetCharX(text,_fileratr.iFileName+1);
if (c == 0) return FALSE;
if (c == '.') {
mchar c = txGetCharX(text,_fileratr.iFileName+2);
if (
c == 0 ||
ispathsepa(c) //3.00A 970502 WZ16 Filerで"..\"を削除できてしまっていた
) return FALSE;
}
#else
return FALSE;
#endif
}
//
return (text->npara <= filer->nDirFile);
}
static BOOL filerIsCurDir(FILER* filer)
{
// ".."の場合もTRUEを返す。
return (txGetCharX(filer->text,FILER_IDIRECTORY) == FATR_DIR);
}
static BOOL filerIsCurFile(FILER* filer)
{
// カーソル位置のファイルがディレクトリでなく、ファイルの場合にTRUEを返す
//2.99 970318 new
return (!filerIsCurDir(filer) && filerIsCurDirFile(filer));
}
static DWORD filerGetCurFileSize(FILER* filer)
{
TX* text = filer->text;
IBUFF off = FILER_OFFSETBASE + _offset[ID_FILESIZE];
int len = _size[ID_FILESIZE];
DWORD ret = 0;
while(len--) {
mchar c = txGetCharX(text,off++);
if (isdigit(c)) {
ret *= 10;
ret += c - '0';
} else {
// 3桁区切り用のカンマ等
}
}
return ret;
}
static void filerMarkAll(FILER* filer,int mode)
{
TX* text = filer->text;
txSetUndispEx(text);
txSetHigh(text);
txJumpFileTop(text);
filer->cbSel = 0;
do {
//statprintf("%d",text->npara);
if (filerIsCurDirFile(filer)) {
if (mode == TXLB_SELECT && filerIsCurDir(filer)) {
// ディレクトリはマークしない
} else {
*txGetBuffX(text,0) = mode;
if (mode == TXLB_SELECT) filer->cbSel += filerGetCurFileSize(filer);
}
}
} while(txNextPara(text));
filer->nSel = filer->nSelDir = 0;
if (mode == TXLB_SELECT) {
filer->nSel = filer->nFile;
}
txResetHigh(text);
txSetDispEx(text);
}
static void _filerCurSelectSet(FILER* filer)
{
// 表示は更新しない
TX* text = filer->text;
if (!filerIsCurDirFile(filer)) return;
BYTE* buff = txGetBuffX(text,0);
if (!buff) return;
if (*buff == TXLB_NORMAL) {
*buff = TXLB_SELECT;
if (filerIsCurDir(filer)) {
filer->nSelDir++;
} else {
filer->cbSel += filerGetCurFileSize(filer);
filer->nSel++;
}
}
}
static void _filerCurSelectClear(FILER* filer)
{
// 表示は更新しない
TX* text = filer->text;
if (!filerIsCurDirFile(filer)) return;
BYTE* buff = txGetBuffX(text,0);
if (!buff) return;
if (*buff == TXLB_SELECT) {
*buff = TXLB_NORMAL;
if (filerIsCurDir(filer)) {
filer->nSelDir--;
} else {
filer->cbSel -= filerGetCurFileSize(filer);
filer->nSel--;
}
}
}
static void _filerCurSelectReverse(FILER* filer)
{
TX* text = filer->text;
if (!filerIsCurDirFile(filer)) return;
if (txGetCharX(text,0) == TXLB_SELECT) {
_filerCurSelectClear(filer);
} else {
_filerCurSelectSet(filer);
}
}
static void filerCurSelectReverse(FILER* filer)
{
// カーソル位置のファイルを選択
// 表示の更新も行う
TX* text = filer->text;
txJumpLineTop(text);
_filerCurSelectReverse(filer);
txDispText(text,text->ly,text->ly);
filerDispInfo(filer);
}
//3.00A 970430 filer.sel復活
sel
{
filerCurSelectReverse(filerGetFocus());
}
static void filerMarkClearAll(FILER* filer)
{
filerMarkAll(filer,TXLB_NORMAL);
filerDispInfo(filer);
}
static void filerMarkSetAll(FILER* filer)
{
filerMarkAll(filer,TXLB_SELECT);
filerDispInfo(filer);
}
//## cmd
// sztop[0]には' ',
// sztop[1]からファイラーのファイル名表示イメージのまま
// 検索文字列を渡して下さい。
static BOOL searchfile(TX* text,mchar *sztop)
{
if (text->fHigh) {
while(1) {
if (!txSearchEx(text,sztop,SEARCH_NOSENSECASE)) return FALSE;
IBUFF lx = txGetAddress(text) - txGetParaTop(text);
if (lx == _fileratr.iFileName - 1) return TRUE;
}
} else {
while(1) {
if (!txSearchEx(text,sztop,SEARCH_NOSENSECASE)) return FALSE;
if (text->lx == _fileratr.iFileName - 1) return TRUE;
}
}
}
compare
{
// フォルダの内容の比較
if (!p_fDouble) {
information("ダブルウィンドウモードで実行してください");
return FALSE;
}
static BOOL fCmpExist = TRUE;
static BOOL fCmpDate = TRUE;
static BOOL fCmpOld = FALSE;
static BOOL fCmpSize = FALSE;
static BOOL fCmpSmall = FALSE;
HDIALOG hd = dialog("ディレクトリの比較");
dialogSetGroupRight(hd,35 * DTCX);
dialogGroup(hd,"存在");
dialogCheck(hd,"存在チェック(&E)",&fCmpExist);
dialogGroupEnd(hd);
dialogGroup(hd,"日付");
dialogCheck(hd,"比較(&D)",&fCmpDate);
dialogRadioIDI(hd,&fCmpOld,"新しい(&N)","古い(&O)");
dialogGroupEnd(hd);
dialogGroup(hd,"サイズ");
dialogCheck(hd,"比較(&F)",&fCmpSize);
dialogRadioIDI(hd,&fCmpSmall,"大きい(&L)","小さい(&S)");
dialogGroupEnd(hd);
if (dialogOpen(hd)) {
BOOL fCmpNew = FALSE;
BOOL fCmpBig = FALSE;
if (fCmpDate) {
fCmpNew = !fCmpOld;
} else {
fCmpOld = FALSE;
}
if (fCmpSize) {
fCmpBig = !fCmpSmall;
} else {
fCmpSmall = FALSE;
}
FILER* filer = filerGetFocus();
FILER* filer2 = filerGetOther(filer);
TX* textf = filer->text; // フォーカスのあるテキスト
TX* textv = filer2->text; // 相手先
txSetUndispEx(textf);
txSetUndispEx(textv);
txSetHigh(textf);
txSetHigh(textv);
filerMarkClearAll(filer);
filerMarkClearAll(filer2);
txJumpFileTop(textf);
do {
if (!filerIsCurDir(filer) && filerIsCurDirFile(filer)) {
mchar *curf = textf->buff + textf->cur + FILER_OFFSETBASE;
mchar buff[CCHFILENAME];
buff[0] = ' ';
if (_fileratr.fLong) {
strcpy(buff+1,curf+_offset[ID_FILENAME]);
} else {
int size = _offset[ID_FILEEXT] + _size[ID_FILEEXT] - _offset[ID_FILENAME];
strcpylen(buff+1,curf+_offset[ID_FILENAME],size);
}
txJumpFileTop(textv);
if (searchfile(textv,buff)) { // 相手先に、存在する
if (fCmpDate || fCmpSize) {// 比較オプションを[存在チェック]のみにした場合も、正しく動作するように
txJumpParaTop(textv);
mchar *curv = textv->buff + textv->cur + FILER_OFFSETBASE;
int cmpnew = memcmp(
curf + _offset[ID_FILEDATE],
curv + _offset[ID_FILEDATE],
_size[ID_FILEDATE]
);
int cmpbig = memcmp(
curf + _offset[ID_FILESIZE],
curv + _offset[ID_FILESIZE],
_size[ID_FILESIZE]
);
if (
(
(!fCmpNew && !fCmpOld) || // 両方指定されてない
(fCmpNew && cmpnew > 0) ||
(fCmpOld && cmpnew < 0)
) &&
(
(!fCmpBig && !fCmpSmall) || // 両方指定されてない
(fCmpBig && cmpbig > 0) ||
(fCmpSmall && cmpbig < 0)
)
) {
_filerCurSelectSet(filer);
}
}
} else {
if (fCmpExist) {
_filerCurSelectSet(filer);
}
}
}
} while(txNextPara(textf));
txResetHigh(textf);
txResetHigh(textv);
txSetDispEx(textf);
txSetDispEx(textv);
filerDispInfo(filer);
filerDispInfo(filer2);
}
return TRUE;
}
sup
{
// 上移動して選択
txUp(text);
filerCurSelectReverse(filerGetFocus());
}
sdown
{
// 選択して下移動
filerCurSelectReverse(filerGetFocus());
txDown(text);
}
SwitchDouble
{
// ダブルウィンドウ/シングルウィンドウ切り替え
HWND hwnd = text->hwndbase;
if (IsZoomed(hwnd) || IsIconic(hwnd)) {
// シングルウィンドウの状態で[最大表示]の時に、おかしな表示にならない様に
ShowWindow(hwnd,SW_SHOWNORMAL);
}
//
p_fDouble ^= 1;
//
RECT r;
GetWindowRect(hwnd,&r);
if (p_fDoubleSize) {
int cx = rectCx(&r);
int cy = rectCy(&r);
if (p_fDouble) {
p_fDoubleH ? (cy *= 2) : (cx *= 2);
} else {
p_fDoubleH ? (cy /= 2) : (cx /= 2);
}
MoveWindow(hwnd,r.left,r.top,cx,cy,TRUE);
}
if (p_fDouble) {
filerLoadPath(filer2,FLP_JUMPFILETOP);
}
SendMessage(text->hwndbase,WM_TXFLUSHWINDOWSIZE,0,0);
if (p_fDouble) {
filerSetFocus(filer2);
} else {
filerSetFocus(filer1);
filerClearSel(filer2);// 選択をクリア
}
previewFlush();//3.00A3 970508 ダブルウィンドウON/OFF時にプレビューを更新
return TRUE;
}
SwitchWindow
{
// ダブルウィンドウ時のウィンドウの切り替え
if (p_fDouble) {
filerSetFocus(filerGetFocus() == filer1 ? filer2 : filer1);
previewFlush();//3.00A3 970508 ダブルウィンドウ時のウィンドウの切り替えでプレビューをフラッシュするようにした
return TRUE;
}
return FALSE;
}
uiAbout
{
ABOUTINFO info;
structClear(info);
info.szicon = "iconWzFiler";
info.szappname = "WZ Filer for Windows";
info.szversion = "version " + VER_WZFILER;
info.szcopyright = "Copyright(c)1995-97 TY";
info.szcopyright2 = "programed by TX-C";
about(&info);
}
uiSetPath
{
// パスの入力
static txstr szpath;
HDIALOG hd = dialog("パス・マスク");
dialogControlHist(hd,HIST_PATH);
dialogStr(hd,"パス・マスク(&P):",szpath,12,40);
if (dialogOpen(hd)) {
if (szpath == "") {
call("menu.FILERパスリスト");
} else {
FILER* filer = filerGetFocus();
filerChdir(filer);
filerSetPath(filer,szpath);
}
}
}
void markClearAll(void)
{
filerMarkClearAll(filerGetFocus());
}
markAll
{
filerMarkSetAll(filerGetFocus());
}
markReverseAll
{
// 選択/非選択入れ替え
FILER* filer = filerGetFocus();
TX* text = filer->text;
txSetUndispEx(text);
txSetHigh(text);
txJumpFileTop(text);
do {
if (filerIsCurDirFile(filer)) {
if (!filerIsCurDir(filer)) _filerCurSelectReverse(filer);
}
} while(txNextPara(text));
txResetHigh(text);
txSetDispEx(text);
filerDispInfo(filer);
}
close
{
txQuit(_textFiler);
}
//## filer cmd
#define CCHARG 32000
static void filerGetCurFilename(FILER *filer,mchar szfilename[CCHFILENAME])
{
// ".."の場合はNULLを返す。
TX* text = filer->text;
if (!filerIsCurDirFile(filer)) {
szfilename[0] = 0;
return;
}
// text->buff direct access
txJumpLineTop(text);
mchar *src = text->buff + text->cur;
src += _fileratr.iFileName;
//
mchar *dst = szfilename;
int len = _size[ID_FILENAME];
if (_fileratr.fLong) {
strcpy(dst,src);
dst += strlen(dst);
if (txGetCharX(text,FILER_IDIRECTORY) == FATR_DIR) {
*dst++ = '\\'; // ディレクトリ記号
}
*dst = 0;
} else {
while(len--) {
mchar c = *src++;
if (c == ' ') {
src += len;
break;
}
*dst++ = c;
}
// "."/"\"の分
if (*src != ' ') *dst++ = *src++;
// 拡張子
len = _size[ID_FILEEXT];
while(len--) {
mchar c = *src++;
if (c == ' ') break;
*dst++ = c;
}
if (*src == '\\') *dst++ = '\\'; // ディレクトリ記号
*dst = 0;
}
// information(szfilename);
}
static void filerGetCurFilenameFull(FILER *filer,mchar szfilename[CCHPATHNAME])
{
mchar sz[CCHFILENAME];
filerGetCurFilename(filer,sz);
strcpy(szfilename,filer->szPath);
pathSetFileName(szfilename,sz);
}
static BOOL filerOpenDir(FILER* filer,mchar *szfilename)
{
TX* text = filer->text;
mchar sz[CCHFILENAME + 2] = {0};
#if 1//2.99F 970404 filerでBSで上のディレクトリに上がったとき、そのディレクトリにカーソルがセットされなかった
if (szfilename[0] == '.' && szfilename[1] == '.' && ispathsepa(szfilename[2]) && szfilename[3] == 0)
#else
if (szfilename[0] == '.' && szfilename[1] == '0'/*2.99B*/)
#endif
{
mchar *szpath = pathGetFileName(filer->szPath);
if (szpath - filer->szPath == 3) {
// ルート
return FALSE;
}
// 親に移動
szpath[-1] = 0;
// [BS]で親ディレクトリに移る際、"11","111"の区別を厳密に
sz[0] = ' ';
strcpy(sz + 1,pathGetFileName(filer->szPath));
if (!_fileratr.fLong) {
strcat(sz,"\\\\");
}
} else {
pathSetFileName(filer->szPath,szfilename);
pathSetDir(filer->szPath);
}
//
txSetUndisp(text);
filerLoadPath(filer,FLP_JUMPDIRTOP);
if (p_fDirJumpRoot) txJumpFileTop(text);
if (sz[0]) {
txJumpFileTop(text);
while(1) {
if (txSearchEx(text,sz,SEARCH_NOSENSECASE)) {
txJumpParaTop(text);
if (_fileratr.fLong) {
//2.00B Filer:親ディレクトリに戻ったときのカーソル位置を改善
mchar szfilename[CCHPATHNAME];
filerGetCurFilename(filer,szfilename);
pathFormDir(szfilename);
if (!stricmp(szfilename,sz + 1)) {
break;
} else {
if (!txDown(text)) break;
}
} else {
break;
}
} else {
break;
}
}
}
txSetDisp(text);
filerDispInfo(filer);
return TRUE;
}
//1.00F ディレクトリが選択されているか、ディレクトリにカーソルがあればTRUEを返す
static BOOL filersIsDirOpen(void)
{
if (filer1->nSelDir || filer2->nSelDir) {
statprintf("ディレクトリが選択されています");
return TRUE;
} else {
FILER* filer = filerGetFocus();
if (filerIsCurDir(filer)) {//1.00H4
mchar szfilename[CCHFILENAME];
#if 1 //3.00A2 970503 3.00AのWZ16 Filerで"..\"をEnterしても何もしなくなった
//3.00A2 970503 WZ Filerで"..\"をEnterしてもフォルダ名に戻らなかった
TXCHAR c1 = txGetCharX(text,_fileratr.iFileName);
TXCHAR c2 = txGetCharX(text,_fileratr.iFileName+1);
TXCHAR c3 = txGetCharX(text,_fileratr.iFileName+2);
if (c1 == '.' && c2 == '.' && (c3 == 0 || ispathsepa(c3))) {
// filerGetCurFilenameで".."は得られないので自前で得る
strcpy(szfilename,"..\\");
} else {
filerGetCurFilename(filer,szfilename);
pathFormDir(szfilename);
}
#else
if (
txGetCharX(text,_fileratr.iFileName) == '.' &&
txGetCharX(text,_fileratr.iFileName+1) == '.' &&//2.99B 970322
txGetCharX(text,_fileratr.iFileName+2) == 0 //2.99B 970322
) {
// filerGetCurFilenameで".."は得られないので自前で得る
strcpy(szfilename,"..");
} else {
filerGetCurFilename(filer,szfilename);
pathFormDir(szfilename);
}
#endif
filerOpenDir(filer,szfilename);
return TRUE;
}
}
return FALSE;
}
static BOOL argCheckSize(mchar* tbuff,mchar* p)
{
if (p - tbuff + CCHPATHNAME > CCHARG) {
attention("ファイル指定が多すぎます");
return FALSE;
}
return TRUE;
}
static int argMake(FILER* filer,mchar* tbuff,mchar *buff,BOOL fDouble,BOOL fShort)
{
// tbuff:バッファ先頭,buff:書き込む位置,fDouble:dstの内容も出力
// 出力したファイル数を返す
// !fLongでも""で囲む。理由:ディレクトリ名に' 'が入っている場合がある
//2.00E 従来末尾に' 'が付いたが付かないようにした
//2.00E4 fShort=TRUEなら、""で括らない。for DOSソフト起動
#if 1///3.00B1 970612 左で選択し、右で開くと左のパスが右のパスになった
mchar szfilename[CCHPATHNAME];
mchar *dst = buff;
int ret = 0;
BOOL fFirst = TRUE;
BOOL fErr = FALSE;//3.00B1 970613 WZ Filerで"ファイル指定が多すぎます"のエラーの後に画面Silentのままになった
for (int i = 0;i < 2;i++) {
TX* text = filer->text;
if (filer->nSel + filer->nSelDir) {
NLINE npara = text->npara;
txSetUndispEx(text);
txJumpFileTop(text);
do {
if (txGetCharX(text,0) == TXLB_SELECT) {
if (!argCheckSize(tbuff,dst)) {
fErr = TRUE;
break;
}
filerGetCurFilenameFull(filer,szfilename);//2.00B ダブルウィンドウでの%src2がおかしかった
if (!fShort) *dst++ = '"';
strcpy(dst,szfilename);
dst += strlen(szfilename);
if (!fShort) *dst++ = '"';
*dst++ = ' ';
ret++;
}
} while(txNextPara(text));
txJumpPara(text,npara);
txSetDispEx(text);
} else {
if (filerIsCurDirFile(filer)) {
if (!argCheckSize(tbuff,dst)) {
fErr = TRUE;
break;
}
filerGetCurFilenameFull(filer,szfilename);//2.00B ダブルウィンドウでの%src2がおかしかった
if (!fShort) *dst++ = '"';
strcpy(dst,szfilename);
dst += strlen(szfilename);
if (!fShort) *dst++ = '"';
*dst++ = ' ';//2.00B
ret++;
}
}
if (!fDouble) break;
filer = filerGetOther(filer);
if (!filer) break;
if (!(filer->nSel + filer->nSelDir)) break;// 選択されてなければ止め
}
if (fErr) {
*buff = 0;
return 0;
}
if (ret) dst--;//2.00E 末尾の' 'を取る
*dst = 0;
return ret;
#else
mchar szfullname[CCHPATHNAME];
if (fShort) {
strcpy(szfullname,"");
} else {
strcpy(szfullname,"\"");
}
strcat(szfullname,filer->szPath);
mchar *szfilename = pathGetFileName(szfullname);
mchar *dst = buff;
int ret = 0;
BOOL fFirst = TRUE;
for (int i = 0;i < 2;i++) {
TX* text = filer->text;
if (filer->nSel + filer->nSelDir) {
NLINE npara = text->npara;
txSetUndispEx(text);
txJumpFileTop(text);
do {
if (txGetCharX(text,0) == TXLB_SELECT) {
if (!argCheckSize(tbuff,dst)) return 0;
filerGetCurFilename(filer,szfilename);//2.00B ダブルウィンドウでの%src2がおかしかった
strcpy(dst,szfullname);
dst += strlen(szfullname);
if (!fShort) *dst++ = '"';
*dst++ = ' ';
ret++;
}
} while(txNextPara(text));
txJumpPara(text,npara);
txSetDispEx(text);
} else {
if (filerIsCurDirFile(filer)) {
if (!argCheckSize(tbuff,dst)) return 0;
filerGetCurFilename(filer,szfilename);//2.00B ダブルウィンドウでの%src2がおかしかった
strcpy(dst,szfullname);
dst += strlen(szfullname);
if (!fShort) *dst++ = '"';
*dst++ = ' ';//2.00B
ret++;
}
}
if (!fDouble) break;
filer = filerGetOther(filer);
if (!filer) break;
if (!(filer->nSel + filer->nSelDir)) break;// 選択されてなければ止め
}
if (ret) dst--;//2.00E 末尾の' 'を取る
*dst = 0;
return ret;
#endif
}
// ファイラーコマンドライン
static int _cmdfiler(mchar *szcmdline,mchar* tbuff)
{
FILER* filer = filerGetFocus();
TX* text = filer->text;
BOOL fShort = FALSE;
mchar szdstfilename[CCHPATHNAME] = {0};
mchar *dst = tbuff;
mchar *p = szcmdline;
mchar szfind[CCHFILENAME] = {0};
BOOL ret = TRUE;
BOOL flushsrc = FALSE;
BOOL flushdst = FALSE;
int nFile = 0;
if (
strisid(szcmdline,"open") ||
strisid(szcmdline,"view") ||
strisid(szcmdline,"winopen")
) {
if (filersIsDirOpen()) return 1;
}
//1.99H カーソルlyを保存
int ly = text->ly;
if (ret) {
while(1) {
p = strGetWordTop(p);
if (!*p) break;
int len = strGetWordLen(p);
mchar c = p[len];
p[len] = 0;
//
if (!argCheckSize(tbuff,dst)) {
ret = FALSE;
break;
}
//
if (p[0] == '/' || p[0] == '-') {//1.00C スイッチ指定中の"%"に対応
mchar *pp;
if (pp = strchr(p,'%')) {
int l = pp - p;
strncpy(dst,p,l);
dst += l;
//
p = pp;
len -= l;
}
}
if (p[0] == '%') {
if (!strcmp(p,"%srcpath")) {//3.00B1 970522 %srcpathはWZ32では""で括る様にした
#ifdef __FLAT__//3.00B1 970522 WZ32 FilerからWZ Grepを起動すると空白を含むパスが途切れた
*dst++ = '"';
#endif
strcpy(dst,filer->szPath);
pathSetFileName(dst,NULL);
dst += strlen(dst);
mchar *src = filer->szMask;
if (*src == '.') *dst++ = '*';
while(1) {
if (*src == ';' && src[1] == '.') {
*dst++ = ';';
*dst++ = '*';
*dst++ = '.';
src += 2;
} else if (*src) {
*dst++ = *src++;
} else {
break;
}
}
#ifdef __FLAT__//3.00B1 970522
*dst++ = '"';
#endif
} else if (!strcmp(p,"%-o")) { //1.00F
if (p_fConfirmOverwrite) {
strcpy(dst,"-o");dst += strlen(dst);
}
} else if (!strcmp(p,"%-s")) {
//2.00E4 filer.fcmdの引数に" %-s "を指定すると、DOSソフト起動のためにファイル名を""で括らない様にした
fShort = TRUE;
} else if (!strcmp(p,"%*")) {//1.00F
flushsrc = TRUE;
flushdst = TRUE;
} else if (!strcmp(p,"%*src")) {//1.00F
flushsrc = TRUE;
} else if (!strcmp(p,"%*dst")) {//1.00F
flushdst = TRUE;
// 以下、可変長コマンド。
// 可変長コマンドは誤動作防止のため、最後に持ってくる。
} else if (!strncmp(p,"%src",4)) {//可変長
nFile = argMake(filer,tbuff,dst,(strchr(p,'2') != NULL),fShort);
//information(tbuff);
if (!nFile) {
ret = FALSE;
break;
} else {
dst += strlen(dst);
if (strchr(p,'1')) {
if (filer->nSel + filer->nSelDir) {
attention("選択中は実行できません");
ret = FALSE;
break;
}
}
}
} else if (!strncmp(p,"%dst",4)) {//可変長
FILER *filer2 = filerGetOther(filer);
if (filer2) {
strcpy(szdstfilename,filer2->szPath);
pathSetFileName(szdstfilename,NULL);
} else {
mchar *szcaption = p + 4;
while(1) {
HDIALOG hd = dialog(szcaption);
dialogStrC(hd,(szcaption)+"先:",szdstfilename,strlen(szcaption)+4,cchof(szdstfilename),30);
if (dialogOpen(hd)) {
if (!szdstfilename[0]) {
attention((szcaption)+"先を指定してください");
continue;
}
if (!pathGetFull(szdstfilename)) {
// 絶対パスに変換
txstr sz = szdstfilename;
strcpy(szdstfilename,filer->szPath);
pathSetFileName(szdstfilename,sz);
}
} else {
ret = FALSE;
}
break;
}
}
// !fLongでも""で囲む。理由:ディレクトリ名に' 'が入っている場合がある
*dst++ = '"';
strcpy(dst,szdstfilename);dst += strlen(dst);
*dst++ = '"';
} else if (!strncmp(p,"%input",6)) {//可変長
mchar *szcaption = p + 6;
BOOL fnew = FALSE;
if (!strncmp(szcaption,"new",3)) {
fnew = TRUE;
szcaption += 3;
}
HDIALOG hd = dialog(szcaption);
mchar szfullname[CCHPATHNAME];
mchar szfilename[CCHFILENAME];
int width = CCHFILENAME;
#ifdef __FLAT__
width = 40;
#endif
if (fnew) {
szfilename[0] = 0;
} else {
filerGetCurFilename(filer,szfilename);
}
dialogStrC(hd,szcaption+":",szfilename,strlen(szcaption)+2,width);
if (dialogOpen(hd)) {
strcpy(szfullname,filer->szPath);
pathSetFileName(szfullname,szfilename);
} else {
ret = FALSE;
break;
}
// !fLongでも""で囲む。理由:ディレクトリ名に' 'が入っている場合がある
*dst++ = '"';
strcpy(dst,szfullname);dst += strlen(dst);
*dst++ = '"';
strcpy(szfind,pathGetFileName(szfullname));
}
*dst++ = ' ';
} else {
strcpy(dst,p);
dst += len;
*dst++ = ' ';
}
//
p[len] = c;
p += len;
}
*dst = 0;
}
//information(tbuff);
if (strisid(tbuff,"del") && p_fConfirmDel && ret) {
if (question("%d 個のファイルを削除します。よろしいですか?",nFile) != IDYES) ret = FALSE;
}
if (strisid(tbuff,"mcopy") && p_fConfirmCopy && ret) {
if (question("%d 個のファイルを %s にコピーします。よろしいですか?",nFile,szdstfilename) != IDYES) ret = FALSE;
}
if (strisid(tbuff,"mmove") && p_fConfirmCopy && ret) {
if (question("%d 個のファイルを移動します。よろしいですか?",nFile) != IDYES) ret = FALSE;
}
txSetUndisp(text);
if (ret) {
ret = cmd(tbuff);
if (flushsrc) filerLoadPath(filer,0);
if (flushdst) {
FILER* filer2 = filerGetOther(filer);
if (filer2) filerLoadPath(filer2,0);
}
if (szfind[0]) {
mchar *pext;
txJumpFileTop(text);
if (!_fileratr.fLong) {
if (pext = strchr(szfind,'.')) {
// 拡張子を正規化
mchar buff[CCHFILENAME];
*pext = 0;
sprintf(buff,"%-8s.%s",szfind,pext+1);
strcpy(szfind,buff);
}
}
txSearchEx(text,szfind,SEARCH_NOSENSECASE);
}
}
if (text->npara < text->lcywindow) {
// 先頭行からカーソルまでの行が全て表示できるのに
// スクロール表示されて先頭行が見えないことがあった
txSetLy(text,text->npara);
} else {
txSetLy(text,ly);
}
txSetDisp(text);
return ret;
}
// マーク情報を使ったマルチコマンドが可能になるように
// _cmdfilerとmarkClearAllに分割した
int cmdfiler(mchar *szcmdline)
{
mchar* szWork = malloc(CCHARG);
if (!szWork) {
attention("メモリが足りません");
return 0;
}
int ret = _cmdfiler(szcmdline,szWork);
free(szWork);
if (ret) {
filerMarkClearAll(filer1);
filerMarkClearAll(filer2);
}
return ret;
}
static void cmdOpenFilesSuccess(void)
{
_fReadOnly = FALSE;
if (p_fIconize) ShowWindow(text->hwndbase,SW_MINIMIZE);
if (_fOpenClose) {
#if 1//2.99 970319 ファイルの挿入からファイラーを起動してファイルを選択するとアプリエラーになった
PostMessage(_textFiler->hwndbase,WM_TXQUIT,0,0);
#else
txQuit(_textFiler);
#endif
}
}
static mchar* argCreate(void)
{
mchar* buff = memAlloc(CCHARG);
if (buff) {
mchar *p = buff;
if (!argMake(filerGetFocus(),buff,p,TRUE,FALSE)) {//3.00A 970429 NULL->FALSE
memFree(buff);
return NULL;
}
return buff;
} else {
attention("メモリが不足しています");
}
return NULL;
}
static int cmdOpenFiles(mchar* szcmdstd)
{
if (filersIsDirOpen()) return 1;
int ret = 0;
if (_hwndParent) {
// vzuiInsertFileで複数ファイルを挿入できるように
// ファイル名は必ず""で括られる
mchar* szcmd = argCreate();
if (szcmd) {
wndtxSendStr(_hwndParent,WM_TXFILERSELECTED,0,szcmd);
memFree(szcmd);
_hwndParent = NULL;
DoCaption();
cmdOpenFilesSuccess();
}
return 0;
}
if (_fViewMode) {
if (ret = cmdfiler("view %src2")) cmdOpenFilesSuccess();
} else if (_fReadOnly) {
if (ret = cmdfiler("openread %src2")) cmdOpenFilesSuccess();
} else {
if (ret = cmdfiler(szcmdstd)) cmdOpenFilesSuccess();
}
return ret;
}
openfiles
{
// WZでオープン
cmdOpenFiles("open %src2");
}
openfileswin
{
// 関連付けされたアプリケーションでオープン
cmdOpenFiles("winopen %src2");
}
back
{
// 一つ上のディレクトリに移動
filerOpenDir(filerGetFocus(),\"..\");
}
BOOL TXCMD mask(mchar* szmask)
{
FILER* filer = filerGetFocus();
filerChdir(filer);
if (!strcmp(szmask,".")) {// マスク"."対応
filerSetPath(filer,wzGetEnv(WZENV_EXT));
} else {
filerSetPath(filer,szmask);
}
return TRUE;
}
windowFlush
{
// ファイルリストの更新
FILER* filer = filerGetFocus();
filerLoadPath(filer,0);
FILER* filer2 = filerGetOther(filer);
if (filer2) filerLoadPath(filer2,0);
}
//## op filer
#define OPFILER_SETATR 0
#define OPFILER_SETDATE 1
#define OPFILER_DUPLICATE 2
static BOOL opFilerExec(FILER* filer,mchar* szfilename,int op,DWORD arg)
{
switch(op) {
case OPFILER_SETATR: {
WORD atr = (WORD)arg;
if (!fileAtr(szfilename,&atr,TRUE)) {
return TRUE;
} else {
information("%s\nアトリビュートの設定に失敗しました。",szfilename);
return FALSE;
}
break;
}
case OPFILER_SETDATE: {
HFILE hfile = hfileOpenWrite(szfilename);
if (hfile != HFILE_ERROR) {
hfileSetDate(hfile,arg);
hfileClose(hfile);
return TRUE;
} else {
information("%s\n日付の設定に失敗しました。",szfilename);
return FALSE;
}
break;
}
case OPFILER_DUPLICATE: {
mchar szdstname[CCHPATHNAME];
strcpy(szdstname,szfilename);
mchar szsrcname[CCHPATHNAME];
strcpy(szsrcname,szdstname);
mchar szext[CCHPATHNAME];
{
mchar* p = pathGetExt(szdstname);
strcpy(szext,p);
*p = 0;
}
mchar* p = pathGetFileName(szdstname);
int lchFilename = strlen(p);
mchar* dst = p + lchFilename;
#ifndef __FLAT__
if (lchFilename >= 8) dst--;
#endif
for (int i = 0;i < 10 + 26;i++) {
mchar* q = dst;
*q++ = i < 10 ? i + '0' : i - 10 + 'A';
strcpy(q,szext);
//information(szdstname);
if (!fileIsExist(szdstname)) {
if (fileCopy(szsrcname,szdstname)) {
_filerCurSelectClear(filer);
//
TX* text = filer->text;
int n = filerAddPath(filer,szdstname);
if (n) {
_filerCurSelectSet(filer);
txNextPara(text);
}
txDispTextAll(text);
return TRUE;
}
break;
}
}
information("%s の複製を作成できません",szsrcname);
return FALSE;
}
}
}
static int opFiler(int op,DWORD arg)
{
FILER* filer = filerGetFocus();
BOOL fErr = FALSE;
int ret = 0;
for (int i = 0;i < 2;i++) {
TX* text = filer->text;
if (filer->nSel + filer->nSelDir) {
NLINE npara = text->npara;
txSetUndispEx(text);
txJumpFileTop(text);
do {
if (txGetCharX(text,0) == TXLB_SELECT) {
mchar szfilename[CCHPATHNAME];
filerGetCurFilenameFull(filer,szfilename);
if (opFilerExec(filer,szfilename,op,arg)) {
ret++;
} else {
fErr = TRUE;
break;
}
}
} while(txNextPara(text));
txJumpPara(text,npara);
txSetDispEx(text);
} else {
if (filerIsCurDirFile(filer)) {
mchar szfilename[CCHPATHNAME];
filerGetCurFilenameFull(filer,szfilename);
if (opFilerExec(filer,szfilename,op,arg)) {
ret++;
} else {
fErr = TRUE;
break;
}
}
}
//
if (op == OPFILER_DUPLICATE) {
filerDispInfo(filer);
} else {
filerLoadPath(filer,0);
}
if (fErr) break;
filer = filerGetOther(filer);
if (!filer) break;
if (!filerIsSelected(filer)) break;// 選択されてなければ止め
}
return ret;
}
static void tmFromDosfiletime(TM* tm,DOSFILETIME dft)
{
WORD time = LOWORD(dft);
WORD date = HIWORD(dft);
tm->tm_sec = (time & 0x1F) * 2;
tm->tm_min = (time >> 5) & 0x3F;
tm->tm_hour = (time >> 11) & 0x1F;
tm->tm_mday = (date & 0x1F);
tm->tm_mon = ((date >> 5) & 0x0F) - 1;
tm->tm_year = ((date >> 9) & 0x7F) + 80;
}
static DOSFILETIME tmToDosfiletime(TM* tm)
{
WORD time = 0;
WORD date = 0;
time |= (tm->tm_sec) / 2;
time |= tm->tm_min << 5;
time |= tm->tm_hour << 11;
date |= tm->tm_mday;
date |= (tm->tm_mon + 1) << 5;
date |= (tm->tm_year - 80) << 9;
return MAKELONG(time,date);
}
duplicate
{
return opFiler(OPFILER_DUPLICATE,0);
FILER* filer = filerGetFocus();
mchar szfilename[CCHPATHNAME];
filerGetCurFilenameFull(filer,szfilename);
opFilerExec(filer,szfilename,OPFILER_DUPLICATE,0);
}
uiDate
{
BOOL ret = FALSE;
FILER* filer = filerGetFocus();
mchar szfilename[CCHPATHNAME];
filerGetCurFilenameFull(filer,szfilename);
HFILE hfile = hfileOpen(szfilename);
DOSFILETIME dft = 0;
if (hfile != HFILE_ERROR) {
dft = hfileGetDate(hfile);
hfileClose(hfile);
}
if (dft) {
TM tm;
tmFromDosfiletime(&tm,dft);
tm.tm_year += 1900;
tm.tm_mon++;
//
HDIALOG hd = dialog("ファイルの日付");
dialogSetH(hd);
dialogIntI(hd,"日付(&D):",&tm.tm_year,10,5);
dialogIntI(hd,"/",&tm.tm_mon,1,3);
dialogIntI(hd,"/",&tm.tm_mday,1,3);
dialogLF(hd);
dialogIntI(hd,"時刻(&T):",&tm.tm_hour,12,3);
dialogIntI(hd,":",&tm.tm_min,1,3);
dialogIntI(hd,":",&tm.tm_sec,1,3);
if (dialogOpen(hd)) {
if (tm.tm_year >= 1900) tm.tm_year -= 1900;
tm.tm_mon--;
DOSFILETIME dft = tmToDosfiletime(&tm);
ret = opFiler(OPFILER_SETDATE,dft);
}
}
return ret;
}
uiAtr
{
BOOL ret = FALSE;
FILER* filer = filerGetFocus();
mchar szfilename[CCHPATHNAME];
filerGetCurFilenameFull(filer,szfilename);
WORD atr;
if (!fileAtr(szfilename,&atr,FALSE)) {
BOOL fReadOnly = ((atr & FA_RDONLY) != 0);
BOOL fHidden = ((atr & FA_HIDDEN) != 0);
BOOL fSystem = ((atr & FA_SYSTEM) != 0);
HDIALOG hd = dialog("ファイルのアトリビュート");
dialogCheck(hd,"書き込み不可(&R)",&fReadOnly);
dialogCheck(hd,"隠しファイル(&H)",&fHidden);
dialogCheck(hd,"システムファイル(&S)",&fSystem);
if (dialogOpen(hd)) {
atr &= ~(FA_RDONLY|FA_HIDDEN|FA_SYSTEM);
if (fReadOnly) atr |= FA_RDONLY;
if (fHidden) atr |= FA_HIDDEN;
if (fSystem) atr |= FA_SYSTEM;
ret = opFiler(OPFILER_SETATR,atr);
}
}
return ret;
}
//## mouse interface
static NPARA _nparamouse = 0;
MouseL
{
FILER* filer = filerGetFocus();
if (filer->nSelDir + filer->nSel) markClearAll();
_nparamouse = 0;
}
MouseL2
{
POINT pointcur;
GetCursorPos(&pointcur);
sleep(100);
openfiles();
SetCursorPos(pointcur.x,pointcur.y);
}
MouseLS
{
FILER* filer = filerGetFocus();
TX* text = filer->text;
if (_nparamouse == 0) _nparamouse = text->npara;
int nparatop;
int nparaend;
if (_nparamouse <= text->npara) {
nparatop = _nparamouse;
nparaend = text->npara;
} else {
nparatop = text->npara;
nparaend = _nparamouse;
}
txSetUndispEx(text);
markClearAll();
for (NPARA i = nparatop;i <= nparaend;i++) {
txJumpPara(text,i);
_filerCurSelectReverse(filer);
}
txSetDispEx(text);
filerDispInfo(filer);
}
//## help
static void WinHelpFiler(UINT fuCommand,DWORD dwData)
{
helpContext("wz",IDH_FILER);
}
uiHelp
{
// ヘルプ(目次)
WinHelpFiler(HELP_CONTENTS,0L);
}
uiHelpKeyword
{
// ヘルプ(キーワード)
WinHelpFiler(HELP_PARTIALKEY,(LPARAM)"");
}
help
{
uiHelp();
}
//## sort cmds
static void filerFlushSortMenu(FILER* filer)
{
HMENU hmenu = GetSubMenu(GetMenu(_textFiler->hwndbase),2);
BOOL _fCheck = FALSE;
int idm;
for (idm = IDM_SORTNAME;idm <= IDM_SORTDIR;idm++) {
BOOL fCheck = (
(idm == IDM_SORTNAME + filer->modeSort - 1) &&
(filer->modeSort2 == 0 || filer->modeSort2 == filer->modeSort)
);
CheckMenuItem(
hmenu,
idm,
fCheck ? MF_CHECKED : MF_UNCHECKED
);
if (fCheck) _fCheck = TRUE;
}
{
static int idm;
if (idm == 0) idm = IDM_WZCMDTOP + wzcmdRegister("\m.uiSortEx");
BOOL fCheck = !_fCheck;
if (filer->modeSort == 0 && filer->modeSort2 == 0) fCheck = FALSE;
CheckMenuItem(
hmenu,
idm,
MF_BYCOMMAND|(fCheck ? MF_CHECKED : MF_UNCHECKED)
);
}
}
static int filerDeleteDir(FILER* filer)
{
// ディレクトリをfiler->textから消すする
// 消した数を返す
TX* text = filer->text;
int ndelete = 0;
txJumpFileTop(text);
txSetHigh(text);
while(1) {
if (text->buff[text->cur + FILER_IDIRECTORY] == FATR_DIR) {
txDeletePara(text);
ndelete++;
} else {
if (!txNextPara(text)) break;
}
}
txResetHigh(text);
return ndelete;
}
static void filerSortInit(FILER *filer)
{
#if 1
//3.00A3 970508 ソートメニューでソート方法を変更しても永久記憶しないようにし、Filerを起動すると設定ダイアログで設定したソート方法で表示するようにした(WZ2の仕様に合わせた)
#else
//2.99B 970322 filer:ソートが永久記憶されなかった
if (filer == filer2) {
p_filer2modeSort = filer->modeSort;
p_filer2modeSort2 = filer->modeSort2;
} else {
p_modeSort = filer->modeSort;
p_modeSort2 = filer->modeSort2;
}
#endif
//
if (filer->modeSort || filer->modeSort2) {
TX* text = filer->text;
txSetUndisp(text);
text->fEditable = TRUE;
filer->nFile = filer->nDirFile - filerDeleteDir(filer);
txJumpFileTop(text);
_fileratr.fld = FLD_DIR | FLD_HIDDEN;
if (!p_fDispGene) _fileratr.fld |= FLD_NOUNDO;
filer->nDir = _filerLoadDisk(text,filer->szPath,&_fileratr);
filer->nDirFile = filer->nDir + filer->nFile;
filerSort(filer);
txSetDisp(text);
text->fEditable = FALSE;
} else {
filerLoadPath(filer,FLP_JUMPFILETOP);
}
}
static void sortSet(int id)
{
FILER* filer = filerGetFocus();
id = id - IDM_SORTNAME + 1;
if (filer->modeSort == id && filer->modeSort2 == 0) {
filer->modeSort = 0;
} else {
filer->modeSort = id;
filer->modeSort2 = 0;
}
filerSortInit(filer);
filerFlushSortMenu(filer);
}
static void dialogAddSort(HDIALOG hd,mchar* szcaption,int* data,int wcaption,int wtext)
{
dialogSelectID(hd,szcaption,data,wcaption,wtext,
"ソートしない","ファイル名","拡張子","新しい順",
"古い順","大きい順","小さい順","ディレクトリ"
);
}
uiSortEx
{
// 高度なソート
FILER* filer = filerGetFocus();
HDIALOG hd = dialog("高度なソート");
dialogAddSort(hd,"ソート&1:",&filer->modeSort,10,16);
dialogAddSort(hd,"ソート&2:",&filer->modeSort2,10,16);
if (dialogOpen(hd)) {
filerSortInit(filer);
filerFlushSortMenu(filer);
}
}
sortName
{
//ファイル名順
sortSet(IDM_SORTNAME);
}
sortExt
{
//拡張子順
sortSet(IDM_SORTEXT);
}
sortNew
{
//新しい順
sortSet(IDM_SORTNEW);
}
sortOld
{
//古い順
sortSet(IDM_SORTOLD);
}
sortBig
{
//大きい順
sortSet(IDM_SORTBIG);
}
sortSmall
{
//小さい順
sortSet(IDM_SORTSMALL);
}
sortDirectory
{
//ディレクトリ
sortSet(IDM_SORTDIR);
}
pathCur
{
// カレンドフォルダを表示
FILER* filer = filerGetFocus();
filerInitPath(filer);
filerLoadPath(filer,FLP_JUMPFILETOP);
}
pathSetCur
{
// 現在表示しているフォルダをカレントフォルダに設定
filerChdir(filerGetFocus());
}
SwitchView
{
// ビューモードオープン/通常オープン切り替え
FILER* filer = filerGetFocus();
_fViewMode ^= 1;
DoCaption();
statprintf(_fViewMode ? "View mode" : "Edit mode");
}
minimize
{
// アイコン化
ShowWindow(_textFiler->hwndbase,SW_MINIMIZE);
}
keyDelete
{
// Deleteキー割り当てコマンド(ユーザインターフェース)
// ユーザインターフェースの設定によって動作が変わります
if (_textFiler->modeEditor == ME_VZ) {
markClearAll();
} else {
// 削除
cmdfiler("del %src %*");
}
}
keyEsc
{
// ESCキー割り当てコマンド
FILER* filer = filerGetFocus();
if (filerIsSelected(filer)) {
filerMarkClearAll(filer);
return TRUE;
}
if (p_fIconize) {
// オープンしたらアイコン化 に連動
minimize();
} else if (p_fEscClose || _fEscClose) {
txQuit(_textFiler);
} else {
txuiOpen(text);
}
}
//## config
static void txSetFilerColor(TX* text)
{
text->rgbBack = p_rgbBack;
text->rgbText = p_rgbText;
text->rgbBlock = p_rgbBlock;
text->rgbBlockText = p_rgbBlockText;
text->rgbComment = p_rgbBinary;
text->rgbString = p_rgbDirectory;
text->rgbConst = p_rgbReadonly;
text->rgbErrorChar = p_rgbHidden;
text->rgbPreprocessor = p_rgbSystem;
}
static void txSetFilerFontstyle(TX* text)
{
FONTSTYLE* fs = text->tFontstyle + FONTTX_TEXT;
fs->tlfHeight[IFONT_STD] = p_lfHeight;
strcpy(fs->tlfFaceName[IFONT_STD],p_lfFaceName);
text->lfBold = p_lfBold;
}
static void txSetFilerDisp(TX* text)
{
text->fDispToolbar = p_fDispToolbar;
text->fDispFunctionKey = p_fDispFunctionKey;
text->fDispStatusbar = p_fDispStatusbar;
}
static void filerSetModesort(FILER* filer)
{
#if 1//3.00A3 970508 ソートの設定がfiler2に効いてなかった
filer->modeSort = p_modeSort;
filer->modeSort2 = p_modeSort2;
#else
if (filer == filer2) {
filer->modeSort = p_filer2modeSort;
filer->modeSort2 = p_filer2modeSort2;
} else {
filer->modeSort = p_modeSort;
filer->modeSort2 = p_modeSort2;
}
#endif
}
static int _iPageConfig = 0;
BOOL dlgprocConfig(HWND hwnd,UINT message,WPARAM wParam,LPARAM lParam)
{
switch(message) {
case WM_TXDIALOGPAGECHANGED: {
_iPageConfig = wParam;
break;
}
}
return FALSE;
}
uiConfig
{
// 設定
HDIALOG hd0 = dialogbig("WZ Filerの設定");
dialogSetHookEx(hd0,"\m.dlgprocConfig");
dialogSetStartPage(hd0,_iPageConfig);
HDIALOG hd = dialog("ウィンドウ");
dialogControlGuide(hd,"文字",6);
dialogCheck(hd,"位置とサイズを保存(&P)",&p_fSaveWindowPos);
dialogCheck(hd,"ファイルオープン後、アイコン化(&I)",&p_fIconize);
dialogCheck(hd,"ツールバー(&T)",&p_fDispToolbar);
dialogCheck(hd,"ファンクションキー(&F)",&p_fDispFunctionKey);
dialogCheck(hd,"ステータスバー(&A)",&p_fDispStatusbar);
dialogCheck(hd,"ダブルウィンドウを、上下に表示(&H)",&p_fDoubleH);
dialogCheck(hd,"ダブルウィンドウ時、サイズを拡大(&E)",&p_fDoubleSize);
dialogAddPage(hd0,hd);
HDIALOG hd = dialog("ユーザインターフェース");
dialogCheck(hd,"コピー前に確認(&C)",&p_fConfirmCopy);
dialogCheck(hd,"削除前に確認(&D)",&p_fConfirmDel);
dialogCheck(hd,"上書きコピー前に確認(&O)",&p_fConfirmOverwrite);
dialogCheck(hd,"英字キーでメニューオープン(&M)",&p_fMenuKey);
dialogCheck(hd,"{Esc}キーですぐ閉じる(&E)",&p_fEscClose);
dialogCheck(hd,"スペース選択でカーソルを移動する(&L)",&p_fSelectMove);
dialogCheck(hd,\"ディレクトリ移動後、..\へカーソル動かす(&T)",&p_fDirJumpRoot);
dialogAddPage(hd0,hd);
HDIALOG hd = dialog("表示");
dialogCheck(hd,"WZ Editorの世代履歴ファイルも表示(&G)",&p_fDispGene);
#ifdef __FLAT__
dialogCheck(hd,"ロングファイル名で表示(&L)",&p_fLong);
#else
//3.00A4 970509 WZ16 Filer 「ロングファイル名で表示」->「ファイル名を右側に表示」
dialogCheck(hd,"ファイル名を右側に表示(&L)",&p_fLong);
#endif
dialogSetH(hd);
dialogCheck(hd,"太字で表示(&B)",&p_lfBold);
{
dialogLF(hd);
SELFONTARG arg;
memset(&arg,0,sizeof(arg));
arg.lfPitch = FIXED_PITCH;
arg.lfCharSet = DEFAULT_CHARSET;
dialogSelectFont(hd,"フォント(&F):",14,p_lfFaceName,&p_lfHeight,&arg);
}
dialogLF(hd);
dialogSetV(hd);
dialogStrC(hd,"バイナリファイルの拡張子(&E):",p_szBinExt,22,CCHPATHNAME,18);
dialogAddSort(hd,"ソート(&S):",&p_modeSort,14,16);
dialogAddSort(hd,"ソート2(&T):",&p_modeSort2,14,16);
dialogAddPage(hd0,hd);
HDIALOG hd = dialog("色");
dialogSetH(hd);
dialogColor(hd,"通常ファイル(&T)...","通常ファイルの色",&p_rgbText,15,NULL);
dialogColor(hd,"背景(&B)...","通常ファイルの背景",&p_rgbBack,11,NULL);
dialogLF(hd);
dialogColor(hd,"選択ファイル(&S)...","選択ファイルの色",&p_rgbBlockText,15,NULL);
dialogColor(hd,"背景(&C)...","選択ファイルの背景",&p_rgbBlock,11,NULL);
dialogSetV(hd);
dialogLF(hd);
dialogColor(hd,"バイナリファイル(&I)...","バイナリファイルの色",&p_rgbBinary,27,NULL);
dialogColor(hd,"ディレクトリ(&D)...","ディレクトリの色",&p_rgbDirectory,27,NULL);
dialogColor(hd,"リードオンリーファイル(&R)...","リードオンリーファイルの色",&p_rgbReadonly,27,NULL);
dialogColor(hd,"隠しファイル(&H)...","隠しファイルの色",&p_rgbHidden,27,NULL);
dialogColor(hd,"システムファイル(&F)...","システムファイルの色",&p_rgbSystem,27,NULL);
dialogAddPage(hd0,hd);
if (dialogOpen(hd0)) {
fileratrInit();
txSetFilerColor(filer1->text);
txSetFilerColor(filer2->text);
txSetFilerFontstyle(filer1->text);
txSetFilerFontstyle(filer2->text);
txSetFilerDisp(filer1->text);
txSetFilerDisp(filer2->text);
txSetFilerDisp(_textFiler);
filerSetModesort(filer1);
filerSetModesort(filer2);
filerLoadPath(filer1,0);
txFlush(filer1->text);
if (p_fDouble) {
filerLoadPath(filer2,0);
txFlush(filer2->text);
}
filerFlushSortMenu(filerGetFocus());
//
txFlushUI(filer1->text);
txFlush(_textFiler); //2.99D 970331 ツールバーを非表示から表示に設定するとゴミが出た
}
}
//##preview
//2.99 970318
static void previewClose(void)
{
if (_hwndPreview) {
DestroyWindow(_hwndPreview);
_hwndPreview = NULL;
if (_hwndPreviewPartition) {
DestroyWindow(_hwndPreviewPartition);
_hwndPreviewPartition = NULL;
}
//
filer1->text->txnMask = 0;
filer2->text->txnMask = 0;
SendMessage(_textFiler->hwndbase,WM_TXFLUSHWINDOWSIZE,0,0);
}
}
preview
{
if (_hwndPreview) {
previewClose();
p_fPreview = FALSE;
} else {
_hwndPreview = CreateWindowEx(
#ifdef __FLAT__
(_fwin40 * WS_EX_CLIENTEDGE),
#else
0,
#endif
TXWS_SZCLASS,
NULL,
TXWS_TEXT|WS_VSCROLL|WS_CHILD|WS_VISIBLE|WS_TABSTOP,
CW_USEDEFAULT,CW_USEDEFAULT,
CW_USEDEFAULT,CW_USEDEFAULT,
_textFiler->hwndbase,
NULL,
_textFiler->hInstance,
NULL
);
if (_hwndPreview) {
_hwndPreviewPartition = CreateWindow(
TXPARTITION_SZCLASS,NULL,
WS_CHILDWINDOW | WS_VISIBLE,
CW_USEDEFAULT,CW_USEDEFAULT,
CW_USEDEFAULT,CW_USEDEFAULT,
_textFiler->hwndbase,
NULL,
_textFiler->hInstance,
NULL
);
//
TX* text = (LPVOID)SendMessage(_hwndPreview,TXWM_GETTX,0,0);
text->hwndbase = _textFiler->hwndbase;
text->txnMask = TXNM_CONTROLTAB|TXNM_CONTROLF4;
txOpenText(text);
//
filer1->text->txnMask = TXNM_CHANGENPARA|TXNM_CONTROLTAB;
filer2->text->txnMask = TXNM_CHANGENPARA|TXNM_CONTROLTAB;
SendMessage(_textFiler->hwndbase,WM_TXFLUSHWINDOWSIZE,0,0);
p_fPreview = TRUE;
}
}
}
//## API
//3.00A 970502 filerGetLine,filerGetFilename,filerGetTitle復活
int TXAPI filerGetLine(txstr str)
{
// ファイラーのカレント表示行の内容をstrに取得
//{#RET}取得したバイト数を返す
//2.00Bで新設
int ret = txGetLine(text,str);
strcpy(str,&str[FILER_LCXMASK]);
ret -= FILER_LCXMASK;
return ret;
}
int TXAPI filerGetLineEx(txstr str)
{
// ファイラーのカレント表示行の内容をstrに取得
// ファイル名を先頭として取得
//{#RET}取得したバイト数を返す
//3.00C1 971017 new
int ret = txGetLine(text,str);
{
mchar* pFilename = &str[_fileratr.iFileName];
int len = _size[ID_FILENAME];
memcpy(pFilename,pFilename + len,strlen(pFilename + len) + 1);
}
{
mchar szfilename[CCHFILENAME];
filerGetCurFilename(filerGetFocus(),szfilename);
str = szfilename + &str[FILER_LCXMASK];
}
return strlen(str);
}
int TXAPI filerGetFilename(txstr str)
{
// ファイラーのカレント表示行のファイル名をstrに取得
//{#RET}取得できたかどうかを返す
//2.00Bで新設
mchar szfilename[CCHFILENAME];
filerGetCurFilename(filerGetFocus(),szfilename);
str = szfilename;
return TRUE;
}
int TXAPI filerGetTitle(txstr str)
{
// ファイラーのファイル一覧ウィンドウのタイトルをstrに返す
FILER* filer = filerGetFocus();
strcpy(str,filer->szPath);
pathSetFileName(str,filer->szMask);
mchar buff[80];
infoSprint(filer,buff);
str += " ";
str += buff;
return TRUE;
}
//## init
static void txSetFilerUI(TX* text)
{
strcpy(text->szToolbar,"txe_filer");
strcpy(text->szKey,"txe_filer");
strcpy(text->szMenu,"bartxe_FILER");
//3.00B1 970612 filerでメニューキーでコンテキストメニューが開く様にした
sstrcpy(text->szMenuMouseR,"menu.FILERファイル");
sstrcpy(text->szMenuMouseRClip,"menu.FILERファイル");
}
static void txSetFilerStatusbar(TX* text)
{
//3.00A3 970508 new
text->fDispPrekey = TRUE;
text->fDispPrekeyLeft = FALSE;
text->fDispLocate = FALSE;
text->fDispSelecting = FALSE;
text->fDispEdit = FALSE;
text->fDispPagingMode = FALSE;
text->fDispSL_RSPACE = FALSE;
text->fDispOverwrite = FALSE;
text->fDispParaCharatr = FALSE;
text->fDispEditmode = FALSE;
text->fDispInlineform = FALSE;
}
static void filerNewText(FILER* filer)
{
HWND hwndtext = CreateWindowEx(
#ifdef __FLAT__
(_fwin40 * WS_EX_CLIENTEDGE),
#else
0,
#endif
TXWS_SZCLASS,
NULL,
WS_CHILDWINDOW|WS_VISIBLE|TXWS_TEXT,
CW_USEDEFAULT,CW_USEDEFAULT,
CW_USEDEFAULT,CW_USEDEFAULT,
_textFiler->hwndbase,
NULL,
_textFiler->hInstance,
NULL
);
if (hwndtext) {
TX* text = (LPVOID)SendMessage(hwndtext,TXWM_GETTX,0,0);
filer->text = text;
text->hwndbase = _textFiler->hwndbase;
#if 0//2.99B 970322 これくらいの初期化は自動化された
text->width = MAXWIDTH;
text->fSpaceLeft = FALSE;
text->fDispSearch = FALSE;
text->fDispEof = FALSE;
text->fDispLf = FALSE;
text->fDispLocate = FALSE;
text->fDispJspace = FALSE;
text->fDispLine = FALSE;
text->fDispParse = FALSE;
text->fDispControlSpace = TRUE;
text->fLineD = FALSE;
text->fBackup = FALSE;
text->fSetWidthByWindow = FALSE;
text->fScrollBarH = FALSE;
text->fScrollBarV = TRUE;
text->fMouseArrow = TRUE;
text->modeImeSetFocus = ISF_OFF;
text->fVertical = FALSE;
text->fPageTurn = FALSE;
text->fConfigBinedit = FALSE;
text->fConfigInlineform = FALSE;//2.98 970310
text->lfWestern = FALSE;
#endif
text->lfProp = FALSE;
text->fSetLocateByMouseFocus = TRUE;//2.99C 970324 foo.cを選択し、別の窓をアクティブにし、bar.cをダブルクリックするとfoo.cが開いた
text->searchmode = SEARCH_NOSENSECASE;
text->fDispControlSpace = TRUE;
text->fDispUnder = TRUE;
text->lcxmask = FILER_LCXMASK;
text->fListbox = TRUE;
text->fTempMem = 1;// WZ32でロングファイルネーム使用時のソートを高速化する
text->fUseMenuKey = TRUE;//2.99 970319
txSetFilerColor(text);
txSetFilerFontstyle(text);
txSetFilerUI(text);
txSetFilerStatusbar(text);//3.00A3 970508
//
txOpenText(text);
}
//
filer->hwndInfo = CreateWindow(
_szClassInfo,NULL,
WS_CHILDWINDOW | WS_VISIBLE,
CW_USEDEFAULT, CW_USEDEFAULT,
CW_USEDEFAULT, CW_USEDEFAULT,
_textFiler->hwndbase,
NULL,
_textFiler->hInstance,
NULL
);
}
HOOKRESULT __wndproctext(HWND hwnd,UINT message,WPARAM wParam,LPARAM lParam)
{
TX* text = textTarget;
if (text != filer1->text && text != filer2->text) return FALSE;
switch(message) {
case WM_CHAR: {
FILER* filer = filerGetFocus();
TX* text = filer->text;
BOOL fshift = (GetKeyState(VK_SHIFT) < 0);
static mchar *szkana = "チコソシイハキクニマノリモミラセタストカナヒテサンツ";
if (iskana(wParam)) {
mchar *p = strchr(szkana,wParam);
if (p) {
int ch = (p - szkana) + 'A';
WZKEY wzkey = txWzkeyFromSzkey(text,chartostr(ch));
if (wzkey) {
WZCMD wzcmd = txKeyGetWzcmd(text,wzkey);
if (wzcmd) SendMessage(text->hwndbase,WM_COMMAND,IDM_WZCMDTOP + wzcmd,0);
}
return HOOK_CAPTURE;
}
}
if (
(!p_fMenuKey && !fshift) ||
(p_fMenuKey && fshift)
) {
if (isalpha(wParam)) {
NPARA npara = text->npara;// 先頭文字検索で見つからなかったとき、カーソルを移動しないように
int ly = text->ly;
mchar buff[3];
buff[0] = ' ';
buff[1] = toupper(wParam);
buff[2] = 0;
txSetUndisp(text);
txJumpParaEnd(text);
if (!searchfile(text,buff)) {
txJumpFileTop(text);
if (!searchfile(text,buff)) txJumpPara(text,npara);
}
txJumpParaTop(text);
txSetLy(text,ly);
txSetDisp(text);
previewFlush();//3.00B1 970613 WZ Filer:Shift+英字でもファイルプレビューを更新
return HOOK_CAPTURE;
}
}
switch(wParam) {
case '*': {
strcpy(filer->szMask,"*.*");
filerLoadPath(filer,FLP_JUMPFILETOP);
return HOOK_CAPTURE;
}
case '/':
case '\\': {
// root
filer->szPath[3] = 0;
filerLoadPath(filer,FLP_JUMPFILETOP);
return HOOK_CAPTURE;
}
case '.': {
// マスクメニューで[Q]を選択するとアプリエラーにならない様に
strcpymax(filer->szMask,wzGetEnv(WZENV_EXT),CCHPATHNAME / 2);
filerLoadPath(filer,FLP_JUMPFILETOP);
return HOOK_CAPTURE;
}
case '0': {
pathCur();
return HOOK_CAPTURE;
}
case ':': {
call("menu.FILERドライブ");
return HOOK_CAPTURE;
}
case ' ': {
if (p_fSelectMove) {//1.00C
fshift ? sup() : sdown();
} else {
filerCurSelectReverse(filer);
}
return HOOK_CAPTURE;
}
case '@': {
call("menu.FILERパスリスト");
return HOOK_CAPTURE;
}
}
if (isdigit(wParam) && wParam != '0') {
SendMessage(text->hwndbase,WM_COMMAND,IDM_DRIVETOP + wParam - '1',0);
return HOOK_CAPTURE;
}
break;
}
case WM_SETFOCUS: {
FILER* filer = (hwnd == filer1->text->hwndtext) ? filer1 : filer2;
filerFlushSortMenu(filer);
filerDispInfo(filer);
filerDoCaption(filer);
PostMessage(hwnd,WM_TXUSER,0,0);
break;
}
case WM_TXUSER: {
// for フォーカス切り替え時の、fListboxの描画フラッシュ
txDispAll(text);
break;
}
case WM_KEYUP: {//3.00B1 970613
if (_fPreviewDirty) {
previewFlush();
}
break;
}
}
return HOOK_CONTINUE;
}
//##menu
static int menuChange(HMENU hmenu,int _idm)
{
int n = GetMenuItemCount(hmenu);
int i;
for (i = 0;i < n;i++) {
int idm = GetMenuItemID(hmenu,i);
if (idm == _idm) {
DeleteMenu(hmenu,i,MF_BYPOSITION);
return i;
}
}
return -1;
}
static void driveMenu(HMENU hmenu,int imenu,BOOL fDriveMenu)
{
mchar idrive;
#ifdef __FLAT__
static mchar szpath[] = " :\\";
#endif
for (idrive = 0;idrive < 26;idrive++) {
#ifdef __FLAT__
static mchar *tsztype[] = {
"不明","","フロッピーディスク","固定ディスク","ネットワーク","CD-ROM","RAMディスク","??",
};
szpath[0] = 'A' + idrive;
int type = GetDriveType(szpath);
if (type > DRIVE_RAMDISK) type = DRIVE_RAMDISK + 1;//tsztypeでサポートしていないtype
if (type == 1) continue;
#else
static mchar *tsztype[] = {
"","ROMディスク","フロッピーディスク","固定ディスク","CD-ROM,ネットワーク",
};
int type = GetDriveType(idrive);
if (type == 0) continue;
#endif
{
int id = IDM_DRIVETOP + idrive;
mchar buff[100];
if (fDriveMenu) {
sprintf(buff,"&%c:\t%s",'A' + idrive,tsztype[type]);
} else {
sprintf(buff,"%c: (%s)",'A' + idrive,tsztype[type]);
}
InsertMenu(hmenu,imenu++,MF_STRING|MF_BYPOSITION,id,buff);
}
}
}
static void jumpMenu(HMENU hmenu,int iposition)
{
int n = histGetCount(HIST_PATH);
if (n == 0) {
InsertMenu(hmenu,iposition++,MF_STRING|MF_BYPOSITION,-1,"パスヒストリは空です");
} else {
#define JUMP_N 20
int i = JUMP_N;
while(i--) {
if (n == 0) break;
//
mchar szpath[CCHPATHNAME];
strcpy(szpath,histRead(HIST_PATH,--n));
if (pathIsWild(szpath)) {
pathForm(szpath);
}
//
mchar *p;
if (pathFormDir(szpath)) {
p = szpath;
} else {
p = pathGetFileName(szpath);
}
int c = toupper(p[0]);
strcpy(szpath,histRead(HIST_PATH,n));
if (pathGetFileName(szpath) == szpath) {//1.00F filer.uiJump:マスクも表示できるようにした
c = toupper(szpath[0]);
if (!isalpha(c)) {
mchar* szext = pathGetExt(szpath);
if (szext[0] && szext[1] && isalpha(szext[1])) {
c = toupper(szext[1]);
} else {
c = ' ';
}
}
} else {
if (pathIsWild(szpath)) {
pathForm(szpath);
}
}
{
int idm = IDM_WZCMDTOP + wzcmdRegister("filer.mask(["+szpath+"])");
txstr sz = "&" + chartostr(c) + "\t" + szpath;
InsertMenu(hmenu,iposition++,MF_STRING|MF_BYPOSITION,idm,sz);
}
}
}
}
static void previewFlush(void)
{
//3.00A3 970508 new
_fPreviewDirty = FALSE;
if (_hwndPreview) {
FILER* filer = filerGetFocus();
mchar szfilename[CCHPATHNAME] = {0};
if (filerIsCurFile(filer)) {
filerGetCurFilenameFull(filer,szfilename);
}
//
extern "event" void at_pf(HWND hctrl,mchar* szfilename,int mode);
at_pf(_hwndPreview,szfilename,1);
}
}
static void myPostMessage(HWND hwnd,int message,WPARAM wParam,LPARAM lParam)
{
MSG msg;
if (PeekMessage(&msg,hwnd,message,message,PM_NOREMOVE)) {
// 既にポストされている場合は、ポストしない
} else {
PostMessage(hwnd,message,wParam,lParam);
}
}
static void previewFlushWithoutKeyRepeat(HWND hwnd)
{
//3.00B1 970613 ファイラーのファイルプレビューでキーリピート中は更新しないようにした
if (
(GetAsyncKeyState(VK_UP) < 0) ||
(GetAsyncKeyState(VK_DOWN) < 0) ||
(GetAsyncKeyState(VK_CONTROL) < 0)
) {
_fPreviewDirty = TRUE;
} else {
previewFlush();
}
}
HOOKRESULT __wndprocbase(HWND hwnd,UINT message,WPARAM wParam,LPARAM lParam)
{
if (textTarget != _textFiler) return FALSE;
switch(message) {
case WM_SYSCOMMAND: {
UINT uID = (UINT)wParam;
if ((uID >= WZSC_HISTORYFIRST) &&
(uID < WZSC_HISTORYFIRST + text->nDispFileHist)) {
uID -= WZSC_HISTORYFIRST;
txOpenForkFast(
text,
histRead(HIST_FILE, histGetCount(HIST_FILE) - uID - 1));
}
break;
}
case WM_COMMAND: {
if (
(_hwndPartition && WM_COMMAND_GetHwndCtrl(wParam,lParam) == _hwndPartition) ||
(_hwndPreviewPartition && WM_COMMAND_GetHwndCtrl(wParam,lParam) == _hwndPreviewPartition)
) {
SendMessage(hwnd,WM_TXFLUSHWINDOWSIZE,0,0);
return TRUE;
}
FILER* filer = filerGetFocus();
int id = LOWORD(wParam);
if (IDM_DRIVETOP <= id && id <= IDM_DRIVEEND) {
mchar buff[CCHPATHNAME];
UCHAR cDrive = id - IDM_DRIVETOP + 'A';
if (driveGetCurDir(cDrive,buff)) {
filerChdir(filer);
strcpy(filer->szPath,buff);
pathSetDir(filer->szPath);
filerLoadPath(filer,FLP_JUMPFILETOP);
} else {
attention("ドライブの指定が違います\n");
}
return HOOK_CAPTURE;
}
if (IDM_SORTNAME <= id && id <= IDM_SORTDIR) {
sortSet(id);
return HOOK_CAPTURE;
}
if (id == IDM_CMDLINE) {
WNDTX_RECEIVE_MEM_ENTER
cmdline((mchar*)lParam,TRUE);
WNDTX_RECEIVE_MEM_EXIT
return HOOK_CAPTURE;
}
return HOOK_CONTINUE;
}
case WM_INITMENUPOPUP: {
FILER* filer = filerGetFocus();
HMENU hmenu = (HMENU)wParam;
// サブメニューを生成させるため、先にWZオリジナルの処理をする
SendMessage(hwnd,WM_TXINITMENU,(WPARAM)hmenu,0);
//
static int tidmSort[SORT_N];
static int idmDrive;
static int idmDriveMenu;
static int idmJump;
static int idmViewMode;
if (tidmSort[0] == 0) {
mchar* tsz[SORT_N] = {
"sortName",
"sortExt",
"sortNew",
"sortOld",
"sortBig",
"sortSmall",
"sortDirectory",
};
int i;
for (i = 0;i < SORT_N;i++) {
tidmSort[i] = IDM_WZCMDTOP + wzcmdRegister("\m." + tsz[i]);
}
//
idmDrive = IDM_WZCMDTOP + wzcmdRegister("\m.driveList");
idmDriveMenu = IDM_WZCMDTOP + wzcmdRegister("\m.driveListMenu");
idmJump = IDM_WZCMDTOP + wzcmdRegister("\m.jumpList");
idmViewMode = IDM_WZCMDTOP + wzcmdRegister("\m.SwitchView");
}
// drive(メニュー内)
{
int i = menuChange(hmenu,idmDrive);
if (i >= 0) driveMenu(hmenu,i,FALSE);
}
// drive menu(独立したメニュー)
{
int i = menuChange(hmenu,idmDriveMenu);
if (i >= 0) driveMenu(hmenu,i,TRUE);
}
// jump
{
int i = menuChange(hmenu,idmJump);
if (i >= 0) jumpMenu(hmenu,i);
}
// sort
{
int n = GetMenuItemCount(hmenu);
int i;
for (i = 0;i < n;i++) {
int idm = GetMenuItemID(hmenu,i);
//information("%d",idm);
int i;
for (i = 0;i < SORT_N;i++) {
if (idm == tidmSort[i]) {
BOOL fcheck = (
(i == filer->modeSort - 1) &&
(filer->modeSort2 == 0 || filer->modeSort2 == filer->modeSort)
);
CheckMenuItem(hmenu,idm,fcheck ? MF_CHECKED : MF_UNCHECKED);
break;
}
}
if (idm == idmDrive) {
InsertMenu(hmenu,i++,MF_STRING|MF_BYPOSITION,1,"aa");
InsertMenu(hmenu,i++,MF_STRING|MF_BYPOSITION,1,"aa");
InsertMenu(hmenu,i++,MF_STRING|MF_BYPOSITION,1,"aa");
}
if (idm == idmViewMode) {
CheckMenuItem(hmenu,idm,_fViewMode ? MF_CHECKED : MF_UNCHECKED);
}
}
}
return HOOK_CAPTURE;
}
case WM_TXNOTIFY: {//2.99 970317
if (lParam == TXN_CHANGENPARA) {
#if 1//3.00A3 970508
#if 1//3.00B1 970613
previewFlushWithoutKeyRepeat(hwnd);
#else
previewFlush();
#endif
#else
if (_hwndPreview) {
FILER* filer = filerGetFocus();
mchar szfilename[CCHPATHNAME] = {0};
if (filerIsCurFile(filer)) {
filerGetCurFilenameFull(filer,szfilename);
}
//
extern "event" void at_pf(HWND hctrl,mchar* szfilename,int mode);
at_pf(_hwndPreview,szfilename,1);
}
#endif
} else if (lParam == TXN_CONTROLTAB) {
#if 1//3.00A3 970508 WZ FIler:Ctrl+Tabでプレビューと切り替えられる様にした
FILER* filer = filerGetFocus();
static BOOL fFocus2;
if (wParam == _hwndPreview) {
if (fFocus2 && p_fDouble) {
SetFocus(filer2->text->hwndtext);
} else {
SetFocus(filer1->text->hwndtext);
}
macroHookWndBaseReturn(TRUE);
return HOOK_CAPTURE;
} else if (wParam == filer->text->hwndtext) {
fFocus2 = (filer == filer2);
SetFocus(_hwndPreview);
macroHookWndBaseReturn(TRUE);
return HOOK_CAPTURE;
}
#else
if (wParam == _hwndPreview) {
SetFocus(_textFiler->hwndtext);
macroHookWndBaseReturn(TRUE);
return HOOK_CAPTURE;
} else if (wParam == _textFiler->hwndtext) {
SetFocus(_hwndPreview);
macroHookWndBaseReturn(TRUE);
return HOOK_CAPTURE;
}
#endif
} else if (lParam == TXN_CONTROLF4) {
if (wParam == _hwndPreview) {
previewClose();
macroHookWndBaseReturn(TRUE);
return HOOK_CAPTURE;
}
}
break;
}
case WM_TXWINDOWSIZE: {
RECT* r0 = (RECT*)lParam;
if (_hwndPreview) {//2.99 970318
int cx = rectCx(r0);
int cy = rectCy(r0);
//
int rate = p_ratePreview;
if (_hwndPreviewPartition) {
rate = SendMessage(_hwndPreviewPartition,WMPB_GETRATE,0,0);
if (rate < 0) {
SendMessage(_hwndPreviewPartition,WMPB_SETRATE,rate = p_ratePreview,0);
}
SendMessage(_hwndPreviewPartition,WMPB_SETRANGE,r0->top,r0->bottom);
}
if (rate < 10 || rate > 90) rate = DEFAULT_PREVIEW_RATE;
p_ratePreview = rate;
//
int cyPreview = (cy * (100-rate)) / 100;
r0->bottom -= cyPreview;
int y = r0->bottom;
MoveWindow(_hwndPreviewPartition,r0->left,y,cx,5,TRUE);
y += 5;
cyPreview -= 5;
MoveWindow(_hwndPreview,r0->left,y,cx,cyPreview,TRUE);
}
RECT r = *r0;
int cyInfo = infoGetCy();
int cx = rectCx(&r);
int cy = rectCy(&r);
int y = r.top;
int x = r.left;
if (p_fDouble) {
int rate = p_rateDouble;
if (_hwndPartition) {
rate = SendMessage(_hwndPartition,WMPB_GETRATE,0,0);
if (rate < 0) {
SendMessage(_hwndPartition,WMPB_SETRATE,rate = p_rateDouble,0);
}
#if 1//2.99 970318 特に上下に分割でツールバー等を表示してるとずれた
if (p_fDoubleH) {
SendMessage(_hwndPartition,WMPB_SETRANGE,r.top,r.bottom);
} else {
SendMessage(_hwndPartition,WMPB_SETRANGE,r.left,r.right);
}
#else
if (p_fDoubleH) {
SendMessage(_hwndPartition,WMPB_SETRANGE,0,cy);
} else {
SendMessage(_hwndPartition,WMPB_SETRANGE,0,cx);
}
#endif
}
if (rate < 10 || rate > 90) rate = 50;
p_rateDouble = rate;
//
if (p_fDoubleH) {
int cy1 = (long)cy * rate / 100;
MoveWindow(filer1->hwndInfo,x,y,cx,cyInfo,TRUE);y += cyInfo;cy1 -= cyInfo;
MoveWindow(filer1->text->hwndtext,x,y,cx,cy1,TRUE);y += cy1;
//
MoveWindow(_hwndPartition,x,y,cx,5,TRUE);y += 5;
//
MoveWindow(filer2->hwndInfo,x,y,cx,cyInfo,TRUE);y += cyInfo;
MoveWindow(filer2->text->hwndtext,x,y,cx,r.bottom - y,TRUE);
} else {
int cxPartition = 5;
int cx1 = (long)cx * rate / 100;
MoveWindow(filer1->hwndInfo,x,y,cx1,cyInfo,TRUE);y += cyInfo;
MoveWindow(filer1->text->hwndtext,x,y,cx1,r.bottom - y,TRUE);
x += cx1;
//
MoveWindow(_hwndPartition,x,r.top,cxPartition,rectCy(&r),TRUE);
x += cxPartition;
//
int cx2 = r.right - x;
y = r.top;
MoveWindow(filer2->hwndInfo,x,y,cx2,cyInfo,TRUE);y += cyInfo;
MoveWindow(filer2->text->hwndtext,x,y,cx2,r.bottom - y,TRUE);
}
} else {
MoveWindow(filer1->hwndInfo,r.left,y,cx,cyInfo,TRUE);y += cyInfo;
MoveWindow(filer1->text->hwndtext,r.left,y,cx,r.bottom - y,TRUE);
//
if (_hwndPartition) MoveWindow(_hwndPartition,-1,-1,0,0,FALSE);
MoveWindow(filer2->hwndInfo,-1,-1,0,0,FALSE);
MoveWindow(filer2->text->hwndtext,-1,-1,0,0,FALSE);
}
return TRUE;
}
case WM_SETFOCUS: {
if (_textFiler->hwndLastFocus == filer2->text->hwndtext) {
filerSetFocus(filer2);
} else {
filerSetFocus(filer1);
}
return TRUE;
}
case WM_SIZE://1.01A
case WM_MOVE: {
#if 1//3.00A3 970508 95のタスクバーを左においているとWZ Filerのウィンドウ位置がずれた。
if (p_fSaveWindowPos) {
RECT r;
GetWindowRect(hwnd,&r);
if (!IsIconic(hwnd) && !IsZoomed(hwnd)) {
p_xWindow = r.left;
p_yWindow = r.top;
p_cxWindow = rectCx(&r);
p_cyWindow = rectCy(&r);
}
}
#else
if (p_fSaveWindowPos) {
// ファイラーをアイコン化して終了しても、
// アイコン化する前の位置に保存されるようにGetWindowPlacementを使う。
WINDOWPLACEMENT wplace;
wplace.length = sizeof(WINDOWPLACEMENT);
GetWindowPlacement(hwnd,(LPWINDOWPLACEMENT)&wplace);
RECT* r = &wplace.rcNormalPosition;
p_xWindow = r->left;
p_yWindow = r->top;
p_cxWindow = rectCx(r);
p_cyWindow = rectCy(r);
}
#endif
break;
}
case WM_TXCLOSE: {//2.99 970318
previewClose();
break;
}
}
return FALSE;
}
static void cmdline(mchar* szcmdline,BOOL fMultiOpen)
{
// fMultiOpen:ファイラーが起動されててvzuiOpenなどでファイラーを起動した場合、
// ファイラーを終了しない。
// init
_fOpenClose = FALSE;
_fReadOnly = FALSE;
// analyze
mchar*p = szcmdline;
while(1) {
p = strGetWordTop(p);
if (*p == 0) break;
int len = strGetWordLen(p);
mchar sw = 0;
if (p[0] == '-' && (sw = p[1])) {
p += 2;
len -= 2;
switch(sw) {
case 'c': {
if (!fMultiOpen) {
_fEscClose = TRUE;
_fOpenClose = TRUE;
}
break;
}
case 'e': {
if (!fMultiOpen) {
_fEscClose = TRUE;
}
break;
}
case 'f': {
mchar szfilename[CCHPATHNAME];
strcpylen(szfilename,p,len);
pathFormLong(szfilename);
if (szfilename[0] == 0) {
// ファイラー起動中にエディタからVZライクファイルオープンダイアログで
// リターンのみを入力してファイラーをアクティブにした際、
// ファイラーのディレクトリを移動しないようにした
} else {
filerSetPath(filerGetFocus(),szfilename);
}
break;
}
case 'O': {
// ウィンドウの親子関連付けはしない
// 関連付けを外すことができない様だ。
while(len) {
_hwndParent = (HWND)((UINT)_hwndParent * 10 + *p++ - '0');//1.00F
len--;
}
break;
}
case 'r': {
_fReadOnly = TRUE;
break;
}
}
}
p += len;
}
}
static void filerInit(FILER* filer)
{
sstrcpy(filer->szPath,filer == filer1 ? p_szPath1 : p_szPath2);
sstrcpy(filer->szMask,filer == filer1 ? p_szMask1 : p_szMask2);
if (!filer->szPath[0]) {
filerInitPath(filer);
}
if (!filer->szMask[0]) {
sstrcpy(filer->szMask,"*.*");
}
}
__txedelete
{
if (_szClassInfo != "") {
wndUnregisterClass(_szClassInfo);
_szClassInfo = "";
}
macroHookWndBaseFree();
macroHookWndTextFree();
p_szPath1 = filer1->szPath;
p_szMask1 = filer1->szMask;
p_szPath2 = filer2->szPath;
p_szMask2 = filer2->szMask;
}
static void sysmenuAdd(HMENU hmenu,int ipos,mchar* szcmd,mchar* szCaption)
{
InsertMenu(
hmenu,
ipos,MF_BYPOSITION,
IDM_WZCMDTOP + wzcmdRegister(szcmd),
szCaption
);
}
static void sysmenuCreate(void)
{
HMENU hmenu = GetSystemMenu(_textFiler->hwndbase,FALSE);
// RemoveMenu(hmenu, SC_ICON, MF_BYCOMMAND);
// RemoveMenu(hmenu, SC_ZOOM, MF_BYCOMMAND);
// RemoveMenu(hmenu, SC_SIZE, MF_BYCOMMAND); //1.00E サイズ変更できなくなってしまう
sysmenuAdd(hmenu,0,"txOpenNew","新規作成(&E)");
sysmenuAdd(hmenu,1,"txuiOpen","ファイルを開く(&O)...");
sysmenuAdd(hmenu,2,"file.uiPrjOpen","プロジェクトを開く(&P)...");
sysmenuAdd(hmenu,3,"grep.txe","Grep検索(&G)");
InsertMenu(hmenu,4,MF_BYPOSITION | MF_SEPARATOR,0,NULL);
}
__txenew
{
_textFiler = text;
text->modeImeSetFocus = ISF_OFF;//2.99D 970402 filerを開いたときIMEをOFFにした
macroHookWndBase();
macroHookWndText();
wndRegisterClass("\m.wndprocInfo",_szClassInfo);
sysmenuCreate();
text->fTxeNoWindowPos = TRUE;
text->fConfigInlineform = FALSE;//2.98 970310
//
txSetFilerDisp(text);
txSetFilerUI(text);
//
text->fNoWndText = TRUE;
//3.00A3 970508
txSetFilerStatusbar(text);
//
fileratrInit();
filerInit(filer1);
filerInit(filer2);
filerNewText(filer1);
filerNewText(filer2);
//2.99B 970322
filerSetModesort(filer1);
filerSetModesort(filer2);
//
_hwndPartition = CreateWindow(
TXPARTITION_SZCLASS,NULL,
WS_CHILDWINDOW | WS_VISIBLE,
CW_USEDEFAULT,CW_USEDEFAULT,
CW_USEDEFAULT,CW_USEDEFAULT,
_textFiler->hwndbase,
NULL,
_textFiler->hInstance,
NULL
);
if (p_fSaveWindowPos) {
wndtxMove(_textFiler->hwndbase,p_xWindow,p_yWindow,p_cxWindow,p_cyWindow,TRUE);
}
}
BOOL __txeclosemulti(HWND hwndprev)
{
// コマンドラインを解釈させる
wndtxSendStr(hwndprev,WM_COMMAND,IDM_CMDLINE,text->szCmdLine);
// hwndprevをアクティブにする
PostMessage(hwndprev,WM_TXACTIVE,0,0);//3.00A2 970504
return TRUE;
}
main
{
cmdline(_textFiler->szCmdLine,FALSE);
filerLoadPath(filer1,FLP_JUMPFILETOP);
if (p_fDouble) {
filerLoadPath(filer2,FLP_JUMPFILETOP);
}
filerSetFocus(filer1);
DoCaption();
//
if (p_fPreview) {//2.99 970318
preview();
previewFlush();//3.00A3 970508 ファイラーを開いた時にプレビューをフラッシュ
}
}
void test(void)
{
//dispinfo("abc");
// information("%d",text->share->nOpen);
//information("%d",txKeyIsEdited(text));
//txQuit(_textFiler);
}
WORD at_cmdcheck(WZCMD wzcmd)
{
mchar* szcmd = wzcmdToSzcmd(wzcmd);
if (!szcmd) return 0;
if (!stricmp(szcmd,"\m.preview")) {
if (_hwndPreview) return MF_CHECKED;
}
return 0;
}