<이탤릭체 텍스트를 출력하려면>

 트루타입이나 GDI 출력 글꼴을 이용하면 회전한 텍스트의 출력이 가능하다고 하던데, 어떻게 하면 되는지요.  

 물론 가능합니다. 어떤 하드웨어 장치는 회전하는 래스터 글꼴을 지원하기도 합니다.
  하드웨어가 추가적인 문자 회전 기능을 지원하는지 확인하려면 TEXTCAP 파라미터를 전달해 CDC::GetDeviceCaps를 호출하면 됩니다. 단, 트루타입이나 GDI 출력 글꼴을 사용중이라면 GetDeviceCaps를 호출할 필요가 없습니다.
 LOGFONT 구조체의 ifEscapement 멤버로 텍스트의 기준선과 x축의 각을 결정할 수 있는데 이때 주의해야 할 점은 실제 숫자보다,정확히 10배를 크게 지정해야 한다는 것입니다. 가령 45도만큼 회전한 글꼴을 생성하려면 ifEscapement를 450으로 설정하면 됩니다.
 그리고 모든 글꼴이 현재 좌표 체계를 기준으로 같은 방향으로 기울이려면 ifClipPrecision 멤버의 CLIP_LH_ANGLES 비트를 설정해야 합니다. 이렇게 하지 않으면 부분적으로 글꼴이 반대 방향으로 회전할 것입니다.
 다음 코드는 15도로 기울어진 문자열을 출력하기 위해 14포인트의 Arial 글꼴을 사용한 예입니다.

    void CSampleleView::OnDraw(CDC* pDC) {
    // 창의 크기를 결정한다.
    CRect rcClient;
    GetClientRect(rcClient);
    // 문자열을 생성한다.
    CString str(_T("마소가 14주년을 맞이 합니다!"));
    //빨간색 텍스트를 출력한다.
    pDC->SetBkMode(TRANSPARENT);
    pDC->SetTextColor(RGB(255, 0, 0));
    CFont font; //글꼴 객체
    LONGFONT stFont; //글꼴 정의
    //변경되지 않을 글꼴 속성을 설정한다.
    memset(&stFont, 0, sizeof(LONFONT));
    stFont.lfHeight=MulPiv(14, -pDC->GetDeviceCaps(LOGPIXELSY), 72);
    stFont.lfWeight=FW_NORMAL;
    stFont.lfClipPrecision=CLIP_LH_ANGLES;
    strcpy(stFont.lfFaceName, "Arial");
    //15 회전한 텍스트를 출력한다.
    for(int nAngle=0; nAngle<3600; nAngle +=150) {
    //새로운 각을 지정한다.
    stFont.lfEscapement=nAngle;
    //글꼴을 생성하고 장치 컨텍스트로 선택한다.

    font.CreatFontIndirect(&stFont);
    CFont* pOldFont=pDC->SelectObject(&font);
    //텍스트를 출력한다.
    pDC->SelectObject(pOldFont);
    font.DeletObject();

 

 <CString 타입의 SQL 문장을 인자로 넘기려면>

 MFC 5.0으로 ODBC 프로그래밍을 하면서 SQLExecDirect 함수를 사용하려 합니다. CString 타입의 SQL 문장을 인자로 넘겨주려고 하는데 가능한지요. 제가 작성한 코드는 다음과 같습니다. 여기서 strSQL은 CString 타입으로 선언했습니다.  

 CString을 SQLExecDirect()의 인자로 바로 사용할 수는 없습니다. 대신 CString의 GetBuffer()를 이용해 포인터를 얻어 오면 됩니다. 여기서 한가지 유의할 점은 GetBuffer()가 새로운 메모리를 할당받아 그 포인터를 리턴하므로 사용하고 난 후에는 할당된 메모리를 해제해주는 ReleaseBuffer()를 반드시 호출해야 한다는 것입니다. 다음과 같이 코드를 수정하면 됩니다.

    HSTMT hstmt = NULL;
    CString strSQL = "select * from yeebw";
    unsigned char* pSQL =
        (unsigned char*)strSQL.GetBuffer(strSQL.GetLength() + 1);
    SQLExecDirect(hstmt, pSQL, SQL_NTS);
    strSQL.ReleaseBuffer();

 

<디렉토리 선택 다이얼로그 띄우기>

 MFC 5.0으로 프로그램을 만들던 중 디렉토리 선택 다이얼로그를 띄우는 함수가 필요하게 되었습니다. 어떤 함수를 쓰면 되는지, 그리고 실제적인 예를 보고 싶습니다.  

 디렉토리 선택 다이얼로그를 띄우려면 시스템 함수인 SHBrowseForFolder를 사용하면 됩니다. 이 함수는 인자로 BROWSEINFO 구조체 포인터를 받으며, shlobj.h에 다음과 같이 정의돼 있습니다.

    typedef struct _browseinfo {  
        HWND hwndOwner;
        LPCITEMIDLIST pidlRoot;
        LPSTR pszDisplayName;
        LPCSTR lpszTitle;
        UINT ulFlags;
        BFFCALLBACK lpfn;
        LPARAM lParam;
        int iImage;
    } BROWSEINFO, *PBROWSEINFO, *LPBROWSEINFO;

 이 구조체에 적당한 값을 채워서 SHBrowseForFolder()를 호출하면 디렉토리 선택 다이얼로그가 뜹니다. 선택한 디렉토리 패스는 HGetPathFromIDList()를 호출해서 얻을 수 있으며, 변수 tmp에는 선택한 디렉토리의 패스가 들어 있습니다. 다음을 참조하세요.

    LPITEMIDLIST pidlBrowse;
    LPSTR tmp[MAX_PATH];

    BROWSEINFO BRinfo;
    BRinfo.hwndOwner = hwnd; // 부모 윈도우의 핸들
    BRinfo.pidlRoot = NULL;
    BRinfo.pszDisplayName = tmp;
    BRinfo.lpszTitle = "디렉토리를 선택하세요";
    BRinfo.ulFlags = BIF_RETURNONLYFSDIRS;
    BRinfo.lpfn = NULL;
    BRinfo.lParam = 0;

    pidlBrowse = SHBrowseForFolder(&BRinfo); // 다이얼로그를 띄운다.
    if(pidlBrowse != NULL) {
        SHGetPathFromIDList(pidlBrowse, tmp); // 패스를 얻어온다.
    }
 

<항상 최상위 창을 유지하려면>

 MFC로 창이 활성화되지 않더라도 항상 위에 떠있는 애플리케이션을 만들려고 합니다.  

 모든 창 위에 최상위창(topmost window)을 띄우는 방법에는 두 가지가 있습니다. 창을 이미 생성했다면 창의 실행시 확장 스타일 비트로 WS_EX_TOPMOST를 지정하면 되며, 그렇지 않다면 CWnd::SetWindowPos를 호출한 후 데이터 멤버인 wndTopMost를 전달하면 됩니다. 스타일 비트가 설정돼 있는지 확인하려면 CWnd::GetExStyle을 불러 간단히 해결할 수 있습니다. 다음 코드를 참조하십시오.
      
    void ToggleTopMost(CWnd* pWnd) {
    if (pWnd->GetExStyle() & WS_EX_TOPMOST)
       pWnd->SetWindowPos(&wndNoTopMost, 0, 0, 0, 0
                              SWP_NOSIZE | SWP_NOMOVE);
    else
        pWnd->SetWindowPos(&wndTopMost, 0, 0, 0, 0
                               SAWP_NOSIZE | SWP_NOMOVE);
    }

 

<MDI 프로그램 시작시 뜨는 도큐먼트 없애기>

 MDI 프로그램에서 처음 실행시 꼭 등장하는 새 도큐먼트를 띄우지 않으려면 어떻게 하면 되나요.  

 자동으로 열리는 빈 윈도우를 없애는 방법은 의외로 간단합니다. 클래스 위저드로 생성한 소스중 xxxApp.CPP라는 파일에 CWinApp에서 상속받은 클래스가 들어 있는데, 이 멤버 함수중 InitInstance() 안에 다음 코드가 존재합니다.

    ParseCommandLine(comInfo);
    if( ProcessShellCommand(...))..

 이 두 줄 사이에 다음 코드를 추가하면 프로그램이 처음 실행될 때 쉘 명령(ShellCommand) 으로 새로운 파일을 만들라는 'FileNew' 명령행이 인자로 들어오게 됩니다(도큐먼트를 지정하지 않았을 때). 이 경우에만 FileNothing으로 바꿔주면 빈 도큐먼트를 만들지 않으며 당연히 뷰/프레임도 보이지 않습니다.

    if(cmdInfo.m_nShellCommand == CCommandLineInfo::FileNew )
         cmdInfo.m_nShellCommand = CCommandLineInfo::FileNothing;