本文转载自:lymcn专栏http://blog.csdn.net/lymcn/article/details/6992926
这两天受到MFC的CTabCtrl的折磨,焦点在主窗口与子界面太难实现切换了,经理一天的努力,查阅了大量资料还是不能简单实现,最后还是只能通过重写PreTranslateMessage。见下面代码:
重载CDialog类:
- #pragma once
- // DlgPage 对话框
- class CDlgPage : public CDialog
- {
- DECLARE_DYNAMIC(CDlgPage)
- public:
- CDlgPage(UINT nIDTemplate, CWnd* pParent = NULL); // 标准构造函数
- virtual ~CDlgPage();
- protected:
- virtual void DoDataExchange(CDataExchange* pDX); // DDX/DDV 支持
- DECLARE_MESSAGE_MAP()
- public:
- virtual BOOL PreTranslateMessage(MSG* pMsg);
- // 获取第一个TAB控件句柄
- HWND GetFirstTab(void);
- // 获取最后一个TAB控件句柄
- HWND GetLastTab(void);
- // 设置第一个控件得到焦点
- void SetFirstFocus(void);
- // 设置最后一个控件得到焦点
- void SetLastFocus(void);
- };
- // DlgPage.cpp : 实现文件
- //
- #include "stdafx.h"
- #include "TabDemo.h"
- #include "DlgPage.h"
- // DlgPage 对话框
- IMPLEMENT_DYNAMIC(CDlgPage, CDialog)
- CDlgPage::CDlgPage(UINT nIDTemplate, CWnd* pParent /*=NULL*/)
- : CDialog(nIDTemplate, pParent)
- {
- #ifndef _WIN32_WCE
- EnableActiveAccessibility();
- #endif
- }
- CDlgPage::~CDlgPage()
- {
- }
- void CDlgPage::DoDataExchange(CDataExchange* pDX)
- {
- CDialog::DoDataExchange(pDX);
- }
- BEGIN_MESSAGE_MAP(CDlgPage, CDialog)
- END_MESSAGE_MAP()
- // DlgPage 消息处理程序
- BOOL CDlgPage::PreTranslateMessage(MSG* pMsg)
- {
- // TODO: 在此添加专用代码和/或调用基类
- if((pMsg->message == WM_KEYDOWN)&& (pMsg->wParam == VK_TAB))
- {
- if(GetAsyncKeyState (VK_SHIFT) & 0x8000)
- {
- if(pMsg->hwnd == GetFirstTab())
- {
- this->GetParent()->SetFocus();
- return TRUE;
- }
- }
- else
- {
- if(pMsg->hwnd == GetLastTab())
- {
- this->GetParent()->GetParent()->GetNextDlgTabItem(this->GetParent())->SetFocus();
- return TRUE;
- }
- }
- }
- return CDialog::PreTranslateMessage(pMsg);
- }
- // 获取第一个TAB控件句柄
- HWND CDlgPage::GetFirstTab(void)
- {
- HWND hWnd = ::GetWindow(m_hWnd,GW_CHILD);
- HWND hFirstCtrl;
- while (hWnd)
- {
- if (::IsWindowEnabled(hWnd) && ::IsWindowVisible(hWnd) &&
- (::GetWindowLong(hWnd, GWL_STYLE) & WS_TABSTOP))
- {
- hFirstCtrl = hWnd;
- break;
- }
- hWnd = ::GetWindow(hWnd, GW_HWNDNEXT);
- }
- return hFirstCtrl;
- }
- // 获取最后一个TAB控件句柄
- HWND CDlgPage::GetLastTab(void)
- {
- HWND hWnd = ::GetWindow(m_hWnd,GW_CHILD);
- HWND hLastCtrl;
- while (hWnd)
- {
- if (::IsWindowEnabled(hWnd) && ::IsWindowVisible(hWnd) &&
- (::GetWindowLong(hWnd, GWL_STYLE) & WS_TABSTOP))
- hLastCtrl = hWnd;
- hWnd = ::GetWindow(hWnd, GW_HWNDNEXT);
- }
- return hLastCtrl;
- }
- // 设置第一个控件得到焦点
- void CDlgPage::SetFirstFocus(void)
- {
- ::SetFocus(this->GetFirstTab());
- }
- // 设置最后一个控件得到焦点
- void CDlgPage::SetLastFocus(void)
- {
- ::SetFocus(this->GetLastTab());
- }
这个类纯为实现在Tab页内Tab order切换用。
借用xianglitian的例子:《TabCtrl使用范例》 地址:http://download.csdn.net/detail/xianglitian/2260893,在此基础上添加以上类,并对内容进行修改,最终实现正常切换效果。
重载PreTranslateMessage:
- BOOL CTabDemoDlg::PreTranslateMessage(MSG* pMsg)
- {
- if((pMsg->message == WM_KEYDOWN)&& (pMsg->wParam == VK_TAB))
- {
- if(GetAsyncKeyState (VK_SHIFT) & 0x8000)
- {
- if(this->GetNextDlgGroupItem(&this->m_tabDemo)->m_hWnd == pMsg->hwnd)
- {
- int nCurItem;
- TCITEM itemCur;
- nCurItem = this->m_tabDemo.GetCurSel();
- itemCur.mask = TCIF_PARAM;
- this->m_tabDemo.GetItem(nCurItem, &itemCur);
- ((CDlgPage*)itemCur.lParam)->SetLastFocus() ;
- return TRUE;
- }
- }
- else
- {
- if(this->m_tabDemo.m_hWnd == pMsg->hwnd)
- {
- int nCurItem;
- TCITEM itemCur;
- nCurItem = this->m_tabDemo.GetCurSel();
- itemCur.mask = TCIF_PARAM;
- this->m_tabDemo.GetItem(nCurItem, &itemCur);
- ((CDlgPage*)itemCur.lParam)->SetFirstFocus();
- return TRUE;
- //TRACE("tab");
- }
- }
- }
- return CDialog::PreTranslateMessage(pMsg);
- }
图片
源代码可以去我的资源那下载:http://download.csdn.net/detail/lymcn/3817823