블로그 이미지
인생의무한루프
인생에 무한루프.....

calendar

1 2 3 4
5 6 7 8 9 10 11
12 13 14 15 16 17 18
19 20 21 22 23 24 25
26 27 28 29 30 31

Notice

Tag

Recent Post

Archive

Recent Comment

Recent Trackback

2008. 12. 16. 11:39 Appication/VC++_Control

하이퍼 링크 컨트롤을 만들어보자. ( MFC Static 예제 )

본 예제에서도 이전처럼 새로운 클래스를 추가하거나 하는 작업들은 하지 않고, 모든 작업을 다이알로그에서 처리 가능하도록 하고자 한다.


위의 그림이 샘플 예제이며,
내부에 사용된 기능은 다음과 같다.

1. 폰트를 만들어 언더라인을 긋는다.
2. 하이퍼 링크 컨트롤 위에 마우스가 가면 손가락 모양으로 바뀐다.
3. 클릭하면 링크된 웹사이트가 뜬다.
4. 클릭이 끝나면 한번 클릭된 것으로 인식하고, 글자 색상을 바꾼다.

구현되는 기능은 일반적인 하이퍼 링크 컨트롤의 기능을 100% 지원한다.
단, 툴팁도 추가할 수 있지만.. 현재 강좌 범위를 넘어가므로 나중을 기약하며 생략한다.

준비해야할 것과 추가해야할 코딩..
1. 먼저 폼에 스태틱 컨트롤 중에 Text 컨트롤을 하나 올리고, IDC_STATIC_1 로 설정한다.
2. 컨트롤의 속성중에 Styles 탭에서 Notify를 첵크한다. (중요하다.)
3. 다이알로그의 헤더 파일에 CFont m_font; 멤버를 하나 추가한다.
4. 다이알로그의 헤처 파일에 BOOL m_m_clicked; 멤버를 추가한다.

BOOL CSssDlg::OnInitDialog()
{
    CDialog::OnInitDialog();
   
    // 밑줄이 쫘악 그어진 폰트를 하나 만든다.
    LOGFONT log;
    GetFont()->GetLogFont(&log);
    log.lfUnderline = TRUE;
    m_font.CreateFontIndirect(&log);

    // 만들어진 폰트를 스태틱 컨트롤에 적용한다.
    GetDlgItem(IDC_STATIC_1)->SetFont(&m_font);

    return TRUE;  // return TRUE unless you set the focus to a control
    // EXCEPTION: OCX Property Pages should return FALSE
}

HBRUSH CSssDlg::OnCtlColor(CDC* pDC, CWnd* pWnd, UINT nCtlColor)
{
    HBRUSH hbr = CDialog::OnCtlColor(pDC, pWnd, nCtlColor);
   
    switch(nCtlColor)
    {
    case CTLCOLOR_STATIC:
        {
            if(pWnd->GetDlgCtrlID() == IDC_STATIC_1)
            {
                // 클릭 한적이 없으면 파랑색으로...
                if(m_clicked == FALSE)
                    pDC->SetTextColor(RGB(0, 0, 255));
                // 한번 클릭하고 나면 보라색 비끄무리하게 바꾼다.
                else
                    pDC->SetTextColor(RGB(255, 100, 100));
               
                // 기왕 하는거 배경은 투명한 형태로 계속 유지하자.. --;
                pDC->SetBkMode(TRANSPARENT);
                return (HBRUSH)GetStockObject(NULL_BRUSH);;
            }
        }
    }
    // TODO: Return a different brush if the default is not desired
    return hbr; 
}

여기 까지는 기존에 강좌에 나온것과 별반 다른작업이 없다. 다음 2가지 과정을 거치고 나면
하이퍼링크 컨트롤로 변신한다. ^^;

클래스 위저드를 열어 WM_SETCURSOR 이벤트를 추가한다.

그러고 나면 다음과 같은 코드가 추가된다.

