[WinAPI] Clipboard, 클립보드

오늘은 클립보드에 대해서 배워보겠습니다.

클립보드에대한 개념과 설명은 구글에서 찾아서 공부하세요.

이 글에서는 int형 변수의 값을 클립보드로 복사하고, 클립보드에서 다시 가져와서 표시하는 것만 해보겠습니다.

프로젝트를 하나 만들어 아래와 같이 Edit Control과 Static Control을 만들어 줍니다.

리소스의 컨트롤 변수를 아래와 같이 만들어 줍니다.

Copy Clipboard 버튼을 더블클릭해서 아래와 같이 코딩합니다.

void CClipboardDlg::OnBnClickedButton1()
{
	UpdateData( TRUE );

	// 글로벌 메모리 얻기
	HANDLE hData = ::GlobalAlloc( GMEM_FIXED, sizeof(m_iInput) );

	// 글로벌 락
	int *piData = (int*)::GlobalLock( hData );
	if ( NULL != piData )
	{
		// input data 복사
		memcpy( piData, &m_iInput, sizeof(m_iInput) );

		// 글로벌  언락
		::GlobalUnlock( hData );

		// 클립보드 Open
		BOOL bOpen = ::OpenClipboard( this->m_hWnd );
		if ( TRUE == bOpen )
		{
			// 초기화
			::EmptyClipboard();

			// 복사
			::SetClipboardData( CF_DIF, hData );

			// 클립보드 닫음
			::CloseClipboard();
		}
	}
}

Paste 버튼을 더블클릭해서 아래와 같이 코딩합니다.

void CClipboardDlg::OnBnClickedButton2()
{
	UINT pri_list = CF_DIF;

	// 클립보드 포맷 얻기
	int iPriFormat = ::GetPriorityClipboardFormat( &pri_list, 1 );

	// 위에 복사한 포맷이랑 같은지 확인
	if ( CF_DIF == iPriFormat )
	{
		// 같으면 클립보드 열기
		BOOL bOpen = ::OpenClipboard( this->m_hWnd );
		if ( TRUE == bOpen )
		{
			// 클립보드 데이터 얻기
			HANDLE hData = ::GetClipboardData( CF_DIF );

			if ( NULL != hData )
			{
				// 락
				int *piData = (int *)::GlobalLock( hData );

				if ( NULL != piData )
				{
					int iData;
					ZeroMemory( &iData, sizeof(iData) );

					// 데이터 복사하고
					memcpy( &iData, piData, sizeof(iData) );

					// 대화상자 표시
					CString sData;
					sData.Format( _T("%d"), iData );
					m_stOutput.SetWindowText( sData );

					// 언락
					::GlobalUnlock( hData );
				}
			}
			// 클립보드 닫기
			::CloseClipboard();
		}
	}
}

실행 시켜서 확인해 봅니다.

GlobalAlloc의 첫번째 인자 Flag에 대해 MSDN에 나와있는 설명은 아래와 같습니다.

==============================MSDN=======================================

DECLSPEC_ALLOCATOR HGLOBAL GlobalAlloc(
  UINT   uFlags,
  SIZE_T dwBytes
);

uFlags

메모리 할당 속성 0을 지정하면 기본값은 GMEM_FIXED 입니다. 이 매개 변수는 특별히 언급 된 호환되지 않는 조합을 제외하고 다음 값 중 하나 이상일 수 있습니다.

값의미

GHND(0x0042)GMEM_MOVEABLE 과 GMEM_ZEROINIT를 결합합니다 .
GMEM_FIXED(0x0000)고정 메모리를 할당합니다. 반환 값은 포인터입니다.
GMEM_MOVEABLE(0x0002)이동식 메모리를 할당합니다. 메모리 블록은 실제 메모리에서 이동되지 않지만 기본 힙 내에서 이동할 수 있습니다.반환 값은 메모리 객체에 대한 핸들입니다. 핸들을 포인터로 변환하려면 GlobalLock 함수를 사용하십시오 .이 값은 GMEM_FIXED 와 결합 할 수 없습니다 .
GMEM_ZEROINIT(0x0040)메모리 내용을 0으로 초기화합니다.
GPTR(0x0040)GMEM_FIXED 와 GMEM_ZEROINIT를 결합합니다

