<?xml version="1.0" encoding="utf-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom">
    <channel>
        <title>hj-yu-code.log</title>
        <link>https://velog.io/</link>
        <description>내가 시작한 공부, 공유할 코드</description>
        <lastBuildDate>Tue, 03 May 2022 05:05:40 GMT</lastBuildDate>
        <docs>https://validator.w3.org/feed/docs/rss2.html</docs>
        <generator>https://github.com/jpmonette/feed</generator>
        <image>
            <title>hj-yu-code.log</title>
            <url>https://images.velog.io/images/hj-yu-code/profile/62840732-01db-440e-a35c-576ece0c25db/social.jpeg</url>
            <link>https://velog.io/</link>
        </image>
        <copyright>Copyright (C) 2019. hj-yu-code.log. All rights reserved.</copyright>
        <atom:link href="https://v2.velog.io/rss/hj-yu-code" rel="self" type="application/rss+xml"/>
        <item>
            <title><![CDATA[mfc db 연결]]></title>
            <link>https://velog.io/@hj-yu-code/mfc-db-%EC%97%B0%EA%B2%B0</link>
            <guid>https://velog.io/@hj-yu-code/mfc-db-%EC%97%B0%EA%B2%B0</guid>
            <pubDate>Tue, 03 May 2022 05:05:40 GMT</pubDate>
            <description><![CDATA[<p>ms access 파일로 연결하기
ODBC 데이터 원본관리자(32비트)
<img src="https://velog.velcdn.com/images/hj-yu-code/post/0ff8e9b7-279e-480e-aacf-502d4eff33fd/image.png" alt=""></p>
<p><img src="https://velog.velcdn.com/images/hj-yu-code/post/5435fba1-51fe-4dfd-b6e1-09ede5a46393/image.png" alt="">
<img src="https://velog.velcdn.com/images/hj-yu-code/post/a6297cfa-45b8-4b58-b667-3347b1a5bc1d/image.png" alt=""></p>
<p><img src="https://velog.velcdn.com/images/hj-yu-code/post/b25b25e1-cabd-4909-9796-b41444ba5983/image.png" alt=""></p>
<p><img src="https://velog.velcdn.com/images/hj-yu-code/post/d228e937-62a3-4e20-84f6-897715264d02/image.png" alt="">
고급설정도 진행하기
<img src="https://velog.velcdn.com/images/hj-yu-code/post/29b34c51-0c8f-4e23-b5bc-7678e64cdfc6/image.png" alt=""></p>
<p><img src="https://velog.velcdn.com/images/hj-yu-code/post/f0b52084-c501-4a01-94c3-4caf0b6813c9/image.png" alt=""></p>
<p>mfc 애플리케이션 옵션 설정
프로젝트 이름 : MFCODBC_EXAM
<img src="https://velog.velcdn.com/images/hj-yu-code/post/a9a6521e-4db4-441e-b326-f24b98dd0128/image.png" alt="">
<img src="https://velog.velcdn.com/images/hj-yu-code/post/cbef8925-81a3-4d63-99fa-5cfb73f5184d/image.png" alt=""></p>
<ul>
<li>formview를 사용하는 이유: 대화상자를 만들어서 버튼을 만들기 위함</li>
</ul>
<p><img src="https://velog.velcdn.com/images/hj-yu-code/post/8ed855d7-690b-415e-a3b1-5d397e638a84/image.png" alt=""></p>
<p>----framework.h</p>
<pre><code class="language-cpp">// odbc 관련된 헤더 파일
#include &lt;afxdb.h&gt;</code></pre>
<p><img src="https://velog.velcdn.com/images/hj-yu-code/post/d8d9bf7f-94a1-4994-a637-fa7c5da3c3e6/image.png" alt="">
32비트로 설정 (ms access만 해당)</p>
<p>----view.cpp</p>
<pre><code class="language-c++">BOOL CMFCODBCEXAMView::PreCreateWindow(CREATESTRUCT&amp; cs)
{
    // TODO: CREATESTRUCT cs를 수정하여 여기에서
    //  Window 클래스 또는 스타일을 수정합니다.

    return CFormView::PreCreateWindow(cs);
}

void CMFCODBCEXAMView::OnInitialUpdate()
{
    CFormView::OnInitialUpdate();
    GetParentFrame()-&gt;RecalcLayout();
    ResizeParentToFit();

    /*
    1. db 연결
    2. sql 실행
    3. sql 결과 얻기
    4. 연결 종료

    CDatabase 클래스 : db 연결 관리하는 클래스
    CRecordset 클래스 : sql 구문을 실행하고 결과 집합을 관라하는 클래스
    */

    //1. db 연결
    CDatabase db;
    BOOL bRet = db.OpenEx(_T(&quot;DSN=scott_db;uid=user1;PWD=passwd;&quot;), 0);

    if (bRet) {
        AfxMessageBox(_T(&quot;DB 연결 성공&quot;));
    }
    else {
        AfxMessageBox(_T(&quot;DB 연결 실패&quot;));

    }
    //4. 연결 종료
    db.Close();
}</code></pre>
<p><img src="https://velog.velcdn.com/images/hj-yu-code/post/b713566f-3c90-41ee-b450-e4a1de63722c/image.png" alt=""></p>
<p>데이터 값 넣기
----view.cpp</p>
<pre><code class="language-cpp">void CMFCODBCEXAMView::OnInitialUpdate()
{
    CFormView::OnInitialUpdate();
    GetParentFrame()-&gt;RecalcLayout();
    ResizeParentToFit();

    m_imageList.Create(48, 48, ILC_COLOR32, 5, 5);
    m_imageListSmall.Create(16, 16, ILC_COLOR32, 5, 5);

    m_imageList.Add(AfxGetApp()-&gt;LoadIcon(IDR_MAINFRAME));
    m_imageListSmall.Add(AfxGetApp()-&gt;LoadIcon(IDR_MAINFRAME));

    m_listView.SetImageList(&amp;m_imageList, LVSIL_NORMAL);
    m_listView.SetImageList(&amp;m_imageListSmall, LVSIL_SMALL);


    //칼럼 정보 출력
    m_listView.InsertColumn(0, _T(&quot;사원번호&quot;), LVCFMT_LEFT, 100);
    m_listView.InsertColumn(1, _T(&quot;이름&quot;), LVCFMT_LEFT, 100);
    m_listView.InsertColumn(2, _T(&quot;직업&quot;), LVCFMT_LEFT, 100);
    m_listView.InsertColumn(3, _T(&quot;관리자&quot;), LVCFMT_LEFT, 100);
    m_listView.InsertColumn(4, _T(&quot;입사일자&quot;), LVCFMT_LEFT, 100);
    m_listView.InsertColumn(5, _T(&quot;급여&quot;), LVCFMT_LEFT, 100);
    m_listView.InsertColumn(6, _T(&quot;상여금&quot;), LVCFMT_LEFT, 100);
    m_listView.InsertColumn(7, _T(&quot;부서번호&quot;), LVCFMT_LEFT, 100);

    DWORD dwExStyle = m_listView.GetExtendedStyle();
    m_listView.SetExtendedStyle(dwExStyle | LVS_EX_CHECKBOXES | LVS_EX_BORDERSELECT | LVS_EX_GRIDLINES | LVS_EX_FULLROWSELECT);



    /*
    1. db 연결
    2. sql 실행
    3. sql 결과 얻기
    4. 연결 종료

    CDatabase 클래스 : db 연결 관리하는 클래스
    CRecordset 클래스 : sql 구문을 실행하고 결과 집합을 관라하는 클래스
    */

    //1. db 연결
    CDatabase db;
    BOOL bRet = db.OpenEx(_T(&quot;DSN=scott_db;uid=user1;PWD=passwd;&quot;), 0);
    if (bRet) {
        //AfxMessageBox(_T(&quot;DB 연결 성공&quot;));

        //2. sql 실행
        CRecordset rs(&amp;db);
        rs.Open(CRecordset::forwardOnly, _T(&quot;select * from emp&quot;));
        // rs에 데이터가 배열로 존재하게 됨

        //3. sql 결과 얻기
        int nRow = 0;
        CString strEmpNo;
        CString strEmpName;
        CString strEmpJob;
        while (!rs.IsEOF()) { // 마지막인지 확인
            rs.GetFieldValue((short)0, strEmpNo);
            rs.GetFieldValue((short)1, strEmpName);

            m_listView.InsertItem(nRow, strEmpNo, 0);
            m_listView.SetItemText(nRow++, 1, strEmpName);

            rs.MoveNext();
        }

    }
    else {
        AfxMessageBox(_T(&quot;DB 연결 실패&quot;));
    }
    //4. 연결 종료
    db.Close();
}</code></pre>
<p><img src="https://velog.velcdn.com/images/hj-yu-code/post/1cfc0922-ac1f-4edf-aa06-386fffed8417/image.png" alt=""></p>
<p>데이터 값 전부 넣기</p>
<pre><code class="language-cpp">void CMFCODBCEXAMView::OnInitialUpdate()
{
    CFormView::OnInitialUpdate();
    GetParentFrame()-&gt;RecalcLayout();
    ResizeParentToFit();

    m_imageList.Create(48, 48, ILC_COLOR32, 5, 5);
    m_imageListSmall.Create(16, 16, ILC_COLOR32, 5, 5);

    m_imageList.Add(AfxGetApp()-&gt;LoadIcon(IDR_MAINFRAME));
    m_imageListSmall.Add(AfxGetApp()-&gt;LoadIcon(IDR_MAINFRAME));

    m_listView.SetImageList(&amp;m_imageList, LVSIL_NORMAL);
    m_listView.SetImageList(&amp;m_imageListSmall, LVSIL_SMALL);


    //칼럼 정보 출력
    m_listView.InsertColumn(0, _T(&quot;사원번호&quot;), LVCFMT_LEFT, 100);
    m_listView.InsertColumn(1, _T(&quot;이름&quot;), LVCFMT_LEFT, 100);
    m_listView.InsertColumn(2, _T(&quot;직업&quot;), LVCFMT_LEFT, 100);
    m_listView.InsertColumn(3, _T(&quot;관리자&quot;), LVCFMT_LEFT, 100);
    m_listView.InsertColumn(4, _T(&quot;입사일자&quot;), LVCFMT_LEFT, 100);
    m_listView.InsertColumn(5, _T(&quot;급여&quot;), LVCFMT_LEFT, 100);
    m_listView.InsertColumn(6, _T(&quot;상여금&quot;), LVCFMT_LEFT, 100);
    m_listView.InsertColumn(7, _T(&quot;부서번호&quot;), LVCFMT_LEFT, 100);

    DWORD dwExStyle = m_listView.GetExtendedStyle();
    m_listView.SetExtendedStyle(dwExStyle | LVS_EX_CHECKBOXES | LVS_EX_BORDERSELECT | LVS_EX_GRIDLINES | LVS_EX_FULLROWSELECT);



    /*
    1. db 연결
    2. sql 실행
    3. sql 결과 얻기
    4. 연결 종료

    CDatabase 클래스 : db 연결 관리하는 클래스
    CRecordset 클래스 : sql 구문을 실행하고 결과 집합을 관라하는 클래스
    */

    //1. db 연결
    CDatabase db;
    BOOL bRet = db.OpenEx(_T(&quot;DSN=scott_db;uid=user1;PWD=passwd;&quot;), 0);
    if (bRet) {
        //AfxMessageBox(_T(&quot;DB 연결 성공&quot;));

        //2. sql 실행
        CRecordset rs(&amp;db);
        rs.Open(CRecordset::forwardOnly, _T(&quot;select * from emp&quot;));
        // 형식 맞추기 (날짜, 상여금)
        //rs.Open(CRecordset::forwardOnly, _T(&quot;select                \
        empno, ename, job, mgr, to_char(hirdate, &#39;YYYY-MM-DD&#39;)        \
        hirdate, to_char(sal, &#39;99,999&#39;) sal ,comm, deptno  from emp&quot;));
        // 매니저 이름으로 바꾸기(없을경우는 null 표시)
        //rs.Open(CRecordset::forwardOnly, _T(&quot;select a.empno,                        \
        a.ename, a.job, b.ename mgr_name, to_char(a.hirdate, &#39;YYYY-MM-DD&#39;) hirdate,    \
        to_char(a.sal, &#39;99,999&#39;) sal , a.comm, a.deptno  from emp a, emp b            \
        where a.mgr = b.empno(+)&quot;));
        // 부서명으로 출력하기
        //rs.Open(CRecordset::forwardOnly, _T(&quot;select        \
        a.empno, a.ename, a.job, b.ename mgr_name,            \
        to_char(a.hirdate, &#39;YYYY-MM-DD&#39;) hirdate,            \
        to_char(a.sal, &#39;99,999&#39;) sal , a.comm, c.dname        \
        from emp a, emp b, dept c where a.mgr = b.empno(+)    \
        and a.depto = c.deptno(+)&quot;));

        // rs에 데이터가 배열로 존재하게 됨

        //3. sql 결과 얻기
        int nRow = 0;
        CString strEmpNo;
        CString strEmpName;
        CString strEmpJob;
        CString strEmpMgr;
        CString strEmpDate;
        CString strEmpSal;
        CString strEmpComm;
        CString strEmpDeptno;

        while (!rs.IsEOF()) { // 마지막인지 확인
            rs.GetFieldValue((short)0, strEmpNo);
            rs.GetFieldValue((short)1, strEmpName);
            rs.GetFieldValue((short)2, strEmpJob);
            rs.GetFieldValue((short)3, strEmpMgr);
            rs.GetFieldValue((short)4, strEmpDate);
            rs.GetFieldValue((short)5, strEmpSal);
            rs.GetFieldValue((short)6, strEmpComm);
            rs.GetFieldValue((short)7, strEmpDeptno);

            m_listView.InsertItem(nRow, strEmpNo, 0);
            m_listView.SetItemText(nRow, 1, strEmpName);
            m_listView.SetItemText(nRow, 2, strEmpJob);
            m_listView.SetItemText(nRow, 3, strEmpMgr);
            m_listView.SetItemText(nRow, 4, strEmpDate);
            m_listView.SetItemText(nRow, 5, strEmpSal);
            m_listView.SetItemText(nRow, 6, strEmpComm);
            m_listView.SetItemText(nRow, 7, strEmpDeptno);

            nRow++;

            rs.MoveNext();
        }

    }
    else {
        AfxMessageBox(_T(&quot;DB 연결 실패&quot;));
    }
    //4. 연결 종료
    db.Close();
}</code></pre>
<p><img src="https://velog.velcdn.com/images/hj-yu-code/post/9db2fb41-5a5e-4751-abe8-51b0f2975437/image.png" alt=""></p>
<p>삭제기능 추가
<img src="https://velog.velcdn.com/images/hj-yu-code/post/226731cc-2ba7-4de3-b72a-2558b343a037/image.png" alt=""></p>
<p>---view.cpp</p>
<pre><code class="language-cpp">void CMFCODBCEXAMView::OnBnClickedButton3()
{
    const int nCount = m_listView.GetItemCount();
    CString strEmpNo;
    CString strSQL;

    CDatabase db;
    BOOL bRet = db.OpenEx(_T(&quot;DSN=scott_db;uid=user1;PWD=passwd;&quot;), 0);
    if (bRet) {

        for (int i = nCount - 1; i &gt;= 0; --i) {
            if (m_listView.GetCheck(i)) {
                // 삭제할 사원 번호 얻음
                strEmpNo = m_listView.GetItemText(i, 0); //  사번이 나옴
                AfxMessageBox(strEmpNo);
                // 삭제할 사원 sql구문 생성
                strSQL.Format(_T(&quot;delete from emp where empno = %s&quot;), strEmpNo);
                // 삭제 sql을 실행
                db.ExecuteSQL(strSQL); // ExecuteSQL : DML구문(insert, delete, update, merge)
                // 목록에서 제거
                m_listView.DeleteItem(i);
            }
        }
    }
    else {

    }
    db.Close();
}</code></pre>
<p>한번에 쿼리 보내서 삭제하기</p>
<pre><code class="language-cpp">void CMFCODBCEXAMView::OnBnClickedButton3()
{
    const int nCount = m_listView.GetItemCount();
    CString strEmpNo;
    CString strSQL;

    CDatabase db;
    BOOL bRet = db.OpenEx(_T(&quot;DSN=scott_db;uid=user1;PWD=passwd;&quot;), 0);
    if (bRet) {
        // CStringArray : mfc에서 사용하는 vector 대용 자료형
        CStringArray arr;

        for (int i = nCount - 1; i &gt;= 0; --i) {
            if (m_listView.GetCheck(i)) {
                //삭제할 사원 번호를 얻음
                strEmpNo = m_listView.GetItemText(i, 0); //  사번이 나옴
                //삭제할 사원번호를 배열에 추가
                arr.Add(strEmpNo);
                //목록에서 제거
                m_listView.DeleteItem(i);
            }
        }
        const int size = arr.GetSize();
        if (size != 0) {
            CString strInParam;
            for (int i = 0; i &lt; size; i++) {
                strInParam += arr.GetAt(i) + _T(&quot;,&quot;);
                //strInParam += _T(&quot;&#39;&quot;) + arr.GetAt(i) + _T(&quot;&#39;, &quot;); // 문자열인 경우
            }
            strInParam.Delete(strInParam.GetLength() - 1, 1); // 마지막 &#39;,&#39; 지움

            // 삭제할 사원 sql구문 생성
            strSQL.Format(_T(&quot;delete from emp where empno in (%s)&quot;), strInParam.GetBuffer());
            //삭제 SQL을 실행
            db.ExecuteSQL(strSQL);
            // ExecuteSQL : DML구문(insert, delete, update, merge)
        }
    }
    else {
        AfxMessageBox(_T(&quot;DB 연결 실패&quot;));
    }
    //DB 연결 종료 
    db.Close();
}</code></pre>
<p>예외처리 진행하기</p>
<pre><code class="language-cpp">void CMFCODBCEXAMView::OnBnClickedButton3()
{
    const int nCount = m_listView.GetItemCount();
    CString strEmpNo;
    CString strSQL;

    CDatabase db;
    BOOL bRet = db.OpenEx(_T(&quot;DSN=scott_db;uid=user1;PWD=passwd;&quot;), 0);
    if (bRet) {
        CString strInParam;
        CArray&lt;int, int&gt; arr;

        // 삭제 위치와 삭제 사원번호만 얻음
        for (int i = nCount - 1; i &gt;= 0; --i) {
            if (m_listView.GetCheck(i)) {
                // 삭제할 사원 번호 얻음
                strEmpNo = m_listView.GetItemText(i, 0);

                strInParam += strEmpNo + _T(&quot;, &quot;);

                // 삭제할 사원의 위치를 배열에 추가
                arr.Add(i);
            }
        }
        const int size = arr.GetSize();
        try {

            if (!strInParam.IsEmpty()) {
                strInParam.Delete(strInParam.GetLength() - 1, 1);

                // 삭제할 사원 sql구문 생성
                strSQL.Format(_T(&quot;delete from emp where empno in (%s)&quot;), strInParam.GetBuffer());
                //AfxMessageBox(strSQL);

                // 삭제 sql을 실행
                db.ExecuteSQL(strSQL);
                // ExecuteSQL : DML구문(insert, delete, update, merge)

                // 거꾸로 넣었으므로 순서대로 제거 실행
                for (int i = 0; i &lt; arr.GetSize(); i++) {
                    m_listView.DeleteItem(arr.GetAt(i));
                }
            }
        }
        catch (CException* p) {
            TCHAR szErr[100];
            p-&gt;GetErrorMessage(szErr, sizeof(szErr));
            AfxMessageBox(szErr);
        }
    }
    else {
        AfxMessageBox(_T(&quot;DB 연결 실패&quot;));
    }
    db.Close();
}</code></pre>
]]></description>
        </item>
        <item>
            <title><![CDATA[오라클 DB, table 출력]]></title>
            <link>https://velog.io/@hj-yu-code/%EC%98%A4%EB%9D%BC%ED%81%B4-DB-table-%EC%B6%9C%EB%A0%A5</link>
            <guid>https://velog.io/@hj-yu-code/%EC%98%A4%EB%9D%BC%ED%81%B4-DB-table-%EC%B6%9C%EB%A0%A5</guid>
            <pubDate>Tue, 26 Apr 2022 07:23:53 GMT</pubDate>
            <description><![CDATA[<pre><code class="language-sql">SELECT NAME FROM v$database;</code></pre>
<p>현재 데이터베이스 출력
<img src="https://velog.velcdn.com/images/hj-yu-code/post/d2d0f9a2-3f54-4ccd-825f-65a49b279b64/image.png" alt="">
오라클 express edition은 기본 데이터베이스가 &quot;xe&quot;로 설정되어 있음</p>
<pre><code class="language-sql">SELECT * FROM tab;
--select table_name from user_tables;</code></pre>
<p>현재 모든 테이블 출력
<img src="https://velog.velcdn.com/images/hj-yu-code/post/3b283fdf-f103-4b21-b294-5f692b223217/image.png" alt=""></p>
<pre><code class="language-sql">select distinct(owner) from ALL_ALL_TABLES;</code></pre>
<p>서버에 있는 모든 사용자 출력
<img src="https://velog.velcdn.com/images/hj-yu-code/post/ce81d180-a804-4720-9629-5fc04d38e523/image.png" alt=""></p>
]]></description>
        </item>
        <item>
            <title><![CDATA[IP 개념 잡기]]></title>
            <link>https://velog.io/@hj-yu-code/IP-%EA%B0%9C%EB%85%90-%EC%9E%A1%EA%B8%B0</link>
            <guid>https://velog.io/@hj-yu-code/IP-%EA%B0%9C%EB%85%90-%EC%9E%A1%EA%B8%B0</guid>
            <pubDate>Tue, 26 Apr 2022 01:02:33 GMT</pubDate>
            <description><![CDATA[<ol>
<li>ip 주소 확인하기
<img src="https://velog.velcdn.com/images/hj-yu-code/post/1f2d1201-d242-4298-8ca3-48e37b96857c/image.png" alt=""></li>
</ol>
<p><img src="https://velog.velcdn.com/images/hj-yu-code/post/13c42c91-d25d-44da-8303-fac0eb40a989/image.png" alt="">
관리자 권한으로 열기
<img src="https://velog.velcdn.com/images/hj-yu-code/post/6a90b418-dd85-4166-937e-08ba06423315/image.png" alt="">
이렇게 작성하면 물리ip주소를 논리ip주소로 바꿔줌</p>
<ol start="2">
<li>방화벽 열어주기
<img src="https://velog.velcdn.com/images/hj-yu-code/post/be50bd52-f568-4387-b93b-073bd10ae42c/image.png" alt=""></li>
</ol>
<p><img src="https://velog.velcdn.com/images/hj-yu-code/post/2cf8f4e2-4f55-49d2-839d-ecbe908f40dd/image.png" alt="">
인바운드 : 외부에서 내부로 들어올 수 있게 하는것
<img src="https://velog.velcdn.com/images/hj-yu-code/post/c8e2c030-d1a2-46aa-89c5-ac7a2a0f7d4c/image.png" alt="">
<img src="https://velog.velcdn.com/images/hj-yu-code/post/639be659-1f07-4801-9ddf-b84a4d4e84a0/image.png" alt=""></p>
<p>TCP : 1대1 연결
UDP : 1대 다수 연결
1521 : 오라클 서버 포트
<img src="https://velog.velcdn.com/images/hj-yu-code/post/be9b3e8d-f1ea-48c3-88e4-bb9a295ab915/image.png" alt="">
<img src="https://velog.velcdn.com/images/hj-yu-code/post/37aac37c-2e3a-4ae7-aac7-68d4f342305b/image.png" alt=""></p>
]]></description>
        </item>
        <item>
            <title><![CDATA[오라클 초기 세팅]]></title>
            <link>https://velog.io/@hj-yu-code/%EC%98%A4%EB%9D%BC%ED%81%B4-%EC%B4%88%EA%B8%B0-%EC%84%B8%ED%8C%85</link>
            <guid>https://velog.io/@hj-yu-code/%EC%98%A4%EB%9D%BC%ED%81%B4-%EC%B4%88%EA%B8%B0-%EC%84%B8%ED%8C%85</guid>
            <pubDate>Mon, 25 Apr 2022 09:32:58 GMT</pubDate>
            <description><![CDATA[<ol>
<li><p>set 설정하기</p>
<pre><code class="language-sql">alter session set &quot;_ORACLE_SCRIPT&quot; = true;</code></pre>
<p>작성해서 실행하기
Oracle 12c의 경우 11g와의 호환을 위해 cmd에서 아래 명령어를 우선 입력해야 함</p>
</li>
<li><p>사용자 생성하기
<img src="https://velog.velcdn.com/images/hj-yu-code/post/fa3490b0-cc6f-4584-b7be-077589570ecb/image.png" alt="">
<img src="https://velog.velcdn.com/images/hj-yu-code/post/cb3b8476-199b-4565-9831-546b6423e43e/image.png" alt="">
<img src="https://velog.velcdn.com/images/hj-yu-code/post/fa6247d3-9416-4e5a-906e-44c5699d6d78/image.png" alt="">
마지막 쿼리 복사만 하고 닫기</p>
<pre><code class="language-sql">CREATE USER user1 IDENTIFIED BY passwd 
DEFAULT TABLESPACE USERS
TEMPORARY TABLESPACE TEMP;
</code></pre>
</li>
</ol>
<p>--drop user user1;</p>
<pre><code>라고 작성해서 실행하기

3. 새로고침 하기
![](https://velog.velcdn.com/images/hj-yu-code/post/86e01059-553c-43f2-a927-2132b10b3f51/image.png)

4. 생성한 사용자에서 사용자 편집 진행
![](https://velog.velcdn.com/images/hj-yu-code/post/a69805d6-7f6b-4d2c-ad2a-ad0cbe737148/image.png)
![](https://velog.velcdn.com/images/hj-yu-code/post/5fe6c074-4514-4715-90be-c7fcd863e5af/image.png)
부여된 롤에서 모든 권한과 모두 기본값으로 설정하여 적용

---
![](https://velog.velcdn.com/images/hj-yu-code/post/63a27bc4-edc1-4a5b-8d75-f93dc74a9a3a/image.png)
접속만 가능하게 하는 권한

5. 생성된 계정 접속
![](https://velog.velcdn.com/images/hj-yu-code/post/6896e24e-9c52-40ff-9f2e-196776e8b654/image.png)
![](https://velog.velcdn.com/images/hj-yu-code/post/3e5b6beb-696a-462a-a705-5ea9ff99f823/image.png)

6. 계정 삭제
![](https://velog.velcdn.com/images/hj-yu-code/post/68aabddd-d49c-4e2e-8e2d-c08fbb1eb6a4/image.png)
![](https://velog.velcdn.com/images/hj-yu-code/post/7fd927ac-6593-416c-9783-b0262c4a28e3/image.png)

7. 예시 테이블 작성
```sql
--DROP TABLE DEPT;
CREATE TABLE DEPT
       (DEPTNO NUMBER(2) CONSTRAINT PK_DEPT PRIMARY KEY,
    DNAME VARCHAR2(14) ,
    LOC VARCHAR2(13) ) ;
DROP TABLE EMP;
CREATE TABLE EMP
       (EMPNO NUMBER(4) CONSTRAINT PK_EMP PRIMARY KEY,
    ENAME VARCHAR2(10),
    JOB VARCHAR2(9),
    MGR NUMBER(4),
    HIREDATE DATE,
    SAL NUMBER(7,2),
    COMM NUMBER(7,2),
    DEPTNO NUMBER(2) CONSTRAINT FK_DEPTNO REFERENCES DEPT);
INSERT INTO DEPT VALUES
    (10,&#39;ACCOUNTING&#39;,&#39;NEW YORK&#39;);
INSERT INTO DEPT VALUES (20,&#39;RESEARCH&#39;,&#39;DALLAS&#39;);
INSERT INTO DEPT VALUES
    (30,&#39;SALES&#39;,&#39;CHICAGO&#39;);
INSERT INTO DEPT VALUES
    (40,&#39;OPERATIONS&#39;,&#39;BOSTON&#39;);
INSERT INTO EMP VALUES
(7369,&#39;SMITH&#39;,&#39;CLERK&#39;,7902,to_date(&#39;17-12-1980&#39;,&#39;dd-mm-yyyy&#39;),800,NULL,20);
INSERT INTO EMP VALUES
(7499,&#39;ALLEN&#39;,&#39;SALESMAN&#39;,7698,to_date(&#39;20-2-1981&#39;,&#39;dd-mm-yyyy&#39;),1600,300,30);
INSERT INTO EMP VALUES
(7521,&#39;WARD&#39;,&#39;SALESMAN&#39;,7698,to_date(&#39;22-2-1981&#39;,&#39;dd-mm-yyyy&#39;),1250,500,30);
INSERT INTO EMP VALUES
(7566,&#39;JONES&#39;,&#39;MANAGER&#39;,7839,to_date(&#39;2-4-1981&#39;,&#39;dd-mm-yyyy&#39;),2975,NULL,20);
INSERT INTO EMP VALUES
(7654,&#39;MARTIN&#39;,&#39;SALESMAN&#39;,7698,to_date(&#39;28-9-1981&#39;,&#39;dd-mm-yyyy&#39;),1250,1400,30);
INSERT INTO EMP VALUES
(7698,&#39;BLAKE&#39;,&#39;MANAGER&#39;,7839,to_date(&#39;1-5-1981&#39;,&#39;dd-mm-yyyy&#39;),2850,NULL,30);
INSERT INTO EMP VALUES
(7782,&#39;CLARK&#39;,&#39;MANAGER&#39;,7839,to_date(&#39;9-6-1981&#39;,&#39;dd-mm-yyyy&#39;),2450,NULL,10);
INSERT INTO EMP VALUES
(7788,&#39;SCOTT&#39;,&#39;ANALYST&#39;,7566,to_date(&#39;13-JUL-87&#39;)-85,3000,NULL,20);
INSERT INTO EMP VALUES
(7839,&#39;KING&#39;,&#39;PRESIDENT&#39;,NULL,to_date(&#39;17-11-1981&#39;,&#39;dd-mm-yyyy&#39;),5000,NULL,10);
INSERT INTO EMP VALUES
(7844,&#39;TURNER&#39;,&#39;SALESMAN&#39;,7698,to_date(&#39;8-9-1981&#39;,&#39;dd-mm-yyyy&#39;),1500,0,30);
INSERT INTO EMP VALUES
(7876,&#39;ADAMS&#39;,&#39;CLERK&#39;,7788,to_date(&#39;13-JUL-87&#39;)-51,1100,NULL,20);
INSERT INTO EMP VALUES
(7900,&#39;JAMES&#39;,&#39;CLERK&#39;,7698,to_date(&#39;3-12-1981&#39;,&#39;dd-mm-yyyy&#39;),950,NULL,30);
INSERT INTO EMP VALUES
(7902,&#39;FORD&#39;,&#39;ANALYST&#39;,7566,to_date(&#39;3-12-1981&#39;,&#39;dd-mm-yyyy&#39;),3000,NULL,20);
INSERT INTO EMP VALUES
(7934,&#39;MILLER&#39;,&#39;CLERK&#39;,7782,to_date(&#39;23-1-1982&#39;,&#39;dd-mm-yyyy&#39;),1300,NULL,10);
DROP TABLE BONUS;
CREATE TABLE BONUS
    (
    ENAME VARCHAR2(10)    ,
    JOB VARCHAR2(9)  ,
    SAL NUMBER,
    COMM NUMBER
    ) ;
DROP TABLE SALGRADE;
CREATE TABLE SALGRADE
      ( GRADE NUMBER,
    LOSAL NUMBER,
    HISAL NUMBER );
INSERT INTO SALGRADE VALUES (1,700,1200);
INSERT INTO SALGRADE VALUES (2,1201,1400);
INSERT INTO SALGRADE VALUES (3,1401,2000);
INSERT INTO SALGRADE VALUES (4,2001,3000);
INSERT INTO SALGRADE VALUES (5,3001,9999);
COMMIT;

SET TERMOUT ON
SET ECHO ON</code></pre><p><img src="https://velog.velcdn.com/images/hj-yu-code/post/401c3ca7-4dc3-4458-ad24-ee04de921a67/image.png" alt="">
<img src="https://velog.velcdn.com/images/hj-yu-code/post/22e685d1-7731-4e17-8974-0d197e92aef1/image.png" alt="">
<img src="https://velog.velcdn.com/images/hj-yu-code/post/139db97c-4f06-4c68-ba35-9cd5ba958d8d/image.png" alt=""></p>
]]></description>
        </item>
        <item>
            <title><![CDATA[[GitHub] Repository 초기 세팅 및 업로드]]></title>
            <link>https://velog.io/@hj-yu-code/GitHub-init</link>
            <guid>https://velog.io/@hj-yu-code/GitHub-init</guid>
            <pubDate>Tue, 19 Apr 2022 13:08:40 GMT</pubDate>
            <description><![CDATA[<h1 id="github-repository-생성">GitHub Repository 생성</h1>
<h2 id="repositories-들어가기">Repositories 들어가기</h2>
<p><img src="https://velog.velcdn.com/images/hj-yu-code/post/6a42afc1-a220-4ea7-91b4-8645952ab058/image.png" alt=""></p>
<h2 id="repository-생성하기">Repository 생성하기</h2>
<p><img src="https://velog.velcdn.com/images/hj-yu-code/post/b723eb7e-fd77-4651-be6a-c5cde5b8fd3a/image.png" alt=""></p>
<hr>
<p><img src="https://velog.velcdn.com/images/hj-yu-code/post/22436642-5145-4ed0-b7a8-7ae3cc39c20f/image.png" alt=""></p>
<p>Repository name를 작성해준다.</p>
<p>Public: 외부 사람도 볼 수 있도록 설정
Private: 본인만 볼 수 있도록 설정</p>
<p>Add a README file</p>
<ul>
<li>해당 Repository 설명할 수 있는 파일을 추가 할지에 대한 여부</li>
<li>체크 안한 상태에서 진행했으며, README.md는 나중에 한번 찾아보길 바람</li>
</ul>
<p><img src="https://velog.velcdn.com/images/hj-yu-code/post/588b8ffc-4c7d-4b1d-9a8e-1cec360b5def/image.png" alt=""></p>
<h1 id="git-설치">git 설치</h1>
<p><a href="https://git-scm.com/downloads">https://git-scm.com/downloads</a>
git 설치 확인 방법 : 명령 프롬프트(cmd)에 &quot;git --version&quot;라고 작성 후 확인</p>
<p><img src="https://velog.velcdn.com/images/hj-yu-code/post/1071e262-683f-4ca1-a64c-e8e57d20e804/image.png" alt=""></p>
<h1 id="초기-세팅-2가지-방법">초기 세팅 2가지 방법</h1>
<p>방법 1 : Repository를 원하는 위치에 폴더로 내려 받기
방법 2 : 현재 폴더를 Repository에 업로드 하기</p>
<h2 id="repository를-원하는-위치에-폴더로-내려-받기">Repository를 원하는 위치에 폴더로 내려 받기</h2>
<h3 id="내려-받고-싶은-폴더로-이동하기">내려 받고 싶은 폴더로 이동하기</h3>
<p><img src="https://velog.velcdn.com/images/hj-yu-code/post/d027918d-e460-4b93-88a1-879e08e70e01/image.png" alt=""></p>
<hr>
<pre><code>&gt; d:
&gt; cd D:\project</code></pre><p><img src="https://velog.velcdn.com/images/hj-yu-code/post/402c7122-3c8e-4234-bf0b-81cc33d26b68/image.png" alt=""></p>
<h3 id="github-repository-내려-받기">github repository 내려 받기</h3>
<p><img src="https://velog.velcdn.com/images/hj-yu-code/post/acdf6aa8-9c72-4bb8-b339-01f2d0baaf0e/image.png" alt=""></p>
<pre><code>&gt; git clone https://github.com/hj-yu-code/test_rep.git</code></pre><p>git clone (git 주소) : 해당 github repository를 현재 폴더 위치에 내려 받기</p>
<p><img src="https://velog.velcdn.com/images/hj-yu-code/post/64a2089a-f53a-4985-a793-0f003aae91d1/image.png" alt=""></p>
<hr>
<p><img src="https://velog.velcdn.com/images/hj-yu-code/post/4ead78dc-655d-43d8-a217-88cabe0c3db0/image.png" alt=""></p>
<hr>
<h2 id="현재-폴더를-repository에-업로드하기">현재 폴더를 Repository에 업로드하기</h2>
<h3 id="올리고-싶은-폴더로-이동하기">올리고 싶은 폴더로 이동하기</h3>
<p><img src="https://velog.velcdn.com/images/hj-yu-code/post/cda95e89-5717-419f-9023-e18efd80dc79/image.png" alt=""></p>
<hr>
<pre><code>&gt; d:
&gt; cd D:\test_local</code></pre><p><img src="https://velog.velcdn.com/images/hj-yu-code/post/602105e4-a058-4d15-a583-9a74a3edbb4d/image.png" alt=""></p>
<h3 id="git-init-하기">git init 하기</h3>
<pre><code>&gt; git init</code></pre><p><img src="https://velog.velcdn.com/images/hj-yu-code/post/ab19efcb-62af-49fd-af72-0d9fe1498553/image.png" alt="">
<img src="https://velog.velcdn.com/images/hj-yu-code/post/827763ed-65be-4a67-aa95-be6036a172ab/image.png" alt=""></p>
<h3 id="git-status-확인하기">git status 확인하기</h3>
<pre><code>&gt; git status // 작성 안해도 가능</code></pre><p>git status : 현재 폴더의 git 상태 확인하기</p>
<p><img src="https://velog.velcdn.com/images/hj-yu-code/post/241e09a5-92bf-4cce-9e60-0cc94fb8e612/image.png" alt=""></p>
<pre><code>On branch master // 현재 있는 Branch : master

No commits yet // commits 된 내용 없음

Untracked files:  // git 에 올라가지 않은 파일 및 변경된 파일
  (use &quot;git add &lt;file&gt;...&quot; to include in what will be committed)
        first.txt

nothing added to commit but untracked files present (use &quot;git add&quot; to track)</code></pre><h3 id="git-add-하기">git add 하기</h3>
<pre><code>&gt; git add .
&gt; git status // 작성 안해도 가능</code></pre><p>git add . : 파일 모두 업로드 하기
git add first.txt : first.txt 파일만 업로드 하기</p>
<p><img src="https://velog.velcdn.com/images/hj-yu-code/post/c63d57e1-da47-4f8e-9dc3-a5772639bbd1/image.png" alt=""></p>
<pre><code>On branch master

No commits yet

Changes to be committed: // 올린 예정인 파일
  (use &quot;git rm --cached &lt;file&gt;...&quot; to unstage)
        new file:   first.txt</code></pre><h3 id="git-commit-하기">git commit 하기</h3>
<pre><code>&gt; git commit -m &quot;init 하고 파일 올리기&quot;
&gt; git status // 작성 안해도 가능</code></pre><p>git commit -m &quot;메세지&quot; : add 한 파일들을 모두 commit 하기</p>
<p><img src="https://velog.velcdn.com/images/hj-yu-code/post/ed0bb52d-4324-4ed5-ac62-7d7d6296aef7/image.png" alt=""></p>
<pre><code>On branch main
nothing to commit, working tree clean // 모든 파일이 commit되어 있음</code></pre><h3 id="git-branch-이름-변경">git branch 이름 변경</h3>
<pre><code>&gt; git branch // 작성 안해도 가능
&gt; git branch -M main
&gt; git branch // 작성 안해도 가능</code></pre><p>git branch : 현재 branch 이름 확인
git branch -v : 현재 branch 이름과 마지막 commit 메세지 확인
git branch -a : 모든 branch 이름 확인</p>
<p>git branch -M main : 현재 branch 이름을 main으로 변경 (default : master)
git branch -m main master : master branch 이름을 main으로 변경</p>
<p><img src="https://velog.velcdn.com/images/hj-yu-code/post/fd4e069f-00e8-44d3-b61e-4172054aad44/image.png" alt=""></p>
<blockquote>
<p>github에서 처음 branch를 생성할 때 master branch였다.
하지만 미국 Black lives matter 운동 연장으로 master-slave를 연상시키는 master 대신 main으로 default branch 이름이 변경되었다.
<a href="https://github.blog/changelog/2020-10-01-the-default-branch-for-newly-created-repositories-is-now-main/">https://github.blog/changelog/2020-10-01-the-default-branch-for-newly-created-repositories-is-now-main/</a></p>
</blockquote>
<h3 id="github와-연결하기">github와 연결하기</h3>
<pre><code>&gt; git remote -v // 작성 안해도 가능
&gt; git remote add origin https://github.com/hj-yu-code/test_rep.git
&gt; git remote -v // 작성 안해도 가능</code></pre><p>git remote -v : 현재 연결된 외부 저장소 확인
git remote add origin (git 주소) : 해당 github repository를 현재 폴더의 외부 저장소로 연결</p>
<ul>
<li>생성한 repository의 https 주소를 넣으면 됨
<img src="https://velog.velcdn.com/images/hj-yu-code/post/acdf6aa8-9c72-4bb8-b339-01f2d0baaf0e/image.png" alt=""></li>
<li>origin : 외부 저장소의 초기 default 이름</li>
<li>2개 이상의 외부 저장소를 사용할 경우에, 2번째 이후부터 origin 대신 다른 이름 사용해야 함</li>
</ul>
<p><img src="https://velog.velcdn.com/images/hj-yu-code/post/f4b15805-be0f-4f97-b600-880eb9fa243c/image.png" alt=""></p>
<h3 id="git-pull-및-push-하기">git pull 및 push 하기</h3>
<pre><code>&gt; git status // 작성 안해도 가능
&gt; git pull origin main // README가 없다면 작성 안해도 가능
&gt; git status // 작성 안해도 가능
&gt; git push -u origin main
&gt; git status // 작성 안해도 가능</code></pre><p>git pull origin main : 외부 저장소(origin)의 내용을 현재 branch(main)에 추가 저장
git push -u origin main : 외부 저장소(origin)에 현재 branch(main)를 올리기
<img src="https://velog.velcdn.com/images/hj-yu-code/post/98abc2c5-314f-4875-afed-d7c37629373c/image.png" alt=""></p>
<pre><code>D:\test_local&gt;git status
On branch main // 현재 있는 branch : main
nothing to commit, working tree clean

D:\test_local&gt;git pull origin main
fatal: couldn&#39;t find remote ref main // README가 없으므로 아무것도 가져오지 않음

D:\test_local&gt;git push -u origin main
Enumerating objects: 3, done.
Counting objects: 100% (3/3), done.
Writing objects: 100% (3/3), 256 bytes | 256.00 KiB/s, done.
Total 3 (delta 0), reused 0 (delta 0), pack-reused 0
To https://github.com/hj-yu-code/test_rep.git
 * [new branch]      main -&gt; main
branch &#39;main&#39; set up to track &#39;origin/main&#39;. // 업로드 완료

D:\test_local&gt;git status
On branch main
Your branch is up to date with &#39;origin/main&#39;. // 외부 저장소와 같은 상태

nothing to commit, working tree clean</code></pre><p><img src="https://velog.velcdn.com/images/hj-yu-code/post/244b2175-539d-485a-8848-5876ffea2e34/image.png" alt=""></p>
<hr>
<h1 id="변경된-파일-github-업로드">변경된 파일 github 업로드</h1>
<h2 id="github-연동된-폴더로-이동하기">github 연동된 폴더로 이동하기</h2>
<p><img src="https://velog.velcdn.com/images/hj-yu-code/post/f0df2d3f-6e50-4462-856a-15dba1fea8a8/image.png" alt=""></p>
<hr>
<pre><code>&gt;d:
&gt;cd D:\project\test_rep</code></pre><p><img src="https://velog.velcdn.com/images/hj-yu-code/post/08adf607-4199-4c95-9de2-15a0fee2c483/image.png" alt=""></p>
<h2 id="git-add-하기-1">git add 하기</h2>
<pre><code>&gt; git add .</code></pre><p><img src="https://velog.velcdn.com/images/hj-yu-code/post/45fbe5b5-4d05-49c0-8d2d-5a95ad7141cd/image.png" alt=""></p>
<h2 id="git-commit-하기-1">git commit 하기</h2>
<pre><code>&gt; git commit -m &quot;수정사항 업로드&quot;</code></pre><p><img src="https://velog.velcdn.com/images/hj-yu-code/post/d16eb219-2508-4865-8348-608841af8ae1/image.png" alt=""></p>
<h2 id="git-push-하기">git push 하기</h2>
<pre><code>&gt; git push -u origin main</code></pre><p><img src="https://velog.velcdn.com/images/hj-yu-code/post/6d529e85-e325-4a14-9ac8-49e5e90ff6fd/image.png" alt=""></p>
<hr>
<p><img src="https://velog.velcdn.com/images/hj-yu-code/post/93c14ce6-0cf6-4404-b5c2-638a864451e4/image.png" alt=""></p>
]]></description>
        </item>
        <item>
            <title><![CDATA[스마트 포인터]]></title>
            <link>https://velog.io/@hj-yu-code/%EC%8A%A4%EB%A7%88%ED%8A%B8-%ED%8F%AC%EC%9D%B8%ED%84%B0</link>
            <guid>https://velog.io/@hj-yu-code/%EC%8A%A4%EB%A7%88%ED%8A%B8-%ED%8F%AC%EC%9D%B8%ED%84%B0</guid>
            <pubDate>Tue, 19 Apr 2022 08:06:19 GMT</pubDate>
            <description><![CDATA[<ol>
<li>UI에 입력된 값을 변수로 읽는다</li>
<li>입력된 값을 이용하여 Member 객체를 생성한다</li>
<li>저장될 공간(ㄱ. vector, ㄴ. map, ㄷ. db)에 저장한다</li>
<li>vector에 저장을 한다고 생각하고 어떤 객체를 저장할지 결정한다</li>
<li>저장 방법: ㄱ. 객체 vector<CMember>
 ㄴ. 포인터 (동적객체) vector&lt;CMember*&gt;, 소멸자에서 객체 해제 반드시 할 것
 ㄷ. 스마트 포인터 vector&lt;shared_ptr<CMember>&gt;</li>
</ol>
<hr>
<h3 id="스마트-포인터">스마트 포인터</h3>
<pre><code class="language-cpp">
CMember* pMember = new CMember();
delete pMember;

// 스마트 포인터 방법 1
#include &lt;memory&gt;
{
shared_ptr&lt;CMember&gt; pMember = make_shared&lt;CMember&gt;();
} // 소멸자 자동 호출

// 스마트 포인터 방법 2
using CMemberPtr = shared_ptr&lt;CMember&gt;;
// 다음부터 shared_ptr&lt;CMember&gt; 대신 CMemberPtr 사용 가능
// vector&lt;CMemberPtr&gt;

// 스마트 포인터 방법 3
// framework.h에 작성
#include &lt;memory&gt;
#include &lt;vector&gt;
using namespace std;</code></pre>
<hr>
<ol>
<li>UI에 입력된 값을 변수로 읽는다<pre><code class="language-cpp">if(!UpdateData()) return;
</code></pre>
</li>
</ol>
<pre><code>
2. 입력된 값을 이용하여 Member 객체를 생성한다

CMemberPtr pMember = make_shared&lt;CMember&gt;();
---
3. 저장될 공간(ㄱ. vector, ㄴ. map, ㄷ. db)에 저장한다
m_array.push_back(pMember);</code></pre>]]></description>
        </item>
        <item>
            <title><![CDATA[버튼]]></title>
            <link>https://velog.io/@hj-yu-code/%EB%B2%84%ED%8A%BC</link>
            <guid>https://velog.io/@hj-yu-code/%EB%B2%84%ED%8A%BC</guid>
            <pubDate>Mon, 18 Apr 2022 07:45:26 GMT</pubDate>
            <description><![CDATA[<h2 id="기본단추">기본단추</h2>
<p><img src="https://velog.velcdn.com/images/hj-yu-code/post/f5fb4522-3639-4a8a-9d54-05357837bf7b/image.png" alt="">
<img src="https://velog.velcdn.com/images/hj-yu-code/post/68f35890-f23f-4abc-8e8c-339b4e88ae72/image.png" alt=""></p>
<h1 id="체크박스">체크박스</h1>
<p><img src="https://velog.velcdn.com/images/hj-yu-code/post/692eabae-1d9f-4a2a-a252-d03df3d1cea6/image.png" alt=""></p>
<h2 id="체크박스-활성화-비활성화">체크박스 활성화 비활성화</h2>
<h3 id="체크박스-활성화-비활성화-기본">체크박스 활성화 비활성화 기본</h3>
<p>----Dlg.cpp</p>
<pre><code class="language-cpp">void CButtonDemoDlg::OnBnClickedCheckAuto()
{
    // TODO: 여기에 컨트롤 알림 처리기 코드를 추가합니다.
    UpdateData();
    if (m_bAuto) {
        CWnd* pWnd = GetDlgItem(IDC_CHECK_UPDATE);
        if (pWnd != nullptr) {
            pWnd-&gt;EnableWindow(FALSE); // 비활성화
        }
    }
    else {
        CWnd* pWnd = GetDlgItem(IDC_CHECK_UPDATE);
        if (pWnd != nullptr) {
            pWnd-&gt;EnableWindow(TRUE); // 활성화
        }
    }
}</code></pre>
<p><img src="https://velog.velcdn.com/images/hj-yu-code/post/60510279-81a8-42c6-b62c-435b552b2bdb/image.png" alt=""></p>
<h3 id="체크박스-활성화-비활성화-코드-간소화">체크박스 활성화 비활성화 코드 간소화</h3>
<p>----Dlg.cpp</p>
<pre><code class="language-cpp">void CButtonDemoDlg::OnBnClickedCheckAuto()
{
    // TODO: 여기에 컨트롤 알림 처리기 코드를 추가합니다.
    UpdateData();
    //if (m_bAuto) {
    //    CWnd* pWnd = GetDlgItem(IDC_CHECK_UPDATE);
    //    if (pWnd != nullptr) {
    //        pWnd-&gt;EnableWindow(FALSE); // 비활성화
    //    }
    //}
    //else {
    //    CWnd* pWnd = GetDlgItem(IDC_CHECK_UPDATE);
    //    if (pWnd != nullptr) {
    //        pWnd-&gt;EnableWindow(TRUE); // 활성화
    //    }
    //}
    CWnd* pWnd = GetDlgItem(IDC_CHECK_UPDATE);
    if (pWnd != nullptr) {
        pWnd-&gt;EnableWindow(!m_bAuto); // 활성화 비활성화 동시에
    }
}</code></pre>
<h3 id="체크박스-활성화-비활성화-및-체크박스-설정">체크박스 활성화 비활성화 및 체크박스 설정</h3>
<p>----Dlg.cpp</p>
<pre><code class="language-cpp">void CButtonDemoDlg::OnBnClickedCheckAuto()
{
    // TODO: 여기에 컨트롤 알림 처리기 코드를 추가합니다.
    UpdateData();

    CWnd* pWndUpdate = GetDlgItem(IDC_CHECK_UPDATE);
    CWnd* pWndSystem = GetDlgItem(IDC_CHECK_SYSTEM);
    if (pWndUpdate != nullptr) {
        pWndUpdate-&gt;EnableWindow(!m_bAuto);
    }
    if (pWndSystem != nullptr) {
        pWndSystem-&gt;EnableWindow(!m_bAuto);
    }

    m_bUpdate = m_bAuto;
    m_bSystem = m_bAuto;

    UpdateData(FALSE);
}</code></pre>
<p><img src="https://velog.velcdn.com/images/hj-yu-code/post/ed512a3d-359e-4722-a353-4da379f2a416/image.png" alt=""></p>
<h3 id="컨트롤로">컨트롤로</h3>
<p><img src="https://velog.velcdn.com/images/hj-yu-code/post/cbdc04cd-ee4f-4684-b156-4e7ba790bcff/image.png" alt="">
----Dlg.cpp</p>
<pre><code class="language-cpp">void CButtonDemoDlg::OnBnClickedCheckAuto()
{
    UpdateData();

    // 컨트롤 변수로 비활성화 방법
    m_wndUpdate.EnableWindow(!m_bAuto);
    m_wndSystem.EnableWindow(!m_bAuto);

    m_bUpdate = m_bAuto;
    m_bSystem = m_bAuto;

    UpdateData(FALSE);
}</code></pre>
]]></description>
        </item>
        <item>
            <title><![CDATA[링크 컨트롤]]></title>
            <link>https://velog.io/@hj-yu-code/%EB%A7%81%ED%81%AC-%EC%BB%A8%ED%8A%B8%EB%A1%A4</link>
            <guid>https://velog.io/@hj-yu-code/%EB%A7%81%ED%81%AC-%EC%BB%A8%ED%8A%B8%EB%A1%A4</guid>
            <pubDate>Mon, 18 Apr 2022 07:02:03 GMT</pubDate>
            <description><![CDATA[<p><img src="https://velog.velcdn.com/images/hj-yu-code/post/41da8310-069a-463c-bde5-48ac86486011/image.png" alt=""></p>
<h2 id="이벤트-추가하기">이벤트 추가하기</h2>
<p><img src="https://velog.velcdn.com/images/hj-yu-code/post/1a47da75-0cf9-433b-b9f9-e8fb45588e97/image.png" alt="">
----Dlg.cpp</p>
<pre><code class="language-cpp">void CLogonDemo2Dlg::OnNMClickSyslink1(NMHDR* pNMHDR, LRESULT* pResult)
{
    // TODO: 여기에 컨트롤 알림 처리기 코드를 추가합니다.
    CString strUrl = _T(&quot;&quot;);
    CLinkCtrl* pLinkCtrl = (CLinkCtrl*)GetDlgItem(IDC_SYSLINK1);
    pLinkCtrl-&gt;GetItemUrl(0, strUrl);

    ::ShellExecute(NULL, TEXT(&quot;open&quot;), strUrl, NULL, NULL, SW_SHOW);
    *pResult = 0;
}</code></pre>
<h3 id="주소-읽기">주소 읽기</h3>
<p><img src="https://velog.velcdn.com/images/hj-yu-code/post/4412b035-1669-4162-b4a0-35fa5eda522c/image.png" alt="">
<img src="https://velog.velcdn.com/images/hj-yu-code/post/c45e2230-f5bb-4e9a-8f5e-483eb2771fc5/image.png" alt="">
<img src="https://velog.velcdn.com/images/hj-yu-code/post/34b7d57f-e0e2-4481-8cad-9fdad74589b2/image.png" alt="">
----Dlg.cpp</p>
<pre><code class="language-cpp">void CLogonDemo2Dlg::OnBnClickedButton1()
{
    // TODO: 여기에 컨트롤 알림 처리기 코드를 추가합니다.
    UpdateData();
    if (m_strLinkAddress.IsEmpty()) {
        MessageBox(_T(&quot; 주소를 입력해주세요&quot;));
        return;
    }
    //  새로운 브라우저 실행
    ::ShellExecute(NULL, _T(&quot;open&quot;), m_strLinkAddress, NULL, NULL, SW_SHOW);
}</code></pre>
<h4 id="주소-초기-입력">주소 초기 입력</h4>
<p>----Dlg.cpp</p>
<pre><code class="language-cpp">CLogonDemo2Dlg::CLogonDemo2Dlg(CWnd* pParent /*=nullptr*/)
    : CDialog(IDD_LOGONDEMO2_DIALOG, pParent)
    , m_strID(_T(&quot;&quot;))
    , m_strPW(_T(&quot;&quot;))
    , m_strLinkAddress(_T(&quot;http://www.naver.com&quot;))
{
    m_hIcon = AfxGetApp()-&gt;LoadIcon(IDR_MAINFRAME);
}</code></pre>
<p><img src="https://velog.velcdn.com/images/hj-yu-code/post/0d3fff4f-81fe-46ec-a2b9-766b28dfc558/image.png" alt=""></p>
<h3 id="변수화하여-링크-연결하기">변수화하여 링크 연결하기</h3>
<p><img src="https://velog.velcdn.com/images/hj-yu-code/post/1aca0d34-491d-4fae-82e9-41b6a7f447eb/image.png" alt=""></p>
<p><img src="https://velog.velcdn.com/images/hj-yu-code/post/9929b9b6-1c9f-49fd-a53d-edc15fdbd38d/image.png" alt="">
----Dlg.cpp</p>
<pre><code class="language-cpp">void CLogonDemo2Dlg::OnNMClickSyslink1(NMHDR* pNMHDR, LRESULT* pResult)
{
    // TODO: 여기에 컨트롤 알림 처리기 코드를 추가합니다.

    /*CString strUrl = _T(&quot;&quot;);
    CLinkCtrl* pLinkCtrl = (CLinkCtrl*)GetDlgItem(IDC_SYSLINK1);
    pLinkCtrl-&gt;GetItemUrl(0, strUrl);

    ::ShellExecute(NULL, TEXT(&quot;open&quot;), strUrl, NULL, NULL, SW_SHOW);*/

    // 변수 추가로 인해 사용 가능함
    UpdateData(); // 변수 값을 가져오기

    CString strUrl;
    m_linkCtrl.GetItemUrl(0, strUrl);
    ::ShellExecute(NULL, _T(&quot;open&quot;), strUrl, NULL, NULL, SW_SHOW);

    *pResult = 0;
}</code></pre>
]]></description>
        </item>
        <item>
            <title><![CDATA[대화상자 기반]]></title>
            <link>https://velog.io/@hj-yu-code/%EB%8C%80%ED%99%94%EC%83%81%EC%9E%90-%EA%B8%B0%EB%B0%98</link>
            <guid>https://velog.io/@hj-yu-code/%EB%8C%80%ED%99%94%EC%83%81%EC%9E%90-%EA%B8%B0%EB%B0%98</guid>
            <pubDate>Mon, 18 Apr 2022 02:39:53 GMT</pubDate>
            <description><![CDATA[<h2 id="생성-설정">생성 설정</h2>
<p><img src="https://velog.velcdn.com/images/hj-yu-code/post/ee9f2472-a602-4d65-93f3-cddda566b690/image.png" alt=""></p>
<h2 id="대화상자-기반-초기-화면">대화상자 기반 초기 화면</h2>
<p><img src="https://velog.velcdn.com/images/hj-yu-code/post/2e65215f-033f-4593-8455-9a11ef2efca4/image.png" alt="">
----LogonDemo.cpp</p>
<pre><code class="language-cpp">    CLogonDemoDlg dlg;
    m_pMainWnd = &amp;dlg; // AfxGetMainWnd() -&gt; CLogonDemoDlg의 객체를 얻음
    INT_PTR nResponse = dlg.DoModal(); // 대화상자를 띄우는 코드</code></pre>
<h2 id="대화상자-기반-특징">대화상자 기반 특징</h2>
<p>직관적으로 윈도우 화면을 구성할 수 있음</p>
<h3 id="static-text">static Text</h3>
<p><img src="https://velog.velcdn.com/images/hj-yu-code/post/c16fc4c7-98b5-4334-9436-bab97c16e7a1/image.png" alt=""></p>
<h3 id="edit-control">Edit Control</h3>
<p><img src="https://velog.velcdn.com/images/hj-yu-code/post/0c228272-b017-4d79-8a9d-3afef8478a4b/image.png" alt=""></p>
<h3 id="picture-control">Picture Control</h3>
<p><img src="https://velog.velcdn.com/images/hj-yu-code/post/bde58cb6-f498-48d2-8a79-048f5beb6537/image.png" alt=""></p>
<p><img src="https://velog.velcdn.com/images/hj-yu-code/post/4603da05-f53f-4b1b-bbfc-4baf2307dc52/image.png" alt=""></p>
<p>----2Dlg.cpp</p>
<pre><code class="language-cpp">
void CLogonDemo2Dlg::OnBnClickedCancel()
{
    // TODO: 여기에 컨트롤 알림 처리기 코드를 추가합니다.
    CDialog::OnCancel();
}


void CLogonDemo2Dlg::OnBnClickedOk()
{
    // TODO: 여기에 컨트롤 알림 처리기 코드를 추가합니다.
    CString strId;
    CString strPwd;

    GetDlgItemText(IDC_EDIT1, strId); // 화면의 값을 변수로 읽어 들임
    GetDlgItemText(IDC_EDIT2, strPwd);

    if (strId == _T(&quot;aaaa&quot;) &amp;&amp; strPwd == _T(&quot;1234&quot;)) {
        CDialog::OnOK();
    }
    else {
        MessageBox(_T(&quot;아이디 또는 비밀번호가 잘못되었습니다.&quot;));
    }
    CDialog::OnOK();
}</code></pre>
<h3 id="초기화">초기화</h3>
<p>----2Dlg.cpp</p>
<pre><code class="language-cpp">// 윈도우가 생성됬을 때 알려주는 메세지 : WM_CREATE
BOOL CLogonDemo2Dlg::OnInitDialog() // WM_INITDIAlOG
{
    CDialog::OnInitDialog();

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

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

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

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

    // TODO: 여기에 추가 초기화 작업을 추가합니다.
    CString strText = _T(&quot;ID 입력&quot;);
    SetDlgItemText(IDC_EDIT1, strText); // 초기 글자 입력
    // 변수 값을 화면에 출력


    return TRUE;  // 포커스를 컨트롤에 설정하지 않으면 TRUE를 반환합니다.
}</code></pre>
<p><img src="https://velog.velcdn.com/images/hj-yu-code/post/4a4742fb-7a5a-4746-ad0f-3d17a78d5415/image.png" alt="">
###
<img src="https://velog.velcdn.com/images/hj-yu-code/post/e41aeb98-769b-4854-898f-17556875b5dd/image.png" alt="">
<img src="https://velog.velcdn.com/images/hj-yu-code/post/ff2ed4d4-b786-4ea7-a84c-c13930465301/image.png" alt=""></p>
<p><img src="https://velog.velcdn.com/images/hj-yu-code/post/e0f3f3e3-14fd-4280-9577-04cb0fdaf279/image.png" alt="">
코드에 추가됨
----Dlg.h</p>
<pre><code class="language-cpp">public:
    afx_msg void OnBnClickedCancel();
    afx_msg void OnBnClickedOk();
    CString m_strID;
};</code></pre>
<p>----Dlg.cpp</p>
<pre><code class="language-cpp">void CLogonDemo2Dlg::DoDataExchange(CDataExchange* pDX)
{
    CDialog::DoDataExchange(pDX);
    DDX_Text(pDX, IDC_EDIT1, m_strID);
    DDV_MaxChars(pDX, m_strID, 12);
}</code></pre>
<h4 id="코드-변경하기">코드 변경하기</h4>
<pre><code class="language-cpp">// 윈도우가 생성됬을 때 알려주는 메세지 : WM_CREATE
BOOL CLogonDemo2Dlg::OnInitDialog() // WM_INITDIAlOG
{
    CDialog::OnInitDialog();

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

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

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

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

    // TODO: 여기에 추가 초기화 작업을 추가합니다.
    // 변수 값을 화면에 출력1
    //CString strText = _T(&quot;ID 입력&quot;);
    //SetDlgItemText(IDC_EDIT1, strText); // 초기 글자 입력

    // 변수 값을 화면에 출력2
    m_strID = _T(&quot;ID 입력&quot;);
    UpdateData(FALSE);


    return TRUE;  // 포커스를 컨트롤에 설정하지 않으면 TRUE를 반환합니다.
}
/////////
void CLogonDemo2Dlg::OnBnClickedOk()
{
    // TODO: 여기에 컨트롤 알림 처리기 코드를 추가합니다.
    //CString strId;
    //CString strPwd;

    //GetDlgItemText(IDC_EDIT1, strId); // 화면의 값을 변수로 읽어 들임
    //GetDlgItemText(IDC_EDIT2, strPwd);

    UpdateData();

    if (m_strID == _T(&quot;aaaa&quot;) &amp;&amp; m_strPW == _T(&quot;1234&quot;)) {
        MessageBox(_T(&quot;로그인 성공&quot;), _T(&quot;로그인&quot;), MB_ICONEXCLAMATION | MB_OK);

        CDialog::OnOK();
    }
    else {
        MessageBox(_T(&quot;아이디 또는 비밀번호가 잘못되었습니다.&quot;));
    }
    //CDialog::OnOK();
}
</code></pre>
<p><img src="https://velog.velcdn.com/images/hj-yu-code/post/74601b88-4fc0-4568-ae38-f8ff9d931de3/image.png" alt=""></p>
<h3 id="디버깅으로-띄우기">디버깅으로 띄우기</h3>
<p>----2.cpp</p>
<pre><code class="language-cpp">BOOL CLogonDemo2App::InitInstance()
{
    // 애플리케이션 매니페스트가 ComCtl32.dll 버전 6 이상을 사용하여 비주얼 스타일을
    // 사용하도록 지정하는 경우, Windows XP 상에서 반드시 InitCommonControlsEx()가 필요합니다.
    // InitCommonControlsEx()를 사용하지 않으면 창을 만들 수 없습니다.
    INITCOMMONCONTROLSEX InitCtrls;
    InitCtrls.dwSize = sizeof(InitCtrls);
    // 응용 프로그램에서 사용할 모든 공용 컨트롤 클래스를 포함하도록
    // 이 항목을 설정하십시오.
    InitCtrls.dwICC = ICC_WIN95_CLASSES;
    InitCommonControlsEx(&amp;InitCtrls);

    CWinApp::InitInstance();


    AfxEnableControlContainer();


    // 표준 초기화
    // 이들 기능을 사용하지 않고 최종 실행 파일의 크기를 줄이려면
    // 아래에서 필요 없는 특정 초기화
    // 루틴을 제거해야 합니다.
    // 해당 설정이 저장된 레지스트리 키를 변경하십시오.
    // TODO: 이 문자열을 회사 또는 조직의 이름과 같은
    // 적절한 내용으로 수정해야 합니다.
    SetRegistryKey(_T(&quot;로컬 애플리케이션 마법사에서 생성된 애플리케이션&quot;));

    CLogonDemo2Dlg dlg;
    m_pMainWnd = &amp;dlg;
    INT_PTR nResponse = dlg.DoModal();
    if (nResponse == IDOK)
    {
        TRACE(&quot;id = %d\n&quot;, dlg.m_strID); // Dlg.h 값 가져오기
        TRACE(&quot;pwd = %d\n&quot;, dlg.m_strPW);

        //AfxMessageBox(_T(&quot;로그인 성공&quot;));
        // MessageBox를 쓰려면 부모가 Wnd여야 함
        // App의 부모는 Object임 -&gt; messagebox를 호출 불가
        // 따라서 전역함수인 AfxMessageBox로 호출
    }
    else if (nResponse == IDCANCEL)
    {
        // TODO: 여기에 [취소]를 클릭하여 대화 상자가 없어질 때 처리할
        //  코드를 배치합니다.
    }
    else if (nResponse == -1)
    {
        TRACE(traceAppMsg, 0, &quot;경고: 대화 상자를 만들지 못했으므로 애플리케이션이 예기치 않게 종료됩니다.\n&quot;);
    }


#if !defined(_AFXDLL) &amp;&amp; !defined(_AFX_NO_MFC_CONTROLS_IN_DIALOGS)
    ControlBarCleanUp();
#endif

    // 대화 상자가 닫혔으므로 응용 프로그램의 메시지 펌프를 시작하지 않고 응용 프로그램을 끝낼 수 있도록 FALSE를
    // 반환합니다.
    return FALSE;
}</code></pre>
]]></description>
        </item>
        <item>
            <title><![CDATA[컨트롤윈도우(1)]]></title>
            <link>https://velog.io/@hj-yu-code/%EC%BB%A8%ED%8A%B8%EB%A1%A4%EC%9C%88%EB%8F%84%EC%9A%B01</link>
            <guid>https://velog.io/@hj-yu-code/%EC%BB%A8%ED%8A%B8%EB%A1%A4%EC%9C%88%EB%8F%84%EC%9A%B01</guid>
            <pubDate>Mon, 18 Apr 2022 02:31:51 GMT</pubDate>
            <description><![CDATA[<p>(제공받은 코드)
----view.cpp</p>
<pre><code class="language-cpp">void CStaticDemoView::OnLButtonDown(UINT nFlags, CPoint point)
{
    // TODO: 여기에 메시지 처리기 코드를 추가 및/또는 기본값을 호출합니다.
    //ID를 이용하여 윈도우 객체 포인터 얻는 방법
    //CWnd* pWnd = GetDlgItem(1235); // ID 전달
    //pWnd-&gt;SetWindowText(_T(&quot;왼쪽 마우스버튼 클릭&quot;));

    // ID를 이용하여 윈도우 객체 메세지 바꾸는 방법
    SetDlgItemText(1235, _T(&quot;왼쪽 마우스버튼 클릭&quot;));

    CView::OnLButtonDown(nFlags, point);
}</code></pre>
<p><img src="https://velog.velcdn.com/images/hj-yu-code/post/b258215e-52c5-4553-9b0e-2bdfb5aa0e67/image.png" alt="">
<img src="https://velog.velcdn.com/images/hj-yu-code/post/2ecafb14-86d4-4b60-b01d-126403224eb3/image.png" alt=""></p>
<h2 id="edit-demo로-바꿔서-다시-작성하기">Edit Demo로 바꿔서 다시 작성하기!!!!</h2>
<pre><code class="language-cpp">// 특성입니다.
public:
    CStaticDemoDoc* GetDocument() const;

    CWnd m_wndEdit1; //Cwnd : 모든 클래스의 부모 클래스
    //CStatic m_wndStatic2; // CWnd의 자식클래스
    CEdit m_wndEdit2; // CWnd의 자식클래스</code></pre>
<pre><code class="language-cpp">int CStaticDemoView::OnCreate(LPCREATESTRUCT lpCreateStruct)
{
    if (CView::OnCreate(lpCreateStruct) == -1)
        return -1;

    // TODO:  여기에 특수화된 작성 코드를 추가합니다.
    m_wndEdit1.Create(_T(&quot;Edit&quot;), _T(&quot;안녕~~~~&quot;), 
        WS_CHILD | WS_VISIBLE | WS_TABSTOP | WS_BORDER | ES_AUTOHSCROLL, 
        CRect(20, 20, 220, 36), this, 1234);
    m_wndEdit2.Create(WS_CHILD | WS_VISIBLE | WS_TABSTOP | WS_BORDER | ES_AUTOHSCROLL,
        CRect(20, 50, 220, 76), this, 1236);
    m_wndEdit2.SetWindowText(_T(&quot;메롱~~~~&quot;));
    CString strText;
    m_wndEdit2.GetWindowText(strText); // &#39;메롱~~~~&#39;문자 가져오기

    return 0;
}</code></pre>
<h3 id="메세지-박스-띄우기">메세지 박스 띄우기</h3>
<pre><code class="language-cpp">void CStaticDemoView::OnLButtonDown(UINT nFlags, CPoint point)
{
    CString strText;
    m_wndEdit2.GetWindowText(strText);

    AfxMessageBox(strText);
    MessageBox(strText, _T(&quot;123564&quot;)); // 타이틀 바꿀수 있음
    CView::OnLButtonDown(nFlags, point);
    MessageBox(strText, NULL, MB_ICONERROR|MB_YESNO); // 특성 바꾸기

    MessageBox(strText, NULL, MB_ICONERROR | MB_YESNOCANCEL); // 특성 바꾸기
}</code></pre>
<p><img src="https://velog.velcdn.com/images/hj-yu-code/post/fb269b39-299e-4110-a286-70a905f8a97e/image.png" alt="">
<img src="https://velog.velcdn.com/images/hj-yu-code/post/2c4b64f9-3c03-463a-92bd-ffd0cce65f10/image.png" alt=""></p>
<p><img src="https://velog.velcdn.com/images/hj-yu-code/post/2292d8b3-bc8e-43fa-988c-4591b00b7ef9/image.png" alt="">
<img src="https://velog.velcdn.com/images/hj-yu-code/post/ab28d935-9bc5-4648-9e11-4f854689461d/image.png" alt=""></p>
]]></description>
        </item>
        <item>
            <title><![CDATA[도구바 및 상태바 설정]]></title>
            <link>https://velog.io/@hj-yu-code/%EB%8F%84%EA%B5%AC%EB%B0%94-%EB%B0%8F-%EC%83%81%ED%83%9C%EB%B0%94-%EC%84%A4%EC%A0%95</link>
            <guid>https://velog.io/@hj-yu-code/%EB%8F%84%EA%B5%AC%EB%B0%94-%EB%B0%8F-%EC%83%81%ED%83%9C%EB%B0%94-%EC%84%A4%EC%A0%95</guid>
            <pubDate>Fri, 15 Apr 2022 08:20:24 GMT</pubDate>
            <description><![CDATA[<h2 id="도구바-설정">도구바 설정</h2>
<p><img src="https://velog.velcdn.com/images/hj-yu-code/post/fc751d30-d74a-4115-9eae-e64f8ea06438/image.png" alt=""></p>
<p><img src="https://velog.velcdn.com/images/hj-yu-code/post/e683d37b-d953-4af1-b37f-8acebee73799/image.png" alt=""></p>
<p><img src="https://velog.velcdn.com/images/hj-yu-code/post/03373e01-b378-4098-ad08-b2572ae99515/image.png" alt=""></p>
<h2 id="상태바-설정">상태바 설정</h2>
<p><img src="https://velog.velcdn.com/images/hj-yu-code/post/d2621d38-24b5-4d0c-ab04-0608ba50e07d/image.png" alt=""></p>
<p>프롬프트에 &#39;선의 색깔을 초록색으로 변경합니다.&#39; 입력
<img src="https://velog.velcdn.com/images/hj-yu-code/post/642d72f1-f781-4a85-ba17-27389535bd57/image.png" alt=""></p>
<p><img src="https://velog.velcdn.com/images/hj-yu-code/post/629cd772-2be6-409e-ad07-06200cab7a02/image.png" alt=""></p>
<h2 id="마우스-커서에서-활성화">마우스 커서에서 활성화</h2>
<p>프롬프트에 &#39;\n초록&#39;추가하기
<img src="https://velog.velcdn.com/images/hj-yu-code/post/defa6cc2-14bf-49d3-a1b7-2040b4f62e23/image.png" alt=""></p>
<p><img src="https://velog.velcdn.com/images/hj-yu-code/post/91ab21ae-01f4-4d67-8aa6-11284ef75381/image.png" alt=""></p>
<h2 id="상태바-영역">상태바 영역</h2>
<h3 id="기존-상태바">기존 상태바</h3>
<p><img src="https://velog.velcdn.com/images/hj-yu-code/post/9bfd7088-71da-4535-a8b9-1db48ea2ed63/image.png" alt="">
선언하는 곳
----MainFrame.cpp</p>
<pre><code class="language-cpp">static UINT indicators[] =
{
    ID_SEPARATOR,           // 상태 줄 표시기
    ID_INDICATOR_CAPS,
    ID_INDICATOR_NUM,
    ID_INDICATOR_SCRL,
};</code></pre>
<hr>
<p>생성하는 곳
----MainFrame.cpp</p>
<pre><code class="language-cpp">    if (!m_wndStatusBar.Create(this))
    {
        TRACE0(&quot;상태 표시줄을 만들지 못했습니다.\n&quot;);
        return -1;      // 만들지 못했습니다.
    }
    m_wndStatusBar.SetIndicators(indicators, sizeof(indicators)/sizeof(UINT));</code></pre>
<h3 id="상태바-색상영역-추가">상태바 &#39;색상영역&#39; 추가</h3>
<p><img src="https://velog.velcdn.com/images/hj-yu-code/post/1be240be-62ac-4218-ab8c-b1a2db9b8071/image.png" alt="">
색상영역 추가
----MainFrame.cpp</p>
<pre><code class="language-cpp">static UINT indicators[] =
{
    ID_SEPARATOR,           // 상태 줄 표시기
    ID_INDICATOR_COLOR,
    ID_INDICATOR_CAPS,
    ID_INDICATOR_NUM,
    ID_INDICATOR_SCRL,
};</code></pre>
<p><img src="https://velog.velcdn.com/images/hj-yu-code/post/40309317-ccf5-435f-860b-471275db6b03/image.png" alt=""></p>
<p><img src="https://velog.velcdn.com/images/hj-yu-code/post/9ff526d2-c09f-48e4-825d-efc300406f6c/image.png" alt=""></p>
<p><img src="https://velog.velcdn.com/images/hj-yu-code/post/963b5a28-3202-45ef-b8d0-738718e3a671/image.png" alt="">
----doc.cpp</p>
<pre><code class="language-cpp">void CCHomeWorkDoc::OnUpdateIndicatorColor(CCmdUI* pCmdUI)
{
    // TODO: 여기에 명령 업데이트 UI 처리기 코드를 추가합니다.
    switch (m_line.m_penColor) {
    case RGB(255, 0, 0):
        pCmdUI-&gt;SetText(_T(&quot;빨간색&quot;));
        break;
    case RGB(0, 255, 0):
        pCmdUI-&gt;SetText(_T(&quot;초록색&quot;));
        break;
    case RGB(0, 0, 255):
        pCmdUI-&gt;SetText(_T(&quot;파랑색&quot;));
        break;
    default:
        pCmdUI-&gt;SetText(_T(&quot;&quot;));
        break;
    }
}</code></pre>
<p><img src="https://velog.velcdn.com/images/hj-yu-code/post/4fca02e8-c113-4ebd-b88b-794841e04220/image.png" alt=""></p>
<h3 id="상태바-좌표-추가">상태바 &#39;좌표&#39; 추가</h3>
<p>특정 좌표만 출력하기
----MainFrame.h</p>
<pre><code class="language-cpp">// 특성입니다.
public:
    void SetMousePositionOutput(const CPoint&amp; pt) {
        m_wndStatusBar.SetWindowText(_T(&quot;100, 200 pt&quot;));
    }</code></pre>
<p><img src="https://velog.velcdn.com/images/hj-yu-code/post/87b13b3e-47eb-4cd6-9d03-cb96c6c574c1/image.png" alt=""></p>
<p>마우스 위치 좌표를 출력하기
----view.cpp</p>
<pre><code class="language-cpp">#include &quot;MainFrm.h&quot;
void CCHomeWorkView::OnMouseMove(UINT nFlags, CPoint point)
{
    // TODO: 여기에 메시지 처리기 코드를 추가 및/또는 기본값을 호출합니다.
    if ((nFlags &amp; MK_LBUTTON) == MK_LBUTTON) {

        CCHomeWorkDoc* pDoc = GetDocument();
        CClientDC dc(this);

        pDoc-&gt;m_line.DrawLastLine(&amp;dc, point);

        pDoc-&gt;m_line.push_back(point);
    }

    CMainFrame* pMainFrame = (CMainFrame*)AfxGetMainWnd();
    pMainFrame-&gt;SetMousePositionOutput(point);

    CView::OnMouseMove(nFlags, point);
}</code></pre>
<p>----MainFrame.h</p>
<pre><code class="language-cpp">// 특성입니다.
public:
    void SetMousePositionOutput(const CPoint&amp; pt) {
        //m_wndStatusBar.SetWindowText(_T(&quot;100, 200 pt&quot;));
        CString str;
        str.Format(_T(&quot;%d, %d pt&quot;), pt.x, pt.y);
        m_wndStatusBar.SetWindowText(str);
    }</code></pre>
<p><img src="https://velog.velcdn.com/images/hj-yu-code/post/18afa4f2-64e1-4cf8-a958-a2ed79a94ca4/image.png" alt=""></p>
]]></description>
        </item>
        <item>
            <title><![CDATA[단축키 추가]]></title>
            <link>https://velog.io/@hj-yu-code/%EB%8B%A8%EC%B6%95%ED%82%A4-%EC%B6%94%EA%B0%80</link>
            <guid>https://velog.io/@hj-yu-code/%EB%8B%A8%EC%B6%95%ED%82%A4-%EC%B6%94%EA%B0%80</guid>
            <pubDate>Fri, 15 Apr 2022 08:08:11 GMT</pubDate>
            <description><![CDATA[<h2 id="단축키-설정">단축키 설정</h2>
<p>리소스 파일 메뉴에 단축키 작성
<img src="https://velog.velcdn.com/images/hj-yu-code/post/0d5e095e-93f1-4e9b-ad9d-5a17aecaab83/image.png" alt=""></p>
<p><img src="https://velog.velcdn.com/images/hj-yu-code/post/8e311480-e2c9-41a7-9070-0da105acc76b/image.png" alt=""></p>
<p>리소스 파일 accelerator에 단축기 설정
<img src="https://velog.velcdn.com/images/hj-yu-code/post/c35c9766-de34-4bf4-9e58-9f29bfd0dc89/image.png" alt=""></p>
]]></description>
        </item>
        <item>
            <title><![CDATA[GDI(7)]]></title>
            <link>https://velog.io/@hj-yu-code/GDI7</link>
            <guid>https://velog.io/@hj-yu-code/GDI7</guid>
            <pubDate>Fri, 15 Apr 2022 03:30:32 GMT</pubDate>
            <description><![CDATA[<h2 id="네모-색칠하기">네모 색칠하기</h2>
<p>----view.cpp</p>
<pre><code class="language-cpp">void CPenBrushDemoView::OnDraw(CDC* pDC)
{
    CPenBrushDemoDoc* pDoc = GetDocument();
    ASSERT_VALID(pDoc);
    if (!pDoc)
        return;

    CBrush brush(RGB(150, 0, 255));
    CBrush* pOldBrush = pDC-&gt;SelectObject(&amp;brush);

    pDC-&gt;Rectangle(100, 100, 200, 200);
    pDC-&gt;SelectObject(pOldBrush);
}</code></pre>
<p><img src="https://velog.velcdn.com/images/hj-yu-code/post/5498e6d6-8008-4724-9392-cc80e367f2ee/image.png" alt=""></p>
<h2 id="배경-색칠하기">배경 색칠하기</h2>
<p>----view.cpp</p>
<pre><code class="language-cpp">void CPenBrushDemoView::OnDraw(CDC* pDC)
{
    CPenBrushDemoDoc* pDoc = GetDocument();
    ASSERT_VALID(pDoc);
    if (!pDoc)
        return;

    CBrush brush(RGB(150, 0, 255));
    CBrush* pOldBrush = pDC-&gt;SelectObject(&amp;brush);

    CRect rect;
    // 현재 클라이언트 영역을 얻음
    GetClientRect(rect);
    pDC-&gt;Rectangle(rect);

    pDC-&gt;SelectObject(pOldBrush);
}</code></pre>
<p><img src="https://velog.velcdn.com/images/hj-yu-code/post/0a6cfd60-7bda-4f47-8674-7b798eae63c5/image.png" alt=""></p>
<h2 id="기존-이미지-사용">기존 이미지 사용</h2>
<p><img src="https://velog.velcdn.com/images/hj-yu-code/post/667fbcf7-45a9-463d-8e32-7aba43959079/image.png" alt="">
<img src="https://velog.velcdn.com/images/hj-yu-code/post/9970634f-2424-46e2-9950-005673a3d704/image.png" alt="">
<img src="https://velog.velcdn.com/images/hj-yu-code/post/cbc1d2a0-1786-41ad-bdd0-3995569fc906/image.png" alt="">
<img src="https://velog.velcdn.com/images/hj-yu-code/post/2f972821-b3d8-46d0-86b7-912261857c1d/image.png" alt=""></p>
<p>----view.cpp</p>
<pre><code class="language-cpp">void CPenBrushDemoView::OnDraw(CDC* pDC)
{
    CPenBrushDemoDoc* pDoc = GetDocument();
    ASSERT_VALID(pDoc);
    if (!pDoc)
        return;

    CBitmap Bmp;
    Bmp.LoadBitmap(IDB_BITMAP1);
    CBrush brush;

    brush.CreatePatternBrush(&amp;Bmp);

    CBrush* pOldBrush = pDC-&gt;SelectObject(&amp;brush);

    CRect rect;
    // 현재 클라이언트 영역을 얻음
    GetClientRect(rect);
    pDC-&gt;Rectangle(rect);

    pDC-&gt;SelectObject(pOldBrush);
}</code></pre>
<p><img src="https://velog.velcdn.com/images/hj-yu-code/post/a7c3e3bc-d101-41d4-a5df-16a1375d2012/image.png" alt=""></p>
<h2 id="bitmap-이미지-생성">Bitmap 이미지 생성</h2>
<h3 id="256색-비트맵">256색 비트맵</h3>
<p><img src="https://velog.velcdn.com/images/hj-yu-code/post/feafe85e-e4a9-40ca-bdcd-d42d463f87c0/image.png" alt=""></p>
<h3 id="24비트-비트맵">24비트 비트맵</h3>
<p>24bit = 4byte
트루 컬러 이미지
<img src="https://velog.velcdn.com/images/hj-yu-code/post/df982c2e-09fc-4eac-baab-e107a1f40265/image.png" alt=""></p>
]]></description>
        </item>
        <item>
            <title><![CDATA[GDI(6)]]></title>
            <link>https://velog.io/@hj-yu-code/GDI6</link>
            <guid>https://velog.io/@hj-yu-code/GDI6</guid>
            <pubDate>Fri, 15 Apr 2022 03:00:10 GMT</pubDate>
            <description><![CDATA[<h2 id="펜-스타일-설정하기">펜 스타일 설정하기</h2>
<p>----view.cpp</p>
<pre><code class="language-cpp">void CPenBrushDemoView::OnDraw(CDC* pDC)
{
    CPenBrushDemoDoc* pDoc = GetDocument();
    ASSERT_VALID(pDoc);
    if (!pDoc)
        return;

    // TODO: 여기에 원시 데이터에 대한 그리기 코드를 추가합니다.
    LOGBRUSH lb;
    lb.lbStyle = BS_SOLID;
    lb.lbColor = RGB(192, 192, 192);

    CPen arNewPen[3];
    CPen* pOldPen = NULL;
    arNewPen[0].CreatePen(PS_GEOMETRIC | PS_SOLID | PS_ENDCAP_ROUND, 20, &amp;lb);
    arNewPen[1].CreatePen(PS_GEOMETRIC | PS_SOLID | PS_ENDCAP_SQUARE, 20, &amp;lb);
    arNewPen[2].CreatePen(PS_GEOMETRIC | PS_SOLID | PS_ENDCAP_FLAT, 20, &amp;lb);

    for (int i = 0; i &lt; 3; i++) {
        pOldPen = pDC-&gt;SelectObject(&amp;arNewPen[i]);
        pDC-&gt;MoveTo(40, i * 100 + 40); // 시작좌표
        pDC-&gt;LineTo(240, i * 100 + 40); // 끝좌표

        pDC-&gt;SelectObject(pOldPen);

        pDC-&gt;MoveTo(40, i * 100 + 40);
        pDC-&gt;LineTo(240, i * 100 + 40);

        arNewPen[i].DeleteObject();
    }
}</code></pre>
<p><img src="https://velog.velcdn.com/images/hj-yu-code/post/a29f6f06-446c-416e-b5b4-db427611ef97/image.png" alt=""></p>
]]></description>
        </item>
        <item>
            <title><![CDATA[개발론]]></title>
            <link>https://velog.io/@hj-yu-code/%EA%B0%9C%EB%B0%9C%EB%A1%A0</link>
            <guid>https://velog.io/@hj-yu-code/%EA%B0%9C%EB%B0%9C%EB%A1%A0</guid>
            <pubDate>Fri, 15 Apr 2022 00:57:45 GMT</pubDate>
            <description><![CDATA[<p>폭포수 개발 방법론(si) : 설계(구조)를 먼저 진행</p>
<ul>
<li>si : 명확한 목표가 있음
애자일 방법론(tdd + bdd : 리팩토링)</li>
<li>tdd : 테스트 코드를 만들어서 진행함</li>
<li>리팩토링 : 수정된 사항을 재수정함</li>
</ul>
<p>MSA</p>
<ul>
<li>기능을 쪼개서 제작함</li>
<li>전문 업체(보안, 회원관리 등)에서 코드를 제공받음</li>
<li>외부에서 가져온 코드는 권한이 없어서 수정하기 어려움</li>
</ul>
]]></description>
        </item>
        <item>
            <title><![CDATA[GDI(4)-색상]]></title>
            <link>https://velog.io/@hj-yu-code/GDI4-%EC%83%89%EC%83%81</link>
            <guid>https://velog.io/@hj-yu-code/GDI4-%EC%83%89%EC%83%81</guid>
            <pubDate>Thu, 14 Apr 2022 08:49:16 GMT</pubDate>
            <description><![CDATA[<p>----doc.h</p>
<pre><code class="language-cpp">// 작업입니다.
public:
    vector&lt;CPoint&gt; m_array;
    COLORREF m_color; // 색상에 대한 변수</code></pre>
<hr>
<p>----doc.cpp</p>
<pre><code class="language-cpp">void CReDrawDemoView::OnDraw(CDC* pDC)
{
    CReDrawDemoDoc* pDoc = GetDocument();
    ASSERT_VALID(pDoc);
    if (!pDoc)
        return;

    // TODO: 여기에 원시 데이터에 대한 그리기 코드를 추가합니다.
    CPen pen(PS_SOLID, 10, pDoc-&gt;m_linecolor);
    // 펜스타일, 굵기, 색상
    CPen* pOldPen = pDC-&gt;SelectObject(&amp;pen);
    if (pDoc-&gt;m_array.size() &gt; 0) {
        const CPoint&amp; pt = pDoc-&gt;m_array[0];
        pDC-&gt;MoveTo(pt.x, pt.y);

        for (const CPoint&amp; pt : pDoc-&gt;m_array) {
            pDC-&gt;LineTo(pt.x, pt.y);
        }
    }
    //CBrush brush(RGB(0, 0, 0));
    CBrush brush(HS_CROSS, RGB(0, 0, 0)); // 격자모양

    CBrush* pOldBrush = pDC-&gt;SelectObject(&amp;brush);
    pDC-&gt;Rectangle(100, 100, 200, 200);
    pDC-&gt;SelectObject(pOldBrush);

    pDC-&gt;SelectObject(pOldPen); // 원래대로 변경
}</code></pre>
<p><img src="https://velog.velcdn.com/images/hj-yu-code/post/46ddbfab-f13a-4c45-bca4-f9f504e1ec09/image.png" alt=""></p>
<h2 id="메뉴에-따른-색상-변경하기">메뉴에 따른 색상 변경하기</h2>
<p><img src="https://velog.velcdn.com/images/hj-yu-code/post/9b7aede1-6d8f-465c-a38e-a44e245b27c5/image.png" alt=""></p>
<p><img src="https://velog.velcdn.com/images/hj-yu-code/post/992afccf-b156-4513-9970-1ff58be48a5f/image.png" alt="">
----doc.cpp</p>
<pre><code class="language-cpp">void CReDrawDemoDoc::OnColorBlue()
{
    // TODO: 여기에 명령 처리기 코드를 추가합니다.
    m_linecolor = RGB(0, 255, 0);
}</code></pre>
<h2 id="윈도우-resize-안해도-색상-변경하기">윈도우 ReSize 안해도 색상 변경하기</h2>
<p>----doc.cpp</p>
<pre><code class="language-cpp">#include &quot;ReDrawDemoView.h&quot; // 헤더 추가 필수
#include &quot;MainFrm.h&quot;
void CReDrawDemoDoc::OnColorBlue()
{
    // TODO: 여기에 명령 처리기 코드를 추가합니다.
    m_linecolor = RGB(0, 0, 255);
    // 방법 1
    // ((CReDrawDemoView*)m_viewList.GetHead())-&gt;Invalidate(); // 강제 형변환
    // 방법 2
    // ((CMainFrame*)AfxGetMainWnd())-&gt;GetActiveView()-&gt;Invalidate();
    // 방법 3
    UpdateAllViews(NULL); // 모든 view에서 호출(1개의 view아니라 모든 view를 호출함)
}</code></pre>
<p><img src="https://velog.velcdn.com/images/hj-yu-code/post/524ab5b3-61e4-48c1-9e0e-bbdf928fe4e2/image.png" alt=""></p>
<h2 id="선택한-색상을-메뉴에-체크하기">선택한 색상을 메뉴에 체크하기</h2>
<p><img src="https://velog.velcdn.com/images/hj-yu-code/post/761bb21c-2c66-4e21-8211-61a0e67bf156/image.png" alt="">
----doc.cpp</p>
<pre><code class="language-cpp">void CReDrawDemoDoc::OnUpdateColorBlue(CCmdUI* pCmdUI)
{
    // TODO: 여기에 명령 업데이트 UI 처리기 코드를 추가합니다.
    pCmdUI-&gt;SetCheck(m_linecolor == RGB(0, 0, 255));
}</code></pre>
<p><img src="https://velog.velcdn.com/images/hj-yu-code/post/21b29385-1785-4b27-828b-96d50c5db111/image.png" alt=""></p>
]]></description>
        </item>
        <item>
            <title><![CDATA[GDI(3)-선]]></title>
            <link>https://velog.io/@hj-yu-code/GDI3-%EC%84%A0</link>
            <guid>https://velog.io/@hj-yu-code/GDI3-%EC%84%A0</guid>
            <pubDate>Thu, 14 Apr 2022 08:10:06 GMT</pubDate>
            <description><![CDATA[<p>선 한개만 그리기!
----view.cpp</p>
<pre><code class="language-cpp">void CReDrawDemoView::OnDraw(CDC* pDC)
{
    CReDrawDemoDoc* pDoc = GetDocument();
    ASSERT_VALID(pDoc);
    if (!pDoc)
        return;

    // TODO: 여기에 원시 데이터에 대한 그리기 코드를 추가합니다.
    CPen pen(PS_SOLID, 10, RGB(255, 0, 0));
    // 펜스타일, 굵기, 색상
    CPen* pOldPen = pDC-&gt;SelectObject(&amp;pen);
    if (pDoc-&gt;m_array.size() &gt; 0) {
        const CPoint&amp; pt = pDoc-&gt;m_array[0];
        pDC-&gt;MoveTo(pt.x, pt.y);

        for (const CPoint&amp; pt : pDoc-&gt;m_array) {
            pDC-&gt;LineTo(pt.x, pt.y);
        }
    }

    pDC-&gt;SelectObject(pOldPen); // 원래대로 변경
}
////////
void CReDrawDemoView::OnLButtonDown(UINT nFlags, CPoint point) // WM_PAINT를 호출하면 사라지는 곳
{
    // TODO: 여기에 메시지 처리기 코드를 추가 및/또는 기본값을 호출합니다.
    CClientDC dc(this);

    /*CPen pen(PS_SOLID, 10, RGB(255, 0, 0));
    CPen* pOldPen = dc.SelectObject(&amp;pen);
    dc.Rectangle(point.x, point.y, point.x+100, point.y+100);
    dc.SelectObject(pOldPen);*/

    CReDrawDemoDoc* pDoc = GetDocument();
    pDoc-&gt;m_array.clear();
    pDoc-&gt;m_array.push_back(point);
    // 배열 내용을 지우고, 점을 다시 넣음


    Invalidate(); // 선 한번 그릴때마다 다시 화면 지우기

    SetCapture(); // 마우스 컨트롤1

    CView::OnLButtonDown(nFlags, point);
}


void CReDrawDemoView::OnLButtonUp(UINT nFlags, CPoint point)
{
    // TODO: 여기에 메시지 처리기 코드를 추가 및/또는 기본값을 호출합니다.
    ReleaseCapture(); // 마우스 컨트롤2
    CView::OnLButtonUp(nFlags, point);
}


void CReDrawDemoView::OnMouseMove(UINT nFlags, CPoint point)
{
    // TODO: 여기에 메시지 처리기 코드를 추가 및/또는 기본값을 호출합니다.
    if ((nFlags &amp; MK_LBUTTON) == MK_LBUTTON) {
        CReDrawDemoDoc* pDoc = GetDocument();

        const CPoint&amp; pt = pDoc-&gt;m_array.back();
        CClientDC dc(this);


        CPen pen(PS_SOLID, 10, RGB(255, 0, 0));
        CPen* pOldPen = dc.SelectObject(&amp;pen);

        dc.MoveTo(pt.x, pt.y);
        dc.LineTo(point.x, point.y);

        dc.SelectObject(pOldPen);

        pDoc-&gt;m_array.push_back(point);

    }

    CView::OnMouseMove(nFlags, point);
}</code></pre>
<p><img src="https://velog.velcdn.com/images/hj-yu-code/post/7d1d8dc4-fd89-4f77-aeee-150745b2857b/image.png" alt=""></p>
]]></description>
        </item>
        <item>
            <title><![CDATA[GDI(2)-색깔 상자]]></title>
            <link>https://velog.io/@hj-yu-code/GDI2</link>
            <guid>https://velog.io/@hj-yu-code/GDI2</guid>
            <pubDate>Thu, 14 Apr 2022 06:38:09 GMT</pubDate>
            <description><![CDATA[<h2 id="색깔-상자-그리기">색깔 상자 그리기</h2>
<p>----view.cpp</p>
<pre><code class="language-cpp">// CReDrawDemoView 그리기

void CReDrawDemoView::OnDraw(CDC* pDC)
{
    CReDrawDemoDoc* pDoc = GetDocument();
    ASSERT_VALID(pDoc);
    if (!pDoc)
        return;

    // TODO: 여기에 원시 데이터에 대한 그리기 코드를 추가합니다.
    CPen pen(PS_SOLID, 10, RGB(255, 0, 0));
    // 펜스타일, 굵기, 색상
    CPen* pOldPen = pDC-&gt;SelectObject(&amp;pen); // 주소 복사
    pDC-&gt;Rectangle(100, 100, 200, 200);
    pDC-&gt;SelectObject(pOldPen); // 원래대로 변경
}</code></pre>
<p><img src="https://velog.velcdn.com/images/hj-yu-code/post/fdf243df-f0df-4b21-b7b8-1de876f9c17f/image.png" alt=""></p>
<h2 id="클릭한-좌표에-상자-그리기">클릭한 좌표에 상자 그리기</h2>
<p>----view.cpp</p>
<pre><code class="language-cpp">void CReDrawDemoView::OnLButtonDown(UINT nFlags, CPoint point)
{
    // TODO: 여기에 메시지 처리기 코드를 추가 및/또는 기본값을 호출합니다.
    CClientDC dc(this);

    CPen pen(PS_SOLID, 10, RGB(255, 0, 0));
    CPen* pOldPen = dc.SelectObject(&amp;pen);
    dc.Rectangle(point.x, point.y, point.x+100, point.y+100);
    dc.SelectObject(pOldPen);

    CView::OnLButtonDown(nFlags, point);
}</code></pre>
<p><img src="https://velog.velcdn.com/images/hj-yu-code/post/b15c17d3-1157-40eb-b370-c9550c8ddd9c/image.png" alt=""></p>
<h2 id="resize해도-안사라지게-하기">ReSize해도 안사라지게 하기</h2>
<h3 id="view에서만-작성">view에서만 작성</h3>
<p>OnDraw에 그려서 사라지지 않게 하기
----view.h</p>
<pre><code class="language-cpp">#include &lt;vector&gt;
using namespace std;
////////
// 작업입니다.
public:
    void Draw(int x, int y, CDC* pDC);
    vector&lt;CPoint&gt; m_array;</code></pre>
<hr>
<p>----view.cpp</p>
<pre><code class="language-cpp">void CReDrawDemoView::OnDraw(CDC* pDC)
{
    CReDrawDemoDoc* pDoc = GetDocument();
    ASSERT_VALID(pDoc);
    if (!pDoc)
        return;

    // TODO: 여기에 원시 데이터에 대한 그리기 코드를 추가합니다.
    CPen pen(PS_SOLID, 10, RGB(255, 0, 0));
    // 펜스타일, 굵기, 색상
    CPen* pOldPen = pDC-&gt;SelectObject(&amp;pen); // 주소 복사
    for (const CPoint&amp; pt : m_array) {
        pDC-&gt;Rectangle(pt.x, pt.y, pt.x + 100, pt.y + 100);
    }
    pDC-&gt;SelectObject(pOldPen); // 원래대로 변경
}
////////
void CReDrawDemoView::OnLButtonDown(UINT nFlags, CPoint point)
{
    // TODO: 여기에 메시지 처리기 코드를 추가 및/또는 기본값을 호출합니다.

    m_array.push_back(point);

    Invalidate(); // 또는 RedrawWindow();

    CView::OnLButtonDown(nFlags, point);
}</code></pre>
<p>Invalidate()의 단점</p>
<ul>
<li><p>너무 많은 데이터가 있을 때, 다시 그리는 과정에서 화면 깜빡임이 생김</p>
<h3 id="많은-데이터에-대한-깜빡임-없애기">많은 데이터에 대한 깜빡임 없애기</h3>
</li>
<li><p>---view.cpp</p>
<pre><code class="language-cpp">void CReDrawDemoView::OnLButtonDown(UINT nFlags, CPoint point)
{
   // TODO: 여기에 메시지 처리기 코드를 추가 및/또는 기본값을 호출합니다.
   CClientDC dc(this);

   CPen pen(PS_SOLID, 10, RGB(255, 0, 0));
   CPen* pOldPen = dc.SelectObject(&amp;pen);
   dc.Rectangle(point.x, point.y, point.x+100, point.y+100);
   dc.SelectObject(pOldPen);

   m_array.push_back(point);

   //Invalidate(); // 또는 RedrawWindow();

   CView::OnLButtonDown(nFlags, point);
}</code></pre>
</li>
</ul>
<h3 id="데이터를-doc에-작성">데이터를 Doc에 작성</h3>
<p>----doc.h</p>
<pre><code class="language-cpp">#include &lt;vector&gt;
using namespace std;
////////
// 작업입니다.
public:
    vector&lt;CPoint&gt; m_array;</code></pre>
<hr>
<p>----doc.cpp</p>
<pre><code class="language-cpp">BOOL CReDrawDemoDoc::OnNewDocument()
{
    if (!CDocument::OnNewDocument())
        return FALSE;

    // TODO: 여기에 재초기화 코드를 추가합니다.
    // SDI 문서는 이 문서를 다시 사용합니다.

    vector&lt;CPoint&gt; m_array; // Document의 초기화

    return TRUE;
}
////////
void CReDrawDemoDoc::Serialize(CArchive&amp; ar)
{
    if (ar.IsStoring())
    {
        // TODO: 여기에 저장 코드를 추가합니다.
        ar &lt;&lt; m_array.size();
        for (const CPoint&amp; pt : m_array) {
            ar &lt;&lt; pt.x;
            ar &lt;&lt; pt.y;
        }
    }
    else
    {
        // TODO: 여기에 로딩 코드를 추가합니다.
        int m_size;
        int x, y;
        ar &gt;&gt; m_size;

        for (int i = 0; i &lt; m_size; i++) {
            ar &gt;&gt; x;
            ar &gt;&gt; y;
            m_array.push_back(CPoint(x, y));
        }
    }
}</code></pre>
<hr>
<p>----view.h</p>
<pre><code class="language-cpp">//#include &lt;vector&gt;
//using namespace std;
////////
// 작업입니다.
public:
    void Draw(int x, int y, CDC* pDC);
    //vector&lt;CPoint&gt; m_array;</code></pre>
<hr>
<p>----view.cpp</p>
<pre><code class="language-cpp">void CReDrawDemoView::OnDraw(CDC* pDC)
{
    CReDrawDemoDoc* pDoc = GetDocument();
    ASSERT_VALID(pDoc);
    if (!pDoc)
        return;

    // TODO: 여기에 원시 데이터에 대한 그리기 코드를 추가합니다.
    CPen pen(PS_SOLID, 10, RGB(255, 0, 0));
    // 펜스타일, 굵기, 색상
    CPen* pOldPen = pDC-&gt;SelectObject(&amp;pen); // 주소 복사
    for (const CPoint&amp; pt : pDoc-&gt;m_array) {
        pDC-&gt;Rectangle(pt.x, pt.y, pt.x + 100, pt.y + 100);
    }
    pDC-&gt;SelectObject(pOldPen); // 원래대로 변경
}
///////
void CReDrawDemoView::OnLButtonDown(UINT nFlags, CPoint point)
{
    // TODO: 여기에 메시지 처리기 코드를 추가 및/또는 기본값을 호출합니다.
    CClientDC dc(this);

    CPen pen(PS_SOLID, 10, RGB(255, 0, 0));
    CPen* pOldPen = dc.SelectObject(&amp;pen);
    dc.Rectangle(point.x, point.y, point.x+100, point.y+100);
    dc.SelectObject(pOldPen);

    CReDrawDemoDoc* pDoc = GetDocument();
    pDoc-&gt;m_array.push_back(point);
    pDoc-&gt;SetModifiedFlag();

    //Invalidate(); // 또는 RedrawWindow();

    CView::OnLButtonDown(nFlags, point);
}
</code></pre>
<h3 id="새로만들기-구현">새로만들기 구현</h3>
<p><img src="https://velog.velcdn.com/images/hj-yu-code/post/47692de5-0aaa-4212-8337-7aec79d545fe/image.png" alt="">
새로만들기를 누르면 빈 화면 나오게 하기</p>
<p><img src="https://velog.velcdn.com/images/hj-yu-code/post/cb729cdf-2624-4d6f-91d8-6d0147000336/image.png" alt="">
----doc.cpp</p>
<pre><code class="language-cpp">void CReDrawDemoDoc::DeleteContents()
{
    // TODO: 여기에 특수화된 코드를 추가 및/또는 기본 클래스를 호출합니다.
    m_array.clear();

    CDocument::DeleteContents();
}</code></pre>
]]></description>
        </item>
        <item>
            <title><![CDATA[GDI(1)]]></title>
            <link>https://velog.io/@hj-yu-code/GDI</link>
            <guid>https://velog.io/@hj-yu-code/GDI</guid>
            <pubDate>Thu, 14 Apr 2022 05:49:45 GMT</pubDate>
            <description><![CDATA[<h2 id="기본화면-출력">기본화면 출력</h2>
<p>----view.cpp</p>
<pre><code class="language-cpp">void CReDrawDemoView::OnPaint()
{
    CPaintDC dc(this); // device context for painting
                       // TODO: 여기에 메시지 처리기 코드를 추가합니다.
                       // 그리기 메시지에 대해서는 CView::OnPaint()을(를) 호출하지 마십시오.
    dc.TextOut(100, 200, _T(&quot;안녕하세요&quot;));
}</code></pre>
<p><img src="https://velog.velcdn.com/images/hj-yu-code/post/3d7b62df-32ab-42d8-b44e-62aaaa78ef23/image.png" alt=""></p>
<h2 id="클릭한-좌표에-문구-출력">클릭한 좌표에 문구 출력</h2>
<p>----view.cpp</p>
<pre><code class="language-cpp">void CReDrawDemoView::OnLButtonDown(UINT nFlags, CPoint point)
{
    // TODO: 여기에 메시지 처리기 코드를 추가 및/또는 기본값을 호출합니다.
    CClientDC dc(this);
    dc.TextOut(point.x, point.y, _T(&quot;Hello World&quot;));
    CView::OnLButtonDown(nFlags, point);
}</code></pre>
<p><img src="https://velog.velcdn.com/images/hj-yu-code/post/97aabe29-4daf-4470-862a-0a3aa9860269/image.png" alt=""></p>
<h2 id="draw-함수-사용">Draw 함수 사용</h2>
<p>----view.h</p>
<pre><code class="language-cpp">// 특성입니다.
public:
    CReDrawDemoDoc* GetDocument() const;</code></pre>
<hr>
<p>----view.cpp</p>
<pre><code class="language-cpp">
void CReDrawDemoView::Draw(int x, int y, CDC* pDC) {
    pDC-&gt;TextOut(x, y, _T(&quot;안녕하세요&quot;));
}

void CReDrawDemoView::OnPaint() // 항상 나오는 곳
{
    CPaintDC dc(this); // device context for painting
                       // TODO: 여기에 메시지 처리기 코드를 추가합니다.
                       // 그리기 메시지에 대해서는 CView::OnPaint()을(를) 호출하지 마십시오.
    //dc.TextOut(100, 200, _T(&quot;안녕하세요&quot;));
    Draw(100, 100, &amp;dc);
}


void CReDrawDemoView::OnLButtonDown(UINT nFlags, CPoint point) // WM_PAINT를 호출하면 사라지는 곳
{
    // TODO: 여기에 메시지 처리기 코드를 추가 및/또는 기본값을 호출합니다.
    CClientDC dc(this);

    //dc.TextOut(point.x, point.y, _T(&quot;Hello World&quot;));
    Draw(point.x, point.y, &amp;dc);


    CView::OnLButtonDown(nFlags, point);
}</code></pre>
<h2 id="cpaintdc-vs-cclientdc">CPaintDC vs. CClientDC</h2>
<p>OnLButtonDown: WM_PAINT를 호출하면 사라짐
<strong>윈도우 창의 크기를 조금만 달라져도 관련된 내용이 사라지게 됨</strong>
<strong>- CPaintDC와 CClientDC의 차이임</strong></p>
<p>ClientDC는 마우스 찍을 때만 동작함</p>
<ul>
<li>임시적으로 동작하게 됨</li>
<li>OnPaint를 제외한 곳에서 사용</li>
</ul>
<p>PaintDC는 임시이긴 함</p>
<ul>
<li>차이점은 ReSize 될 때마다 호출하게 됨</li>
<li>OnPaint에서만 사용</li>
</ul>
]]></description>
        </item>
        <item>
            <title><![CDATA[MouseMsg]]></title>
            <link>https://velog.io/@hj-yu-code/MouseMsg</link>
            <guid>https://velog.io/@hj-yu-code/MouseMsg</guid>
            <pubDate>Thu, 14 Apr 2022 03:01:48 GMT</pubDate>
            <description><![CDATA[<h2 id="창에-문구-띄우기">창에 문구 띄우기</h2>
<p>-----view.cpp</p>
<pre><code class="language-cpp">void CMouseMsgView::OnDraw(CDC* pDC)
{
    CMouseMsgDoc* pDoc = GetDocument();
    ASSERT_VALID(pDoc);
    if (!pDoc)
        return;

    // TODO: 여기에 원시 데이터에 대한 그리기 코드를 추가합니다.
    pDC-&gt;TextOut(100, 100, _T(&quot;안녕하세요&quot;)); // _T : char, wchar_t 구별하지 않고 사용하기 위해
}</code></pre>
<p><img src="https://velog.velcdn.com/images/hj-yu-code/post/8654cebf-1104-435b-aaed-4b855278aa7b/image.png" alt=""></p>
<h2 id="doc과-view로-나누기">Doc과 View로 나누기</h2>
<p>-----view.cpp</p>
<pre><code class="language-cpp">void CMouseMsgView::OnDraw(CDC* pDC)
{
    CMouseMsgDoc* pDoc = GetDocument(); // Doc.h에 정의된 내용 가져오는 함수
    ASSERT_VALID(pDoc);
    if (!pDoc)
        return;

    // TODO: 여기에 원시 데이터에 대한 그리기 코드를 추가합니다.
    pDC-&gt;TextOut(pDoc-&gt;m_x, pDoc-&gt;m_y, pDoc-&gt;m_strText);
}</code></pre>
<hr>
<p>-----doc.h</p>
<pre><code class="language-cpp">// 특성입니다.
public:
    int m_x;
    int m_y;
    CString m_strText;</code></pre>
<hr>
<p>-----doc.cpp</p>
<pre><code class="language-cpp">BOOL CMouseMsgDoc::OnNewDocument()
{
    if (!CDocument::OnNewDocument())
        return FALSE;

    // TODO: 여기에 재초기화 코드를 추가합니다.
    // SDI 문서는 이 문서를 다시 사용합니다.

    m_x = 100;
    m_y = 100;
    m_strText = _T(&quot;안녕하세요&quot;);

    return TRUE;
}
</code></pre>
<h2 id="마우스-클릭에-따라-문구가-움직이기">마우스 클릭에 따라 문구가 움직이기</h2>
<p>-----view.cpp</p>
<pre><code class="language-cpp">void CMouseMsgView::OnLButtonDown(UINT nFlags, CPoint point)
{
    // TODO: 여기에 메시지 처리기 코드를 추가 및/또는 기본값을 호출합니다.
    CMouseMsgDoc* pDoc = GetDocument();
    pDoc-&gt;m_x = point.x;
    pDoc-&gt;m_y = point.y;

    Invalidate(); // 현재 화면을 다시 그려라
    // WM_PAINT 메세지가 현재 나의 윈도우에 전달됨 -&gt; OnDraw() 호출

    CView::OnLButtonDown(nFlags, point);
}</code></pre>
<p><img src="https://velog.velcdn.com/images/hj-yu-code/post/17ee181f-b9a9-4114-90b8-13507d1c4c64/image.png" alt=""></p>
<h2 id="변경된-내용-저장하기">변경된 내용 저장하기</h2>
<h3 id="변경사항-있을-때-저장-문구-출력">변경사항 있을 때 저장 문구 출력</h3>
<p>문구를 옮긴 후, 해당 변경사항을 파악하여 윈도우를 닫을 때 저장문구 보이게 하기</p>
<p>-----view.cpp</p>
<pre><code class="language-cpp">void CMouseMsgView::OnLButtonDown(UINT nFlags, CPoint point)
{
    // TODO: 여기에 메시지 처리기 코드를 추가 및/또는 기본값을 호출합니다.
    CMouseMsgDoc* pDoc = GetDocument();
    pDoc-&gt;m_x = point.x;
    pDoc-&gt;m_y = point.y;

    pDoc-&gt;SetModifiedFlag(); //문서가 수정되었다고 설정됨

    Invalidate(); // 현재 화면을 다시 그려라
    // WM_PAINT 메세지가 현재 나의 윈도우에 전달됨 -&gt; OnDraw() 호출
    // RedrawWindow();와 같은 기능

    CView::OnLButtonDown(nFlags, point);
}</code></pre>
<p><img src="https://velog.velcdn.com/images/hj-yu-code/post/4e8fcce9-6359-4759-bba6-a5bd6e677c0c/image.png" alt="">
저장하는 문구가 나타나게 됨</p>
<h3 id="변경된-데이터-실제로-저장-및-열기">변경된 데이터 실제로 저장 및 열기</h3>
<p><img src="https://velog.velcdn.com/images/hj-yu-code/post/ad238bac-ce99-461f-b7ea-f8047450a264/image.png" alt=""></p>
<pre><code class="language-cpp">// CMouseMsgDoc serialization

void CMouseMsgDoc::Serialize(CArchive&amp; ar)
{
    if (ar.IsStoring()) // 저장
    {
        // TODO: 여기에 저장 코드를 추가합니다.
        ar &lt;&lt; m_x;
        ar &lt;&lt; m_y;
        ar &lt;&lt; m_strText;
    }
    else // 불러오기
    {
        // TODO: 여기에 로딩 코드를 추가합니다.
        ar &gt;&gt; m_x;
        ar &gt;&gt; m_y;
        ar &gt;&gt; m_strText;
    }
}</code></pre>
<p>코드 변경 후 해당 파일 내용 확인
<img src="https://velog.velcdn.com/images/hj-yu-code/post/aecdf9be-6206-42fd-acdc-095635cefb7c/image.png" alt=""></p>
<p>코드 실행 후 &#39;열기&#39;해서 해당 파일 열면, 저장한 내용으로 출력됨</p>
<h3 id="저장된-데이터-해석">저장된 데이터 해석</h3>
<p>기본 세팅 값</p>
<ul>
<li>m_x : int, 100</li>
<li>m_y : int, 100</li>
<li>m_strText : wchar_t(unicode), abcdef</li>
</ul>
<p><img src="https://velog.velcdn.com/images/hj-yu-code/post/b4478949-89f2-4fea-86ab-48bc194fdb44/image.png" alt=""></p>
<p>해당 내용 저장 후 데이터 확인
<img src="https://velog.velcdn.com/images/hj-yu-code/post/51415a4e-ae99-4b16-abbe-bf44a6a145c0/image.png" alt="">
데이터 해석</p>
<ul>
<li>64 00 00 00 : m_x의 데이터 ( dex : 100)</li>
<li>64 00 00 00 : m_y의 데이터 ( dex : 100)</li>
<li>06 : m_strText의 데이터 길이</li>
<li>61 00 62 00 63 00 64 00 65 00 66 00 : m_strText의 데이터 ( unicode : abcdef )<ul>
<li>만약 multibyte 라면 1byte 씩, &#39;06 61 62 63 64 65 66&#39; 로 저장됨</li>
</ul>
</li>
</ul>
<h2 id="마우스에-문구가-따라다니기">마우스에 문구가 따라다니기</h2>
<h3 id="기본적인-기능">기본적인 기능</h3>
<p><img src="https://velog.velcdn.com/images/hj-yu-code/post/cc258d97-8572-411c-8e2c-9b45a57552d0/image.png" alt=""></p>
<pre><code class="language-cpp">void CMouseMsgView::OnMouseMove(UINT nFlags, CPoint point)
{
    if ((nFlags &amp; MK_LBUTTON) == MK_LBUTTON) { // 왼쪽 마우스 눌러진 상탱에서 움직임
        CMouseMsgDoc* pDoc = GetDocument();
        pDoc-&gt;m_x = point.x;
        pDoc-&gt;m_y = point.y;

        pDoc-&gt;SetModifiedFlag(); //문서가 수정되었다고 설정됨

        Invalidate();
    }
    CView::OnMouseMove(nFlags, point);
}</code></pre>
<p>다른 버튼 누른 상태여도 왼쪽 버튼만 누르고 있으면 문구가 따라니게 됨</p>
<h3 id="bool-m_bmousedown-플로우-추가">bool m_bMouseDown 플로우 추가</h3>
<p>nFlags를 모를 때, 변수를 하나 만들어서 해당 플로우 만들기</p>
<p>특징</p>
<ul>
<li>윈도우 밖에서 마우스가 눌러졌을 때 작업되는 것을 방지함</li>
<li>윈도우 밖에서 마우스를 땠을 때 작업되는 것을 방지함</li>
<li>누른 상태에서 마우스를 윈도우 밖으로 나온다면, 누른 상태로 윈도우 안으로 들어가야 함</li>
</ul>
<p>-----view.h</p>
<pre><code class="language-cpp">// 특성입니다.
public:
    CMouseMsgDoc* GetDocument() const;
    bool m_bMouseDown; // 변수 선언</code></pre>
<p><img src="https://velog.velcdn.com/images/hj-yu-code/post/39cb46aa-3c45-4f57-b310-4b2edad39865/image.png" alt="">
해당 함수 추가하기</p>
<p>-----view.cpp</p>
<pre><code class="language-cpp">// CMouseMsgView 생성/소멸

CMouseMsgView::CMouseMsgView() noexcept
{
    // TODO: 여기에 생성 코드를 추가합니다.
    m_bMouseDown = false;
}
///////////////
void CMouseMsgView::OnLButtonDown(UINT nFlags, CPoint point)
{
    // TODO: 여기에 메시지 처리기 코드를 추가 및/또는 기본값을 호출합니다.
    CMouseMsgDoc* pDoc = GetDocument();
    pDoc-&gt;m_x = point.x;
    pDoc-&gt;m_y = point.y;

    pDoc-&gt;SetModifiedFlag(); //문서가 수정되었다고 설정됨

    Invalidate(); // 현재 화면을 다시 그려라
    // WM_PAINT 메세지가 현재 나의 윈도우에 전달됨 -&gt; OnDraw() 호출
    // RedrawWindow();와 같은 기능

    m_bMouseDown = true;

    CView::OnLButtonDown(nFlags, point);
}


void CMouseMsgView::OnMouseMove(UINT nFlags, CPoint point)
{
    // if ((nFlags &amp; MK_LBUTTON) == MK_LBUTTON) { // 왼쪽 마우스 눌러진 상탱에서 움직임
    if(m_bMouseDown) {
        CMouseMsgDoc* pDoc = GetDocument();
        pDoc-&gt;m_x = point.x;
        pDoc-&gt;m_y = point.y;

        pDoc-&gt;SetModifiedFlag(); //문서가 수정되었다고 설정됨

        Invalidate();
    }

    CView::OnMouseMove(nFlags, point);
}


void CMouseMsgView::OnLButtonUp(UINT nFlags, CPoint point)
{
    // TODO: 여기에 메시지 처리기 코드를 추가 및/또는 기본값을 호출합니다.
    m_bMouseDown = false;

    CView::OnLButtonUp(nFlags, point);
}</code></pre>
<h3 id="마우스-캡쳐-기능-추가">마우스 캡쳐 기능 추가</h3>
<p>해당 윈도우 밖으로 벗어나도 해당 문구가 마우스 좌표로 따라 오게 만들기</p>
<p>-----view.h</p>
<pre><code class="language-cpp">void CMouseMsgView::OnLButtonDown(UINT nFlags, CPoint point)
{
    // TODO: 여기에 메시지 처리기 코드를 추가 및/또는 기본값을 호출합니다.
    CMouseMsgDoc* pDoc = GetDocument();
    pDoc-&gt;m_x = point.x;
    pDoc-&gt;m_y = point.y;

    pDoc-&gt;SetModifiedFlag(); //문서가 수정되었다고 설정됨

    Invalidate(); // 현재 화면을 다시 그려라
    // WM_PAINT 메세지가 현재 나의 윈도우에 전달됨 -&gt; OnDraw() 호출
    // RedrawWindow();와 같은 기능

    m_bMouseDown = true;

    SetCapture(); // 윈도우 밖으로 나가도 마우스 좌표를 계속 따라다님

    CView::OnLButtonDown(nFlags, point);
}


void CMouseMsgView::OnMouseMove(UINT nFlags, CPoint point)
{
    //if ((nFlags &amp; MK_LBUTTON) == MK_LBUTTON) { // 왼쪽 마우스 눌러진 상탱에서 움직임
    if(m_bMouseDown) {
        CMouseMsgDoc* pDoc = GetDocument();
        pDoc-&gt;m_x = point.x;
        pDoc-&gt;m_y = point.y;

        pDoc-&gt;SetModifiedFlag(); //문서가 수정되었다고 설정됨
        TRACE(&quot;%d %d\n&quot;, point.x, point.y); // 디버깅 상황에서 출력

        Invalidate();
    }

    CView::OnMouseMove(nFlags, point);
}


void CMouseMsgView::OnLButtonUp(UINT nFlags, CPoint point)
{
    // TODO: 여기에 메시지 처리기 코드를 추가 및/또는 기본값을 호출합니다.
    m_bMouseDown = false;
    ReleaseCapture(); // 마우스 좌표를 따라다니는 것을 풀어줌

    CView::OnLButtonUp(nFlags, point);
}</code></pre>
]]></description>
        </item>
    </channel>
</rss>