您的位置:首页 > Web前端 > HTML

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

}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: 
相关文章推荐