여기와서 질문만 하다가 드디어 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;
}
//=============================================================================