728x90
300x250
[MFC] 메시지 처리 - Timer(타이머) 만들기

 

Visual Studio 2019(C++.NET MFC 142)에서 Timer(타이머)를 작성해보도록 하겠다.

실시간 타이머는 말 그대로 일정+시간을 의미하는 타이머이다.

일상생활에서 컴퓨터의 "날짜 및 시간"을 보면 확인할 수 있다.

아래의 그림은 정적인 Timer이다.

 

 

이번 예제는 동적인 실시간 타이머를 구현하도록 하겠다.

 

[작성 환경]
Microsoft Visual Studio 2019
Microsoft Windows 10

 


1. 프로젝트 생성하기

 

프로젝트 생성하는 방법은 이전 예제에서도 다루고 있지만, SDI, MDI 등이 있을 수 있어서 표기하고 있다.

 

 

그림 1) 프로젝트 생성하기

 

 

그림 2) 프로젝트 생성하기

 

 

그림 3) 프로젝트 생성하기

 

 

그림 4) 프로젝트 생성하기

 

 

그림 5) 프로젝트 생성하기

 

 

그림 6) 프로젝트 생성하기

 


2. 변수 만들기, 클래스 마법사, 코드 입력하기

 

코드 작성 전략을 소개하면 크게, "변수 만들기"->"클래스 마법사"->"코드 입력하기" 순서로 진행해볼 수 있겠다.

 

 

그림 7) 프로젝트 생성 후 첫 화면

 

 

그림 8) 클래스 뷰에서 "CTimerDigitalView" 오른쪽 버튼 후 추가에서 변수 추가(B)... 클릭하기

 

그림 8처럼 따라서 진행하도록 한다.

 

 

그림 9) 변수 추가의 예(m_bTimerRun)

 

그림 9의 변수는 타이머의 실행 유무를 bool(부울)로 체크하는 함수이다.

 

 

그림 10) 코드 완성의 예

 

정상적으로 변수가 생성되었음을 알 수 있다. 그림 8처럼 그림 11을 다시 따라하도록 한다.

 

 

그림 11) 변수 추가의 예

 

 

그림 12) m_bTimerType 변수 추가 모습

 

그림 12는 m_bTimerType이라는 변수를 추가하고 있는 모습이다. m_bTimerType의 목표는 타이머 출력의 형식을 어떻게 할지 추후에 구현할 때 사용하게 될 것이다. 이 예제에서는 추후 고려에 대해서만 담고 있다.

 

 

그림 13) Timer_DigitalView.cpp 더블 클릭

 

그림 13은 CTimerDigitalView::CTimerDigitalView를 변형한 모습을 담고 있다.

 

// CTimerDigitalView 생성/소멸

CTimerDigitalView::CTimerDigitalView() noexcept
           :m_bTimerRun(false)
           , m_bTimerType(true)
{
           // TODO: 여기에 생성 코드를 추가합니다.

}

 

코드를 입력한다.

 


3. 생성자 만들기

 

Ctrl+Shift+X 단축키를 클릭해서 클래스 마법사를 실행한다.

메시지 탭을 클릭 후, "WM_Create"라고 입력한다.

그리고 "처리기 추가(A)"를 클릭한다.

OnCreate를 선택한 후, "코드 편집(E)"를 클릭한다.

 

 

그림 14) 클래스 마법사 실행하기

 

그림 15처럼 코드를 입력한다.

 

 

그림 15) OnCreate에 코드 작성하기

 

// CTimerDigitalView 메시지 처리기


int CTimerDigitalView::OnCreate(LPCREATESTRUCT lpCreateStruct)
{
        if (CView::OnCreate(lpCreateStruct) == -1)
              return -1;

 

        // TODO:  여기에 특수화된 작성 코드를 추가합니다.


        SetTimer(0, 1000, NULL);  // 타이머 설정
        m_bTimerRun = TRUE;    // 타이머 동작

        return 0;
}

 


4. 메시지 출력을 담을 변수 추가하기

 

다음은 메시지 출력을 담을 변수를 추가할 것이다.

CString 자료형으로 메시지 출력을 담을 것이다.

 

CTimerDigitalView를 오른쪽 버튼한 후, "추가", "변수 추가(B)..."를 클릭한다.

 

 

그림 16) 변수 추가의 모습

 

 

그림 17) m_strTimer 변수 추가 모습

 

변수를 추가한 후, 확인을 누른다.

Ctrl+Shift+X키를 눌러서 클래스 마법사를 호출한다.

 

 

그림 18) 클래스 마법사 호출한 모습

 

메시지 탭에서 "WM_TIMER"를 검색한다.

"처리기 추가"를 누른다.

"OnTimer"를 클릭 후 "코드 편집(E)"를 클릭한다.

 

 

그림 19) OnTimer()에 소스코드를 입력한 모습의 예(1)

 

 

그림 20) OnTimer()에 소스코드를 입력한 모습의 예(1)

 

