가.메타 레코드 열거

앞에서 메타 파일의 구조에 대해 간략하게 알아 보았는데 다시 한번 더 정리하자면 메타 파일은 단순한 GDI 함수 호출의 집합일 뿐이다. 즉 LineTo, SelectObject, CreatePen 따위의 함수 호출문이 부호화되어 저장되어 있는 것이 메타 파일이다. 그렇다면 메타 파일을 읽어 해석을 해 보면 어떤 함수들이 호출되는지를 역으로 알아낼 수도 있다는 얘기인데 과연 그렇다. 그러나 일일이 부호화된 GDI 함수 호출문을 일일이 해독해낸다는 것은 무척 번거롭고 귀찮은 작업인데 다음 함수를 사용하면 메타 파일에 포함된 각각의 메타 레코드를 순서대로 얻을 수 있다.

BOOL EnumEnhMetaFile(HDC hdc, HENHMETAFILE hemf, ENHMFENUMPROC lpEnhMetaFunc, LPVOID lpData, CONST RECT *lpRect);

이 함수는 메타 파일에 포함된 메타 레코드를 순서대로 열거하여 콜백 함수로 전달해 준다. 첫번째 인수 hdc는 메타 레코드가 열거될 DC의 핸들이며 마지막 인수 lpRect는 메타 파일을 출력할 사각 영역에 대한 논리적인 좌표이다. 메타는 크기 변경이 가능하고 맵핑 모드나 좌표 변환 체계의 영향을 받기 때문에 열거중에 메타 레코드를 출력해 보려면 이런 값들을 읽을 수 있는 DC의 핸들과 출력 영역을 지정해 주어야 한다. 그러나 만약 메타 레코드를 출력하지 않고 순수하게 메타 레코드만 보고 싶다면 hdc와 lpRect는 지정하지 않아도 상관없다. hdc는 그대로 콜백 함수로 전달되며 lpRect는 헤더 레코드에 포함되는데 이 값은 PlayEnhMetaRecord 함수에 의해 메타 레코드를 출력할 때 사용된다.
두번째 인수는 두말할 필요없이 열거 대상이 되는 메타 파일이며 세번째 인수는 열거중에 호출될 콜백 함수이다. 네번째 인수 lpData는 콜백 함수로 전달될 옵션 데이터이되 필요하지 않으면 NULL로 지정하면 된다. 콜백 함수는 다음과 같은 원형을 가지며 메타 파일내의 모든 레코드를 전달받는다. 함수의 이름은 물론 원하는대로 변경할 수 있다.

int CALLBACK EnhMetaFileProc(HDC hDC, HANDLETABLE *lpHTable, CONST ENHMETARECORD *lpEMFR, int nObj, LPARAM lpData);

hDC, lpData는 EnumEnhMetaFile함수로부터 전달받은 것이고 나머지 세 인수는 메타 레코드에 대한 정보를 가진다. lpHTable은 메타 파일내의 그래픽 오브젝트에 대한 핸들 배열이며 nObj는 이 배열의 크기이되 이 배열은 분석에 사용된다기보다 PlayEnhMetaRecord 함수로 전달되어 재생에 사용된다. 세번째 인수 lpEMFR이 메타 레코드인데 이 레코드는 앞에서도 살펴 보았다시피 다음과 같은 가변 길이의 구조체이다.

typedef struct tagENHMETARECORD { // enmr
DWORD iType;
DWORD nSize;
DWORD dParm[1];
} ENHMETARECORD;

iType을 읽으면 어떤 GDI 함수 호출인지 알 수 있으며 nSize는 메타 레코드의 크기를 바이트 단위로 조사할 수 있다. 단 nSize에는 iType과 nSize 자체의 크기도 포함되므로 실제 인수의 길이는 이 값이 지정하는 값보다 8 더 작다. dParm 배열은 GDI 함수의 인수에 대한 정보를 가지고 있는데 GDI 함수의 인수는 대부분 정수형이므로 DWORD형에 대한 배열로 정의되어 있다. 이렇게 전달받는 메타 레코드는 임의대로 분석해 볼 수 있지만 직접 변경은 할 수 없으며 꼭 변경해야 한다면 사본을 만든 후 변경해야 한다. 메타 레코드를 단순히 출력해 보기만 하려면 다음 함수를 호출한다.

BOOL PlayEnhMetaFileRecord(HDC hdc, LPHANDLETABLE lpHandletable, CONST ENHMETARECORD *lpEnhMetaRecord, UINT nHandles);

dc, 핸들 테이블 그리고 메타 레코드를 전달해 주면 이 레코드의 GDI 함수 호출문이 실행될 것이다


목록 보기  다음 강좌            written by http://www.winapi.co.kr