BOOL CSssDlg::OnSetCursor(CWnd* pWnd, UINT nHitTest, UINT message)
{
   
return CDialog::OnSetCursor(pWnd, nHitTest, message);
}
간단하게 WM_SETCURSOR 이벤트에 대하여 설명해 보면, 다이알로그 위에서 마우스가 움직이는 동안 필요한 커서를 제어할 수 있도록 기능을 제공하는 것이다.
일단 코드를 다음과 같이 변경한다.
BOOL CSssDlg::OnSetCursor(CWnd* pWnd, UINT nHitTest, UINT message)
{
    CPoint pt;  
// 마우스 커서 위치를 저장할 객체
    CRect rc;   // 스태틱 컨트롤의 위치를 저장할 객체.

    // 마우스 커서의 위치를 찾아온다.
    GetCursorPos(&pt);
    // 스태틱 컨트롤의 위치를 찾아온다.
    GetDlgItem(IDC_STATIC_1)->GetWindowRect(rc);

    // 만약 마우스가 스태틱 컨트롤 위에 와있으면..
    if(rc.PtInRect(pt))
    {
        // IDC_HAND라는 스탠다드 커서를 읽어와서 커서를 변경시킨다.
        SetCursor(AfxGetApp()->LoadStandardCursor(MAKEINTRESOURCE(IDC_HAND)));

        // 꼭 리턴을 해주어야하는데, 이로써 화면에 바뀐커서가 적용된다.
        // 리턴 해주지 않으면 아무리 커서를 바꾸어도 전혀 변경이 없다.
        // 아래 return CDialog::OnSetCursor(pWnd, nHitTest, message); 에서 커서를
        // 원상 복구 시켜버리기 때문이다.
        return TRUE;
    }
 
 return CDialog::OnSetCursor(pWnd, nHitTest, message);
}

이제 마지막 하나의 기능이 남아있다.
스태틱 컨트롤을 마우스로 클릭하고 나면, 그걸 인식하여 웹페이지를 열어 주어야한다.
아까전에 속성창에서 Notify를 첵크하고 하였던 것이 기억날것이다. 만약 이 속성을 주지 않는다면
아무리 마우스를 컨트롤에 놓고 꼭, 꼭 찍어도 아래의 함수는 동작하지 않는다.

클래스 위저드를 열어서 IDC_STATIC_1의 BN_CLICKED 이벤트를 추가한다.

그러면 해당 이벤트의 핸들러가 추가된다.

그리고 코드를 다음과 같이 입력하면 된다.
void CSssDlg::OnStatic1()
{
    m_clicked = TRUE;
    GetDlgItem(IDC_STATIC_1)->Invalidate();
    ShellExecute(m_hWnd, "open", "http://crowback.tistory.com", NULL, NULL, SW_SHOW);
}

여기서 유용한 함수중에 하나가 ShellExecute라는 함수인데.. 외부 프로그램을 실행시킬때 주로
사용하는 기능이다.

설명은 길지만 전체 추가한 라인수는 대략 30라인 정도밖에는 되지않는 아주 간단한 코드이다.
이렇게 하여 하이퍼링크 하나를 넣기 위하여 새로운 클래스를 추가하는 번거로움을 막을 수 있다.




Posted by 까막백(홈페이지 이동)
posted by 인생의무한루프
2008. 12. 16. 11:37 Appication/VC++_Control

글자 배경 바꾸기 2 ( MFC Static 예제 )

아래 그림을 보면 배경을 다양한 형태로 처리할 수 있음을 알수 있다.
사실상 저렇게 쓰는 경우는 별반 없지만... UI 작업을 하다보면
어떤 정신 세계가 독특한 커스터머나 디자이너를 만날지 모른다..


화면을 보면 무엇을 설명하고자 하는지 쉽게 이해할 수 있을 것이다.

스태틱 컨트롤의 배경 전체 색상을 바꾸어 주기위해서는 저 영역을 먼가로 칠해주어야한다.
MFC에서 먼가 영역을 칠할 때 필요한 객체는 CGdiObject를 상속받은 놈 중에 CBrush 라고 하는
일종의 빗자루? 붓? 비끄무리한 객체가 있다.