void CTimerDigitalView::OnTimer(UINT_PTR nIDEvent)
{
         // TODO: 여기에 메시지 처리기 코드를 추가 및/또는 기본값을 호출합니다.
         int hour;
         CString str;
         CTime timer;
         timer = CTime::GetTickCount(); // Visual Studio 2017부터 GetCurrentTime() 삭제

 

        if (m_bTimerType) {
             m_strTimer.Format(_T("현재는 %d년 %d월 %d일 %d시 %d분 %d초"),
                   timer.GetYear(), timer.GetMonth(), timer.GetDay(),
                   timer.GetHour(), timer.GetMinute(), timer.GetSecond());


        }

        else {
                  hour = timer.GetHour();

 

                  if (hour >= 12) {
                        str = _T("PM");
   
                       if (hour >= 13) {
                              hour = hour - 12;
                       }

                 }
                 else {
                       str = _T("AM");
                 }

           

                 m_strTimer.Format(_T("지금은 %s %d %d %초"), str, hour,
                 timer.GetMinute(), timer.GetSecond());

       }

     

       Invalidate();

       CView::OnTimer(nIDEvent);
}

 

코드 입력을 마쳤으면, OnDraw를 클릭한다. 코드를 입력해준다.

 

 

그림 21) OnDraw() 함수 원형 내에 코드 입력해주기

 

// CTimerDigitalView 그리기

 

void CTimerDigitalView::OnDraw(CDC* pDC)
{
        CTimerDigitalDoc* pDoc = GetDocument();
        ASSERT_VALID(pDoc);

  

        if (!pDoc)
             return;

 

        // TODO: 여기에 원시 데이터에 대한 그리기 코드를 추가합니다.

 

        CRect rect;
        GetClientRect(&rect);

 

        // 윈도우의 중앙에 타이머를 출력
        pDC->DrawText(m_strTimer, rect, DT_SINGLELINE | DT_CENTER | DT_VCENTER);

}

 

코드 입력을 마쳤다면, Ctrl+Shift+X를 누른다.

 


5. 소멸자 만들기

 

지금 작업은 실시간 타이머를 윈도우 프로그램이 종료할 때, 같이 종료될 수 있도록 지정해주는 기능을 구현하는 것이다.

 

메시지 탭에서 "WM_Destory"를 검색한다.

"처리기 추가(A)"를 클릭한다.

"OnDestory"를 클릭 후 "코드 편집(E)"을 클릭한다.

 

 

그림 22) 창 소멸에 관한 클래스 정의

 

 

 

그림 23) 코드 입력하기

 


6. 시연하기

 

시연하는 것이다.

Ctrl+F5를 눌러서 시연한다.

 

 

그림 25) 시연하기

 

[소스코드]

 

[첨부(Attachment)]

Timer_Digital.7z

 

 


7. 참고자료(Reference)

 

1. CTime::GetCurrentTime intellisense missing - Developer Community, Last Modified , Accessed by 2019-11-30, https://developercommunity.visualstudio.com/content/problem/100004/ctimegetcurrenttime-intellisense-missing.html

 

 

 

2. CTime 클래스 | Microsoft Docs, Last Modified, Accessed by 2019-11-30, https://docs.microsoft.com/ko-kr/cpp/atl-mfc-shared/reference/ctime-class?view=vs-2019#getcurrenttime

 

 

 

 

반응형
728x90
300x250
[MFC] 메시지 처리 - WM_Create, WM_LButtonDBLCLK, AfxMessageBox

 

메시지 처리에 대해서 두 가지 "메시지"를 바탕으로 구현해보도록 하겠다.

WM_Create라는 메시지는 "기존 처리기"에서의 함수 이름으로 OnCreate로 사용되고 있다.

OnCreate란, 윈도우 창이 생성되었을 때, 호출되는 메시지 처리를 말한다.

함수 원형으로 표현했을 때를 말한다.

WM_LButtonDBLCLK라는 메시지는 "기존 처리기"에서의 함수 이름으로 OnLButtonDblClk으로 사용되고 있다.

 

다음은 AfxMessage에 대한 것이다. 말 그대로 메시지 처리에서 상자를 만드는 것이다.

 

 

 

[사용 환경]
Microsoft Visual Studio 2019

Microsoft Windows 10

 


1. 프로젝트 생성하기

 

프로젝트 생성은 아래의 그림 단계처럼 진행할 수 있다.

 

 

그림 1) 프로젝트 생성하기

 

 

그림 2) 프로젝트 생성하기

 

 

 

그림 3) 프로젝트 생성하기

 

 

그림 4) 프로젝트 생성하기

 

 

 

그림 5) 프로젝트 생성하기

 

 

 

그림 6) 프로젝트 생성하기

 


2. 클래스 마법사로 (2가지)기능 생성하기

 

메시지 처리에 관한 기능을 생성할 것이다.

WM_Create와 WM_LButtonDblClick을 생성하여 코드를 입력해주겠다.

 

 

그림 7) 클래스 마법사에서 함수 원형 만들기

 

 

그림 8) 클래스 마법사에서 함수 원형 만들기

 

 

그림 9) 클래스 마법사에서 함수 원형 만들기

 

 

그림 10) 클래스 마법사에서 함수 원형 코드 입력하기

 

 

그림 11) 클래스 마법사에서 함수 원형 만들기

 

AfxMessage(_T("윈도우가 생성되었습니다."), MB_OKCANCEL | MB_ICONINFORMATION );

 

 

그림 11) 클래스 마법사에서 함수 원형 만들기

 

 

