MFC CTabCtrl焦点转移PreTranslateMessage实现方法


本文转载自:lymcn专栏http://blog.csdn.net/lymcn/article/details/6992926

这两天受到MFC的CTabCtrl的折磨,焦点在主窗口与子界面太难实现切换了,经理一天的努力,查阅了大量资料还是不能简单实现,最后还是只能通过重写PreTranslateMessage。见下面代码:

重载CDialog类:

[cpp]  view plain  copy
  1. #pragma once  
  2.   
  3.   
  4. // DlgPage 对话框  
  5.   
  6. class CDlgPage : public CDialog  
  7. {  
  8.     DECLARE_DYNAMIC(CDlgPage)  
  9.   
  10. public:  
  11.     CDlgPage(UINT nIDTemplate, CWnd* pParent = NULL);   // 标准构造函数  
  12.     virtual ~CDlgPage();  
  13.   
  14. protected:  
  15.     virtual void DoDataExchange(CDataExchange* pDX);    // DDX/DDV 支持  
  16.   
  17.     DECLARE_MESSAGE_MAP()  
  18. public:  
  19.     virtual BOOL PreTranslateMessage(MSG* pMsg);  
  20.     // 获取第一个TAB控件句柄  
  21.     HWND GetFirstTab(void);  
  22.     // 获取最后一个TAB控件句柄  
  23.     HWND GetLastTab(void);  
  24.     // 设置第一个控件得到焦点  
  25.     void SetFirstFocus(void);  
  26.     // 设置最后一个控件得到焦点  
  27.     void SetLastFocus(void);  
  28. };  
  29.   
  30. // DlgPage.cpp : 实现文件  
  31. //  
  32.   
  33. #include "stdafx.h"  
  34. #include "TabDemo.h"  
  35. #include "DlgPage.h"  
  36.   
  37.   
  38. // DlgPage 对话框  
  39.   
  40. IMPLEMENT_DYNAMIC(CDlgPage, CDialog)  
  41.   
  42. CDlgPage::CDlgPage(UINT nIDTemplate, CWnd* pParent /*=NULL*/)  
  43.     : CDialog(nIDTemplate, pParent)  
  44. {  
  45. #ifndef _WIN32_WCE  
  46.     EnableActiveAccessibility();  
  47. #endif  
  48.   
  49. }  
  50.   
  51. CDlgPage::~CDlgPage()  
  52. {  
  53. }  
  54.   
  55. void CDlgPage::DoDataExchange(CDataExchange* pDX)  
  56. {  
  57.     CDialog::DoDataExchange(pDX);  
  58. }  
  59.   
  60.   
  61. BEGIN_MESSAGE_MAP(CDlgPage, CDialog)  
  62. END_MESSAGE_MAP()  
  63.   
  64.   
  65. // DlgPage 消息处理程序  
  66.   
  67. BOOL CDlgPage::PreTranslateMessage(MSG* pMsg)  
  68. {  
  69.     // TODO: 在此添加专用代码和/或调用基类  
  70.     if((pMsg->message == WM_KEYDOWN)&& (pMsg->wParam == VK_TAB))  
  71.     {  
  72.         if(GetAsyncKeyState (VK_SHIFT) & 0x8000)  
  73.         {  
  74.             if(pMsg->hwnd == GetFirstTab())  
  75.             {  
  76.                 this->GetParent()->SetFocus();  
  77.                 return TRUE;  
  78.             }  
  79.         }  
  80.         else  
  81.         {  
  82.             if(pMsg->hwnd == GetLastTab())  
  83.             {  
  84.                 this->GetParent()->GetParent()->GetNextDlgTabItem(this->GetParent())->SetFocus();  
  85.                 return TRUE;  
  86.             }  
  87.         }  
  88.     }  
  89.     return CDialog::PreTranslateMessage(pMsg);  
  90. }  
  91.   
  92. // 获取第一个TAB控件句柄  
  93. HWND CDlgPage::GetFirstTab(void)  
  94. {  
  95.     HWND   hWnd   =   ::GetWindow(m_hWnd,GW_CHILD);  
  96.     HWND   hFirstCtrl;  
  97.     while (hWnd)  
  98.     {  
  99.         if   (::IsWindowEnabled(hWnd)   &&   ::IsWindowVisible(hWnd)   &&  
  100.             (::GetWindowLong(hWnd,   GWL_STYLE)   &   WS_TABSTOP))   
  101.         {  
  102.             hFirstCtrl   =   hWnd;  
  103.             break;  
  104.         }  
  105.         hWnd   =   ::GetWindow(hWnd,   GW_HWNDNEXT);  
  106.     }  
  107.     return hFirstCtrl;  
  108. }  
  109.   
  110. // 获取最后一个TAB控件句柄  
  111. HWND CDlgPage::GetLastTab(void)  
  112. {  
  113.     HWND   hWnd   =   ::GetWindow(m_hWnd,GW_CHILD);  
  114.     HWND   hLastCtrl;  
  115.     while (hWnd)  
  116.     {  
  117.         if   (::IsWindowEnabled(hWnd)   &&   ::IsWindowVisible(hWnd)   &&  
  118.             (::GetWindowLong(hWnd,   GWL_STYLE)   &   WS_TABSTOP))    
  119.             hLastCtrl   =   hWnd;  
  120.         hWnd   =   ::GetWindow(hWnd,   GW_HWNDNEXT);  
  121.     }  
  122.     return hLastCtrl;  
  123. }  
  124. // 设置第一个控件得到焦点  
  125. void CDlgPage::SetFirstFocus(void)  
  126. {  
  127.     ::SetFocus(this->GetFirstTab());  
  128. }  
  129.   
  130. // 设置最后一个控件得到焦点  
  131. void CDlgPage::SetLastFocus(void)  
  132. {  
  133.     ::SetFocus(this->GetLastTab());  
  134. }  

