더북(TheBook)

4.2.5 클립보드 지원(복사 및 붙여넣기)

클립보드를 이용하면 다른 프로그램과 자료를 교환하기가 용이해진다. IppDib 클래스에서는 비트맵을 클립보드로 복사하는 기능과 클립보드에 있는 비트맵을 가져와서 DIB 객체를 만드는 기능을 제공한다. 클립보드 관련 멤버 함수 선언은 아래와 같다.

BOOL CopyToClipboard();
• BOOL PasteFromClipboard();

CopyToClipboard 함수는 IppDib 객체가 가지고 있는 DIB 영상을 Windows 클립보드로 복사한다. 반대로 PasteFromClipboard 함수는 클립보드로부터 DIB 내용을 불러와서 IppDib 객체로 변환하는 함수이다. 이 두 함수들의 실제 구현은 소스 4-6에 나타내었으며, 소스 코드에 대한 자세한 설명을 주석으로 대체한다.

소스 4-6 IppDib 클래스 - 클립보드 지원(IppDib.cpp)
BOOL IppDib::CopyToClipboard()
{
    if (!::OpenClipboard(NULL))
        return FALSE;

    // DIB 전체를 전역 메모리 블럭에 복사
    DWORD dwDibSize = GetDibSize();
    HANDLE hDib = ::GlobalAlloc(GMEM_MOVEABLE | GMEM_DDESHARE, dwDibSize);
    if (hDib == NULL)
    {
        ::CloseClipboard();
        return FALSE;
    }

    LPVOID lpDib = ::GlobalLock((HGLOBAL)hDib);
    memcpy(lpDib, GetBitmapInfoAddr(), dwDibSize);
    ::GlobalUnlock(hDib);

    // 클립보드에 데이터 입력
    ::EmptyClipboard();
    ::SetClipboardData(CF_DIB, hDib);
    ::CloseClipboard();

    return TRUE;
}

BOOL IppDib::PasteFromClipboard()
{
    // CF_DIB 타입이 아니면 종료한다.
    if (!::IsClipboardFormatAvailable(CF_DIB))
        return FALSE;

    // 클립보드를 연다.
    if (!::OpenClipboard(NULL))
        return FALSE;

    // 클립보드 내용을 받아 온다.
    HANDLE hDib = ::GetClipboardData(CF_DIB);
    if (hDib == NULL)
    {
        ::CloseClipboard();
        return FALSE;
    }

    // 메모리 블럭의 크기는 DIB 전체 크기와 동일
    DWORD dwSize = (DWORD)::GlobalSize((HGLOBAL)hDib);
    LPVOID lpDib = ::GlobalLock((HGLOBAL)hDib);

    LPBITMAPINFOHEADER lpbi = (LPBITMAPINFOHEADER)lpDib;
    m_nWidth    = lpbi->biWidth;
    m_nHeight   = lpbi->biHeight;
    m_nBitCount = lpbi->biBitCount;

    DWORD dwWidthStep = (DWORD)((m_nWidth * m_nBitCount / 8 + 3) & ~3);
    DWORD dwSizeImage = m_nHeight * dwWidthStep;

    if (m_nBitCount == 24)
        m_nDibSize = sizeof(BITMAPINFOHEADER) + dwSizeImage;
    else
        m_nDibSize = sizeof(BITMAPINFOHEADER) + sizeof(RGBQUAD) * (1 << m_nBitCount) + dwSizeImage;

    // 현재 설정된 IppDib 객체가 있다면 삭제한다.
    if (m_pDib)
        Destroy();

    m_pDib = new BYTE[m_nDibSize];
    if (m_pDib == NULL)
    {
        ::GlobalUnlock(hDib);
        ::CloseClipboard();
        return FALSE;
    }

    memcpy(m_pDib, lpDib, m_nDibSize);
    ::GlobalUnlock(hDib);
    ::CloseClipboard();

    return TRUE;
}
신간 소식 구독하기
뉴스레터에 가입하시고 이메일로 신간 소식을 받아 보세요.