2007-04-02

NVIDIA Geforce显卡系列驱动 游戏优化驱动

最近为了nvidia gefore4 mx4000显卡的驱动搜索了无数网页,找到了一个比较全的资料:

NV的各种版本驱动下载地址(NV官方ftp站点):
ftp://download.nvidia.com/Windows/
为游戏作特别优化的驱动列表如下:
《古墓丽影6:黑暗天使》 61.11
《古墓丽影7:传奇》 84.43
《使命召唤》 61.11
《使命召唤:联合攻击》 66.93
《使命召唤2》 81.95
《孤岛惊魂》 61.11,66.93,NGO81.85
《模拟城市4:高峰时刻》 61.77,66.81
《反恐精英》 DNA77.76,DNA83.10
《反恐精英:起源》 DNA71.80,DHO78.03,DHO81.84
《半条命2》 NGO67.02,DNA71.80,DHO78.03,DHO81.84
《半条命2:失落的海岸》 78.05,DHO81.84
《胜利之日:起源》 78.05,DHO81.84
《战地风云2》 77.50,NGO84.66
《魔兽世界》 77.72
《侠盗猎车手:圣安地列斯》NGO77.76
《光晕》 NGO77.76
《帝国时代3》 81.26
《美国军队》 DNA78.01,DNA83.10
《黑与白2》 81.84
《毁灭战士3》 NGO70.90,DHO78.03,NGO81.26
《雷神之锤4》 81.95
《恐惧》(F.E.A.R) NGO77.76,84.21
《虚幻竞技场2004》 DHO81.95
《极品飞车9:最高通缉》 81.98
《上古卷轴4:湮没》 84.25,91.33
为游戏作特别优化的驱动下载地址如下:
61.11《古墓丽影6:黑暗天使》《使命召唤》《孤岛惊魂》
http://count.mydrivers.com/downl ... /61.11_Win2K+XP.zip
61.77《模拟城市4:高峰时刻》
ftp://download.nvidia.com/Window ... p_international.exe
66.81《模拟城市4:高峰时刻》
ftp://download.nvidia.com/Window ... ernational_whql.exe
66.93《使命召唤:联合攻击》《孤岛惊魂》
ftp://download.nvidia.com/Window ... p_international.exe
NGO67.02《半条命2》
http://count.mydrivers.com/downl ... lay/NV_TCDrv0.3.exe
NGO70.90《毁灭战士3》
http://count.mydrivers.com/downl ... lay/NV_TCDrv0.4.exe
DNA71.80《反恐精英:起源》《半条命2》
http://count.mydrivers.com/downl ... _dnaforce117180.exe
77.50《战地风云2》
http://count.mydrivers.com/downl ... /nvidia_fw7750b.zip
77.72《魔兽世界》
ftp://download.nvidia.com/Window ... ernational_whql.exe
DNA77.76《反恐精英》
http://count.mydrivers.com/downl ... _Force_1.9.7776.exe
NGO77.76《光晕》《侠盗猎车手:圣安地列斯》《恐惧》(F.E.A.R)
http://count.mydrivers.com/downl ... A_NGO_drv177761.exe
DNA78.01《美国军队》
http://count.mydrivers.com/downl ... _Force_2.1.7801.exe
DHO78.03《反恐精英:起源》《半条命2》《毁灭战士3》
http://count.mydrivers.com/downl ... dia_DHzp_0.7803.exe
78.05《半条命2:失落的海岸》《胜利之日:起源》
ftp://download.nvidia.com/Window ... k_international.exe
81.26《帝国时代3》
http://count.mydrivers.com/downl ... /nvidia_fw8126b.zip
NGO81.26《毁灭战士3》
http://count.mydrivers.com/downl ... DIA_ngo8126beta.exe
81.84《黑与白2》
ftp://download.nvidia.com/Window ... t_international.exe
DHO81.84《反恐精英:起源》《半条命2》《半条命2:失落的海岸》《胜利之日:起源》
http://count.mydrivers.com/downl ... zer0point_08184.exe
NGO81.85《孤岛惊魂》
http://count.mydrivers.com/downl ... nVIDIA_NGO18185.exe
81.95《使命召唤2》《雷神之锤4》
ftp://download.nvidia.com/Window ... ernational_whql.exe
DHO81.95《虚幻竞技场2004》
http://count.mydrivers.com/downl ... a_dhzerop_08195.exe
81.98《极品飞车9:最高通缉》
ftp://download.nvidia.com/Window ... ernational_whql.exe
DNA83.10《美国军队》《反恐精英》
http://count.mydrivers.com/downl ... DNAForce.248310.exe
84.21《恐惧》(F.E.A.R)
ftp://download.nvidia.com/Window ... ernational_whql.exe
84.25《上古卷轴4:湮没》
ftp://download.nvidia.com/Window ... k_international.exe
84.43《古墓丽影7:传奇》
ftp://download.nvidia.com/Window ... k_international.exe
NGO84.66《战地风云2》
http://count.mydrivers.com/downl ... A_nvodngov18466.exe
91.33《上古卷轴4:湮没》
ftp://download.nvidia.com/Window ... k_international.exe
重要总结(驱动的使用方法指导):如果你所玩的游戏出现在“为游戏作特别优化的驱动列表”中,你就应该选用游戏所对应的驱动,但如果游戏没有出现在列表 中,对于FX显卡(FX5200 256MB显存除外)而言请使用 StarStorm56.72XQ,66.81,81.95,85.96 这4个版本驱动,对于其它系列显卡而言请参阅“nVIDIA全系列显示卡驱动程序使用指导”选择与显卡相对应的驱动。FX显卡(FX5200 256MB显存除外)驱动的使用方法是:先装StarStorm56.72XQ,如果在游戏中没有发现贴图错误,就用StarStorm56.72XQ, 如果在游戏中有贴图错误就换66.81,如果还有贴图错误就换81.95,还有错误就换85.96。在这4个版本驱动中最少有1个版本适合你,而且还能保 证你的FX卡在最快速度下运行。
StarStorm56.72XQ(为质量优化)(Windows 2000/XP)
http://downloads.guru3d.com/download.php?det=766
66.81(Windows 2000/XP)
ftp://download.nvidia.com/Window ... ernational_whql.exe
81.95(Windows 2000/XP)
ftp://download.nvidia.com/Window ... ernational_whql.exe
85.96(Windows 2000/XP)
http://count.mydrivers.com/downl ... orceWare_v8596b.exe
我建议大家把这4个版本驱动下载后收藏起来,作为“GeforceFX显卡经典系列驱动”以便随时更换使用版本。
用80.40等版本播放2D视频的颜色修正说明:
用80.40等版本播放2D视频时,视频的颜色会出现灰白现象,这只不过是80.40等版本的2D视频颜色默认设置没设置好而已,修正方法是打开80.40等版本的驱动控制面版,点颜色修正,点全部,点恢复默认,再点应用,最后点确定,OK问题解决!
特别说明:
我之所以用PCMark05的显卡部分做测试,而不是拿3DMark做测试就是因为象NV和ATI显卡厂商他们是非常重视给3DMark做优化的,但致于 PCMark的显卡部分的分数,显卡厂商是不太会重视的,从我测的分数上看也正好反映了这一点,比如:越高版本的驱动在3DMark05中得分越高,但越 高版本的驱动在游戏中却有的版本快有的版本慢,也就是说3DMark05被显卡厂商优化了,3DMark05的得分不能反映驱动的真实性能,而用 PCMark05的显卡部分的得分就能看出驱动对某一代显卡的真实性能,在PCMark05的显卡部分的得分中老驱动都比较高,新驱动有的高有的低,但都 没有老驱动高,正好反应了显卡厂商对老卡是不再提升性能了,而是在修正BUG,所以说PCMark的显卡部分的分数是比较能真实地反映驱动的真实性能,因 为显卡厂商非常重视给3DMark做优化,显卡厂商是不太会重视给PCMark的显卡部分做优化的。
所以说我选择PCMark05的显卡部分做测试还是比较有道理的。
附加,nVIDIA全系列显示卡驱动程序使用指导(以下资料根据台湾著名显卡网站的资料修改而成):
TNT2 系列 使用 14.10
14.10(Windows 2000/XP)
http://file2.mydrivers.com/display/W2k-1410-WHQL.exe
GeForce2 Ti/Pro/GTS 系列 使用 28.32
28.32(Windows 2000/XP)
ftp://download.nvidia.com/Windows/28.32/Winxp_2000_28.32.exe
GeForce2 MX 系列 使用 42.30
42.30(Windows 2000/XP)
http://file2.mydrivers.com/display/nvidia4230Win2K_XP.zip
GeForce3 系列 使用 28.32
28.32(Windows 2000/XP)
ftp://download.nvidia.com/Windows/28.32/Winxp_2000_28.32.exe
GeForce4 Ti4200-4X/ Ti4400 / Ti4600 / MX420 / MX440-4X / MX460 系列 使用 42.30
42.30(Windows 2000/XP)
http://file2.mydrivers.com/display/nvidia4230Win2K_XP.zip
GeForce4 Ti4800SE / Ti4200-8X / MX440-8X / MX440SE / MX4000 系列 使用 53.03
53.03(Windows 2000/XP)
ftp://download.nvidia.com/Window ... ernational_whql.exe
GeForceFX 5200(256MB显存) 使用 44.71(只适用于5200 256MB显存) 66.81 81.95 85.96
44.71(Windows 2000/XP)
http://file2.mydrivers.com/display/Win2K_XP_44.71_WHQL.exe
GeForce6 系列 使用 84.21
84.21(Windows 2000/XP)
ftp://download.nvidia.com/Window ... ernational_whql.exe
GeForce7 系列 使用 91.33
91.33(Windows 2000/XP)
ftp://download.nvidia.com/Window ... k_international.exe

宫琦俊所有动画片的剧情

1《幽灵公主》
古时遭受侵略而移居远方的虾夷族青年阿斯达卡,为了拯救遭受危险的村人,右手被凶煞神诅咒,为了寻找解除诅咒的方法,阿斯达卡决定离开亲人到西方去流浪。 在旅行中他见到了一群由幻姬大人领导的贫穷人们。他们在麒鳞兽的森林开采铁矿,并在森林中建立炼铁厂。然而森林中的种种生物都视他们为敌,总是袭击人类。 有着三百岁智慧的白狼神莫娜和被她养大的人类女孩“幽灵公主”桑更是时刻想杀死幻姬,毁灭人类的城市。阿斯达卡既被桑所深深的吸引,理解“幽灵公主”保护 森林的心情,但同时又想帮助人类。在战斗的过程中阿斯达卡被麒鳞兽所救,立场更加摇摆不定。以疙瘩和尚为首的一批人受领主的命令来杀麒鳞兽,更利用幻姬的 力量与反攻人类的大批山猪作战。幻姬以火枪杀死麒鳞兽,失去头颅的麒鳞兽为了夺回自己的头对森林造成了极大的破坏。阿斯达卡和桑合力将麒鳞兽的头颅从疙瘩 和尚手里多回,并还给了愤怒的麒鳞兽,麒鳞兽的灵魂方才安息,被破坏的大自然又恢复了正常。

