DUILIB热键

本文档详细介绍了DUILIB中CHotKeyWnd和CHotKeyUI类的实现,用于创建和管理热键。内容包括类的构造、初始化、窗口创建、消息处理以及热键设置和获取的方法。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

#ifndef __UIHOTKEY_H__
#define __UIHOTKEY_H__


#pragma once


namespace DuiLib{


class CHotKeyUI;


class UILIB_API CHotKeyWnd : public CWindowWnd
{
public:
CHotKeyWnd(void);
public:
void Init(CHotKeyUI * pOwner);
RECT CalPos();
LPCTSTR GetWindowClassName() const;
void OnFinalMessage(HWND hWnd);
LPCTSTR GetSuperClassName() const;
LRESULT HandleMessage(UINT uMsg, WPARAM wParam, LPARAM lParam);
LRESULT OnKillFocus(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled);
LRESULT OnEditChanged(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled);
public:
void SetHotKey(WORD wVirtualKeyCode, WORD wModifiers);
void GetHotKey(WORD &wVirtualKeyCode, WORD &wModifiers) const;
CStdString GetHotKeyName();
void SetRules(WORD wInvalidComb, WORD wModifiers);
CStdString GetKeyName(UINT vk, BOOL fExtended);
protected:
CHotKeyUI * m_pOwner;
HBRUSH m_hBkBrush;
bool m_bInit;
};


class UILIB_API CHotKeyUI : public CLabelUI
{
friend CHotKeyWnd;
public:
CHotKeyUI();
LPCTSTR GetClass() const;
LPVOID GetInterface(LPCTSTR pstrName);
UINT GetControlFlags() const;
void SetEnabled(bool bEnable = true);
void SetText(LPCTSTR pstrText);
LPCTSTR GetNormalImage();
void SetNormalImage(LPCTSTR pStrImage);
LPCTSTR GetHotImage();
void SetHotImage(LPCTSTR pStrImage);
LPCTSTR GetFocusedImage();
void SetFocusedImage(LPCTSTR pStrImage);
LPCTSTR GetDisabledImage();
void SetDisabledImage(LPCTSTR pStrImage);
void SetNativeBkColor(DWORD dwBkColor);
DWORD GetNativeBkColor() const;


void SetPos(RECT rc);
void SetVisible(bool bVisible = true);
void SetInternVisible(bool bVisible = true);
SIZE EstimateSize(SIZE szAvailable);
void DoEvent(TEventUI& event);
void SetAttribute(LPCTSTR pstrName, LPCTSTR pstrValue);


void PaintStatusImage(HDC hDC);
void PaintText(HDC hDC);
public:
void GetHotKey(WORD &wVirtualKeyCode, WORD &wModifiers) const;
void SetHotKey(WORD wVirtualKeyCode, WORD wModifiers);
protected:
CHotKeyWnd * m_pWindow;
UINT m_uButtonState;
CStdString m_sNormalImage;
CStdString m_sHotImage;
CStdString m_sFocusedImage;
CStdString m_sDisabledImage;
DWORD m_dwHotKeybkColor;
protected:
WORD m_wVirtualKeyCode;
WORD m_wModifiers;
};


}


#endif



#include "stdafx.h"
#include "UIHotKey.h"


