MFC Tab 만들기

----------------------------------------------------------------------------------------------------------------------------------

MFC프로그램을 하다보면,

Tabcontrol을 만들어야 하는 경우가 생길 것이다.

그 탭컨트롤을 만드는 과정을 알아보자.

모든 프로그램은 Dialog based로 하는 것을 기준으로 한다.

 

우선 dialog based 프로젝트를 만든다.

다이어로그 베이스 프로젝트는 앞의 포스트에서 미리 설명을 하였다.

test라는 프로젝트 이름으로 만들었다.

만든 뒤에, TODO:…. 된 부분을 지우고,

그림에서 보듯 Toolbox에서 Tab Control을 드래그 해서 아래와 같이 화면에 붙여 넣어준다.

만약 Toolbox가 보이지 않는다면,

메뉴바의 view에서 toolbox를 찾을 수 있다.

 

 

이렇게 만들어진 Tab에 이름을 정해주자.

그림에서 보듯이 Add Variable을 클릭한다. (변수 추가)

새로 창이 뜨는데,

Access는 public, Variable type은 CTabCtrl인지를 확인하고,

Variable name에는 m_Tab이라고 적자. (대/소문자 구분을 하기 때문에 확실하게 적어야 된다.)

이제 Finish를 눌러주면 지금 만든 탭의 이름은 m_Tab가 된다.

 

이제는 프로그램 내용을 수정할 차례이다.

위의 그림처럼 CtestDlg.cpp 파일에서 OnInitDialog를 찾는다.

이 안의 내용을 수정할 것인데,

 

 

 

Code Snippet
  1. BOOL CtestDlg::OnInitDialog()
  2. {
  3.     CDialog::OnInitDialog();
  4.  
  5.     // Add "About..." menu item to system menu.
  6.  
  7.     // IDM_ABOUTBOX must be in the system command range.
  8.     ASSERT((IDM_ABOUTBOX & 0xFFF0) == IDM_ABOUTBOX);
  9.     ASSERT(IDM_ABOUTBOX < 0xF000);
  10.  
  11.     CMenu* pSysMenu = GetSystemMenu(FALSE);
  12.     if (pSysMenu != NULL)
  13.     {
  14.         BOOL bNameValid;
  15.         CString strAboutMenu;
  16.         bNameValid = strAboutMenu.LoadString(IDS_ABOUTBOX);
  17.         ASSERT(bNameValid);
  18.         if (!strAboutMenu.IsEmpty())
  19.         {
  20.             pSysMenu->AppendMenu(MF_SEPARATOR);
  21.             pSysMenu->AppendMenu(MF_STRING, IDM_ABOUTBOX, strAboutMenu);
  22.         }
  23.     }
  24.  
  25.     // Set the icon for this dialog.  The framework does this automatically
  26.     //  when the application's main window is not a dialog
  27.     SetIcon(m_hIcon, TRUE);            // Set big icon
  28.     SetIcon(m_hIcon, FALSE);        // Set small icon
  29.  
  30.     // TODO: Add extra initialization here
  31.  
  32.     CString    strOne = _T("First");
  33.     CString    strTwo = _T("Second");
  34.     CString    strThree = _T("Third");
  35.     m_Tab.InsertItem(1, strOne);
  36.     m_Tab.InsertItem(2, strTwo);
  37.     m_Tab.InsertItem(3, strThree);
  38.  
  39.     return TRUE;  // return TRUE  unless you set the focus to a control
  40. }

그 안의 내용에서 위와 같이 추가를 한다.

추가 된 내용은 32번째 줄에서 37번째 줄인데,

32 - 34번째 줄은 탭컨트롤에서 탭의 제목으로 들어갈 내용 들이다.

35 - 37번재 줄은 몇 번째 탭에 어떤 이름이 들어갈 지에 대한 내용으로,

35번째 줄을 보면 (1, strOne)으로 되어있는데, 1번째 탭에 strOne에 들어있는 내용을 넣는 다는 말이다.

여기서 strOne에는 First라는 내용이 들어 있기 때문에

1번째 탭은 First라는 이름으로 들어간다.

여기까지 수정을 하고, 빌드를 해보자.

예상한 대로 1번째 탭의 이름은 First이고 나머지도 예상 대로 됬다.

이제 각각의 탭에 내용을 넣어줄 차례이다.

 

 

 

지금부터 하는 과정은 뒤에서 그만이라는 말이 나올때까지의 부분을 3번 반복해준다.

(탭이 3개일 경우에 3번으로 탭의 수에 맞춰서 해주면 된다.)

위의 그림처럼 Resource View를 클릭을 해서 Resource view를 열어주자.

