레이저마우스의 WHEEL_DELTA...

@codemaru · December 04, 2007 · 8 min read

제가 집에서 원래 사용하던 마우스는 마이크로소프트 익스플로러 3.0 버전 새로 나온 것 이었습니다. 마우스가 워낙 인기가 있다보니 단종됐다가도 다시 나오곤 하더군요. 좀 커서 손이 부담스러웠는데 쓰다보니 또 익숙해지고 그랬습니다. 그렇게 불편함 없이 사용하다 버튼이 고장나서 한 번만 클릭을해도 더블 클릭이 되는 현상이 발생하더군요. 억지로 참고 쓰다, 버튼 스왑해서 쓰다가 결국 그냥 마이크로소프트의 노트북용 무선 레이저 마우스로 교체했습니다.

        WHEEL DELTA    md 0

마우스 감도도 좋고, 무선이니깐 편하기도 하고 좋았습니다. 그런데 왠걸 이 놈은 이상하게 휠이 자꾸 저의 의도처럼 움직이질 않더군요. 파폭이나, 탐색기같은데는 괜찮은데 소스 인사이트가 특히 이상하더군요. 한참을 휠을 돌려야 겨우 한 페이지 정도 올라가는게 아니겠습니까? 인터넷을 찾아봐도 관련 정보를 찾을 수가 없었습니다. 그러다 어제 소리통 코드를 짜다가 소리통의 재생 목록 스크롤도 소스 인사이트처럼 버벅 거린다는 사실을 알게 되었죠. 그리고 그 레이저 마우스의 심오함을 MSDN을 통해서 알게되었습니다. ㅋㅋ

일반적으로 휠 마우스가 날려주는 WM_MOUEWHEEL 메시지의 WPARAM에는 delta값이 넘어옵니다. 휠을 얼만큼 스크롤을 시켰냐하는 것이죠. 돌리는 방향은 양수, 음수로 계산합니다. 일반적으로 구형 마우스의 경우에는 이 값은 거의 변동 없이 WHEEL_DELTA의 배수로 넘어옵니다. WHEEL_DELTA가 120으로 정의되어 있기 때문에 +120, -120, +240 따위의 값으로 넘어오는 거죠. 그래서 보통은 휠 코드를 아래와 같이 많이 작성합니다.

LRESULT CPlayListBox::OnMouseWheel(UINT, short delta, CPoint)  
{  
    UINT lines;  
    SystemParametersInfo(SPI\_GETWHEELSCROLLLINES, 0, &lines, 0);  
    VScroll(-delta / WHEEL\_DELTA \* lines);  
    return 0;  
}

lines는 한번 스크롤 시켰을 때 얼마씩 페이지를 넘길지를 정해둔 값 입니다. 보통 제어판에서 설정하도록 되어있습니다. 위 코드는 delta가 120이면 lines만큼, 240이면 2*lines만큼 스크롤을 시킵니다. 구형 마우스에서는 별 문제 없이 동작하죠. 왜냐하면 delta값이 항상 WHEEL_DELTA의 배수로 넘어오기 때문입니다.

하지만 제가 새로 장착한 그 레이저 마우스는 틀렸습니다. 친절하게도 사용자가 조금 휠을 돌리면 28따위의 작은 값을 보내주는게 아니겠습니까? 따라서 쌩하고 한바퀴를 돌리기 전까지 절때 delta값이 120이상 나오지 않고, 결국 WHEEL_DELTA로 나눈 값은 0이 되어서 스크롤이 안됐던 겁니다. 물론 MSDN에는 이것에 대해서 상세하게 코멘트가 되어 있었습니다. 사용자가 조금 돌린만큼 친절하게 알려주는 마우스들도 있기 때문에 그 값을 저장해서 WHEEL_DELTA만큼 됐을때 스크롤을 시키거나 아니면 부분 값으로 스크롤 시킬 수 있는 만큼 스크롤을 시키라고 되어 있더군요. 그래서 휠 코드를 아래와 같이 고쳤습니다.

LRESULT CPlayListBox::OnMouseWheel(UINT, short d, CPoint)  
{  
    static int delta = 0;  
    UINT lines;  
    SystemParametersInfo(SPI\_GETWHEELSCROLLLINES, 0, &lines, 0);  
  
    delta += d \* lines;  
    if(abs(delta) < WHEEL\_DELTA)  
        return 0;  
  
    VScroll(-delta / WHEEL\_DELTA);  
    delta %= WHEEL\_DELTA;  
    return 0;  
}

특별한 건 없고, 값을 저장 시켜 두었다가 스크롤 시킬 수 있는 만큼이 되면 스크롤을 시켜줍니다. 이 코드로 변경하고 나니 스크롤이 정말 친절하게 잘 되더군요. 저의 의도대로 한줄씩 할 수도 있고, 한번에 팍팍 내려갈 수도 있었습니다. 이런 짓을 해보기 전까지는 그 레이저 마우스의 휠에 어떤 특별한 기능이 있다는 것을 알지 못했습니다. 그러나 이제는 그 마우스를 사용하면 한줄씩 스크롤을 할 수 있다는 사실을 알게되었죠. 노트북에서 사용하는 마우스도 바꾸어야 겠습니다. 한 번 편리함을 경험하고 난다음 돌아가기란 쉽지 않죠. 세 줄씩 휙휙 넘어가는 마우스의 불편함이란 ^^;;

XP에서의 WHEEL_DELTA
위의 내용은 모두 Vista에서 테스트했던 내용입니다. 집에있던 레이저 마우스를 회사에 들고와서 XP에서 테스트 해보았습니다. 그런데 도저히 컨트롤을 해도 한줄씩 스크롤을 할 수가 없더군요. 왜 그럴까 하다가 간단한 휠 테스트 프로그램을 만들어 보았습니다.

        WHEEL DELTA    md 1
휠에 넘어오는 delta값을 출력해본 것 입니다. 죄다 120의 배수임을 알 수 있습니다. 어떻게 돌려도 무조건 120의 배수가 나오죠. 그렇다면 전용 드라이버를 설치하지 않아서 그런 것일까하는 생각에 시디를 뜯어서 인텔리 마우스 전용 드라이버를 설치해 주었습니다. 설치하고 나서도 결과는 별반 차이가 없더군요.

        WHEEL DELTA    md 2
제어판에 마우스 등록 정보를 살펴봤습니다. 전용 드라이버답게 다양한 옵션이 추가되었더군요. 그 중에 하나가 위에서 보이는 가속 스크롤 기능입니다. 체크를 하고 테스트를 해보았습니다.

        WHEEL DELTA    md 3
뭔가 120으로 떨어지지 않는 숫자가 많이 보이죠. 그런데 안타깝게도 120아래에 있는 숫자는 보질 못했습니다. 즉 아무리 조금 돌려도 XP에서는 기본 120은 먹고 들어가더군요. ㅠㅠ 결국은 한 줄씩 스크롤을 할 수 없다는 이야기 일까요? 하드웨어가 좋아도 운영체제가 구리면 기능을 다 사용하지 못하는 경우도 있나봅니다. ㅎㅎ

@codemaru
돌아보니 좋은 날도 있었고, 나쁜 날도 있었다. 그런 나의 모든 소소한 일상과 배움을 기록한다. 여기에 기록된 모든 내용은 한 개인의 관점이고 의견이다. 내가 속한 조직과는 1도 상관이 없다.
(C) 2001 YoungJin Shin, 0일째 운영 중