|
아래와 같이 몹시 Visual Studio의 Form Editor와 같은 프로그램이 있다고 하자. 여기서 버튼을 마우스로 클릭을 하고 드래그를 해서 이동하는 코드를 만들고 싶다고 하자. ![]() 일단 가장 간단하게 떠오를 수 있는 방법은:
정도가 될 것이다. 그런데 여기에서 부족한 점이 하나 있다. 바로 Drag Threshold를 고려하지 않았다는 점이다. 이걸 첨 들어보셨다면 한 번 바탕화면에 있는 아이콘 하나를 드래그를 해보기를 바란다. 마우스를 조심스래 클릭하고 아주 작은 움직임, 한두 픽셀 정도를 살짝 움직여 봐라. 아마 아무런 반응이 없을 것이다. 여기서 다시 마우스를 버튼을 놓으면 어떠한 드래그도 일어나지 않는다. 드래그를 하기 위해서는 마우스 왼쪽 버튼을 클릭한 채로 움직임이 최소 몇 픽셀 이상 되어야만 한다. 마치 물리학 책에 나오는 최대정지마찰력과 같은 개념이다. 이건 사용자의 실수를 막기 위해 둔 장치이다. 위의 방법은 어떤 문제가 있냐면, 사용자가 해당 컨트롤를 클릭만 하고 1~2픽셀만 움직여도 그만 컨트롤이 움직이는 일이 벌어진다는 것이다. 이걸 그대로 두면 상당히 짜증난다. 따라서 드래그를 구현할 때는 반드시 이런 문턱 값을 넘을 때 까지는 드래그를 진행해서는 안된다. 다시 위의 그림에서 컨트롤 드래그 방법을 생각해보자. 사실 나는 위의 각 메세지 핸들러에 드래그 관련 코드를 쭉 분산 시키는 것을 좋아하지 않는다.내가 좋아하는 방법은 일반적인 OLE Drag & Drop을 바로 이용하는 것이다. 그러면 Ctrl + 드래그&드랍을 바로 카피로 구현할 수도 있고 편해진다. MFC를 이용하면 COleDataSource::DoDragDrop를 이용해서 처리한다. 실제 이 COleDataSource (C:\Program Files\Microsoft Visual Studio 8\VC\atlmfc\src\mfc\oledrop1.cpp)의 OnBeginDrag 메소드에는 언급한 drag threshold를 처리하고 있다. BOOL COleDropSource::OnBeginDrag(CWnd* pWnd) 코드에서 보다시피 메세지 큐를 계속 읽어와서 마우스 움직임이 m_rectStartDrag에 정의된 값 보다 크다면 (예를 들어, x/y 방향 중 어느 한 쪽이라도 4픽셀보다 크게 움직인다면) drag가 시작되었다고 판단한다. 또, 특정 시간 이후가 지나도 드래그로 인식하도록 하고 있다. 요렇게 간단히 드래그에도 이런 복잡함이 숨어있다는 사실. UI 프로그래밍은 이렇게 미묘한 것이 쌓여 엄청난 차이를 주기 때문에 이런 미묘한 것도 주의 깊게 관찰하는 센스가 필요하다. p.s. 또 하나 이런 드래그 코드를 두는 방법은 드래그 시작이 감지되었을 때 자체 메세지 루프를 돌리는 것이다. 이런 경우 관련 코드를 한 곳에 모을 수 있고 불필요한 클래스 변수를 하나 없앨 수 있는 장점이 있다. // OnBeginDrag 코드를 대략 카피해서 만든 녀석
최근 등록된 덧글
zzzzzzzzzzzzzzzzz..
by xxx at 23:10 저도 논문을 위해 작문위주의.. by Gerald at 10/11 opaque type은 내부를 알 .. by 몽몽이 at 10/09 샘이님 말씀에 한 표~ ^^;; by 엽우 at 10/09 Globefish 라는 Firefox .. by nurigis at 10/09 커스텀 사전에서 명사로 등.. by 게드 at 10/09 그렇네요. 제가 가지고 있는.. by object at 10/09 전산용어가 되면 뭐든지 셀 .. by 샘이 at 10/09 최근 등록된 트랙백
|