|
1. 뭐 소스 없이 이렇다 저렇다 말씀드릴 것은 안되겠습니다만...
MouseEnter, MouseLeave 메시지는 반드시 넘어온다는 보장은 없습니다.
윈도우 메시지가 아니라 컨트롤 메시지잖아요? (CM_ ... )
이는 재가공된 메시지기 때문에, 부모 컨트롤에서 감지해 주지 못하면 소용없습니다.
(갑자기 컨트롤 밖으로 나가거나, 마우스 메시지를 강제 해제(ReleaseCapture)했을 경우 등등)
굳이 완벽하게 그걸 하려면 쓰레드나 폴링을 해야되겠죠... (그럴 필요까지야 있겠습니까)
그런데 다이얼로그를 띄웠다가 나가는 정도의 처리에 다운 상태가 갱신되지 않는다는건,
다른문제가 있을 것 같군요.
가령,
void __fastcall TAButton::MouseUp(Controls::TMouseButton Button, Classes::TShiftState Shift, int X, int Y ){
inherited::MouseUp(Button, Shift, X, Y );
if (Enabled && Button == mbLeft){
if (!fGroupIndex) fDown = false; // Speed Button 처럼 그룹 인덱스를 지원할 경우
Invalidate();
}
}
이런식으로 Up을 구현하실때
inherited::MouseUp을 먼저 실행하시고 Invalidate하는게 맞죠.
저게 뒤로 가 있으면 문제의 소지가 있을겁니다. (MouseDown의 경우는 invalidate후 inherited::MouseDown)
이 문제가 아니라면,
VCL_MESSAGE_HANDLER(CM_MOUSEENTER, TMessage, CMMouseEnter)
VCL_MESSAGE_HANDLER(CM_MOUSELEAVE, TMessage, CMMouseLeave)
VCL_MESSAGE_HANDLER(CM_TEXTCHANGED, TMessage, CMTextChanged)
VCL_MESSAGE_HANDLER(CM_FONTCHANGED, TMessage, CMTextChanged)
VCL_MESSAGE_HANDLER(CM_ENABLEDCHANGED, TMessage, CMEnabledChanged)
이와 같은 메시지맵에서 EnabledChanged가 구현되었는지를 확인해 보시는게 좋을 것 같네요.
모달 다이얼로그면 Enabled가 변하니까...
그때도 잘 그려지게 CMEnabledCHanged와 같은 함수 안에서 Invalidate를 한번 넣어주시면 되리라 생각합니다.
2. KeyDataToShiftState(KeyData).Empty() 처럼하면 되겠죠.
skjoon 님이 쓰신 글 :
: TCustomControl을 상속받아서 간단한 버튼을 만들었습니다.
: MouseEnter, MouseLeave, Click 등의 이벤트 처리를 구현하였는데..
: 사용하다보니 작은(?)문제가 생겼습니다.
: 클릭해서 메시지박스를 띄운 후에 확인 버튼을 클릭하면..
: (화면 중앙에서 실행된 메시지 박스의 확인버튼을 클릭하느라 커서는 이미 버튼을 벗어난 상태이구요..)
: 아직도 제가 만든 버튼은 마우스가 Enter인 상태로 남아있습니다.
: XiButton을 참조해서 만들었는데.. 그녀석은 그런 현상이 없습니다.
:
: 혹시 저와 비슷한 경험을 하신분이 계시다면 도움을 부탁드리겠습니다.
:
: 그리고 또 하나.. XiButton의 소스인데요.. 파스칼..
:
: C++ 코드로 어떻게 바꿔야 하는지 궁금해서요..
: ----------------------------------------
: procedure TXiButton.CMDialogKey(var msg: TCMDialogKey);
: begin
: with msg do begin
: if (((CharCode = VK_RETURN) and FFocused) or
: ((CharCode = VK_ESCAPE) and FCancel)) and
: (KeyDataToShiftState(KeyData) = []) and CanFocus then
: begin
: Click;
: Result := 1;
: end else if (FDefault and (CharCode = VK_RETURN) and CanFocus) then begin
: Click;
: Result := 1;
: end
: else inherited;
: end;
: end;
: ----------------------------------------------------------
: 6 Line의 (KeyDataToShiftState(KeyData) = []) 입니다.
: Forms.hpp 파일에 보니 TShiftState 를 반환하는 것 같은데요..
: 반환되는 결과 중에 ssShift, ssCtrl, ssAlt 가 모두 포함되지 않음을 확인하는 것 같습니다.
: 단순하게 결과.Contains(ssShift), 결과.Contains(ssCtrl), 결과.Contains(ssAlt) 를 일일이 비교해야 하나요?
:
: 에효.. ^^;; 좋은 주말들 되세요.
|