2012-06-07 5 views
22

다중 모니터 시스템에서 "비어있는"VCL 응용 프로그램을 사용하면 스타일을 최대화 할 수 있지만 스타일을 활성화 한 응용 프로그램 (기본적으로 선택한 응용 프로그램)은 잘못 최대화됩니다. 내가보고있는 것은 윈도우의 오른쪽 가장자리가 두 번째 모니터로 확장된다는 것입니다 (내 메인은 왼쪽에 있습니다). 다른 Windows 응용 프로그램과 비교를 시작했을 때, Windows 7 (최소)에서는 최대화 된 창에 왼쪽, 오른쪽 또는 아래쪽에 클라이언트가 아닌 테두리가없는 것으로 나타났습니다. 실제로 표준 VCL (스타일이없는) 앱은 비 클라이언트 테두리없이 동일한 방식으로 작동합니다.인접한 모니터에 경계선을 표시하는 최대화 된 스타일의 윈도우는 어떻게해야합니까?

어떻게 수정합니까? TFormStyleHook에는 아직 해부하지 않은 WMNCCalcSize에 대한 핸들러가 있지만, VCL이 최대화 된 윈도우에 대해이 메시지를 잘못 처리하고 있는지 궁금하게 생각합니다.

+5

더 많은 VCL 스타일 버그. QC를 이용해주세요. –

+1

QC 웹 주소 : http://qc.embarcadero.com/wc/qcmain.aspx –

+0

이 동작을 단일 모니터에서 재현 할 수 있습니까? 현재 위치에서이 문제를 테스트 할 다른 모니터가 없기 때문에 묻습니다. – RRUZ

답변

5

이것에 대해 약간의 시간을 들인 후, 필자의 생각은 vcl 스타일 버그가 아닙니다. 이것은 실제로 comment에 언급 된 article의 질문과 관련된 문제와 관련이 있습니다. mghie.

특정 동작은 최대화 된 창의 크기가 창이 최대화되는 모니터의 작업 영역보다 큰 것입니다. 창 관리자가 오버행 경계를 숨 깁니다. 외관상으로는, 그것은 주문을 받아서 만들어진 구조로 확실히하지 않는다. MSDN 자체의 custom window frame example은 동일한 문제 (게시 된 내용의 "Bug when Maximized"커뮤니티 콘텐츠의)를 참조하십시오. VCL의 애플리케이션은 DWM을 기반으로하지 않는다는 점에서 MSDN 예제와 다르지만 여전히 동일한 문제라고 생각합니다.

오버행 테두리는 시스템 크기 조정 테두리 (SM_C [X | Y] SIZEFRAME)의 크기를 갖지만 OS 제안 크기/위치를 무시하고 작업 영역을 사용하므로 아래의 해결 방법과는 관련이 없습니다.

불행히도이 해결 방법을 전혀 사용할 수 없다고 생각합니다. 하나는 언급 된 동작이 문서화되어 있지 않습니다. 둘째, 해결 방법은 완벽하지 않습니다. 여전히 이상한 픽셀이 있습니다. 창을 작업 영역에 정확히 맞추면 창 관리자는 창을 숨겨진 프레임과 함께 배치해야한다고 생각하는 위치로 창을 옵셋하기로 결정합니다. (VCL은 창 관리자가 할 일을 수정하고 오버행을 고려하여 그와 비슷한 것을 그리지는 않겠지 만 더 많은 작업이 될 것이고 여전히 문서화되지 않은 문제를 해결할 수 있습니다.)

어쨌든

;

type 
    TForm1 = class(TForm) 
    .. 
    protected 
    // overriding styles is not necessary since TFormStyleHook.WMGetMinMaxInfo 
    // first calls the default window procedure 
    procedure WMGetMinMaxInfo(var Message: TWMGetMinMaxInfo); 
     message WM_GETMINMAXINFO; 

.. 

procedure TForm1.WMGetMinMaxInfo(var Message: TWMGetMinMaxInfo); 
var 
    R: TRect; 
begin 
    // always arrives with MinMaxInfo.ptMaxPosition = (-SM_CXFRAME, -SM_CYFRAME) 
    // and MinMaxInfo.ptMaxSize = (PrimaryMonitor.Width (?) + 2 * SM_CXFRAME, ...) 
    inherited; 

    // should test for OS, styles etc. before running the below 
    R := Monitor.WorkareaRect; 
    InflateRect(R, -1, -1);    // odd pixel 
    OffsetRect(R, -Monitor.Left, -Monitor.Top); 
    Message.MinMaxInfo.ptMaxPosition := R.TopLeft; 
    Message.MinMaxInfo.ptMaxSize := Point(R.Width, R.Height); 
end; 
+0

Raymond는 특별히 "시각적 트릭"이라고 말합니다. 그래서 우리는 창 rect의 크기를 조정하지 않고 돌출 된 테두리를 잘라내겠습니까? – whosrdaddy

+0

@whos - 물론, 내부 프레임을 제거하는 것이 훨씬 낫습니다. 나는 VCL의 협조가 필요하다고 생각했지만, 그렇지 않을 수도 있습니다. –

0

유일한 방법은 WM_SIZE 이벤트를 처리하고 여분의 테두리를 잘라 내기 위해 창 영역을 수정하는 것입니다.