DHTML设计VC界面《三》- Toolbar工具栏

来源:互联网 发布:php手册下载 编辑:程序博客网 时间:2024/05/17 01:10

 

 要用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);
 

  1. int CDHtmlUIDemoDlg::GetToolbarElemCount()
  2. {
  3.     cHtmlTable tb(this->GetElem("tbToolbar"));
  4.     if(!tb.Valid()||tb.GetRowCount()<=0)
  5.         return 0;
  6.     return tb.GetRow(0).GetCellCount();
  7. }
  8. int CDHtmlUIDemoDlg::GetToolbarElemID(int index)
  9. {
  10.     cHtmlTable tb(this->GetElem("tbToolbar"));
  11.     if(!tb.Valid()||tb.GetRowCount()<=0)
  12.         return 0;
  13.     cHtmlTableRow tr = tb.GetRow(0);
  14.     if(index<0||index>=tr.GetCellCount())
  15.         return 0;
  16.     BSTR bstr;
  17.     tr.GetCell(index).mi_Elem->get_id(&bstr);
  18.     string sid = (LPCTSTR)CString(bstr);
  19.     int len = sid.rfind('_');
  20.     return atoi(sid.substr(len+1,sid.length()-len-1).c_str());
  21. }
  22. BOOL CDHtmlUIDemoDlg::GetToolbarElemEnable(int id)
  23. {
  24.     CString tid;
  25.     tid.Format("toolbar_%d",id);
  26.     cHtmlElement elem = this->GetElem(tid);
  27.     if(!elem.Valid())
  28.         return FALSE;
  29.     return atoi(elem.GetAttribute("bar"));
  30. }
  31. void CDHtmlUIDemoDlg::AddToolbarElem(CString img,CString text,CString title,int id,BOOL enable)
  32. {
  33.     CString tid;
  34.     tid.Format("toolbar_%d",id);
  35.     cHtmlElement e = this->GetElem(tid);
  36.     if(e.Valid())
  37.         return;
  38.     string s_img = img;
  39.     _replace(s_img,"/","//");
  40.     char path[_MAX_PATH];
  41.     sprintf_s(path,sizeof(path),"file:///%s%s",QueryExePath().c_str(),s_img.c_str());
  42.     s_img = path;
  43.     cHtmlTable tb(GetElem("tbToolbar"));
  44.     if(!tb.Valid())
  45.         return;
  46.     cHtmlTableRow tr(0);
  47.     if(tb.GetRowCount()<=0)
  48.         tr = tb.InsertRow(-1,0);
  49.     else
  50.         tr = tb.GetRow(0);
  51.     cHtmlTableCell tc = tr.InsertCell(-1);
  52.     if(id==0)
  53.     {
  54.         char path[_MAX_PATH];
  55.         sprintf_s(path,sizeof(path),"file:///%sres//splite.png",QueryExePath().c_str());
  56.         stringstream ss;
  57.         ss << "<img src='" << path << "' border=0>";
  58.         tc.SetInnerHtml(ss.str().c_str());
  59.     }
  60.     else
  61.     {
  62.         tc.mi_Elem->put_title(title.AllocSysString());
  63.         CString sid;
  64.         sid.Format("toolbar_%d",id);
  65.         tc.mi_Elem->put_id(sid.AllocSysString());
  66.         stringstream ss;
  67.         ss << "<table  width=68 height=64 parent=" << sid << ">";
  68.         ss << "<tr><td align=center parent=" << sid << ">";
  69.             ss << "<img src='" << s_img << "' parent=" << sid << ">";
  70.         ss << "</td></tr>";
  71.         ss << "<tr><td align=center parent=" << sid << ">";
  72.             ss << "<span parent=" << sid << ">" << text << "</span>";
  73.         ss << "</td></tr>";
  74.         ss << "</table>";
  75.         tc.SetInnerHtml(ss.str().c_str());
  76.         this->EnableToolbarElem(id,enable);
  77.     }
  78. }
  79. void CDHtmlUIDemoDlg::ClearToolbarElem()
  80. {
  81.     cHtmlTable tb(GetElem("tbToolbar"));
  82.     if(!tb.Valid())
  83.         return;
  84.     if(tb.GetRowCount()>0)
  85.         tb.GetRow(0).Remove();
  86. }
  87. void CDHtmlUIDemoDlg::EnableToolbarElem(int id,BOOL enable)
  88. {
  89.     CString tid;
  90.     tid.Format("toolbar_%d",id);
  91.     cHtmlElement elem = this->GetElem(tid);
  92.     if(!elem.Valid())
  93.         return;
  94.     if(enable)
  95.     {
  96.         elem.mi_Elem->put_className(CString("td_normal").AllocSysString());
  97.         elem.mi_Elem->put_onmouseover(this->m_vtEventHover);
  98.         elem.mi_Elem->put_onmouseout(this->m_vtEventOut);
  99.         elem.SetAttribute("bar",1);
  100.     }
  101.     else
  102.     {
  103.         elem.mi_Elem->put_className(CString("td_gray").AllocSysString());
  104.         elem.mi_Elem->put_onmouseover(this->m_vtEventNull);
  105.         elem.mi_Elem->put_onmouseout(this->m_vtEventNull);
  106.         elem.SetAttribute("bar",0);
  107.     }
  108. }

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就可以加入一个分隔符

 具体代码里面可以看到

  1.     if(id==0)
  2.     {
  3.         char path[_MAX_PATH];
  4.         sprintf_s(path,sizeof(path),"file:///%sres//splite.png",QueryExePath().c_str());
  5.         stringstream ss;
  6.         ss << "<img src='" << path << "' border=0>";
  7.         tc.SetInnerHtml(ss.str().c_str());
  8.     }

