퇴근5분전


 회사에서 hwp 파일에 대해 모바일 지원 검토를 해보라고 하길래...

지난번 한글에서 표준문서포멧이 떠올라서 재미삼아 파일을 분해해보는데, 처음부터 걸리는게 너무 많았다.

 우선 포멧서에 나온 미리보기 이미지 PreImage 라는 태그로 있기에 이걸 뽑아올 수 있다면 이걸 페이지에 뿌리면 좋을텐데 라고 생각해서 시도하였다.

Compound File 규격으로 포멧팅 되어 있는 파일을 Stream으로 읽어들여서 규격서에 나온대로
BinaryReader를 이용해서 256을 짤랐는데. 당췌... 아무것도 안나온다.

Unicode, UTF-8 로 인코딩을 아무리 해봐도 제대로 보이는게 없을정도니까...

하다 하다 안되길래 Free로 된 Compound File 관련 뷰어 소스를 두세개 받아서 디버깅 해보았다.

우선 확인된 사항은 PreImage 는 아이콘에 미리보기용으로 만들어지는 이미지임을 확인했다.

소용없다는 얘기..

그래서 왜 아무것도 안나오는지 소스를 디버깅 걸면서 하나 하나 추적해보았더니... 쉐뜨.

Compound File 자체게 어떤 표준이 있어서 내부 RootEntry 전에 헤더값이 존재하는듯 하다.

다 걸러내고 RootEntry부터는 다음 Entry까지 binary를 Seek하면서 트리로 끌어올리는것을 확인하였다.

파일 형태는 대략

RootEntry .....  RootEntry
DocInfo ... DocInfo
PreImage ... PreImage

처럼... 앞태그  내용   뒷태그  형태로 존재하는듯 하다.

반나절 고생하고 소스 디버깅 3시간... 정도 하니 지친다.

결론은 저거 다 분석하면 한글 뷰어를 만들수 있다는거? 정도??? 
 
그러나 그닥 이득이 되지 않으므로... 여기서 마무리...

Compound File 이란 형태의 파일도 존재하는구나 했음... 음.. 멋진데?



'# 1) 프로그래밍' 카테고리의 다른 글

[C#] 배열 최대 크기  (0) 2011.04.26
ActiveDirectory] Query  (0) 2011.04.19
문자열 첫번째 검색 문자만 Replace  (0) 2010.09.30
일자가 해당 월에 몇주차인지 구하는 법.  (0) 2010.09.30
DateTime관련..  (0) 2010.09.09

"문자"를 "_"로 변경할때 그냥 문자열에 Replace를 하면 조건에 걸리는것 모두를 변경..

훈스 게시판에 처음 조건에 걸리는것만 바꾸는 메서드가 자바에서 지원이 된다기에... 

만들어봤다. 

// 사용예!
   string ss = "바뀔문자,바뀐문자,바꿔봐요!".ReplaceFirst("문자", "_");

결과 : 바뀔_,바뀐문자,바꿔봐요!".
  

// 확장 메서드 구현

  public static class StringEX
    {
        public static string ReplaceFirst(this string s, string re, string ch)
        {
            int offsetIndex = s.IndexOf(re) + re.Length;
            string first = s.Substring(0, s.IndexOf(re));
            string midle = ch;
            string last = s.Substring(s.IndexOf(re) + re.Length, s.Length - offsetIndex);
            return string.Concat(first, midle, last);
        }
    }


'# 1) 프로그래밍' 카테고리의 다른 글

