출처 : 데브피아(조휘경님 글)


실무에서 프로젝트를 수행하다 보면 매번 중복되는 작업을 하게 된다. 예를 들면 레지스트리의 값을 읽고 쓰는 작업, GDI를 이용한 그래픽 작업, 멋진 버튼 같은 컨트롤들의 구현 작업 등 프로젝트에서 중요한 위치의 일이 아니면서도 안 할 수도 없고, 시간은 많이 걸리고, 코드도 복잡해서 프로젝트 전체 코드를 읽는데 적잖이 부담을 준다.



이전에 개발의 생산성에 관한 주제를 다루면서 이미 누군가 고민한 사람이 있을 테니 찾아보라고 언급한적이 있다. www.devpia.com www.codeproject.com www.codeguru.com 등의 사이트가 존재해서 얼마나 고마운지 모른다. 만일 내가 세세하게 모두 구현하려 한다면, 정말 많은 시간이 필요할 것이다. 모두 그러하겠지만 이런 개발자 사이트에서 적정한 코드를 구했다면, 자신의 것으로 소화해내는 작업을 수행해야 한다.



MyMSNMessenger 에서도 여기 저기서 구한 몇 개의 클래스들이 사용되는 그 소스에 관한 자세한 설명은 배제하기로 한다. 각 부분에 대한 이해는 여러분의 몫으로 남기고, 클래스들의 목적 및 사용법만 설명한다.



MyMSNMessenger 에서 다음과 같은 함수와 클래스들이 있다.



1. RgMgr.h 에는 레지스트리에 데이터를 저장하고 읽어들이는 함수가 선언되어 있다.



#define MY_DEFAULT_KEY "SoftWare\\MyMSNMessenger"

BOOL TfcGetRegData (LPCTSTR lpszKey, CString& strData);

BOOL TfcSetRegData (LPCTSTR lpszKey, LPCTSTR lpszData);

BOOL TfcGetRegData (LPCTSTR lpszKey, int& nData);

BOOL TfcSetRegData (LPCTSTR lpszKey, int nData);



함수명에서도 알 수 있듯이 함수가 중복 정의 되어 문자열, 숫자의 값을 레지스트리에 입출력할수 있다.

CMainFrame:: OnCreate() 함수에서 윈도우의 크기를 레지스트리에서 읽어들이고,

CMainFrame::OnClose() 함수에서 윈도우의 크기를 저장하는 루틴이 구현되어 있다.



::TfcGetRegData (_T("General\\MainFrame\\nX"), nX);

::TfcSetRegData (_T("General\\MainFrame\\nX"), rcFrame.left);



저장되는 위치는 HKEY_CURRENT_USER\Software\MyMSNMessenger\General\MainFrame\nX 이다.



2. CListCtrl 에서 상속받아 CMagicList 를 구현하였다.

CListCtrl 을 확장하여 만든 클래스들이 많이 존재한다. 그 기능을 살펴보면 다음과 같다.

1) 컬럼의 SORTING (문자 및 숫자) 기능을 제공한다.

2) 배경색과 선택된 라인 색상을 조절할 수 있다.

3) 가로 세로 그리드라인을 넣을 수 있다.

4) 폰트를 지정할 수 있다.

5) 헤더 컬럼의 개수, 크기, 문자열을 쉽게 정의할 수 있다.

6) 플랫 헤더 컨트롤을 사용한다.

7) 데이터의 입출력을 String Array 로 쉽게 처리할 수 있다.

8) 특정 컬럼의 문자열을 쉽게 검색해 낼 수 있다.



여기 저기서 모은 팁들을 혼합해서 구현하였다. 다른 부수적인 기능들은 타 리스트 확장 클래스와 비슷할 것이다. 다만, 리스트의 컬럼 지정과, 데이터의 입출력이 상당히 복잡하고, 코드양이 많아짐을 불편하게 여겨 CStringArray 에 담아 처리하는 큰 특징이 있다.



CMyMSNMessengerView::InitUserListCtrl () 에서 다음과 같은 리스트 컨트롤 초기화 하는 작업을 수행한다.

1) List 속성 설정 및 Subclassing

2) 리스트의 배경색, 선택라인 색상, 폰트 지정

