ファイル名:edit.dlg

editdlg DIALOG 6, 18, 200, 120
STYLE WS_MINIMIZEBOX | WS_MAXIMIZEBOX | WS_POPUP | WS_VISIBLE | WS_CAPTION | WS_SYSMENU | WS_THICKFRAME
CAPTION "簡易テキストエディタ"
FONT 12, "System"
MENU editmenu
BEGIN
	EDITTEXT  IDEDIT, 4, 15, 150, 79, ES_MULTILINE | WS_VSCROLL | ES_WANTRETURN | ES_NOHIDESEL
END

ファイル名:search.dlg

searchdlg DIALOG 6, 18, 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
	PUSHBUTTON "実行(&F)", IDOK, 141, 3, 40, 14
	PUSHBUTTON "終了(&L)", IDCANCEL, 141, 23, 40, 14
END

ファイル名:replace.dlg

replacedlg DIALOG 6, 18, 199, 50
STYLE DS_MODALFRAME | WS_POPUP | WS_VISIBLE | WS_CAPTION | WS_SYSMENU
CAPTION "文字列の置換"
FONT 12, "System"
BEGIN
	LTEXT "検索文字列(&N)", -1, 6, 9, 53, 8
	EDITTEXT               IDS_EDIT, 61, 7, 74, 12, ES_AUTOHSCROLL
	LTEXT "置換文字列(&P)", -1, 7, 28, 53, 8
	EDITTEXT               IDR_EDIT, 61, 26, 74, 12, ES_AUTOHSCROLL
	PUSHBUTTON "実行(&R)", IDOK, 145, 3, 40, 14
	PUSHBUTTON "終了(&L)", IDCANCEL, 146, 20, 40, 14
	CONTROL "確認なし(&A)", IDCHECK, "Button", BS_AUTOCHECKBOX | WS_TABSTOP, 140, 37, 55, 10
END

ファイル名:edit.rc

#include <windows.h>
#include "edit.h"
editmenu MENU
BEGIN
	POPUP        "ファイル(\036F\037フ)"
	BEGIN
		MENUITEM "新規作成(\036N\037サ)", IDM_NEW
		MENUITEM "開く(\036O\037ヒ)...", IDM_OPEN
		MENUITEM "上書き保存(\036S\037セ)", IDM_SAVE
		MENUITEM "名前をつけて保存(\036A\037ナ)...", IDM_NAME
		MENUITEM SEPARATOR
		MENUITEM "終了(\036X\037シ)",    IDM_EXIT
	END
	POPUP        "編集(\036E\037ヘ)"
	BEGIN
		MENUITEM "元に戻す(\036U\037モ)", IDM_UNDO
		MENUITEM SEPARATOR
		MENUITEM "切り取り(\036T\037キ)", IDM_CUT
		MENUITEM "コピー(\036C\037コ)", IDM_COPY
		MENUITEM "貼り付け(\036P\037ハ)", IDM_PASTE
		MENUITEM "削除(\036L\037サ)", IDM_DEL
		MENUITEM "すべての範囲を選択(\036L\037ス)", IDM_ALL
		MENUITEM SEPARATOR
		MENUITEM "右端で折り返す(\036W\037ミ)", IDM_FOLD
	END
	POPUP        "検索(\036S\037ケ)"
	BEGIN
		MENUITEM "文字列の検索(\036F\037ケ)...", IDM_FIND
		MENUITEM "次を検索(\036N\037ツ)", IDM_NEXT
		MENUITEM "文字列の置換(\036R\037チ)...", IDM_REP
	END
	POPUP        "ヘルプ(\036H\037ヘ)"
	BEGIN
		MENUITEM "ヘルプの表示(\036H\037ヘ)...", IDM_HELP
		MENUITEM "バージョン情報(\036A\037シ)...", IDM_ABOUT
	END
END
#include "edit.dlg"
#include "search.dlg"
#include "replace.dlg"