Resource View의 화면이다.

여기서 오른쪽 버튼을 눌러서, 다이어로그를 추가해주자.

그러면 Dialog1이라는 다이어로그가 추가가 된 것을 볼 수있다.

이 다이어로그는 아까의 탭안에 들어갈 내용들을 넣어줄 다이어로그이다.

따라서 우리가 한 것처럼 탭이 3개가 있으면 3개의 다이어로그를 만들어 주어야 한다.

위의 그림처럼 IDD_Dialog1을 클릭한 뒤

메뉴의 view에서 Properties Window를 클릭해서 프로퍼티 창을 열어준다.

이러한 창을 볼 수 있는데, 여기서 ID를 자신이 원하는 ID로 바꾸어준다.

이 ID는 지금 새로 만드는 다이어로그의 이름으로서 나중에 탭컨트롤에서 쓸 것이다.

기본으로는 IDD_Dialog1으로 되어있을 것이다.

이 화면은 ID를 이미 바꾸어 놓은 것이다.

이 ID는 자신이 원하는 것도 괜찮지만, 우선은 똑같이 IDD_First로 해준다.

그런 뒤에 화면의 다이어로그를 클릭해준다.

그러면 프로퍼티 창이 바뀌는 것을 볼 수 있는데,

여기서 Border를 None으로,

Style을 Child로 바꾸어준다.

그러면 이 다이어로그가 바뀌는 것을 볼 수 있다.

border를 none으로 바꿈으로서 경계가 다 없어졌고,

style을 child로 바꿈으로서 다이어로그 안에 들어갈 수 있게 되었다.

 

이제 이 다이어로그의 구분을 해주기 위해,

static text를 추가해주자.

역시 tabcontrol처럼 드래그하면 된다.

막 드래그 한 상태이면 위의 그림처럼 선택이 되어있을 것이다.

이 상태에서 프로퍼티 윈도우를 보면 내용을 수정할 수 있다.

여기서 Caption을 수정해주면된다.

First라고 수정을 해주면,

바뀐 것을 알 수 있다.

이제 이 다이어로그에 이름을 붙여줄 차례이다.

다이어로그에서 오른쪽 버튼을 눌러서 Add Class를 눌러주고,

뜨는 창에서

그림과 같이 Class name을 정해준다.

여기선 CFirst로 정해주었다.

그리고 Base class 가 CDialog인지를 확인하고 finish를 눌러준다.

위에서부터 지금까지의 과정(새로운 다이어로그를 만들고 이름을 붙여주는 과정)을

3번 반복한다.

물론 각각의 이름을 다르게 해주어야 한다.

여기선 두번째, 세번째 다이어로그의 이름을 CSecond, CThird라고 해주었다.

여기까지의 과정이 완료가 되었다면 이제부터가 시작이다.

 

testDlg.h파일을 열어서 다음과 같이 수정한다.

Code Snippet
  1.  
  2. // testDlg.h : header file
  3. //
  4.  
  5. #pragma once
  6. #include "afxcmn.h"
  7. #include "First.h"
  8. #include "Second.h"
  9. #include "Third.h"
  10.  
  11.  
  12. // CtestDlg dialog
  13. class CtestDlg : public CDialog
  14. {
  15. // Construction
  16. public:
  17.     CtestDlg(CWnd* pParent = NULL);    // standard constructor
  18.  
  19. // Dialog Data
  20.     enum { IDD = IDD_TEST_DIALOG };
  21.     CFirst        m_First;
  22.     CSecond        m_Second;
  23.     CThird        m_Third;
  24.     CWnd*        m_pwndShow;
  25.  
  26.     protected:
  27.     virtual void DoDataExchange(CDataExchange* pDX);    // DDX/DDV support
  28.  
  29.  
  30. // Implementation
  31. protected:
  32.     HICON m_hIcon;
  33.  
  34.     // Generated message map functions
  35.     virtual BOOL OnInitDialog();
  36.     afx_msg void OnSysCommand(UINT nID, LPARAM lParam);
  37.     afx_msg void OnPaint();
  38.     afx_msg HCURSOR OnQueryDragIcon();
  39.     DECLARE_MESSAGE_MAP()
  40. public:
  41.     CTabCtrl m_Tab;
  42. };

위의 내용을 보면

7, 8, 9번째 줄에 방금 만든 헤더파일을 추가 시켜줬음을 알 수 있다.

또한, 21, 22, 23, 24번째 줄에도 내용이 추가 되었다.

각각의 다이어로그의 이름에 맞춰서 그 다이어로그를 제어할 수 있는 부분을 추가해주었다.

이제 다시 testDlg.cpp파일을 열어서