namespace DuiLib{


CHotKeyWnd::CHotKeyWnd(void) : m_pOwner(NULL), m_hBkBrush(NULL), m_bInit(false)
{
}


void CHotKeyWnd::Init(CHotKeyUI * pOwner)
{
m_pOwner = pOwner;
do 
{
if (NULL == m_pOwner)
{
break;
}
RECT rcPos = CalPos();
UINT uStyle = WS_CHILD | ES_AUTOHSCROLL;
HWND hWnd = Create(m_pOwner->GetManager()->GetPaintWindow(), NULL, uStyle, 0, rcPos);
if (!IsWindow(hWnd))
{
break;
}
SetWindowFont(m_hWnd, m_pOwner->GetManager()->GetFontInfo(m_pOwner->GetFont())->hFont, TRUE);
SetHotKey(m_pOwner->m_wVirtualKeyCode, m_pOwner->m_wModifiers);
m_pOwner->m_sText = GetHotKeyName();
::EnableWindow(m_hWnd, m_pOwner->IsEnabled() == true);
::ShowWindow(m_hWnd, SW_SHOWNOACTIVATE);
::SetFocus(m_hWnd);
m_bInit = true;   
} while (0); 
}


RECT CHotKeyWnd::CalPos()
{
CRect rcPos = m_pOwner->GetPos();
RECT rcInset = m_pOwner->GetTextPadding();
rcPos.left += rcInset.left;
rcPos.top += rcInset.top;
rcPos.right -= rcInset.right;
rcPos.bottom -= rcInset.bottom;
LONG lHeight = m_pOwner->GetManager()->GetFontInfo(m_pOwner->GetFont())->tm.tmHeight;
if( lHeight < rcPos.GetHeight() ) {
rcPos.top += (rcPos.GetHeight() - lHeight) / 2;
rcPos.bottom = rcPos.top + lHeight;
}
return rcPos;
}


LPCTSTR CHotKeyWnd::GetWindowClassName() const
{
return _T("HotKeyClass");
}


void CHotKeyWnd::OnFinalMessage(HWND /*hWnd*/)
{
// Clear reference and die
if( m_hBkBrush != NULL ) ::DeleteObject(m_hBkBrush);
m_pOwner->m_pWindow = NULL;
delete this;
}

LRESULT CHotKeyWnd::HandleMessage(UINT uMsg, WPARAM wParam, LPARAM lParam)
{
LRESULT lRes = 0;
BOOL bHandled = TRUE;
if( uMsg == WM_KILLFOCUS ) lRes = OnKillFocus(uMsg, wParam, lParam, bHandled);
else if( uMsg == OCM_COMMAND ) {
if( GET_WM_COMMAND_CMD(wParam, lParam) == EN_CHANGE ) lRes = OnEditChanged(uMsg, wParam, lParam, bHandled);
else if( GET_WM_COMMAND_CMD(wParam, lParam) == EN_UPDATE ) {
RECT rcClient;
::GetClientRect(m_hWnd, &rcClient);
::InvalidateRect(m_hWnd, &rcClient, FALSE);
}
}
else if( uMsg == WM_KEYDOWN && TCHAR(wParam) == VK_RETURN ) {
m_pOwner->GetManager()->SendNotify(m_pOwner, _T("return"));
}
else if ( (uMsg == WM_NCACTIVATE) || (uMsg == WM_NCACTIVATE) || (uMsg == WM_NCCALCSIZE) )
{
return 0;
}
else if (uMsg == WM_PAINT)
{
PAINTSTRUCT ps = { 0 };
HDC hDC = ::BeginPaint(m_hWnd, &ps);
DWORD dwTextColor = m_pOwner->GetTextColor();
DWORD dwBkColor = m_pOwner->GetNativeBkColor();
CStdString strText = GetHotKeyName();
::RECT rect;
::GetClientRect(m_hWnd, &rect);
::SetBkMode(hDC, TRANSPARENT);
::SetTextColor(hDC, RGB(GetBValue(dwTextColor), GetGValue(dwTextColor), GetRValue(dwTextColor)));
HBRUSH hBrush =  CreateSolidBrush( RGB(GetBValue(dwBkColor), GetGValue(dwBkColor), GetRValue(dwBkColor)) );
::FillRect(hDC, &rect, hBrush);
::DeleteObject(hBrush);
HFONT hOldFont = (HFONT)SelectObject(hDC, GetWindowFont(m_hWnd));
::SIZE size = { 0 };
::GetTextExtentPoint32(hDC, strText.GetData(), strText.GetLength(), &size) ;
::DrawText(hDC, strText.GetData(), -1, &rect, DT_LEFT|DT_SINGLELINE|DT_END_ELLIPSIS|DT_NOPREFIX);
::SelectObject(hDC, hOldFont);
::SetCaretPos(size.cx, 0);
::EndPaint(m_hWnd, &ps);
bHandled = TRUE;
}
else bHandled = FALSE;
if( !bHandled ) return CWindowWnd::HandleMessage(uMsg, wParam, lParam);
return lRes;
}


LPCTSTR CHotKeyWnd::GetSuperClassName() const
{
return HOTKEY_CLASS;
}


LRESULT CHotKeyWnd::OnKillFocus(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled)
{
LRESULT lRes = ::DefWindowProc(m_hWnd, uMsg, wParam, lParam);
::SendMessage(m_hWnd, WM_CLOSE, 0, 0);
return lRes;
}


LRESULT CHotKeyWnd::OnEditChanged(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled)
{
if( !m_bInit ) return 0;
if( m_pOwner == NULL ) return 0;
GetHotKey(m_pOwner->m_wVirtualKeyCode, m_pOwner->m_wModifiers);
if (m_pOwner->m_wVirtualKeyCode == 0)
{
m_pOwner->m_sText = _T("无");
m_pOwner->m_wModifiers = 0;
}
else
{
m_pOwner->m_sText = GetHotKeyName();
}
m_pOwner->GetManager()->SendNotify(m_pOwner, _T("textchanged"));
return 0;
}


void CHotKeyWnd::SetHotKey(WORD wVirtualKeyCode, WORD wModifiers)
{
ASSERT(::IsWindow(m_hWnd));  
::SendMessage(m_hWnd, HKM_SETHOTKEY, MAKEWORD(wVirtualKeyCode, wModifiers), 0L);
}


void CHotKeyWnd::GetHotKey(WORD &wVirtualKeyCode, WORD &wModifiers) const
{
ASSERT(::IsWindow(m_hWnd));
LRESULT dw = ::SendMessage(m_hWnd, HKM_GETHOTKEY, 0, 0L);
wVirtualKeyCode = LOBYTE(LOWORD(dw));
wModifiers = HIBYTE(LOWORD(dw));
}


void CHotKeyWnd::SetRules(WORD wInvalidComb, WORD wModifiers)

ASSERT(::IsWindow(m_hWnd));  
::SendMessage(m_hWnd, HKM_SETRULES, wInvalidComb, MAKELPARAM(wModifiers, 0)); 
}