ActiveDirectory] Query  (0) 2011.04.19
HWP 바이너리 파일...  (0) 2011.03.23
일자가 해당 월에 몇주차인지 구하는 법.  (0) 2010.09.30
DateTime관련..  (0) 2010.09.09
피벗 메서드  (0) 2010.08.26


 제목 달기 어렵네.. 

    // 테스트용도.
     for (int day = 1; day <= 31; day++)
     {
         int wcnt1 = GetWeeksOfYear(new DateTime(2010, 10, day));
         int wcnt2 = GetWeeksOfMonth(new DateTime(2010, 10, day));
         textBox1.AppendText(string.Format("{0} : {1}주차 / {0} : {2}주차" + Environment.NewLine,
                                                              day, wcnt1,             wcnt2));

     }

     // 내가 만든 것.
     private static int GetWeekCnt(DateTime dt)
        {
            int week =  Enum.GetValues( typeof( DayOfWeek) ).Length;
            int dayOffset = (int)dt.AddDays(-(dt.Day - 1)).DayOfWeek;
            int weekCnt = (dt.Day + dayOffset) / week ;
            weekCnt += ((dt.Day + dayOffset) % week ) > 0 ? 1 : 0;
            return weekCnt;
        }

   // 훈스에 몬난아님이 검색하신걸 내가 수정한것.
   // 이건 해당 년도에 주차 수를 구한다.
        public int GetWeeksOfYear(DateTime date)
        {
            System.Globalization.CultureInfo cult_info = System.Globalization.CultureInfo.CreateSpecificCulture("ko");
            System.Globalization.Calendar cal = cult_info.Calendar;
            int weekNo = cal.GetWeekOfYear(date, cult_info.DateTimeFormat.CalendarWeekRule, cult_info.DateTimeFormat.FirstDayOfWeek);
            int week1day = cal.GetWeekOfYear(date.AddDays( -( date.Day+1 )), cult_info.DateTimeFormat.CalendarWeekRule, cult_info.DateTimeFormat.FirstDayOfWeek);
            return weekNo - week1day + 1;
        }

음...

'# 1) 프로그래밍' 카테고리의 다른 글

HWP 바이너리 파일...  (0) 2011.03.23
문자열 첫번째 검색 문자만 Replace  (0) 2010.09.30
DateTime관련..  (0) 2010.09.09
피벗 메서드  (0) 2010.08.26
새로운 프로젝트 & 6월에 나의 프로젝트!  (0) 2010.06.03


DateTime fromDT = DateTime.ParseExact("201011", "yyyyMM", null);

위처럼 하면 포멧 기준을 뒤에 적어주면 날자값으로 변경해서 반환 해준다.


참고로 기간중 Month 개월수 구하는 로직..

    DateTime fromDT = DateTime.ParseExact("201011", "yyyyMM", null);
    DateTime toDT = DateTime.ParseExact("201012", "yyyyMM", null);

            int month = 0;
            try
            {
                while (true)
                {
                    if (fromDT.AddMonths(month).CompareTo(toDT) >= 0)
                    {
                        break;
                    }
                    month++;
                }
            }
            catch
            {
                month = 0;
            }



쿼리상에서의 피벗은 집계함수를 적용해야 하는데...

챠트를 구현하면서 나온 데이타를 피벗할필요없이 특정 컬럼을 기준으로 대상데이타를 가로축으로 변경하고자 할때 사용하면 됨.


이하 소스.

그리드뷰 4개를 놓고 왼쪽은 기본데이타 오른쪽은 피벗된 데이타.

Pivot(DataTable sourceTb, string sBaseColumnName, string sBaseHeaderColumnName, string RotColumnName)  : DataTable

소스 테이블, 컬럼이 될 데이타를 가진 컬럼명,   컬럼의 설명이 들어간 컬럼,  데이타컬럼

   피봇 전                                                            피봇 후