就是添加一个<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中

 

  1. void CDHtmlUIDemoDlg::EnableToolbarElem(int id,BOOL enable)
  2. {
  3.     CString tid;
  4.     tid.Format("toolbar_%d",id);
  5.     cHtmlElement elem = this->GetElem(tid);
  6.     if(!elem.Valid())
  7.         return;
  8.     if(enable)
  9.     {
  10.         elem.mi_Elem->put_className(CString("td_normal").AllocSysString());
  11.         elem.mi_Elem->put_onmouseover(this->m_vtEventHover);
  12.         elem.mi_Elem->put_onmouseout(this->m_vtEventOut);
  13.         elem.SetAttribute("bar",1);
  14.     }
  15.     else
  16.     {
  17.         elem.mi_Elem->put_className(CString("td_gray").AllocSysString());
  18.         elem.mi_Elem->put_onmouseover(this->m_vtEventNull);
  19.         elem.mi_Elem->put_onmouseout(this->m_vtEventNull);
  20.         elem.SetAttribute("bar",0);
  21.     }
  22. }

看看上面的代码,就知道这3个变量的作用了

 

5. 按钮事件处理

  常规的DHtml事件处理都是通过DHTML_EVENT_CLASS + css 或者 DHTML_EVENT_ONCLICK + id 实现,本文不做具体介绍,但是由于我们的按钮是<td>元素里面的内嵌<table>,通过测试发现,这种混合型的table,使用DHTML_EVENT_CLASS 并不能有效的监控到按钮区域的完全点击,也就是说有些区域点到了,事件并不触发。

   所以作者使用了更加原始的PreTranslateMessage来处理这个问题

    DHtml的PreTranslateMessage能做很多事情,例如屏蔽鼠标右键等等,这里我们只处理左键点击

 

  1. BOOL CDHtmlUIDemoDlg::PreTranslateMessage(MSG* pMsg)
  2. {
  3.     if(pMsg->message==WM_LBUTTONUP)
  4.     {
  5.         CPoint point(pMsg->pt);
  6.         ScreenToClient(&point);
  7.         IHTMLElement* pElement=NULL;
  8.         this->m_spHtmlDoc->elementFromPoint(point.x,point.y,&pElement);
  9.         if(pElement)
  10.         {
  11.             cHtmlElement elem(pElement);
  12.             if(elem.Valid())
  13.             {
  14.                 BSTR b;
  15.                 elem.mi_Elem->get_id(&b);
  16.                 CString id(b);
  17.                 string pid = elem.GetAttribute("parent");
  18.                 if(pid.empty())
  19.                 {
  20.                     CComPtr<IHTMLElement> parent;
  21.                     elem.mi_Elem->get_parentElement(&parent);
  22.                     cHtmlElement eParent(parent);
  23.                     pid = elem.GetAttribute("parent");
  24.                 }
  25.                 if(!pid.empty())
  26.                 {
  27.                     cHtmlElement elem = this->GetElem(pid.c_str());
  28.                     BOOL bar = atoi(elem.GetAttribute("bar"));
  29.                     if(bar)
  30.                     {                       
  31.                         int len = pid.rfind('_');
  32.                         int id = atoi(pid.substr(len+1,pid.length()-len-1).c_str());
  33.                         CString fmt;
  34.                         fmt.Format("Toolbar ID %d Clicked",id);
  35.                         AfxMessageBox(fmt);
  36.                     }
  37.                 }
  38.             }
  39.         }
  40.         return CDHtmlDialog::PreTranslateMessage(pMsg);
  41.     }
  42.     return CDHtmlDialog::PreTranslateMessage(pMsg);
  43. }

 

原创粉丝点击