다음 값은 더 이상 사용되지 않지만 16 비트 Windows와의 호환성을 위해 제공됩니다. 그들은 무시됩니다.

GMEM_DDESHARE
GMEM_DISCARDABLE
GMEM_LOWER
GMEM_NOCOMPACT
GMEM_NODISCARD
GMEM_NOT_BANKED
GMEM_NOTIFYGMEM_SHARE

dwBytes

할당 할 바이트 수입니다. 이 매개 변수가 0이고 uFlags 매개 변수가 GMEM_MOVEABLE을 지정 하면, 함수는 삭제 된 것으로 표시된 메모리 오브젝트에 핸들을 리턴합니다.

=========================================================================

그리고 SetClipboardData할때 사용된 첫번째 인자 Format에 대한 MSDN 설명은 아래와 같습니다.

==============================MSDN=======================================

CF_BITMAP(2)비트 맵에 대한 핸들 ( HBITMAP )
CF_DIB(8)비트 맵 비트 다음에 BITMAPINFO 구조를 포함하는 메모리 객체 .
CF_DIBV5(17)비트 맵 색 공간 정보와 비트 맵 비트가 뒤 따르는 BITMAPV5HEADER 구조를 포함하는 메모리 객체 .
CF_DIF(5)소프트웨어 아트 데이터 교환 형식.
CF_DSPBITMAP(0x0082)개인 형식과 관련된 비트 맵 표시 형식입니다. hMem의 매개 변수는 개인적으로 형식의 데이터 대신에 비트 맵 형식으로 표시 할 수있는 데이터의 핸들이어야합니다.
CF_DSPENHMETAFILE(0x008E)개인 형식과 관련된 향상된 메타 파일 표시 형식. hMem의 매개 변수는 개인적으로 형식의 데이터 대신에 확장 된 메타 파일 형식으로 표시 할 수있는 데이터의 핸들이어야합니다.
CF_DSPMETAFILEPICT(0x0083)개인 형식과 관련된 메타 파일 그림 표시 형식입니다. hMem의 매개 변수는 개인적으로 형식의 데이터 대신에 메타 파일 – 그림 형식으로 표시 할 수있는 데이터의 핸들이어야합니다.
CF_DSPTEXT(0x0081)개인 형식과 관련된 텍스트 표시 형식. hMem의 매개 변수는 개인적으로 형식의 데이터 대신에 텍스트 형식으로 표시 할 수있는 데이터의 핸들이어야합니다.
CF_ENHMETAFILE(14)확장 메타 파일 ( HENHMETAFILE )에 대한 핸들 입니다.
CF_GDIOBJFIRST(0x0300)응용 프로그램 정의 GDI 개체 클립 보드 형식에 대한 정수 값 범위의 시작 범위의 끝은 CF_GDIOBJLAST 입니다.
이 범위의 클립 보드 형식과 관련된 핸들 은 클립 보드를 비울 때 GlobalFree 기능을 사용하여 자동으로 삭제되지 않습니다 . 또한이 범위의 값을 사용할 때 hMem 매개 변수는 GDI 오브젝트에 대한 핸들이 아니라 GMEM_MOVEABLE 플래그를 사용하여 GlobalAlloc 함수에 의해 할당 된 핸들 입니다.
CF_GDIOBJLAST(0x03FF)CF_GDIOBJFIRST를 참조하십시오 .
CF_HDROP(15)파일 목록을 식별하는 HDROP 를 입력하는 핸들 입니다. 응용 프로그램은 핸들을 DragQueryFile 함수 에 전달하여 파일에 대한 정보를 검색 할 수 있습니다 .
CF_LOCALE(16)데이터는 클립 보드의 텍스트와 관련된 로캘 식별자에 대한 핸들입니다. 클립 보드를 닫을 때 CF_TEXT 데이터는 있지만 CF_LOCALE 데이터 는 포함 하지 않으면 CF_LOCALE 형식이 현재 입력 언어로 자동 설정 됩니다. CF_LOCALE 형식을 사용하여 다른 로케일을 클립 보드 텍스트와 연관 시킬 수 있습니다 .
클립 보드에서 텍스트를 붙여 넣는 응용 프로그램은이 형식을 검색하여 텍스트를 생성하는 데 사용 된 문자 집합을 확인할 수 있습니다.
클립 보드는 여러 문자 집합에서 일반 텍스트를 지원하지 않습니다. 이를 위해 RTF와 같은 형식화 된 텍스트 데이터 유형을 대신 사용하십시오.
시스템은 CF_LOCALE 와 관련된 코드 페이지를 사용합니다.CF_TEXT 에서 CF_UNICODETEXT 로 암시 적으로 변환 합니다. 따라서 올바른 코드 페이지 테이블이 변환에 사용됩니다.
CF_METAFILEPICT(3)METAFILEPICT 구조 로 정의 된 메타 파일 그림 형식을 처리합니다 . 통과 할 때 CF_METAFILEPICT의 DDE에 의해 핸들을, 삭제에 대한 책임이있는 응용 프로그램 hMem는 또한 메타 파일을 해제해야는에 의해 참조 CF_METAFILEPICT의 핸들입니다.
CF_OEMTEXT(7)OEM 문자 세트의 문자를 포함하는 텍스트 형식입니다. 각 라인은 캐리지 리턴 / 라인 피드 (CR-LF) 조합으로 끝납니다. 널 문자는 데이터의 끝을 나타냅니다.
CF_OWNERDISPLAY(0x0080)소유자 표시 형식 클립 보드 소유자는 클립 보드 뷰어 창을 표시 및 업데이트하고 WM_ASKCBFORMATNAME , WM_HSCROLLCLIPBOARD , WM_PAINTCLIPBOARD , WM_SIZECLIPBOARD 및 WM_VSCROLLCLIPBOARD 메시지를 수신해야합니다. hMem의 매개 변수는 다음과 같아야합니다 NULL .
CF_PALETTE(9)컬러 팔레트를 처리합니다. 응용 프로그램이 색상 팔레트에 의존하거나 색상 팔레트를 사용하는 데이터를 클립 보드에 배치 할 때마다 팔레트도 클립 보드에 배치해야합니다.
클립 보드에 CF_PALETTE (논리적 색상 팔레트) 형식의 데이터가 포함 된 경우 응용 프로그램은 SelectPalette 및 RealizePalette 함수를 사용하여 해당 논리적 팔레트에 대해 클립 보드의 다른 데이터를 실현 (비교)해야합니다.
클립 보드 데이터를 표시 할 때 클립 보드는 항상 클립 보드에서 CF_PALETTE 형식 인 객체를 현재 팔레트로 사용 합니다.
CF_PENDATA(10)펜 컴퓨팅을위한 Microsoft Windows 펜 확장명 데이터.
CF_PRIVATEFIRST(0x0200)개인용 클립 보드 형식의 정수 범위에서 시작합니다. 범위는 CF_PRIVATELAST로 끝납니다 . 개인 클립 보드 형식과 관련된 핸들은 자동으로 해제되지 않습니다. 클립 보드 소유자는 일반적으로 WM_DESTROYCLIPBOARD 메시지 에 대한 응답으로 이러한 핸들을 해제해야합니다 .
CF_PRIVATELAST(0x02FF)CF_PRIVATEFIRST를 참조하십시오 .
CF_RIFF(11)CF_WAVE 표준 웨이브 형식 으로 표현할 수있는 것보다 복잡한 오디오 데이터를 나타냅니다 .
CF_SYLK(4)SYLK (Microsoft Symbolic Link) 형식
CF_TEXT(1)텍스트 형식. 각 라인은 캐리지 리턴 / 라인 피드 (CR-LF) 조합으로 끝납니다. 널 문자는 데이터의 끝을 나타냅니다. ANSI 텍스트에는이 형식을 사용하십시오.
CF_TIFF(6)태그가 지정된 이미지 파일 형식.
CF_UNICODETEXT(13)유니 코드 텍스트 형식. 각 라인은 캐리지 리턴 / 라인 피드 (CR-LF) 조합으로 끝납니다. 널 문자는 데이터의 끝을 나타냅니다.
CF_WAVE(12)11kHz 또는 22kHz PCM과 같은 표준 웨이브 형식 중 하나로 오디오 데이터를 나타냅니다.

=========================================================================

사실 포맷을 저도 CF_DIF로 사용했는데, 상황에 맞게 사용하시면 됩니다.