namespace PIVOT_TABLE
{
    public partial class Form1 : Form
    {
        public Form1()
        {
            InitializeComponent();

            DataTable sourceTable = new DataTable();
            sourceTable.Columns.Add("YM_MAGAM");
            sourceTable.Columns.Add("CD_GMGS");
            sourceTable.Columns.Add("DS_GMGS");
            sourceTable.Columns.Add("AM_CURRENT1");

            sourceTable.Rows.Add(201006, "F100000", "유동비율(%)", 120.2);
            sourceTable.Rows.Add(201006, "F100100", "부채비율(%)", 367.6);
            sourceTable.Rows.Add(201006, "F100200", "차입금의존도(%)", 63.3);
            sourceTable.Rows.Add(201006, "F100300", "영업이익이자보상배율(배)", 0.1);
            sourceTable.Rows.Add(200912, "F100000", "유동비율(%)", 130.3);
            sourceTable.Rows.Add(200912, "F100100", "부채비율(%)", 207.0);
            sourceTable.Rows.Add(200912, "F100200", "차입금의존도(%)", 47.8);
            sourceTable.Rows.Add(200912, "F100300", "영업이익이자보상배율(배)", 2.4);
            sourceTable.Rows.Add(200812, "F100000", "유동비율(%)", 135.8);
            sourceTable.Rows.Add(200812, "F100100", "부채비율(%)", 107.2);
            sourceTable.Rows.Add(200812, "F100200", "차입금의존도(%)", 27.0);
            sourceTable.Rows.Add(200812, "F100300", "영업이익이자보상배율(배)", 2.7);

            dataGridView1.DataSource = sourceTable;


            dataGridView2.DataSource = Pivot(sourceTable, "CD_GMGS", "DS_GMGS", "AM_CURRENT1");


            DataTable sourceTable1 = new DataTable();
            sourceTable1.Columns.Add("YM_MAGAM");
            sourceTable1.Columns.Add("AM_JUMSU");


            sourceTable1.Rows.Add(200612,  null);
            sourceTable1.Rows.Add(200712,  null);
            sourceTable1.Rows.Add(200812,  null);
            sourceTable1.Rows.Add(200912,  27.5000);
            sourceTable1.Rows.Add(201006,  20.0000);

            dataGridView3.DataSource = sourceTable1;

            dataGridView4.DataSource = Pivot(sourceTable1, "YM_MAGAM", "YM_MAGAM", "AM_JUMSU");

        }

        /// <summary>
        /// 피벗 메서드.
        /// 소스 데이타를 특정 컬럼 기준으로 컬럼으로 확장 후 데이타를 확장컬럼에 넣어서 반환해줌.
        /// 추가 : 챠트에 쓰기 위해 NO를 추가해서 넘버링 함. ( 기준 BindingX 값으로 사용함 )
        /// 추가 : 나머지 컬럼은 모두 제자리.
        /// </summary>
        /// <param name="sourceTb"> 변환 될 데이타 테이블</param>
        /// <param name="sBaseColumnName"> 컬럼변경 데이타를 가진 컬럼명</param>
        /// <param name="sBaseHeaderColumnName"> 컬럼에 대한 헤더컬럼.</param>
        /// <param name="RotColumnName"> 옮겨질 데이타. </param>
        /// <returns></returns>
        DataTable Pivot(DataTable sourceTb, string sBaseColumnName, string sBaseHeaderColumnName, string RotColumnName)
        {
            DataTable dt = new DataTable();
            int sBaseColumnIndex = sourceTb.Columns.IndexOf(sBaseColumnName);
            int sBaseHeaderColumnIndex = sourceTb.Columns.IndexOf(sBaseHeaderColumnName);
            int sRotColumnIndex = sourceTb.Columns.IndexOf(RotColumnName);

            dt.Columns.Add("_NO");
            for (int colIndex = 0; colIndex < sourceTb.Columns.Count; colIndex++)
            {
                if (sBaseColumnIndex == colIndex || sRotColumnIndex == colIndex || sBaseHeaderColumnIndex == colIndex) continue;
                dt.Columns.Add(string.Format("_{0}", sourceTb.Columns[colIndex].ColumnName));
            }

            string ColName = string.Empty;

            foreach (DataRow sBaseColumnRow in sourceTb.Rows)
            {
                ColName = sBaseColumnRow[sBaseColumnIndex].ToString();
                if (!dt.Columns.Contains(string.Format("_{0}", ColName)))
                {
                    dt.Columns.Add(string.Format("_{0}", ColName));
                    if (sBaseHeaderColumnIndex >= 0)
                        dt.Columns[dt.Columns.Count - 1].Caption = sBaseColumnRow[sBaseHeaderColumnIndex].ToString();
                }
            }
            int offsetCol = sBaseHeaderColumnIndex == -1 ? 2 : 3;

            // Row 한번에 뛰어넘을 간격을 계산함.
            int step = dt.Columns.Count - (sourceTb.Columns.Count - offsetCol) - 1; // 1은 NO 컬럼 몫.

            if (step <= 0)
            {
                throw new Exception("RowIndex 계산증가값은 0이하가 될수 없습니다.");
            }

            List<object> values = new List<object>();
            for (int rowIndex = 0; rowIndex < sourceTb.Rows.Count; rowIndex += step)
            {
                values.Add(dt.Rows.Count + 1);
                for (int colIndex = 0; colIndex < sourceTb.Columns.Count; colIndex++)
                {
                    if (sBaseColumnIndex == colIndex || sRotColumnIndex == colIndex || sBaseHeaderColumnIndex == colIndex) continue;

                    values.Add(sourceTb.Rows[rowIndex][colIndex]); // 기존 컬럼 복사
                }

                for (int i = 0; i < step; i++) // 세로로 된 기준 컬럼데이타를 가로로 복사함.
                {
                    if (sourceTb.Rows.Count <= rowIndex + i) break;
                    values.Add(sourceTb.Rows[rowIndex + i][sRotColumnIndex]);
                }
                dt.Rows.Add(values.ToArray<object>());
                values.Clear();
            }
            return dt;
        }


    }
}