우선 헤더에 CBrush m_brush; 라고 객체를 하나 선언한다.
BOOL CSssDlg::OnInitDialog()
{
    CDialog::OnInitDialog();
   
    // 브러쉬 객체를 녹색으로 생성한다.
    m_brush.CreateSolidBrush(RGB(0, 255, 0));

    return TRUE; // return TRUE unless you set the focus to a control
    // EXCEPTION: OCX Property Pages should return FALSE
}

그리고, 지금까지와 마찬가지로.. WM_CTLCOLOR 이벤트 핸들러를 추가한후
다음과 같이 코드를 수정한다.

HBRUSH CSssDlg::OnCtlColor(CDC* pDC, CWnd* pWnd, UINT nCtlColor)
{
    HBRUSH hbr = CDialog::OnCtlColor(pDC, pWnd, nCtlColor);
   
    switch(nCtlColor)
    {
    case CTLCOLOR_STATIC:
        {
            pDC->SetTextColor(RGB(255, 0, 0));
           
            if(pWnd->GetDlgCtrlID() == IDC_STATIC_1)
                pDC->SetBkColor(RGB(0, 255, 0));
            else if(pWnd->GetDlgCtrlID() == IDC_STATIC_3)
                // 앙? 그냥 브러쉬를 리턴하면 끝이냐?
                // 그렇다 그냥은 디폴트 브러쉬가 날라가게 되는데..
                // 여기에 먼가 특별한 브러쉬를 만들어 리턴하면 그게 그 컨트롤의
                // 배경에 영향을 미치게 된다.
                // 다양한 브러쉬를 만들어 리턴해보자 ^^;
                return m_brush;
            else if(pWnd->GetDlgCtrlID() == IDC_STATIC_2)
            {
                pDC->SetBkColor(RGB(0, 255, 0));
                return m_brush;
            }
        }
    }
    // TODO: Return a different brush if the default is not desired
    return hbr;
   
}




---------------------------------------------------------------------------------
이 부분을 진행하다 보니, 만약 패턴 브러쉬를 넣었을 경우는 어떻게 될까? 라는
생각이 들어서 별도로 진행해 보았다.

이 그림은 위의 소스 일부를 수정하여, 변경해 본 것으로.. Hatch 브러쉬를 이용하여
배경을 칠해본것이다. 자? 두번째를 어떻게 처리할 수 있을까?

BOOL CSssDlg::OnInitDialog()
{
    CDialog::OnInitDialog();
   
    m_brush.CreateHatchBrush(HS_DIAGCROSS, RGB(0, 255, 0));
   
    return TRUE;  // return TRUE unless you set the focus to a control
    // EXCEPTION: OCX Property Pages should return FALSE
}


HBRUSH CSssDlg::OnCtlColor(CDC* pDC, CWnd* pWnd, UINT nCtlColor)
{
    HBRUSH hbr = CDialog::OnCtlColor(pDC, pWnd, nCtlColor);
   
    switch(nCtlColor)
    {
    case CTLCOLOR_STATIC:
        {
            pDC->SetTextColor(RGB(255, 0, 0));
           
            if(pWnd->GetDlgCtrlID() == IDC_STATIC_1)
                pDC->SetBkColor(RGB(0, 255, 0));
            else if(pWnd->GetDlgCtrlID() == IDC_STATIC_3)
                return m_brush;
            else if(pWnd->GetDlgCtrlID() == IDC_STATIC_2)
            {
                // ???
                // 한번 직접 구현해 보자.
                // 결과물은 아래의 첨부파일에 포함되어 있다.

            }
        }
    }
    // TODO: Return a different brush if the default is not desired
    return hbr;
   
}




Posted by 까막백(홈페이지 이동)
posted by 인생의무한루프
2008. 12. 16. 11:36 Appication/VC++_Control

이미지 동적 로딩 ( MFC Static 예제 )

스태틱 컨트롤을 이미지 형태로 사용할 경우 보통은 리소스에 있는 이미지를 연결시킨다.


왼쪽은 리소스 편집기에서 정적으로 이미지를 연결시킨 픽처 컨트롤이고,
오른쪽은 속성을 비트맵으로 설정해 놓고, 아무런 작업도 진행하지 않은 경우이다.

그렇다면 파일에서 비트맵을 로딩하여 필요할 때마다 바꾸려면 어떤 과정을 거쳐야할까?