그림 12) 클래스 마법사에서 함수 원형에 코드 입력하기

 


3. 시연하기(Practice)

 

코드 입력 등이 완료가 되었다면, "Ctrl + F5키" 또는 "로컬 Windows 디버거"를 클릭하여 시연하면 된다.

 

 

그림 13) 시연하기

 

 

그림 14) 시연하기

 

반응형
728x90
300x250
[MFC] 도큐먼트(폼 뷰) - DDX에 관한 이야기

 

이전의 Visual Studio 2010, Visual Studio 2013, Visual Studio 2015에서는 아래처럼 따라하면, CFormView에서 변수를 생성할 수 있었다.

하지만, 최근 출시된 Visual Studio 2019에서는 달라진 점이 CFormView에서는 그냥 더블클릭 하나면 변수가 생성된다는 점이다.

이전의 주요 기능은 남아있으나 C#으로 진영이 넘어가는 것으로 보인다.

 

태스트 환경:
Microsoft Visual Studio 2019 Community
Microsoft Windows 10

 


1. 프로젝트 생성하기

 

새 프로젝트 만들기->MFC 앱을 클릭한다.

 

 

그림 1) 프로젝트 생성하기 (1단계)

 

 

 

그림 2) 프로젝트 생성하기 (2단계 - 프로젝트 이름 지정)

 

 

 

 

그림 3) 프로젝트 생성하기 (단일 문서)

 

 

그림 4) 프로젝트 생성하기 (단일 문서)

 

파일 확장명을 "txt"라고 입력 후 "다음"을 클릭한다.

 

 

그림 5) Command bar (menu/toolbar/ribbon)에서 메뉴 모음 및 도구 모음 사용을 클릭하기

 

 

그림 6) View 클래스 선택 후, 마침 누르기

 

FormView_ex에서 리소스 파일을 클릭 후 Formview_ex.rc를 더블 클릭한다.

 

 

그림 7) 완성된 프로젝트

 

 

그림 8) 완성된 프로젝트

 


2. CFormView 확인하기

 

초기에 생성된 CFormView의 모습이다.

IDD_FORMVIEW_EX_FORM의 Style은 Child로 지정한다.

 

 

그림 9) IDD_FORMVIEW_EX_FORM 스타일 설정의 예

 

IDD_FORMVIEW_EX_FORM 스타일을 Child가 아닌 Popup으로 변경할 경우, 오류가 발생한다.

 

임시로 Ctrl+F5를 눌러서 잘 동작하는지 확인을 해본다.

 

 

그림 10) 프로젝트가 동작하는 모습의 예

 

 


3. CFormView 꾸미기(실습)

 

FormViewex.rc의 IDD_FORMVIEW_EX_FORM (Dialog)를 아래처럼 컨트롤박스를 배치하여 꾸미도록 한다.

이전 버전(Visual Studio 2010, Visual Studio 2013, 2015, 2017)과 호환이 된다.

 

 

그림 11) 디자인 모습

 

그림 11처럼 도구 상자에 있는 컨트롤을 배치하도록 한다.

 

 

 

그림 12) ID 이름 변경하기

 

 

 

그림 13) IDC_EDIT_BLUE (Edit Control)의 Number 옵션 변경하기

 

그림 13처럼 Number 옵션을 True로 변경하면 항상 숫자만 입력할 수 밖에 없도록 된다.

 

 

 

그림 14) Caption 변경하는 모습

 


4. 충돌 오류 발생 - "변수 추가(B)..."

 

Visual Studio 2017, Visual Studio 2019부터 CFormView에서 변수 추가(B)로 컨트롤에 변수를 주는 것이 금지되었다.

"DoDataExchange 메서드를 업데이트할 수 없습니다."라는 오류를 발생시킨다.

 

 

그림 15) 변수 추가(B)의 모습

 

 

그림 16) 변수명을 이전 스타일(Visual Studio 2015)로 입력하는 모습의 예

 

범주(T)를 "값"으로 설정하고 이전 스타일로 입력을 하였다.

이전 버전에서는 동작할 수도 있겠으나 최신 버전(Visual Studio 2017, 2019)에서는 동작하지 않는다.

 

"DoDataExchanage 메서드를 업데이트할 수 없습니다." 라는 오류를 접하게 된다.

아래의 그림들도 마찬가지이다.

 

 

그림 17) 변수명을 이전 스타일(Visual Studio 2015)로 입력하는 모습의 예

 

 

그림 18) 변수명을 이전 스타일(Visual Studio 2015)로 입력하는 모습의 예

 


5. 다이얼 로그에서만 사용가능

 

마이크로소프트 공식 사이트에서 "대화 상자 작업"이라는 주제에 대해서 찾아보았다.

해당 관련 자료를 찾아볼 수 있었다.

https://docs.microsoft.com/ko-kr/cpp/mfc/life-cycle-of-a-dialog-box?view=vs-2019

https://docs.microsoft.com/ko-kr/cpp/mfc/dialog-data-exchange?view=vs-2019

 

그림 19) MFC 공식 메뉴얼 - 마이크로소프트

 

 

그림 20) 대화 상자 데이터 교환 - 마이크로소프트