새로 프로젝트에 투입되었음. 이랜드!

집에서는 나의 프로젝트를 시작함.

JsFW20 을 이용한 프로그램디자이너이다.

투표하고 곰곰히 설계를 몇번씩 뒤집어서 고민했다. 

우선 Biz 생성부분을 처리 하기 위한 로직을 그려보니 관련 xml처리를 하기 위해서는
JsFW20.XML 에 추가적인 확장이 필요해서 저녁내내 잡아서 데이타 변환 처리부분을 수정완료하였다.

오늘 집에가면 Update, Delete관련해서 확인하고 Biz 구성관련해서 간단한 디자인을 하고 코드산출을 해야겠다.

적절한 문서를 만들기 위한 툴에 익숙함이 부족해서인지 파워포인트(오픈오피스)가 손에 익지 않는다.

어떻게 하면 좋을까? 


문서작성을 위한 툴!! 객체를 표현하고 이를 이해하기 편하게 보여주는 툴...

1. UML을 이용한다.
2. 현재 있는 터치패드를 연결해서 노트가 아닌 그림판에 펜으로 그린다.
3. 파워포인트를 숙달한다. <-- 이건 내가 만들고자 하는 객체 표현법은 손이 너무 많이 감.
4. 툴을 만든다? --;;  방사형을 만들어볼까도 고민했는데.. 훔...



한글로 만들었더니 대박!!! 지저분함. ㅡ.,ㅡ;

----------------------------------------------------------- 훈스 팁게시판에 올린 글! 그대로..

소스를 보시고 대체 이건 뭥미? 하실텐데요...

오늘 질문게시판에 TextBox에 들어온 숫자의 갯수가 4개가 연속이면 제거해야된다는 글을

들어온 문자열중 4개가 중복되면 제거로 잘못보고 ㅡ.,ㅡ;;; 아래 클래스를 만들었었습니다.  난독증...

처음 클래스명과 변수명들은 모두 영문자로 늘 하던데로 대충.. 때려맞춰서 만들어놓고 보니

이걸 미친척 한글로 바꿔보고 싶은 생각이 문득 들어... 만들어보았습니다.

어떤가요?잘 지었는지? 검사와 검색이란 단어를 적용하려니.. 한글 사전없이는 힘든것 같네요.(아래도 불분명합니다. )

한글로 지어놓으니 대략 난감하네요. 하하하.

한글로 써놓으니 글씨 폰트도 영문자랑 안맞아서 그런지 많이 지저분하네요.

만들어본 목적

객체지향 <-- 을 되새기며 객체이름을 명시하고 기능을 명시하면서 코드를 문장으로 볼수 있다면... 이란 오랜

생각끝에 영어로 안되서 ㅡ.,ㅡ;; 한글로 도전해봤습니다.

중복문자처리객체.제거실행(  this.textBox1.Text  );

조금은 억지스럽지만 ^^ 미천한 실력으로 만들다보니 역시 미흡해보이는게 눈에 너무 띠네요.

이팁을 보시는 여러분들은 어떠신가요?

코드자체를 직독직해?  가능하신지요?? 객체를 얼마나 자연스러운 코드로 만드시는지요?

영어잘하시는분 넘 부러워요!!