아래는 디스크에 있는 파일을 읽어 들여서 오른족에 보이는 컨트롤에 동적 로딩한 화면이다.


복잡한 과정은 전혀 필요없다.

BOOL CSssDlg::OnInitDialog()
{
    CDialog::OnInitDialog();
   
    // 파일에서 이미지를 비트맵 타입으로 읽어온다.
    // 현재는 커렌트 경로에 존재하므로 전체 경로를 넣지 않았지만.
    // 실행파일과 다른 경로에 존재한다면 절대 경로를 넣어야한다.
    // 전달되는 인자값은 MSDN에 자세히 설명이 나와있다.
    HANDLE h = ::LoadImage(AfxGetInstanceHandle(), "image_file.bmp", IMAGE_BITMAP, 0, 0, LR_LOADFROMFILE);

    // 화면의 픽처 컨트롤을 임시로 CStatic 컨트롤로 받아들인다.
    CStatic* pStatic = (CStatic*)GetDlgItem(IDC_STATIC_FILE);

    // 이미지 핸들과 스태틱 컨트롤이 제대로 값을 가지고 있다면
    if(h && pStatic)
        // 컨트롤에 비트맵을 연결시킨다.
        pStatic->SetBitmap((HBITMAP)h);

   
    return TRUE; // return TRUE unless you set the focus to a control
    // EXCEPTION: OCX Property Pages should return FALSE
}

아이콘일 경우도 위의 과정에서 필요한 형태만 변경한다면 아주 쉬울것이다.

참고. 만약 이미 비트맵이 로딩되어 있다면.. GetBitmap()으로 비트맵 핸들을 받은 후에
그 핸들을 CloseHandle()을 이용하여 해제해주고, 새로이 SetBitmap()을 해주어야 한다.

이렇게 생성하거나 할당한 리소스를 필요할 때 해제해 주지 않으면 나중에 [리소스가 부족합니다.]
라는 엉뚱한 메시지를 볼 수 있을것이다.




Posted by 까막백(홈페이지 이동)


posted by 인생의무한루프
2008. 12. 16. 11:33 Appication/VC++_Control

Text 뒤에 비트맵 깔기 ( MFC Static 예제 )

Picture 컨트롤에 이미지를 넣는 것은 쉬운일이다.
컨트롤 자체가 그러하도록 설계되었기 때문이지만, 이 또한 글자를 제대로 표현할 수 없다.
그렇다면 이미지에 글자를 그려 넣을 것인가?

기존에 Text 의 배경을 투명하게 하고, 색상을 넣을 수 있다면 이미지도 넣을 수 있지 않을까?
답은 그렇다이다.

MFC에서 제공해주는 많은 객체중에 CBrush는 상당히 잘 꾸며진 객체이다.
그중에 관심을 가져볼만한것이 Hatch와 Partten 기능이다.
해치는 제공해준 패턴만을 그려주지만, 패턴기능은 사용자가 비트맵을 제공함으로써
배경을 원하는 형태로 그릴 수 있도록 해준다.

아래는 비주얼 스튜디오에서 리소스 편집창의 일부를 캡쳐한 화면이다.


저 배경에 아래의 그림을 깔아보자 ^^;

어디서 많이본 그림인데??
윈도우즈에서 기본으로 제공해주는 커피잔.bmp이다 저걸 컨트롤의 배경으로 사용할 것이다.

아래의 그림은 그걸 구현해 놓은 실행화면이다.

위의 그림은 Text 컨트롤(스태틱에서 문자열만을 제공하도록 특화됨)의 배경에 비트맵을 패턴으로
깔은 것이다.
하나의 그림을 전체 배경으로 넣으려면 그림 크기를 컨트롤 크기와 동일하게 맞추면 된다.

지금까지 스태틱 컨트롤 강좌를 살펴보면 저 기능을 구현하는 것은 아주 쉽다.
1. CBitmap 객체를 선언한 후 커피잔.bmp를 로딩한다.
2. CBrush 객체를 선언한 후 패턴브러쉬로 생성하고 저 비트맵을 설정해준다.
3. 기존의 강좌에서 나온 배경에 색칠하기 기능을 이용하여 그 브러쉬를 리턴해준다.
끝~

