2017-09-28 1 views
0

CWnd에서 상속 된 사용자 정의 클래스를 사용하여 Custome Splitter Wnd를 작성중인 개발자입니다. 처음에는 화면에 두 개의 버튼 (수직 분할, 수평 분할)이있는 하나의 창 (사용자 정의 클래스 - CTile)이 있습니다. 사용자가 두 개의 단추 중 하나를 클릭하면 빨간색 분리 막대가 나타나고 두 개의 하위 창 (CTile)이 나타납니다. 아시겠지만 사용자가 빨간색 분리 막대를 끌면 하위 창을 수정해야합니다. 내가 여기서 말하는 것은이 순간에 깜박임이 나타나는 것입니다. 부모 wnd는 세 개의 요소 (두 개의 자식 창과 하나의 분할 막대) 만 가지고 있으므로 그림의 내용을 필요로하지 않는다고 생각합니다. 나는 WM_PAINT 메시지 처리기를 의미합니다. 여기 내 코드가 있습니다. 단지 부모 초기 창 - 여기C++ : RedrawWindow() 깜박임

this->cDiv = new CDivider(this->wth_tile/2, 1); 
this->cDiv->CreateDivider(this, this->hgt_tile); 

//cDiv is split bar I used custom class which is inherited from CWnd. 
//CreateDivider() is also my self-defined method. 

this->first_child = new CTile(); 

// As I mentioned above, CTile is divided child window which is also inherited from CWnd. 

POINT pt; 
pt.x = 0; 
pt.y = 0; 
this->first_child->CreateTile(this, this->cDiv->sd_pos, this->hgt_tile, pt); 

this->second_child = new CTile(); 


pt.x = this->cDiv->sd_pos + 5; 
pt.y = 0; 

this->second_child->CreateTile(this, this->cDiv->sd_pos, this->hgt_tile, pt); 

This is make movable split bar wnd creation code. 

And next is about modified child window size while drag the split bar. 

void CDivider::OnMouseMove(UINT nFlags, CPoint point) 
{ 
// TODO: Add your message handler code here and/or call default 

POINT pt; 
HDC hdc; 
RECT rect; 

this->parentWnd->GetWindowRect(&rect); 

//convert the mouse coordinates relative to the top-left of 
//the window 
ClientToScreen(&point); 
pt = point; 
pt.x -= rect.left; 
pt.y -= rect.top; 

if (this->sd_mode == 1) 
{ 
    ::SetCursor(AfxGetApp()->LoadStandardCursor(IDC_SIZEWE)); 
    if (GetCapture() == this && this->dragged) 
    { 
     this->sd_pos = pt.x; 
     if (pt.x != oldPos.x && nFlags & MK_LBUTTON) 
     { 
      this->length = this->parentWnd->hgt_tile; 
      this->MoveWindow(this->sd_pos, 0, 4, this->length); 
      this->parentWnd->ResizeParent(); 
      this->parentWnd->Invalidate(); 
      this->parentWnd->UpdateWindow(); 
      TRACE("Resize Parent\n"); 
      /*this->parentWnd->first_child->Invalidate(); 
      this->parentWnd->second_child->Invalidate();*/ 
     } 
    } 

} 
else if (this->sd_mode == 2) 
{ 
    ::SetCursor(AfxGetApp()->LoadStandardCursor(IDC_SIZENS)); 

    if (GetCapture() == this && this->dragged) 
    { 
     this->sd_pos = pt.y; 
     if (pt.y != oldPos.y && nFlags & MK_LBUTTON) 
     { 
      this->Invalidate(); 
      this->length = this->parentWnd->wth_tile; 
      this->MoveWindow(0, this->sd_pos, this->length, 4); 

      this->parentWnd->ResizeParent(); 
      this->parentWnd->Invalidate(); 
      this->parentWnd->UpdateWindow(); 
      TRACE("Resize Parent\n"); 
      /*this->parentWnd->first_child->Invalidate(); 
      this->parentWnd->second_child->Invalidate();*/ 
     } 
    } 
} 

CWnd::OnMouseMove(nFlags, point); 

는}, parentWnd 분할 바의 부모 창입니다. first_child 및 second_child는 자식으로 분할 된 창입니다. sd_mode는 split 메소드 - 수직 &을 의미합니다.

왜이 코드가 작동하지 않습니까?

+1

'WS_CLIPCHILDREN' 창 스타일로 부모 창을 만드시겠습니까? – VTT

+0

WS_CLIPCHILDREN? 나는 WS_CLIPCHILDREN을 사용한 적이 없다. WS_VISIBLE 및 WS_CHILD 만 창을 만드는 데 사용되었습니다. @VTT –

답변

2

그림이 대부분의 일반 창에서 2 단계 작업으로 인해 깜박입니다. 1. 배경이 지워집니다. 2. 창이 다시 그려집니다.

그래서 문제는 다시 그리기가 필요한 하위 창입니다. 깜박 거리지 않는 그림에 대한 기사가 많이 있습니다.

또한 영향을받는 창 부분 만 무효화하여 다시 그리기를 최적화 할 수 있습니다. 전체 창을 강제로 다시 그립니다. 그것은 이상적이지 않습니다. 이 경우 창의 대부분이 깜박일 수 있습니다.

BTW : 특정 플래그가있는 RedrawWindow가 유효성 검사/업데이트 시퀀스를 호출하는 것보다 낫고 빠르게 틱이 될 수 있습니다.

또한 드래그하는 동안 XOR-Paining을 사용하여 바를 그리는 방법을 사용하는 것이 좋습니다. 그리고 LButtonUp-Event가 발생할 때 창 크기를 업데이트하십시오. CSplitterWnd가하는 방법은 ... 소스가 있습니다. 그것 좀 봐.

+0

제안 해 주셔서 감사합니다. @xMRi –

+0

자식 창 다시 그리기에 대한 아이디어를 따르겠습니다. 그리고 창의 특정 부분에 대해서도 좋다고 생각합니다. "드래그하는 동안 XOR- 그림으로 바를 그리는 방법을 사용하는 것이 더 나을 것입니다."라고 말했을 때, 그것에 대해 귀중한 예제를 제공 할 수 있습니까? –

+0

MFC CSpiltterWnd의 소스 코드가 있습니다. 그것만 들여다 봐라. 당신은 필요한 모든 것을 찾을 수 있습니다. – xMRi