사용법          

  만약 ) this.textBox1.Text = "aa abbccc c d e11 ffffc a aabbbbbb 22b 4444 66";

 데이타가 존재시... 아래와 같이 중복을 제거할수 있습니다.

숫자 2는 2개씩 체크합니다.

            using (중복문자제거클래스 중복문자처리객체 = new 중복문자제거클래스(2))
            {
                this.textBox1.Text = 중복문자처리객체.제거실행(this.textBox1.Text);
            }

    public class 중복문자제거클래스 : IDisposable
        {
            int 체크문자개수 = 0;

            int 현재위치 = 0;
            List<char> 검사문자저장소 = new List<char>();
            List<string> 중복문자목록 = new List<string>();

            public 중복문자제거클래스(int _체크문자갯수)
            {
                체크문자개수 = _체크문자갯수;
            }

            public string 제거실행(string 검사소스문자열)
            {
                string 제거된문자열 = "";
                현재위치 = 0;
                for (int loop = 0; loop < 검사소스문자열.Length; loop++)
                {                   
                    char? 검색대상문자 = 검색대상문자얻어내기(검사소스문자열);
                    if (검색대상문자 != null)
                    {                     
                        bool 검사여부 = 문자체크여부(검색대상문자.Value);

                        if (검사여부 == false)
                        {
                            중복문자체크(검사소스문자열, 검색대상문자.Value);
                        }
                        현재위치++;
                    }
                    if (현재위치 >= 검사소스문자열.Length - 1)
                    {
                        제거된문자열 = 문자변환(검사소스문자열).Replace("  ", " ");
                    }
                }
                return 제거된문자열;
            }

            private string 문자변환(string 검사소스문자열)
            {
                foreach (string 중복문자항목 in 중복문자목록)
                {
                    검사소스문자열 = 검사소스문자열.Replace(중복문자항목, "");
                }
                return 검사소스문자열;
            }

            private void 중복문자체크(string 검사소스문자열, char 검사대상문자)
            {
                try
                {
                    string 중복검사문자열 = new string(검사대상문자, 체크문자개수);
                    if (검사소스문자열.IndexOf(중복검사문자열, 현재위치) >= 0)
                    {
                        중복문자목록.Add(중복검사문자열);
                    }
                }
                catch{ }
            }

            private bool 문자체크여부(char 검색대상문자)
            {
                bool 체크여부 = false;
                if (검사문자저장소.Contains(검색대상문자))
                {
                    체크여부 = true;
                }
                else
                {
                    체크여부 = false;
                    검사문자저장소.Add(검색대상문자);
                }
                return 체크여부;
            }

            private char? 검색대상문자얻어내기(string 검사소스문자열)
            {
                char? 검색대상문자 = null;
                try
                {
                    검색대상문자 = 검사소스문자열[현재위치];
                }
                catch { }
                return 검색대상문자;
            }

            #region IDisposable 멤버

            public void Dispose()
            {
                검사문자저장소.Clear();
                중복문자목록.Clear();
                중복문자목록 = null;
                검사문자저장소 = null;
            }

            #endregion
        }


아래 소스는 훈스게시판에 중복문자열을 찾아서 지우는 질문이 있었는데 

숫자타입만을 제거한다고 된걸 못보고 만들었다. 질문을 대충보는 버릇때문인지...

아래는 변수명을 억지로 한글로 바꾸어봤는데... 대충 대충 지었더니... 영어보다 더 보기 어렵다...