3) 리스트 컬럼 (MSN Contact 상태, FriendlyName, SigninName) 만들기

4) 리스트 첫째 컬럼을 이미지로 사용

5) 플랫 헤더 컨트롤을 생성하고 헤더에 이미지 넣기



다음은 리스트 컨트롤을 사용하는 루틴이다.

void CMyMSNMessengerView::OnInitialUpdate() 에 테스트용으로 구현해 놓았다.



CStringArray saContactInfo;

saContactInfo.Add (_T("0")) // 온라인 상태

saContactInfo.Add (_T("거북선")); // 대화명

saContactInfo.Add (_T("gobuksun@empal.com")); // SignIn



m_listUser.InsertDataToList (&saContactInfo);



CStringArrary 에 들어갈 데이터를 입력한 후 리스트 컨트롤에 추가하면 된다.



입력된 데이터를 얻는 방법은 void GetDataFromList (CStringArray* psaData, int nPos = -1); 함수를 사용하면 되는데 입력과는 반대로 CStringArray 에 담아온다. 얻고자 하는 행을 nPos 로 지정할 수 있는 지정되지 않으면 현재 선택된 행의 값을 얻어온다.

또다른 방법으로 void GetSpecificData (CString& strData, int nCol, int nPos = -1); 함수가 있는데 특정 컬럼의 문자열을 스트링으로 바로 얻어올 수 있다.



다음 코드는 현재 선택된 행의 SigninName 을 얻어오는 루틴이다.

CString strSigninName = _T("");

m_listUser.GetSpecificData (strSigninName, 2);



리스트컨트롤을 더블클릭할 경우인

void CMyMSNMessengerView::OnRclickListUser(NMHDR* pNMHDR, LRESULT* pResult) 에 예제를 구현해 놓았다.



기타 MyMSNMessenger 에 다른 유용한 클래스들이 사용되는데 이는 개발자 사이트에서 구한것으로 원 저작자에 대한 주석이 달려 있다. 자세한 구현방법은 각자 소스를 살펴보기로 하고 여기서는 간단하게 기능적으로 살펴본다.



1. NewMenu Author : Bruno Podetti

XP 스타일의 메뉴를 구현한 클래스로 작지만 강력하다.

사용법은 간단하다. CFrameWnd 를 찾아 CNewFrameWnd 로만 바꿔주면 된다.

CMainFrame::OnCreate() 에서 메뉴 설정에 관한 간단한 수정만 해주면 된다.



2. SystemTray Author : Chris Maunder

시스템 트레이를 구현한 클래스로 애니메이션을 지원하고 안정적이다.

// 시스템 트레이 아이콘 설정

m_TrayIcon.Create (NULL, WM_TRAYICON_NOTIFY, "Click here", ::LoadIcon(NULL, IDI_ASTERISK),

IDR_MENU_TRAY);

m_TrayIcon.SetMenuDefaultItem (2, TRUE);



m_TrayIcon.SetIconList(IDI_TRAY_ANI_1, IDI_TRAY_ANI_4);

m_TrayIcon.Animate (50); // 50 millisecond delay between frames, for Infinite



3. void DrawCorner(….)

모서리를 곡선으로 그려주는 함수.



소스는 여기에~ http://myhome.konetic.or.kr/UserUploadData/gobuksun/MyMSNMessenger.zip



실무에서 뛰시는 분들은 나름대로의 유용한 클래스들을 라이브러리로 보관하고 있을 것이다. 중요한 것은 필요할 때 매번 찾을게 아니라, 유용할 것으로 판단되는 클래스들을 정리 정돈해서 자신의 것으로 만드는 작업일 것이다.



이제 마지막 한 강좌만 남았네요. IMessenger 인터페이를 사용한 MSN 메신저에 접근하는 방법 사용자 리스트를 얻어오는 방법에 대해 나가겠습니다. 저도 일년전이라 알쏭달쏭한 부분이 있어서 잠시 정리할 시간이 필요하군요. 역시 구현하는것과 누군가에게 전달하는것은 많이 다르다는걸 느낍니다. 아무쪼록 많은분들께 도움이 되었으면 합니다.. *^^*
Posted by 장안동베짱e :