GetDeviceCaps

원형

int GetDeviceCaps(HDC hdc, int nIndex);

MFC 원형

int CDC::GetDeviceCaps( int nIndex ) const;

인수

▶hdc : DC의 핸들

▶nIndex : 조사하고자 하는 DC의 속성이며 다음 중 하나의 값을 지정해 준다.

인수 설명

DRIVERVERSION

드라이버의 버전

TECHNOLOGY

디바이스의 종류를 조사한다. 이 값을 조사하면 DC의 대상 장치가 프린터인지 화면인지를 구분할 수 있다.

리턴값 설명

DT_PLOTTER

벡터 플로터

DT_RASDISPLAY

래스터 디스플레이. 일반적으로 모니터라고 생각하면 된다.

DT_RASPRINTER

래스터 프린터. 일반적으로 프린터라고 생각하면 된다.

DT_RASCAMERA

래스터 카메라.

DT_CHARSTREAM

캐릭터 스트림

DT_METAFILE

메타 파일

DT_DISPFILE

디스플레이 파일

hdc가 메타 파일의 핸들인 경우 조사되는 디바이스 종류는 CreateEnhMetaFile 함수로 메타 DC를 생성할 때 참조한 디바이스의 종류이다. hdc가 메타 DC인지를 알고 싶으면 GetObjectType 함수를 사용해야 한다.

HORZSIZE, VERTSIZE

장치의 크기를 밀리미터 단위로 조사한다.

HORZRES, VERTRES

장치의 크기를 픽셀 단위로 조사한다.

LOGPIXELSX, LOGPIXELSY

인치당 픽셀수, 즉 해상도를 조사한다.

BITSPIXEL

픽셀단 비트수를 조사한다. 15bpp, 16bpp는 모두 16으로 조사된다.

PLANES

색상면의 수를 조사하되 이 값은 모든 장치에 1로 고정되어 있다.

NUMBRUSHES

디바이스 브러시의 개수

NUMPENS

디바이스 펜의 개수

NUMFONTS

디바이스 폰트의 개수

NUMCOLORS

장치가 8bpp 이하일 때 색상 테이블의 엔트리 개수를 조사한다. 8bpp 이상의 색상을 가지는 장치인 경우 -1이 리턴된다.

ASPECTX, ASPECTY

선을 그릴 때 상대적인 폭과 높이

ASPECTXY

선을 그릴 때 대각선의 폭

PDEVICESIZE

예약

CLIPCAPS

장치의 클리핑 능력을 조사한다. 장치가 사각 영역을 클리핑할 수 있으면 1을 리턴하면 그렇지 않을 경우 0을 리턴한다.

SIZEPALETTE

시스템 팔레트의 엔트리 개수를 조사한다. RASTERCAPS에 RC_PALETTE 비트가 설정되어 있을 때, 그리고 드라이버가 16비트 윈도우즈와 호환될 때만 유효하다. 아래 두 속성도 이와 동일하다.

NUMRESERVED

시스템 팔레트의 예약된 엔트리 개수를 리턴한다.

COLORRES

장치의 실제 색상 수를 bpp로 조사한다.

PHYSICALWIDTH, PHYSICALHEIGHT

프린터에만 해당되며 페이지의 실제 폭과 높이를 조사한다. 조사되는 값은 논리 단위가 아닌 장치 단위이며 인쇄할 수 있는 면적보다는 항상 더 크다. 용지의 면 중 실제 인쇄 가능한 영역(Printable Area)는 용지 바깥쪽의 여백을 제외한 중앙 부분이다.

PHYSICALOFFSETX, PHYSICALOFFSETY

인쇄 가능한 영역과 용지와의 거리를 장치 단위로 조사한다.

VREFRESH

NT/2000 이후에만 사용할 수 있으면 장치의 수직 주파수를 조사한다. 0 또는 1이 조사될 경우 디폴트 수직 주파수로 설정되어 있다는 뜻이다.

SCALINGFACTORX,
SCALINGFACTORY

