MFC CTabCtrl焦点转移PreTranslateMessage实现方法

本文介绍了在MFC中如何解决CTabCtrl焦点转移的问题。通过重写CDialog类的PreTranslateMessage函数,并参考了xianglitian的文章《TabCtrl使用范例》,最终实现了主窗口与子界面焦点的正常切换。详细代码可从作者的资源下载链接获取。

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

这两天受到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


评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值