BOOL CSssDlg::OnInitDialog()
{
    CDialog::OnInitDialog();
  
    bm.LoadBitmap(IDB_BITMAP3);
    brh.CreatePatternBrush(&bm);
    return TRUE;  // return TRUE unless you set the focus to a control
    // EXCEPTION: OCX Property Pages should return FALSE
}

HBRUSH CSssDlg::OnCtlColor(CDC* pDC, CWnd* pWnd, UINT nCtlColor)
{
    HBRUSH hbr = CDialog::OnCtlColor(pDC, pWnd, nCtlColor);
   
    switch(nCtlColor)
    {
    case CTLCOLOR_STATIC:
        {
            pDC->SetTextColor(RGB(255, 255, 0));
            pDC->SetBkMode(TRANSPARENT);
            return brh;
        }
    }
    return hbr;
}




저 형태로 모든 코드가 마무리되었다.
지금까지 스태틱 컨트롤에 대한 기본적인 내용을 다루었으며, 저러한 기능을 모아
클래스로 생성해 둔다면 나중에 편하게 사용할 수 있을 것이다.
이것이 바로 C로는 가져보기 힘든, C++만의 장점이다.

리소스 편집창에는
그룹박스,  버튼이 다음 순서로 나오지만..
MFC를 다루는 대부분의 서적에서 다루는 내용만으로 사용에 전혀 무리가 없을 것이다.

그룹박스 투명화는 지금까지의 방법을 사용하면 테두리 사각형에 어색하게 찍힌 글자가 나오고
버튼 자체는 상속받아 이러저러한 기능을 구현하지 않으면 부모윈도우에서 처리해줄 일이 거의 없다.

다음으로는 버튼의 기능중에 특화된 첵크박스와 라디오 버튼을 함께 다루어 보겠습니다.
첵크 박스와 라디오 버튼도 CButton의 일부이지만 특화된 만큼 따로 다룰 것입니다.


Posted by 까막백(홈페이지 이동)
posted by 인생의무한루프
2008. 12. 15. 23:12 Appication/VC++_Control

에디트 컨트롤 시작하기. ( MFC CEdit 예제 )

의미.
지금 글을 보여주는 것과 같이 사용자로 부터, 어떠한 글을 입력받거나 혹은 입력된 글을 보여주거나
하는 기능을 제공한다.

기본기능.
1. 글을입력한다.
2. 복사-잘라내기-붙히기 등의 기본 기능과 메뉴를 제공한다.
3. 저장된 글을 불러와 편집가능하도록 제공되거나 읽기 전용으로 사용할 수 있다.


워크스페이스에서 리소스 편집창을 열면 오른쪽에 동그라미 처진 것이 에디트 컨트롤이다.


다이알로그에 에디트 컨트롤을 올리기 위해서는 드래그&드랍을 이용하거나, 툴바에서 에디트 컨트롤을 클릭하고, 다시 다이알로그의 적당한 위치에서 클릭하면 그 위치에 에디트 컨트롤이 생성된다.
위의 그림은 대표적인 4가지 속성의 에디트 컨트롤을 보여준다.
1. 일반적인 상태
2. Disable 된 상태
3. Password 입력 상태
4. 읽기 전용 상태.
그 밖의 여러가지 상태가 있지만 보통 기본적으로 저런 형태로 가장 많이 사용된다.



그렇다면 저 에디트 컨트롤은 어떠 어떠한 속성값을 가지고 있을까?
에디트 컨트롤을 선택한 다음 Alt+Enter를 누르거나, 오른쪽 마우스로 메뉴를 띄운 후 프로퍼티를 선택하자

1. ID - 개별 컨트롤을 구별하는 하나의 리소스 창에서 유일하게 구분되어지는 키 값.
    (다이알로그 몇개 있을 때, 각각의 다이알로그 마다 IDC_EDIT1을 가질 수 있다.)
