정의는 비교적 간단하다.

윈도우의 클라이언트 영역안에 들어 있는 Control Bar들의 위치나 크기를 조정하기 위해 호출하는 것이다.

Prototype을 보면 다음과 같다.
void RepositionBars(
   UINT nIDFirst,
   UINT nIDLast,
   UINT nIDLeftOver,
   UINT nFlag = reposDefault,
   LPRECT lpRectParam = NULL,
   LPCRECT lpRectClient = NULL,
   BOOL bStretch = TRUE 
);
nIDFirst 부터 nIDLast의 Control Bar까지 위치나 크기가 조정되며, nIDLeftOver Pane으로 나머지 Client영역을 채운다. 나머지는 Default 값을 사용하거나 다음과 같은 목적으로 조합할 수 있다.

만약 nFlag의 값으로 CWnd::reposQuery 를 사용하면 조정이 실제 행해지지는 않으면서 조정이 실제로 이루어 졌을때의 Client 영역을 얻을 수 있다.

만약 nFlag값을 CWnd::reposExtra 으로 설정하면 nIDLast Client 영역에 lpRectParam 만큼의 영역을 더하여 조정을 하게된다.

lpRectClient는 임의로 윈도우의 Client 영역을 정할 수도 있으며, NULL인경우 윈도우의 현재 Client 영역을 사용한다.

bStretch 는 Bar를 윈도우 Frame 크기에 맏도록 늘릴지를 결정한다.

이상 별로 어려워 보일것 같지 않은 함수이다. 그러나 오늘 이 함수를 깊이 있게 살펴보고자 하는 이유는 다음 때문이다.

FrameWnd가 있는데 그 안쪽에 SplitterWnd를 사용하여 두개의 View를 보여주고 있었다. 이때 FrameWnd에 두개의 ToolBar를 이어붙여 보여줄 필요가 생겼다. 그래서 두 툴바를 이어 붙여주는 함수에서 RepositionBars()를 다음과 같이 사용하였다.

[CODE]void DockRightOf(CXTPToolBar* pBarToDock, CXTPToolBar* pBarOnLeft)
{
      RepositionBars(AFX_IDW_CONTROLBAR_FIRST, AFX_IDW_CONTROLBAR_LAST, AFX_IDW_PANE_FIRST);

      CXTPWindowRect rcBar(pBarOnLeft);

       if (IsVerticalPosition(pBarOnLeft->GetPosition()))
            rcBar.OffsetRect(0, rcBar.Height());
       else
            rcBar.OffsetRect(rcBar.Width(), 0);

       GetCommandBars()->DockCommandBar(pBarToDock, rcBar, pBarOnLeft->GetDockBar());
}[/CODE]

그런데 SplitterWnd에서 Assertion이 발생하였다.

AFX_IDW_PANE_FIRST 대신 0 을 넣어준 결과 Assertion도 발생하지 않고 원하는 결과를 보여주었다.

일단 무식하게 유추해 보면 AFX_IDW_PANE_FIRST는 첫번째 걸린 Child Window(보통 View)로 Client영역을 채워주라는 것인데, 그렇게 따지면 SplitterWnd가 되지 않을까? 첫번째 걸린 View로 Client를 채우라는 것인가?

다음에서 pView가 NULL이 되어 Error가 발생한다. 0,0 Pane을 가져오지 못하는 이유를 알 수 없다.

CWnd* CSplitterWnd::GetPane(int row, int col) const
{
ASSERT_VALID(this);

CWnd* pView = GetDlgItem(IdFromRowCol(row, col));
ASSERT(pView != NULL);  // panes can be a CWnd, but are usually CViews
return pView;
}

여하튼, MFC는 CFrameWnd를 상속받은 Frame에 ToolBar, Status Bar등을 배치할 수 있는 함수들을 제공하고 이들의 크기와 위치를 변경하기 위해 RepositionBars()를 활용한다는 것을 확인할 수 있었다.

RepositionBars()와 관련된 다음의 주제들 또한 참고할 만하다.

nFlag, lpRectParam 의 활용 예를 볼 수 있는 MSDN 자료

MFC/ 다이얼로그에 있는 툴바와 상태 표시줄 - 위 문서와 같은 내용을 포함하고 있다. 전반적 이해를 위해서는 이 문서가 더 좋을 것이다.




크리에이티브 커먼즈 라이센스
Creative Commons License
2007/05/07 22:17 2007/05/07 22:17

Trackback Address :: http://www.codeforum.net/blog/pitoosung/trackback/73