ファイル名:edit.h

#define IDEDIT 100
#define IDM_NEW 101
#define IDM_OPEN 102
#define IDM_SAVE 103
#define IDM_NAME 104
#define IDM_EXIT 105

#define IDM_UNDO 106
#define IDM_CUT  107
#define IDM_COPY 108
#define IDM_PASTE 109
#define IDM_DEL 110
#define IDM_ALL 111
#define IDM_FOLD 112

#define IDM_FIND 113
#define IDM_NEXT 114
#define IDM_REP 115

#define IDM_HELP 116
#define IDM_ABOUT 117

#define IDS_EDIT 118
#define IDR_EDIT 119
#define IDCHECK  120
#define IDM_REP2 121

ファイル名:edit.c

#define STRICT
#include <windows.h>
#include "edit.h"
#include <commdlg.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#ifdef WIN32
	#define fmalloc(size) malloc(size)
	#define ffree(ptr)    free(ptr)
	#define MAXPATH 260
	#define MAXNAME 256
#else
	#define fmalloc(size) MAKELONG(0,GlobalAlloc(GMEM_FIXED,size))
	#define ffree(ptr)    GlobalFree((HGLOBAL)HIWORD(ptr))
	#define MAXPATH 80
	#define MAXNAME 13
#endif

#define MAXTEXTSIZE 30000

DLGPROC lpSearch, lpReplace;
HWND hDlgMain, hDlgSearch, hDlgReplace;
HINSTANCE hInstApp;
char searchstr[256], replacestr[256];
int nocheck;

void SetTitleBar(HWND hwnd, char *name){
	char buf[14+MAXNAME];
	if (name==NULL) sprintf(buf, "簡易テキストエディタ:(無題)");
	else            sprintf(buf, "簡易テキストエディタ:%s", name);
	SetWindowText(hwnd, buf);
}