CtestDlg를 찾아서 아래와 같이 수정을 해준다.

5번째 줄만 수정을 해주었다.

Code Snippet
  1. CtestDlg::CtestDlg(CWnd* pParent /*=NULL*/)
  2.     : CDialog(CtestDlg::IDD, pParent)
  3. {
  4.     m_hIcon = AfxGetApp()->LoadIcon(IDR_MAINFRAME);
  5.     m_pwndShow = NULL;
  6. }

같은 파일(testDlg.cpp)에서

OnInitDialog에

Code Snippet
  1. // TODO: Add extra initialization here
  2.  
  3. CString    strOne = _T("First");
  4. CString    strTwo = _T("Second");
  5. CString    strThree = _T("Third");
  6. m_Tab.InsertItem(1, strOne);
  7. m_Tab.InsertItem(2, strTwo);
  8. m_Tab.InsertItem(3, strThree);
  9.  
  10. CRect Rect;
  11. m_Tab.GetClientRect(&Rect);
  12.  
  13. m_First.Create(IDD_First, &m_Tab);
  14. m_First.SetWindowPos(NULL, 5, 25,
  15.     Rect.Width() - 12, Rect.Height() - 33,
  16.     SWP_SHOWWINDOW | SWP_NOZORDER);
  17. m_pwndShow = &m_First;
  18.  
  19. m_Second.Create(IDD_Second, &m_Tab);
  20. m_Second.SetWindowPos(NULL, 5, 25,
  21.     Rect.Width() -12, Rect.Height() - 33,
  22.     SWP_NOZORDER);
  23.  
  24. m_Third.Create(IDD_Third, &m_Tab);
  25. m_Third.SetWindowPos(NULL, 5, 25,
  26.     Rect.Width() - 12, Rect.Height() - 33,
  27.     SWP_NOZORDER);
  28.  
  29. return TRUE;  // return TRUE  unless you set the focus to a control

아까 탭을 만들때 추가시켜준 부분 아래에 다음과 같이 추가를 해준다.

중요한 것은 16번째 줄의 내용은 한번만 추가해주는 것이다.

탭컨트롤을 만드는 것은 책에서 보고 따라한 것인데

아무생각없이 3번 복사했더니, 탭컨트롤이 똑바로 초기화가 안되어서

실행을 했을 때, 탭안의 내용이 바로 실행이 되어야 하는데,

다른 탭을 일일이 눌러주지 않으면 처음탭의 내용이 보이기만하고 실행이 안되는 경우가 생긴다.

 

다시 Resource view로 돌아와서,

그림에서 보이는 화면을 클릭해주고, (탭안을 클릭해야됨)

프로퍼티 창을 보면(위에 설명 해놨음)

이 화면에서 오른쪽의 번개마크를 누르면 아래와 같이 화면이 바뀌게 된다.

이 화면에서, 밑에서 두번째에 있는

TCN_SELCHANGE를 누르면 창이 뜨는데,

OnTcnSelchangeTab을 추가할 수 있게 된다.

추가를 하면 testDlg.cpp파일로 돌아오게 되는데,

Code Snippet
  1. void CtestDlg::OnTcnSelchangeTab1(NMHDR *pNMHDR, LRESULT *pResult)
  2. {
  3.     // TODO: Add your control notification handler code here
  4.     *pResult = 0;
  5. }

이런 것이 생긴 것을 볼 수 있다.

 

Code Snippet
  1. void CtestDlg::OnTcnSelchangeTab1(NMHDR *pNMHDR, LRESULT *pResult)
  2. {
  3.     // TODO: Add your control notification handler code here
  4.     if(m_pwndShow != NULL)
  5.     {
  6.         m_pwndShow->ShowWindow(SW_HIDE);
  7.         m_pwndShow = NULL;
  8.     }
  9.  
  10.     int nIndex = m_Tab.GetCurSel();
  11.     switch(nIndex)
  12.     {
  13.     case 0:
  14.         m_First.ShowWindow(SW_SHOW);
  15.         m_pwndShow = &m_First;
  16.         break;
  17.     case 1:
  18.         m_Second.ShowWindow(SW_SHOW);
  19.         m_pwndShow = &m_Second;
  20.         break;
  21.     case 2:
  22.         m_Third.ShowWindow(SW_SHOW);
  23.         m_pwndShow = &m_Third;
  24.         break;
  25.     }
  26.     *pResult = 0;
  27. }

위와 같이 수정을 해주면 탭컨트롤 추가가 끝이다.

이로서 완성이 되었다.

실행을 해보면,

위와 같이 잘 된 것을 볼 수 있다.^^