CStdString CHotKeyWnd::GetKeyName(UINT vk, BOOL fExtended)
{
LONG lScan = MapVirtualKey(vk, 0) << 16;


// if it's an extended key, add the extended flag
if (fExtended)
lScan |= 0x01000000L;


TCHAR szStr[MAX_PATH] = { 0 };
::GetKeyNameText(lScan, szStr, MAX_PATH - 1);


return CStdString(szStr);
}


CStdString CHotKeyWnd::GetHotKeyName()
{
ASSERT(::IsWindow(m_hWnd));


CStdString strKeyName;
WORD wCode = 0;
WORD wModifiers = 0;
const TCHAR szPlus[] = _T(" + ");


GetHotKey(wCode, wModifiers);
if (wCode != 0 || wModifiers != 0)
{
if (wModifiers & HOTKEYF_CONTROL)
{
strKeyName += GetKeyName(VK_CONTROL, FALSE);
strKeyName += szPlus;
}


if (wModifiers & HOTKEYF_SHIFT)
{
strKeyName += GetKeyName(VK_SHIFT, FALSE);
strKeyName += szPlus;
}


if (wModifiers & HOTKEYF_ALT)
{
strKeyName += GetKeyName(VK_MENU, FALSE);
strKeyName += szPlus;
}


strKeyName += GetKeyName(wCode, wModifiers & HOTKEYF_EXT);
}


return strKeyName;
}


//////////////////////////////////////////////////////////////////////////
CHotKeyUI::CHotKeyUI() : m_pWindow(NULL), m_wVirtualKeyCode(0), m_wModifiers(0), m_uButtonState(0), m_dwHotKeybkColor(0xFFFFFFFF)
{
SetTextPadding(CRect(4, 3, 4, 3));
SetBkColor(0xFFFFFFFF);
}


LPCTSTR CHotKeyUI::GetClass() const
{
return _T("HotKeyUI");
}


LPVOID CHotKeyUI::GetInterface(LPCTSTR pstrName)
{
if( _tcscmp(pstrName, _T("HotKey")) == 0 ) return static_cast<CHotKeyUI *>(this);
return CLabelUI::GetInterface(pstrName);
}


UINT CHotKeyUI::GetControlFlags() const
{
if( !IsEnabled() ) return CControlUI::GetControlFlags();


return UIFLAG_SETCURSOR | UIFLAG_TABSTOP;
}


void CHotKeyUI::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;
}


