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


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

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라인 정도밖에는 되지않는 아주 간단한 코드이다.
이렇게 하여 하이퍼링크 하나를 넣기 위하여 새로운 클래스를 추가하는 번거로움을 막을 수 있다.

29.zip
0.04MB

 

+ Recent posts