원리, 이론적으로는 가능해보이나 Visual Studio 2019부터는 훨씬 엄격해진 것 같다.

 


결론(Conclusion)

 

CFormView에서는 DDX 메커니즘은 동작하지 않는다.

 

[첨부(Attachment)]

FormView_ex1.zip

반응형
728x90
300x250

[MS C++(MFC)] SDI(단일 문서)에서 자녀 다이얼로그(Child dialog in single document interface (SDI)


MFC의 SDI를 다루는 방법 중 자녀 다이얼로그 제어에 대해서 소개합니다.
(This section introduces the child dialog control method of handling MDI's SDI.)

작성 환경은 Visual Studio 2019, Windows 10 1909에서 진행하였습니다.
(The authoring environment was in Visual Studio 2019, Windows 10 1909.)

 


1. MFC 프로젝트 생성하기(Creating an MFC Project)

 

"단일 문서"를 선택하고 아래의 그림처럼 설정합니다.
(Select "Single Document" and set it as shown below.)

 

다음을 누릅니다.(Click Next.)

 

 

다음을 누릅니다.(Click Next.)

 

 

다음을 누릅니다.(Click Next.)

 

 

"체크 박스"를 위의 그림처럼 해줍니다.(Do a "check box" as shown above.)

 

 

마침을 클릭합니다.(Click Finish.)

"로컬 Windows 디버거" 또는 "Ctrl + F5키"를 누르면 아래의 창이 뜹니다.
(Press "Local Windows Debugger" or "Ctrl + F5" to bring up the window below.)

 

 


2. MFCFormView.rc에서 다이얼로그 생성하기(Creating a dialog in MFCFormView.rc)

 

다이얼로그를 하나 생성합니다. (Create one dialog.)

 

 

다이얼 로그를 생성하면 아래의 그림처럼 생성됩니다.(When you create a dial log, it is created as shown below.)

 

 

그리고 다이얼 로그를 오른쪽 버튼 한 후, 클래스 추가를 클릭합니다.
(Then right-click on the dialog and click Add Class.)

 

 

Dlg1으로 해도 상관없지만, 기존 이름에 C만 더 붙여서 CDlg로 클래스 이름을 지정해주는 것도 하나의 방법입니다.
(Dlg1 can be used, but it is also a way to specify the class name as CDlg by adding C to the existing name.)

 

예제에서는 편의상 Dlg1으로 하였습니다.(In this example, we have used Dlg1 for convenience.)

 


3. 메뉴에 다이얼로그 커맨드 기능 추가하기(Adding dialog command functions to the menu)

 

메뉴에 다이얼로그 커맨드 기능을 추가하겠습니다.(We will add a dialog command function to the menu.)

 

 

"예"라는 항목에 ID에 "ID_TOOLS_EX"로 지정하였습니다.(You have assigned "ID_TOOLS_EX" to the ID of "Yes".)

 

 

오른쪽 버튼을 클릭 후 "이벤트 처리기 추가(A)..."를 클릭합니다.
(Right click and click "Add Event Handler ...")

 

 

그림처럼 설정이 되어있을 것입니다. 확인을 클릭합니다. (It will be set as shown. Click OK.)

 


4. 코드 작성(Write the code)

 

코드 작성은 크게 어렵지 않게 진행할 수 있습니다.(Writing code can be very easy.)

 

 

그림에서는 CDlg.h로 되어있는데, 앞에 설명은 Dlg.h로 설명한 것처럼 보일 수 있습니다.

앞에서 지정한 헤더명으로 입력해주시면 됩니다.

Inteligence 기능으로 헤더를 찾아주기 때문에 적절히 잘 지정해주면 될 것 같습니다.

 

(In the figure, it is called CDlg.h, which may look like the one described as Dlg.h.

Enter the header name you specified earlier.

The Inteligence function finds the header, so I think it should be properly specified.)

 

 

 

반응형
728x90
300x250
[MS C++(MFC)] Visual C++ 샘플 사이트 소개 및 백업 안내

 

소개하고자 하는 사이트는 Microsoft에서 공식적으로 배포하고 있는 Visual C++ 샘플에 관한 페이지이다.

(The site I want to introduce is a page about the Visual C ++ samples that are officially distributed by Microsoft.)

https://docs.microsoft.com/ko-kr/cpp/overview/visual-cpp-samples?view=vs-2019

 

 

 

그림 1) MS Doc 공식 홈페이지

 

MFC 샘플 페이지를 보면, MSDN 코드 갤러리라는 페이지가 사용 중지될 예정이라고 코드를 백업하라는 메시지가 출력되어 있다.

Visual Studio 2019에서 C++ MFC를 사용해보면, 리소스(Resource) 부분에서 오류가 발생해서 튕기는 경우가 자주 발생한다.

(In the MFC sample page, you are prompted to back up your code that the page called MSDN Code Gallery will be deprecated.

When using C ++ MFC in Visual Studio 2019, you'll often see errors and bounces in the Resource section.)

 

 

그림 2) MSDN 홈페이지

 

반응형
728x90
300x250
[MS Visual C++] Visual Studio 2019(C++ MFC) 사용하기 및 OpenCV 4.1 환경설정


Microsoft Windows 10, Visual Studio 2019으로 진행하였습니다.

C++ MFC를 사용하면, 종종 프로그램이 강제로 튕기는 것을 경험할 수 있습니다.

C#으로 가는 것이 좋을 거 같다는 의견입니다.


(I went to Microsoft Windows 10, Visual Studio 2019.)
(With C ++ MFC, you can often experience program bounces.)
(I think it would be nice to go to C#.)



1. MFC 설치하기


Visual Studio 2017, Visual Studio 2019부터는 MFC를 자동으로 지원하지 않습니다. 개별적으로 설치해야 합니다.

(Starting with Visual Studio 2017, Visual Studio 2019, MFC is not automatically supported.)



2. OpenCV 시작하기(Getting started with OpenCV)

OpenCV는 아래의 사이트에서 내려받을 수 있습니다. (OpenCV can be downloaded from the following site.)

https://www.opencv.org




Learn More를 클릭합니다.



OpenCV - 4.1.2에서 Windows를 클릭합니다.

(In OpenCV-4.1.2, click Windows.)






다운받은 파일을 Extract로 풀어줍니다.(Extract the downloaded file with Extract.)





2-1. 압축 풀었던 OpenCV 폴더 C:\로 이동하기(2-1. Navigate to the Unzipped OpenCV folder C:\)


압축 풀었던 Opencv 폴더를 C:\로 이동합니다.(Move the extracted Opencv folder to C:\.)







3. 프로젝트 구성하기(Organize your project)


프로젝트 구성입니다. MFC 앱을 검색하여 더블클릭하면, 아래의 그림을 볼 수 있습니다.

(Project configuration. Search for the MFC app and double-click it to see the picture below.)


단일 문서, 대화 상자, 다중 문서에 대해서 전부 소개하지 않았기 때문에 깊이 생각하지 않으셨으면 합니다.

(I didn't introduce a single document, a dialog box, or multiple documents, so I don't want to think deeply about it.)



4. 프로젝트 속성 변경하기(Changing project properties)


제일 중요한 부분이 아니겠느냐 싶습니다.

이 부분 설정을 해놓으면 코딩은 구역에 프로그램 코드를 작성해서 잘 동작하도록 만들어주면 되겠습니다.

(I think it's the most important part.)
(With this part set up, the coding can be done by writing program code in the section.)












참고하면 흥미로운 정보(Interesting information for your reference)


-> 카테고리에 opencvCsharp 이라는 코너를 운영하고 있습니다. 같이 병행해서 보면 도움이 될 것입니다.

(Categories are operating in the corner of opencvCsharp. It will be helpful to see them in parallel.)

반응형
728x90
300x250

[MFC] Visual C++ 2019(C++ MFC)에서 Maria DB 연동하기

마리아 DB를 Visual C++ 2019(C++ MFC)에서 사용하는 방법을 소개하겠습니다.

 

1단계: 프로젝트 생성하기

Visual Studio 2019를 켭니다.

 

"새 프로젝트 만들기"를 클릭합니다.

 

 

"MFC 앱"을 클릭합니다.

 

프로젝트 이름을 정한 후 다음을 누릅니다.

이번 예제에서는 "대화 상자 기반"으로 하였습니다.
"대화 상자 기반"을 클릭합니다.

"다음"을 누릅니다.

 

주 프레임 스타일의 체크를 "해제"합니다.

"다음"을 클릭합니다.

"인쇄 및 인쇄 미리 보기(P)", "ActiveX 컨트롤(R)"을 체크 해제합니다.

"다음"을 클릭합니다.

생성된 클래스의 이름 등을 확인하고 "마침"을 클릭합니다.

 

 

2단계: Maria DB Connector(MySQL Connector)

DB 사용 방법은 MySQL과 Maria DB는 동일하나 Connector 등에서 일부 이름이 변경되었습니다.


(MySQL Connectors)
https://dev.mysql.com/downloads/connector/

 

MySQL :: MySQL Connectors

MySQL Connectors MySQL offers standard database driver connectivity for using MySQL with applications and tools that are compatible with industry standards ODBC and JDBC. Any system that works with ODBC or JDBC can use MySQL. Standardized database driver f

dev.mysql.com

(Maria Connectors)
https://downloads.mariadb.org/

 

Downloads - MariaDB

 

downloads.mariadb.org

3단계: libmariadb.dll 문제

(아래 파일로 작업을 하시는 분들은 64bit로 디버그, 릴리즈하셔야 합니다.
MariaDB 10.4 64bit 버전에서 추출하였습니다.)

lib-mariadb-10.4.7z
2.52MB


4단계: 프로젝트 속성 변경

MariaDB-Connector를 소스 코드 버전으로 다운받은 경우입니다.

C/C++의 경로 설정할 때 변경해주시면 되겠습니다.

예: c:\....\mariadb-connector-c-3.1.2-src\mariadb-connector-c-3.1.2-src\include

 

"프로젝트 속성 창"을 띄우는 방법은 다음과 같습니다.

아래처럼 설정해줍니다.
첫 번째
"VC++ 디렉터리->" 라이브러리 디렉터리 : C:\................\MariaDB XX.X\lib

 

두 번째

"C/C++->추가 포함 디렉터리": C:\................\MariaDB XX.X\include\mysql

또는 c:\....\mariadb-connector-c-3.1.2-src\mariadb-connector-c-3.1.2-src\include
(MySQL 사용자는 mysql-connector.....로 찾아서 할 것)

 

세 번째

"링커->추가 종속성" libmariadb.lib로 설정해주기

(MySQL 사용자는 libmysql.lib로 할 것)

5단계: libmysql.dll 또는 libmariadb.dll 프로젝트에 추가해주기


아래의 그림처럼 libmariadb.dll 또는 libmysql.dll을 추가해줍니다. 참조성 오류를 예방할 수 있습니다.



6단계: 사용자 인터페이스 구현

이쁘게 그려줍니다.

(리스트 박스, 텍스트 박스, 버튼, 그룹 박스)를 사용하였습니다.

"아이디", "이름", "생년월일", "리스트박스"의 "변수"를 지정하였습니다.

변수 지정을 잊어버린 분들을 위해서 아래 그림을 보면 생각이 나게 될 것입니다.

변수는 아래처럼 선택하고 입력하면 되겠습니다.
이름(N)은 "m_txtId"로 하였습니다.
범주(T)는 "값"으로 선택하였습니다.

최대 문자는 적절하게 조절하시면 되겠습니다.

ID 변수명 비고
IDC_TxtID m_TxtId  
IDC_TxtName m_TxtName  
IDC_IDC_DATETIMEPICKER m_txtBirthDate  
IDC_LST_Dataview   Report로 속성 변경하였음.


7단계:

소스 코드는 아래처럼 사용하면 적절할 거 같습니다.

MFCApplication1Dlg.cpp

BOOL CMFCApplication1Dlg::OnInitDialog()
BOOL CMFCApplication1Dlg::OnInitDialog()
{
CDialogEx::OnInitDialog();

// m_lst_dataview
m_lst_dataview.InsertColumn(0, _T("번호"), NULL, 50);
m_lst_dataview.InsertColumn(1, _T("이름"), NULL, 150);
m_lst_dataview.InsertColumn(2, _T("생년월일"), NULL, 20);

// 시스템 메뉴에 "정보..." 메뉴 항목을 추가합니다.

// IDM_ABOUTBOX는 시스템 명령 범위에 있어야 합니다.
ASSERT((IDM_ABOUTBOX & 0xFFF0) == IDM_ABOUTBOX);
ASSERT(IDM_ABOUTBOX < 0xF000);

CMenu* pSysMenu = GetSystemMenu(FALSE);
if (pSysMenu != nullptr)
{
BOOL bNameValid;
CString strAboutMenu;
bNameValid = strAboutMenu.LoadString(IDS_ABOUTBOX);
ASSERT(bNameValid);
if (!strAboutMenu.IsEmpty())
{
pSysMenu->AppendMenu(MF_SEPARATOR);
pSysMenu->AppendMenu(MF_STRING, IDM_ABOUTBOX, strAboutMenu);
}
}

// 이 대화 상자의 아이콘을 설정합니다.  응용 프로그램의 주 창이 대화 상자가 아닐 경우에는
//  프레임워크가 이 작업을 자동으로 수행합니다.
SetIcon(m_hIcon, TRUE); // 큰 아이콘을 설정합니다.
SetIcon(m_hIcon, FALSE); // 작은 아이콘을 설정합니다.

// TODO: 여기에 추가 초기화 작업을 추가합니다.

return TRUE;  // 포커스를 컨트롤에 설정하지 않으면 TRUE를 반환합니다.
}
void CMFCApplication1Dlg::OnBnClickedBtnSubmit()
void CMFCApplication1Dlg::OnBnClickedBtnSubmit()
{
CString strTxt = CString(_T("안녕하세요"));
MessageBoxW( (LPCTSTR) strTxt );

UpdateData(TRUE); // 필드 값 최신화
MessageBox((LPCTSTR)m_txtId, _T("알림(Alert)"), MB_ICONINFORMATION);
}
void CMFCApplication1Dlg::OnBnClickedBtnDataload()
void CMFCApplication1Dlg::OnBnClickedBtnDataload()
{

LVITEM firstitem;

char* host = "hostName";
char* userId = "userID";
char* passwd = "passwd";
char* dbName = "dbName";
int port = 3306;

/* MariaDB(MySQL 연동) */
MYSQL mysql;
MYSQL_RES* res;
MYSQL_ROW row;

mysql_init(&mysql);
if (mysql_real_connect(&mysql, host, userId, passwd, dbName, port, NULL, 0) == NULL)
{
return;
}
else {
mysql_query(&mysql, "set names euckr"); // 한글 깨짐 보완
}

char* szQuery = "select * from member";

if (mysql_query(&mysql, szQuery)) {
return;
}

if ((res = mysql_store_result(&mysql)) == NULL) {
return;
}

row = mysql_fetch_row(res);

while (row)
{
std::string name = row[1];
std::string type = row[2];

CString tmp;
tmp = name.c_str();

firstitem = { 0 };

firstitem.mask = LVIF_TEXT;
firstitem.iItem = 0;

// 데이터 삽입 - Firstitem
m_lst_dataview.InsertItem(&firstitem);

// 데이터 값 넣기 - Firstitem
m_lst_dataview.SetItemText(0, 0, _T("1번"));
m_lst_dataview.SetItemText(0, 1, tmp);
m_lst_dataview.SetItemText(0, 2, _T("도도1-2"));

row = mysql_fetch_row(res);
}

mysql_free_result(res);

mysql_close(&mysql);

}
void CMFCApplication1Dlg::OnBnClickedBtnDatainsert()
void CMFCApplication1Dlg::OnBnClickedBtnDatainsert()
{
LVITEM firstitem;

char* host = "hostName";
char* userId = "userID";
char* passwd = "passwd";
char* dbName = "dbName";
int port = 3306;

/* MariaDB(MySQL 연동) */
MYSQL mysql;
MYSQL_RES* res;
MYSQL_ROW row;

UpdateData(TRUE); // 필드 값 최신화

mysql_init(&mysql);
if (mysql_real_connect(&mysql, host, userId, passwd, dbName, port, NULL, 0) == NULL)
{
return;
}
else {
mysql_query(&mysql, "set names euckr"); // 한글 깨짐 보완
}

const int KO_KR_MAX_SIZE = 128; // 한글 지원(여유공간)
CString csTemp = (LPCTSTR)m_txtId;
char* strName = new char[(strlen(CT2A(csTemp)) + 1) + KO_KR_MAX_SIZE];
strcpy_s(strName, sizeof(strName) + KO_KR_MAX_SIZE, CT2A(csTemp));

CTime cTime = m_txtBirthDate.GetYear();

csTemp.Empty();
csTemp.Format(_T("%04d-%02d-%02d %d:%d:%d"), m_txtBirthDate.GetYear(),
m_txtBirthDate.GetMonth(),
m_txtBirthDate.GetDay(),
m_txtBirthDate.GetHour(),
m_txtBirthDate.GetMinute(),
m_txtBirthDate.GetSecond());


char* strBirthDate = new char[(strlen(CT2A(csTemp)) + 1) + KO_KR_MAX_SIZE];
strcpy_s(strBirthDate, sizeof(strBirthDate) + KO_KR_MAX_SIZE, CT2A(csTemp));

char szQuery[256 + KO_KR_MAX_SIZE];
int len = sprintf_s(szQuery, sizeof(szQuery), "insert into member(name, birthdate) values('%s', '%s')", strName, strBirthDate);

if (mysql_query(&mysql, szQuery)) {
return;
}

int check = _CrtDumpMemoryLeaks();

mysql_close(&mysql);

}



* 참고(Reference):

1. CWnd::MessageBox | Microsoft Docs, https://docs.microsoft.com/en-us/previous-versions/0eebkf6f(v=vs.140) Last Modified 2019-07-23, Accessed by 2019-07-23
2. CWnd 클래스 | Microsoft Docs, https://docs.microsoft.com/ko-kr/cpp/mfc/reference/cwnd-class?view=vs-2019#messagebox Last Modified 2019-07-23, Accessed by 2019-07-23
3. MariaDB Connector/C - MariaDB, https://downloads.mariadb.org/connector-c/, Last Modified 2019-07-23, Accessed by 2019-07-23
4. GitHub - viaduck/mariadbpp: C++ client library for MariaDB. Continuation of https://code.launchpad.net/mariadb++, https://github.com/viaduck/mariadbpp, Last Modified 2019-07-23, Accessed by 2019-07-23

반응형
728x90
300x250

[MFC] 윈도우 프로그래밍 기초 - 트리 컨트롤

 

이번에는 트리 컨트롤에 대해서 소개하고자 합니다.

 

위의 그림에서 빨간색으로 표기된 구조가 Tree Control의 한 예입니다.

이런 구조는 많이 익숙하실거라고 생각됩니다.

 


1. CTreeCtrl 클래스

 

1-a. 멤버 함수

 * InsertItem

 HTREEITEM InsertItem( LPCTSTR lpszItem, HTREEITEM hParent = TVI_ROOT , HTREEITEM hInsertAfter = TVI_LAST ) ;

 

 -> lpszItem : 아이템에 표시할 문자열 주소

 -> hParent : 추가되어 있는 부모 아이템의 헨들 -> TVI_ROOT는 루트 아이템으로 기본 값 지정되어 있음.

 

     (궁금하신 분들은 자료 정의나 구글링 해보세요.)

 -> hInsertAfter : 새로운 아이템이 어떤 아이템의 뒤에 삽입될 것인지를 지정

 *> Return Value : 추가된 아이템의 헨들(HTREEITEM 반환), 실패시 NULL

 

 기존에 리스트 컨트롤 강의에선 InsertItem 이런 거에 담는 개념이었는데,

 이 원형은 HTREEITEM이라는 형태로 반환하여 뿌리 구축 단위로 동작함. (직접 코드 짜보면 이해함)

 

 * DeleteItem 

 BOOL DeleteItem ( HTREEITEM hItem ) ;

 -> hItem : 삭제할 트리 아이템의 헨들

 -> Return Value : 성공시 TRUE, 실패시 FALSE;

 * DeleteAllItems

 BOOL DeleteAllItems( ) ;

 

 -> 트리 컨트롤의 모든 아이템들을 전체 삭제함.

 

 -> Return Value : 성공시 TRUE, 실패시 FALSE

 * GetParentItem

 HTREEITEM GetParentItem( HTREEITEM hItem ) const;

 

 -> hItem : 부모 아이템을 찾고자 하는 트리 아이템의 핸들 (쉽게 말하면 부모 아이템을 가져온다고 이해하는 게 정신적으로 편함)

 -> Return Value : 부모 아이템의 핸들, 실패시 NULL

 

 * GetItemText

 CString GetItemText ( HTREEITEM hItem ) const ;

 

 -> hItem : 텍스트를 획득하고자 하는 트리 아이템의 핸들

 -> Return Value : 트리 아이템의 텍스트

 


1-b. 트리 컨트롤(Tree Control)의 Primative Attribute (주요 속성)

 

 

 

주요 속성이라고 지정하긴 제목을 말하긴 했는데, 트리를 운영하는 데 가장 중요한 요소라서 이렇게 불렀으니깐

쉽게 생각하시기 바랍니다. 잊어버리셔도 됩니다. 동물적으로 찾아서 보실 수 있으면 됩니다.

 

 트리 컨트롤 속성

 설명

 Check Boxes

 아이템에 체크박스를 표시하기 위한 속성

 Has Buttons

 서브 아이템이 있는 경우,

 해당 아이템에 [+], [-] 버튼을 표시하기 위한 속성

 (옵션??이 더 맞는 말인거 같음)

 Has Lines

 아이템 간의 연결 관계를 라인을 사용하여 표현하기 위한 속성

 -> 제 블로그에도 사실 보면 트리 라인있습니다.

     모르시면 메뉴 보셔도 됩니다.

 Lines At Root

 루트 아이템에도 라인을 표시하기 위한 속성.

 Single Expand

 확장되는 아이템을 하나로 지정하기 위한 속성.

 True로 설정하면 하나의 아이템을 확장했을 때 다른 확장 아이템은 축소한다.

 Tract Select

 트래킹 표시를 지정하기 위한 속성

 True로 설정하면 마우스 포인터가 위치된 아이템에 밑줄이 표시된다.

 

 


2. 결과물

 

 

 

 

 

 

 

 

 


3. 실습

 

a. 레이아웃 디자인

 

컨트롤 이름 

 범주(T)

 매개 변수(N)

 비고

 IDC_TREE1

 Control

 m_yourtree

 

 IDC_EDIT1

 해당 없음

 해당 없음

 해당 없음

 

IDC_TREE1의 리소스 속성

Has Buttons, Has Lines, Single Expand, Lines At Root (True)로 해주기

 

 

 

 


4. 코드 구현

 

// CMyTreeDlg 메시지 처리기

BOOL CMyTreeDlg::OnInitDialog()

 

//         (중략~~~~~)

 

         // TODO: 여기에 추가 초기화 작업을 추가합니다.

         HTREEITEM root_branch = m_yourtree.InsertItem(_T("지사"));
         HTREEITEM root_headoffice = m_yourtree.InsertItem(_T("본사"));

         HTREEITEM child_b_china = m_yourtree.InsertItem(_T("중국"), root_branch);
         HTREEITEM child_b_gumi = m_yourtree.InsertItem(_T("한국"), root_branch);

         HTREEITEM child_h_seoul = m_yourtree.InsertItem(_T("서울"), root_headoffice);
         HTREEITEM child_b_c_bejing = m_yourtree.InsertItem(_T("베이징"), child_b_china);

         // this->m_yourtree.InsertItem

 

//         (중략~~~~~)

 

}

 OnInitDialog

 

 

void CMyTreeDlg::OnTvnSelchangedTree1(NMHDR *pNMHDR, LRESULT *pResult)
{
 LPNMTREEVIEW pNMTreeView = reinterpret_cast<LPNMTREEVIEW>(pNMHDR);  // 자동 생성된 부분임.

 

          // TODO: 여기에 컨트롤 알림 처리기 코드를 추가합니다.
          HTREEITEM hItemRoot;
          HTREEITEM hItemParent;
          HTREEITEM hItemCur;

 

          CString strRoot;
          CString strParent;
          CString strCur;

          CString strTxt;

 

          hItemCur = pNMTreeView->itemNew.hItem;
          hItemParent = this->m_yourtree.GetParentItem( hItemCur );
          hItemRoot = this->m_yourtree.GetParentItem( hItemParent );

 

          strRoot = m_yourtree.GetItemText(hItemRoot);
          strParent = m_yourtree.GetItemText(hItemParent);
          strCur = m_yourtree.GetItemText(hItemCur);
 
          strTxt.Append(_T("/") + strRoot);
          strTxt.Append(_T("/") + strParent);
          strTxt.Append(_T("/") + strCur);
 
          ::SetDlgItemText( this->m_hWnd, IDC_EDIT1, strTxt );

 

 

           *pResult = 0;      // 자동 생성된 부분임.

 

 OnTvnSelchangedTree1 ( ) -> 마우스로 클릭해서 생성한 함수 원형
 -> (쉽게 말하면, 트리 선택시 동작 구현)

 

 

 

 

 

 

[첨부(Attachment)]

MyTree.zip

 

 

반응형

+ Recent posts