2. Visible - 초기에 컨트롤이 자동으로 사용자 눈에 보이게 한다.(당연히 첵크 박스를 없애면 않보인다.)
3. Group - 그룹 속성으로 나중에 그룹박스 컨트롤편에서 다루게 될것이다.
4. Help ID - 도움말 기능을 추가하게되면 해당 아이디를 도움말의 구분 키로 사용하게 된다.
5. Disable - 초기에 컨트롤이 사용 불가능하게 된다.
6. Tab Stop - 다이알로그 위에 올려진 콤포넌트는 TAB(shift+TAB)키를 이용하여 전환이 가능하다.
   (이걸 꺼 놓으면 탭으로의 이동이 불가능하고 사용자가 직접 클릭해야한다.)


스타일 페이지는 말 그대로 에디트 컨트롤의 스타일을 변경할 수있도록 해준다.

1. Align Text - 말 그대로 문자열이 left, center, right로 정렬되어 보여진다.
2. Multiline - 쓰여진 문자열이 화면 폭을 넘어갈때 여러줄로 보여줄지를 결정한다.
3. Number - 말그대로 숫자만 입력할 수 있도록 설정된다.
4. Horizontal Scroll - 수평 스크롤 바를 보여준다.
5. Auto HScroll - 글자가 화면너비을 넘어갈 경우 자동으로 스크롤바를 활성화 하여 스크롤 가능하게 한다.
6. Vertical Scroll - 수직 스크롤 바를 보여준다.
7. Auto VScroll - 글자가 화면폭을 넘어갈 경우 자동으로 스크롤바를 활성화 하여 스크롤 가능하게 한다.
8. Password -  글자를 입력하면 **** 와 같이 보여주도록 하여 주요글자가 시작적으로 노출되지 안도록한다.
9. No hide selection - 에디트 컨트롤에서 문자열을 선택하였을 경우, 다른 윈도우가 활성화 되면 선택하여 표시해 놓은 마크가 보여지지 않게 된다. 물론 다시 창을 활성화 하면 보여지게 되지만, 이 옵션을 켜 놓으면 항상 언제나 선택한 드래그 영역을 볼 수있다.
10. OEM Convert - 국가 설정에 맞도록 자동으로 문자열 타입을 변환(문자열 종류가 여러가지다)
11. Want Return -  컨트롤 내부에서 Enter키를 이용하여 줄바꿈을 할 수 있도록 지원한다.
12. Border - 컨트롤에 외곽 검은색 그림자 테두리를 보여준다.
13. Uppercase - 말 그대로 입력된 모든 글자를 대문자로 보여준다(실제 입력된 글자체는 그대로다.)
14. Lowercase - 입력된 글자를 모두 소문자로 보여준다.
15. read-only - 이미 저장된 내용을 보고 선택하고 복사할 수는 있지만 편집할 수는 없다.


요건 확장 스타일이라는 건데.. 나중에 알게 되겠지만 보통 WS_EX_...로 시작되는 넘들이다.
1. Client edge - 컨트롤의 클라이언트 영역, 즉 내부영역에 그림자 외곽 박스를 그린다.
2. Static edge - 1번과 비슷하지만 왼쪽과 상단부의 그림자만 그린다.
3. Modal Frame - 다얄로그의 외곽처럼 툭 튀어나오게 그린다.
4. Transparent - 배경을 그리지 않는다.
5. Accept files - 파일을 드래그 하여 놓았을 때, 그 정보를 인지할수 있다.
6. Right aligned text - 입력한 글자가 오른쪽에 정렬되어 보여진다.
7. Right-to-left reading order - 외국에는 입력을 한국과 다르게 하는 나라 들이 있다. 그리하여 글자를 입력하면 오른쪽부터 왼쪽으로 보여지며 입력하게 된다.
8. left scroll bar - 수직 스크롤바가 생길 때 왼쪽에 생기도록 한다.

이상으로 아주 간단하게 나마, 윈도우 폼에서 사용되는 에디트 컨트롤의 기본 속성에 대하여 살펴보았다.
다음에 시간이 되면 간단한 활용부터 응용까지 쭈욱 한번 달려보자.

Posted by 까막백(홈페이지 이동)
posted by 인생의무한루프
prev 1 ··· 4 5 6 7 8 9 next