| 订阅 | 在线投稿
分享
 
 
 

IE Toolbar 的实现思路

来源:互联网网民  宽屏版  评论
2006-09-15 06:28:02

实现思路思路:

在实现之前,需要先了解IE下 ToolBar的工作原理,关于这部分内容这里就不多介绍,http://www.vckbase.com/上有很多介绍,里面列举了一些如何创建基本的IE ToolBar的方法及原理。了解创建原理后,按照里面的套路,就可以亦步亦趋的生成基本框架。

IE的ToolBar的开发,实质上也就是一个一般的ToolBar开发,为了加速开发,我们选择基于MFC的开发。因此需要在项目的stdafx.h里加入MFC相关的头文件。并写一个类(CMyToolBar)继承自MFC的CToolBar类。今后所有的操作都基于这个类来进行。

ToolBar在实现的时候,根据实现的过程,分为2个部分:

1. 上的控件生成ToolBar

2. 的弹出子菜单生成及弹出子菜单的事件响应ToolBar

1. 上的控件生成ToolBar

目前在ToolBar里添加了4个类型的控件

l 图片Lable

l 文字Lable

l TextBox

l Button

a) 图片Label

因为CToolBar不支持同时显示不同宽度的图片Button,因此,要显示图片,我们只能用一些其它取巧的方法。设置一个不处理事件的Button,宽度和要显示的图片的宽度一样,然后创建一个带图片的Label,将Button覆盖。这样就只看到带图片的Label了。

创建带图片Label的四个步骤:

1) 通过 InsertButton 方法创建一个占位Button

2) 读取要显示图片(BMP)

3) 通过SetButtonInfo方法重新设置Button宽度(与读取图片等宽)

4) 创建CStatic,并SetBitmap设置要显示的图片

p.s. 实际在显示bitmap图片的时候,图片的背景色并不是透明的,因此显示效果不是很好,在实际应用中,采用了一个 CTransparentImage 的控件实现透明背景。

p.s. 如果需要显示的图片是ICON,则无须透明背景的设置,只要在编辑ICON的时候设置好透明色即可。不过考虑到CStatic在显示ICON的时候,是按照正方形方式去显示,因此非正方形的ICON在显示的时候会被缩放,目前还没找到合适的解决办法。

p.s. 插入一个占位Button的方法:

CToolBarCtrl& tbc = GetToolBarCtrl();

TBBUTTONtButton;

ZeroMemory(&tButton, sizeof(TBBUTTON));

tButton.fsStyle = TBSTYLE_BUTTON;

tButton.idCommand = IDC_PICTURE;

tButton.iBitmap = -1;

tbc.InsertButton(-1, &tButton);

p.s. 修改一个Button的宽度的方法

CToolBarCtrl& tbc = GetToolBarCtrl();

TBBUTTONINFOtif;

tif.cbSize = sizeof(tif);

tif.dwMask = TBIF_SIZE;

tif.fsStyle = TBSTYLE_AUTOSIZE;

tif.cx = bmpInfo.bmWidth + 4; // 设置Button的宽度

tbc.SetButtonInfo (IDC_PICTURE, &tif);

b) 文字Label

文字Label的创建方法和图片Label步骤一样,只不过缺少设置图片过程,不过占位用的Button宽度还是需要通过获得Label显示的文字宽度来进行调整。

c) TextBox

TextBox的创建和Label的方法和过程一样,基本上也是创建后即可使用。

不过需要注意的是,直接创建的TextBox在运行的时候,无法处理某些特殊功能的按键,例如:“退格键”。原因应该是IE没有把所有的键盘消息传递给它的子控件,因此TextBox自然无法使用“退格键”进行文本的删除操作。

解决方案有两个:

1. 实现 IInputObject接口,来获得用户输入信息

2. 通过钩子函数拦截系统的键盘消息

考虑到实现IInputObject接口的方法示例代码太少,无从研究,因此采用第二种方案,采用钩子函数拦截键盘消息。

1. 新建一个CMyEdit类,继承自CEdit。

2. 重载OnSetFocus和OnKillFocus方法。

当TextBox获得焦点(OnSetFocus)的时候通过SetWindowsHookEx创建一个消息钩子

当TextBox失去焦点(OnKillFocus)的时候通过UnhookWindowsHookEx释放钩子

3. 实现一个删除字符功能的函数

因为IE已经屏蔽了退格键,因此在拦截到用户输入的键盘消息后,不能将消息转发TextBox控件,消息会再次被IE拦截并屏蔽。这里只能通过自己实现删除文字的功能。

voidCMyEdit::KillChar()

{

int nStartChar, nEndChar;

GetSel(nStartChar, nEndChar);

if(nStartChar == nEndChar)

{

if (nStartChar > 0)

nStartChar --;

}

this->SetSel(nStartChar, nEndChar);

this->ReplaceSel(_T(""));

}

4. 实现处理钩子功能的函数