if( event.Type == UIEVENT_SETCURSOR && IsEnabled() )
{
::SetCursor(::LoadCursor(NULL, MAKEINTRESOURCE(IDC_IBEAM)));
return;
}
if( event.Type == UIEVENT_WINDOWSIZE )
{
if( m_pWindow != NULL ) m_pManager->SetFocusNeeded(this);
}
if( event.Type == UIEVENT_SCROLLWHEEL )
{
if( m_pWindow != NULL ) return;
}
if( event.Type == UIEVENT_SETFOCUS && IsEnabled() ) 
{
if( m_pWindow ) return;
m_pWindow = new CHotKeyWnd();
ASSERT(m_pWindow);
m_pWindow->Init(this);
Invalidate();
}
if( event.Type == UIEVENT_KILLFOCUS && IsEnabled() ) 
{
Invalidate();
}
if( event.Type == UIEVENT_BUTTONDOWN || event.Type == UIEVENT_DBLCLICK || event.Type == UIEVENT_RBUTTONDOWN) 
{
if( IsEnabled() ) {
GetManager()->ReleaseCapture();
if( IsFocused() && m_pWindow == NULL )
{
m_pWindow = new CHotKeyWnd();
ASSERT(m_pWindow);
m_pWindow->Init(this);
}
}
return;
}
if( event.Type == UIEVENT_MOUSEMOVE ) 
{
return;
}
if( event.Type == UIEVENT_BUTTONUP ) 
{
return;
}
if( event.Type == UIEVENT_CONTEXTMENU )
{
return;
}
if( event.Type == UIEVENT_MOUSEENTER )
{
if( IsEnabled() ) {
m_uButtonState |= UISTATE_HOT;
Invalidate();
}
return;
}
if( event.Type == UIEVENT_MOUSELEAVE )
{
if( IsEnabled() ) {
m_uButtonState &= ~UISTATE_HOT;
Invalidate();
}
return;
}
CLabelUI::DoEvent(event);
}


void CHotKeyUI::SetEnabled(bool bEnable)
{
CControlUI::SetEnabled(bEnable);
if( !IsEnabled() ) {
m_uButtonState = 0;
}
}


void CHotKeyUI::SetText(LPCTSTR pstrText)
{
m_sText = pstrText;
if( m_pWindow != NULL ) Edit_SetText(*m_pWindow, m_sText);
Invalidate();
}


LPCTSTR CHotKeyUI::GetNormalImage()
{
return m_sNormalImage;
}


void CHotKeyUI::SetNormalImage(LPCTSTR pStrImage)
{
m_sNormalImage = pStrImage;
Invalidate();
}


LPCTSTR CHotKeyUI::GetHotImage()
{
return m_sHotImage;
}


void CHotKeyUI::SetHotImage(LPCTSTR pStrImage)
{
m_sHotImage = pStrImage;
Invalidate();
}


LPCTSTR CHotKeyUI::GetFocusedImage()
{
return m_sFocusedImage;
}


void CHotKeyUI::SetFocusedImage(LPCTSTR pStrImage)
{
m_sFocusedImage = pStrImage;
Invalidate();
}


LPCTSTR CHotKeyUI::GetDisabledImage()
{
return m_sDisabledImage;
}


void CHotKeyUI::SetDisabledImage(LPCTSTR pStrImage)
{
m_sDisabledImage = pStrImage;
Invalidate();
}


void CHotKeyUI::SetNativeBkColor(DWORD dwBkColor)
{
m_dwHotKeybkColor = dwBkColor;
}


DWORD CHotKeyUI::GetNativeBkColor() const
{
return m_dwHotKeybkColor;
}


void CHotKeyUI::SetPos(RECT rc)
{
CControlUI::SetPos(rc);
if( m_pWindow != NULL ) {
RECT rcPos = m_pWindow->CalPos();
::SetWindowPos(m_pWindow->GetHWND(), NULL, rcPos.left, rcPos.top, rcPos.right - rcPos.left, 
rcPos.bottom - rcPos.top, SWP_NOZORDER | SWP_NOACTIVATE);        
}
}


void CHotKeyUI::SetVisible(bool bVisible)
{
CControlUI::SetVisible(bVisible);
if( !IsVisible() && m_pWindow != NULL ) m_pManager->SetFocus(NULL);
}


void CHotKeyUI::SetInternVisible(bool bVisible)
{
if( !IsVisible() && m_pWindow != NULL ) m_pManager->SetFocus(NULL);
}


