优化duilib中的CDateTimeUI控件-修正XP下无法使用的问题
duilib没有自己实现日期时间选择控件,转而封装了系统原生控件来代替,虽不能完美解决界面美观问题,暂时解决了有无的问题。但是使用过程中,很多朋友反应在Win7以上系统是没问题的,但是在XP系统上出现无法选择日期的问题,今天抽空修复了一下,核心代码如下:
-
class CDateTimeWnd : public CWindowWnd
-
{
-
public:
-
CDateTimeWnd();
-
-
-
void Init(CDateTimeUI* pOwner);
-
RECT CalPos();
-
-
-
LPCTSTR GetWindowClassName() const;
-
LPCTSTR GetSuperClassName() const;
-
void OnFinalMessage(HWND hWnd);
-
-
-
LRESULT HandleMessage(UINT uMsg, WPARAM wParam, LPARAM lParam);
-
protected:
-
CDateTimeUI* m_pOwner;
-
HBRUSH m_hBkBrush;
-
bool m_bInit;
-
bool m_bDropOpen;
-
SYSTEMTIME m_oldSysTime;
-
};
-
-
-
CDateTimeWnd::CDateTimeWnd() : m_pOwner(NULL), m_hBkBrush(NULL), m_bInit(false), m_bDropOpen(false)
-
{
-
}
-
-
-
void CDateTimeWnd::Init(CDateTimeUI* pOwner)
-
{
-
m_pOwner = pOwner;
-
m_pOwner->m_nDTUpdateFlag = DT_NONE;
-
-
-
if (m_hWnd == NULL)
-
{
-
RECT rcPos = CalPos();
-
UINT uStyle = WS_CHILD;
-
Create(m_pOwner->GetManager()->GetPaintWindow(), NULL, uStyle, 0, rcPos);
-
SetWindowFont(m_hWnd, m_pOwner->GetManager()->GetFontInfo(m_pOwner->GetFont())->hFont, TRUE);
-
}
-
-
-
if (m_pOwner->GetText().IsEmpty()) {
-
::GetLocalTime(&m_pOwner->m_sysTime);
-
}
-
memcpy(&m_oldSysTime, &m_pOwner->m_sysTime, sizeof(SYSTEMTIME));
-
::SendMessage(m_hWnd, DTM_SETSYSTEMTIME, 0, (LPARAM)&m_pOwner->m_sysTime);
-
::ShowWindow(m_hWnd, SW_SHOWNOACTIVATE);
-
::SetFocus(m_hWnd);
-
-
-
m_bInit = true;
-
}
-
-
-
RECT CDateTimeWnd::CalPos()
-
{
-
CDuiRect rcPos = m_pOwner->GetPos();
-
-
-
CControlUI* pParent = m_pOwner;
-
RECT rcParent;
-
while( pParent = pParent->GetParent() ) {
-
if( !pParent->IsVisible() ) {
-
rcPos.left = rcPos.top = rcPos.right = rcPos.bottom = 0;
-
break;
-
}
-
rcParent = pParent->GetClientPos();
-
if( !::IntersectRect(&rcPos, &rcPos, &rcParent) ) {
-
rcPos.left = rcPos.top = rcPos.right = rcPos.bottom = 0;
-
break;
-
}
-
}
-
-
-
return rcPos;
-
}
-
-
-
LPCTSTR CDateTimeWnd::GetWindowClassName() const
-
{
-
return _T("DateTimeWnd");
-
}
-
-
-
LPCTSTR CDateTimeWnd::GetSuperClassName() const
-
{
-
return DATETIMEPICK_CLASS;
-
}
-
-
-
void CDateTimeWnd::OnFinalMessage(HWND hWnd)
-
{
-
if( m_hBkBrush != NULL ) ::DeleteObject(m_hBkBrush);
-
if( m_pOwner->GetManager()->IsLayered() ) {
-
m_pOwner->GetManager()->RemovePaintChildWnd(hWnd);
-
}
-
m_pOwner->m_pWindow = NULL;
-
delete this;
-
}
-
-
-
LRESULT CDateTimeWnd::HandleMessage(UINT uMsg, WPARAM wParam, LPARAM lParam)
-
{
-
LRESULT lRes = 0;
-
BOOL bHandled = TRUE;
-
if (uMsg == WM_KEYDOWN && wParam == VK_ESCAPE)
-
{
-
memcpy(&m_pOwner->m_sysTime, &m_oldSysTime, sizeof(SYSTEMTIME));
-
m_pOwner->m_nDTUpdateFlag = DT_UPDATE;
-
m_pOwner->UpdateText();
-
PostMessage(WM_CLOSE);
-
return lRes;
-
}
-
else if(uMsg == OCM_NOTIFY)
-
{
-
NMHDR* pHeader=(NMHDR*)lParam;
-
if(pHeader != NULL && pHeader->hwndFrom == m_hWnd) {
-
if(pHeader->code == DTN_DATETIMECHANGE) {
-
LPNMDATETIMECHANGE lpChage=(LPNMDATETIMECHANGE)lParam;
-
::SendMessage(m_hWnd, DTM_GETSYSTEMTIME, 0, (LPARAM)&m_pOwner->m_sysTime);
-
m_pOwner->m_nDTUpdateFlag = DT_UPDATE;
-
m_pOwner->UpdateText();
-
}
-
else if(pHeader->code == DTN_DROPDOWN) {
-
m_bDropOpen = true;
-
-
-
}
-
else if(pHeader->code == DTN_CLOSEUP) {
-
::SendMessage(m_hWnd, DTM_GETSYSTEMTIME, 0, (LPARAM)&m_pOwner->m_sysTime);
-
m_pOwner->m_nDTUpdateFlag = DT_UPDATE;
-
m_pOwner->UpdateText();
-
PostMessage(WM_CLOSE);
-
m_bDropOpen = false;
-
}
-
}
-
bHandled = FALSE;
-
}
-
else if(uMsg == WM_KILLFOCUS)
-
{
-
if(!m_bDropOpen) {
-
PostMessage(WM_CLOSE);
-
}
-
bHandled = FALSE;
-
}
-
else if( uMsg == WM_PAINT) {
-
if (m_pOwner->GetManager()->IsLayered()) {
-
m_pOwner->GetManager()->AddPaintChildWnd(m_hWnd);
-
}
-
bHandled = FALSE;
-
}
-
else bHandled = FALSE;
-
if( !bHandled ) return CWindowWnd::HandleMessage(uMsg, wParam, lParam);
-
return lRes;
-
}
把UIDateTime.cpp中的CDateTimeWnd类替换成以上代码即可解决。
好了,需要的小伙伴赶紧试试吧!
duilib开源项目圈QQ群:261675375 \ 261851826
最新代码托管地址:https://github.com/qdtroy/DuiLib_Ultimate
By Troy (QQ:656067418)