--------------------------------------------------------------------------------------------------------------------------------------------

<출처>

http://jaiyun.tistory.com/5 

------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------

자! 오늘부터 주식공부도 시작하려고합니다. HTS를 만들어노면 모해요 쓸줄을 모르는데 ㅋㅋ 그쵸? 그래서 오늘부터 주식 스터디할겁니다.

본 포스팅은 <바보스탁 산호님의 주식 바로보기>의 정리 및 독후감 형식으로 진행됩니다.


****************************************************

챕터 1. 캔들은 화장발이다. 속으면 안된다.

1. 캔들의 새로운 해석

2. 캔들의 시종가에 이런 비밀이 있다.

3. 상한가 위꼬리에 대한 고찰

4. 하한가 아래꼬리와 캔들 속 숨은 키포인트

5. 캔들아~ 분봉 종가선 차트의 내조를 받아라

****************************************************

- 캔들은 시가, 종가, 저가, 고가로 구성되어져 있습니다.

- 상한가가 오전에 치는게 좋을까요? 오후에 치는게 좋을까요?, 답은 오후입니다. 비교적 매수세가 강한 오전 중에 세력이 물량을 던져버리게 되면, 주가를 상승시킬 주체가 없어지기 때문에 주가는 힘없이 밀리게 됩니다. 이렇게 주가가 하락하게 되면 매물대에서 매수 가담했던 투자자나 저점 매수했던 투자자들 역시 수익실현이나 손절 등으로 매도세에 가담하게 되어 주가가 더 하락하기 때문에 오전이 상투가 되는 것입니다.


1. 캔들의 새로운 해석


2. 캔들의 시종가에 이런 비밀이 있다.

- 캔들의 시가는 자잘한 변수에 의해서 조금은 왜곡될 수 있습니다. 무조건 플러스가 중요한게 아니라 흐름이 중요합니다.

- 캔들에서 시가라는 의미는 하루 중에 가장 많은 체결이 일어난 곳일 수 있고, 매수 심리나 매도 심리가 어느 한쪽으로 쏠린 상황일 수도 있는 곳입니다.

- 시가 지지 여부는 아침 시작할 때의 심리가 그대로 이어져 있는가? 라는 질문만 파악해도 충분하다.

- 상한가의 종가 자리는 많은 거래량을 수반한 자리이다.

- 상한가의 자리를 지켜내기 위해서는 상한가에서 매도하는 물량을 받아내야 하는데 세력 중의 누군가가 그 물량을 다 받았기 때문에 상한가의 종가는 대량 거래가 일어날 수 밖에 없는 자리이다.

- 상한가의 종가를 지키고 익일 아침에 매수 흐름이 있을 때 물량을 다 팔아버린다.


3. 상한가 위꼬리에 대한 고찰

- 4개의 포인트로만 만들어지는 캔들로는 세부적인 흐름을 파악할 수 없다. 거래량에 따라서 단타로 갈지, 스윙으로갈지 결정해야한다.

- 매매를 할때에는 불분명한 느낌으로 해서는 안된다. 그 종목이 관심 종목인 명백한 이유가 있어야 하고 어느 자리에서 왜 매수할 것인지에 대한 기준을 가져야만 한다. 그렇기 때문에 매매 후에 복기를 해야하고 원인을 파악하여 발전이 있어야 한다.

- 오른쪽의 그림은 주식 가격 상승의 강한 복선이다.(둘다 상한가 위꼬리)

- 이처럼 캔들의 의미를 파악하는 것은 세력의 마음을 읽어내는 강력한 스킬이다.

- 캔들에 마우스를 올려보아야 한다. (거래가 터진 상한가의 위꼬리인지 아니면 일반적인 고점의 위꼬리인지 살피라는 의미)


4. 하한가의 아래꼬리와 캔들 속 숨은 키포인트

- 캔들 속 하한가의 아래꼬리나 하한가성 아래꼬리는 많은 투자자들을 손절시켰나? 하는 심리적 포인트를 가지고 있다.

- 매집 구간에서 많은 흔들기와 하한가의 공포를 조장하는데, 이때 투자자들은 손절하거나 수익시 매도하게 되는데 나중에는 보고 싶지도 않은 종목이 되게 된다. 세력은 이런 심리를 이용하여 물량을 성공적으로 매집하게 된다.

- 즉, 훌륭한 매집이라는 것은 일반 투자자가 떨어져 나갈 수 밖에 없는 구간이 있어야한다. (일반 투자자가 떨어져 나간 구간이 있는지 살펴보는게 중요하다.) 아래는 그 구간을 찾아내는 스킬이다.