SIZE CHotKeyUI::EstimateSize(SIZE szAvailable)
{
if( m_cxyFixed.cy == 0 ) return CSize(m_cxyFixed.cx, m_pManager->GetFontInfo(GetFont())->tm.tmHeight + 6);
return CControlUI::EstimateSize(szAvailable);
}


void CHotKeyUI::SetAttribute(LPCTSTR pstrName, LPCTSTR pstrValue)
{
if( _tcscmp(pstrName, _T("normalimage")) == 0 ) SetNormalImage(pstrValue);
else if( _tcscmp(pstrName, _T("hotimage")) == 0 ) SetHotImage(pstrValue);
else if( _tcscmp(pstrName, _T("focusedimage")) == 0 ) SetFocusedImage(pstrValue);
else if( _tcscmp(pstrName, _T("disabledimage")) == 0 ) SetDisabledImage(pstrValue);
else if( _tcscmp(pstrName, _T("nativebkcolor")) == 0 ) {
if( *pstrValue == _T('#')) pstrValue = ::CharNext(pstrValue);
LPTSTR pstr = NULL;
DWORD clrColor = _tcstoul(pstrValue, &pstr, 16);
SetNativeBkColor(clrColor);
}
else CLabelUI::SetAttribute(pstrName, pstrValue);
}


void CHotKeyUI::PaintStatusImage(HDC hDC)
{
if( IsFocused() ) m_uButtonState |= UISTATE_FOCUSED;
else m_uButtonState &= ~ UISTATE_FOCUSED;
if( !IsEnabled() ) m_uButtonState |= UISTATE_DISABLED;
else m_uButtonState &= ~ UISTATE_DISABLED;


if( (m_uButtonState & UISTATE_DISABLED) != 0 ) {
if( !m_sDisabledImage.IsEmpty() ) {
if( !DrawImage(hDC, (LPCTSTR)m_sDisabledImage) ) m_sDisabledImage.Empty();
else return;
}
}
else if( (m_uButtonState & UISTATE_FOCUSED) != 0 ) {
if( !m_sFocusedImage.IsEmpty() ) {
if( !DrawImage(hDC, (LPCTSTR)m_sFocusedImage) ) m_sFocusedImage.Empty();
else return;
}
}
else if( (m_uButtonState & UISTATE_HOT) != 0 ) {
if( !m_sHotImage.IsEmpty() ) {
if( !DrawImage(hDC, (LPCTSTR)m_sHotImage) ) m_sHotImage.Empty();
else return;
}
}


if( !m_sNormalImage.IsEmpty() ) {
if( !DrawImage(hDC, (LPCTSTR)m_sNormalImage) ) m_sNormalImage.Empty();
else return;
}
}


void CHotKeyUI::PaintText(HDC hDC)
{
if( m_dwTextColor == 0 ) m_dwTextColor = m_pManager->GetDefaultFontColor();
if( m_dwDisabledTextColor == 0 ) m_dwDisabledTextColor = m_pManager->GetDefaultDisabledColor();


if( m_sText.IsEmpty() ) return;


CStdString sText = m_sText;


RECT rc = m_rcItem;
rc.left += m_rcTextPadding.left;
rc.right -= m_rcTextPadding.right;
rc.top += m_rcTextPadding.top;
rc.bottom -= m_rcTextPadding.bottom;
if( IsEnabled() ) {
CRenderEngine::DrawText(hDC, m_pManager, rc, sText, m_dwTextColor, \
m_iFont, DT_SINGLELINE | m_uTextStyle);
}
else {
CRenderEngine::DrawText(hDC, m_pManager, rc, sText, m_dwDisabledTextColor, \
m_iFont, DT_SINGLELINE | m_uTextStyle);
}
}


void CHotKeyUI::GetHotKey(WORD &wVirtualKeyCode, WORD &wModifiers) const
{
wVirtualKeyCode = m_wVirtualKeyCode;
wModifiers = m_wModifiers;
}


void CHotKeyUI::SetHotKey(WORD wVirtualKeyCode, WORD wModifiers)
{
m_wVirtualKeyCode = wVirtualKeyCode;
m_wModifiers = wModifiers;


if( m_pWindow ) return;
m_pWindow = new CHotKeyWnd();
ASSERT(m_pWindow);
m_pWindow->Init(this);
Invalidate();
}


}//end namespace

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值