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
[317] 전체화면의 경계에 윈도우가 착 달라붙게 하는 방법.
유지상 [newjisang] 8366 읽음    2002-03-08 14:08
여기와서 질문만 하다가 드디어 Tip'N Tricks에 처음으로 글을 쓰게 되었습니다.
sasami2k나 WimAmp의 윈도우를 드레그해보면, 윈도우전체스크린에 위,아래,왼쪽,오른쪽에 착 달라붙는 것을 알 수 있습니다.
여기서는 이런 기능을 구현하기 위해서, WM_MOVE, WM_MOVING 메시지를 이용해봤습니다.
소스는 아래와 같습니다.
만약 프로그램 사용자가 작업표시줄숨기기기능을 쓰고 있지 않을 때에는,
전체스크린의 아래 경계선에 윈도우가 달라붙게 하기보다는 작업표시줄의 위쪽 경계선에 달라붙게 하는 것이 좋을 것입니다. 이런 경우는,SHAppBarMessage라는 API함수와, 그리고, Q&A의 16119번째 글에 대한 답변을 참조하시면 됩니다.

제가 아직 초보인지라 구현소스에 한계가 많습니다.
예를 들면, WimAmp에서는 전체스크린 경계에만 붙는게 아니라, 서로가 서로를 향해 붙고, 또,
HelloWin(딱지?)라는 프로그램도 이런 기능이 있습니다.
여기서 보이는 소스는 스크린 경계에 붙는 것만 구현되어있지요.
지금 제가 만들고 있는 프로그램에 HelloWin처럼 불특정개수의 윈도우가 서로서로 붙는 기능을 구현해야 할 필요가 있는데, 지금은 이것까지만 구현했습니다.

만약 이것 외에 다른 좋은 소스가 있는 경우, 알려주시면 감사하겠습니다. (결국 또다시 질문이 되었네.)
class TForm1 : public TForm
{
//...
  void __fastcall WMMove(TWMMove& Msg);
  void __fastcall WMMoving(TMessage& Msg);
protected:
  BEGIN_MESSAGE_MAP
    VCL_MESSAGE_HANDLER(WM_MOVE, TWMMove, WMMove)
    VCL_MESSAGE_HANDLER(WM_MOVING, TMessage, WMMoving)
  END_MESSAGE_MAP(TForm)
};

//====================================== ability of sticking to screen borders.=========
static bool X_sticked = false; /* whether or not this form is sticked to a vertical line*/
static bool Y_sticked = false; /* whether or not this form is sticked to a horizantal line*/
void __fastcall TForm1::WMMove(TWMMove& Msg)  { X_sticked = false; Y_sticked = false; }
int GetCursorX()                              { POINT point; GetCursorPos(&point); return point.x; }
int GetCursorY()                              { POINT point; GetCursorPos(&point); return point.y; }
void __fastcall TForm1::WMMoving(TMessage& Msg)
{
  LPRECT pRect = (LPRECT)Msg.LParam;
  int shift,i;
  static int stickedX; /* x-cordinate of the vertical line to which this form is sticked. this variable is valid only while X_sticked==true*/
  static int prevCursorX;  /* x-cordinate of the cursor position at the moment this form was sticking to some vertical line*/
  static int stickedY;
  static int prevCursorY;
  static int X_attractor[2] = {0,Screen->Width - this->Width}; /*x-cordinates of all vertical lines to stick*/
  static int Y_attractor[2] = {0,Screen->Height - this->Height};
  int num_X_attractors = sizeof(X_attractor)/sizeof(int);
  int num_Y_attractors = sizeof(Y_attractor)/sizeof(int);

  if(X_sticked) /* if this form is sticked to some vertical line*/
    if( shift=GetCursorX()-prevCursorX , abs(shift)>=10 )
    { pRect->left+=shift; pRect->right+=shift; X_sticked=false; }
    else
    { shift=stickedX-pRect->left; pRect->left+=shift; pRect->right+=shift; }
  else  /* if this form is not yet sticked*/
    for(i=0 ; ileft , abs(shift)<=10 )
      {
        prevCursorX=GetCursorX(); stickedX=X_attractor[i];
        prevCursorX+=shift; pRect->left+=shift; pRect->right+=shift;
        X_sticked = true; break;
      }

  if(Y_sticked)
    if( shift=GetCursorY()-prevCursorY , abs(shift)>=10 )
    { pRect->top+=shift; pRect->bottom+=shift; Y_sticked=false; }
    else
    { shift=stickedY-pRect->top; pRect->top+=shift; pRect->bottom+=shift; }
  else
    for(i=0 ; itop , abs(shift)<=10 )
      {
        prevCursorY=GetCursorY(); stickedY=Y_attractor[i];
        prevCursorY+=shift; pRect->top+=shift; pRect->bottom+=shift;
        Y_sticked = true; break;
      }

  Msg.Result = true;
}
//=============================================================================
장성호 [nasilso]   2009-12-09 02:22 X
Delphi7 이후로
  ScreenSnap ,   SnapBuffer 라는 Form의 프로퍼티로 기본 기능으로 포함된 기능으로 알고 있습니다.

+ -

관련 글 리스트
317 전체화면의 경계에 윈도우가 착 달라붙게 하는 방법. 유지상 8366 2002/03/08
Google
Copyright © 1999-2015, borlandforum.com. All right reserved.