- 음봉의 공포 : 음봉의 심리 상태는 대부분 매도 심리가 깔려있기 때문에, 그 음봉을 이용한 매수를 의심해야 한다.

- 라운드 피겨(주가가 5천원 1만원, 1만5천원 단위로 끊어져서 부딪히는 현상) : 이때 저항선을 돌파할때는 단번에 돌파하기 보다는 그곳의 매물대를 몇 차례 돌파를 시도하다가 돌파하게 된다. 

- 이러한 원리는 라운드 피겨 뿐만 아니라 많은 분들이 매도하고자 했던 저항대(이동편균선이나 기타 보조 지표들)도 역시 같은 원리이다. 그 이유는 저항대 역시도 많은 매물이 나오는 자리기 때문에 많은 체결이 일어난 자리가 될 것이기 때문이다. 저항이 지지로 바뀐다는 말의 근거값이 이와 같은 종가선 차트의 원리와 같은 것이다.

- 라운드 피겨는 매수 매도가 몰리는 구간이다.

- 이처럼 어떤 의미에서든지 많은 거래가 일어나는 곳은 캔들 속에 보이지 않는 가이드 라인이 되어 보이지 않는 지표가 있다. 이동평균선, 저항선, 매물대, 상한가의 종가, 긴 위꼬리 등이 모두 포함된다.

- 이를 확인하기 위해 캔들의 색상을 비우자


5. 캔들아~ 분봉 종가선 차트의 내조를 받아라

- 종가선 차트는 다른 표현으로 틱라인 차트라고 불리기도 한다.

- 분봉 차트와 차이점이라면 움직임을 봉으로 표현한 것이 아니라 선으로 표현한 것이다. 점들을 이어놓았기 때문에 좀더 기민하고 예리하게 움직임을 관찰할 수 있다.

- 틱라인 차트

- 주문 체결 1건을 하나의 점으로 나타내면 1틱

- 주문체결 3건을 하나의 점으로 나타내면 3틱 (시간과 무관)

- 분봉 종가선 차트

- 0.5분을 하나의 틱으로 나타내도 됨. (시간적 연속성)

- 시간은 좋은 캔들을 구별하기 위한 필수 요소이다.

- 상승하면서 물량을 받기 위해서는 충분한 시간도 고려되어야 한다.

- 좋은 양봉은 추가 상승할 여력이 있는 캔들이어야 한다.

- 그 양봉은 고점에서 세력이 많은 물량을 매도해서는 안될 것이며, 내일 비싸게 팔기 위해서 종가만 수직각으로 상승시켜 마감한 캔들이어서도 안될 것이다.

- 충분한 매집이 있는 양봉이어야 오래간다.

- 좋은 양봉은 물량을 뺏고 싶어서 안달 난 캔들이 좋은 양봉이다.

- 물량을 뻇고 싶은 곳에서 물량을 뺏는 것이 중요하다.

- 음봉의 종가선 차트는 어떨까?

- 세력이 물량을 처분할 때 물량을 떄리기만하면 누가 받아줄까?

- 고가권에서는 급락과 급등을 반복하면서 주가가 크게 요동을 치면 그것은 팔고 있을 가능성이 높습니다. 이것은 물량을 팔아 치울 때 어쩔 수 없이 나타나는 현상입니다.

- 보유 중인 투자자를 매도할 수 밖에 없는 상황으로 유도를 하여야 하며 대기 매수세가 이 종목에 진입하기 싫은 상황을 만들어서 매도하는 사람들의 물량을 모두 걷어들이고 매수세 유입을 막아 매집으로 활용했다면 그것은 좋은 음봉입니다.

----------------------------------------------------------------------------------------------------------------------------------------------------------------

<나의 적용>


----------------------------------------------------------------------------------------------------------------------------------------------------------------

<참고서적>

- 바보스탁 산호님의 주식 바로보기 <정성훈 지음>

버전처리 오류 해결하기

------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------

 이번엔, 버전 처리 오류를 해결하는 방법을 알아 볼거에요. 그 과정은 가이드 북에 잘 나와 있는데요, 제가 느낌점을 좀더 추가해볼꼐요.


 위와 같이 버전처리 창이 뜰 경우, 처리 과정은 다음과 같습니다.

1. 현재 진행중인 프로젝트를 완전 종료해버린다.  (비주얼스튜디오)

2. KOA스튜디오를 킨다.

3. 로그인한다.

4. 위와 같은 버전처리 창이 뜨면, KOA 스튜디오를 종료하고, 확인을 누른다.

5. 성공적으로 해결 ㅎㅎ


모두들 성공하는 주식투자 하시기 바랄꼐요~


+ Recent posts