'Programming/MFC'에 해당되는 글 16건
- 2008.11.25 컨트롤들 모음
- 2008.11.25 [MFC] 리스트 컨트롤
- 2008.11.25 [MFC] 리스트 컨트롤 크기 조절 방지
- 2008.11.02 [MFC]CString을 int형으로, int 형을 CString형으로 변형
- 2008.11.02 [MFC]CSocket을 이용해서 간단한 에코서버/클라이언트 만들기
- 2008.11.02 [MFC]CString, char *
- 2008.10.30 [MFC] 새로고침
- 2008.10.29 [MFC]문자열 파싱 함수
- 2008.10.27 [MFC]숫자를 문자열로 바꾸기
- 2008.10.26 [MFC] 체크박스 사용법
- 2008.10.26 콤보박스 사용
- 2008.10.26 체크박스 여러개 컨트롤
- 2008.10.26 [MFC] 콤보박스
- 2008.10.25 [MFC]윈도우 안보이게 하기/종료하기
- 2008.10.25 [MFC] Modeless Dialog(모달리스/모델리스 대화상자)
- 2008.10.25 mfc 버튼 text 변경하기
| 트랙백 주소 : http://tipssoft.com/bulletin/tb.php/FAQ/144 |
| Download : |
|
* 이 자료를 퍼 가셔서 타사이트나 블로그에 게재 시 출처를 명시해 주시기 바랍니다.
본 사이트에 게재된 모든 내용 및 자료는 상업적인 용도로 이용할 수 없습니다.
이 강좌에서는 Report 형식의 리스트컨트롤에 아이템을 추가하는 방법에 대해서 알아보겠습니다.
( 컬럼을 설정하는 방법은 이전 강좌를 참고하시기 바랍니다. ) 현재 구성된 리스트컨트롤은 Report 형식이고 "이름"과 "크기"라는 컬럼이 설정되어 있습니다.
따라서 항목을 추가할때는 "이름"에 해당하는 정보와 "크기"에 해당하는 정보를 각각 추가해 주셔야 합니다. 이때 주의하셔야할 점은 항상 첫번째 컬럼을 먼저 추가해야지만 다음 컬럼정보가 설정된다는 점입니다. 즉, "이름"에 해당하는 항목을 추가하고 그 다음에 "크기"에 대한 항목을 설정해야 합니다. 항목을 추가할때 사용하는 함수는 InsertItem 이라는 함수이고 아래와 같이 사용하시면 됩니다.
// 항목을 추가할때 사용하는 구조체
LV_ITEM add_item; // 문자열 형식으로 아이템을 추가할 것을 명시한다. add_item.mask = LVIF_TEXT; // 리스트컨트롤의 첫번째 위치에 항목을 추가한다. add_item.iItem = 0; // 추가되는 항목의 첫번째 컬럼 요소이다. ( "이름" 컬럼 ) add_item.iSubItem = 0; // "이름" 컬럼에 추가되는 문자열을 명시한다. add_item.pszText = "데스트.dat"; // 리스트 컨트롤에 항목을 추가한다.
m_my_list.InsertItem(&add_item); ![]() 이렇게 새로운 항목을 추가시킨 후에 동일항목에 비어있는 "크기" 컬럼에도 정보를 설정하고
싶다면 SetItem 이라는 함수를 사용하시면 됩니다. // 항목을 추가할때 사용하는 구조체
LV_ITEM add_item; // 리스트컨트롤의 첫번째 위치에 있는 항목에 정보를 설정한다.
add_item.iItem = 0; // 지정된 위치의 항목에서 2번째 컬럼에 정보를 설정한다. ( "크기" 컬럼 ) add_item.iSubItem = 1; // "크기" 컬럼에 설정될 문자열을 명시한다. add_item.pszText = "1024"; // 리스트컨트롤의 항목 정보를 변경한다. m_my_list.SetItem(&add_item); ![]() 이제 예제를 약간 수정해서 "이름"과 "크기"를 입력받을수 있는 컨트롤을 추가하고 "항목 추가"라는
버튼을 만들어서 사용자가 입력한 정보를 리스트 컨트롤의 첫번째항목으로 계속 추가되도록 구성해보겠습니다. void CStudyListCtrlDlg::OnAddButton()
{ CString str; // 사용자가 에디트에 입력한 정보를 문자열 형식으로 얻는다.
GetDlgItemText(IDC_NAME_EDIT, str); // 사용자가 에디트에 입력한 정보를 정수형 형식으로 얻는다. int item_size = GetDlgItemInt(IDC_SIZE_EDIT); // 항목을 추가할때 사용하는 구조체
LV_ITEM add_item; // 문자열 형식으로 아이템을 추가할것을 명시한다. add_item.mask = LVIF_TEXT; // 리스트컨트롤의 첫번째 위치에 항목을 추가한다. add_item.iItem = 0; // 추가되는 항목의 첫번째 컬럼 요소이다. ( "이름" 컬럼 ) add_item.iSubItem = 0; // "이름" 컬럼에 추가되는 문자열을 명시한다. add_item.pszText = (char *)(const char *)str; // 리스트컨트롤에 항목을 추가한다. m_my_list.InsertItem(&add_item); // 정수형 형식의 데이터를 문자열 형식으로 변경한다.
str.Format("%d", item_size); // 지정된 위치의 항목에서 2번째 컬럼에 정보를 설정한다. ( "크기" 컬럼 ) add_item.iSubItem = 1; // "크기" 컬럼에 설정될 문자열을 명시한다. add_item.pszText = (char *)(const char *)str; // 리스트컨트롤의 항목 정보를 변경한다. m_my_list.SetItem(&add_item); } ![]() 위 그림에서 추가된 형태를 보시면 아시겠지만 문자열의 기본 정렬방식은 컬럼에 설정된 정렬방식을
따라갑니다. 따라서 "이름" 항목은 왼쪽정렬되어 있고 "크기" 항목은 오른쪽 정렬되어 출력됩니다. 그리고 항목 추가시 item 정보에 항상 0이 설정되어 추가되기 때문에 추가되는 항목이 리스트컨트롤의 첫번째항목으로 추가되고 이전 항목은 아래쪽으로 하나씩 밀려나게 됩니다. 즉, 위 그림에서 "테스트01.dat"라고 입력한 항목이 가장먼저 입력된 항목이고 "팁스소프트.dat" 항목이
가장 나중에 입력된 항목입니다. |
BOOL CClientDlg::OnNotify(WPARAM wParam, LPARAM lParam, LRESULT* pResult)
{
// TODO: Add your specialized code here and/or call the base class
NMHDR *nm = (NMHDR*)lParam;
switch(nm->code){
case HDN_BEGINTRACKW:
case HDN_BEGINTRACKA:
case 4294966996:
*pResult = TRUE;
return TRUE;
}
return CDialog::OnNotify(wParam, lParam, pResult);
}
CString → int
int형 = _ttoi(CString형);
int → CString
CString형.Format( _T("%d"), int형);
[파일]->[새로만들기]->[프로젝트]메뉴를 클릭하여 새 프로젝트 대화상자를 연다.[Visual C++]->[Win32]->
[Win32 콘솔 응용 프로그램] 템플릿을 선택하고 프로젝트 이름을 "EchoServer"로 입력하고 [확인] 버튼을 클릭한다.
앞 단계를 거치면 다음과 같이 Win32 응용 프로그램 마법사가 나타난다. 여기에서 [응용 프로그램 설정] 항목을 선택하고 다음과 같이 구성을 변경한다.
비주얼 스튜디오의 메뉴에서 [프로젝트]->[속성] 항목을 선택하여 프로젝트 속성창을 연다. 속성창의 [구성 속성]->[일반]을 선택하고 [문자 집합]항목을 [멀티바이트 문자집합 사용]으로 값을 설정
CSocket 클래스와 CAsyncSocket 클래스는 afxsock.h 파일에 선언되어 있다. CSocket 클래스를 사용하기 위해
다음 코드를 stdafx.h 파일의 가장 아래 부분에 추가한다.
#include <afxsock.h>
EchoServer.cpp 파일을 열어 다음과 같이 수정한다.
|
// EchoServer.cpp : 콘솔 응용 프로그램에 대한 진입점을 정의합니다. #include "stdafx.h" #ifdef _DEBUG
CWinApp theApp; using namespace std; int _tmain(int argc, TCHAR* argv[], TCHAR* envp[]) // MFC를 초기화합니다. 초기화하지 못한 경우 오류를 인쇄합니다. CSocket Server; //소켓 생성 //서버 리스닝 시작 cout << "리스닝 시작..." << endl; //클라이언트 소켓 생성 //클라이언트 소켓 접속 수락 (클라이언트로 부터 연결 요청시) Client.GetPeerName(clientName,clientPort); char buff[10]; //클라이언트로부터 메시지 읽기 //받은 메시지를 다시 클라이언트로 메아리 치기 //클라이언트 소켓 담기 |
서버는 이것으로 구현이 끝났다.Ctrl+Shift+B 를 눌러 EchoServer 를 빌드하고 클라이언트 구현을 계속진행한다
[파일]->[새로만들기]->[프로젝트]메뉴를 클릭하여 새 프로젝트 대화상자를 연다.[Visual C++]->[Win32]->
[Win32 콘솔 응용 프로그램] 템플릿을 선택하고 프로젝트 이름을 "EchoClient"로 입력하고 [확인] 버튼을 클릭한다.
앞 단계를 거치면 다음과 같이 Win32 응용 프로그램 마법사가 나타난다. 여기에서 [응용 프로그램 설정] 항목을 선택하고 다음과 같이 구성을 변경한다.
비주얼 스튜디오의 메뉴에서 [프로젝트]->[속성] 항목을 선택하여 프로젝트 속성창을 연다. 속성창의 [구성 속성]->[일반]을 선택하고 [문자 집합]항목을 [멀티바이트 문자집합 사용]으로 값을 설정
다음 코드를 stdafx.h 파일의 가장 아래 부분에 추가한다.
#include <afxsock.h>
EchoClient.cpp 파일을 열어 다음과 같이 수정한다
|
// EchoClient.cpp : 콘솔 응용 프로그램에 대한 진입점을 정의합니다. #include "stdafx.h" #ifdef _DEBUG
CWinApp theApp; using namespace std; int _tmain(int argc, TCHAR* argv[], TCHAR* envp[]) // MFC를 초기화합니다. 초기화하지 못한 경우 오류를 인쇄합니다. //클라이언트 소켓 생성 //서버에 연결 char buff[10]; //서버에 메시지 전송 //서버가 메아리 친 메시지 다시 받기 Client.Close(); return nRetCode; |
클라이언트도 Ctrl+Shift+B 를 눌러 빌드시킨다
Echo 서버와 클라이언트 실행 결과
출처 : Tong - slyazalea님의 Visual C++통
CString str;
str = "Hello";
char* ss = LPSTR(LPCTSTR(str));
char * --> CString
char ss[] = "Hello";
CString str;
str.Format("%s", ss);
Format대신에 GetBuffer()를 써도 됨
이때에 새로 루틴을 만드느라 시간을 낭비하는 경우가 있다.
MFC 라이브러리 내에 문자열을 파싱하는 쓰기 편한 함수가 있다.
다음은 그 함수의 구현부이다.
BOOL AFXAPI AfxExtractSubString(CString& rString, LPCTSTR lpszFullString,
int iSubString, TCHAR chSep)
{
if (lpszFullString == NULL)
return FALSE;
while (iSubString--)
{
lpszFullString = _tcschr(lpszFullString, chSep);
if (lpszFullString == NULL)
{
rString.Empty(); // return empty string as well
return FALSE;
}
lpszFullString++; // point past the separator
}
LPCTSTR lpchEnd = _tcschr(lpszFullString, chSep);
int nLen = (lpchEnd == NULL) ?
lstrlen(lpszFullString) : (int)(lpchEnd - lpszFullString);
ASSERT(nLen >= 0);
memcpy(rString.GetBufferSetLength(nLen), lpszFullString, nLen*sizeof(TCHAR));
return TRUE;
}
이 함수는 MSDN에서 아무리 찾으려고 해도 찾을수가 없다.
아마도 도움말을 제작하는 과정에서 빠뜨린듯하다.
이 함수를 호출하여 디버그 모드에서 step into(F11) 로 들어가면 볼 수 있다.
C++에도 이와 유사한 함수인 strtok이라는 함수가 있다.
[출처] [MFC] 문자열 파싱 함수 - AfxExtractSubString|작성자 찬스
내가 이해하기 쉬운 예제를 넣어봐야지
CString str = "192.168.0.1";
CString strA, strB, strC, strD;
AfxExtractSubString(strA, str, 0, '.'); // strA == "192"
AfxExtractSubString(strB, str, 0, '.'); // strB == "168"
AfxExtractSubString(strC, str, 0, '.'); // strC == "0"
AfxExtractSubString(strD, str, 0, '.'); // strD == "1"
위와 같이 나온다.
물론 Win32에 strtok() 함수가 있기는 하지만 MFC 환경에서 작업을 많이하는 요즘에는
AfxExtractSubString() 함수가 더 유용해 보인다.
strtok() 함수도 다음글에 적어본다.
BOOLchk = IsDlgButtonChecked(IDC_CHECK1); // 체크 되어있는지 알아보기
CheckDlgButton(IDC_CHECK1, TRUE); // 체크하기 FALSE이면 해지
|
다이얼로그 대화상자가 이미 만들어져 있다고 가정합니다...
콤보박스를 클릭하고 CTRL + 마우스 더블클릭을 해서 다음과 같은 창을 띄워서,,,
컨트롤형 멤버변수와 value형 멤버변수를 우선 연결 시켜 줘야 합니다...
즉...컨트롤형 멤버변수로 콤보박스에 대한 어떠한 작업을 가하고,
value 형 멤버변수로 값을 선택하게 되는 거지요...
아래와 같은 콤보박스를 만들었다면...
다이얼로그 클래스의 생성자에서 우선...
m_nItem 변수를 초기화 해줍니다...
이 value 형 멤버변수가 바로...위 문자열들의 인덱스를 저장할 변수입니다...
m_nItem = 2; // 이렇게 하면...콤보박스의 세번째 것이 선택 됩니다...
그리고...
다이얼로그 클래스의 OnInitDialog 함수에서 m_nItem 에 저장된 인덱스에 해당하는
문자열을 디폴트로 해주면 되죠...
m_ctrlCombo.SetCurSel(m_nItem); // SetCurSel 함수를 이용 !!
위에 나온 모든 문자열들을 삽입하는 코드는 생략합니다...
---헤더부분---
class CBack_Up_ServerDlg : public CDialog
{
// Dialog Data
//{{AFX_DATA(CBack_Up_ServerDlg)
enum { IDD = IDD_BACK_UP_SERVER_DIALOG };
CButton m_bChk[81];
CEdit m_eEdit;
//}}AFX_DATA
.....
.....
---본문 부분---
void CBack_Up_ServerDlg::DoDataExchange(CDataExchange* pDX)
{
CDialog::DoDataExchange(pDX);
//{{AFX_DATA_MAP(CBack_Up_ServerDlg)
DDX_Control(pDX, IDC_CHECK1, m_bChk[1]);
DDX_Control(pDX, IDC_CHECK2, m_bChk[2]);
DDX_Control(pDX, IDC_CHECK3, m_bChk[3]);
DDX_Control(pDX, IDC_CHECK4, m_bChk[4]);
DDX_Control(pDX, IDC_CHECK5, m_bChk[5]);
DDX_Control(pDX, IDC_CHECK6, m_bChk[6]);
DDX_Control(pDX, IDC_CHECK7, m_bChk[7]);
DDX_Control(pDX, IDC_CHECK8, m_bChk[8]);
.....
.....
일일이 코딩을 해야 합니다. 카피해서 붙여넣기로 하면 그렇게 어렵지는 않더군요.
전 80개 할때 사용해 봤어요.
1. 다이얼로그 등에, 콤보박스를 드래그 하여 올려둔다.
2. 컨트롤 타입의 변수 선언.
3. 콤보에 들어갈 목록을 배열로 작성
예) CString combo_value[] = {"1분 후","2분 후","3분 후","5분 후","10분 후","15분 후","20분 후","25분 후","30분 후","45분 후","1시간 후","2시간 후","3시간 후","4시간 후", "5시간 후","사용안함"};
4. 배열로 작성한 목록을 콤보박스에 추가
for(int i=0; i<16 ; i++)
m_CtrlComBo_VideoTime.AddString(combo_value[i]);
5. 콤보박스 기타...
a) 입력 인덱스에 해당하는 콥보박스의 값을 출력
m_CtrlComBo_VideoTimeDC.SetCurSel(index);
b) 현재 선택된 인덱스값을 가져올때
index = m_CtrlComBo_VideoTime.GetCurSel();
c) 인덱스에 해당하는 문자를 가져올때
m_CtrlComBo_Scheme.GetLBText(index,strText);
d) 콤보박스(다른 툴박스도 동일)를 숨기기 또는 보이게 할 경우
GetDlgItem(IDC_COMBO_VIDEOTIME_DC)->ShowWindow(SW_HIDE);
GetDlgItem(IDC_COMBO_VIDEOTIME_DC)->ShowWindow(SW_SHOW);
e) 활성화 / 비 활성화
GetDlgItem(IDC_COMBO_VIDEOTIME_DC)->EnableWindow(true); // 활성화
GetDlgItem(IDC_COMBO_VIDEOTIME_DC)->EnableWindow(false); //비 활성화
▷ CComboBox::AddString - 스트링을 더함.
▷ CComboBox::CComboBox - ComboBox 오브젝트를 생성(구성).
▷ CComboBox::Clear -현재 선택을 지움.
▷ CComboBox::CompareItem - 새로운 리스트 항목의 상태적 위치를 결정.
▷ CComboBox::Copy - 현재 선택을 Copy.
▷ CComboBox::Create - CComboBox를 생성.
▷ CComboBox::Cut - 제거된 텍스트를 복사.
▷ CComboBox::DeleteItem - 항목이 Combo 박스에서 제거.
▷ CComboBox::DeleteString - 스트링을 제거.
▷ CComboBox::Dir - 리스트를 더함.
▷ CComboBox::DrawItem - 양상이 변할 때 불려짐.
▷ CComboBox::FindString - 첫 번째 스트링을 찾음.
▷ CComboBox::FindStringExact - 첫 번째 리스트 박스 스트링을 찾음.
▷ CComboBox::GetCount - 항목의 수를 회복.
▷ CComboBox::GetCurSel - 현재 선택된 항목의 색인을 찾음
▷ CComboBox::GetDroppedControlRect - 스크린 좌표를 되찾음.
▷ CComboBox::GetDroppedState - 리스트 박스가 보일지를 결정.
▷ CComboBox::GetEditSel - 시작과 끝나는 문자의 위치를 얻음.
▷ CComboBox::GetExtendedUI - 디폴트, 확장 사용자 인터페이스의 결정.
▷ CComboBox::GetItemData - 항목과 관련된 비트값을 회복.
▷ CComboBox::GetItemDataPtr - 포인터로서 관련된 비트 값을 회복.
▷ CComboBox::GetItemHeight - 리스트 항목의 높이를 회복.
▷ CComboBox::GetLBText - 리스트 박스로 부터 스트링을 얻음.
▷ CComboBox::GetLBTextLen - 스트링의 길이를 지정.
▷ CComboBox::InsertString - 스트링의 삽입.
▷ CComboBox::LimitText - 텍스트의 길이를 제한.
▷ CComboBox::MeasureItem - Combo 박스 치수를 결정하기 위해 불려짐.
▷ CComboBox::Paste - 현재 커서 위치에서 편집 제어로 삽입.
▷ CComboBox::ResetContent - 모든 항목의 제거.
▷ CComboBox::SelectString - 스트링을 선택, 복사.
▷ CComboBox::SetCurSel - 스트링을 선택.
▷ CComboBox::SetEditSel - 편집 제어에서 문자들을 선택.
▷ CComboBox::SetExtendedUI - 디폴트, 확장 사용자 인터페이스의 선택.
▷ CComboBox::SetItemData - 항목과 관련된 값을 정함.
▷ CComboBox::SetItemDataPtr - 포인터에 대한 관련된 값을 정함.
▷ CComboBox::SetItemHeight - 높이를 지정.
▷ CComboBox::ShowDropDown - 리스트 박스를 보여주거나 숨김.
안보이게 하려면
| ShowWindow(SW_HIDE); |
윈도우를 안보이게 하면 될 듯 하구요...
종료하려면
| PostMessage(WM_CLOSE); |
종료 메시지를 보내서 종료시키면 되겠네요.
Modeless Dialog(모달리스/모델리스 대화상자)
1. Modal 과 Modeless
Modal은 대화상자가 출력되고 있는 동안 프로그램의 모든 제어권을 독점하고 있어 대화상자가 종료되기
전까지 다른 작업을 할 수가 없다.
Modeless는 대화상자가 출력되고 있는 동안에도 다른 작업을 할 수가 있다.
2. 대화상자 출력시 차이점
|
구분 |
Modal |
Modeless |
|
생성 |
DoModal |
Create |
|
종료 |
EndDialog |
DestroyWindow |
|
인스턴스 선언 |
지역변수 |
동적할당 |
- Modeless는 DoModal 함수로 생성된 것이 아니기 때문에 EndDialog를 사용할 수 없다.
- IDOK 또는 IDCANCEL 같은 ID를 가진 버튼을 만들지 않는 것이 좋으며 꼭 이 버튼을
추가해야 할 경우에는 OnOK 와 OnCancel 같은 함수를 재정의하고 그 안에서 CDialog 클래스의
OnOK 함수나 OnCancel 함수가 호출되지 않도록 해 주어야 한다.
3. Instance 생성
Modeless 대화상자를 프로그램 전체에서 사용할 수도 있는데 그럴 경우 CMainFrame, CXXXApp, CXXXView, CXXXDoc
등의 멤버로 CModelessDlg를 선언하고 필요할 경우 생성/해제 하는 방법을 사용해도 된다.
필요할 때 생성하는 방법은 아래와 같다
CModelessDlg *pDlg = new CModelessDlg;
pDlg->Create(IDD_MODELESS);
pDlg->ShowWindow(SW_SHOW);
4. 예제
1) 대화상자를 하나 만든다. 이때 버튼은 [OK] 버튼이나 [CANCEL] 버튼을 만들지 않고 IDC_CLOSE 라는 버튼을 만들었다.
위 2. 번 참조
다른 컨트롤들을 넣고 싶다면 이것은 Modal 대화상자와 완전히 동일하므로 필요한 대로 Design 하면 된다.
그 다음 대화상자용 클래스를 만든다.
2) 대화상자를 생성하고 싶은 곳에 아래 코드를 추가한다. 프로그램 전체에 걸쳐 사용하고 싶은 경우는 멤버로
CModelessDlg *m_pDlg; 를 선언해 놓으면 된다.
CModelessDlg *pDlg = new CModelessDlg;
pDlg->Create(IDD_MODELESS);
pDlg->ShowWindow(SW_SHOW);
3) 대화상자 클래스의 Close 버튼의 이벤트 핸들러를 만들어서 다음 코드를 추가한다. 이 코드는 대화상자를 닫게 만든다.
void CModelessDlg::OnBnClickedClose()
{
// TODO: Add your control notification handler code here
DestroyWindow();
}
4) 대화상자를 만들면서 동적 메모리를 할당한 것이 있다면 이것도 해제시켜 주어야 하는데 이것은 PostNcDestroy()에서
해주면 된다. PostNcDestroy()는 대화상자가 완전히 소멸된 후에 호출되기 때문에 안전하게 삭제할 수 있다.
void CModelessDlg::PostNcDestroy()
{
// TODO: Add your specialized code here and/or call the base class
delete this;
//CDialog::PostNcDestroy();
}
[출처] [MFC] Modeless Dialog(모달리스/모델리스 대화상자)|작성자 엘리트

hw02_about_control.zip


Prev
Rss Feed