문제점 발견

프로그램에 스킨을 입히거나 특정 용도가 있는 경우 Border를 bsNone으로 하여 상단 Caption을 숨길 때가 있다.
일반 폼이라면 정상동작하나 bsNone인 폼이라면 폼 최대화 기능 구현을 위해 WindowState를 wsMaximized로 세팅하면 작업표시줄까지 덮어버린다.
그래서 보통은 아래와 같이 작업표시줄을 제외한 작업영역을 구해서 그 크기만큼 폼의 크기를 세팅하고 한다.

// 폼을 최대화하고 Align을 설정하거나
begin
  Form.WindowState := wsMaximized;
  Form.Align := alClient;
end;

// 혹은 작업 영역을 구해서 폼의 크기를 맞춰준다.
var
  WorkRect: TRect;
begin
  Form.WindowState := wsMaximized;        

  SystemParametersInfo( SPI_GETWORKAREA, 0, @WorkRect, 0 );
  Form.SetBounds( WorkRect.Left, WorkRect.Top, WorkRect.Right - WorkRect.Left, WorkRect.Bottom - WorkRect.Top );
 end;


문제는 듀얼모니터인 경우이다.
프로그램을 두번째 스크린으로 옮기고 최대화를 실행하면 폼이 보이지 않게 되어버린다.
어디로 날라간 것일까 -_-;

폼이 다른 모니터에 있는 경우 위치를 제대로 얻어오지 못한다.


해결방법

Forms에 있는 Screen 전역 객체를 이용하여 폼이 위치한 모니터를 얻어내고 작업 영역을 구하면 된다.

1. 폼이 위치한 곳의 TMonitor 객체를 얻어내보자
var
  Monitor: TMonitor;
begin
  Monitor := Screen.MonitorFromWindow( Form.Handle );
end;

2. TMonitor에는 API를 래핑한 여러가지 프로퍼티가 존재한다.
작업 영역을 얻기 위해서는 TMonitor의 WorkareaRect를 이용하자.
작업 영역을 구해보자
var
  WorkRect: TRect;
begin
  WorkRect := Monitor.WorkareaRect;
end;


전체 코드

var
  Monitor: TMonitor;
  WorkRect: TRect;
begin
  Form.WindowState := wsMaximized;

  Monitor := Screen.MonitorFromWindow( Form.Handle );
  WorkRect := Monitor.WorkareaRect;
  Form.SetBounds( WorkRect.Left, WorkRect.Top, WorkRect.Right - WorkRect.Left, WorkRect.Bottom - WorkRect.Top );
end;


PS
더 자세한 사항은 Forms 유닛의 TScreen, TMonitor 클래스를 참조하기 바란다.
화면과 관련한 Windows API 사용법이 자세히 작업되어 있다.

+ Recent posts