DHTML设计VC界面《三》- Toolbar工具栏
2008-09-01 13:21
375 查看
要用DHtml实现工具栏,有几个工具栏的特性要实现
1.Tooltip 鼠标移到按钮上要有提示出现,这个比较简单,HTML元素里面的title即可实现;
2.分隔栏,这个嘛也不难,做一个分隔栏的背景图做<td>即可,demo/res/splite.png即这个资源文件
3.按钮变灰,这个可以用css控制来实现
4.按钮的xp浮动效果,正常平板显示,鼠标移上按钮凸出,鼠标移开按钮凹下,这个也是需要用css来实现,后文具体交代
5.按钮的点击事件处理,这个一般有2种方法,一种是使用
DHTML_EVENT_CLASS配合css名称完成,一种是处理PreTranslateMessage事件,本文采用第二种方式,后文具体交代为什么不采用第一种方式。
基本函数集
VARIANT m_vtEventHover;//鼠标hover事件预设
VARIANT m_vtEventOut;//鼠标out事件预设
VARIANT m_vtEventNull;//鼠标null事件预设
int GetToolbarElemCount();
int GetToolbarElemID(int index);
void AddToolbarElem(CString img,CString text,CString title,int id,BOOL enable=TRUE);
void EnableToolbarElem(int id,BOOL enable=TRUE);
BOOL GetToolbarEnable(int id);
void ClearToolbarElem();
BOOL GetToolbarElemEnable(int id);
int CDHtmlUIDemoDlg::GetToolbarElemCount()
{
cHtmlTable tb(this->GetElem("tbToolbar"));
if(!tb.Valid()||tb.GetRowCount()<=0)
return 0;
return tb.GetRow(0).GetCellCount();
}
int CDHtmlUIDemoDlg::GetToolbarElemID(int index)
{
cHtmlTable tb(this->GetElem("tbToolbar"));
if(!tb.Valid()||tb.GetRowCount()<=0)
return 0;
cHtmlTableRow tr = tb.GetRow(0);
if(index<0||index>=tr.GetCellCount())
return 0;
BSTR bstr;
tr.GetCell(index).mi_Elem->get_id(&bstr);
string sid = (LPCTSTR)CString(bstr);
int len = sid.rfind('_');
return atoi(sid.substr(len+1,sid.length()-len-1).c_str());
}
BOOL CDHtmlUIDemoDlg::GetToolbarElemEnable(int id)
{
CString tid;
tid.Format("toolbar_%d",id);
cHtmlElement elem = this->GetElem(tid);
if(!elem.Valid())
return FALSE;
return atoi(elem.GetAttribute("bar"));
}
void CDHtmlUIDemoDlg::AddToolbarElem(CString img,CString text,CString title,int id,BOOL enable)
{
CString tid;
tid.Format("toolbar_%d",id);
cHtmlElement e = this->GetElem(tid);
if(e.Valid())
return;
string s_img = img;
_replace(s_img,"/","//");
char path[_MAX_PATH];
sprintf_s(path,sizeof(path),"file:///%s%s",QueryExePath().c_str(),s_img.c_str());
s_img = path;
cHtmlTable tb(GetElem("tbToolbar"));
if(!tb.Valid())
return;
cHtmlTableRow tr(0);
if(tb.GetRowCount()<=0)
tr = tb.InsertRow(-1,0);
else
tr = tb.GetRow(0);
cHtmlTableCell tc = tr.InsertCell(-1);
if(id==0)
{
char path[_MAX_PATH];
sprintf_s(path,sizeof(path),"file:///%sres//splite.png",QueryExePath().c_str());
stringstream ss;
ss << "<img src='" << path << "' border=0>";
tc.SetInnerHtml(ss.str().c_str());
}
else
{
tc.mi_Elem->put_title(title.AllocSysString());
CString sid;
sid.Format("toolbar_%d",id);
tc.mi_Elem->put_id(sid.AllocSysString());
stringstream ss;
ss << "<table width=68 height=64 parent=" << sid << ">";
ss << "<tr><td align=center parent=" << sid << ">";
ss << "<img src='" << s_img << "' parent=" << sid << ">";
ss << "</td></tr>";
ss << "<tr><td align=center parent=" << sid << ">";
ss << "<span parent=" << sid << ">" << text << "</span>";
ss << "</td></tr>";
ss << "</table>";
tc.SetInnerHtml(ss.str().c_str());
this->EnableToolbarElem(id,enable);
}
}
void CDHtmlUIDemoDlg::ClearToolbarElem()
{
cHtmlTable tb(GetElem("tbToolbar"));
if(!tb.Valid())
return;
if(tb.GetRowCount()>0)
tb.GetRow(0).Remove();
}
void CDHtmlUIDemoDlg::EnableToolbarElem(int id,BOOL enable)
{
CString tid;
tid.Format("toolbar_%d",id);
cHtmlElement elem = this->GetElem(tid);
if(!elem.Valid())
return;
if(enable)
{
elem.mi_Elem->put_className(CString("td_normal").AllocSysString());
elem.mi_Elem->put_onmouseover(this->m_vtEventHover);
elem.mi_Elem->put_onmouseout(this->m_vtEventOut);
elem.SetAttribute("bar",1);
}
else
{
elem.mi_Elem->put_className(CString("td_gray").AllocSysString());
elem.mi_Elem->put_onmouseover(this->m_vtEventNull);
elem.mi_Elem->put_onmouseout(this->m_vtEventNull);
elem.SetAttribute("bar",0);
}
}
1. 按钮添加
注意添加按钮的操作要放在OnNavigateComplete里面,而不能放在OnInitDialog里。
#define ID_ADD 1000
#define ID_START 1001
#define ID_STOP 1002
#define ID_DELETE 1003
this->AddToolbarElem("res/add.gif","添加","添加新文件",ID_ADD);
this->AddToolbarElem("","","",0);//分隔符
this->AddToolbarElem("res/start.gif","开始","开始工作",ID_START);
this->AddToolbarElem("res/stop.gif","停止","停止工作",ID_STOP);
this->AddToolbarElem("res/delete.gif","删除","删除单元",ID_DELETE,FALSE);
2.分隔符
this->AddToolbarElem("","","",0),将ID设置为0就可以加入一个分隔符
具体代码里面可以看到
if(id==0)
{
char path[_MAX_PATH];
sprintf_s(path,sizeof(path),"file:///%sres//splite.png",QueryExePath().c_str());
stringstream ss;
ss << "<img src='" << path << "' border=0>";
tc.SetInnerHtml(ss.str().c_str());
}
就是添加一个<image src=res/splite.png>
3.按钮变灰
this->AddToolbarElem("res/delete.gif","删除","删除单元",ID_DELETE,FALSE);
函数最后一个参数置为FALSE就是变灰,实际就是控制cssName为tb_grey
4. xp按钮浮动效果
javascript高手都知道,用Html的Table可以模仿出一个Window按钮,而通过重载onmouseover和onmouseout2个事件加以一定的css控制就可以完全模拟出浮动效果
本文的浮动效果原理就是这样,常规时table的css为tb_normal,onmouserover时修改css为tb_hover,onmouserout时修改回tb_normal
原理是这样,但是要完美的实现并不是那么简单。
javascript的事件处理,我们在DHtml初始化的时候可以简单的写<tb onmouseover="this.className=aaa">,但是如果要在程序运行时去修改这个onmouseover就不那么简单了,因为对于DHtml来说,只要初始化以后,系统内部就把这个事件解释成一个VARIANT对象了,再修改时使用简单的SetInnerHtml是修改不了的,必须也是针对VARIANT对象,搜搜Google可以看到有专栏文章介绍在VC里面怎么为javascript的事件创建VARIANT。本文为了简单用了一个偷懒的方法,就是在html里面人工创建一个事件母体
<div id="eventSet" onmouseover="this.className='td_hover'" onmouseout="this.className='td_normal'" onmousedown=""></div>
然后在初始化的时候把这些事件存储到m_vtEventHover,m_vtEventOut,m_vtEventNull中
void CDHtmlUIDemoDlg::EnableToolbarElem(int id,BOOL enable)
{
CString tid;
tid.Format("toolbar_%d",id);
cHtmlElement elem = this->GetElem(tid);
if(!elem.Valid())
return;
if(enable)
{
elem.mi_Elem->put_className(CString("td_normal").AllocSysString());
elem.mi_Elem->put_onmouseover(this->m_vtEventHover);
elem.mi_Elem->put_onmouseout(this->m_vtEventOut);
elem.SetAttribute("bar",1);
}
else
{
elem.mi_Elem->put_className(CString("td_gray").AllocSysString());
elem.mi_Elem->put_onmouseover(this->m_vtEventNull);
elem.mi_Elem->put_onmouseout(this->m_vtEventNull);
elem.SetAttribute("bar",0);
}
}
看看上面的代码,就知道这3个变量的作用了
5. 按钮事件处理
常规的DHtml事件处理都是通过DHTML_EVENT_CLASS + css 或者 DHTML_EVENT_ONCLICK + id 实现,本文不做具体介绍,但是由于我们的按钮是<td>元素里面的内嵌<table>,通过测试发现,这种混合型的table,使用DHTML_EVENT_CLASS 并不能有效的监控到按钮区域的完全点击,也就是说有些区域点到了,事件并不触发。
所以作者使用了更加原始的PreTranslateMessage来处理这个问题
DHtml的PreTranslateMessage能做很多事情,例如屏蔽鼠标右键等等,这里我们只处理左键点击
BOOL CDHtmlUIDemoDlg::PreTranslateMessage(MSG* pMsg)
{
if(pMsg->message==WM_LBUTTONUP)
{
CPoint point(pMsg->pt);
ScreenToClient(&point);
IHTMLElement* pElement=NULL;
this->m_spHtmlDoc->elementFromPoint(point.x,point.y,&pElement);
if(pElement)
{
cHtmlElement elem(pElement);
if(elem.Valid())
{
BSTR b;
elem.mi_Elem->get_id(&b);
CString id(b);
string pid = elem.GetAttribute("parent");
if(pid.empty())
{
CComPtr<IHTMLElement> parent;
elem.mi_Elem->get_parentElement(&parent);
cHtmlElement eParent(parent);
pid = elem.GetAttribute("parent");
}
if(!pid.empty())
{
cHtmlElement elem = this->GetElem(pid.c_str());
BOOL bar = atoi(elem.GetAttribute("bar"));
if(bar)
{
int len = pid.rfind('_');
int id = atoi(pid.substr(len+1,pid.length()-len-1).c_str());
CString fmt;
fmt.Format("Toolbar ID %d Clicked",id);
AfxMessageBox(fmt);
}
}
}
}
return CDHtmlDialog::PreTranslateMessage(pMsg);
}
return CDHtmlDialog::PreTranslateMessage(pMsg);
}
相关文章推荐
- DHTML设计VC界面《二》- 背景
- DHTML设计VC界面《五》- 容器
- DHTML设计VC界面《四》- TabCtrl标签栏
- VC.NET界面编程中关于的ToolBar(工具栏)的编程应用(一)
- VC.NET界面编程中关于的ToolBar(工具栏)的编程应用(二)2008/07/01 19:22 上回说到给工具栏上添加IE风格的下拉菜单按钮,我们通过设置工具栏按钮的风格已经完成了下拉菜单按钮的添加,现在我们准备为下拉菜单按钮中响应下拉箭头部分的实现
- CJLibrary--VC下高级界面设计的利器
- VC++界面编程之--实现工具栏自定义皮肤
- VC界面设计(破解版skin++皮肤库使用)
- vc 界面编程常用方法 listctrl toolbar
- vc--基于mfc对话框的手柄遥控机器人界面设计(二)
- IOS界面元素四栏(状态栏、导航栏、工具栏、TAB栏)设计规范
- DirectUI Skin++界面解决方案 界面设计 界面开发 软件UI界面开发 软件UI界面美术设计 界面编程 界面教程 Skin VC VB C# .net pb delphi c builder GUI
- VC远控(一)界面设计及套接字连接测试
- [开发日记]图片抽奖软件的原型设想及界面设计-打算用PowerPoint结合Vc++完美实现 (进展一)
- VC/Wince 实现仿Win8 Metro风格界面1——设计概述和自绘Button(附效果图)
- VC个性化窗口界面设计
- 界面设计-VC++中英繁多国语言CLI实现
- 为对话框设计美观的工具栏 (Add toolbar for CDialog)
- 【VC编程技巧】动态链接库☞1.6设计应用程序界面换肤
- VC++界面编程----个性化你的工具栏图标(转)