본문 바로가기

Language/MFC

Child 크기 동적 변경

Child를 분할 한 후 원하는 크기를 조절하지 못해서 한참 해맸다.


MFC 특성상 왠만한 함수들이 지원이 될거라 생각하고, 내가 그걸 모르고 있다고 생각하면서 서칭만 몇일째 하다 결국 노가다로 해결하는 수 밖에 없었다.


데브피아, 팁스 소프트에 사진까지 올려가며 질문했지만 답글은 0 ..ㅡㅡ!!



Child Frame에서 분할 뷰 뿐 아니라 단일 뷰 일때도 동적으로 크기 변경(수동 말고...)을 하고자 할때 사실 특정함 함수 또는 오버라이딩 가능한 함수가 있을거라 생각했다만... 없다. 


특히 영상처리를 하기 위하여 단일 윈도우가 아닌 MDI 처럼 영상 마다 각 윈도우를 띄우는 형식이라면 영상의 크기에 따라서 창의 크기도 달라져야 한다. (물론 영상 자체를 고정된 창에 축소 해서 보여 줄 수도 있지만 일단 이건 패스하고...)


때문에 MainFrame 또는 ChildFrame 의 PreCreateWindow() 에서 창의 크기를 조절하는 것은 사실상 의미가 없다. 


왜냐면 대부분 영상을 로드하거나 새로 생성 할때 Frame 클래스에서 하지않고 (특히 MDI 같은 경우는) 대부분 Document  클래스에서 처리를 하기 때문이다. 물론 Frame 클래스에서 불가능 하진 않지만 역시 MDI  경우에는 Document 로 하라는 책느님의 지시가..ㅋㅋ

머 꼭 책이 아니더라도 기본적인 데이터 처리는 Document 클래스에서 하는 것이 좋다. (그런 식으로 하도록 설계를 해놓았기 때문이라고 한다.)


서론이 길었다...;;; 결국 어떻게 해야 동적으로 가능하면....


어짜피 Frame의 크기는 View의 크기와 동일하게 들어간다. 

특별한 경우가 아닌 이상에야 View보다 Frame의 크기를 작게 했으면 작게 했지 크게 하진 않는다. (특별한 경우는 워드 같은 SDI 구조에서 문서 크기를 조절 할때나 봤을까?)


때문에 View 클래스를 초기화 하는 과정에서 하는 것이 괜찬은듯 하다.


로직은 다음과 같다.

1. OnInitUpdate() 함수에서 Document 클래스의 변수를 참조하여 영상의 크기를 얻는다.

2. 얻어진 영상의 크기에 따라서 원하는 크기로 계산.

3. Child 크기를 얻는다. 

4. MoveWindow를 이용하여 창의 크기를 강제로 변경.


처음에 MoveWindow , SetWindowPos 함수를 죽어라 사용했지만 크기를 조절하려는 클래스의 핸들이 맞지 않아 어떻게 해도 이동이 되지 않았다. 


그리고 MainFrame의 객체를 얻은 후 GetActiveFrame 함수를 이용하여 Child 객체를 얻고 MoveWindow를 하니까 어떻게 된게 매인 프레임이 움직인다?ㅡㅡ ;;


원인 분석은 아직 않해봤지만 머 코딩 실수 일거라 생각한다. 


여튼 혹시나 그런 버그가 일어나지 않도록 하기 위하여 GetParentSplitter 함수를 이용하여 Child 핸들러를 가지고 처리를 하니 깔금하게 된다. 


GetParentSplitter(this, FALSE)->SetColumnInfo(1, sizeTotal.cx - int(sizeTotal.cx / 3), 10);

CRect rect;

//Frame의 크기를 얻는다. 

GetParentFrame()->GetWindowRect(&rect);


//256보다 크면 1/3 크기로 세로를 세팅

if(sizeTotal.cy > 256)

{

rect.bottom = rect.top + (sizeTotal.cy - int(sizeTotal.cy  / 3));

}

else

{

//256 보다 작으면 영상에 맞도록 세팅.

rect.bottom = rect.top + sizeTotal.cy;

}

//Child 크기를 변경.

GetParentFrame()->MoveWindow(rect.left,rect.top, (sizeTotal.cx - int(sizeTotal.cx / 3)) * 2 + 30,rect.Height(), TRUE);

//GetParentSplitter(this, FALSE)->SetRowInfo(1,sizeTotal.cy - int(sizeTotal.cy / 3), 10);//세로 분할 창이 존재 한다면.

//Frame을 다시 그린다. 

GetParentSplitter(this, FALSE)->RecalcLayout();


분할 뷰 라서 기본적으로 SetColumnInfo를 이용했는데 일단 전체 프레임을 움직이는건 이 함수로 무리였다.


만일 코드 최적화를 시킨다면 

GetParentSplitter(this, FALSE)->SetColumnInfo(1, sizeTotal.cx - int(sizeTotal.cx / 3), 10);

이 부분은 필요 없을 듯....


왜 좀 더 빨리 이런 생각을 못한 것일까.... 틀에 박혀서 시간을 낭비하니 돌아버리 겠다.


---------------------------------

2015-02-27

위 방법을 쓰면 창의 크기 조절이 가능하나 멀티 모니터일 경우 좌표 계산을 따로 해줘야 한다. 

멀티 모니터를 사용하는 방법에 대해서는 구글에 많은 자료가 올라와있으며 멀티모니터 인지 아닌지를 판단하여 좌표를 가감해줘야 한다. 않그럼 않보임....