ファイル名:text.h

変更無し

ファイル名:text.c

#pragma resource "text.res"
#define STRICT
char buf[512];
#include <windows.h>
#include <windowsx.h>
#include <commdlg.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "text.h"
#define APPNAME "TEXTVIEW"
#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))
#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 HWND hwndApp;
static HINSTANCE hInstApp;
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 tab=8;

static void scrollset(HWND hwnd){
	int b=nHscrollPos;
	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);
}
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;
		linebuf[0]=textbuf; maxlen=0;
		for(;;){
			p=_fstrchr(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;
		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);
}
/****************************************************************************
関数: MainWndProc(HWND, UINT, WPARAM, LPARAM) 目的:       メッセージ処理
****************************************************************************/
#ifdef __cplusplus
extern "C"
#endif
long FAR PASCAL MainWndProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam){
	static OPENFILENAME ofn;
	static char achFilePath[MAXPATH], achFileTitle[MAXNAME]="noname.txt";
	int i;
	HDC	hdc; RECT rc;
	int nPaintBeg, nPaintEnd;
	PAINTSTRUCT   ps;
	TEXTMETRIC	tm;
	HFONT hfont, hfontOld;
	int fuFormat;

	switch (message) {
	case WM_CREATE:
		hdc = GetDC (hwnd);
		GetTextMetrics (hdc, &tm);
		cxChar = tm.tmAveCharWidth;
		cyChar = tm.tmHeight + tm.tmExternalLeading;
		pitch=cyChar*24/20;
		ReleaseDC (hwnd, hdc);
		return 0;
	case WM_SIZE:
		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_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_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_ABOUT:
		#ifdef WIN32
			strcpy(buf, "Text Viewer 32bit版\nVersion 0.01\nCopyright (c)のぐー");
		#else
			strcpy(buf, "Text Viewer 16bit版\nVersion 0.01\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()を使うとき
		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:
		PostQuitMessage(0);
		return 0;
	}
	return DefWindowProc(hwnd, message, wParam, lParam);
}
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){
	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 (cyChar!=pitch) CheckMenuItem(hmenu, IDM_LINE, MF_CHECKED);
	return TRUE;
}
int PASCAL WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow){
	MSG msg;
	HACCEL hAccel=LoadAccelerators(hInstance, "TextAccel");
	hInstApp=hInstance;
	if (!hPrevInstance)
		if (!InitApplication(hInstance))
			return FALSE;
	if (!InitInstance(hInstance, nCmdShow))
		return FALSE;
	while (GetMessage(&msg, NULL, 0, 0)) {
		if (!TranslateAccelerator(hwndApp, hAccel, &msg)) {
			TranslateMessage(&msg);
			DispatchMessage(&msg);
		}
	}
	return msg.wParam;
}

ファイル名:text.rc

変更無し

ファイル名:text.def

変更無し
戻る