这个类纯为实现在Tab页内Tab order切换用。

借用xianglitian的例子:《TabCtrl使用范例》 地址:http://download.csdn.net/detail/xianglitian/2260893,在此基础上添加以上类,并对内容进行修改,最终实现正常切换效果。

重载PreTranslateMessage:

[cpp]  view plain  copy
  1. BOOL CTabDemoDlg::PreTranslateMessage(MSG* pMsg)  
  2. {  
  3.     if((pMsg->message == WM_KEYDOWN)&& (pMsg->wParam == VK_TAB))  
  4.     {  
  5.         if(GetAsyncKeyState (VK_SHIFT) & 0x8000)  
  6.         {  
  7.             if(this->GetNextDlgGroupItem(&this->m_tabDemo)->m_hWnd == pMsg->hwnd)  
  8.             {  
  9.                 int     nCurItem;  
  10.                 TCITEM  itemCur;  
  11.   
  12.                 nCurItem        = this->m_tabDemo.GetCurSel();  
  13.                 itemCur.mask    = TCIF_PARAM;  
  14.   
  15.                 this->m_tabDemo.GetItem(nCurItem, &itemCur);  
  16.                 ((CDlgPage*)itemCur.lParam)->SetLastFocus() ;  
  17.                   
  18.                 return TRUE;  
  19.             }  
  20.         }  
  21.         else  
  22.         {  
  23.             if(this->m_tabDemo.m_hWnd == pMsg->hwnd)  
  24.             {  
  25.                 int     nCurItem;  
  26.                 TCITEM  itemCur;  
  27.   
  28.                 nCurItem        = this->m_tabDemo.GetCurSel();  
  29.                 itemCur.mask    = TCIF_PARAM;  
  30.   
  31.                 this->m_tabDemo.GetItem(nCurItem, &itemCur);  
  32.                 ((CDlgPage*)itemCur.lParam)->SetFirstFocus();  
  33.                 return TRUE;  
  34.                 //TRACE("tab");  
  35.             }  
  36.         }  
  37.     }  
  38.     return CDialog::PreTranslateMessage(pMsg);  
  39. }  

图片


源代码可以去我的资源那下载:http://download.csdn.net/detail/lymcn/3817823


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值