这两天受到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.youkuaiyun.com/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.youkuaiyun.com/detail/lymcn/3817823