본문 바로가기
C | C++ | VC++

Owner Draw Menu 에서 WM_MEASUREITEM의 itemWidth와 WM_DRAWITEM이 다른이유

by 두루물 2010. 9. 15.
윈도우즈 프로그래밍을 조금만 하다보면 컨트롤을 직접 만들거나 기존의 컨트롤을 Customizing 할 필요를 느낄 것이다.
여기서는 그 중에서도 커스텀 메뉴의 것에 대해 심심한 팁을 소개하고자 한다.

즉, WM_DRAWITEM이나 MFC의 OnDrawItem()에서의 처리를 말하는 것이다.

막상 이부분을 개발하다가 대부분의 사람들이 한가지 이해가 안가는 것이 있을 것이다.
그것은 아마도 아무리 MEASUREITEM에 값을 설정해도,실제로 DRAWITEM시의 사각 영역이 약 14 만큼 더 늘어나서 항상 들어온다 라는 사실..

과연 왜 그런가? 그 이유는 MS-윈도우즈가 내 윈도우의 프로시듀어가 메세지를 받도록 메세지큐에 전달하기 훨씬 이전에 이미 시스템 내부적으로 항상 CHECKBOX의 크기만큼 더해주기 때문에 그렇다.



It will be Increased to 14 pixel on DrawItem more than MeasureItem setting.

BOOL kxNSMenu::MeasureItem(LPMEASUREITEMSTRUCT lpMeasureItemStruct)
{

  dc.DrawText(pItem->szMenuText, rci, DT_CALCRECT|DT_SINGLELINE|DT_LEFT|DT_VCENTER);
  lpMeasureItemStruct->itemHeight = rci.Height();
  lpMeasureItemStruct->itemWidth = rci.Width();

}

BOOL kxNSMenu::DrawItem(LPDRAWITEMSTRUCT lpDrawItemStruct)
{
         lpDrawItemStruct->rcItem 's width more than 14 pixel...
}

why?

Windows will add the width of a menu checkmark,so you subtract more width as
 int cx = GetSystemMetrics(SM_CXMENUCHECK)-1;

따라서 결론은,아래 예시처럼 WM_MEASUREITEM 메세지에서 해당 부분의 소스를 이렇게 하면 된다.
CXMENUTEXTMARGIN 는 자신이 용도에 맞게 더해줄 Custom Margin 값이다.

BOOL kxNSMenu::MeasureItem(LPMEASUREITEMSTRUCT lpMeasureItemStruct)
{

  dc.DrawText(pItem->szMenuText, rci, DT_CALCRECT|DT_SINGLELINE|DT_LEFT|DT_VCENTER);
  lpMeasureItemStruct->itemHeight = rci.Height();
  lpMeasureItemStruct->itemWidth = rci.Width();

  lpMeasureItemStruct->itemWidth -= cx;  
  lpMeasureItemStruct->itemWidth += CXMENUTEXTMARGIN; // your margin

}


이 걸 모르면, 이미 상업용으로 전락한지 꽤 되는 국내 오합지졸의 메카 데브피아 같은 인력 포탈 시장 바닥에 올라온 수준처럼 0으로 주었는데 왜 작은 사각박스가 계속 뜨냐는둥의 삽질 질/답 드립을 하게 된다.

만일 메뉴아이템 크기를 0 으로 원하면  lpMeasureItemStruct->itemWidth = 0 할 것이 아니라
lpMeasureItemStruct->itemWidth -= GetSystemMetrics(SM_CXMENUCHECK); 해야 된다는 것이다.

사실,이런 부분은 MS 제품군의 사용자(개발자)의 삽질이라는 표현보다는 파보면 파볼수록 이런식으로 엉성하게 밖에 만들지 못한 MS의 자체 제품군의 로직에서 조차 들쑥 날쑥한 비표준의 극치를 달리는 삽질이라고 해야 옳다.

현실의 굴레에 갇혀서 또 이런 것을 알면서도 어쩔수 없이 써야만 하는 뭇 개발자들의 심정은 어떠할까?
이글을 발견하지 않고도 이걸 이미 알고 있던 사람은 윈도우즈 메카니즘을 어느정도 꿰뚫고 이해한 중고렙이상의 경험치를 쌓은 개발자라 인정한다.
더 궁금하다면
kxLibrary 나 well-done coolmenu 소스를 보시라!

출처:http://krkim.net/34