프린터의 확대 비율

BLTALIGNMENT

NT/2000 : 수평 그리기에 사용되는 정렬값이며 픽셀의 배수로 표현된다. 운영체제는 그리기 속도의 향상의 위해 항상 이 값의 배수 위치에 윈도우를 그린다. 만약 이 값이 0이면 액셀러레이터 기능이 있다는 뜻이며 정렬은 하지 않는다.

SHADEBLENDCAPS

98/ME, 2000이상. 그림자 및 블렌딩(Shading, Blending)능력을 조사한다. 조사한 결과값을 다음 플래그들과 &연산하여 해당 비트가 설정되어 있으면 장치가 이 기능을 지원하는 것이다. 이하의 값들도 마찬가지이다.

설명

SB_CONST_ALPHA

Handles the SourceConstantAlpha member of the BLENDFUNCTION structure, which is referenced by the blendFunction parameter of the AlphaBlend function.

SB_GRAD_RECT GradientFill 함수로 사각형의 그라디언트를 그릴 수 있다.
SB_GRAD_TRI GradientFill 함수로 삼각형의 그라디언트를 그릴 수 있다.
SB_NONE 그림자 및 블랜딩 기능을 사용할 수 없다.
SB_PIXEL_ALPHA AlphaBlend 함수로 픽셀별 알파를 사용할 수 있다.
SB_PREMULT_ALPHA AlphaBlend 함수로 미리 계산된 알파를 사용할 수 있다.

 

RASTERCAPS

장치의 래스터 출력 능력을 조사한다.

설명

RC_BANDING

밴딩 지원이 요구된다.

RC_BITBLT 비트맵 전송을 지원한다. 즉 BitBlt 함수를 사용할 수 있다.
RC_BITMAP64 64KB 이상의 비트맵을 지원한다.
RC_DI_BITMAP Get(Set)DIBits 함수를 사용할 수 있다.
RC_DIBTODEV SetDIBitsToDevice 함수를 사용할 수 있다. 즉 DIB를 장치로 곧바로 출력할 수 있다.
RC_FLOODFILL 면 채우기 기능을 사용할 수 있다.
RC_GDI20_OUTPUT 16비트의 윈도우즈 2.0의 기능을 지원한다.
RC_PALETTE 팔레트 기반의 장치이다.
RC_SCALING 확대를 지원한다.
RC_STRETCHBLT StretchBlt 함수를 사용할 수 있다.
RC_STRETCHDIB StretchDIBits 함수를 사용할 수 있다.

 

CURVECAPS

장치의 곡선 그리기 능력을 조사한다.

설명

CC_NONE

곡선을 그릴 수 없다.

CC_CHORD chord를 그릴 수 있다.
CC_CIRCLES 원을 그릴 수 있다.
CC_ELLIPSES 타원을 그릴 수 있다.
CC_INTERIORS 내부를 채색할 수 있다.
CC_PIE pie를 그릴 수 있다.
CC_ROUNDRECT 둥근 사각형을 그릴 수 있다.
CC_STYLED 스타일이 있는 경계선을 그릴 수 있다.
CC_WIDE 폭이 넓은 경계선을 그릴 수 있다.
CC_WIDESTYLED 폭이 넓은 스타일이 있는 경계선을 그릴 수 있다.

 

LINECAPS

장치의 직선 그리기 능력을 조사한다.

설명

LC_NONE

선을 그릴 수 없다.

LC_INTERIORS 내부를 채색할 수 있다.
LC_MARKER 마커를 그릴 수 있다.
LC_POLYLINE 다각선을 그릴 수 있다.
LC_POLYMARKER 복수개의 마커를 그릴 수 있다.
LC_STYLED 스타일이 있는 선을 그릴 수 있다.
LC_WIDE 폭이 넓은 선을 그릴 수 있다.
LC_WIDESTYLED 폭이 넓은 스타일이 있는 선을 그릴 수 있다.

 

POLYGONALCAPS

