문제

Having realised my own reasons were way too dubious, I've now gone about this a different way. But I'm still curious...

For reasons of nostalgia, familiarity and laziness, I'm coding a UI with MFC. For dubious reasons (as if those were not enough), I wanted to add a (double-)click event to a group box. Naturally, the group box contains things - in fact, it contains another static item, to which I can successfully add a (double-)click event handler.

Is there any reason I cannot get an event handler to work for clicks on my group box the same way I can do that for the simple text static item? No amount of clicking on, in or near the control fires the event.

Note - I've read through http://www.codeproject.com/KB/static/staticctrl_tut.aspx and tried responding to both ON_STN_... events and ON_BN_... messages, setting the notify style (BS_NOTIFY appears in the rc file)... and still I'm missing something - what is it? Is it even possible? Most of what I've googled suggests it is... but without clear answers for C++/MFC.

Since first posting this question, I've found reference to a WM_NCHITTEST message, and hints that you have to create a handler for this message to override the group box default behaviour of responding with HT_TRANSPARENT... despite having its transparent property in ClassWizard set to false. Hmmm. Can anyone confirm that this is indeed the key?

도움이 되었습니까?

해결책

I think WM_NCHHITTEST/HT_TRANSPARENT is indeed the key here.

Group boxes are an odd sort of control: while it looks like they contain other controls, they are actually siblings of those controls in the HWND tree. So a groupbox that looks like it contains two buttons is actually a sibling of those buttons - and could come before or after it in the HWND hierarchy.

Group boxes respond to WM_NCHITTEST with HT_TRANSPARENT, so that mouse clicks go right through them. One benefit of this is that it doesn't matter whether the group box comes before or after the controls that it appears to contain in the window order; the clicks will end up being routed to those controls, not the groupbox.

To get double-clicking (or just plain clicking) on the groupbox to work, you'd need to do two things:

  • override the default WM_NCHITTEST behavior and instead return HT_CLIENT, like a regular control
  • ; at this point it should be capable of getting WM_LBUTTONDOWN and related events that would otherwise have gone elsewhere (to a sibling, or to the dialog itself).
  • ensure that the contents of the groupbox come *before* it in the HWND z-order, so that they are no longer relying on clicks going 'through' the groupbox. (At least I think you want them to be before; either way, you may need to play with the HWND ordering now that it's significant again.)

Note that this is a different type of transparency again from the WS_EX_TRANSPARENT, which might be what the Transparent class wizard property maps to. Grossly simplified, HT_TRANSPARENT has to do with being transparent to the mouse; WS_EX_TRANSPARENT is more about being painted last so that siblings "show through".

라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top