diff --git a/tool_kits/duilib/Box/TabBox.cpp b/tool_kits/duilib/Box/TabBox.cpp index 773b5ba3..f01c17f1 100644 --- a/tool_kits/duilib/Box/TabBox.cpp +++ b/tool_kits/duilib/Box/TabBox.cpp @@ -181,6 +181,7 @@ bool TabBox::SelectItem(int iIndex) } if( m_pWindow != NULL ) { + m_pWindow->SetNextTabControl(); m_pWindow->SendNotify(this, kEventSelect, m_iCurSel, iOldSel); } return true; diff --git a/tool_kits/duilib/Control/Button.h b/tool_kits/duilib/Control/Button.h index ea385e72..8e5538b0 100644 --- a/tool_kits/duilib/Control/Button.h +++ b/tool_kits/duilib/Control/Button.h @@ -14,6 +14,7 @@ public: /// 重写父类方法,提供个性化功能,请参考父类声明 virtual void Activate() override; virtual void HandleMessage(EventArgs& event) override; + virtual UINT GetControlFlags() const override; /** * @brief 绑定鼠标点击处理函数 @@ -23,6 +24,12 @@ public: void AttachClick(const EventCallback& callback) { this->OnEvent[kEventClick] += callback; } }; +template +UINT ui::ButtonTemplate::GetControlFlags() const +{ + return IsKeyboardEnabled() && IsEnabled() ? UIFLAG_TABSTOP : UIFLAG_DEFAULT; +} + template ButtonTemplate::ButtonTemplate() { diff --git a/tool_kits/duilib/Control/RichEdit.cpp b/tool_kits/duilib/Control/RichEdit.cpp index 01f43378..4115425e 100644 --- a/tool_kits/duilib/Control/RichEdit.cpp +++ b/tool_kits/duilib/Control/RichEdit.cpp @@ -2268,6 +2268,11 @@ void RichEdit::SetPos(UiRect rc) } } +UINT RichEdit::GetControlFlags() const +{ + return IsEnabled() ? UIFLAG_TABSTOP : UIFLAG_DEFAULT; +} + void RichEdit::HandleMessage(EventArgs& event) { if ((!IsMouseEnabled() && event.Type > kEventMouseBegin && event.Type < kEventMouseEnd) || diff --git a/tool_kits/duilib/Control/RichEdit.h b/tool_kits/duilib/Control/RichEdit.h index da8623b6..303a72eb 100644 --- a/tool_kits/duilib/Control/RichEdit.h +++ b/tool_kits/duilib/Control/RichEdit.h @@ -686,6 +686,7 @@ public: virtual void SetEnabled(bool bEnable = true) override; virtual CSize EstimateSize(CSize szAvailable) override; virtual void SetPos(UiRect rc) override; + virtual UINT GetControlFlags() const override; virtual void HandleMessage(EventArgs& event) override; void OnSetCursor(EventArgs& event); void OnSetFocus(EventArgs& event); diff --git a/tool_kits/duilib/Core/Box.cpp b/tool_kits/duilib/Core/Box.cpp index 69c0cf7d..530961cd 100644 --- a/tool_kits/duilib/Core/Box.cpp +++ b/tool_kits/duilib/Core/Box.cpp @@ -735,6 +735,11 @@ void Box::ClearImageCache() } } +UINT Box::GetControlFlags() const +{ + return UIFLAG_DEFAULT; // Box 默认不支持 TAB 切换焦点 +} + ///////////////////////////////////////////////////////////////////////////////////// // // diff --git a/tool_kits/duilib/Core/Box.h b/tool_kits/duilib/Core/Box.h index 2bc7ab19..9204a2ac 100644 --- a/tool_kits/duilib/Core/Box.h +++ b/tool_kits/duilib/Core/Box.h @@ -119,8 +119,10 @@ public: virtual void InvokeLoadImageCache() override; virtual void UnLoadImageCache() override; virtual void ClearImageCache() override; + virtual UINT GetControlFlags() const override; - /// 容器自有方法 */ + + /// 容器自有方法 /** * @brief 查找指定子控件 * @param[in] pstrSubControlName 子控件名称 diff --git a/tool_kits/duilib/Core/Control.cpp b/tool_kits/duilib/Core/Control.cpp index 4ceaa447..f16e981c 100644 --- a/tool_kits/duilib/Core/Control.cpp +++ b/tool_kits/duilib/Core/Control.cpp @@ -540,6 +540,11 @@ void Control::SetFocus() if( m_pWindow != NULL ) m_pWindow->SetFocus(this); } +UINT Control::GetControlFlags() const +{ + return UIFLAG_TABSTOP; +} + void Control::SetNoFocus() { m_bNoFocus = true; @@ -798,11 +803,13 @@ void Control::HandleMessage(EventArgs& msg) } } else if (msg.Type == kEventInternalSetFocus) { + SetState(kControlStateHot); m_bFocused = true; Invalidate(); return; } else if (msg.Type == kEventInternalKillFocus) { + SetState(kControlStateNormal); m_bFocused = false; Invalidate(); return; diff --git a/tool_kits/duilib/Core/Control.h b/tool_kits/duilib/Core/Control.h index 989332d2..60b04762 100644 --- a/tool_kits/duilib/Core/Control.h +++ b/tool_kits/duilib/Core/Control.h @@ -423,6 +423,12 @@ public: */ virtual void SetFocus(); + /** + * @brief 返回控件的标识,用于判断是否可以响应 TAB 切换事件 + * @return 返回控件的标识类型 + */ + virtual UINT GetControlFlags() const; + /** * @brief 让控件设置永远获取不到焦点 * @return 无 diff --git a/tool_kits/duilib/Core/GlobalManager.cpp b/tool_kits/duilib/Core/GlobalManager.cpp index cfe4d8dd..77ee2f69 100644 --- a/tool_kits/duilib/Core/GlobalManager.cpp +++ b/tool_kits/duilib/Core/GlobalManager.cpp @@ -3,7 +3,7 @@ #include #include "Utils/UnZip.h" -namespace ui +namespace ui { std::wstring GlobalManager::m_pStrResourcePath; @@ -60,7 +60,7 @@ void GlobalManager::Startup(const std::wstring& strResourcePath, const CreateCon else { MutiLanSupport::GetInstance()->LoadStringTable(strResourcePath + language + L"\\gdstrings.ini"); } - + GdiplusStartup(&g_gdiplusToken, &g_gdiplusStartupInput, NULL); // Boot Windows Common Controls (for the ToolTip control) ::InitCommonControls(); @@ -80,27 +80,27 @@ void GlobalManager::Shutdown() std::wstring GlobalManager::GetCurrentPath() { - TCHAR tszModule[MAX_PATH + 1] = { 0 }; - ::GetCurrentDirectory(MAX_PATH, tszModule); - return tszModule; + TCHAR tszModule[MAX_PATH + 1] = { 0 }; + ::GetCurrentDirectory(MAX_PATH, tszModule); + return tszModule; } std::wstring GlobalManager::GetResourcePath() { - return m_pStrResourcePath; + return m_pStrResourcePath; } void GlobalManager::SetCurrentPath(const std::wstring& strPath) { - ::SetCurrentDirectory(strPath.c_str()); + ::SetCurrentDirectory(strPath.c_str()); } void GlobalManager::SetResourcePath(const std::wstring& strPath) { - m_pStrResourcePath = strPath; - if( m_pStrResourcePath.empty() ) return; - TCHAR cEnd = m_pStrResourcePath.at(m_pStrResourcePath.length() - 1); - if( cEnd != _T('\\') && cEnd != _T('/') ) m_pStrResourcePath += _T('\\'); + m_pStrResourcePath = strPath; + if (m_pStrResourcePath.empty()) return; + TCHAR cEnd = m_pStrResourcePath.at(m_pStrResourcePath.length() - 1); + if (cEnd != _T('\\') && cEnd != _T('/')) m_pStrResourcePath += _T('\\'); } void GlobalManager::LoadGlobalResource() @@ -165,78 +165,6 @@ std::unique_ptr GlobalManager::CreatePath() return p; } -void GlobalManager::MessageLoop() -{ - MSG msg = { 0 }; - while( ::GetMessage(&msg, NULL, 0, 0) ) { - if( !GlobalManager::TranslateMessage(&msg) ) { - ::TranslateMessage(&msg); - ::DispatchMessage(&msg); - } - } -} - -bool GlobalManager::TranslateMessage(const LPMSG pMsg) -{ - // Pretranslate Message takes care of system-wide messages, such as - // tabbing and shortcut key-combos. We'll look for all messages for - // each window and any child control attached. - UINT uStyle = GetWindowStyle(pMsg->hwnd); - UINT uChildRes = uStyle & WS_CHILD; - LRESULT lRes = 0; - if (uChildRes != 0) - { - HWND hWndParent = ::GetParent(pMsg->hwnd); - - for( auto it = m_aPreMessages.begin(); it != m_aPreMessages.end(); it++ ) { - auto pT = *it; - HWND hTempParent = hWndParent; - while(hTempParent) - { - if(pMsg->hwnd == pT->GetHWND() || hTempParent == pT->GetHWND()) { - if (pT->TranslateAccelerator(pMsg)) - return true; - - if( pT->PreMessageHandler(pMsg->message, pMsg->wParam, pMsg->lParam, lRes) ) - return true; - - return false; - } - hTempParent = GetParent(hTempParent); - } - } - } - else - { - for( auto it = m_aPreMessages.begin(); it != m_aPreMessages.end(); it++ ) { - auto pT = *it; - if(pMsg->hwnd == pT->GetHWND()) { - if (pT->TranslateAccelerator(pMsg)) - return true; - - if( pT->PreMessageHandler(pMsg->message, pMsg->wParam, pMsg->lParam, lRes) ) - return true; - - return false; - } - } - } - return false; -} - -void GlobalManager::AddPreMessage(Window* pWindow) -{ - m_aPreMessages.push_back(pWindow); -} - -void GlobalManager::RemovePreMessage(Window* pWindow) -{ - auto it = std::find(m_aPreMessages.begin(), m_aPreMessages.end(), pWindow); - if (it != m_aPreMessages.end()) { - m_aPreMessages.erase(it); - } -} - void GlobalManager::AddClass(const std::wstring& strClassName, const std::wstring& strControlAttrList) { ASSERT(!strClassName.empty()); @@ -373,14 +301,14 @@ HFONT GlobalManager::AddFont(const std::wstring& strFontId, const std::wstring& if (strNewFontId.empty()) { strNewFontId = std::to_wstring(m_mCustomFonts.size()); - } + } auto iter = m_mCustomFonts.find(strNewFontId); ASSERT(iter == m_mCustomFonts.end()); static bool bOsOverXp = IsWindowsVistaOrGreater(); std::wstring fontName = strFontName; - if ( fontName == L"system" ) { + if (fontName == L"system") { fontName = bOsOverXp ? L"微软雅黑" : L"新宋体"; } @@ -389,14 +317,14 @@ HFONT GlobalManager::AddFont(const std::wstring& strFontId, const std::wstring& _tcscpy(lf.lfFaceName, fontName.c_str()); lf.lfCharSet = DEFAULT_CHARSET; lf.lfHeight = -DpiManager::GetInstance()->ScaleInt(nSize); - if( bBold ) lf.lfWeight += FW_BOLD; - if( bUnderline ) lf.lfUnderline = TRUE; - if( bItalic ) lf.lfItalic = TRUE; + if (bBold) lf.lfWeight += FW_BOLD; + if (bUnderline) lf.lfUnderline = TRUE; + if (bItalic) lf.lfItalic = TRUE; HFONT hFont = ::CreateFontIndirect(&lf); - if( hFont == NULL ) return NULL; + if (hFont == NULL) return NULL; TFontInfo* pFontInfo = new TFontInfo; - if( !pFontInfo ) return false; + if (!pFontInfo) return false; pFontInfo->hFont = hFont; pFontInfo->sFontName = fontName; pFontInfo->iSize = nSize; @@ -440,8 +368,8 @@ HFONT GlobalManager::GetFont(const std::wstring& strFontName, int nSize, bool bB { for (auto it = m_mCustomFonts.begin(); it != m_mCustomFonts.end(); it++) { auto pFontInfo = it->second; - if( pFontInfo->sFontName == strFontName && pFontInfo->iSize == nSize && - pFontInfo->bBold == bBold && pFontInfo->bUnderline == bUnderline && pFontInfo->bItalic == bItalic) + if (pFontInfo->sFontName == strFontName && pFontInfo->iSize == nSize && + pFontInfo->bBold == bBold && pFontInfo->bUnderline == bUnderline && pFontInfo->bItalic == bItalic) return pFontInfo->hFont; } return NULL; @@ -450,7 +378,7 @@ HFONT GlobalManager::GetFont(const std::wstring& strFontName, int nSize, bool bB TFontInfo* GlobalManager::GetFontInfo(const std::wstring& strFontId, HDC hDcPaint) { TFontInfo* pFontInfo = GetTFontInfo(strFontId); - if( pFontInfo->tm.tmHeight == 0 ) { + if (pFontInfo->tm.tmHeight == 0) { HFONT hOldFont = (HFONT) ::SelectObject(hDcPaint, pFontInfo->hFont); ::GetTextMetrics(hDcPaint, &pFontInfo->tm); ::SelectObject(hDcPaint, hOldFont); @@ -460,10 +388,10 @@ TFontInfo* GlobalManager::GetFontInfo(const std::wstring& strFontId, HDC hDcPain TFontInfo* GlobalManager::GetFontInfo(HFONT hFont, HDC hDcPaint) { - for( auto it = m_mCustomFonts.begin(); it != m_mCustomFonts.end(); it++ ) { + for (auto it = m_mCustomFonts.begin(); it != m_mCustomFonts.end(); it++) { auto pFontInfo = it->second; - if( pFontInfo->hFont == hFont ) { - if( pFontInfo->tm.tmHeight == 0 ) { + if (pFontInfo->hFont == hFont) { + if (pFontInfo->tm.tmHeight == 0) { HFONT hOldFont = (HFONT) ::SelectObject(hDcPaint, pFontInfo->hFont); ::GetTextMetrics(hDcPaint, &pFontInfo->tm); ::SelectObject(hDcPaint, hOldFont); @@ -478,9 +406,9 @@ TFontInfo* GlobalManager::GetFontInfo(HFONT hFont, HDC hDcPaint) bool GlobalManager::FindFont(HFONT hFont) { - for( auto it = m_mCustomFonts.begin(); it != m_mCustomFonts.end(); it++ ) { + for (auto it = m_mCustomFonts.begin(); it != m_mCustomFonts.end(); it++) { auto pFontInfo = it->second; - if( pFontInfo->hFont == hFont ) + if (pFontInfo->hFont == hFont) return true; } return false; @@ -490,8 +418,8 @@ bool GlobalManager::FindFont(const std::wstring& strFontName, int nSize, bool bB { for (auto it = m_mCustomFonts.begin(); it != m_mCustomFonts.end(); it++) { auto pFontInfo = it->second; - if( pFontInfo->sFontName == strFontName && pFontInfo->iSize == nSize && - pFontInfo->bBold == bBold && pFontInfo->bUnderline == bUnderline && pFontInfo->bItalic == bItalic) + if (pFontInfo->sFontName == strFontName && pFontInfo->iSize == nSize && + pFontInfo->bBold == bBold && pFontInfo->bUnderline == bUnderline && pFontInfo->bItalic == bItalic) return true; } return false; diff --git a/tool_kits/duilib/Core/GlobalManager.h b/tool_kits/duilib/Core/GlobalManager.h index 3bc39e7e..bbfef519 100644 --- a/tool_kits/duilib/Core/GlobalManager.h +++ b/tool_kits/duilib/Core/GlobalManager.h @@ -104,11 +104,6 @@ public: */ static std::unique_ptr CreatePath(); - static void MessageLoop(); - static bool TranslateMessage(const LPMSG pMsg); - static void AddPreMessage(Window* pWindow); - static void RemovePreMessage(Window* pWindow); - /** * @brief 添加一个全局 class 属性 * @param[in] strClassName 全局 class 名称 diff --git a/tool_kits/duilib/Core/Window.cpp b/tool_kits/duilib/Core/Window.cpp index 00409dc4..bc8e836c 100644 --- a/tool_kits/duilib/Core/Window.cpp +++ b/tool_kits/duilib/Core/Window.cpp @@ -99,8 +99,6 @@ Window::~Window() // Reset other parts... if (m_hwndTooltip != NULL) ::DestroyWindow(m_hwndTooltip); if (m_hDcPaint != NULL) ::ReleaseDC(m_hWnd, m_hDcPaint); - - GlobalManager::RemovePreMessage(this); } HWND Window::GetHWND() const @@ -241,33 +239,6 @@ void Window::ShowWindow(bool bShow /*= true*/, bool bTakeFocus /*= false*/) ::ShowWindow(m_hWnd, bShow ? (bTakeFocus ? SW_SHOWNORMAL : SW_SHOWNOACTIVATE) : SW_HIDE); } -UINT Window::ShowModal() -{ - ASSERT(::IsWindow(m_hWnd)); - UINT nRet = 0; - HWND hWndParent = GetWindowOwner(m_hWnd); - ::ShowWindow(m_hWnd, SW_SHOWNORMAL); - ::EnableWindow(hWndParent, FALSE); - MSG msg = { 0 }; - HWND hTempWnd = m_hWnd; - while( ::IsWindow(hTempWnd) && ::GetMessage(&msg, NULL, 0, 0) ) { - if( msg.message == WM_CLOSE && msg.hwnd == m_hWnd ) { - nRet = msg.wParam; - ::EnableWindow(hWndParent, TRUE); - ::SetFocus(hWndParent); - } - if( !GlobalManager::TranslateMessage(&msg) ) { - ::TranslateMessage(&msg); - ::DispatchMessage(&msg); - } - if( msg.message == WM_QUIT ) break; - } - ::EnableWindow(hWndParent, TRUE); - ::SetFocus(hWndParent); - if( msg.message == WM_QUIT ) ::PostQuitMessage(msg.wParam); - return nRet; -} - void Window::ShowModalFake(HWND parent_hwnd) { ASSERT(::IsWindow(m_hWnd)); @@ -420,8 +391,6 @@ void Window::Init(HWND hWnd) ASSERT(::IsWindow(hWnd)); // Remember the window context we came from m_hDcPaint = ::GetDC(hWnd); - // We'll want to filter messages globally too - GlobalManager::AddPreMessage(this); m_renderContext = GlobalManager::CreateRenderContext(); RegisterTouchWindowWrapper(hWnd, 0); @@ -840,24 +809,6 @@ void Window::SetInitSize(int cx, int cy, bool bContainShadow, bool bNeedDpiScale } } -bool Window::AddPreMessageFilter(IUIMessageFilter* pFilter) -{ - ASSERT(std::find(m_aPreMessageFilters.begin(), m_aPreMessageFilters.end(), pFilter) == m_aPreMessageFilters.end()); - m_aPreMessageFilters.push_back(pFilter); - return true; -} - -bool Window::RemovePreMessageFilter(IUIMessageFilter* pFilter) -{ - for (auto it = m_aPreMessageFilters.begin(); it != m_aPreMessageFilters.end(); it++) { - if (*it == pFilter) { - m_aPreMessageFilters.erase(it); - return true; - } - } - return false; -} - bool Window::AddMessageFilter(IUIMessageFilter* pFilter) { ASSERT(std::find(m_aMessageFilters.begin(), m_aMessageFilters.end(), pFilter) == m_aMessageFilters.end()); @@ -920,28 +871,6 @@ bool Window::TranslateAccelerator(LPMSG pMsg) return false; } -bool Window::PreMessageHandler(UINT uMsg, WPARAM wParam, LPARAM lParam, LRESULT& /*lRes*/) -{ - for (auto it = m_aPreMessageFilters.begin(); it != m_aPreMessageFilters.end(); it++) - { - BOOL bHandled = false; - (*it)->MessageHandler(uMsg, wParam, lParam, bHandled); - if( bHandled ) { - return true; - } - } - switch( uMsg ) { - case WM_SYSKEYDOWN: - { - if( m_pFocus != NULL ) { - m_pFocus->HandleMessageTemplate(kEventSystemKey, 0, 0, wParam); - } - } - break; - } - return false; -} - LRESULT Window::HandleMessage(UINT uMsg, WPARAM wParam, LPARAM lParam) { bool handled = false; @@ -1433,6 +1362,15 @@ LRESULT Window::DoHandlMessage(UINT uMsg, WPARAM wParam, LPARAM lParam, bool& ha { if (m_pFocus == NULL) break; + // Tabbing between controls + if (wParam == VK_TAB) { + if (m_pFocus && m_pFocus->IsVisible() && m_pFocus->IsEnabled() && dynamic_cast(m_pFocus) != nullptr) { + if (dynamic_cast(m_pFocus)->IsWantTab()) return false; + } + SetNextTabControl(::GetKeyState(VK_SHIFT) >= 0); + return true; + } + m_pEventKey = m_pFocus; m_pFocus->HandleMessageTemplate(kEventKeyDown, wParam, lParam, wParam); } @@ -1459,8 +1397,6 @@ LRESULT Window::DoHandlMessage(UINT uMsg, WPARAM wParam, LPARAM lParam, bool& ha m_ptLastMousePos = pt; Control* pControl = FindControl(pt); if (pControl == NULL) break; - //if( (pControl->GetControlFlags() & UIFLAG_SETCURSOR) == 0 ) break; - pControl->HandleMessageTemplate(kEventSetCursor, wParam, lParam, 0, pt); } handled = true; @@ -1571,7 +1507,7 @@ void Window::SetFocusNeeded(Control* pControl) FINDTABINFO info = { 0 }; info.pFocus = pControl; info.bForward = false; - m_pFocus = nullptr; //m_pRoot->FindControl(__FindControlFromTab, &info, UIFIND_VISIBLE | UIFIND_ENABLED | UIFIND_ME_FIRST); + m_pFocus = m_pRoot->FindControl(__FindControlFromTab, &info, UIFIND_VISIBLE | UIFIND_ENABLED | UIFIND_ME_FIRST); m_bFocusNeeded = true; if (m_pRoot != NULL) m_pRoot->Arrange(); } @@ -1623,36 +1559,36 @@ HWND Window::GetTooltipWindow() const return m_hwndTooltip; } -//bool Window::SetNextTabControl(bool bForward) -//{ -// // If we're in the process of restructuring the layout we can delay the -// // focus calulation until the next repaint. -// if( m_bIsArranged && bForward ) { -// m_bFocusNeeded = true; -// ::InvalidateRect(m_hWnd, NULL, FALSE); -// return true; -// } -// // Find next/previous tabbable control -// FINDTABINFO info1 = { 0 }; -// info1.pFocus = m_pFocus; -// info1.bForward = bForward; -// Control* pControl = m_pRoot->FindControl(__FindControlFromTab, &info1, UIFIND_VISIBLE | UIFIND_ENABLED | UIFIND_ME_FIRST); -// if( pControl == NULL ) { -// if( bForward ) { -// // Wrap around -// FINDTABINFO info2 = { 0 }; -// info2.pFocus = bForward ? NULL : info1.pLast; -// info2.bForward = bForward; -// pControl = m_pRoot->FindControl(__FindControlFromTab, &info2, UIFIND_VISIBLE | UIFIND_ENABLED | UIFIND_ME_FIRST); -// } -// else { -// pControl = info1.pLast; -// } -// } -// if( pControl != NULL ) SetFocus(pControl); -// m_bFocusNeeded = false; -// return true; -//} +bool Window::SetNextTabControl(bool bForward) +{ + // If we're in the process of restructuring the layout we can delay the + // focus calulation until the next repaint. + if (m_bIsArranged && bForward) { + m_bFocusNeeded = true; + ::InvalidateRect(m_hWnd, NULL, FALSE); + return true; + } + // Find next/previous tabbable control + FINDTABINFO info1 = { 0 }; + info1.pFocus = m_pFocus; + info1.bForward = bForward; + Control* pControl = m_pRoot->FindControl(__FindControlFromTab, &info1, UIFIND_VISIBLE | UIFIND_ENABLED | UIFIND_ME_FIRST); + if (pControl == NULL) { + if (bForward) { + // Wrap around + FINDTABINFO info2 = { 0 }; + info2.pFocus = bForward ? NULL : info1.pLast; + info2.bForward = bForward; + pControl = m_pRoot->FindControl(__FindControlFromTab, &info2, UIFIND_VISIBLE | UIFIND_ENABLED | UIFIND_ME_FIRST); + } + else { + pControl = info1.pLast; + } + } + if (pControl != NULL) SetFocus(pControl); + m_bFocusNeeded = false; + return true; +} Control* Window::GetRoot() const { @@ -2038,19 +1974,19 @@ Control* CALLBACK Window::__FindControlFromPoint(Control* pThis, LPVOID pData) return ::PtInRect(&pos, *pPoint) ? pThis : NULL; } -//Control* CALLBACK Window::__FindControlFromTab(Control* pThis, LPVOID pData) -//{ -// FINDTABINFO* pInfo = static_cast(pData); -// if( pInfo->pFocus == pThis ) { -// if( pInfo->bForward ) pInfo->bNextIsIt = true; -// return pInfo->bForward ? NULL : pInfo->pLast; -// } -// if( (pThis->GetControlFlags() & UIFLAG_TABSTOP) == 0 ) return NULL; -// pInfo->pLast = pThis; -// if( pInfo->bNextIsIt ) return pThis; -// if( pInfo->pFocus == NULL ) return pThis; -// return NULL; // Examine all controls -//} +Control* CALLBACK Window::__FindControlFromTab(Control* pThis, LPVOID pData) +{ + FINDTABINFO* pInfo = static_cast(pData); + if (pInfo->pFocus == pThis) { + if (pInfo->bForward) pInfo->bNextIsIt = true; + return pInfo->bForward ? NULL : pInfo->pLast; + } + if ((pThis->GetControlFlags() & UIFLAG_TABSTOP) == 0) return NULL; + pInfo->pLast = pThis; + if (pInfo->bNextIsIt) return pThis; + if (pInfo->pFocus == NULL) return pThis; + return NULL; // Examine all controls +} //Control* CALLBACK Window::__FindControlFromShortcut(Control* pThis, LPVOID pData) //{ diff --git a/tool_kits/duilib/Core/Window.h b/tool_kits/duilib/Core/Window.h index ce3614ef..843291a2 100644 --- a/tool_kits/duilib/Core/Window.h +++ b/tool_kits/duilib/Core/Window.h @@ -8,6 +8,10 @@ namespace ui class Box; +// Flags for Control::GetControlFlags() +#define UIFLAG_DEFAULT 0x00000000 // 默认状态 +#define UIFLAG_TABSTOP 0x00000001 // 标识控件是否在收到 TAB 切换焦点时允许设置焦点 + // Flags for FindControl() #define UIFIND_ALL 0x00000000 #define UIFIND_VISIBLE 0x00000001 @@ -16,14 +20,6 @@ class Box; #define UIFIND_TOP_FIRST 0x00000008 #define UIFIND_ME_FIRST 0x80000000 -// Flags for the CDialogLayout stretching -#define UISTRETCH_NEWGROUP 0x00000001 -#define UISTRETCH_NEWLINE 0x00000002 -#define UISTRETCH_MOVE_X 0x00000004 -#define UISTRETCH_MOVE_Y 0x00000008 -#define UISTRETCH_SIZE_X 0x00000010 -#define UISTRETCH_SIZE_Y 0x00000020 - ///////////////////////////////////////////////////////////////////////////////////// // @@ -147,12 +143,6 @@ public: */ virtual void ShowWindow(bool bShow = true, bool bTakeFocus = true); - /** - * @brief 显示模态对话框(不推荐) - * @return 接收到的消息 - */ - UINT ShowModal(); - /** * @brief 显示模态对话框(推荐) * @param[in] parent_hwnd 父窗口句柄 @@ -537,21 +527,6 @@ public: */ void SetInitSize(int cx, int cy, bool bContainShadow = false, bool bNeedDpiScale = true); - /// 窗口内部消息处理 - /** - * @brief 添加一个消息被派发到窗口前的消息过滤器 - * @param[in] pFilter 一个继承了 IUIMessageFilter 的对象实例,需要实现 MessageHandler 方法 - * @return 始终返回 true - */ - bool AddPreMessageFilter(IUIMessageFilter* pFilter); - - /** - * @brief 移除一个消息被派发到窗口前的消息过滤器 - * @param[in] pFilter 一个继承了 IUIMessageFilter 的对象实例 - * @return 返回 true 表示移除成功,否则可能该过滤器不存在 - */ - bool RemovePreMessageFilter(IUIMessageFilter* pFilter); - /** * @brief 添加一个消息过滤器,此时消息已经派发 * @param[in] pFilter 一个继承了 IUIMessageFilter 的对象实例,需要实现 MessageHandler 方法 @@ -601,16 +576,6 @@ public: */ bool TranslateAccelerator(LPMSG pMsg); - /** - * @brief 执行派发消前的过滤器 - * @param[in] uMsg 消息体 - * @param[in] wParam 消息附加参数 - * @param[in] lParam 消息附加参数 - * @param[in] lRes 处理结果 - * @return 返回 true 则继续派发该消息,否则不再派发该消息 - */ - bool PreMessageHandler(UINT uMsg, WPARAM wParam, LPARAM lParam, LRESULT& lRes); - /** * @brief 窗口消息的派发函数 * @param[in] uMsg 消息体 @@ -726,7 +691,12 @@ public: */ HWND GetTooltipWindow() const; - //bool SetNextTabControl(bool bForward = true); + /** + * @brief 切换控件焦点到下一个(或上一个)控件 + * @param[in] bForward true 为上一个控件,否则为 false,默认为 true + * @return 始终返回 true,暂无参考意义 + */ + bool SetNextTabControl(bool bForward = true); /// 控件相关 /** @@ -877,7 +847,7 @@ private: static Control* CALLBACK __FindControlFromNameHash(Control* pThis, LPVOID pData); static Control* CALLBACK __FindControlFromCount(Control* pThis, LPVOID pData); static Control* CALLBACK __FindControlFromPoint(Control* pThis, LPVOID pData); - //static Control* CALLBACK __FindControlFromTab(Control* pThis, LPVOID pData); + static Control* CALLBACK __FindControlFromTab(Control* pThis, LPVOID pData); //static Control* CALLBACK __FindControlFromShortcut(Control* pThis, LPVOID pData); static Control* CALLBACK __FindControlFromUpdate(Control* pThis, LPVOID pData); static Control* CALLBACK __FindControlFromName(Control* pThis, LPVOID pData); diff --git a/tool_kits/duilib/Utils/WinImplBase.cpp b/tool_kits/duilib/Utils/WinImplBase.cpp index c273ff8b..8c0bd562 100644 --- a/tool_kits/duilib/Utils/WinImplBase.cpp +++ b/tool_kits/duilib/Utils/WinImplBase.cpp @@ -17,7 +17,6 @@ WindowImplBase::~WindowImplBase() void WindowImplBase::OnFinalMessage( HWND hWnd ) { __super::OnFinalMessage(hWnd); - RemovePreMessageFilter(this); ReapObjects(GetRoot()); delete this; } @@ -289,7 +288,6 @@ LRESULT WindowImplBase::OnCreate(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& ::SetWindowLong(this->GetHWND(), GWL_STYLE, GetStyle()); Init(m_hWnd); - AddPreMessageFilter(this); SetWindowResourcePath(GetSkinFolder()); WindowBuilder builder;