您的位置:首页 > 其它

MFC CTabCtrl焦点转移PreTranslateMessage实现方法

2011-11-20 13:50 495 查看
这两天受到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
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: