C++Builder Programming Forum
C++Builder  |  Delphi  |  FireMonkey  |  C/C++  |  Free Pascal  |  Firebird
볼랜드포럼 BorlandForum
 경고! 게시물 작성자의 사전 허락없는 메일주소 추출행위 절대 금지 |
아이디 비밀번호
 
C++빌더 포럼
Q & A
FAQ
팁&트릭
강좌/문서
자료실
컴포넌트/라이브러리
메신저 프로젝트
볼랜드포럼 홈
헤드라인 뉴스
IT 뉴스
공지사항
자유게시판
해피 브레이크
공동 프로젝트
구인/구직
회원 장터
건의사항
운영진 게시판
회원 메뉴
북마크
볼랜드포럼 광고 모집

C++빌더 Q&A
C++Builder Programming Q&A
[54591] Re:마우스를 이용한 패널,메모,에디트박스의 사이즈 변경...
장성호 [nasilso] 3568 읽음    2008-09-18 03:07
음..
이번에는 질문을 제대로 이해했길 기대합니다.

아래 박지훈.임프 님께서 올려주신 팁을 참조하신거죠?
http://cbuilder.borlandforum.com/impboard/impboard.dll?action=read&db=bcb_tip&no=47

위 팁에 소개된 방법으로 런타임에 control을 resize하려는데
Panel 은 되는데 TMemo나 TEdit의 경우 잘 안된다는 거죠?

TPanel과 TMemo,TEdit의 공통된 속성중에 차이점을 살펴보면 
Default로 생성될때 BorderStyle이 다릅니다.

Panel의 경우 BorderStyle이 bsNone 이구
TMemo 나 TEdit의 경우 BorderStyle이 bsSingle 입니다.

즉 Panel은 되는데 TMemo는 잘 안되는것은 BorderStyle이 다르기 때문입니다.
그러므로 Panel 도 BorderStyle을 bsSingle로 바꾸면 잘안되고
TMemo나 TEdit도 BorderStyle을 bsNone로 바꾸면 잘 됩니다.

그런데 TMemo나 TEdit의 BorderStyle을 bsNone로 바꾸면 모양이 이상하게 나오죠?

왜그런가하면 BorderStyle을 bsSingle로 두면 Control의 가장자리에 Border영역이 생기는데
이 영역에서는 MouseMove이벤트가 발생하지 않기 때문입니다.
Border영역 안으로 들어와서 발생하는 이벤트는 이미 re-size 마우스 위치를 벗어났을 때죠

방법1.
   Border영역 신경쓰지 않고 가능하게 하려면
   Control의 Width와 Height 대신 ClientWidth 와 ClientHeight로 바꾸시면 됩니다.
   ( MouseMove이벤트는 Control의 Client영역을 기준으로 발생하기 때문입니다.)
 
void __fastcall TForm1::Memo2MouseDown(TObject *Sender,
      TMouseButton Button, TShiftState Shift, int X, int Y)
{
    TWinControl *SenderControl = dynamic_cast(Sender);
    int SysCommWparam;

    if(X < 4 && Y < 4)
        SysCommWparam = SC_DRAG_RESIZEUL;
    else if(X > SenderControl->ClientWidth-4 && Y > SenderControl->ClientHeight-4)
        SysCommWparam = SC_DRAG_RESIZEDR;
    else if(X < 4 && Y > SenderControl->ClientHeight-4)
        SysCommWparam = SC_DRAG_RESIZEDL;
    else if(X > SenderControl->ClientWidth-4 && Y < 4)
        SysCommWparam = SC_DRAG_RESIZEUR;
    else if(X < 4)
        SysCommWparam = SC_DRAG_RESIZEL;
    else if(X > SenderControl->ClientWidth-4)
        SysCommWparam = SC_DRAG_RESIZER;
    else if(Y < 4)
        SysCommWparam = SC_DRAG_RESIZEU;
    else if(Y > SenderControl->ClientHeight-4)
        SysCommWparam = SC_DRAG_RESIZED;
    else
        SysCommWparam = SC_DRAG_MOVE;

    ReleaseCapture();
    SendMessage(SenderControl->Handle, WM_SYSCOMMAND, SysCommWparam, 0);

}


void __fastcall TForm1::Memo2MouseMove(TObject *Sender, TShiftState Shift,
      int X, int Y)
{

    TControl *SenderControl = dynamic_cast(Sender);
    if((X < 4 && Y < 4) || (X > SenderControl->ClientWidth-4 && Y > SenderControl->
      ClientHeight-4))
        SenderControl->Cursor = crSizeNWSE;
    else if((X < 4 && Y > SenderControl->ClientHeight-4) || (X > SenderControl->
      ClientWidth-4 && Y < 4))
        SenderControl->Cursor = crSizeNESW;
    else if(X < 4 || X > SenderControl->ClientWidth-4)
        SenderControl->Cursor = crSizeWE;
    else if(Y < 4 || Y > SenderControl->ClientHeight-4)
        SenderControl->Cursor = crSizeNS;
    else
        SenderControl->Cursor = crDefault;

}



방법2.
  그런데 위 방식에 한가지 깔끔하지 못한것이 하나있으니
  컨트롤의 BorderStyle이 bsSingle 이고 
  Mouse가 Border영역에서 움직일때는 여전히 적용이 안된다는것입니다.

  그럼 BorderStyle이 bsSingle일때 Mouse가 Border영역에서 움직일때
  발생하는 메세지를 이용하면 가능하지 않을까요?

  그것은 WM_NCHITTEST 메세지를 이용하시면 됩니다.