2《天空之城》
这是一个讲述寻找神秘国度Laputa的故事。Laputa在影片中即是一个超然云上、浮于空中的城市,因此也称之为"天空之城"。 一块小小的飞行石是小女孩shita的传家之宝,这块她一直戴在项间的石头似乎没有什么特殊之处,但它却是很多人争夺的对象。一天,当她为了逃离军方的魔 掌,意外摔下了飞艇,而飞行石就在这时放出了耀眼的蓝光,并且保护她缓慢、安全地降落。这时她才明白了石头的魔力。飞行石的魔力远大于她的想象。无论是野 蛮单纯的太空强盗mada,还是贪婪愚蠢的将军,更或者是野心勃勃的mossca,飞行石都是他们达到目的的关键。但是,唯一能够操控这块魔石的人却是小 女孩shita。
Shita无意中念动的咒语使飞行石放出光芒,射向天际。这道光指引大家来到了云中国度--Laputa,也就是传说中的"天空之城"。城中空无一人,宁 静安详,只有一些庞大而善良的机器人尽忠职守的守护着shita的祖先墓地。但是,这种安详被外来者破坏了。将军疯狂的抢劫财宝,而mossca则开始了 他控制天空之城、称霸世界的每一个步骤。原本美丽的天空之城变成了人们实现其野心和欲望的地方。最终,Shita和她的伙伴pasu选择了毁灭这个地方, 选择了与mossca同归于尽。当shita念动毁灭咒语时,心中一定是充满伤痛的,看着自己祖先的城市即将毁灭,负罪感油然而生。但是,她也一定感到庆 幸,因为她可以让野心家mossca的阴谋化为泡影,她可以拥抱着这片土地,和自己的好伙伴pasu一起离开人世。当然,他们没有死,而是回到了一直帮助 他们的mada身边。只留下天空之城中最后一块残留的墓地缓缓的飞向太空。

3《岁月的童话》
以一个小学生为主角讲述六十年代的小学趣事,但是高畑勲导演此片的时候加入了原创要素,将背景拖后了十余年,和题目一样,由快三十岁的女主人公一点一点地回忆以前小学时代的事情,还加入了主人公在最后终于找到意中人的小插曲。

4《千与千寻的神隐》
10岁的少女千寻与父母一起从都市搬家到了乡下。没想到在搬家的途中,一家人发生了意外。他们进入了汤屋老板魔女控制的奇特世界——在那里不劳动的人将会 被变成动物。千寻的父母出生在日本经济高速增长时代,对金钱物质有强烈的向往和控制欲,他们在幻境里触犯规则而变成了猪,千寻孤独的留在幻境里。支配城镇 的魔女强行改掉了千寻的名字,这更让她感觉到自我丧失的恐怖。

5《魔女宅急便》
 相传,魔女家庭的少女要成为一个合格的魔女,必须经过社会实践的考验。琪琪利用自己会飞行的本领,在面包店打工和送快递。完全没有工作经验的她,对一切都 充满好奇和不解。她的出现,为平静的小城带来一场不小的风波。经过许多的小波折后,琪琪终于成为了一个合格的魔女,在新的城市里,她将用自己的力量去开创 自己的生活道路。

6《红猪》
与宫崎骏其他的作品有所不同,“红猪”的主角并不是少男少女,而是一头已届中年的猪。主人公虽然生得一付猪的脸孔,却异常地受到女性的欢迎呢。剧中的两位 女主角年龄跨度不小,但都是一如既往地真心喜欢着波鲁克。《红猪》是宫崎骏一部带有自传性质的电影,宫崎骏自喻为剧中主人公波鲁克,将自己的那种处在俗世 而身不由己的矛盾构思成波鲁克的传奇故事。

7《侧耳倾听》
女孩月岛霞在受到挫折、失去方向的时候,来到地球屋求助。圣司追求自己成为小提琴制作者梦想的执着使她十分感动。在圣司去意大利的两个月中,她为了寻找自 己的方向,试炼自己的能力,决定开始写一部小说。爷爷称赞他们都是未经琢磨的原石,在经过巧手匠人的刀后,就能焕发出宝石一般的光彩。在彷徨犹豫之后,月 岛霞终于找到了自己前进的方向。在痛苦的努力以后,得来的是圣司的真情告白。两人以后的路还很长远,但是经过他们的努力,相信一定能得到幸福!

8《风之谷》
 这是一部极具环保省思的动画。故事中看似死亡森林的腐海及居住在腐海中的巨大昆虫以及群虫之王“王虫”皆是为了使污染的大地复元而生。而主角娜乌西卡从小 生长的地方“风之谷”则象征着人与自然共生共荣的处女大地。人类文明因为战争“火之七日”而崩毁的千年之后,荒芜的大地被放出有毒瘴气的菌类森林“腐海” 所覆盖,那里居住着巨大昆虫,是一座死寂的森林。某夜,运输着自培吉特市挖出的巨神兵的多尔梅吉亚大型运输船坠落在风之谷,翌日,风之谷遭到欲取回巨神兵 的多尔梅吉亚军占领,族长基尔被杀。 司令官库夏娜,带着人质娜乌西卡,在前往培吉特市的路上,遭到阿斯贝尔驾史的炮艇袭击。 趁机逃出的娜乌西卡,为了救阿斯贝尔而深入腐海,郄意外地发现了腐海底下竟充满着干净的水、土和空气。于是两人明白了“腐海”的秘密,是为了使污染的大地 复元而存在,而虫群则是为了保护腐海而生的。另一方面,培吉特市民为了抢回巨神兵,将虫群引至风之谷。得知此消息的娜乌西卡被关入帆艇中,但后来得到阿斯 贝尔等人的帮助而逃脱,同时帆船郄遭到冬尔梅吉亚军的攻击……

9《龙猫》
和爸爸一起搬到乡下的两姐妹,在家旁的一棵大树下发现了只有好孩子才能看见的TOTORO,其间发生了很多不可思议而有趣的故事。一天,妹妹小米和姐姐吵 架之后,便独自出走,去找自己生病住院的妈妈,途中却迷路了。姐姐四处寻找无果的情况下,只好求助于TOTORO。善良而温和的TOTORO唤来龙猫电 车,载着姐姐找到了迷路的妹妹,乘着龙猫电车,妹妹把亲手摘的玉米送给妈妈,希望她早日康复。

10《再见萤火虫》
故事讲述大战末期,十四岁的哥哥和四岁的妹妹在空袭中失去了母亲,而当地政府为了强迫人民节省战争下剩余的物资,对他们实施严厉的管制,哥哥和妹妹两人都 不愿意在这种管制下生活,两兄妹遂以洞穴为家,没有大人帮助他们,要自行找寻食物维生,生活刻苦之余,他们也像其他小孩一样活泼好动,闲来在杂乱下的田间 玩乐,夜晚更一起在草地上观看漫天飞舞的萤火虫。可是快乐的日子不长,最后妹妹因身体衰弱而死.....

11《百变狸猫》
 在东京多摩丘陵森林,住着一群天真可爱的狸子,由于人类扩张新市镇,使它们的居住地濒临消失!对此生成空前危机感的狸子,于是召开紧急会议,决定振兴祖先 流传下来的变身术,让自己变**注意语言**类以及各种妖怪的样子,来阻止开发工程的进行;为捍卫家园,开朗客观的狸子,会发动一场击退人类的战争吗?

12《猫的报恩》
对17岁的高中二年级生春来说,这个早晨的开头如此倒霉:她因为迟到而被批评,更重要的是,她暗恋的男生町田君看到了这一幕。 放学回家的途中,郁闷的春意外的救下了一只差点被卡车轧过的猫儿。更叫她吃惊的是,这只猫居然幻化成人形,彬彬有礼使用人类的礼节向她致谢,又神秘的消失 在春面前。实际上,张口结舌的春还不知道,这只是一连串奇遇的小小开头。 这一夜,春的家门前聚起了许多不知来自何处的猫咪。在这个巨大的“猫”之方阵中,猫王乘坐着“猫车”出现了。猫王以高贵的姿态告诉春,白天她所救下的小猫 实际是猫国的王子,因此,猫国上下将视春为恩人,并将对她有所报答。 第二天,猫们的"报恩"行动开始了。好友广美收到了许多来自猫的礼物;春在学校的储物箱里堆满了死老鼠;正当春眼花缭乱之际,猫王的秘书出现在她家附近, 邀请她前往猫国一游。生性迷糊的春在猫国做客时,还稀里糊涂的答应了嫁给猫国王子为妃…… 处于困境的春忽然听见有人在喊她名字——“小春,请到猫之事务所来一趟吧”...

13《听到涛声》
 因为家庭问题而从东京般到高知女孩,武藤里枷子.和主角杜崎拓成为了同班同学.一次,由于武藤和杜崎拓的一次东京之旅,二人产生了感情.但是,由于二人的 任性,双方都没有能够表达出自己真正的心意.就这样,高中毕业后,大家各奔前程. 一次同学会,同学突然提起没来的武藤,说是在东京见到过她.至于为什么回东京,"东京有我想见的人!"武藤当时是这样对同学说的.问她想见的是什么人,她 只回答说:"一个睡浴缸的人".杜崎听后恍然大悟.当年,武藤和杜崎去东京时,杜崎便是睡的浴缸......

14 《On Your Mark》(MTV)
 仅仅是六分半钟长的一部MTV,仅仅是一个简单的故事,而且一再反复。
灯红酒绿的摩天大楼,蒙面的警察和歹徒火并,尸体遍地的房间。 就在这样的地方,却突然出现天使,虽然她被绳索缚着,而且昏倒在地。她看起来是那么单纯,那么柔弱,好象雷场上的一朵小花。但单纯也是一种力量,使打扫战 场的警察也揭开了面罩,使我们发现其实他们也不是单纯的执行机器,不是一堆高科技的组合,而是普通的人。但一个天使和两个普通人是不能与强大的意志作斗争 的,她被带到了 研究机构,科学要物化所有它不知道的东西。 他们救出了她,但没有逃脱追踪。她柔弱的翅膀不能承受三个人的重量,于是她宁愿一起落入万丈深渊,也不愿独自逃生。 镜头闪回,汽车在落入深渊的一刹那腾空而起。他们终于摆脱了敌人, 奔向外面的世界。隧道的尽头就是阳光,警示牌接连闪过:注意阳光!”、 不保障生命!”、Extreme Danger!”。不管它,汽车继续飞奔! 外面的世界,是一片绿色,间或有几间久已无人的低矮的木房。清新 的空气里,她终于露出了笑容,展开白鸟之翼,在蓝天白云下自由翱翔。 音乐也转入轻柔的合唱,伴着风声,好象人们飞翔的梦想。

15 《哈尔的移动城堡》
19世纪末的欧洲,荒地出现了一座移动的城堡,传说城堡中的邪恶巫师哈尔会吃掉姑娘的心。苏菲是个18岁的少女,一次,因为迷路,苏菲被英俊神秘的哈尔营 救。但对苏菲和哈尔关系的误解,导致妒嫉的女魔术师给苏菲下了一个诅咒,苏菲被变成了90岁的老太太。苏菲决定离家出走。她独自一人在空旷的大山上逆风而 行,遇到一个善良的稻草人,在他的指点下,苏菲走进了魔法师哈尔的移动城堡...

16 《我的邻居山田君》
 讲的是山田一家人的故事,这个日本传统的家庭有着平凡的生活:上班族的父亲,做家庭主妇的母亲,作为长辈的姥姥,孩子是兄妹两个。就是这样千千万万个普通 的家庭,过着普通的生活,构成了整个社会。但是如果你仔细地去发掘,也能从中发现无数的温馨、欢乐、忧伤和痛苦。从一个个小故事中体会到生活的真谛。

2007-03-16

WebBrowser Customization

This tutorial shows you several ways to customize the "out of the box" behavior and appearance of the WebBrowser Control. You'll see how to use the advanced hosting interfaces IDocHostUIHandler, IDocHostUIHandler2, IDocHostShowUI, and ICustomDoc. This article will also look at other customization techniques such as download control through handling DISPID_AMBIENT_DLCONTROL in the host's IDispatch implementation, and using IHostDialogHelper.

This article is divided into the following sections:

Prerequisites and Requirements

In order to understand and use this tutorial, you need:

  • A good understanding of C++ and the Component Object Model (COM).
  • Familiarity with the Active Template Library (ATL).
  • Microsoft Internet Explorer 6 or later installed.
  • Header files and libraries for Internet Explorer 6 or later for use in your development environment; in particular, you need Mshtmhst.h.