void readtext(HWND hwnd, char *path, char *name){
	LPSTR p; UINT readsize;
	HFILE hfile=_lopen(path, OF_READ | OF_SHARE_DENY_WRITE);
	if (hfile==HFILE_ERROR) {
		MessageBox(hwnd, "オープンできません", "簡易テキストエディタ", MB_OK);
		return;
	}
	p=(LPSTR)fmalloc(MAXTEXTSIZE+1);
	if (p==NULL) {
		MessageBox(hwnd, "メモリ不足", "簡易テキストエディタ", MB_OK);
		return;
	}
	readsize=_lread(hfile, p, MAXTEXTSIZE);
	if (readsize>MAXTEXTSIZE) p[0]=0; /* HFILE_ERROR */
	else                      p[readsize]=0;
	SetDlgItemText(hwnd, IDEDIT, p);
	ffree(p);
	_lclose(hfile);
	SetTitleBar(hwnd, name);
}
void writetext(HWND hwnd, char *path, char *name){
	LPSTR p; UINT writesize;
	HFILE hfile=_lcreat(path, 0);
	if (hfile==HFILE_ERROR) {
		MessageBox(hwnd, "オープンできません", "簡易テキストエディタ", MB_OK);
		return;
	}
	writesize=(UINT)SendDlgItemMessage(hwnd, IDEDIT, WM_GETTEXTLENGTH, 0, 0L);
	p=(LPSTR)fmalloc(writesize+1);
	if (p==NULL) {
		MessageBox(hwnd, "メモリ不足", "簡易テキストエディタ", MB_OK);
		return;
	}
	writesize=GetDlgItemText(hwnd, IDEDIT, p, writesize+1);
	_lwrite(hfile, p, writesize);
	_lclose(hfile);
	ffree(p);
	SetTitleBar(hwnd, name);
}
/*ダイアログ関数(Windowsからコールバックされる)*/
#ifdef __cplusplus
extern "C"
#endif
BOOL FAR PASCAL replacedlg(HWND hDlg, UINT msg, WPARAM wParam, LPARAM lParam){

	switch (msg) {
	case WM_CLOSE:
		DestroyWindow(hDlg); hDlgReplace=NULL;
		return TRUE;
	case WM_COMMAND:
		switch((WORD)wParam){
		case IDOK:
			GetDlgItemText(hDlg, IDS_EDIT, searchstr, sizeof(searchstr));
			GetDlgItemText(hDlg, IDR_EDIT, replacestr, sizeof(replacestr));
			if (IsDlgButtonChecked(hDlg, IDCHECK)) nocheck=1; else nocheck=0;
			SendMessage(hDlgMain, WM_COMMAND, IDM_REP2, 0L);
			return TRUE;
		case IDCANCEL:
			DestroyWindow(hDlg); hDlgReplace=NULL;
			return TRUE;
		}
		return TRUE;
	case WM_INITDIALOG:
		SetDlgItemText(hDlg, IDS_EDIT, searchstr);
		SetDlgItemText(hDlg, IDR_EDIT, replacestr);
		return TRUE;/* SetFocusしたらfalse */
	}
	return FALSE;
}
#ifdef __cplusplus
extern "C"
#endif
BOOL FAR PASCAL searchdlg(HWND hDlg, UINT msg, WPARAM wParam, LPARAM 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(hDlgMain, 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;
}
#ifdef __cplusplus
extern "C"
#endif
BOOL FAR PASCAL dlgproc(HWND hDlg, UINT msg, WPARAM wParam, LPARAM lParam){
	RECT rc;
	static OPENFILENAME ofn;
	static char achFilePath[MAXPATH], achFileTitle[MAXNAME];
	char buf[512]; int end, lin, maxlin;

	switch(msg){
	case WM_COMMAND:
		switch((WORD)wParam) {/*コントロールID*/
		case IDM_NEW:
			SetDlgItemText(hDlg, IDEDIT, "");
			achFilePath[0]=achFileTitle[0]=0;
			SetTitleBar(hDlg, NULL);
			break;
		case IDM_SAVE:
			if (achFilePath[0]) {writetext(hDlg, achFilePath, achFileTitle); break;}
			/*NO BREAK*/
		case IDM_OPEN:
		case IDM_NAME:
			memset(&ofn, 0, sizeof(OPENFILENAME));
			ofn.lStructSize = sizeof(OPENFILENAME);
			ofn.hwndOwner = hDlg;
			ofn.lpstrFilter = "テキスト(*.TXT)\0*.TXT\0全ファイル(*.*)\0*.*\0";
			ofn.lpstrCustomFilter = NULL;
			ofn.nFilterIndex = 1;
			if ((WORD)wParam==IDM_OPEN)	achFilePath[0] = 0;
			else strcpy(achFilePath,achFileTitle);
			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;
			if ((WORD)wParam==IDM_OPEN)	ofn.Flags = OFN_HIDEREADONLY | OFN_FILEMUSTEXIST;
			else                        ofn.Flags = OFN_HIDEREADONLY | OFN_OVERWRITEPROMPT;
			if ((WORD)wParam==IDM_OPEN) {
				if(GetOpenFileName((LPOPENFILENAME)&ofn))
					readtext(hDlg, achFilePath, achFileTitle);
			}else{
				if (GetSaveFileName((LPOPENFILENAME)&ofn))
					writetext(hDlg, achFilePath, achFileTitle);
			}
			break;
		case IDCANCEL: case IDM_EXIT:
			DestroyWindow(hDlg);
			break;
		case IDM_ABOUT:
			MessageBox(hDlg, "簡易エディタ\nバージョン 0.02\nCopyright (c)のぐー",
			"バージョン情報", MB_OK);
			break;
		case IDM_FIND:
			if (hDlgSearch) SetActiveWindow(hDlgSearch);
			else hDlgSearch=CreateDialog(hInstApp, "searchdlg", hDlg, lpSearch);
			break;
		case IDM_NEXT:
			if (searchstr[0]==0) {
				PostMessage(hDlg, WM_COMMAND, IDM_FIND, 0L);
				break;
			}
			maxlin=SendDlgItemMessage(hDlg, IDEDIT, EM_GETLINECOUNT, 0, 0L);
		#ifdef WIN32
			SendDlgItemMessage(hDlg, IDEDIT, EM_GETSEL, 0, (LPARAM)&end);
		#else
			end=HIWORD(SendDlgItemMessage(hDlg, IDEDIT, EM_GETSEL, 0, 0L));
		#endif
			lin=SendDlgItemMessage(hDlg, IDEDIT, EM_LINEFROMCHAR, end, 0L);
			end=end-SendDlgItemMessage(hDlg, IDEDIT, EM_LINEINDEX, lin, 0L);
			for(;;){
				int cbText; char *p;
				*(WORD *) buf = sizeof(buf) - 1;
				cbText = (int) SendDlgItemMessage(hDlg, IDEDIT, EM_GETLINE, lin, (DWORD) (LPSTR) buf);
				buf[cbText] = '\0';
				if ((p=strstr(buf+end, searchstr))!=NULL) {
					int sta=SendDlgItemMessage(hDlg, IDEDIT, EM_LINEINDEX, lin, 0L)+(p-buf);
				#ifdef WIN32
					SendDlgItemMessage(hDlg, IDEDIT, EM_SETSEL, sta, sta+strlen(searchstr));
				#else
					SendDlgItemMessage(hDlg, IDEDIT, EM_SETSEL, 0, MAKELONG(sta, sta+strlen(searchstr)));
				#endif
					break;
				}
				lin++; end=0;
				if (lin>maxlin) {
					MessageBox(hDlg, "見つかりません", "簡易エディタ", MB_OK);
					break;
				}
			}
			break;
		case IDM_REP:
			if (hDlgReplace) SetActiveWindow(hDlgReplace);
			else hDlgReplace=CreateDialog(hInstApp, "replacedlg", hDlg, lpReplace);
			break;
		case IDM_REP2:
			if (searchstr[0]==0) break;
			maxlin=SendDlgItemMessage(hDlg, IDEDIT, EM_GETLINECOUNT, 0, 0L);
			lin=end=0;
			for(;;){
				int cbText; char *p;
				*(WORD *) buf = sizeof(buf) - 1;
				cbText = (int) SendDlgItemMessage(hDlg, IDEDIT, EM_GETLINE, lin, (DWORD) (LPSTR) buf);
				buf[cbText] = '\0';
				if ((p=strstr(buf+end, searchstr))!=NULL) {
					int answer;
					int sta=SendDlgItemMessage(hDlg, IDEDIT, EM_LINEINDEX, lin, 0L)+(p-buf);
				#ifdef WIN32
					SendDlgItemMessage(hDlg, IDEDIT, EM_SETSEL, sta, sta+strlen(searchstr));
				#else
					SendDlgItemMessage(hDlg, IDEDIT, EM_SETSEL, 0, MAKELONG(sta, sta+strlen(searchstr)));
				#endif
					if (nocheck) answer=IDYES;
					else answer=MessageBox(hDlg, "置換しますか?", "簡易エディタ", MB_YESNOCANCEL);
					if (answer==IDYES)
						SendDlgItemMessage(hDlg, IDEDIT, EM_REPLACESEL, 0, (LPARAM)(LPSTR)replacestr);
					if (answer==IDCANCEL) break;
				#ifdef WIN32
					SendDlgItemMessage(hDlg, IDEDIT, EM_GETSEL, 0, (LPARAM)&end);
				#else
					end=HIWORD(SendDlgItemMessage(hDlg, IDEDIT, EM_GETSEL, 0, 0L));
				#endif
					lin=SendDlgItemMessage(hDlg, IDEDIT, EM_LINEFROMCHAR, end, 0L);
					end=end-SendDlgItemMessage(hDlg, IDEDIT, EM_LINEINDEX, lin, 0L);
				}else
					lin++, end=0;
				if (lin>maxlin) {
					MessageBox(hDlg, "置換が終了しました", "簡易エディタ", MB_OK);
					break;
				}
			}
			break;
		case IDM_DEL  : SendDlgItemMessage(hDlg, IDEDIT, EM_REPLACESEL, 0, (LPARAM)(LPSTR)""); break;
		case IDM_CUT  : SendDlgItemMessage(hDlg, IDEDIT, WM_CUT  , 0, 0); break;
		case IDM_UNDO : SendDlgItemMessage(hDlg, IDEDIT, EM_UNDO , 0, 0); break;
		case IDM_COPY : SendDlgItemMessage(hDlg, IDEDIT, WM_COPY , 0, 0); break;
		case IDM_PASTE: SendDlgItemMessage(hDlg, IDEDIT, WM_PASTE, 0, 0); break;
		case IDM_ALL:
		#ifdef WIN32
			SendDlgItemMessage(hDlg, IDEDIT, EM_SETSEL, 0, -1); break;
		#else
			SendDlgItemMessage(hDlg, IDEDIT, EM_SETSEL, 0, MAKELONG(0,-1)); break;
		#endif
		case IDM_FOLD:
		case IDM_HELP:
			MessageBox(hDlg, "未サポート","簡易テキストエディタ", MB_OK);
			break;
		}
		break;
	case WM_DESTROY:
		PostQuitMessage(0);
		break;
	case WM_SIZE:
		GetClientRect (hDlg, &rc);
		MoveWindow(GetDlgItem(hDlg, IDEDIT) , 0, 0, rc.right, rc.bottom, TRUE);
		break;
	case WM_INITDIALOG:
		SetTitleBar(hDlg, NULL);
		GetClientRect (hDlg, &rc);
		MoveWindow(GetDlgItem(hDlg, IDEDIT) , 0, 0, rc.right, rc.bottom, TRUE);
		return TRUE;/* SetFocusしたらFALSE */
	default:
		return FALSE; /*メッセージを処理しなかった*/
	}
	return TRUE; /*メッセージを処理した*/
}
/*メイン関数*/
int PASCAL WinMain(HINSTANCE hinst, HINSTANCE hprev, LPSTR cmdline, int cmdshow){
	DLGPROC lpProc = (DLGPROC)MakeProcInstance((FARPROC)dlgproc, hinst);
	MSG msg;
	hDlgMain=CreateDialog(hinst, "editdlg", NULL, lpProc);/*ここでダイアログボックスを作成*/
	lpSearch  = (DLGPROC)MakeProcInstance((FARPROC)searchdlg,  hinst);
	lpReplace = (DLGPROC)MakeProcInstance((FARPROC)replacedlg, hinst);
	hInstApp=hinst;
	while (GetMessage(&msg, NULL, 0, 0)) {
		if ((hDlgSearch ==NULL || !IsDialogMessage(hDlgSearch,  &msg)) &&
		    (hDlgReplace==NULL || !IsDialogMessage(hDlgReplace, &msg))){
			TranslateMessage(&msg);
			DispatchMessage(&msg);
		}
	}
	FreeProcInstance((FARPROC)lpSearch);
	FreeProcInstance((FARPROC)lpReplace);
	FreeProcInstance((FARPROC)lpProc);
	return 0;
}

ファイル名:edit.def

NAME	EDIT
DESCRIPTION  'EDIT: EASY TEXT EDITOR'
EXETYPE WINDOWS
STUB	    'WINSTUB.EXE'
CODE    PRELOAD MOVEABLE
DATA    MOVEABLE PRELOAD MULTIPLE
HEAPSIZE  4096
STACKSIZE 8192
EXPORTS
	DLGPROC    @1
	SEARCHDLG  @2
	REPLACEDLG @3
戻る