LRESULTFARPASCALGetMsgProc(intnCode, WPARAMwParam, LPARAMlParam)

{

LPMSGlpMsg = (LPMSG) lParam;

try

{

if ( nCode >= 0 && PM_REMOVE == wParam )

{

if (lpMsg->message == WM_KEYUP)

{

if (lpMsg->wParam == VK_BACK)

{

if (pEditMenuBar != NULL)

{

if (pEditMenuBar->m_edit.IsDialogMessage(lpMsg) == TRUE)

{

pEditMenuBar->m_edit.KillChar();

}

}

}

}

}

}

catch(CString& error)

{

CLog::WriteLogData(error.GetBuffer(0));

}

catch (...) {

// 捕捉异常,免得发生错误后系统崩溃

}

returnCallNextHookEx(g_hKeyHook, nCode, wParam, lParam);

}

d) Button

ToolBar本身在设计的时候,就是为了放置Button的,因此添加一个Button的操作比较简单。按照上边的方法设计即可,不需要再创佳对应的Button控件。不过郁闷的是,一旦Button指定了图片,SetButtonInfo方法就不能修改Button的大小了。

在实际设计过程中,最后一个Button需要在Button右边加一个小三角,用于提示这里可以弹出一个用于选择的菜单,方法行简单,通过设置Button的属性即可

tbc.SendMessage(TB_SETEXTENDEDSTYLE, 0, (LPARAM)TBSTYLE_EX_DRAWDDARROWS);

DWORDdwStyle = this->GetButtonStyle(this->CommandToIndex(MenuBtn.idCommand));

dwStyle |= TBSTYLE_DROPDOWN;

this->SetButtonStyle(this->CommandToIndex(MenuBtn.idCommand), dwStyle);

2.创建弹出子菜单,及子菜单的事件处理。

ToolBar的所有功能都集中在弹出菜单里。这部分功能其实行简单,就是一个在初始的时候动态创建菜单,并且在菜单事件被触发后,执行相应的逻辑代码而已。

菜单通过MFC的CMenu类进行创建,当ToolBar的Button被按下的时候(触发OnLButtonDown事件)的时候,通过CMenu里的TrackPopupMenu显示子菜单,并在菜单

我们通过重载CMyMenu的OnCommand方法,实现响应菜单消息,当弹出子菜单的时候,我们通过 LOWORD(wParam) 获响应菜单的ID,并根据菜单ID来处理响应的逻辑代码。

 
免责声明:本文为网络用户发布,其观点仅代表作者个人观点,与本站无关,本站仅提供信息存储服务。文中陈述内容未经本站证实,其真实性、完整性、及时性本站不作任何保证或承诺,请读者仅作参考,并请自行核实相关内容。
 