Many of the WebBrowser customization features have been available since Internet Explorer 5 and Internet Explorer 5.5. Only a couple require Internet Explorer 6. One more requires Internet Explorer 6 for Microsoft Windows XP Service Pack 2 (SP2). Check the reference documentation for versioning information.

Introduction

Hosting the WebBrowser Control is a powerful tool for rapid application development. Through hosting, you can leverage easy-to-use technologiesDynamic HTML (DHTML), HTML, and XMLfor displaying content and developing a user interface (UI). However, "out of the box," the WebBrowser Control may not behave quite the way you want. For instance, in its default state the user can view the source of a displayed page by right-clicking and choosing the View Source option on the shortcut menu. You might want to disable or eliminate that option. You might also want to go even further and replace the default shortcut menu entirely with your own custom menu.

Aside from the customizations just mentioned, the advanced hosting features of Internet Explorer enable you to:

  • Use buttons and other controls on a displayed page to call internal methods in your application, effectively extending the DHTML Object Model.
  • Change drag-and-drop behavior.
  • Control which pages your application can access, restricting navigation, for example, to specify pages, domains, or sites.
  • Intercept user keystrokes and process them however you want. For example, you might intercept CTRL+O to prevent the user from opening a new page in Internet Explorer rather than the host application.
  • Change default font and display settings.
  • Control the kinds of content that are downloaded and what the WebBrowser Control does with them once they are downloaded. For example, you can prevent videos from playing, script from running, or new windows from opening when users click on links, or prevent Microsoft ActiveX controls from downloading or executing.
  • Restrict View Source.
  • Capture searches.
  • Capture navigation errors.
  • Replace or modify shortcut menus and shortcut menu entriesdisabling, replacing, customizing, or adding to them.
  • Change registry settings for your application.
  • Intercept and change messages dialogs shown by the WebBrowser Control.
  • Control how new windows are created.

In the following sections, we'll look at many, though not all, of these possibilities and discuss how to implement them.

WebBrowser Customization Architecture

Introducing IDocHostUIHandler, IDocHostUIHander2, IDocHostShowUI, and ICustomDoc

Three interfaces are at the heart of WebBrowser ControlUI customization: IDocHostUIHandler, IDocHostUIHandler2, and IDocHostShowUI. These are interfaces that you implement in your application when you want to modify the WebBrowser Control. There are also a couple of service interfaces. ICustomDoc is implemented by MSHTML and provides a means to enable WebBrowser Control customization in some scenarios. IHostDialogHelper provides a means to open trusted dialog boxes, without identification that marks them as Internet Explorer dialog boxes.

In addition to using these interfaces, there are two other things you can do. For one, you can control download by intercepting ambient property changes in your IDispatch implementation. Second, you can control how new windows are created by intercepting DISPID_NEWWINDOW2 in your IDispatch implementation.

How It Works

The mechanism for WebBrowser Control customization is designed to be automated when a container provides support for ActiveX controls. Whenever the WebBrowser Control is instantiated, it attempts to find IDocHostUIHandler, IDocHostUIHandler2 and IDocHostShowUI implementations from the host, if they are available. The WebBrowser Control does this by a QueryInterface call on the host's IOleClientSite interface.

This architecture works automatically for an application that implements an IOleClientSite interface and that passes an IOleClientSite pointer to the WebBrowser Control through the browser's IOleObject::SetClientSite method. A typical instantiation of the WebBrowser Control might look like this:

