当全局Hook到回车键按下时, 在对话框中响应自定义消息.
因为回车键的处理好多. 也不想封装成函数单独调用. 这样工作量多了.
我想在自定义消息中, 直接模拟Duilib按钮的点击. 这样, 原来的代码一点不用改.
但是DuiLib的库要改改, 现在看起来没有副作用.
LRESULT CDlgLogin::WndMessageProc_WM_ENTER_KEY_PRESS(UINT uMsg, WPARAM wParam, LPARAM lParam)
{
TEventUI event;
POINT pt;
pt.x = m_pBtnOk->GetPos().left;
pt.y = m_pBtnOk->GetPos().top;
event.Type = UIEVENT_BUTTONUP;
event.pSender = m_pBtnOk;
event.wParam = wParam;
event.lParam = lParam;
event.ptMouse = pt;
event.wKeyState = (WORD)wParam;
event.dwTimestamp = ::GetTickCount();
m_pBtnOk->AddButtonStateBit(UISTATE_CAPTURED); ///< ! 这是我刚添加的方法
m_pBtnOk->DoEvent(event);
return S_OK;
}
void CButtonUI::AddButtonStateBit(UINT uFlagBits)
{
m_uButtonState |= uFlagBits;
}
添加这个方法的原因 : 在DuiLib::CButtonUI 处理点击消息时, 要判断这个 按钮状态 要具有 UISTATE_CAPTURED, 才认为是按钮已经被按下过, 现在是键盘抬起, 算作click.
BOOL CButtonUI::DoEvent(TEventUI& event)
{
if( !IsMouseEnabled() && event.Type > UIEVENT__MOUSEBEGIN && event.Type < UIEVENT__MOUSEEND ) {
if( m_pParent != NULL ) m_pParent->DoEvent(event);
else CLabelUI::DoEvent(event);
return TRUE;
}
if( event.Type == UIEVENT_SETFOCUS )
{
Invalidate();
}
if( event.Type == UIEVENT_KILLFOCUS )
{
Invalidate();
}
if( event.Type == UIEVENT_KEYDOWN )
{
if (IsKeyboardEnabled()) {
if( event.chKey == VK_SPACE || event.chKey == VK_RETURN ) {
Activate();
return TRUE;
}
}
}
if( event.Type == UIEVENT_BUTTONDOWN || event.Type == UIEVENT_DBLCLICK )
{
if( ::PtInRect(&m_rcItem, event.ptMouse) && IsEnabled() ) {
m_uButtonState |= UISTATE_PUSHED | UISTATE_CAPTURED;
Invalidate();
}
return TRUE;
}
if( event.Type == UIEVENT_MOUSEMOVE )
{
if( (m_uButtonState & UISTATE_CAPTURED) != 0 ) {
if( ::PtInRect(&m_rcItem, event.ptMouse) ) m_uButtonState |= UISTATE_PUSHED;
else m_uButtonState &= ~UISTATE_PUSHED;
Invalidate();
}
return TRUE;
}
<span style="color:#ff0000;">if( event.Type == UIEVENT_BUTTONUP )
{
if( (m_uButtonState & UISTATE_CAPTURED) != 0 ) {
if( ::PtInRect(&m_rcItem, event.ptMouse) ) Activate();
m_uButtonState &= ~(UISTATE_PUSHED | UISTATE_CAPTURED);
Invalidate();
}
return TRUE;
}</span>
...
执行Activate()后, 会进入dialog的OnClick处理
void CDlgLogin::OnClick(TNotifyUI& msg)
{
std::wstring strName = L"";
std::wstring strUserName = L"";
std::wstring strPwd = L"";
if ((NULL == msg.pSender)
|| (NULL == m_pOwner))
{
return;
}
else if (m_pBtnClose == msg.pSender)
{
OutputDebugStringW(L"关闭按钮-被按下\r\n");
::PostMessageW(this->GetHWND(), WM_CLOSE, 0, 0);
}
else if (m_pBtnOk == msg.pSender)
{
<span style="color:#ff0000;">OutputDebugStringW(L"登录按钮-被按下\r\n");</span>
strUserName = m_pEditUserName->GetText().GetData();
strPwd = m_pEditPwd->GetText().GetData();
m_AuthorInfo.SetData(
((_tcslen(strUserName.c_str()) > 0) && (_tcslen(strPwd.c_str()) > 0)),
strUserName.c_str(),
strPwd.c_str());
if (m_AuthorInfo.IsValidData())
{
::PostMessageW(this->GetHWND(), WM_CLOSE, 0, 0);
}
else
{
if (_tcslen(strUserName.c_str()) <= 0)
m_pEditUserName->SetFocus();
else
m_pEditPwd->SetFocus();
OutputDebugStringW(L"用户名和口令输入无效, 请重新输入\r\n");
}
}