장치의 다각형 그리기 능력을 조사한다.

설명

PC_NONE

다각형을 그릴 수 없다.

PC_INTERIORS 내부를 채색할 수 있다.
PC_POLYGON alternate 채우기 모드로 다각형을 그릴 수 있다.
PC_RECTANGLE 사각형을 그릴 수 있다.
PC_SCANLINE single scanline을 그릴 수 있다.
PC_STYLED 스타일이 있는 경계선을 그릴 수 있다.
PC_WIDE 폭이 넓은 경계선을 그릴 수 있다.
PC_WIDESTYLED 폭이 넓은 스타일이 있는 경계선을 그릴 수 있다.
PC_WINDPOLYGON winding 채우기 모드로 다각형을 그릴 수 있다.

 

TEXTCAPS

장치의 텍스트 출력 능력을 조사한다.

설명

TC_OP_CHARACTER

출력 정확도를 지정할 수 있다.

TC_OP_STROKE 스트록 출력 정확도를 지정할 수 있다.
TC_CP_STROKE 스트록 클립 정확도를 지정할 수 있다.
TC_CR_90 90도 회전된 문자를 출력할 수 있다.
TC_CR_ANY 임의 각도로 회전된 문자를 출력할 수 있다.
TC_SF_X_YINDEP x,y각 방향 독립적으로 확대할 수 있다.
TC_SA_DOUBLE 두배 확대된 문자를 출력할 수 있다.
TC_SA_INTEGER 정수배 확대할 수 있다.
TC_SA_CONTIN Device uses any multiples for exact character scaling.
TC_EA_DOUBLE 두배 두께의 문자를 출력할 수 있다.
TC_IA_ABLE 이탤릭 가능
TC_UA_ABLE 밑줄 가능
TC_SO_ABLE 취소선 가능
TC_RA_ABLE 래스터 폰트를 출력할 수 있다.
TC_VA_ABLE 벡터 폰트를 출력할 수 있다.
TC_RESERVED 예약
TC_SCROLLBLT 비트맵 복사 방식의 스크롤을 할 수 있다.

 

COLORMGMTCAPS

2000이상에서만 사용할 수 있으며 장치의 색상 관리 능력을 조사한다.

설명

CM_CMYK_COLOR

CMYK 색상을 받아들일 수 있다.

CM_DEVICE_ICM

장치나 또는 드라이버에서 ICM을 수행할 수 있다.

CM_GAMMA_RAMP

Get(Set)DeviceGammaRamp 함수를 지원한다.

CM_NONE

IDM을 지원하지 않는다.

 

 

리턴

조사된 값을 리턴한다. 이 값을 해석하는 방식은 어떤 값을 조사했는가에 따라 달라진다.

설명

DC가 참조하는 장치의 여러 가지 속성이나 능력을 조사한다. 이 값들은 장치에 대해 그리기나 기타 각종 설정 변경 등에 참고 정보로 사용된다. 예를 들어 플로터는 벡터의 직선이나 곡선을 그릴 수는 있지만 비트맵은 출력할 수 없으며 흑백 프린터는 색상을 표현하지 못한다. 이런 장치의 특성이나 능력을 이 함수로 반드시 먼저 조사한 후 가능한 기능일 때만 사용해야 한다.

이 함수로 조사할 수 있는 값의 종류가 많고 의미가 어려운 것도 있으므로 정확하게 의미를 파악한 후 사용해야 한다. 이 함수로 조사한 값을 부적절하게 사용할 경우 엉뚱한 동작을 할 수도 있다. 다른 방식으로는 조사하기 힘든 정보를 의외로 쉽게 구할 수도 있으므로 이 함수의 인덱스들은 한번씩 눈여겨 봐두는 것이 좋다.

예제 1

다음 예제는 화면 크기를 조사한 후 폭과 높이가 화면의 절반 크기인 윈도우를 생성한다. GetDeviceCaps 함수로 화면 크기를 실시간으로 조사해야만 정확하게 절반 크기의 윈도우를 생성할 수 있다. 화면 크기는 이 함수 외에도 GetSystemMetrics 함수로도 조사할 수 있다.