实现思路思路: 在实现之前,需要先了解IE下 ToolBar的工作原理,关于这部分内容这里就不多介绍,http://www.vckbase.com/上有很多介绍,里面列举了一些如何创建基本的IE ToolBar的方法及原理。了解创建原理后,按照里面的套路,就可以亦步亦趋的生成基本框架。 IE的ToolBar的开发,实质上也就是一个一般的ToolBar开发,为了加速开发,我们选择基于MFC的开发。因此需要在项目的stdafx.h里加入MFC相关的头文件。并写一个类(CMyToolBar)继承自MFC的CToolBar类。今后所有的操作都基于这个类来进行。 ToolBar在实现的时候,根据实现的过程,分为2个部分: 1. 上的控件生成ToolBar 2. 的弹出子菜单生成及弹出子菜单的事件响应ToolBar 1. 上的控件生成ToolBar 目前在ToolBar里添加了4个类型的控件 l 图片Lable l 文字Lable l TextBox l Button a) 图片Label 因为CToolBar不支持同时显示不同宽度的图片Button,因此,要显示图片,我们只能用一些其它取巧的方法。设置一个不处理事件的Button,宽度和要显示的图片的宽度一样,然后创建一个带图片的Label,将Button覆盖。这样就只看到带图片的Label了。 创建带图片Label的四个步骤: 1) 通过 InsertButton 方法创建一个占位Button 2) 读取要显示图片(BMP) 3) 通过SetButtonInfo方法重新设置Button宽度(与读取图片等宽) 4) 创建CStatic,并SetBitmap设置要显示的图片 p.s. 实际在显示bitmap图片的时候,图片的背景色并不是透明的,因此显示效果不是很好,在实际应用中,采用了一个 CTransparentImage 的控件实现透明背景。 p.s. 如果需要显示的图片是ICON,则无须透明背景的设置,只要在编辑ICON的时候设置好透明色即可。不过考虑到CStatic在显示ICON的时候,是按照正方形方式去显示,因此非正方形的ICON在显示的时候会被缩放,目前还没找到合适的解决办法。 p.s. 插入一个占位Button的方法: CToolBarCtrl& tbc = GetToolBarCtrl(); TBBUTTONtButton; ZeroMemory(&tButton, sizeof(TBBUTTON)); tButton.fsStyle = TBSTYLE_BUTTON; tButton.idCommand = IDC_PICTURE; tButton.iBitmap = -1; tbc.InsertButton(-1, &tButton); p.s. 修改一个Button的宽度的方法 CToolBarCtrl& tbc = GetToolBarCtrl(); TBBUTTONINFOtif; tif.cbSize = sizeof(tif); tif.dwMask = TBIF_SIZE; tif.fsStyle = TBSTYLE_AUTOSIZE; tif.cx = bmpInfo.bmWidth + 4; // 设置Button的宽度 tbc.SetButtonInfo (IDC_PICTURE, &tif); b) 文字Label 文字Label的创建方法和图片Label步骤一样,只不过缺少设置图片过程,不过占位用的Button宽度还是需要通过获得Label显示的文字宽度来进行调整。 c) TextBox TextBox的创建和Label的方法和过程一样,基本上也是创建后即可使用。 不过需要注意的是,直接创建的TextBox在运行的时候,无法处理某些特殊功能的按键,例如:“退格键”。原因应该是IE没有把所有的键盘消息传递给它的子控件,因此TextBox自然无法使用“退格键”进行文本的删除操作。 解决方案有两个: 1. 实现 IInputObject接口,来获得用户输入信息 2. 通过钩子函数拦截系统的键盘消息 考虑到实现IInputObject接口的方法示例代码太少,无从研究,因此采用第二种方案,采用钩子函数拦截键盘消息。 1. 新建一个CMyEdit类,继承自CEdit。 2. 重载OnSetFocus和OnKillFocus方法。 当TextBox获得焦点(OnSetFocus)的时候通过SetWindowsHookEx创建一个消息钩子 当TextBox失去焦点(OnKillFocus)的时候通过UnhookWindowsHookEx释放钩子 3. 实现一个删除字符功能的函数 因为IE已经屏蔽了退格键,因此在拦截到用户输入的键盘消息后,不能将消息转发TextBox控件,消息会再次被IE拦截并屏蔽。这里只能通过自己实现删除文字的功能。 voidCMyEdit::KillChar() { int nStartChar, nEndChar; GetSel(nStartChar, nEndChar); if(nStartChar == nEndChar) { if (nStartChar > 0) nStartChar --; } this->SetSel(nStartChar, nEndChar); this->ReplaceSel(_T("")); } 4. 实现处理钩子功能的函数 LRESULTFARPASCALGetMsgProc(intnCode, WPARAMwParam, LPARAMlParam) { LPMSGlpMsg = (LPMSG) lParam; try { if ( nCode >= 0 && PM_REMOVE == wParam ) { if (lpMsg->message == WM_KEYUP) { if (lpMsg->wParam == VK_BACK) { if (pEditMenuBar != NULL) { if (pEditMenuBar->m_edit.IsDialogMessage(lpMsg) == TRUE) { pEditMenuBar->m_edit.KillChar(); } } } } } } catch(CString& error) { CLog::WriteLogData(error.GetBuffer(0)); } catch (...) { // 捕捉异常,免得发生错误后系统崩溃 } returnCallNextHookEx(g_hKeyHook, nCode, wParam, lParam); } d) Button ToolBar本身在设计的时候,就是为了放置Button的,因此添加一个Button的操作比较简单。按照上边的方法设计即可,不需要再创佳对应的Button控件。不过郁闷的是,一旦Button指定了图片,SetButtonInfo方法就不能修改Button的大小了。 在实际设计过程中,最后一个Button需要在Button右边加一个小三角,用于提示这里可以弹出一个用于选择的菜单,方法行简单,通过设置Button的属性即可 tbc.SendMessage(TB_SETEXTENDEDSTYLE, 0, (LPARAM)TBSTYLE_EX_DRAWDDARROWS); DWORDdwStyle = this->GetButtonStyle(this->CommandToIndex(MenuBtn.idCommand)); dwStyle |= TBSTYLE_DROPDOWN; this->SetButtonStyle(this->CommandToIndex(MenuBtn.idCommand), dwStyle); 2.创建弹出子菜单,及子菜单的事件处理。 ToolBar的所有功能都集中在弹出菜单里。这部分功能其实行简单,就是一个在初始的时候动态创建菜单,并且在菜单事件被触发后,执行相应的逻辑代码而已。 菜单通过MFC的CMenu类进行创建,当ToolBar的Button被按下的时候(触发OnLButtonDown事件)的时候,通过CMenu里的TrackPopupMenu显示子菜单,并在菜单 我们通过重载CMyMenu的OnCommand方法,实现响应菜单消息,当弹出子菜单的时候,我们通过 LOWORD(wParam) 获响应菜单的ID,并根据菜单ID来处理响应的逻辑代码。
󰈣󰈤
 
 
 
>>返回首页<<
 
 热帖排行
 
 
静静地坐在废墟上,四周的荒凉一望无际,忽然觉得,凄凉也很美
©2005- 王朝网络 版权所有