집에서 다시 고쳐보자!! 한글로 뭔가 객체지향느낌이 나도록....


    public partial class Form1 : Form
    {
        public Form1()
        {
            InitializeComponent();
            this.textBox1.Text = "aa a bb c d e ffff c a aa bbbbbb b";
        }

        public class 중복문자제거 : IDisposable
        {
            int 중복체크문자갯수 = 0;

            int 인덱스 = 0;
            List<char> 문자히스토리 = new List<char>();
            List<string> 중복문자 = new List<string>();

            public 중복문자제거(int 문자갯수 )
            {
                중복체크문자갯수 = 문자갯수;
            }

            public string 실행(string 문자열소스)
            {
                string 반환문자열 = "";
                인덱스 = 0;
                for (int loop = 0; loop < 문자열소스.Length; loop++)
                {
                    // 검색문자 뽑기 
                    char? c = 검색문자뽑기(문자열소스);
                    if (c != null)
                    {
                        // hist와 체크
                        bool b = 문자체크(c.Value);

                        if (b == false)
                        {
                            중복문자체크(문자열소스, c.Value);
                        }
                        인덱스++;
                    }
                    if (인덱스 >= 문자열소스.Length - 1)
                    {
                        반환문자열 = 문자변환(문자열소스).Replace("  ", " ");
                      
                    }
                }
                return 반환문자열;

            }

            private string 문자변환(string 문자열소스)
            {
                foreach (string s in 중복문자)
                {
                    문자열소스 = 문자열소스.Replace(s, "");
                }
                return 문자열소스;
            }

            private void 중복문자체크(string 문자열소스, char 체크문자)
            {
                try
                {
                    string s = new string(체크문자, 중복체크문자갯수);
                    if (문자열소스.IndexOf(s, 인덱스) >= 0)
                    {
                        중복문자.Add(s);
                    }
                }
                catch
                {}
            }

            private bool 문자체크(char c)
            {
                bool ret = false;
                if (문자히스토리.Contains(c))
                {
                    ret = true;
                }
                else
                {
                    ret = false;
                    문자히스토리.Add(c);
                }
                return ret;
            }

            private char? 검색문자뽑기(string 문자열소스)
            {
                char? 뽑기문자 = null;
                try
                {
                    뽑기문자 = 문자열소스[인덱스];
                }
                catch { }
                return 뽑기문자;
            }

            #region IDisposable 멤버

            public void Dispose()
            {
                문자히스토리.Clear();
                중복문자.Clear();
                중복문자 = null;
                문자히스토리 = null;
            }

            #endregion
        }


        private void button1_Click(object sender, EventArgs e)
        {
            using (중복문자제거 cc = new 중복문자제거(2))
            {
                this.textBox1.Text = cc.실행(this.textBox1.Text);
            }
        }
    }


프로젝트가 지루해져가서 잠깐 딴짓을 해본다. 

 소요 시간 : 1시간반쯤? 기록 10분...쿵..,  
 도구 : 종이 두장. ( 낙서가 생각하는데 도움을 준다. )

 막상 글을 다 적고 보니 전공자가 아니라서 그런지 부족한게 보여도 채워넣기가 쉽지 않다.
몰라서이기도 하고, 알아야 하는것이 있음에도 그걸 익힐 시간이 만만치 않기에... (핑계~ )

제목처럼 글하나를 프로그래밍 해본다.( 조금은 복잡하게... 말이다. )

물론 저 간단한 문장을 쉽다면 아주 아주 쉽게, 어렵다면 어렵게... 상황에 맞춰서 코딩을 하겠지만...

코딩전 객체설계단계를 연습삼아.. 만들어보자! 우선은 글에서 나타난 객체들을 구상한다.

 (나) 라는 주체가 있고 (종이)와 (글)을 쓰는 (펜) 이 존재하게 된다. 


 음. 네가지의 객체가 서로 관련되어 있다. 이를 간단한 구상도( 나만에 방법 )를 그려보자.


 
음 위에 종이와 펜도 구체화 해보자.

 간단하다.   중간에 대리자나 객체 또는 인터페이스... 등등.. 선택하고 싶은걸 넣으면 된다. 

코딩에 들어가야겠지? 
굳이 대리자를 써본이유는

  public void Write(string wrMsg)
        {
            _wPen.Data = wrMsg;
            //_wPaper.Get(_wPen.Draw);  // 기본사용..

            _wPaper.Get(delegate(Graphics g) {   
                g.DrawString(wrMsg, new Font("궁서체", 20f), Brushes.Red, new PointF(10, 100));
            });
        }

이걸 기록하기 위해서다.
( 반드시 제공되는 소스대로가 아닌 취향에 맞게 변경할수도 있다는 것을 제공해주기 위한 배려?...
    : 이걸 제공함으로 원치 않은 동작이 나타날수 있으니.. 설계시 설계자의 판단에 맞겨야겠지?  )
{
 * 국어인 한글을 단어 찾아보면서 써야되겠네... 
  반드시   [부사] 틀림없이 꼭.
  반듯이   [부사] 찾아보기: 반듯하다
}
아래는 소스 전문이다.