LRESULT CALLBACK WndProc(HWND hWnd,UINT iMessage,WPARAM wParam,LPARAM lParam)
{
	HDC hdc;
	PAINTSTRUCT ps;
	int x,y;
	LPCTSTR Mes=TEXT("화면 크기의 절반만큼의 윈도우를 생성합니다");

	switch(iMessage) {
	case WM_CREATE:
		hdc=GetDC(NULL);
		x=GetDeviceCaps(hdc,HORZRES);
		y=GetDeviceCaps(hdc,VERTRES);
		MoveWindow(hWnd,0,0,x/2,y/2,TRUE);
		ReleaseDC(hWnd,hdc);
		return 0;
	case WM_PAINT:
		hdc=BeginPaint(hWnd, &ps);
		TextOut(hdc,10,10,Mes,lstrlen(Mes));
		EndPaint(hWnd, &ps);
		return 0;
	case WM_DESTROY:
		PostQuitMessage(0);
		return 0;
	}
	return(DefWindowProc(hWnd,iMessage,wParam,lParam));
}

예제 2

다음 예제 현재 화면 DC의 여러 가지 능력을 조사해서 출력해 준다.

LRESULT CALLBACK WndProc(HWND hWnd,UINT iMessage,WPARAM wParam,LPARAM lParam)
{
	HDC hdc;
	PAINTSTRUCT ps;
	TCHAR str[128];
	int y=0;

	switch(iMessage) {
	case WM_PAINT:
		hdc=BeginPaint(hWnd, &ps);
		if (GetDeviceCaps(hdc,RASTERCAPS) & RC_BITBLT) {
			lstrcpy(str,TEXT("비트맵을 출력할 수 있습니다."));
		} else {
			lstrcpy(str,TEXT("비트맵을 출력할 수 없습니다."));
		}
		TextOut(hdc,10,y,str,lstrlen(str));y+=20;

		if (GetDeviceCaps(hdc,RASTERCAPS) & RC_PALETTE) {
			lstrcpy(str,TEXT("팔레트가 있습니다."));
		} else {
			lstrcpy(str,TEXT("팔레트가 없습니다."));
		}
		TextOut(hdc,10,y,str,lstrlen(str));y+=20;

		if (GetDeviceCaps(hdc,CURVECAPS) & CC_ELLIPSES) {
			lstrcpy(str,TEXT("타원을 그릴 수 있습니다."));
		} else {
			lstrcpy(str,TEXT("타원을 그릴 수 없습니다."));
		}
		TextOut(hdc,10,y,str,lstrlen(str));y+=20;

		if (GetDeviceCaps(hdc,LINECAPS) & LC_POLYLINE) {
			lstrcpy(str,TEXT("다각선을 그릴 수 있습니다."));
		} else {
			lstrcpy(str,TEXT("다각선을 그릴 수 없습니다."));
		}
		TextOut(hdc,10,y,str,lstrlen(str));y+=20;

		if (GetDeviceCaps(hdc,TEXTCAPS) & TC_CR_ANY) {
			lstrcpy(str,TEXT("텍스트를 임의 각도로 회전할 수 있습니다."));
		} else {
			lstrcpy(str,TEXT("텍스트를 임의 각도로 회전할 수 없습니다."));
		}
		TextOut(hdc,10,y,str,lstrlen(str));y+=20;

		EndPaint(hWnd, &ps);
		return 0;
	case WM_DESTROY:
		PostQuitMessage(0);
		return 0;
	}
	return(DefWindowProc(hWnd,iMessage,wParam,lParam));
}

예제 3