SetClientSite(this;">// Error checking omitted for clarity
CComPtr spOleObj;

// Create WebBrowser--store pointer in class member variable m_spWebBrowser
CoCreateInstance(CLSID_WebBrowser, NULL, CLSCTX_INPROC, IID_IWebBrowser2, (void**)&m_spWebBrowser);

// Query WebBrowser for IOleObject pointer
m_spWebBrowser->QueryInterface(IID_IOleObject, (void**)&spOleObj);

// Set client site
spOleObj->SetClientSite(this);

// In-place activate the WebBrowser control
RECT rcClient
GetClientRect(&rcClient);
spOleObj->DoVerb(OLEIVERB_INPLACEACTIVATE, NULL, this, 0, GetTopLevelWindow(), &rcClient);

// Register container to intercept WebBrowser events
AtlAdvise(m_spWebBrowser, GetUnknown(), DIID_DWebBrowserEvents2, &m_dwCookie);

// Navigate to start page
m_spWebBrowser->Navigate(L"res://webhost.exe/startpage.htm", NULL, NULL, NULL, NULL);

However, if your application doesn't have an IOleClientSite interface, all is not lost. Internet Explorer provides the ICustomDoc interface so you can pass Internet Explorer your IDocHostUIHandler interface yourself. You cannot use IDocHostUIHandler2 and IDocHostShowUI without providing an IOleClientSite interface on the object hosting the WebBrowser Control.

When the WebBrowser Control holds a pointer to any of these interfaces, the methods of the interfaces are called at appropriate times during the lifetime of the WebBrowser Control. For instance, when the user right-clicks with the mouse anywhere in the WebBrowser Control's client area, your implementation of IDocHostUIHandler::ShowContextMenu will be called before Internet Explorer displays its default shortcut menu. This gives you a chance to display your own shortcut menu and prevent Internet Explorer from displaying its menu.

There are a few more important points to remember when initializing the WebBrowser Control. Your application should use OleInitialize rather than CoInitialize to start COM. OleInitialize enables support for the Clipboard, drag-and-drop operations, OLE, and in-place activation. Use OleUninitialize to close the COM library when your application shuts down.

The ATLCOM Wizard uses CoInitialize rather than OleInitialize to open the COM libraries. If you use this wizard to build an executable program, you need to change the CoInitialize and CoUninitialize calls to OleInitialize and OleUninitialize. For a Microsoft Foundation Classes (MFC) application, be sure that your application calls AfxOleInit, which calls OleInitialize, in its initialization process.

If you don't want drag-and-drop support in your application, you can call IWebBrowser2::RegisterAsDropTarget, passing in VARIANT_TRUE, to prevent any drag-and-drop operations on your WebBrowser Control instance.

An application hosting the WebBrowser Control will also need an implementation of IOleInPlaceSite, and since IOleInPlaceSite derives from IOleWindow, the application will also need an implementation of IOleWindow. You need these implementations so your application has a window in which to display the WebBrowser Control and so you can manage its display.

The implementations of these interfaces and IOleClientSite can be minimal or nonexistent in many cases. The IOleClientSite methods can all return E_NOTIMPL. Some of the IOleInPlaceSite and IOleWindow methods need an implementation beyond their return value. See the code sample for an example of a minimal implementation of IOleInPlaceSite and IOleWindow.

Now that we have covered the initialization preliminaries, let's take a look at each of the interfaces for WebBrowser Control customization.

IDocHostUIHandler

IDocHostUIHandler has been available since Internet Explorer 5. It provides fifteen methods. In general, some of the more important methods are IDocHostUIHandler::GetExternal, IDocHostUIHandler::GetHostInfo, IDocHostUIHandler::GetOptionKeyPath, IDocHostUIHandler::ShowContextMenu, and IDocHostUIHandler::TranslateAccelerator. Of course, the methods that are most important to you will depend on your application.

IDocHostUIHandler::GetHostInfo

You use IDocHostUIHandler::GetHostInfo to tell MSHTML about your application's capabilities and requirements. With it you can control a variety of things, for instance:

  • You can disable the browser's 3-D border.
  • You can prevent scroll bars or change their appearance.
  • You can define how you want to handle double-clicks.

IDocHostUIHandler::GetHostInfo has one parameter, a pointer to a DOCHOSTUIINFO structure allocated by MSHTML. Your job is to fill this structure with the information you want to pass to MSHTML.

There are four members in the DOCHOSTUIINFO structure. The first member is cbSize, which is the size of the structure. You should set this yourself as the following code sample shows. The second member is dwFlags, which can take any number of flag values, combined with the bitwise OR operator, from the DOCHOSTUIFLAG enumeration. The third member is dwDoubleClick, which takes a value from the DOCHOSTUIDBLCLK enumeration. The fourth member is pchHostCss. You can set pchHostCss to a pointer to a string with Cascading Style Sheets (CSS) rules that you want to apply globally to any page displayed in the WebBrowser control. The final member of DOCHOSTUIINFO is pchHostNs. This is also a string pointer with which you can provide a semicolon-delimited list of namespaces. Use this member when you use custom tags on the pages you're displaying in the WebBrowser Control. This way you can have a global declaration for namespaces and don't have to declare them on each displayed page.

Be sure to use CoTaskMemAlloc to allocate strings for pchHostCss or pchHostNS.

HRESULT GetHostInfo(DOCHOSTUIINFO *pInfo)
{
WCHAR* szCSS = L"BODY {background-color:#ffcccc}";
WCHAR* szNS = L"IE;MyTags;MyTags2='www.microsoft.com'";

#define CCHMAX 256
size_t cchLengthCSS, cchLengthszNS;

HRESULT hr = StringCchLengthW(szCSS, CCHMAX, &cchLengthCSS);
// TODO: Add error handling code here.
OLECHAR* pCSSBuffer = (OLECHAR*)CoTaskMemAlloc((cchLengthCSS + 1) * sizeof(OLECHAR));
// TODO: Add error handling code to make sure memory block was allocated successfully.

hr = StringCchLengthW(szNS, CCHMAX, &cchLengthszNS);
// TODO: Add error handling code here.
OLECHAR* pNSBuffer = (OLECHAR*)CoTaskMemAlloc((cchLengthszNS + 1) * sizeof(OLECHAR));
// TODO: Add error handling code to make sure memory block was allocated successfully.

hr = StringCchCopyW(pCSSBuffer, cchLengthCSS + 1, szCSS);
// TODO: Add error handling code here.
hr = StringCchCopyW(pNSBuffer, cchLengthszNS + 1, szNS);
// TODO: Add error handling code here.

pInfo->cbSize = sizeof(DOCHOSTUIINFO);
pInfo->dwFlags = DOCHOSTUIFLAG_NO3DBORDER | DOCHOSTUIFLAG_SCROLL_NO;
pInfo->dwDoubleClick = DOCHOSTUIDBLCLK_DEFAULT;
pInfo->pchHostCss = pCSSBuffer;
pInfo->pchHostNS = pNSBuffer;

return S_OK;
}

If you have nothing special to say to MSHTML, you can return E_NOTIMPL from this method.

IDocHostUIHandler::ShowContextMenu

By implementing this method, you gain control over the shortcut menus displayed by the WebBrowser Control when a user right-clicks. You can prevent Internet Explorer from displaying its default menu by returning S_OK from this method. Returning some other value, like S_FALSE or E_NOTIMPL, allows Internet Explorer to go ahead with its default shortcut menu behavior.

If you return S_OK from this method and nothing more, you can prevent any right-click behavior by the WebBrowser Control. This may be all you desire in many scenarios but you can do more. Often, you use this method to create and display your own shortcut menu before returning S_OK. If you know the resources from which the WebBrowser Control displays its menus, and how it chooses them, you can also effectively customize the default WebBrowser Control shortcut menus themselves.

Refer to WebBrowser Customization (Part 2) for an implementation example of this method.

IDocHostUIHandler::GetExternal: Extending the DOM

IDocHostUIHandler provides you with a means to extend the Internet ExplorerDocument Object Model (DOM) with objects, methods, and properties of your own, implemented in your own application. You do this by providing MSHTML a pointer to the IDispatch interface for the COM automation object that implements your custom object, properties, and methods. These objects, properties, and methods will then be available to any page displayed in the WebBrowser Control through the document's external object.

You can easily implement this method, assuming your IDispatch interface is on the same object that implements IDocHostUIHandler.

HRESULT CBrowserHost::GetExternal(IDispatch **ppDispatch)
{
*ppDispatch = this;
return S_OK;
}

Once MSHTML has a pointer to your IDispatch, MSHTML will pass any calls on Web pages to automation methods on your application through the external object:


You can also use this technique to pass whole objects to a page. To do this, create a method in your IDispatch implementation that passes back the object you want to make available.


See the sample application for an example of IDispatch automation implementation using ATL.

IDocHostUIHandler::GetOptionKeyPath

IDocHostUIHandler::GetOptionKeyPath is a very powerful tool for customizing the WebBrowser Control. Many of the WebBrowser Control display and behavior settings are stored in the registry under the HKEY_CURRENT_USER key. IDocHostUIHandler::GetOptionKeyPath gives you an opportunity to override these registry settings for your specific instance of the WebBrowser Control. It does this by letting you supply an alternate registry location from which the WebBrowser Control will read in registry settings.

An implementation of IDocHostUIHandler::GetOptionKeyPath passes a string to the WebBrowser Control for the registry location you want it to read from. The WebBrowser Control will look for this key under the HKEY_CURRENT_USER key.

HRESULT CBrowserHost::GetOptionKeyPath(LPOLESTR *pchKey,
DWORD dwReserved)
{
HRESULT hr;

#define CCHMAX 256
size_t cchLength;

if (pchKey)
{
WCHAR* szMyKey = L"Software\\MyCompany\\MyApp";
hr = StringCchLengthW(szMyKey, CCHMAX, &cchLength);
// TODO: Add error handling code here.

*pchKey = (LPOLESTR)CoTaskMemAlloc((cchLength + 1) * sizeof(WCHAR));
if (*pchKey)
hr = StringCchCopyW(*pchKey, cchLength + 1, szKey);
// TODO: Add error handling code here.

hr = (*pchKey) ? S_OK : E_OUTOFMEMORY;
}
else
hr = E_INVALIDARG;

return hr;
}

As with IDocHostUIHandler::GetHostInfo, be sure to allocate memory for your strings using CoTaskMemAlloc.

Telling the WebBrowser Control where to look for your registry settings is the first stepactually, it's the second step as far as program execution is concerned. Your program must set the keys at the location specified by IDocHostUIHandler::GetOptionKeyPath so the WebBrowser Control can read them. There are a variety of ways to do this. One way would be with a registry script that runs when the application is installed. Another way might be to do it programmatically when the application starts. Here's a function that sets keys to change the default font, size, and color.

HRESULT SetSomeKeys()
{
HKEY hKey = NULL;
HKEY hKey2 = NULL;
HKEY hKey3 = NULL;
DWORD dwDisposition = NULL;
LONG lResult = NULL;
#define CBMAX 256
size_t cbLength;

RegCreateKeyEx(HKEY_CURRENT_USER, _T("Software\\MyCompany\\MyApp"),
NULL, NULL, REG_OPTION_NON_VOLATILE, KEY_SET_VALUE,
NULL, &hKey, &dwDisposition);

RegCreateKeyEx(hKey, _T("Main"), NULL, NULL, REG_OPTION_NON_VOLATILE,
KEY_SET_VALUE, NULL, &hKey2, &dwDisposition);

RegSetValueEx(hKey2, _T("Use_DlgBox_Colors"), NULL, REG_SZ,
(CONST BYTE*)_T("no"), sizeof(_T("no")));

RegCloseKey(hKey2);

RegCreateKeyEx(hKey, _T("Settings"), NULL, NULL, REG_OPTION_NON_VOLATILE,
KEY_SET_VALUE, NULL, &hKey2, &dwDisposition);

RegSetValueEx(hKey2, _T("Anchor Color"), NULL, REG_SZ,
(CONST BYTE*)_T("0,255,255"), sizeof(_T("0,255,255")));

RegSetValueEx(hKey2, _T("Text Color"), NULL, REG_SZ,
(CONST BYTE*)_T("255,0,255"), sizeof(_T("255,0,255")));

RegCloseKey(hKey2);

RegCreateKeyEx(hKey, _T("International\\Scripts"), NULL, NULL,
REG_OPTION_NON_VOLATILE, KEY_SET_VALUE, NULL,
&hKey2, &dwDisposition);

BYTE bDefaultScript = 0x3;

RegSetValueEx(hKey2, _T("Default_Script"), NULL, REG_BINARY,
&bDefaultScript, sizeof(bDefaultScript));

RegCreateKeyEx(hKey2, _T("3"), NULL, NULL, REG_OPTION_NON_VOLATILE,
KEY_SET_VALUE, NULL, &hKey3, &dwDisposition);

BYTE bSize = 0x4; // Value from 0 - 4. 2 is medium.
TCHAR* szFontName = _T("Comic Sans MS");
TCHAR* szFixedFontName = _T("Courier");

HRESULT hr = StringCbLength(szFontName, CBMAX, &cbLength);
// TODO: Add error handling code here.
RegSetValueEx(hKey3, _T("IEPropFontName"), NULL, REG_SZ,
(CONST BYTE*)szFontName, cbLength + sizeof(TCHAR));

hr = StringCbLength(szFixedFontName, CBMAX, &cbLength);
// TODO: Add error handling code here.
RegSetValueEx(hKey3, _T("IEFixedFontName"), NULL, REG_SZ,
(CONST BYTE*)szFixedFontName, cbLength + sizeof(TCHAR));

RegSetValueEx(hKey3, _T("IEFontSize"), NULL, REG_BINARY, &bSize, sizeof(bSize));

RegCloseKey(hKey3);
RegCloseKey(hKey2);
RegCloseKey(hKey);

return S_OK;
}

IDocHostUIHandler2

IDocHostUIHandler2 has a single method, IDocHostUIHandler2::GetOverrideKeyPath. It performs a function very similar to IDocHostUIHandler::GetOptionKeyPath. It points your hosted WebBrowser to registry settings to modify the default Internet Explorer registry settings. An implementation of IDocHostUIHandler2::GetOverrideKeyPath will look much the same as an implementation of IDocHostUIHandler::GetOptionKeyPath.

GetOptionKeyPath and GetOverrideKeyPath Compared

The difference between IDocHostUIHandler::GetOptionKeyPath and IDocHostUIHandler2::GetOverrideKeyPath is subtle, but significant. If you implement IDocHostUIHandler::GetOptionKeyPath, your WebBrowser Control instance will ignore any user settings for Internet Explorer. These settings are stored in the registry under HKEY_CURRENT_USER/Software/Microsoft/Internet Explorer. If you implement IDocHostUIHandler2::GetOverrideKeyPath, your WebBrowser Control instance will incorporate any user settingsfont settings, menu extensions, and so forthinto the way it displays and behaves.

To illustrate the difference between IDocHostUIHandler::GetOptionKeyPath and IDocHostUIHandler2::GetOverrideKeyPath, refer to the code example for adding extensions to the context menu in WebBrowser Customization (Part 2). Recall the line:

spCT->Exec(&CGID_ShellDocView, SHDVID_ADDMENUEXTENSIONS, 0, &var1, &var2);

If you've implemented IDocHostUIHandler::GetOptionKeyPath, this line would add none of the menu extension information that is stored in the registry for the current user. Instead, it would only add menu items that you have created. If you've implemented IDocHostUIHandler2::GetOverrideKeyPath, this line would add any extensions defined for the current user under HKEY_CURRENT_USER\Software\Microsoft\Internet Explorer\MenuExt unless you explicitly supply an empty or alternative MenuExt key in your custom registry key.

Controlling Navigation

You may have wondered why the section on IDocHostUIHandler didn't mention IDocHostUIHandler::TranslateUrl as a method to implement when you wish to control page navigation. The reason is that this method is not the most general purpose technique with which to control navigation. Unless you are hosting MSHTML directly, this method will have no effect on navigation. Instead, you can control navigation by implementing your IDispatch::Invoke method to handle DISPID_BEFORENAVIGATE2. As an example, the following code prevents navigation to a particular URL, displaying a "No Navigation Allowed" error page if the user attempts to do so.

case DISPID_BEFORENAVIGATE2:
{
CComBSTR url = ((*pDispParams).rgvarg)[5].pvarVal->bstrVal;
if (url == "http://www.adatum.com" || url == "http://www.adatum.com/")
{
CComPtr spBrowser;
CComPtr spDisp = ((*pDispParams).rgvarg)[6].pdispVal;
spDisp->QueryInterface(IID_IWebBrowser2, (void**)&spBrowser);
spBrowser->Stop();
CComBSTR newURL = "L"res://webhost.exe/nonavigate.htm";
spBrowser->Navigate(newURL, NULL, NULL, NULL, NULL);
((*pDispParams).rgvarg)[0].boolVal = TRUE;
}
break;
}

IDocHostShowUI

This interface gives you control over the message boxes and help files displayed by the WebBrowser Control. It works the same way as IDocHostUIHandler and IDocHostUIHandler2 in that you implement it so the WebBrowser Control can call your IDocHostShowUI methods before it displays any messages or help menus of its own. This gives you a chance to prevent the WebBrowser Control from displaying anything and enables you to display your own custom message or help instead. IDocHostShowUI has two methods, IDocHostShowUI::ShowMessage and IDocHostShowUI::ShowHelp.

IDocHostShowUI::ShowMessage

Return S_OK to disable WebBrowser Control messages. Any other return value, like S_FALSE or E_NOTIMPL, allows the WebBrowser Control to display with its message box.

One nice thing you can do with this method is customize the message box captions for your application so they don't read "Microsoft Internet Explorer." You can do this by comparing the caption string in lpstrCaption with the string resource Internet Explorer uses, which is stored in Shdoclc.dll. It is identified by the symbol IDS_MESSAGE_BOX_TITLE, whose value is 2213. The following code snippet shows how you might do this.

HRESULT CBrowserHost::ShowMessage(HWND hwnd,
LPOLESTR lpstrText,
LPOLESTR lpstrCaption,
DWORD dwType,
LPOLESTR lpstrHelpFile,
DWORD dwHelpContext,
LRESULT *plResult)
{
USES_CONVERSION;
TCHAR pBuffer[50];

// resource identifier for window caption "Microsoft Internet Explorer"
#define IDS_MESSAGE_BOX_TITLE 2213

// Load Shdoclc.dll and the IE message box title string
HINSTANCE hinstSHDOCLC = LoadLibrary(TEXT("SHDOCLC.DLL"));

if (hinstSHDOCLC == NULL)
{
// Error loading module -- fail as securely as possible
return;
}
LoadString(hinstSHDOCLC, IDS_MESSAGE_BOX_TITLE, pBuffer, 50);

// Compare the IE message box title string with lpstrCaption
// If they're the same, substitute your own Caption
if (_tcscmp(OLE2T(lpstrCaption), pBuffer) == 0)
lpstrCaption = L"Custom Caption";

// Create your own message box and display it
*plResult = MessageBox(OLE2T(lpstrText), OLE2T(lpstrCaption), dwType);

// Unload Shdoclc.dll and return
FreeLibrary(hinstSHDOCLC);
return S_OK;
}
security note Security Alert Using LoadLibrary incorrectly can compromise the security of your application by loading the wrong DLL. Refer to the LoadLibrary documentation for information on how to correctly load DLLs with different versions of Windows.

IDocHostShowUI::ShowHelp

This method is called whenever Internet Explorer Help would be shown, for instance when the F1 key is pressed, and works analogously to IDocHostShowUI::ShowMessage. Return S_OK to override Internet Explorer Help, or another HRESULT value to let Internet Explorer proceed with its Help.

Controlling Download and Execution

The WebBrowser Control gives you control over what it downloads, displays, and executes. To gain this control, you need to implement your host's IDispatch so it handles DISPID_AMBIENT_DLCONTROL. When the WebBrowser Control is instantiated, it will call your IDispatch::Invoke with this ID. Set pvarResult to a combination of following flags, using the bitwise OR operator, to indicate your preferences.

  • DLCTL_DLIMAGES, DLCTL_VIDEOS, and DLCTL_BGSOUNDS: Images, videos, and background sounds will be downloaded from the server and displayed or played if these flags are set. They will not be downloaded and displayed if the flags are not set.
  • DLCTL_NO_SCRIPTS and DLCTL_NO_JAVA: Scripts and Java applets will not be executed.
  • DLCTL_NO_DLACTIVEXCTLS and DLCTL_NO_RUNACTIVEXCTLS : ActiveX controls will not be downloaded or will not be executed.
  • DLCTL_DOWNLOADONLY: The page will only be downloaded, not displayed.
  • DLCTL_NO_FRAMEDOWNLOAD: The WebBrowser Control will download and parse a frameSet, but not the individual frame objects within the frameSet.
  • DLCTL_RESYNCHRONIZE and DLCTL_PRAGMA_NO_CACHE: These flags cause cache refreshes. With DLCTL_RESYNCHRONIZE, the server will be asked for update status. Cached files will be used if the server indicates that the cached information is up-to-date. With DLCTL_PRAGMA_NO_CACHE, files will be re-downloaded from the server regardless of the update status of the files.
  • DLCTL_NO_BEHAVIORS: Behaviors are not downloaded and are disabled in the document.
  • DLCTL_NO_METACHARSET_HTML: Character sets specified in meta elements are suppressed.
  • DLCTL_URL_ENCODING_DISABLE_UTF8 and DLCTL_URL_ENCODING_ENABLE_UTF8: These flags function similarly to the DOCHOSTUIFLAG_URL_ENCODING_DISABLE_UTF8 and DOCHOSTUIFLAG_URL_ENCODING_ENABLE_UTF8 flags used with IDocHostUIHandler::GetHostInfo. The difference is that the DOCHOSTUIFLAG flags are checked only when the WebBrowser Control is first instantiated. The download flags here for the ambient property change are checked whenever the WebBrowser Control needs to perform a download.
  • DLCTL_NO_CLIENTPULL: No client pull operations will be performed.
  • DLCTL_SILENT: No user interface will be displayed during downloads.
  • DLCTL_FORCEOFFLINE: The WebBrowser Control always operates in offline mode.
  • DLCTL_OFFLINEIFNOTCONNECTED and DLCTL_OFFLINE: These flags are the same. The WebBrowser Control will operate in offline mode if not connected to the Internet.

DISPID_AMBIENT_DLCONTROL and the flag values are defined in mshtmdid.h.

Initially, when the function call to IDispatch::Invoke starts, the VARIANT to which the parameter pvarResult points is of type VT_EMPTY. You must switch the type to VT_I4 for any settings to have an effect. You can place your flag values in the lVal member of the VARIANT.

Most of the flag values have negative effects, that is, they prevent behavior that normally happens. For instance, scripts are normally executed by the WebBrowser Control if you don't customize its behavior. But if you set the DLCTL_NOSCRIPTS flag, no scripts will execute in that instance of the control. However, three flagsDLCTL_DLIMAGES, DLCTL_VIDEOS, and DLCTL_BGSOUNDSwork exactly opposite. If you set flags at all, you must set these three for the WebBrowser Control to behave in its default manner vis-a-vis images, videos and sounds.

The following code sample causes a WebBrowser Control instance to download and display images and videos, but not background sounds, since the DLCTL_BGSOUNDS is not explicitly set. Also, script execution on pages displayed by the WebBrowser Control is disabled.

STDMETHODIMP CAtlBrCon::Invoke(DISPID dispidMember, REFIID riid,
LCID lcid, WORD wFlags,
DISPPARAMS* pDispParams,
VARIANT* pvarResult,
EXCEPINFO* pExcepInfo,
UINT* puArgErr)
{
switch (dispidMember)
{
case DISPID_AMBIENT_DLCONTROL:
pvarResult->vt = VT_I4;
pvarResult->lVal = DLCTL_DLIMAGES | DLCTL_VIDEOS | DLCTL_NO_SCRIPTS;
break;

default:
return DISP_E_MEMBERNOTFOUND;
}

return S_OK;
}

IHostDialogHelper

IHostDialogHelper is an interface you can use to create dialog boxes according to your liking. This interface has one method, IHostDialogHelper::ShowHTMLDialog. This method provides the same service as the function ShowHTMLDialog, but it's a little easier to use.

To use IHostDialogHelper, you create the dialog helper object from scratch. Here's how you would do it using CoCreateInstance. The interface and IDs are defined in mshtmhst.h.

IHostDialogHelper* pHDH;
IMoniker* pUrlMoniker;
BSTR bstrOptions = SysAllocString(L"dialogHeight:30;dialogWidth:40");
BSTR bstrPath = SysAllocString(L"c:\\dialog.htm");

CreateURLMoniker(NULL, bstrPath, &pUrlMoniker);

// Create the dialog helper object
CoCreateInstance(CLSID_HostDialogHelper,
NULL,
CLSCTX_INPROC,
IID_IHostDialogHelper,
(void**)&pHDH);

// Call ShowHTMLDialog to create your dialog box
pHDH->ShowHTMLDialog(NULL,
pUrlMoniker,
NULL,
bstrOptions,
NULL,
NULL);

// Free resources
SysFreeString(bstrPath);
SysFreeString(bstrOptions);
pUrlMoniker->Release();
pHDH->Release();

Controlling New Windows

One important way to take control of the WebBrowser Control is to control navigation. You saw earlier how you can intercept DISPID_BEFORENAVIGATE2 in an IDispatch::Invoke implementation to control where your WebBrowser Control will navigate. Another important aspect of navigation is to control how the navigation occurs, especially when opening new windows. Let's say, for instance, that the user clicks the right mouse button over a link and chooses "Open in New Window" or that a page contains a script like this:

window.open("www.msn.com");

By default, the WebBrowser Control deals with this code by opening a new instance of Internet Explorer to display the page. This may be fine for your application. But then again, it may not. Perhaps you'll want all links to open in your current WebBrowser Control instance. Or perhaps you'll want to open a link in a new WebBrowser Control instance under your control, with your user interface and with your branding.

You can intercept an event, DWebBrowserEvents2::NewWindow2, in your IDispatch implementation to control this. Your control needs to connect to the DWebBrowserEvents2 connection point to intercept this event.

Once you're connected to DWebBrowserEvents2, implement your IDispatch::Invoke so that it handles DISPID_NEWWINDOW2. During the IDispatch::Invoke function call for DISPID_NEWWINDOW2, the array pDispParams contains two parameters. The first one, at index zero, is a Boolean value that tells the WebBrowser Control whether to cancel the new window or not. By default, it is FALSE and a new window will open. If you want to cancel new window creation completely, set the flag to TRUE.

The parameter at index one is a pointer to an IDispatch interface. You can set this parameter to the IDispatch of a WebBrowser Control that you've created. When you pass back an IDispatch like this, MSHTML will use the control you've given it to open the link.

Information Bar

Internet Explorer 6 for Windows XP SP2 introduced a new security UI element called the Information Bar. The Information Bar displays a UI element to users of Internet Explorer when certain actions are prevented. Specifically, it displays when the following are blocked.

  • Pop-up window instantiation (see Pop-up Blocker)
  • File downloads (see File Download Restrictions)
  • ActiveX control installation (see ActiveX Restrictions)
  • ActiveX control security prompts because of the user's security settings or because the control is not marked safe for scripting
  • Files that have a mismatch between the file extension and the MIME type (see MIME Handling)
  • Content restricted by the network protocol lockdown (see Protocols)

The Information Bar is one of the feature controls introduced in Internet Explorer 6 for Windows XP SP2. Like the other feature controls, it is managed through a registry key (FEATURE_SECURITYBAND). Internet Explorer (iexplorer.exe) and Windows Explorer (explorer.exe) run under this feature control by default. The following shows the registry key and enabled processes.

HKEY_LOCAL_MACHINE (or HKEY_CURRENT_USER)
SOFTWARE
Microsoft
Internet Explorer
Main
FeatureControl
FEATURE_SECURITYBAND
iexplorer.exe= 0x00000001
explorer.exe= 0x00000001
process name.exe=0x00000001

The FEATURE_SECURITYBAND feature control only affects whether Internet Explorer displays the Information Bar, which alerts the user that an action has been mitigated. It does not control the mitigation of the action.

An application hosting the WebBrowser Control can enable the Information Bar by adding its process to this registry key. This can be done programmatically by using the CoInternetSetFeatureEnabled function. If an application does not run under this feature control, the WebBrowser Control behaves the same as Internet Explorer 6 SP1b.

There is no access to this feature through script.

Applications running under the FEATURE_SECURITYBAND and related feature controls can also leverage the Information BarAPIs to customize the UI displayed when a URL action is disallowed. There are several new OLECMDID commands for the Information Bar. The first three are part of the CGID_DocHostCommandHandler group. Hosting applications should implement IOleCommandTarget on their implementation of IDocHostUIHandler to receive IOleCommandTarget::Exec calls from the WebBrowser Control.

  • OLECMDID_PAGEACTIONBLOCKED
  • OLECMDID_PAGEACTIONUIQUERY
  • OLECMDID_FOCUSVIEWCONTROLS

Hosting applications can use the following two new OLECMDID commands to make IOleCommandTarget::Exec calls on the WebBrowser Control.

  • OLECMDID_FOCUSVIEWCONTROLSQUERY
  • OLECMDID_SHOWPAGEACTIONMENU
This example uses IWebBrowser2::ExecWB to execute the OLECMDID_SHOWPAGEACTIONMENU command.
   POINT pt = { 0 };
GetCursorPos(&pt);

CComVariant varHwnd((LONG)hwnd);
CComVariant varX(pt.x);
CComVariant varY(pt.y);

SAFEARRAY* psa = SafeArrayCreateVector(VT_VARIANT, 0, 3);

LONG lIndex = 0;
SafeArrayPutElement(psa, &lIndex, &varHwnd);
lIndex++;
SafeArrayPutElement(psa, &lIndex, &varX);
lIndex++;
SafeArrayPutElement(psa, &lIndex, &varY);

CComVariant varArgIn;
V_VT(&varArgIn) = VT_ARRAY | VT_I4;
V_ARRAY(&varArgIn) = psa;

pBrowser-<>*Fix pointer operator!!ExecWB(OLECMDID_SHOWPAGEACTIONMENU, (OLECMDEXECOPT)dwPageActionFlags, &varArgIn, NULL);

Also, an application can override the default security zone settings by implementing IInternetSecurityManager. See Implementing a Custom Security Manager for more information.

Conclusion

You now have a number of techniques at your disposal to customize the WebBrowser Control. This article is by no means exhaustive, but hopefully you also now have a sense of some of the possibilities you may discover on your own beyond the techniques in this article. Check out the Internet Explorer registry to see the kinds of information stored there that you can modify with IDocHostUIHandler::GetOptionKeyPath or IDocHostUIHandler2::GetOverrideKeyPath. Keep in mind that many registry settings are interdependent with others. You may have to do some experimentation to discover how particular registry settings can be customized effectively. You can also look into IDocHostUIHandler::GetDropTarget if you want to control what the WebBrowser Control does during drag-and-drop operations.

Part one of this tutorial introduced several of the standard hosting interfaces for the WebBrowser Control: IDocHostUIHandler, IDocHostShowUI, and ICustomDoc to name a few. Part two of this article explains how to retrieve a reference to the client site while processing IPersistMoniker::Load, and how to use the IServiceProvider and IOleCommandTarget interfaces to send messages between the Active document (DocObject) and its host.

IPersistMoniker and IBindCtx

When the WebBrowser Control determines that a hyperlinked resource is associated with a helper application, it creates an instance of the target application and prompts the Active document (DocObject) to load the resource by using the IPersistMoniker interface. Before the browser navigates to a document, it registers a reference to its IOleClientSite interface in the binding context using IBindCtx::RegisterObjectParam. This reference allows the DocObject to retrieve and use the client site during IPersistMoniker::Load.

The following example demonstrates how to retrieve and set the client site from the binding context:

HRESULT CDoc::Load(BOOL fFullyAvailable, IMoniker *pimkName, LPBC pibc, DWORD grfMode)
{
HRESULT hr = S_OK;
CComPtr spUnk;
CComPtr spBindCtx;

// SHDOCVW stashes the client site in the bind context.
if (pibc)
{
pibc->GetObjectParam(SZ_HTML_CLIENTSITE_OBJECTPARAM, &spUnk);
if (spUnk)
{
CComQIPtr spSite(spUnk);

if (spSite)
{
hr = SetClientSite(spSite);
}
}
}
}

IServiceProvider

The IServiceProvider interface is a generic access mechanism to locate a GUID-identified service that is provided through a control or any other object. Using IServiceProvider::QueryService, its one and only method, the caller specifies a service identifier (SID), the IID of the desired interface, and the address of the interface pointer variable that is set upon a successful return.

In many ways, IServiceProvider::QueryService functions a lot like QueryInterface. However, the more adaptable IServiceProvider mechanism allows an implementer to delegate the query to one of its member objects, or to hand off the request to a callback hierarchy that is searched for an object that can support the requested IID. The implementer need not recognize the interfaces being requested. In common usage, IServiceProvider::QueryService is used to improve the discoverability of some interfaces.

QueryService Example

For example, a call to QueryService with SID_SShellBrowser gets the nearest shell browser, such as the Microsoft Internet Explorer Web Object Control (WebOC). So, if the DocObject is hosted in the search pane, it will not mistakenly execute commands on the main browser window. SID_SShellBrowser is a WebOC-specific service; any DocObject that implements the IBrowserService interface should respond to queries for this service.

The following example demonstrates this basic scenario.

    CComPtr pSvc;
CComPtr pShb;
HRESULT hr;

hr = m_pUnk->QueryInterface(IID_IServiceProvider, &pSvc);
if (S_OK == hr && pSvc)
{
hr = pSvc->QueryService(SID_SShellBrowser, IID_IShellBrowser, &pShb);
if (hr == E_NOINTERFACE)
return;

// . . . use the interface here

pShb->Release();
}

CLSID_CMarkup

The special CLSID_CMarkup GUID is used to determine if an object is a native MSHTML markup object. No code except Internet Explorer should use this CLSID. Your QueryService or QueryInterface implementation should return E_NOINTERFACE if invoked with this GUID.

PRIVATE_GUID(CLSID_CMarkup, 0x3050F4FB, 0x98B5, 0x11CF, 0xBB, 0x82, 0x00, 0xAA, 0x00, 0xBD, 0xCE, 0x0B);
Note The MSHTML implementation uses a non-standard QueryInterface for CLSID_CMarkup to obtain an object pointer without adding a reference. In other words, the out parameter ppv does not receive an interface pointer; it contains the address of the object behind pUnknown.

IOleCommandTarget

The IOleCommandTarget interface enables objects and their containers to dispatch commands to each other. Available commands are defined by integer identifiers from a command group, which is itself identified by command group ID (also a GUID). The interface allows a caller both to query for one or more supported commands within a group and to issue a command to the object.

The WebBrowser Control uses the IOleCommandTarget interface extensively. The following sections highlight just a few of the ways that the client site can communicate with its control.

Showing a Certificate Dialog

With Internet Explorer 6 for Microsoft Windows XP Service Pack 2 (SP2) and later, you can show the Certificate dialog when the user is viewing a valid Secure Hypertext Transfer Protocol (HTTPS) site. This is the same as the user clicking the lock icon in Internet Explorer. You can use the DWebBrowserEvents2::SetSecureLockIcon event to show your own icon.

#define SHDVID_SSLSTATUS 33

IOleCommandTarget *pct;
if (SUCCEEDED(pWebBrowser2->QueryInterface(IID_IOleCommandTarget, (void **) &pct)))
{
pct->Exec(&CGID_ShellDocView, SHDVID_SSLSTATUS, 0, NULL, NULL);
pct->Release();
}

Controlling Navigation (Revisited)

If the MSHTML control is aggregated, the controlling DocObject is in a position to regulate navigation events. The fact that a document can navigate on its own implies that it will also take care of updating the navigation history.

In Internet Explorer 6 and later, the DocObject can indicate to the client site that it can navigate using CGID_DocHostCmdPriv (a privately defined command group GUID) and the DOCHOST_DOCCANNAVIGATE command. A pointer to the object that implements the IHTMLWindow2 interface is passed with the command in the VARIANTARG* parameter pvaIn. (Set pvaIn to NULL if the document cannot perform its own navigation.)

DEFINE_SHLGUID( CGID_DocHostCmdPriv, 0x000214d4, 0, 0);
#define DOCHOST_DOCCANNAVIGATE 0

// Create variant, initialize with pointer to our IUnknown
VARIANTARG var;

V_VT(&var) = VT_UNKNOWN;
V_UNKNOWN(&var) = (IUnknown*)this;

// Execute IOleCommandTarget with command group and ID
m_pCmdTarg->Exec(&CGID_DocHostCmdPriv, DOCHOST_DOCCANNAVIGATE, 0L, &amp;var, NULL);

Specifying the Zone Icon

In conjunction with CGID_Explorer, the SBCMDID_MIXEDZONE command is used to determine the zone icon and text displayed in the Internet Explorer status bar.

Active document objects hosted in Internet Explorer 6 for Windows XP SP2 or later can respond to the SBCMDID_MIXEDZONE command to determine the zone icon and text displayed in the Internet Explorer status bar. The document object should implement IOleCommandTarget, and Internet Explorer calls IOleCommandTarget::Exec with the CGID_Explorer command group.

To specify the zone icon:

  1. Define SBCMDID_MIXEDZONE.

    #define SBCMDID_MIXEDZONE 39
  2. Initialize pvaOut with VariantInit.

  3. Determine the zone you wish to specify and then set pvaOut as follows. To specify:

    • Internet, Intranet, Trusted or Untrusted zones; set pvaOut->vt to VT_UI4, and set pvaOut->ulVal to URLZONE_INTERNET, URLZONE_INTRANET, URLZONE_TRUSTED or URLZONE_UNTRUSTED respectively.
    • A mixed zone, set pvaOut->vt to VT_NULL.
    • An unknown zone, set pvaOut->vt to VT_EMPTY.

If an active document does not handle SBCMDID_MIXEDZONE, the default behavior is to show Unknown Zone in the status bar.

security note Security Alert If you cannot reliably determine your document's zone, you should not handle this command.

More Examples of Commands

The IDM_CONTEXT command (CGID_EditStateCommands command group) is used to determine if editing command should be routed to the host first. An IOleCommandTarget implementation will return S_OK to indicate that editing commands should be routed.

If the host is designed to handle editing commands, it will respond to the SID_SEditCommandTarget service identifier by providing an IOleCommandTarget interface to process editing commands as defined in the CGID_MSHTML command group.

DEFINE_GUID(CGID_MSHTML, 0xde4ba900, 0x59ca,0x11cf, 0x95, 0x92, 0x44, 0x45, 0x53, 0x54, 0x00, 0x00);

For more information on editing commands, see Introduction to MSHTML Editing and MSHTML Command Identifiers reference.

Context Menus and Extensions

The IDocHostUIHandler::ShowContextMenu method was introduced in WebBrowser Customization (Part 1). The following examples demonstrate how to use the IOleCommandTarget interface with SHDVID_GETMIMECSETMENU and SHDVID_ADDMENUEXTENSIONS (CGID_ShellDocView command group) to add and remove custom menu options from the standard Internet Explorer context menu.

The WebBrowser Control gets its context menu resources from Shdoclc.dll. That knowledge and a few #defines gives you a chance to manipulate the browser's menu. Let's say for instance that you're happy with the default menu, except for the View Source option, which you'd like to eliminate. The following code loads the WebBrowser Control shortcut menu resource from Shdoclc.dll, chooses the correct menu for the context, removes the menu item corresponding to the IDM_VIEWSOURCE command, and then displays the menu.

HRESULT CBrowserHost::ShowContextMenu(DWORD dwID,
POINT *ppt,
IUnknown *pcmdTarget,
IDispatch *pdispObject)
{
#define IDR_BROWSE_CONTEXT_MENU 24641
#define IDR_FORM_CONTEXT_MENU 24640
#define SHDVID_GETMIMECSETMENU 27
#define SHDVID_ADDMENUEXTENSIONS 53

HRESULT hr;
HINSTANCE hinstSHDOCLC;
HWND hwnd;
HMENU hMenu;
CComPtr spCT;
CComPtr spWnd;
MENUITEMINFO mii = {0};
CComVariant var, var1, var2;

hr = pcmdTarget->QueryInterface(IID_IOleCommandTarget, (void**)&spCT);
hr = pcmdTarget->QueryInterface(IID_IOleWindow, (void**)&spWnd);
hr = spWnd->GetWindow(&hwnd);

hinstSHDOCLC = LoadLibrary(TEXT("SHDOCLC.DLL"));

if (hinstSHDOCLC == NULL)
{
// Error loading module -- fail as securely as possible
return;
}

hMenu = LoadMenu(hinstSHDOCLC,
MAKEINTRESOURCE(IDR_BROWSE_CONTEXT_MENU));

hMenu = GetSubMenu(hMenu, dwID);

// Get the language submenu
hr = spCT->Exec(&CGID_ShellDocView, SHDVID_GETMIMECSETMENU, 0, NULL, &amp;var);

mii.cbSize = sizeof(mii);
mii.fMask = MIIM_SUBMENU;
mii.hSubMenu = (HMENU) var.byref;

// Add language submenu to Encoding context item
SetMenuItemInfo(hMenu, IDM_LANGUAGE, FALSE, &mii);

// Insert Shortcut Menu Extensions from registry
V_VT(&var1) = VT_INT_PTR;
V_BYREF(&var1) = hMenu;

V_VT(&var2) = VT_I4;
V_I4(&var2) = dwID;

hr = spCT->Exec(&CGID_ShellDocView, SHDVID_ADDMENUEXTENSIONS, 0, &amp;var1, &var2);

// Remove View Source
DeleteMenu(hMenu, IDM_VIEWSOURCE, MF_BYCOMMAND);

// Show shortcut menu
int iSelection = ::TrackPopupMenu(hMenu,
TPM_LEFTALIGN | TPM_RIGHTBUTTON | TPM_RETURNCMD,
ppt->x,
ppt->y,
0,
hwnd,
(RECT*)NULL);

// Send selected shortcut menu item command to shell
LRESULT lr = ::SendMessage(hwnd, WM_COMMAND, iSelection, NULL);

FreeLibrary(hinstSHDOCLC);
return S_OK;
}
security note Security Alert Using LoadLibrary incorrectly can compromise the security of your application by loading the wrong DLL. Refer to the LoadLibrary documentation for information on how to correctly load DLLs with different versions of Windows.

Appending Extensions to Your Custom Menu

In the previous example, the menu (hMenu) and menu context identifier (dwID) are passed as arguments to the IOleCommandTarget with the SHDVID_ADDMENUEXTENSIONS command. This operation inserts the registered menu extensions into the menu.

Should you choose to replace the standard menu with your own, you can still append menu extensions to your custom menu. Simply include a blank IDM_MENUEXT_PLACEHOLDER menu option in your menu definition to indicate where the custom commands are to be inserted. Menu extensions are inserted just before this placeholder. You can also add your own custom command to the standard menu by inserting the menu option before IDM_MENUEXT_PLACEHOLDER, as shown in the following example.

#define IDM_MENUEXT_PLACEHOLDER  6047

// If the placeholder is gone or was never there, then just exit
if (GetMenuState(hMenu, IDM_MENUEXT_PLACEHOLDER, MF_BYCOMMAND) != (UINT) -1)
{
InsertMenu(hMenu, // The Context Menu
IDM_MENUEXT_PLACEHOLDER, // The item to insert before
MF_BYCOMMAND|MF_STRING, // by item ID and str value
IDM_MENUEXT_FIRST__ + nExtCur, // the command ID
(LPTSTR)aOpts[nExtCur].pstrText);// The menu command text

// Remove placeholder
DeleteMenu(hMenu, IDM_MENUEXT_PLACEHOLDER, MF_BYCOMMAND);
}

The menu IDs for extensions fall between IDM_MENUEXT_FIRST__ and IDM_MENUEXT_LAST__ for a maximum of 33 custom commands.

References

The following table indicates where the identifiers described in this article are defined:

IdentifierHeader File
CGID_EditStateCommandsMshtml.h
CGID_ExplorerShlguid.h
CGID_MSHTMLMshtmhst.h
CGID_ShellDocViewShlguid.h
IDM_CONTEXTMshtmcid.h
SID_SEditCommandTargetMshtml.h
SID_SShellBrowserShlguid.h
SZ_HTML_CLIENTSITE_OBJECTPARAMMshtmhst.h

原文链接:http://msdn.microsoft.com/workshop/browser/hosting/wbcustomization.asp

2007-03-11

与领导喝酒的18个诀窍

  • 诀窍1 酒桌上虽然"感情深,一口闷;感情浅,舔一舔"但喝酒的时候决不能把这句话挂在嘴上。
  • 诀窍2 韬光养晦,厚积薄发,切不可一上酒桌就充大。  
  • 诀窍3 领导相互喝完才轮到自己敬。  
  • 诀窍4 可以多人敬一人,决不可一人敬多人,除非你是领导。  
  • 诀窍5 自己敬别人,如果不碰杯,自己喝多少可视乎情况而定,比如对方酒量,对方喝酒态度,切不可比对方喝得少,要知道是自己敬人。  
  • 诀窍6 自己敬别人,如果碰杯,一句,我喝完,你随意,方显大度。  
  • 诀窍7 自己职位卑微,记得多给领导添酒,不要瞎给领导代酒,就是要代,也要在领导确实想找人代,还要装作自己是因为想喝酒而不是为了给领导代酒而喝酒。比如领导甲不胜酒力,可以通过旁敲侧击把准备敬领导甲的人拦下。  
  • 诀窍8 端起酒杯(啤酒杯),右手扼杯,左手垫杯底,记着自己的杯子永远低于别人。自己如果是领导,知趣点,不要放太低,不然怎么叫下面的做人?
  • 诀窍9 如果没有特殊人物在场,碰酒最好按时针顺序,不要厚此薄彼。
  • 诀窍10 碰杯,敬酒,要有说词。  
  • 诀窍11 桌面上不谈生意,喝好了,生意也就差不多了,大家心里面了然,不然人家也不会敞开了跟你喝酒。  
  • 诀窍12 不要装歪,说错话,办错事,不要申辩,自觉罚酒才是硬道理。
  • 诀窍13 假如,纯粹是假如,遇到酒不够的情况,酒瓶放在桌子中间,让人自己添,不要傻不啦叽地去一个一个倒酒,不然后面的人没酒怎么办?
  • 诀窍14 最后一定还有一个闷杯酒,所以,不要让自己的酒杯空着。跑不了的~  
  • 诀窍15 注意酒后不要失言,不要说大话,不要失态,不要唾沫横飞,筷子乱甩,不要手指乱指,喝汤噗噗响,不要放屁打嗝,憋不住上厕所去,没人拦你。  
  • 诀窍16 不要把"我不会喝酒"挂在嘴上(如果你喝的话),免得别人骂你虚伪,不管你信不信,人能不能喝酒还真能看出来。  
  • 诀窍17 领导跟你喝酒,是给你脸,不管领导要你喝多少,自己先干为敬,记着啊,双手,杯子要低。  
  • 诀窍18 花生米对喝酒人来说,是个好东西。保持清醒的头脑,酒后嘘寒问暖是少不了的,一杯酸奶,一杯热水,一条热毛巾都显得你关怀备至。

2007-02-09

firefox 使用技巧-----插件兼容性的修改

firefox依靠其优异的性能和强大的插件功能,获得了广大电脑爱好者的喜爱,尤其是它的各种功能的插件让使用者在网络活动中获得了极大的方便。可是每种插件为了保证其稳定性,都有一个版本的兼容性,这样一些好的插件因为没有更新,在新版本的firefox中就不能使用,如何解决这个问题呢?用 google搜了一下,原来方法很简单:



1. 先把你需要的插件下载下来,一般下载下来的文件是xpi扩展名;

2. 关闭firefox;

3. 把xpi扩展名改为zip扩展名,然后解压;

4. 打开其中的install.rdf,找到其中和firefox有关的语句,修改“maxVersion“后面的版本号,例如”3.0.0.*“改大一些,如”4.0.0.*“,如果找不到明显和firefox有关的语句,那索性把所有“maxVersion“后面的版本号都改大一些。

5. 重新压缩成zip包,改扩展名为xpi,再安装即可。



如果你已经安装了插件包,在firefox升级后不能使用了,那就要这样做:



1. 关闭firefox;

2. 先找到firefox的profile所在文件夹,一般默认是在C:\Documents and Settings\(当前用户名)\Application Data\Mozilla\Firefox\Profiles\*.default\,进入文件夹extensions下面的每个目录,按照上面的方法修改每个install.rdf文件。

3. 最后再用相同的方法修改profile文件夹下面的extensions.rdf文件中maxVersion后面的版本号。

4. 重新启动firefox你就可以看到插件又可以用了。





2007-02-06

《落叶归根》有感

很感人,画面清晰,用色非常好,特别是里面的多个人物表现出的形形色色的性格,惟妙惟肖。

可以说是近年电影中难得的佳作。



最难忘的是赵本山坐在大卡车上,深情的朗诵的一首诗:

"如果我的祖国是一片大海,我就是一条小鱼,我游啊游,我真快乐!


如果我的祖国是一条大路,我就是一辆汽车,我开啊开,我真快乐!


如果我的祖国是一棵大树,我就是一片树叶,我摇啊摇,我真快乐!"



《了望东方周刊》:《越狱》背后的中国字幕组

中文字幕组为盗版的英美电视剧配上字幕,很容易被看成中国盗版猖獗的证据,而《纽约时报》记者又把他们冠名为“打破文化屏蔽者”.这两条理由就足够把中文字幕组的哥们全吊死在电线杆子上.

随着美剧《越狱》在写字楼里的风靡,一个神秘的群体—— 负责为“狱粉”们下载、翻译、制作、压制、发布、分流的字幕组逐渐浮出水面.



  第一个揭开神秘面纱的是《纽约时报》,不久前该报发表了一篇题为《打破文化屏蔽的中国字幕组》的文章, 报道出来后被专栏作者连岳转载进个人博客,立即引来跟帖无数,有网友回帖高声赞叹:“以自然法的名义,向字幕组的同志们致敬!他们是这个时代真正的教育家,如果没有这些人,中国青年脑中的知识将起码丧失一半。”



  越来越多的网友开始好奇中国字幕组究竟是一个什么样的组织?他们在做着什么样的工作?他们做这些工作的初衷何在,他们是否以此为生?



他们不再隐秘



  在伊甸园论坛上,打出了这样的招聘启事:字幕组长期招募各语种(英、日、韩、德、法、俄、意、西、其他)字幕翻译、听译及时间轴制作人员,待遇优厚。欢迎高手加盟!



基本条件:

(1)热爱电影或美剧;

(2)有一定的网络条件(公众网资源下载速度10KB/s以上);

(3)有一定的业余时间(平均每月10小时以上);

(4)做事踏实认真,具有敬业精神、团队精神和强烈的责任感;

(5)目前不在其他电影或美剧字幕组效力或担任职务。



  当记者试图以应聘者的身份发帖咨询时被拒之门外,原因是只有会员才可以发帖,而想要注册伊甸园会员必须受到现有会员的邀请才能注册。据一位不愿透露身份的伊甸园会员称,这样做的目的是为了保证论坛的安全,里面的人还是尽量不希望过多地暴露在阳光下。



  所有的字幕组都在拼时间,都想抢在第一时间把中文字幕发布出来。一位不愿透露姓名的《越狱》字幕组成员讲述了从接收片源到上传字幕所经历的六个小时的 “生死时速”:FOX电视台播放完一集《越狱》,就有片源从国外BT网站传到国内字幕组的FTP,这个工作通常由国外的留学生完成,大概需要半小时,为了争取时间,有的字幕组还会先借道韩国的服务器, 再传回国内的FTP,这样能将片源的传输过程从半小时缩短到10分钟。英文字幕常由录制人员直接用MSN或QQ传给字幕总监,字幕总监再分发给下面的工作人员,同时通知参与这次翻译行动的时间轴、翻译、校对、压片人员。



  当一集《越狱》的无字幕视频准备好后,先由时间轴人员清理字幕里的广告,并为英文字幕配上时间轴,即“从几分几秒到几分几秒,某个角色说了什么话”,做这项工作最重要的是细心,因为一不小心就可能对错时间点。一部45分钟的片子,一名熟练的时间轴人员大概两个小时就可以搞定。



  字幕总监收到配好时间轴的英文字幕,分派给4名翻译,每人10分钟左右,差不多200句对白,两个小时的工作量。翻译是件挺郁闷的事情,要赶时间,所以翻译过程中少有交流,遇到问题就请教Google。



翻译完成后,还需要校对人员最后把关,纠正翻译错误,统一翻译风格,并重新检查时间轴,因为有时英文一句话要分两行显示,而中文几个字就能表达。更何况字幕不是书本上、网站上的文字,可供读者按自己的阅读速度来读。字幕在画面上是一闪即逝的,观众的阅读速度,会被它的停留时间所控制。即使观众能在该行字幕消失前阅毕,太长的字幕仍会占用观众的时间,妨碍他们观赏画面。



  校对完毕后,字幕总监就可以在射手网(国内最大的字幕网站)上发布中文字幕文件了。通常,他们还会顺便把简体中文转换成繁体格式,连同英文字幕一并打包,单独提供下载。射手网做过一个简单的统计,《越狱》第二季第13集是伊甸园最早发布的,从北京时间上午9点30分拿到片源,到当天下午16点零2分在网上发布,只用了6个半小时。伊甸园字幕组文件发布后被下载了1万多次,而 3个小时后上传的另外一个字幕组的中文字幕,下载量不足它的1/10。这个数字或许可以解释字幕组之间为什么会如此争分夺秒地抢进度。



但求热爱 不问回报



  很多网友都有这样的同感:“网上翻译的字幕比很多DVD的字幕好多了”。这种好不仅体现在准确度和时效性上,更体现在字里行间译者流露的感情,一种对片子的感情。现在新加坡攻读物理学博士的王鹏曾经是伊甸园论坛的一名普通译工,他对《了望东方周刊》记者说:“粉丝看粉丝翻译的字幕,最能心领神会,相顾莞尔。”



  复旦大学中文系严锋教授对《了望东方周刊》说:“他们所翻译的东西并不是达到了怎样的高度,翻译得多么好,但他们的翻译不像一些正规、专业的翻译那么生硬,他们的翻译更加生活化,很贴近我们自然的语言,有时他们还使用了一些我们熟悉的成语。最可贵的是他们在一些对话旁边还加了注释,比如一些文化、历史方面的典故,这些都是非常贴心的。我能在他们身上看见一种敬业精神。”



  《纽约时报》报道过一位“痴情”的中国骨灰级粉丝兼字幕翻译:“23岁的丁承泰是一家银行的网络技术专家,一年半来,他一下班就把自己关在房间里,开始消灭那些大部头的美国电视剧,比如 ‘Lost’、‘C.S.I.’还有‘律政俏主妇’,朋友还以为他失踪了。他连夜为这些连续剧编译字幕,发布到网上。通过BT这样的技术,越来越多的中国观众能够免费下载观看到这些节目。”



  只要登录到相关的字幕网站,不难发现网站招聘的都是像丁承泰这样的兼职人员,所谓的待遇都不是拿人民币来衡量的。TLF被网友公认为最具实力的字幕组之一,成立于2002年7月,主要从事电影翻译和美剧翻译。4年内,有全世界超过500名电影爱好者为TLF字幕组的发展贡献了力量。目前,TLF字幕组现役组员超过100名,组员涵盖出生于60年代、70年代和80年代的三代人,学历包含中学、大学、硕士、博士四个级别。组内男女性别比例6:1,囊括了全中国的语言精英,其中相当部分为海外留学人员,其中不乏来自哈佛等世界名校的学子。



  参加字幕组的人, 并非个个毫无私心, 不少人是冲着字幕组的内部FTP账号去的。对喜欢美剧的人来说, 那个账号是个宝贝, 几乎可以看到所有的美剧。王鹏告诉记者:“我当时加入字幕组的动机也主要在于此,学校曾一度把BT的端口给封了,我只好加入字幕组,每个星期翻译三四个小时,就可以换得最新一集的美剧,后来电视剧播完,我也就退出了。”



  正是因为有了这些字幕组,中国的美剧粉丝们从此过上了“天涯共此时”的日子。美国东部时间11月27日晚19点,即北京时间28日的早8点,《越狱》第二季第13集在美国福克斯电视网开播。这是《越狱》第二季进入冬歇期之前的最后一集。美剧的规矩是每周一集,中国《越狱》迷苦等了一个星期后,早已心痒难耐,隔几个钟头就跑到射手网和各大美剧论坛上去看中文字幕出来了没有。



  长期以来,各大中国字幕组以翻译字幕为乐,享受着彼此之间竞争速度和质量的简单快乐。他们类似早期的黑客一样低调,仅仅在作品的流布范围上就能取得足够的自我满足。



在接受《了望东方周刊》采访的字幕翻译中还有一位是上海电影制片厂的签约译员蒋蔚,他在上影译制片厂作兼职翻译,不同的是他的工作有回报,他最终没有透露收入的多少。“坦率地说,我在乎的不是翻译的酬劳,我更看重自己连续赶上几个通宵翻译一部作品,最后被中国观众接受的成就感。” 蒋蔚告诉记者,他把每一部由他参与翻译的电影都刻成光盘,小心地珍藏着,“将来儿子长大了,我要告诉儿子这部电影里面也有老爸的一份功劳。”



  提到影视论坛里那些自发组织不拿一分钱报酬的中文字幕组,蒋蔚很钦佩这样一个躲在幕后,默默奉献,无声无息的群体。“如果让你加入他们,不拿一分钱报酬,你肯吗?”记者问道。“我愿意。”蒋蔚回答地很干脆,“对于美国电影或电视剧的影迷剧迷们来说,第一时间享受到一个好故事,第一时间伴着剧情的起承转合,心情随之跌宕起伏,第一时间得知人物命运的结局,这些意义都要远远胜过外界的赞许或者任何物质上的回报。



翻错一个字就是对美剧的亵渎



  美剧的很多剧迷们都知道网上流传着一个王牌翻译叫Re-quiem,此人是《太空堡垒卡拉狄加》的超级粉丝,这部片子最初在网上流行没有英文字幕,他就一句一句听译,翻来覆去地听上一整天,如临大敌,仿佛一个错别字都是对这部剧的亵渎。有热心人给他算了一下,他翻译一集片子,至少要对着字幕看6次片子。因此同行都开玩笑说字幕组新招的人跟谁比都不要跟Re-quiem比,他属于变态级别的。



  “听译已经是翻译的最高境界了。”王鹏坦言他只做过一次听译,当时是翻译一部电影,花了一天时间,非常辛苦,来来回回,反反复复听了好多遍。“尤其是一些不太熟悉的人名、地名,还有一些深刻的老片老引用历史,我就要不断Google。认真一点的做法都是要查清楚并且作注释的,尽管观众一般都不注意注释。”



  一些被认为“痴气”的字幕翻译常常一翻就是8小时,不吃不喝不睡,像着了魔一样。当看到一些触景生情的场面,翻译还会一边抹眼泪一边在键盘上敲字,浑然忘我。最让王鹏敬佩的是一部日本动画《Ghost in Shell》的翻译,里面大量引用世界文学名著原话,在他看来翻译真是到了炉火纯青的地步。



  一位网名叫“冬天”的网友说:“我印象最深的一句特别富有中国特色的翻译是‘I swear to God’这句话,在Shark(《律政狂鲨》)的某一集里面,这句话被‘fr’翻译为‘向毛主席保证’,哈哈,太贴切了,中国人是不会向上帝发誓的。”



  把美国民谚翻译成中文有其特别的难处。《欲望都市》有一集里面,“我想你们两个将会很适合”(I thought you two would hit it off)被翻成“我想你们两个会来电”。《越狱》里面的名句“准备的作用是有限的” (Preparation can only take you so far)则被改成了“谋事在人,成事在天”。尽管故事的背景完全在美国,经过了这样的翻译,或多或少会带上一点中国特色。而这些都要归功于翻译的精心雕琢。



  据王鹏介绍,即使都是志愿翻译者,水平差异还是很大的,有些翻译质量太差,斑竹会自动清理掉。字幕组间在内容的相互竞争也就是把字幕发到字幕站,靠公众的口碑来评判。



  “各个字幕小组之间存在竞争,这种竞争不是商业角度的,而是从业务角度,他们互相比速度、比质量,这种良性的竞争必然会使得他们的翻译越来越好。”严锋说。



  韩剧的著名字幕团队骄阳字幕组就受到了韩剧迷们的首肯,有网友这样写道:“通过《天可怜见》认识了骄阳。从那时开始,《19岁的纯情》、《真的真的喜欢你》、《美好的一天》还有《伟大的遗产》也都是看骄阳出品的。我信赖骄阳,骄阳也没有让我们失望!骄阳人的服务是一流的,你们虚心接受意见;主动与韩迷沟通;韩剧在线播完之后,骄阳字幕组人员通宵制作,凌晨发布!这种敬业精神让我们感动!骄阳,你们为韩迷们所做的、所奉献的一切心血和汗水,我们都看在眼里,感激在心里!”



你不是公安局的吧



  “你不是公安局的吧?” 还在新加坡读博的字幕翻译王鹏,通过MSN接受本刊记者采访的一个小时里,不下五次质疑记者的身份。一位自称是“自闭症患者”的网友在论坛里发帖也表示这样的担忧:“字幕组成员应该被央视评为2006感动中国年度人物,唉,还是不要炒作了,否则这些幕后英雄就要挂了。”



  一位不愿透露姓名的网友在“航海日志”里发言:“中文字幕组为盗版的英美电视剧配上字幕,很容易被看成中国盗版猖獗的证据,而《纽约时报》记者又把他们冠名为‘打破文化屏蔽者’。这两条理由就足够把中文字幕组的哥们全吊死在电线杆子上。”有些网友准备在网上发表联合声明,连煽情的标题都想好了:《求求你们放过中国字幕组吧!》



  对于无数美剧的忠实粉丝来说,他们的心情是复杂和矛盾的,“从丁承泰接受了《纽约时报》的采访起,多米诺骨牌就开始倒下。结果是所有中文字幕组都曝露在阳光之下,当年各大黑客组织出水就是这样的情形。”一位《越狱》粉丝这样慨叹,“而我不能对此说什么,甚至不能谴责谁。因为我是中文字幕组的受益者,我无权要求他们永远隐姓埋名下去。如果他们有一天不希望如此了,要走到前台来,得到他们应有的荣耀,这是他们的自由。或者因此而得到美国方面的工作邀请,则更是他们的权益所在。即使因此而导致我没有翻译的美剧看,也只能如此。我可以遗憾,我可以悲伤,但是我不能呼吁,不能要求。没有谁规定他们必须保持缄默,因此我的保护也就无从说起。只是一想到未来可能没有BT可下,心里总觉得怅然得很。”



  “你担心中国法律有一天会封杀中文字幕组吗?”王鹏回答记者说:“我担心的是法律有一天会禁止下载,那样字幕组也就名存实亡了。如果这帮哥们遭遇不测,意味着无数粉丝将无法看到及时准确的美剧翻译版本,只好苦练英文了,中文字幕组是中国特色的产物,在新加坡,美剧迷们的英文比中文还好,没有中文字幕组也就不存在这样的担心了。”



  聪明的字幕制作组成员早已做到兵来将挡,水来土掩。细心的观众会在《越狱》每集的LOGO旁边看到这样一段文字:“伊甸园影视论坛荣誉出品,本字幕仅供学习交流,严禁用于商业用途,请于24小时内删除,请购买正版”。字幕组还意识到,他们的作品在其他国家可能被认为是侵权。不过根据中国法律,这些作品很可能被认为是学术研究。因为他们既不收费,也不以赢利为目的。



  上海大学影视艺术技术学院教授林少雄回顾了我国引进影片的正常渠道和程序:“文革”及上世纪80年代,国家对于外国影片的引进有专门的审查机构,意识形态占主要的因素。那时候国内的观众所能看到的都是苏联、阿尔巴尼亚等社会主义国家的影片。后来我们国家开始引进国外大片,我还记得引进的第一部进口大片是Harrison Ford主演的《亡命天涯》。



“现在我们国家引进国外影片实行配额制,每年引进的外国影片数量有具体的规定,逐年有所增加。至于国外电视剧的引进,则由电视台来做。比如韩国《大长今》就是由湖南经济卫视引进的。”林少雄说。





作文化交流的使者





  姑且不论中文字幕组所从事的是不是合法的工作,至少他们被网友看作是美国流行文化的爱好者和传播者。他们为那些想通过看大量的美国电视和电影来学英语、了解西方文化的人提供了一个绝佳的平台。



不少《越狱》粉丝说他们从电视剧里学到了许多知识,从流行时尚到生化医学,还有美国各州名称及地理位置,FBI的工作流程,甚至包括美国的dating culture。



  “从电视里你能看到日常生活的方方面面,从政治、历史到文化艺术。”丁承泰说,“这就是美剧的独特之处。当我第一次看《老友记》时,我发现里面随处可见美国历史的相关知识,也显示了美国的高速发展。这比课本上的有趣多了。”



林少雄在接受《了望东方周刊》采访时表示,国内出现的字幕组客观上会对国内的受众产生三方面的影响:



  “首先,对观众的欣赏习惯有很大的改变。’‘文革’以后80年代,欣赏和接受外国影片都是通过翻译、配音,而现在很多受众在观看外国影片的时候都要求必须要听原声、看字幕。我上课的时候给学生作过试验,给学生播放配音的影片,学生们就会觉得很别扭。”



  “第二,保持了影片原有的品质。在影片中原声和配音的差距还是比较明显的,人物对话和音乐等都是影视作品中比较重要的方面。”



  “第三,改变人们的认知能力。虽然观众在看原声电影的时候,一方面要看画面,一方面又要忙着看字幕,这肯定会分散他们的注意力,但是把阅读和观看两者结合起来,经过长期的培养,可能会对人的认知能力产生一些影响。”



精选文章

如何准备适合的美术器材

按: 本文是少数派共创栏目 《写给家长的幼儿美术启蒙指南》 的第三章,在栏目更新完成之际,免费开放给大家阅读,希望能给正在为挑选美术器材而犯难的你有所帮助。 本栏目在专业的理论基础之上,结合作者多年育儿经验与真实案例,用足够简单、实用、接地气的语言,让每个人都能逐渐掌握美术启蒙所...