TWndMethod OrgPanelProc;
void __fastcall TForm1::FormCreate(TObject *Sender)
{
    OrgPanelProc=Panel5->WindowProc;
    Panel5->WindowProc=PanelProc;
}
//-------------------------------------------------
void __fastcall TForm1::PanelProc(TMessage &Msg)
{

    if(Msg.Msg==WM_NCHITTEST)
   {
        TPoint MousePos=Point(Msg.LParamLo,Msg.LParamHi);
        MousePos=Panel5->ScreenToClient(MousePos);

        if (MousePos.x <= 4)  Msg.Result = HTLEFT;
        if (Panel5->Width - 4 <= MousePos.x)  Msg.Result = HTRIGHT;
        if (Panel5->Height - 4 <= MousePos.y)  Msg.Result = HTBOTTOM;
        if (MousePos.y <= 4)  Msg.Result = HTTOP;

        if ((MousePos.x <= 7) && (MousePos.y <= 7))  Msg.Result = HTTOPLEFT;
        if ((MousePos.x <= 7) && (Panel5->Height - 7 <= MousePos.y))  Msg.Result = HTBOTTOMLEFT;
        if ((Panel5->Width - 7 <= MousePos.x) && (MousePos.y <= 7))  Msg.Result = HTTOPRIGHT;
        if ((Panel5->Width - 7 <= MousePos.x) && (Panel5->Height - 7 <= MousePos.y))  Msg.Result = HTBOTTOMRIGHT;

        if ((Msg.ResultHTBOTTOMRIGHT) )
            OrgPanelProc(Msg);

        return;

    }

    OrgPanelProc(Msg);
}



생각건데 방법2를 좀더 보완해서 하는 방향을 추천합니다.

그럼..





linuxman 님이 쓰신 글 :
: 안녕하세요..
:
: 팁에 있는 패널에 대한 콤포넌트 사이즈 변경에 대한것을 보고...(마우스 커서를 이용한 )
: 그것을 그대로 메모장이나,editbox에 적용하려고 해보니, 패널은  상하,좌우 모두 마우스 잘 동작됩니다.
: 그런데.. 메모장이나 editbox는 왼쪽과 윘쪽은 잘 동작하는데...
:
: 오른쪽과 아랫쪽은  마우스가 잘 인지 못하는것 같습니다... 모두 TControl을 상속 받아서, 패널과 틀릴것이 없다고 생각이 되는데... 왜 이런 차이가 생기는건가요?
:
:
: void __fastcall TForm1::Panel1MouseDown(TObject *Sender,
:       TMouseButton Button, TShiftState Shift, int X, int Y)
: {
:
:
:  TControl *SenderControl = dynamic_cast<TControl *>(Sender);
:     int SysCommWparam;
:
:     if(X < 4 && Y < 4)
:         SysCommWparam = SC_DRAG_RESIZEUL;
:     else if(X > SenderControl->Width-4 && Y > SenderControl->Height-4)
:         SysCommWparam = SC_DRAG_RESIZEDR;
:     else if(X < 4 && Y > SenderControl->Height-4)
:         SysCommWparam = SC_DRAG_RESIZEDL;
:     else if(X > SenderControl->Width-4 && Y < 4)
:         SysCommWparam = SC_DRAG_RESIZEUR;
:     else if(X < 4)
:         SysCommWparam = SC_DRAG_RESIZEL;
:     else if(X > SenderControl->Width-4)
:         SysCommWparam = SC_DRAG_RESIZER;
:     else if(Y < 4)
:         SysCommWparam = SC_DRAG_RESIZEU;
:     else if(Y > SenderControl->Height-4)
:         SysCommWparam = SC_DRAG_RESIZED;
:     else
:         SysCommWparam = SC_DRAG_MOVE;
:
:     ReleaseCapture();
:     SendMessage(Panel1->Handle, WM_SYSCOMMAND, SysCommWparam, 0);
:
: }
: //---------------------------------------------------------------------------
: void __fastcall TForm1::Panel1MouseMove(TObject *Sender, TShiftState Shift,
:       int X, int Y)
: {
:
: TControl *SenderControl = dynamic_cast<TControl *>(Sender);
:     if((X < 4 && Y < 4) || (X > SenderControl->Width-4 && Y > SenderControl->
:       Height-4))  
:         SenderControl->Cursor = crSizeNWSE;  
:     else if((X < 4 && Y > SenderControl->Height-4) || (X > SenderControl->
:       Width-4 && Y < 4))
:         SenderControl->Cursor = crSizeNESW;
:     else if(X < 4 || X > SenderControl->Width-4)
:         SenderControl->Cursor = crSizeWE;
:     else if(Y < 4 || Y > SenderControl->Height-4)
:         SenderControl->Cursor = crSizeNS;
:     else 
:         SenderControl->Cursor = crDefault;    
: }

+ -

관련 글 리스트
54589 마우스를 이용한 패널,메모,에디트박스의 사이즈 변경...[1] linuxman 2226 2008/09/18
54591     Re:마우스를 이용한 패널,메모,에디트박스의 사이즈 변경... 장성호 3568 2008/09/18
54600         Re:Re:마우스를 이용한 패널,메모,에디트박스의 사이즈 변경... linuxman 2021 2008/09/18
54601             Re:Re:Re:마우스를 이용한 패널,메모,에디트박스의 사이즈 변경... 장성호 2349 2008/09/18
Google
Copyright © 1999-2015, borlandforum.com. All right reserved.