다음 예제는 Draw라는 함수 하나로 화면과 프린터로 동시에 출력을 보낸다. 윈도우즈의 DC는 화면과 프린터를 동질의 장치로 취급하도록 하기 때문에 DC만 바꿔 가며 동일한 함수로 같은 출력을 작성할 수 있다. 그러나 만약 화면과 프린터의 출력 모양이 달라져야 할 필요가 있다면 전달된 DC로부터 현재 출력이 화면으로 나가는지 프린터로 나가는지를 조사할 수 있다. GetDeviceCaps로 TECHNOLOGY를 조사하여 현재 DC에 대한 장치의 종류를 판별한다.

void Draw(HDC hdc)
{
	TCHAR str[128];

	if (GetDeviceCaps(hdc,TECHNOLOGY) == DT_RASDISPLAY) {
		lstrcpy(str,TEXT("이 문자열은 화면으로 출력됩니다"));
	} else {
		lstrcpy(str,TEXT("이 문자열은 프린터로 인쇄됩니다"));
	}
	TextOut(hdc,10,10,str,lstrlen(str));
}

void Print()
{
	HDC hPrtdc;
	DOCINFO doc;
	int Result;
	PRINTDLG pd;

	// 프린터에 관한 정보를 구하고 DC를 만든다.
	memset(&pd,0,sizeof(PRINTDLG));
	pd.lStructSize=sizeof(PRINTDLG);
	pd.Flags=PD_RETURNDC;
	pd.hwndOwner=hWndMain;
	pd.nFromPage=1;
	pd.nToPage=1;
	pd.nMinPage=1;
	pd.nMaxPage=1;
	pd.nCopies=1;
	PrintDlg(&pd);
	hPrtdc=pd.hDC;
	if (hPrtdc == NULL) return;

	// 인쇄 작업을 시작한다.
	doc.cbSize=sizeof(DOCINFO);
	doc.lpszDocName="Test Document";
	doc.lpszOutput=NULL;
	doc.lpszDatatype=NULL;
	doc.fwType=0;
	Result=StartDoc(hPrtdc, &doc);
	if (Result <= 0) goto end;
	Result=StartPage(hPrtdc);
	if (Result <= 0) goto end;

	// 출력을 보낸다.
	Draw(hPrtdc);

	// 출력을 종료한다.
	Result=EndPage(hPrtdc);
	if (Result <= 0) goto end;

	// 인쇄 작업을 끝낸다.
	Result=EndDoc(hPrtdc);
	if (Result <= 0) goto end;

end:
	if (pd.hDevMode)
		GlobalFree(pd.hDevMode);
	if (pd.hDevNames)
		GlobalFree(pd.hDevNames);
	DeleteDC(hPrtdc);
	return;
}

LRESULT CALLBACK WndProc(HWND hWnd,UINT iMessage,WPARAM wParam,LPARAM lParam)
{
	HDC hdc;
	PAINTSTRUCT ps;
	LPCTSTR Mes=TEXT("마우스 왼쪽 버튼을 누르면 문자열을 인쇄합니다");

	switch(iMessage) {
	case WM_LBUTTONDOWN:
		Print();
		return 0;
	case WM_PAINT:
		hdc=BeginPaint(hWnd, &ps);
		Draw(hdc);
		TextOut(hdc,10,30,Mes,lstrlen(Mes));
		EndPaint(hWnd, &ps);
		return 0;
	case WM_DESTROY:
		PostQuitMessage(0);
		return 0;
	}
	return(DefWindowProc(hWnd,iMessage,wParam,lParam));
}

화면상의 출력 모양은 다음과 같다.

그러나 왼쪽 마우스 버튼을 눌러 인쇄를 해 보면 다른 문자열이 출력될 것이다. 화면과 프린터과 완전히 동일한 위지윅이라면 이런 처리가 불필요하겠지만 배치가 조금 다르다거나 페이지 넘김 처리 등이 필요하다면 이런 식으로 장치를 구분할 수 있다.

참고함수

DeviceCapabilities

플랫폼

95이상

참조

29장의 인쇄 관련 예제를 보면 프린터의 해상도와 용지 크기 등을 구하기 위해 이 함수가 자주 사용된다.


written by http://www.winapi.co.kr