.다중 모니터 출력

윈도우가 두 개의 모니터 중간에 걸쳐 있는 상황이더라도 응용 프로그램의 그리기 코드가 특별한 영향을 받을 필요는 없다. WM_PAINT 메시지에서 하나의 DC를 발급받고 이 DC의 표면에 그리기만 하면 나머지 작업은 시스템이 알아서 해 준다. 그리기 표면이 두 모니터에 있더라도 응용 프로그램은 하나의 논리적인 윈도우에 그리기만 하면 되는 것이다.

두 모니터에 걸쳐 있는 윈도우의 경우 그리기 속도가 조금 저하되기는 하겠지만 그것도 무시할만한 수준이다. 다만 두 모니터의 색상 포맷이 다른 경우는 속도 저하가 다소 심할 수도 있고 시스템의 출력이 최적이 아닐 수도 있다. 예를 들어 주 모니터는 24비트 색상으로 맞추어져 있고 추가 모니터는16비트 색상으로 설정되어 있을 경우 시스템이 최적의 출력 결과를 맞추기가 다소 어려울 것이다. 이때도 시스템은 최대한 비슷한 출력을 하지만 최적의 성능과는 다소 거리가 멀 수도 있다.

그래픽 편집 프로그램이나 전자 출판 프로그램 등 출력 결과가 아주 중요한 경우나 CAD같이 그리기 속도가 아주 중요한 경우는 이런 상황을 직접 처리할 수도 있다. 다음 예제는 다중 모니터 상황에서 각 모니터의 색상 포맷에 따라 최적의 출력을 만들어내는 예를 보여준다.

 

BOOL CALLBACK MonitorEnumProc(HMONITOR hMonitor,HDC hdcMonitor,LPRECT lprcMonitor,LPARAM dwData)

{

   HBRUSH Brush,OldBrush;

   HPEN Pen,OldPen;

   RECT rtRect,rtPaint;

 

   if (GetDeviceCaps(hdcMonitor,BITSPIXEL) == 16) {

      Brush=CreateSolidBrush(RGB(0,0,255));

      Pen=CreatePen(PS_SOLID,1,RGB(0,0,255));

   } else {

      Brush=CreateSolidBrush(RGB(255,0,0));

      Pen=CreatePen(PS_SOLID,1,RGB(255,0,0));

   }

   SetRect(&rtRect,10,50,1000,150);

   IntersectRect(&rtPaint,&rtRect,lprcMonitor);

   OldBrush=(HBRUSH)SelectObject(hdcMonitor,Brush);

   OldPen=(HPEN)SelectObject(hdcMonitor,Pen);

   Rectangle(hdcMonitor,rtPaint.left,rtPaint.top,rtPaint.right,rtPaint.bottom);

   DeleteObject(SelectObject(hdcMonitor,OldBrush));

   DeleteObject(SelectObject(hdcMonitor,OldPen));

   return TRUE;

}

 

LRESULT CALLBACK WndProc(HWND hWnd,UINT iMessage,WPARAM wParam,LPARAM lParam)

{

   HDC hdc;

   PAINTSTRUCT ps;

   TCHAR Mes[]="16비트 색상 모니터에서는 파란색, 그외의 모니터에서는 빨간색";

 

   switch(iMessage) {

   case WM_PAINT:

      hdc=BeginPaint(hWnd, &ps);

      TextOut(hdc,10,10,Mes,lstrlen(Mes));

      EnumDisplayMonitors(hdc,NULL,MonitorEnumProc,NULL);

      EndPaint(hWnd, &ps);

      return 0;

   case WM_DESTROY:

      PostQuitMessage(0);

      return 0;

   }

   return(DefWindowProc(hWnd,iMessage,wParam,lParam));

}

 

WM_PAINT에서는 간단한 메시지 출력 외에 특별한 그리기 코드를 가지지 않으며 모니터 열거 함수만 호출한다. 이때 EnumDisplayMonitors 함수의 첫번째 인수로 hdc를 넘겨 주어 이 DC의 영역에 걸쳐 있는 모니터에 대해서만 조사하도록 했다. 그리기를 위해 모니터 열거를 하는 것이므로 hdc와 겹쳐 있지 않은 모니터에 대해서는 열거할 필요가 없다.

콜백 함수는 인수로 전달된 hdcMonitor DC에 그리기를 하되 이 DC의 색상 포맷이 16비트이면 파란색으로, 그 외의 색상 포맷이면 빨간색으로 그리기를 한다. lprcMonitor 인수로는 hdc와 교차되는 모니터 영역의 좌표가 전달되므로 이 영역안에만 그리기를 하면 된다. 실행해 보면 두 모니터의 중간에 걸쳤을 때 16비트 모니터에서는 파란색, 24비트 모니터에서는 빨간색 사각형이 그려질 것이다.

이 예제는 색상 포맷이 다른 모니터의 경계에 있을 때 각 영역에 대해 다른 방식으로 그릴 수도 있다는 것을 보여줄 뿐 실용적인 가치는 없다. 하지만 아무리 복잡한 출력이라도 기본 원리는 이 예제와 동일하다. WM_PAINT에서는 모니터 열거만 하고 실제 그리기 코드는 모니터 열거 함수로 전달되는 DC lprcMonitor 영역을 참조하면 된다.