폼에 버튼 하나 추가되있고 버튼에 Click이벤트를 추가한것 뿐이다. 

위 구성도가 있으니... 주석은 패쑤!

 public partial class Form1 : Form
    {
        Writer me = null;
        Paper paper = null;
        Pen pen = null;
        public Form1()
        {
            InitializeComponent();
            pen = new Pen();
            paper = new Paper(this);
            pen.Penfont = this.Font;
            me = new Writer( pen, paper );
        }

        protected override void OnFormClosed(FormClosedEventArgs e)
        {
            base.OnFormClosed(e);
            pen = null;
            paper.Dispose();
            paper = null;
            me = null;
        }

        private void button1_Click(object sender, EventArgs e)
        {
            me.Write("가나다라");
        }
    }

    public class Writer
    {
        Pen _wPen = null;
        Paper _wPaper = null;

        public Writer(Pen p1, Paper p2)
        {
            _wPaper = p2;
            _wPen = p1;
        }

        public void Write(string wrMsg)
        {
            _wPen.Data = wrMsg;
            _wPaper.Get(_wPen.Draw);
        }
    }

    public delegate void Delegate_Draw(Graphics paper);

    public class Paper : IDisposable
    {
        Graphics _g = null;

        public Paper( Control ctrl)
        {
            _g = Graphics.FromHwnd( ctrl.Handle );
        }

        public void Get(Delegate_Draw toolDraw)
        {
            toolDraw(_g);
        }

        #region IDisposable 멤버

        public void Dispose()
        {
            _g.Dispose();
            _g = null;
        }

        #endregion
    }

    public class Pen
    {
        string _data = string.Empty;

        public string Data
        {
            get { return _data; }
            set { _data = value; }
        }

        Font _penfont;

        public Font Penfont
        {
            get { return _penfont; }
            set { _penfont = value; }
        }

        public void Draw(Graphics  g)
        {
            g.DrawString(_data, _penfont, Brushes.Black, new PointF());
        }
    }













 



오픈 오피스로 작성해두었던 일부이다.

서버 - 클라이언트 간 패킷 전송은 이전 글에서 처럼 CommPack이 맡아서 한다.
여기에 실제 응용에서 사용될 데이타들을 실어서 보내게 되는 개념이다.

추후에 이점으로 작용하는것은 응용프로그램 모델만 신경쓰면된다 tcpip를 래핑해두었기에
구지 통신패킷까지 재구성할 필요가 없었진다.  앞으로 추가적인 실어보내는 데이타 패킷만 만들면 된다.

 테스트용으로 문자열전송만 테스트 했으나 아주 아주 잘되기에 ...

 시간이 되면... 메신져 모델링을 해보고 위 래핑 객체를 써서 만들어보든가...


 이글을 쓰는 지금.. 또는 가끔... 내가 너무 옛날 기술들에 대해 집착하는것이 아닌가? 싶어진다.
물론 요새도 c개발자들은 일을 하고 있는데

 C#이란 언어를 하면서 보아온 잘하는 사람들을 보면 대부분 이런 구현에 치중하지 않아보인다. 물론 잘할테니까...
앞을 바라보며... 늘 앞서가는 모습들만 보게된다. 그렇다면 난 ? 언제쯤.. 앞으로도 계속 잡을수 없는가?

비전공이기에?? 이제 닉을 바꿀까? 비전공으로? 훔....

 나름 프로그래밍은 학력보다 실력이 우선시 되지 않을까 하여 기대감에 시작했는데 이래저래... 안되는것도 같고...
... 넋두리나 읊자는건 아니고.. 


지금 TCP/IP를 이렇게 만들어두는게 의미가 있는것일까? ... 자꾸 만들어놔야지 했던것을 미뤘던것도... 자꾸 이럴 필요가 있을까? 라는 의문이 자꾸 내게 들어서 였다.

WCF라는 기술이 있는데... 훔... 다음 버젼은 WCF? 하하 또 만들다 마는건가?