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
[54601] Re:Re:Re:마우스를 이용한 패널,메모,에디트박스의 사이즈 변경...
장성호 [nasilso] 2349 읽음    2008-09-18 16:57
음...
Panel위에 TImage가  Align=alClient 로 놓여있을경우에...

Panel의 크기를 변경하고 싶으신 건가요?
Image의 크기를 변경하고 싶으신 것인가요?

1. Panel의 크기를 변경하고 싶을때는?
   여러가지 방법이 있겠지만.
   1.1  OnMouseMove 이벤트 와  OnMouseDown이벤트를 Image와 Panel에 같은 메소드를 걸어두는 방법

   1.2 ImageOnMouse.. 이벤트 핸들러 에서  Panel의 PanelOnMouse... 이벤트 핸드러를 호출해 주는 방법

   1.3 그리고 이전답변에 WM_NCHITTEST를 이용하는 방법이

   등이 있겠네요

2. Image의 크기를 변경하고 싶으시다면?
   Image에 SendMessage로 메세지를 보낼수는 없습니다만 Image에도 WindowProc가 있습니다.
   그런데 이놈은 제대로된 WindowProc가 아니라 Image컨트롤이 올려진 Parent에서 메세지가 발생하면
   자신의 Client영역에 있는 graphic컨트롤에 메세지를 전달해 주죠

   하지만 image가 WM_SYSCOMMAND를 받더라도  그것을 처리하는 루틴이 없으니 아무 쓸모가 없습니다.
   
   그래서 Image같은 Graphic컨트롤을 마우스로 drag하여 움직이거나 resize하려면
   직접 imageMouseDown과 ImageMouseMove이벤트에서 좌표계산해서 Image크기를 조절해주던가
   위치를 변경해주던가 해야 합니다.
 
   그런데 Image의 Align이 alClient로 되어있다면 , 크기를 변경하더라도 .다시 원상 복구 되버릴것 같은데요
   image의 Align을 alNone로 설정한후에 적용해야 될듯....


그럼...



linuxman 님이 쓰신 글 :
: 그런곳에 차이가 있었군요... 정말 감사...합니다.(몇주 하다가 포기하려하던참에... 좋은 답변을 듣게 되어...참으로 감사합니다 )
: 여기서 한가지 더 궁금한것이 있습니다..
: handle이 있는 놈들한테는  WM_SYSCOMMAND같은것을 보낼수 있는데...
: handle 이 없는 Image 콤포넌트 같은 놈은 sendMessage 자체를 못하니까...사이즈 변화를 줄수 있는 방법이 궁금합니다.
:
: 아래처럼 했을경우.. 이미지 영역에 왔을때...감지는 모두됩니다 (상,하,좌,우)...
: 패널위에 이미지를 올려놓고 (client 속성 )... 패널의 크기 가 변할때 이미지 사이즈를 변하게 하려니까,
: 이미지가 이벤트를 가로채서, 패널에 전달되지 않는 현상이 발생합니다...
:
: 이미지는 어떻게 마우스로 사이즈를 변화시킬수 있나요?
:
: 수고하세요.
:
: int DeltaX;
: int DeltaY;
: TImage *Image1;
: void __fastcall TForm1::Image1MouseDown(TObject *Sender,
:       TMouseButton Button, TShiftState Shift, int X, int Y)
: {
:    /* 이미지 move 를 하기위해 - SendMessage(Image1, WM_SYSCOMMAND, SysCommWparam, 0);
:    를 사용할수 없어서.. */
:      Image1=(TImage *)Sender;    
:      DeltaX=X;
:      DeltaY=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(Image1, WM_SYSCOMMAND, SysCommWparam, 0);
: */
:
: }
: void __fastcall TForm1::Image1MouseMove(TObject *Sender, TShiftState Shift,
:       int X, int Y)
: {
:    /*이미지 move를 하기위해 - SendMessage(Image1, WM_SYSCOMMAND, SysCommWparam, 0);
: */
:       AnsiString xy ;
:       if(Shift.Contains(ssLeft))
:       {
:          int dx=X-DeltaX;
:          int dy=Y-DeltaY;
:          if(Image1)
:          {
:              Image1->Left+=dx;
:              Image1->Top+=dy;
:          }
:       }
:
: /*
:
:     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;
: */
:       
: }

:
: 장성호 님이 쓰신 글 :
: : 음..
: : 이번에는 질문을 제대로 이해했길 기대합니다.
: :
: : 아래 박지훈.임프 님께서 올려주신 팁을 참조하신거죠?
: : 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 마우스를 이용한 패널,메모,에디트박스의 사이즈 변경... linuxman 2227 2008/09/18
54591     Re:마우스를 이용한 패널,메모,에디트박스의 사이즈 변경... 장성호 3569 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.