윈폼(winform) 메모장 예제
인쇄
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using System.IO;//**
namespace MemoEx
{
public partial class Memo : Form
{
#region 멤버 변수
//멤버 변수(살려두기 위해서.. or 모든 메서드에서 접근)
private string currentFileName;//현재 열린 파일명
private bool isModified;//열린 파일의 수정
private int linesPrinted;//인쇄 라인 수
private string oldFind;//이전에 검색했던 검색어
private bool isNew;//새파일
private FindForm ff;//찾기 대화상자
private ReplaceForm rf;//바꾸기 대화상자
private GotoForm gf;//줄이동 대화상자
#endregion
public Memo()
{
InitializeComponent();
//파일 연 후 수정하지 않음
this.isModified = false;
this.isNew = true;
}
private void Memo_Load(object sender, EventArgs e)
{
//초기화
this.Text = "제목없음 - 메모장";
this.currentFileName = "제목없음.txt";
//대화상자
this.openFileDialog1.Filter = "텍스트 파일|*.txt|C# 파일|*.cs|모든 파일|*.*";
this.saveFileDialog1.Filter = "텍스트 파일|*.txt|C# 파일|*.cs|모든 파일|*.*";
this.fontDialog1.Font = richTextBox1.Font;
}
#region 파일 메뉴
private void 끝내기XToolStripMenuItem_Click(object sender, EventArgs e)
{
//메모장 종료
Application.Exit();
}
private void 열기OToolStripMenuItem_Click(object sender, EventArgs e)
{
//수정된 내용이 아직 저장 전이라면..
if (this.isModified)
{
string msg = string.Format("{0} 파일의 내용이 변경되었습니다.\r\n\r\n변경된 내용을 저장하시겠습니까?",
Path.GetFileName(this.currentFileName));
DialogResult result = MessageBox.Show(msg, "메모장", MessageBoxButtons.YesNoCancel,
MessageBoxIcon.Exclamation);
if (result == DialogResult.Yes)
{
//저장 메뉴 실행과 동일
저장SToolStripMenuItem_Click(null, null);
}
else if (result == DialogResult.Cancel)
{
//취소 -> 파일 열기 실행 X
return;
}
else
{
}
}
//텍스트 파일 열기(UTF-8)
if (openFileDialog1.ShowDialog() == DialogResult.OK)
{
//열기로 한 파일 전체 경로
string file = openFileDialog1.FileName;
//읽기 위한 StreamReader 생성
StreamReader reader = new StreamReader(file);
//읽은 내용을 텍스트 박스에 출력
richTextBox1.Text = reader.ReadToEnd();
//스트림 닫기
reader.Close();
//C:\Test\memo.txt
//열린 파일명으로 제목 바꾸기
this.Text = Path.GetFileName(file) + " - 메모장";
//파일을 열고 난 직후!! -> 수정하지 않은 상태
this.isModified = false;
//열린 파일명을 저장
this.currentFileName = file;
//파일을 열기 != 새파일
this.isNew = false;
}
}
private void 저장SToolStripMenuItem_Click(object sender, EventArgs e)
{
//richTextBox1의 텍스트를 물리적인 *.txt파일로 저장하기
//새로 만든 파일인지? 기존에 있던 파일을 연 상태?
if (isNew)
{
//새로 만든 파일..
if (saveFileDialog1.ShowDialog() == DialogResult.OK)
{
this.currentFileName = saveFileDialog1.FileName;//사용자가 선택한 저장할 파일명
}
else
{
return;//저장하기 취소
}
}
//파일 저장
StreamWriter writer = new StreamWriter(this.currentFileName);
writer.Write(richTextBox1.Text.Replace("\r", "").Replace("\n", "\r\n"));
writer.Close();
//제목 바꾸기
this.Text = Path.GetFileName(this.currentFileName) + " - 메모장";
//수정 유무
this.isModified = false;
//새파일 유무
this.isNew = false;
}
private void 다른이름으로저장AToolStripMenuItem_Click(object sender, EventArgs e)
{
//다른 이름으로 저장하기
saveFileDialog1.FileName = this.currentFileName;
if (saveFileDialog1.ShowDialog() == DialogResult.OK)
{
StreamWriter writer = new StreamWriter(saveFileDialog1.FileName);
writer.Write(richTextBox1.Text.Replace("\n", "\r\n"));
writer.Write(richTextBox1.Text.Replace("\r", "").Replace("\n", "\r\n"));
writer.Close();//파일 저장
//저장된 파일명으로 제목 바꾸기
this.Text = Path.GetFileName(saveFileDialog1.FileName) + " - 메모장";
//저장을 했다는 것은 수정된 부분 없음
this.isModified = false;
//다른이름으로 저장도 != 새파일이 아니다.
this.isNew = false;
}
}
private void 새로만들기NToolStripMenuItem_Click(object sender, EventArgs e)
{
if (this.isModified)
{
string msg = string.Format("{0} 파일의 내용이 변경되었습니다.\r\n\r\n변경된 내용을 저장하시겠습니까?",
Path.GetFileName(this.currentFileName));
DialogResult result = MessageBox.Show(msg, "메모장", MessageBoxButtons.YesNoCancel,
MessageBoxIcon.Exclamation);
if (result == DialogResult.Yes)
{
//저장 메뉴 실행과 동일
저장SToolStripMenuItem_Click(null, null);
}
else if (result == DialogResult.Cancel)
{
//취소 -> 새로 만들기 X
return;
}
}
//새로 만들기 작업
richTextBox1.Text = "";
this.currentFileName = "제목없음.txt";
this.isModified = false;
this.isNew = true;
this.Text = "제목없음 - 메모장";
}
private void Memo_FormClosing(object sender, FormClosingEventArgs e)
{
//변경되고 난 후에 아직 저장X -> 닫기 시도
if (this.isModified)
{
string msg = string.Format("{0} 파일의 내용이 변경되었습니다.\r\n\r\n변경된 내용을 저장하시겠습니까?",
Path.GetFileName(this.currentFileName));
DialogResult result = MessageBox.Show(msg, "메모장", MessageBoxButtons.YesNoCancel,
MessageBoxIcon.Exclamation);
if (result == DialogResult.Yes)
{
//저장 메뉴 실행과 동일
저장SToolStripMenuItem_Click(null, null);
}
else if (result == DialogResult.Cancel)
{
//취소 -> 폼닫기 취소
e.Cancel = true;
}
}
}
private void 인쇄미리보기VToolStripMenuItem_Click(object sender, EventArgs e)
{
//인쇄 미리보기
printPreviewDialog1.ShowDialog();
}
private void 인쇄PToolStripMenuItem_Click(object sender, EventArgs e)
{
printDocument1.Print();
}
private void printDocument1_PrintPage_1(object sender, System.Drawing.Printing.PrintPageEventArgs e)
{
//인쇄 명령이 실행될때 발생
//텍스트 -> 도화지 옮겨 그리기 작업을 구현
//1. 출력할 내용
string[] txts = richTextBox1.Lines;
//2. 가상 문서에 출력할 위치 선정
int x = 20;
int y = 50;
//3. 한줄씩 그리기
this.linesPrinted = 0;
while (this.linesPrinted < txts.Length)
{
e.Graphics.DrawString(txts[linesPrinted], richTextBox1.Font, new SolidBrush(richTextBox1.ForeColor), x, y);
//줄간격
y += (int)richTextBox1.Font.Size + 10;
//페이지가 넘치면..
if (y >= e.PageBounds.Height - 100)
{
//다음 페이지로 이동
e.HasMorePages = true;
return;
}
linesPrinted++;
}
//옮겨 적기 완료
this.linesPrinted = 0;
e.HasMorePages = false;
}
#endregion
#region 편집 메뉴
private void 실행취소UToolStripMenuItem_Click(object sender, EventArgs e)
{
richTextBox1.Undo();
}
private void 잘라내기TToolStripMenuItem_Click(object sender, EventArgs e)
{
richTextBox1.Cut();
}
private void 복사CToolStripMenuItem_Click(object sender, EventArgs e)
{
richTextBox1.Copy();
}
private void 붙여넣기PToolStripMenuItem_Click(object sender, EventArgs e)
{
richTextBox1.Paste();
}
private void 삭제LToolStripMenuItem_Click(object sender, EventArgs e)
{
if (richTextBox1.SelectionLength == 0)
{
richTextBox1.SelectionLength = 1;
}
richTextBox1.SelectedText = "";
}
private void 모두선택AToolStripMenuItem_Click(object sender, EventArgs e)
{
richTextBox1.SelectionStart = 0;
richTextBox1.SelectionLength = richTextBox1.Text.Length;
}
private void 시간날짜DToolStripMenuItem_Click(object sender, EventArgs e)
{
richTextBox1.SelectedText = DateTime.Now.ToString();
}
private void 찾기FToolStripMenuItem_Click(object sender, EventArgs e)
{
//이미 찾기 창이 띄어져 있는 경우..
if (!(this.ff == null || !ff.Visible))
{
ff.Focus();
return;
}
//찾기폼 생성
this.ff = new FindForm();
//1. 메모창에서 선택된 문자열 있으면 찾기폼의 텍스트박스의 기본값으로 복사
if (richTextBox1.SelectionLength > 0)
{
this.ff.textBoxSearch.Text = richTextBox1.SelectedText;
}
else
{
this.ff.textBoxSearch.Text = this.oldFind;
}
//검색어가 입력이 되어 있다면 찾기버튼이 활성
this.ff.textBoxSearch.TextChanged += new EventHandler(textBoxSearch_TextChanged);
textBoxSearch_TextChanged(null, null);
//찾기폼의 찾기 버튼 클릭이벤트
this.ff.buttonFind.Click += new EventHandler(buttonFind_Click);
this.ff.Show();
}
void buttonFind_Click(object sender, EventArgs e)
{
//검색어 찾기
string txt = richTextBox1.Text;//전체 문자열
string search = this.ff.textBoxSearch.Text;//검색어
//대소문자 구분
if (!this.ff.checkBoxCase.Checked)
{
//구분X
txt = txt.ToLower();
search = search.ToLower();
}
//찾기
int index = -1;//찾은 위치
if (this.ff.radioButtonDown.Checked)
{
//아래로 검색
index = txt.IndexOf(search, richTextBox1.SelectionStart + richTextBox1.SelectionLength);
}
else
{
//위로 검색
index = txt.LastIndexOf(search, richTextBox1.SelectionStart - 1);
}
//더이상 검색어가 발견되지 않으면
if (index == -1)
{
MessageBox.Show("더 이상 찾는 문자열이 없습니다.");
return;//메서드 종료
}
//찾은 단어는 선택영역으로 표시
richTextBox1.SelectionStart = index;
richTextBox1.SelectionLength = search.Length;
//다음번에 찾기를 할때 선택 영역이 없으면 이전 찾았던 검색어를 기본값 사용
this.oldFind = search;
}
//찾기폼의 텍스트박스의 값이 변경될때마다..
void textBoxSearch_TextChanged(object sender, EventArgs e)
{
//검색어 있는냐?
if (this.ff.textBoxSearch.Text != "")
this.ff.buttonFind.Enabled = true;
else
this.ff.buttonFind.Enabled = false;
}
private void 다음찾기NToolStripMenuItem_Click(object sender, EventArgs e)
{
if (ff == null || !ff.Visible)
{
ff = new FindForm();
ff.Hide();
}
ff.textBoxSearch.Text = this.oldFind;
//다음찾기 버튼 클릭***
buttonFind_Click(null, null);
}
#endregion
#region 서식 메뉴
#endregion
#region 보기 메뉴
#endregion
#region 도움말 메뉴
private void 메모장정보AToolStripMenuItem_Click(object sender, EventArgs e)
{
//메모장 정보
About about = new About();
about.StartPosition = FormStartPosition.CenterParent;//**Modal에게만 적용 한가운데 뜨게하기 위함
about.ShowDialog();
}
#endregion
private void richTextBox1_TextChanged(object sender, EventArgs e)
{
//텍스트를 수정했음!!
this.isModified = true;
}
private void 페이지설정UToolStripMenuItem_Click(object sender, EventArgs e)
{
pageSetupDialog1.ShowDialog();
}
private void 보기VToolStripMenuItem_Click(object sender, EventArgs e)
{
}
private void 바꾸기RToolStripMenuItem_Click(object sender, EventArgs e)
{
//이미 존재하면..폼을 다시 생성하지 않기 위해서.
if (!(this.rf == null || !rf.Visible))
{
rf.Focus();
return;
}
//존재하지 않으면 새로 생성
this.rf = new ReplaceForm();
//선택영역이 있으면 초기화. 없으면 예전 검색어
if (richTextBox1.SelectionLength > 0)
{
this.rf.textBoxSearchR.Text = richTextBox1.SelectedText;
}
else
{
this.rf.textBoxSearchR.Text = this.oldFind;
}
//버튼 이벤트
rf.buttonFindR.Click += new EventHandler(buttonFindR_Click);
rf.buttonReplace.Click += new EventHandler(buttonReplace_Click);
rf.buttonReplaceAll.Click += new EventHandler(buttonReplaceAll_Click);
//창 띄우기
rf.Show();
}
void buttonReplaceAll_Click(object sender, EventArgs e)
{
richTextBox1.Text = richTextBox1.Text.Replace(this.rf.textBoxSearchR.Text, this.rf.textBoxReplace.Text);
}
void buttonReplace_Click(object sender, EventArgs e)
{
//바꾸기
//1. 선택 영역이 없으면 찾기 버튼을 클릭한 효과
if (richTextBox1.SelectionLength == 0 || richTextBox1.SelectedText != this.rf.textBoxSearchR.Text)
{
buttonFindR_Click(null, null);
return;//다음 검색어만 찾고 종료
}
//2. 선택된 문자열을 바꿀 문자열로 치환
// - 이곳까지 왔으면 무조건 바꾸고자 하는 검색어가 선택영역으로 잡혀있음!!!
richTextBox1.SelectedText = this.rf.textBoxReplace.Text;//바꾸기**
//3. 또 찾기 버튼을 클릭
buttonFindR_Click(null, null);
}
void buttonFindR_Click(object sender, EventArgs e)
{
//검색어 찾기
string txt = richTextBox1.Text;//전체 문자열
string search = this.rf.textBoxSearchR.Text;//검색어
//대소문자 구분
if (!this.rf.checkBoxCaseR.Checked)
{
//구분X
txt = txt.ToLower();
search = search.ToLower();
}
//찾기
int index = -1;//찾은 위치
//아래로 검색
index = txt.IndexOf(search, richTextBox1.SelectionStart + richTextBox1.SelectionLength);
//더이상 검색어가 발견되지 않으면
if (index == -1)
{
MessageBox.Show("더 이상 찾는 문자열이 없습니다.");
return;//메서드 종료
}
//찾은 단어는 선택영역으로 표시
richTextBox1.SelectionStart = index;
richTextBox1.SelectionLength = search.Length;
//다음번에 찾기를 할때 선택 영역이 없으면 이전 찾았던 검색어를 기본값 사용
this.oldFind = search;
}
private void 이동GToolStripMenuItem_Click(object sender, EventArgs e)
{
//줄이동
//richTextBox1.SelectionStart = 10;
if (!(this.gf == null || !gf.Visible))
{
gf.Focus();
return;
}
gf = new GotoForm();
//줄이동
gf.buttonOk.Click += new EventHandler(buttonOk_Click);
//현재 캐럿의 위치가 몇란인인지 알아낸후 줄이동창의 기본값
int nowLineNumber = richTextBox1.GetLineFromCharIndex(richTextBox1.SelectionStart);
nowLineNumber++;
this.gf.textBoxLine.Text = nowLineNumber.ToString();
gf.ShowDialog();
}
void buttonOk_Click(object sender, EventArgs e)
{
//1. 전체 라인의 수
int totalLines = richTextBox1.Lines.Length;
//2. 사용자 입력값
int gotoLine = 0;
try
{
gotoLine = int.Parse(this.gf.textBoxLine.Text);
}
catch
{
MessageBox.Show("올바른 줄 번호가 아닙니다.", "메모장 - 줄 이동");
return;
}
//3. 유효성 검사
if (gotoLine < 1 || gotoLine > totalLines)
{
MessageBox.Show("줄 번호가 범위를 벗어납니다.", "메모장 - 줄 이동");
this.gf.textBoxLine.Text = totalLines.ToString();
return;
}
//4. 줄 이동
int pos = 0;
richTextBox1.SelectionStart = 0;
for (int i = 0; i < (gotoLine - 1); i++)
{
pos += richTextBox1.Lines[i].Length;
pos++;
}
richTextBox1.SelectionStart = pos;
this.gf.Close();
}
private void 자동줄바꿈WToolStripMenuItem_Click(object sender, EventArgs e)
{
if (자동줄바꿈WToolStripMenuItem.Checked)
{
자동줄바꿈WToolStripMenuItem.Checked = false;
richTextBox1.WordWrap = false;
상태표시줄SToolStripMenuItem.Enabled = true;
statusStrip1.Visible = true;
}
else
{
자동줄바꿈WToolStripMenuItem.Checked = true;
richTextBox1.WordWrap = true;
상태표시줄SToolStripMenuItem.Enabled = true;
statusStrip1.Visible = true;
}
}
private void 상태표시줄SToolStripMenuItem_Click(object sender, EventArgs e)
{
if (상태표시줄SToolStripMenuItem.Checked)
{
상태표시줄SToolStripMenuItem.Checked = statusStrip1.Visible = false;
}
else
{
상태표시줄SToolStripMenuItem.Checked = true;
statusStrip1.Visible = true;
}
}
private void 글꼴FToolStripMenuItem_Click(object sender, EventArgs e)
{
fontDialog1.Font = richTextBox1.Font;
if (fontDialog1.ShowDialog() == DialogResult.OK)
{
richTextBox1.Font = fontDialog1.Font;
}
}
private void richTextBox1_KeyUp(object sender, KeyEventArgs e)
{
//현재 작업중인 라인 표시
//1. 편집상태가 저장완료0, 전0
if (this.isModified)
toolStripStatusLabel1.Text = "*";
else
toolStripStatusLabel1.Text = "";
//2. 현재 작업중인 라인수 표시
toolStripStatusLabel2.Text = "줄 : " + (richTextBox1.GetLineFromCharIndex(richTextBox1.SelectionStart) + 1).ToString();
}
}
}