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

C++빌더 팁&트릭
C++Builder Programming Tip&Tricks
[47] 팁! 런타임에 컨트롤 리사이즈하기
박지훈.임프 [cbuilder] 12349 읽음    1999-06-04 00:00
허.. 아래 훔쳐온? 긁어온? 팁을 올리고 나서.. 너무 쪽팔려서요.
실추된 명예를 되살릴 멋진 팁이 없을까.. 하고 곰곰히 생각해보다가..

오래전에 연습삼아 만들었던 소스들중에서, 아주 멋지진 않지만 그래도 재미있는 걸
하나 찾아서 올립니다. 사실 옛날에 한번 언급하긴 했습니다만(1457번),
드래깅만 설명하고 리사이즈에 대해선 설명하지 않았거든요. ^^;;;;

자아.. 그럼 얘기를 풀어볼까요.
윈도우즈 메시지중 WM_SYSCOMMAND 메시지를 보면, 윈도우 자체의 동작에 관한
기능들을 하는 메시지란 것을 알 수 있습니다. 닫기, 스크롤, 사이즈변경 등등의
기능이 이 메시지의 옵션(WPARAM 인자)를 통해서 이루어집니다.

그런데, 사실 이 메시지에는 win32 api 레퍼런스에서 언급하지 않은 몇가지의
옵션이 더 있습니다. 그중의 하나가 위에서 언급한 오래전의 팁에서 언급했던
런타임 드래깅.. 0xf12구요. 그외에 여덟개의 옵션이 더 있죠.

이 여덟개의 옵션은 각각 윈도우를 위쪽경계 / 아래경계 / 오른쪽경계 / 왼쪽경계
/ 위왼쪽끝 / 위오른쪽끝 / 아래왼쪽끝 / 아래오른쪽끝 / 의 여덟개의 방향에서
클릭하고 드래그했을때 WM_SYSCOMMAND 메시지가 발생하면서 WPARAM으로 넘어오는
것입니다.

다시 말하면, 윈도우 핸들을 가지는 컨트롤이라면 강제로 이 여덟개의 옵션을
사용해서 런타임에 드래깅을 통해 리사이즈할 수 있다는 말이 되죠.

길게 설명할 시간은 없고.. 잘 이해가 안되시는 분은, 위의 짤막한 설명을 한번
더 읽어보시든지, 아래 소스를 읽어보시고 직접 실행해보시기 바랍니다.

여덟개나 되는 값을 일일이 값만으로 기억하긴 뭣하니까 매크로로 선언해봅시다.

#define SC_DRAG_RESIZEL  0xf001  // left resize
#define SC_DRAG_RESIZER  0xf002  // right resize
#define SC_DRAG_RESIZEU  0xf003  // upper resize
#define SC_DRAG_RESIZEUL 0xf004  // upper-left resize
#define SC_DRAG_RESIZEUR 0xf005  // upper-right resize
#define SC_DRAG_RESIZED  0xf006  // down resize
#define SC_DRAG_RESIZEDL 0xf007  // down-left resize
#define SC_DRAG_RESIZEDR 0xf008  // down-right resize
#define SC_DRAG_MOVE     0xf012  // move


하는김에, 전에 설명했던 드래그 옴션인 0xf012까지 함께 선언했습니다.

그담에.. 폼에 패널을 하나 놓고, 패널의 OnMouseMove 이벤트의 핸들러를 작성합니다.

void __fastcall TForm1::Panel1MouseMove(TObject *Sender, TShiftState Shift,
      int X, int Y)
{
    TControl *SenderControl = dynamic_cast(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;
}


위 이벤트 핸들러는, 단순히 커서의 위치에 따라 커서모양만 각 상황에 맞는
리사이즈 커서로 바꾸어준거구요.
중요한 것은 아래 부분입니다.
이번엔, 이 패널의 OnMouseDown 이벤트의 핸들러를 작성합니다.

void __fastcall TForm1::Panel1MouseDown(TObject *Sender,
      TMouseButton Button, TShiftState Shift, int X, int Y)
{
    TControl *SenderControl = dynamic_cast(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);
}


ReleaseCapture()함수에 대한 것은 위에 언급한 저번 팁에서 간단히 언급했었던것
같습니다. 궁금하신 분은 참고하시길.

이 소스를 실제로 실행해보면.. 신기하게도, 폼위에 놓여진 패널이, 마치
독립적인 윈도우처럼 드래깅 될 뿐 아니라, 바깥쪽 경계를 드래그해서 리사이즈도
할 수 있습니다.

별 도움이 안된다고 생각할 수도 있습니다만, 잘 응용하면 생각보다 아주
재미있게 활용할 수 있습니다. 실제로 제가 그렇구요.

오랜만에 올린 팁이 까마득히 오래전에 알아냈던 구닥다리 팁이라서 죄송합니다.
혹 다른 분들도 이미 이 방법을 아시고 있는 분들도 있을지..?
쩝.. 바쁜 시간을 좀더 쪼개어서라도 좀 화끈하게 재미있는 팁을 찾아보겠습니다..
분발하자 임프... ^^;;;;




임펠리테리 박지훈이었습니다.
푸른꿈 [bluedream]   2008-08-15 18:11 X
훌륭한 팁입니다.

+ -

관련 글 리스트
47 팁! 런타임에 컨트롤 리사이즈하기 박지훈.임프 12349 1999/06/04
Google
Copyright © 1999-2015, borlandforum.com. All right reserved.