ファイル名:text.h
#define IDM_OPEN 101
#define IDM_EXIT 102
#define IDM_EDIT 103
#define IDM_READ 104
#define IDM_TAB8 105
#define IDM_TAB4 106
#define IDM_TAB2 107
#define IDM_TAB1 108
#define IDM_LINE 109
#define IDM_FOLD 110
#define IDM_FIND 111
#define IDM_NEXT 112
#define IDM_ABOUT 113
#define IDS_EDIT 114
#define IDCHECK 115
ファイル名:text.c
#pragma resource "text.res"
#define STRICT
char buf[512];
#include <windows.h>
#include <windowsx.h>
#include <commdlg.h>
#include <shellapi.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "text.h"
#define APPNAME "TEXTVIEW"
#if defined(__TURBOC__) && __TURBOC__ <= 0x452
#include <jctype.h>
#define _fnthctype m_nthctype
#else
#if _MSC_VER == 600
#include <jstring.h>
#else
#include <mbstring.h>
#include <mbctype.h>
#define nthctype m_nthctype
#define _fnthctype m_nthctype
#define CT_ANK _MBC_SINGLE
#define CT_KJ1 _MBC_LEAD
#define CT_KJ2 _MBC_TRAIL
#define CT_ILGL _MBC_ILLEGAL
#endif
#include <sys/types.h>
#endif
static int m_nthctype(const char far *s, int n);
#ifdef __cplusplus
#define NotUse(para)
//#define cpp(cast) (cast)
#else
#define NotUse(para) para
//#define cpp(cast)
#endif
#define min(a,b) (((a) < (b)) ? (a) : (b))
#define max(a,b) (((a) > (b)) ? (a) : (b))
#define MsgOut(str) MessageBox(hwndApp, (str), NULL, MB_OK)
#ifdef WIN32
#define huge
//#define _fnthctype nthctype
#define fmalloc(size) malloc(size)
#define ffree(ptr) free(ptr)
#define MAXPATH 260
#define MAXNAME 256
#else
#include <io.h>/*filelength()*/
#define fmalloc(size) MAKELONG(0,GlobalAlloc(GMEM_FIXED,size))
#define ffree(ptr) GlobalFree((HGLOBAL)HIWORD(ptr))
#define MAXPATH 80
#define MAXNAME 13
#endif
WORD Version; BOOL NT;
static DLGPROC lpSearch;
static HWND hwndApp, hDlgSearch;
static HINSTANCE hInstApp;
static char searchstr[256];
static char achFilePath[MAXPATH], achFileTitle[MAXNAME]="noname.txt";
static char *szAppName="textview";
static HMENU hmenu;
static char huge *textbuf;
#ifdef WIN32
#define MAXLINE 65535
#else
#define MAXLINE 2000
#endif
static char far *linebuf[MAXLINE];
static int linecount, maxlen;
static int nVscrollPos, nVscrollMax;
static int nHscrollPos, nHscrollMax;
static int cyClient, cyChar;
static int cxClient, cxChar;
static int pitch;
static int fold=1, linecount2, lin1;
static int tab=8;
#define ARGCMAX 16
static int argc=16;
static char *argv[ARGCMAX];
static void cmdlinesprit(LPSTR CmdLin);
static void pathsplit(const char *path, char *dir, char*name);
static void scrollset(HWND hwnd){
int b=nHscrollPos;
if (fold) {
int i; int len;
linecount2=0; lin1=(cxClient/cxChar)-2;
for(i=0; i<linecount; i++){
len=lstrlen(linebuf[i])-1;
if (len==-1) len=0;
linecount2 += len/lin1+1;
}
nVscrollMax = max (0, linecount2 + 0 - cyClient / pitch);
nHscrollMax = 0;
}else{
nVscrollMax = max (0, linecount + 0 - cyClient / pitch);
nHscrollMax = max (0, maxlen + 2 - cxClient / cxChar);
}
nVscrollPos = min (nVscrollPos, nVscrollMax);
SetScrollRange (hwnd, SB_VERT, 0, nVscrollMax, FALSE);
SetScrollPos (hwnd, SB_VERT, nVscrollPos, TRUE);
nHscrollPos = min (nHscrollPos, nHscrollMax);
SetScrollRange (hwnd, SB_HORZ, 0, nHscrollMax, FALSE);
SetScrollPos (hwnd, SB_HORZ, nHscrollPos, TRUE);
if (b!=nHscrollPos)
InvalidateRect(hwnd, NULL, TRUE);
}
void SetTitleBar(HWND hwnd, char *name){
if (name==NULL) sprintf(buf, APPNAME":(無題)");
else sprintf(buf, APPNAME":%s", name);
//if (name==NULL) sprintf(buf, szAppName);
//else sprintf(buf, "%s:%s %d行 %d桁", szAppName, name, linecount, maxlen);
SetWindowText(hwnd, buf);
}
static int callcount;
//#define STRCHR(p, str, c) (callcount++, (p)=_fstrchr((str), (c)))
#define STRCHR(p, str, c) do{ \
char far*s=str; \
for(;;s++){ \
if (*s==c) {p=s; break;}\
if (*s==0) {p=0; break;}\
} \
}while(0)
void readtext(HWND hwnd, char *path, char *name){
unsigned long textsize, readsize;
HFILE hfile;
hfile=_lopen(path, OF_READ | OF_SHARE_DENY_WRITE);
if (hfile==HFILE_ERROR) {
MessageBox(hwnd, "オープンできません", szAppName, MB_OK);
return;
}
if (textbuf) ffree(textbuf), textbuf=NULL, linebuf[0]=NULL;
#ifdef WIN32
{
WIN32_FIND_DATA ffd; HANDLE h;
h=FindFirstFile(path, &ffd);
if (h==INVALID_HANDLE_VALUE) {
MessageBox(hwnd, "ファイルが見つからない", szAppName, MB_OK);
return;
}
FindClose(h);
textsize=ffd.nFileSizeLow+ffd.nFileSizeHigh*65536;
}
#else
textsize=filelength(hfile);
#endif
textbuf=(LPSTR)fmalloc(textsize+1);
if (textbuf==NULL) {
char buf[100];
linebuf[0]=NULL; linecount=0; maxlen=0;
sprintf(buf, "メモリ不足 %d", textsize);
MessageBox(hwnd, buf, szAppName, MB_OK);
return;
}
readsize=_hread(hfile, textbuf, textsize);
#ifndef WIN32
if (readsize>65535LU) readsize=65535LU;
#endif
if (readsize>textsize) textbuf[0]=0, linebuf[0]=NULL; /* HFILE_ERROR */
else textbuf[readsize]=0, textsize=readsize;
_lclose(hfile);
//MessageBox(NULL, "success", "read", MB_OK);
if (textbuf[0]){
char far *p; int i=0; int len;
unsigned long tick=GetTickCount();
linebuf[0]=textbuf; maxlen=0;
for(;;){
STRCHR(p, linebuf[i], '\n');
i++; if (i==MAXLINE) break;
if (p==NULL) {
len=textsize;
if (len>maxlen) maxlen=len;
linebuf[i]=NULL;
break;
} //Lp p L 14 15
*p=0; //012345678\n0123\0
len=p-linebuf[i-1]; //9-0=9 4
textsize-=(len+1); //14-(9+1)=4
if (p!=linebuf[i-1])
if (*(p-1)=='\r') *(p-1)=0, len--;
if (len>maxlen) maxlen=len;
if (*(p+1)==0) {linebuf[i]=NULL; break;}
linebuf[i]=p+1;
}
linecount=i;
//sprintf(buf, "%d kai %f sec", callcount, (GetTickCount()-tick)/1000.0);
//MsgOut(buf); callcount=0;
scrollset(hwnd);
}
SetTitleBar(hwnd, name);
InvalidateRect(hwnd, NULL, TRUE);
}
/****************************************************************************
目的: WM_VSCROLL WM_HSCROLLメッセージ処理
****************************************************************************/
static void MainWClass_OnVScroll(HWND hwnd, HWND NotUse(hwndCtl), UINT code, int pos){
int nVscrollInc;
switch (code) {
case SB_TOP: nVscrollInc = -nVscrollPos; break;
case SB_BOTTOM: nVscrollInc = nVscrollMax - nVscrollPos; break;
case SB_LINEUP: nVscrollInc = -1; break;
case SB_LINEDOWN: nVscrollInc = 1; break;
case SB_PAGEUP: nVscrollInc = min (-1, -cyClient / pitch);break;
case SB_PAGEDOWN: nVscrollInc = max (1, cyClient / pitch); break;
case SB_THUMBTRACK:nVscrollInc = pos - nVscrollPos; break;
default: nVscrollInc = 0;
}
nVscrollInc = max(-nVscrollPos, min(nVscrollInc, nVscrollMax - nVscrollPos));
if (nVscrollInc != 0) {
nVscrollPos += nVscrollInc;
ScrollWindow (hwnd, 0, -pitch * nVscrollInc, NULL, NULL);
SetScrollPos (hwnd, SB_VERT, nVscrollPos, TRUE);
UpdateWindow (hwnd);
}
{
HDC hdc=GetWindowDC(hwndApp);
sprintf(buf, " %d - %d ", nVscrollPos+1, nVscrollPos+cyClient/pitch);
TextOut(hdc, cxClient-strlen(buf)*cxChar-20, 2, buf, strlen(buf));
ReleaseDC (hwndApp, hdc);
}
}
static void MainWClass_OnHScroll(HWND hwnd, HWND NotUse(hwndCtl), UINT code, int pos){
int nHscrollInc;
switch (code) {
case SB_TOP: nHscrollInc = nHscrollPos; break;
case SB_BOTTOM: nHscrollInc = nHscrollMax - nHscrollPos; break;
case SB_LINEUP: nHscrollInc = -1; break;
case SB_LINEDOWN: nHscrollInc = 1; break;
case SB_PAGEUP: nHscrollInc = -8; break;
case SB_PAGEDOWN: nHscrollInc = 8; break;
case SB_THUMBPOSITION:nHscrollInc = pos - nHscrollPos; break;
default: nHscrollInc = 0;
}
nHscrollInc = max(-nHscrollPos, min(nHscrollInc, nHscrollMax - nHscrollPos));
if (nHscrollInc != 0) {
nHscrollPos += nHscrollInc;
ScrollWindow (hwnd, -cxChar * nHscrollInc, 0, NULL, NULL);
SetScrollPos (hwnd, SB_HORZ, nHscrollPos, TRUE);
}
}
/****************************************************************************
目的: WM_KEYDOWN メッセージ処理
****************************************************************************/
static void MainWClass_OnKey(HWND hwnd,UINT vk,BOOL NotUse(fDown),int NotUse(cRepeat),UINT NotUse(flags)){
switch (vk) {
case VK_HOME: SendMessage (hwnd, WM_VSCROLL, SB_TOP, 0L);break;
case VK_END: SendMessage (hwnd, WM_VSCROLL, SB_BOTTOM, 0L);break;
case VK_PRIOR:SendMessage (hwnd, WM_VSCROLL, SB_PAGEUP, 0L);break;
case VK_NEXT: SendMessage (hwnd, WM_VSCROLL, SB_PAGEDOWN,0L);break;
case VK_UP: SendMessage (hwnd, WM_VSCROLL, SB_LINEUP, 0L);break;
case VK_DOWN: SendMessage (hwnd, WM_VSCROLL, SB_LINEDOWN,0L);break;
case VK_LEFT: SendMessage (hwnd, WM_HSCROLL, SB_PAGEUP, 0L);break;
case VK_RIGHT:SendMessage (hwnd, WM_HSCROLL, SB_PAGEDOWN,0L);break;
}
}
static void tabmenucheck(int i){
if (tab==8) CheckMenuItem(hmenu, IDM_TAB8, i);
if (tab==4) CheckMenuItem(hmenu, IDM_TAB4, i);
if (tab==2) CheckMenuItem(hmenu, IDM_TAB2, i);
if (tab==1) CheckMenuItem(hmenu, IDM_TAB1, i);
}
static void kenspos(int lin, int col, int *lin2, int *col2){
int i, len, outlen, p, k=0;
for (i = 0; i <= lin; i++) {
len = _fstrlen(linebuf[i]); p=0; *col2=col;
do {
*lin2=k; k++;
if (i==lin && *col2<lin1) return;
if (len>lin1)
if (_fnthctype(&linebuf[i][p], lin1-1)==CT_KJ1) outlen=lin1-1;
else outlen=lin1;
else outlen=len;
len-=outlen; p+=outlen; (*col2)-=outlen;
}while (len>0);
}
}
/****************************************************************************
関数: MainWndProc(HWND, UINT, WPARAM, LPARAM) 目的: メッセージ処理
****************************************************************************/
LRESULT CALLBACK MainWndProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam){
static int lin, end;
static OPENFILENAME ofn;
int i;
HDC hdc; RECT rc;
int nPaintBeg, nPaintEnd;
PAINTSTRUCT ps;
TEXTMETRIC tm;
HFONT hfont, hfontOld;
int fuFormat;
switch (message) {
case WM_DROPFILES: {
UINT cFiles, a;
cFiles = DragQueryFile((HDROP) wParam, (UINT)-1, (LPSTR) NULL, 0U);
if (cFiles>1) cFiles=1; /* 最初の一個だけ */
for(a = 0; a < cFiles; a++) {
DragQueryFile((HDROP) wParam, a, achFilePath, sizeof(achFilePath));
pathsplit(achFilePath, buf, achFileTitle);
readtext(hwnd, achFilePath, achFileTitle);
}
DragFinish((HDROP) wParam);
break;
}
case WM_CREATE:
hdc = GetDC (hwnd);
GetTextMetrics (hdc, &tm);
cxChar = tm.tmAveCharWidth;
cyChar = tm.tmHeight + tm.tmExternalLeading;
pitch=cyChar*24/20;
ReleaseDC (hwnd, hdc);
DragAcceptFiles(hwnd, TRUE);
return 0;
case WM_SIZE:
if (fold && cxClient != LOWORD (lParam)) InvalidateRect(hwnd, NULL, TRUE);
cxClient = LOWORD (lParam);
cyClient = HIWORD (lParam);
scrollset(hwnd);
return 0;
case WM_VSCROLL:
return HANDLE_WM_VSCROLL(hwnd, wParam, lParam, MainWClass_OnVScroll);
case WM_HSCROLL:
return HANDLE_WM_HSCROLL(hwnd, wParam, lParam, MainWClass_OnHScroll);
case WM_KEYDOWN:
return HANDLE_WM_KEYDOWN(hwnd, wParam, lParam, MainWClass_OnKey);
case WM_COMMAND:
switch((WORD)wParam){
case IDM_FIND:
if (hDlgSearch) SetActiveWindow(hDlgSearch);
else hDlgSearch=CreateDialog(hInstApp, "searchdlg", hwnd, lpSearch);
return 0;
case IDM_NEXT:
if (searchstr[0]==0) {
PostMessage(hwnd, WM_COMMAND, IDM_FIND, 0L);
return 0;
}
//lin=現在のカーソル行;
//end=現在のカーソル位置(行先頭から);
for (;;) {
char far *p;
p=_fstrstr(&linebuf[lin][end], searchstr);
if (p) {
int x, y;
end=p-linebuf[lin]+strlen(searchstr);
hdc=GetDC(hwnd);
hfont = (HFONT)GetStockObject(OEM_FIXED_FONT);
hfontOld=(HFONT)SelectObject(hdc,hfont);
SetTextColor(hdc, RGB(255,0,0));
if (fold){
//必要ならスクロール
int k, m; kenspos(lin, p-linebuf[lin], &k, &m);
MainWClass_OnVScroll(hwnd, NULL, SB_THUMBTRACK, k);
//pからendまで強調表示
x=(m+1)*cxChar;
y=(k-nVscrollPos+0.25)*pitch;
TextOut(hdc, x, y, p, strlen(searchstr));
}else{
//必要ならスクロール
MainWClass_OnVScroll(hwnd, NULL, SB_THUMBTRACK, lin);
MainWClass_OnHScroll(hwnd, NULL, SB_THUMBTRACK, end);
//pからendまで強調表示
x=(p-linebuf[lin]-nHscrollPos+1)*cxChar;
y=(lin-nVscrollPos+0.25)*pitch;
TextOut(hdc, x, y, p, strlen(searchstr));
}
SelectObject(hdc, hfontOld);
ReleaseDC (hwnd, hdc);
break;
}
lin++; end=0;
if (lin>=linecount) {
MessageBox(hwnd, "見つかりません", "textview", MB_OK);
lin=0; break;
}
}
return 0;
case IDM_OPEN:
memset(&ofn, 0, sizeof(OPENFILENAME));
ofn.lStructSize = sizeof(OPENFILENAME);
ofn.hwndOwner = hwnd;
ofn.lpstrFilter = "テキスト(*.TXT)\0*.TXT\0全ファイル(*.*)\0*.*\0";
ofn.lpstrCustomFilter = NULL;
ofn.nFilterIndex = 1;
achFilePath[0] = 0;
ofn.lpstrFile = (LPSTR)achFilePath;
ofn.nMaxFile = sizeof(achFilePath);
ofn.lpstrFileTitle = (LPSTR)achFileTitle;
ofn.nMaxFileTitle = sizeof(achFileTitle);
ofn.lpstrInitialDir = NULL;
ofn.lpstrTitle = NULL; //ofn.lpstrTitle = "ファイルを開く";
ofn.lpstrDefExt = NULL;
ofn.Flags = OFN_HIDEREADONLY | OFN_FILEMUSTEXIST;
if(GetOpenFileName((LPOPENFILENAME)&ofn))
readtext(hwnd, achFilePath, achFileTitle);
return 0;
case IDM_READ:
readtext(hwnd, achFilePath, achFileTitle);
return 0;
case IDM_EDIT:
sprintf(buf, "textedit %s", achFilePath);
WinExec(buf, SW_SHOW);
return 0;
case IDM_EXIT:
SendMessage(hwnd, WM_CLOSE, 0, 0L);
return 0;
case IDM_TAB8:
tabmenucheck(MF_UNCHECKED);
tab=8; InvalidateRect(hwnd, NULL, TRUE);
tabmenucheck(MF_CHECKED);
return 0;
case IDM_TAB4:
tabmenucheck(MF_UNCHECKED);
tab=4; InvalidateRect(hwnd, NULL, TRUE);
tabmenucheck(MF_CHECKED);
return 0;
case IDM_TAB2:
tabmenucheck(MF_UNCHECKED);
tab=2; InvalidateRect(hwnd, NULL, TRUE);
tabmenucheck(MF_CHECKED);
return 0;
case IDM_TAB1:
tabmenucheck(MF_UNCHECKED);
tab=1; InvalidateRect(hwnd, NULL, TRUE);
tabmenucheck(MF_CHECKED);
return 0;
case IDM_LINE:
if (cyChar==pitch) pitch=cyChar*24/20, CheckMenuItem(hmenu, IDM_LINE, MF_CHECKED);
else pitch=cyChar, CheckMenuItem(hmenu, IDM_LINE, MF_UNCHECKED);
scrollset(hwnd);
InvalidateRect(hwnd, NULL, TRUE);
return 0;
case IDM_FOLD:
if (fold) fold=0, CheckMenuItem(hmenu, IDM_FOLD, MF_UNCHECKED);
else fold=1, CheckMenuItem(hmenu, IDM_FOLD, MF_CHECKED);
scrollset(hwnd);
InvalidateRect(hwnd, NULL, TRUE);
return 0;
case IDM_ABOUT:
#ifdef WIN32
strcpy(buf, "Text Viewer 32bit版\nVersion 0.03\nCopyright (c)のぐー");
#else
strcpy(buf, "Text Viewer 16bit版\nVersion 0.03\nCopyright (c)のぐー");
#endif
MessageBox(hwnd, buf, "About", MB_OK);
return 0;
}
break;
case WM_PAINT:
hdc = BeginPaint (hwnd, &ps);
hfont = (HFONT)GetStockObject(OEM_FIXED_FONT);
hfontOld=(HFONT)SelectObject(hdc,hfont);
SetTextColor(hdc, GetSysColor(COLOR_WINDOWTEXT));
SetBkColor(hdc, GetSysColor(COLOR_WINDOW));
//if (tab==8) fuFormat = DT_SINGLELINE|DT_EXPANDTABS|DT_NOPREFIX;
//else fuFormat = DT_SINGLELINE|DT_EXPANDTABS|DT_TABSTOP|(tab<<8);
fuFormat = tab*cxChar;//TabbedTextOut()を使うとき
if (fold){
int k=0, len, outlen, p;
nPaintBeg = max (0, nVscrollPos + ps.rcPaint.top / pitch - 1);
nPaintEnd = min (linecount2+1, nVscrollPos + ps.rcPaint.bottom / pitch+1);
rc.left = cxChar; rc.right=cxClient;
for (i = 0; i < linecount; i++) {
len = _fstrlen(linebuf[i]); p=0;
do {
rc.top = pitch * (0.25 - nVscrollPos + k); k++;
rc.bottom=rc.top+pitch;
if (len>lin1)
if (_fnthctype(&linebuf[i][p], lin1-1)==CT_KJ1) outlen=lin1-1;
else outlen=lin1;
else outlen=len;
if (k>nPaintBeg){
//DrawText(hdc, &linebuf[i][p], outlen, &rc, fuFormat);
//TextOut(hdc, rc.left, rc.top, &linebuf[i][p], outlen);
TabbedTextOut(hdc, rc.left, rc.top, &linebuf[i][p], outlen,
1, &fuFormat, rc.left);
}
if (k>nPaintEnd) {i=linecount;break;}
len-=outlen; p+=outlen;
}while (len>0);
}
}else{
nPaintBeg = max (0, nVscrollPos + ps.rcPaint.top / pitch - 1);
nPaintEnd = min (linecount, nVscrollPos + ps.rcPaint.bottom / pitch+1);
rc.left = cxChar*(1-nHscrollPos); rc.right=cxClient;
for (i = nPaintBeg; i < nPaintEnd; i++) {
rc.top = pitch * (0.25 - nVscrollPos + i);
rc.bottom = rc.top+pitch;
//DrawText(hdc, linebuf[i], _fstrlen(linebuf[i]), &rc, fuFormat);
//TextOut(hdc, rc.left, rc.top, linebuf[i], _fstrlen(linebuf[i]));
TabbedTextOut(hdc, rc.left, rc.top, linebuf[i], _fstrlen(linebuf[i]),
1, &fuFormat, rc.left);
}
}
SelectObject(hdc, hfontOld);
//SetBkColor(hdc, RGB(255,255,255));
//sprintf(buf, "%d %d %d", cyChar, cxChar, linecount);
//TextOut (hdc, 0, 0, buf, lstrlen (buf));
EndPaint (hwnd, &ps);
return 0;
case WM_DESTROY:
DragAcceptFiles(hwnd, FALSE);
PostQuitMessage(0);
return 0;
}
return DefWindowProc(hwnd, message, wParam, lParam);
}
BOOL CALLBACK searchdlg(HWND hDlg, UINT msg, WPARAM wParam, LPARAM NotUse(lParam)){
switch (msg) {
case WM_CLOSE:
DestroyWindow(hDlg); hDlgSearch=NULL;
return TRUE;
case WM_COMMAND:
switch((WORD)wParam){
case IDOK:
GetDlgItemText(hDlg, IDS_EDIT, searchstr, sizeof(searchstr));
SendMessage(hwndApp, WM_COMMAND, IDM_NEXT, 0L);
return TRUE;
case IDCANCEL:
DestroyWindow(hDlg); hDlgSearch=NULL;
return TRUE;
}
return TRUE;
case WM_INITDIALOG:
EnableWindow(GetDlgItem(hDlg, IDCHECK), FALSE);
/* ↑ 大文字小文字の同一視はサポートしない */
SetDlgItemText(hDlg, IDS_EDIT, searchstr);
return TRUE;/* SetFocusしたらfalse */
}
return FALSE;
}
BOOL InitApplication(HINSTANCE hInstance){
WNDCLASS wc;
wc.style = 0;
wc.lpfnWndProc = MainWndProc;
wc.cbClsExtra = 0;
wc.cbWndExtra = 0;
wc.hInstance = hInstance;
//wc.hIcon = LoadIcon(NULL, IDI_APPLICATION);
wc.hIcon = LoadIcon(hInstance, "TextIcon");
wc.hCursor = LoadCursor(NULL, IDC_ARROW);
//wc.hbrBackground = (HBRUSH)GetStockObject(WHITE_BRUSH);
wc.hbrBackground = (HBRUSH)(COLOR_WINDOW+1);
wc.lpszMenuName = "TextMenu";
wc.lpszClassName = "TextWClass";
return RegisterClass(&wc);
}
void GetWindowsVersion(void){
// 0x300: Windows 3.00
// 0x30a: Windows 3.10
// 0x30b: Windows 3.11
// 0x35f: Windows 95 (16bit) (3.95)
// 0x400: Windows 95 (32bit) (4.00)
// 0x362: Windows 98 (16bit) (3.98)
// 0x40a: Windows 98 (32bit) (4.10)
WORD DosVersion = HIWORD(GetVersion());
Version = LOWORD(GetVersion());
Version = (WORD)((LOBYTE(Version)<<8) + HIBYTE(Version));
#ifdef WIN32
if (DosVersion & 0x8000) NT=0; else NT=1;
#else
if (Version==0x35f && DosVersion >=0x70a) Version+=3;
#endif
}
BOOL InitInstance(HINSTANCE hInstance, int nCmdShow, LPSTR lpCmdLine){
int i;
GetWindowsVersion();
hwndApp = CreateWindow(
"TextWClass", APPNAME, WS_OVERLAPPEDWINDOW | WS_VSCROLL | WS_HSCROLL,
CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT,
NULL, NULL, hInstance, NULL);
if (!hwndApp) return FALSE;
ShowWindow(hwndApp, nCmdShow);
UpdateWindow(hwndApp);
hmenu=GetMenu(hwndApp);
tabmenucheck(MF_CHECKED);
if (fold) CheckMenuItem(hmenu, IDM_FOLD, MF_CHECKED);
if (cyChar!=pitch) CheckMenuItem(hmenu, IDM_LINE, MF_CHECKED);
#ifdef WIN32
cmdlinesprit(GetCommandLine()); (void)lpCmdLine;
#else
cmdlinesprit(lpCmdLine);
#endif
for (i=1; i<argc; ++i) {
if (argv[i][0]!='/' && argv[i][0]!='\0') {
strcpy(achFilePath, argv[i]);
pathsplit(achFilePath, buf, achFileTitle);
readtext(hwndApp, achFilePath, achFileTitle);
break;
}
}
return TRUE;
}
int PASCAL WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow){
MSG msg;
HACCEL hAccel=LoadAccelerators(hInstance, "TextAccel");
lpSearch = (DLGPROC)MakeProcInstance((FARPROC)searchdlg, hInstance);
hInstApp=hInstance;
if (!hPrevInstance)
if (!InitApplication(hInstance))
return FALSE;
if (!InitInstance(hInstance, nCmdShow, lpCmdLine))
return FALSE;
while (GetMessage(&msg, NULL, 0, 0)) {
if (!TranslateAccelerator(hwndApp, hAccel, &msg)) {
if (hDlgSearch ==NULL || !IsDialogMessage(hDlgSearch, &msg)) {
TranslateMessage(&msg);
DispatchMessage(&msg);
}
}
}
FreeProcInstance((FARPROC)lpSearch);
return msg.wParam;
}
/*********************************************************************************
日本語処理
*********************************************************************************/
#define __LCC__
#ifdef __LCC__
#define U(c) ((unsigned char)(c))
#define iskanji(c) ((0x81 <=U(c) && U(c)<= 0x9F) || (0xE0 <=U(c) && U(c)<= 0xFC))
#define iskanji2(c) ((0x40 <=U(c) && U(c)<= 0x7E) || (0x80 <=U(c) && U(c)<= 0xFC))
/*以下の二つの関数は、松田晋氏によるC MAGAZINE 92年5月号掲載のものである*/
/* nth_kanjiの非再帰版プログラム */
/* 文字列sのn文字目が漢字1バイト目か? */
static int nth_kanji(const char far *s, int n) {
int k;
if (! iskanji(s[n])) return 0;
k = n;
while (--k >= 0 && iskanji(s[k]))
;
return (n - k) & 1;
}
/* 高速版nthctype */
static int m_nthctype(const char far *s, int n){
if (n > 0 && nth_kanji(s, n - 1)) {/* 左隣が漢字1バイト目である場合 */
if (iskanji2(s[n])) /* 漢字2バイト目か? */
return CT_KJ2;
return CT_ILGL;
} else if (iskanji(s[n]))
return CT_KJ1;
else
return CT_ANK;
}
#endif
/*********************************************************************************
jstrrpbrk(s, t):文字列を末尾から検索し、特定の文字集合が見つかったら検索を打ち切る
sには全角を含む文字列を指定できるが、tにはできない(手抜きモード)
*********************************************************************************/
static const char *jstrrpbrk(const char *s, const char *t){
int n; const char *q;
if (s==NULL || *s==0) return NULL;
if (t==NULL || *t==0) return NULL;
n = strlen(s) - 1;
for (; n >= 0; --n) {
for (q=t; *q!='\0'; ++q) {
if (s[n] == *q)
if (nthctype(s, n)==CT_ANK) return &s[n];
}
}
return NULL;
}
/**********************************************************************
pathsplit(): フルパスをファイル名とそれ以外に分離します。
**********************************************************************/
static void pathsplit(const char *path, char *dir, char*name){
const char *p; int i;
if (path[0]==0) {dir[0]=0; name[0]=0; return;}
p=jstrrpbrk(path, "\\/:"); //p=strrchr(path,'\\');
if (p==NULL) dir[0]=0;
else {
for(i=0;i<=p-path;++i)
dir[i]=path[i];
dir[p-path+1]=0;
path=p+1;
}
strcpy(name,path);
}
/************************************************************************************
コマンドライン分割処理
************************************************************************************/
#ifdef WIN32
#undef _fnthctype
#define _fnthctype nthctype
#endif
static void qu_strncpy(char *dst, char far *src, int n){
int i, j;
for (; n>0; ){
if (src[n-1]!=' ')break;
n--;
}
for(i=0,j=0; i<n; j++){
if (src[j]=='"' && (j==0 || (src[j-1]!='\\' || _fnthctype(src, j-1)==CT_KJ2)))
n--;
else if (src[j]=='\\' && _fnthctype(src, j)!=CT_KJ2 && src[j+1]=='"')
n--;
else dst[i]=src[j], i++;
if (src[j]==0) break;
}
dst[n]=0;
}
static void cmdlinesprit(LPSTR CmdLin){
int i=0, p=0, inflag=0;
#ifdef WIN32
argc=0;
#else
argc=1;
#endif
for(;;){
if (CmdLin[i]=='\0'){
argv[argc]=(char*)malloc(i-p+1);
if (argv[argc]==NULL) break;
qu_strncpy(argv[argc],&CmdLin[p],i-p);
break;
}
if (CmdLin[i]=='"' && (i==0 ||
(CmdLin[i-1]!='\\' || _fnthctype(CmdLin, i-1)==CT_KJ2))) inflag=!inflag;
if (inflag==0 && (CmdLin[i]=='/' || (CmdLin[i]==' ' && (argc==0 || CmdLin[p]=='/')))){
argv[argc]=(char*)malloc(i-p+1);
if (argv[argc]==NULL) break;
qu_strncpy(argv[argc],&CmdLin[p],i-p);
argc++;if (argc>=ARGCMAX-1) break;
do{
p=i;i++;
}while (CmdLin[p]==' ');
}else i++;
}
argc++;
}
ファイル名:text.rc
//#include <windows.h>
#include "text.h"
TextIcon ICON "text.ICO"
TextMenu MENU
BEGIN
POPUP "ファイル(\036F\037フ)"
BEGIN
MENUITEM "開く(\036O\037ヒ)...", IDM_OPEN
MENUITEM "編集(\036E\037ヘ)...", IDM_EDIT
MENUITEM "再読込(\036R\037サ)...", IDM_READ
MENUITEM SEPARATOR
MENUITEM "終了(\036X\037シ)", IDM_EXIT
END
POPUP "表示(\036V\037ヒ)"
BEGIN
MENUITEM "TAB(&8)", IDM_TAB8
MENUITEM "TAB(&4)", IDM_TAB4
MENUITEM "TAB(&2)", IDM_TAB2
MENUITEM "TAB(&1)", IDM_TAB1
MENUITEM SEPARATOR
MENUITEM "行ピッチを広げる(&L)", IDM_LINE
MENUITEM "右端で折り返す(&F)", IDM_FOLD
END
POPUP "検索(\036S\037ケ)"
BEGIN
MENUITEM "文字列の検索(\036F\037ケ)...", IDM_FIND
MENUITEM "次を検索(\036N\037ツ) F3", IDM_NEXT
END
POPUP "ヘルプ(\036H\037ヘ)"
BEGIN
MENUITEM "バージョン情報(\036A\037シ)...", IDM_ABOUT
END
END
TextAccel ACCELERATORS
BEGIN
VK_F1, IDM_ABOUT, VIRTKEY
VK_F3, IDM_NEXT, VIRTKEY
END
#include "search.dlg"
ファイル名:search.dlg
searchdlg DIALOG 20, 40, 185, 43
STYLE DS_MODALFRAME | WS_POPUP | WS_VISIBLE | WS_CAPTION | WS_SYSMENU
CAPTION "文字列の検索"
FONT 12, "System"
BEGIN
LTEXT "検索文字列(&N)", -1, 4, 8, 52, 8
EDITTEXT IDS_EDIT, 58, 5, 77, 12, ES_AUTOHSCROLL
CONTROL "大文字と小文字を同一視(&C)", IDCHECK, "Button", BS_AUTOCHECKBOX | WS_TABSTOP,
7, 25, 112, 10
DEFPUSHBUTTON "実行(&F)", IDOK, 141, 3, 40, 14
PUSHBUTTON "終了(&L)", IDCANCEL, 141, 23, 40, 14
END
ファイル名:text.def
NAME TextView
DESCRIPTION 'テキストビュアー'
EXETYPE WINDOWS
STUB 'WINSTUB.EXE'
CODE PRELOAD MOVEABLE DISCARDABLE
DATA PRELOAD MOVEABLE MULTIPLE
HEAPSIZE 1024
STACKSIZE 8192
EXPORTS
MainWndProc @1 ; ウィンドウ処理関数の名前
searchdlg @2 ; ダイアログ処理関数の名前
戻る