<다이얼로그에 프린트 기능을 넣으려면>

 다이얼로그 기반의 애플리케이션이나 뷰/도큐먼트 구조의 애플리케이션에서 기본으로 제공되는 프린트 기능을 사용하지 않고, 다이얼로그 안에 프린트 기능을 구현하고 싶습니다.  

 MFC는 기본적으로 OnDraw()를 작성하면 도큐먼트를 프린트할 수 있습니다. 그리고 도큐먼트/뷰 구조에서는 프린트 미리 보기 기능을 포함해 몇 가지 유용한 프린트 관련 기능도 제공합니다. 그러나 기존의 프린트 기능을 이용하지 않고 다이얼로그에서 프린트하고자 할 경우에는 먼저 프린트에 사용할 폰트를 생성하고 (만일 그림을 프린트하고자 한다면 필요없다) 프린터의 DC 핸들을 얻기 위해 CPrintDialog 객체를 생성합니다. 그런 다음 프린트 다이얼로그를 띄우거나 GetDefaults()를 호출해 프린터 DC의 핸들을 얻습니다. 이렇게 얻은 핸들을 이용해 CDC 객체를 생성하고 CDC의 멤버 함수인 StartDoc(), StartPage()를 호출한 다음 마지막으로 TextOut()이나 BitBlt() 등의 함수를 사용해 프린트합니다. 다음의 예제 코드를 참고하세요.

        // ...
        CFont font;
        font.CreateFont(-200,0,0,0,100,FALSE,FALSE,
            0,ANSI_CHARSET,OUT_DEFAULT_PRECIS,
            CLIP_DEFAULT_PRECIS,DEFAULT_QUALITY,
            NULL,"굴림");
        CPrintDialog dlg(FALSE, PD_ALLPAGES | PD_RETURNDC, NULL);
        dlg.DoModal();
        //dlg.GetDefaults( );
        if(!dlg.m_pd.hDC){
            MessageBox("유효하지 않은 프린터 핸들입니다!");
            font.DeleteObject();
            return;
        }
        CDC * pDC = new CDC;
        pDC->Attach(dlg.m_pd.hDC);
        pDC->StartDoc("MyDocument");
        pDC->StartPage();
        CFont * pFont;
        pFont = pDC->SelectObject(&font);
        pDC->TextOut(10,10,"마소 독자 여러분 안녕하세요?");
        pDC->SelectObject(pFont);
        pDC->EndPage();
        pDC->EndDoc();
        pDC->DeleteDC();
        pDC->Detach();
        delete pDC;
        font.DeleteObject();
        // ...

 

<체크 리스트박스를 템플릿에 올리기>

 MFC 클래스 중 CCheckListBox를 이용해 다이얼로그 템플릿에 체크 리스트박스를 올려놓고 싶습니다.  

 CCheckListBox는 CListBox 클래스로부터 상속받은 클래스로 다이얼로그 에디터의 컨트롤 팔레트에는 보이지 않지만, 리스트박스를 올려놓은 후 몇 가지만 코딩해 주면 리스트박스를 체크 리스트박스로 바꿀 수 있습니다.
 이때 주의할 사항은 <화면 1>과 같이 옵션을 설정해야 한다는 것입니다. 리스트박스의 속성 다이얼로그에서 Owner draw를 'Fixed'로 선택한 다음 Has string에 체크합니다. 그런 후에 클래스 위저드를 이용해 다이얼로그 클래스를 만들어 주고 컨트롤과 맵핑되는 변수를 만들어 줍니다. 그리고 CListBox를 선택하면 됩니다(<화면 2>). 클래스 위저드가 만들어 준 헤더 파일을 보면 다음과 같은 코드를 발견할 수 있습니다.

    // dialog Data
        //{{AFX_DATA(CTestDlg)
        enum { IDD = IDD_DIALOG1 };
        CListBox    m_list;
        //}}AFX_DATA

    이것을 다음과 같이 고쳐 줍니다.

    // dialog Data
        //{{AFX_DATA(CTestDlg)
        enum { IDD = IDD_DIALOG1 };
        CCheckListBox    m_list;
        //}}AFX_DATA

    그런 후 AddString() 등의 함수를 이용해 리스트박스를 채워 넣으면 됩니다.

                                        < 화면 1 >

                                < 화면 2 >

<전체 화면 보기 옵션 만들기>  

 개발툴이나 그래픽 프로그램을 보면 전체 화면 보기라는 옵션이 있고, 선택하면 프로그램 크기가 스크린과 동일해지며 캡션바가 없어집니다. 이런 기능을 어떻게 구현하는지 알고 싶습니다.

 가까운 실례로 전체 화면 보기 기능을 마이크로소프트의 비주얼 C++ 개발환경에서 볼 수 있습니다. 화면을 최대한 이용해 코드를 편집할 수 있는 이 기능은 코드를 편집하는 데 불필요한 윈도우 요소를 제거함으로써 편집의 편의를 돕습니다.
 구현 방법은 윈도우에는 여러 가지 스타일이 존재한다는 것을 착안한다면 매우 간단합니다. 즉, 사용자가 전체 화면 보기 명령을 선택했을 때 윈도우 스타일을 바꿔준 후 윈도우를 화면의 크기에 맞게 조정해 주면 됩니다.

 

<메인프레임이 차지하는 행의 수를 찾으려면>

 최상위 메뉴인 메인프레임 메뉴가 차지하는 행의 수를 계산하고 싶습니다.

 뺄셈과 나눗셈만으로 이 문제를 간단히 해결할 수 있습니다. 먼저 메인프레임과 클라이언트 영역의 높이를 계산합니다. 그 다음 프레임의 높이에서 클라이언트 영역의 높이, 프레임의 테두리, 캡션을 뺀 후 마지막으로 메뉴바의 높이로 나누면 됩니다.

    int CMainFrame::GetMenuRows() const {
    CRect rcFrame, rcClient;
    GetWindowRect(rcFrame);
    GetClientRect(rcClient);

    return(rcFrame.Height() - rcClient.Height() -
          ::GetSystemMetrics(SM_CYCAPTION) -
          (::GetSystemMetrics(SM_CYFRAME)*2))/
          ::GetSystemMetrics(SM_CYMENU);