2007-04-17
[转贴]爱一个人不一定要得到
如果你不爱一个人,请放手,好让别人有机会爱她。如果你爱的人放弃了你,请放开自己,好让自己有机会爱别人。
有的东西你再喜欢也不会属於你的,有的东西你再留恋也注定要放弃的,人生中有许多种爱,但别让爱成为一种伤害。
有些缘分是注定要失去的,有些缘分是永远都不会有好结果的,爱一个人不一定要拥有,但拥有一个人就一定要好好的去爱他。
男人哭了,是因为他真的爱了;女人哭了是因为她真的放弃了。
如果真诚是一种伤害,我选择谎言;如果谎言是一种伤害,我选则沉默;如果沉默是一种伤害,我选择离开。
如果失去是苦 你怕不怕付出 ;
如果迷乱是苦 你会不会选择结束 如果追求是苦 你会不会选择执迷不悟 如果分离是苦 你要向谁倾诉,好多事情都是后来才看清楚,好多事情当时一点也不觉得苦,然而我已经找不到来时的路 。
有一种爱,明明是深爱,却说不出来.有一种爱,明明想放弃,却无法放弃.有一种爱,明知是煎熬,却又放不开.有一种爱,明知无前路.心却早已收不回来.
决定放弃你的那一刻我哭了,我的眼泪证明了我是真的很爱你。
我们永远都不要提分手好吗?爱你不是游戏。爱你是真心的。忘记你我做不到。不管我们的解决是否完美,勾勾手指,说好不再分手。
什么是勇气?是哭着要你爱我,还是哭着让你离开。
男人的自信来自一个女人对他的崇拜,女人的高傲来自一个男人对她的倾慕。永远不要栽培你爱的男人,你把他栽培的太好,结果只有两个:他从此看不起你或他给人偷了。追求一个人的手法不需要太聪明,但离开的手法必须聪明绝顶!
为什么我们总是不懂得珍惜眼前人?在未可预知的重逢里,我们以为总会重逢,总会有缘再会,总以为有机会说一声对不起,却从没想过每一次挥手道别,都可能是诀别,
一声叹息,都可能是人间最后的一声叹息。
也许爱情只是因为寂寞,需要找一个人来爱,即使没有任何结局。
伤口是别人给与的耻辱,自己坚持的幻觉。
发现自己只能爱一个人在一瞬间。而且渐渐变的自私。
很多人不需要再见,因为只是路过而已。遗忘就是我们给彼此最好的纪念。
我不知道一个人的一生可以有多少个十年可以给另一个人。
爱可以是一瞬间的事情,也可以是一辈子的事情。每个人都可以在不同的时间爱上不同的 人。不是谁离开了谁就无法生活,遗忘让我们坚强。
人这样的生物,仔细一看,原来是伤痕累累的。是否被爱,每个人有不同的感受。重寻旧梦的代价往往是我们付不起的。人世间的幸福,总会令人好看一点。因为微笑,我才了解爱。
身上一切,看似不经意,却是我苦心经营,希望你快乐。你说:不如送我一双雨鞋。不如,你送我一场春雨。那么即使我流泪,在雨中,也不容易被你看到。
世事其实都是在它适当的时候降临,只是我们没有适当的心情去迎接它。
因为爱他,所以离开他。我喜欢这句话。有些感情如此直接和残酷。容不下任何迂回曲折的温暖。带着温暖的心情离开,要比苍白的真相要好,纯粹的东西死的太快了。
感情被懂得是一种幸福,等待着被懂得是一种孤独!
因为爱过 所以懂得,因为失去 所以容易满足,因为留恋
所以珍惜。。。。。我曾经爱过的人。。。最终消失的。。无影无踪。。。END。。。。。让自己停止。。悲哀
我是教育硕士了!
上个周末去华南师范大学办入学手续,发现课程比想象中的要复杂,难度也要大一些,即使如此,我也可以统统搞定的。
上课的时间大多数在寒暑假,还有一些时间会在开学期间,所以和我现在的竞赛辅导和上课有很大的冲突,特别是寒暑假的时候。既然这样,那我的工作要重新考虑了,回原来学校的可能性很大。
留给后世的训诫
如果在去世前有机会为后世留下一条宝贵的教训的话,您会留下什么?
Here are their responses:
下面是听众们的回答。
"You always have choices." - Janine Freeman
"车到山前自有路。"
"Goodness is all there is." - Janice
(不敢确定…… 美德就在那里?)
"Spend your time with admirable, successful people." - Loren Ekroth
"花时间同可敬的、成功的人在一起。"
"You create whatever you're focusing on." - Julie Donnelly
"你将在自己一直关注的东西上做出创造。"
"Trust your instincts." - Toni Reiser
"相信你的本能。"
"Trust your vibrations." - Denise Marshall
"相信你的感受。"
"The day is going to be excruciatingly long, but the time is short." - Victor Andrijauskas
"日子长得让人倍感折磨,时间却非常短暂。"
"Communicate your life lessons through your children." - Judith August
"通过你的子女传递生活的教训。"
"Never wrestle with a pig because you both get dirty and one of you likes it." - Judi Moreo
"绝不要与猪摔跤,因为双方都会弄脏自己,但有一方却乐此不疲。"
"You create and co-create your own life's truth." - Steva Giles
"生活的真理是人创造的,并且是人们在一起共同创造的"
"When you realize what beliefs imprison you, you will find the key to your freedom." - Ayesha Ashley
"当意识到那些囿限自己的信条时,你将找到属于自己的自由。"
"Feelings are the lights on the dashboard of life." - Cherie Carter-Scott
"情绪是映在生活仪表盘上的光亮。"
"Be realistic, plan for a miracle." - Vicki Kallman
"实实在在地生活,规划一个奇迹。"
"After the age of 50, you will discover that your greatest trophies in life are your children." - Rod LeGrande
"50 岁之后,你将发现生活最好的奖赏是你的子女。"
"Power to change." - Anonymous
"改变的力量。"
"A lesson is repeated until learned." - Michael Pomije
"在你了解一件教训之前,它们将一直重复。"
"There are no ordinary moments." - Mark Valentine
"生活中没有平常的时刻。"
"Travel as much as possible." - Sandra
"尽可能多地旅行。"
"Successful people give more than they receive." - Greg Bruce
"成功的人的奉献多于个人所得。"
"It takes one to know one, all others must guess." - Daniel Braisted
(这句太哲理了,求助各位读者帮忙翻译)
"Confront your fears. Overcoming them reaps rich rewards." - Robin Jay
"勇敢面对恐惧,克服它们你将收获丰厚的回报。"
"Don't fret about the weather; change the entire climate." - Peter Pizor
"不要为天气苦恼,去改变整个气候吧。"
"Forgive everyone and everything, including yourself." - Scott Desgrosseilliers
"原谅每个人与每件事,包括你自己。"
"The things you own end up owning you." - Joey Vaux
"你所拥有的东西最终会拥有你。"
"Never buy anything you can't sell at a garage sale." - John Kinde
"永远不要在旧货市场上买那些你无法卖掉的东西。"
"Act as if everything you do has an impact; it does." - Leslie Stambaugh
"行动时假设你做的一切都是有影响的,它们一定会。"
"Effective communication involves more than talent. It involves trust, respect, understanding, empathy, and resolution. It is an art." - David Rohlander
"实现有效沟通不仅需要天分,更包括信任,尊重,理解,同情心和决心。它是一门艺术。"
"Happiness is a choice." - Samuel Peery
"幸福是一种选择。"
"Live simple." - Bill Paetzke
"简朴地生活。"
"Three things you can't change: the weather, your past, and other people." - Jim Jackson
"有三件事是无法改变的:天气,你的过去,其他人。"
"Focus on being of extraordinary value." - Hector G. Diaz
"把关注放在那些具有非凡价值的事物上。"
How would you answer this question? What wisdom would you like to pass on to others?
您将如何回答这个问题?您希望将何种智慧传递给后世人?
刹那间瞥见自由
就在我打算离弃她的时候,自由之女神突然现身,让我在一刹那间为她的光辉所笼罩……
我决定将这美妙的瞬间记录下来,立此存照。
小时候,我曾经因为喜欢涂鸦而立志做画家,但小学时连调色板都用不好;我曾经因为感染于文字的美感而希望当一位作家,却连世界名家的作品都对不上号;我
曾经因为迷恋代数而为成为一位数学家而信心满满,却在大学时将很多数学课程都读得很糟;我曾经想做一位思想家,却发现在生活的压力面前,自己都解脱不
了……
到今天我突然发现,这些都不算什么。原来自由从不栖身于那些凌云壮志之中,真正的自由,是一种难得的心境,深藏在每个人的心中待人寻找。
曾经对各种古怪的哲学问题进行思考,却发现人终有一死,没办法自保——客观规律是残酷的,任何人都逃不掉。然而,我也同时发现了另外的规律:年轻时务当奋进,把消极留给年老,因为常人的身体就是这样演变,起初不断成长,最终逐渐衰老。
生活中难免遇到这样那样的难题,我会尽力将它们解决好。即使功亏一篑,也没什么大不了。人人都可以有理想,但是否真的选对了方向,谁也算不到。不过这样更妙,再不必为一时选择的对错而烦恼……
最后祝每位到此观光的朋友们安好,我的理想是让每位我能关照到的人都找到自由与幸福,也许这只是个可望而不可及的目标,但这并不重要。
2007-04-05
不得不看:男人的一百条“感悟”!(转载)
2:给自己定目标,一年,两年,五年,也许你出生不如别人好,通过努力,往往可以改变70%的命运。破罐子破摔只能和懦弱做朋友。
3:找女朋友外表是第一关,但要了解她的品行之后再做打算也不迟。
4:不要在乎小钱,工作的人都后悔从前对自己的GF不够好。记住你们的重要日子,你们的谈话,女生要敏感得多,这样做,至少可以证明你对她的重视。
5:爱她,但别怕她,你们是恋人,也是朋友,她要的不是宠物,这样的感情,走不长远。
6:她要是病了,带她去医院,她害怕时,找个人少的地方抱着她,给她勇气,帮她排队,挂号,放下你那点可悲的面子,周围人只会向她投来羡慕的眼光,不会对你说三道四。
7:别把两个人的生活绞在一起,空间才是爱情的长寿药。不要经常吃醋,谁都有异性朋友,该吃的时候才吃,并且让她知道。
8:善待她的朋友,即使她讨厌的人,你也没资格说坏话,你要做的,就是静静的听她倾诉。适当给她安慰。有时候,她们更需要依靠,即使你们都还是学生。
9:不要问她过去,时机到了,她会毫无保留的告诉你。她要是想见从前那位,让她去,原因是你不让她去,她也会去。为何不表现得大度点,但要让她知道你相当的郁闷。
10:珍惜身边人,不要见异思迁,大家都需要安定。即使对方比你GF漂亮10倍,还主动靠近你,给你暗号,请严肃的告诉她,你有女朋友!
11:她开始管你的生活,你的钱,对你唠叨,频繁发消息询问你的位置。别担心,她只是把自己交给了你,害怕失去你。
12:带她去你从前常去的地方,她内心会无比快乐,你失意时,她会在第一时间找到你。
13:发生口角后,别关机,也别在街上和其他异性闲逛,那只能使矛盾激化。
14:过生日,送她草莓蛋糕,不要太大,但要足够精致,把你对她的腻称放在蛋糕上。再买一个大的,让她和朋友一起过。
15:牵手时,即使你的手有多汗,也别放开。
16:把她介绍给你最好的朋友,包括异性朋友。
17:别总是让她打电话来,她也需要被重视的感觉。
18:衣着尽量和她的品位搭调,即使你要提升品质,请带上她一起。
19:别偷看她的隐私,不要去猜测,在一起是缘分,离开也是缘分。
20:如果失恋,不要轻信江湖上传言的借酒消愁,吐的滋味不好受,即使喝了,也别急着喝茶,茶不但不能解酒,反而还会伤肾。
21:不要整天想着如何重修旧好,除了爱情,前面还有许多问题需要你去解决。这是个现实的社会,感情不能当饭吃,贫穷夫妻百事哀。不要相信电影,那只是个供许多陌生人喧嚣情感的场所。
22:分手之后,可以伤心难过,但过渡期不能太长,因为这期间是绝佳的学习和工作时间。
23:如果你实在奈不住寂寞,至少等上大半年,否则你不仅否定了她,也否定了你自己。
24:当她不再爱你的时候,无论你有多想她也别打电话告诉她,因为有些人会记住第一个,而有些人只会记住上一个。
25:好朋友里面,一定要培养出一个知己,不要以为你有多么八面玲珑,到处是朋友,最后真心对你的,只有一个,相信我。
26:她的离开如若是一个重大打击,找间手艺不错的发型设计理个发,这样可以让你涣然一新。
27:不要去打扰她的生活,她只会觉得从前看错人,你也会鄙视自己。
28:你们在街上相遇,请向她微笑,把微笑留给伤你最深的人。
29:告诉周围人,你和她已经分手,避免他们给你打报告,哪天又看见谁谁谁了。
30:不要相信星座命理,那是哄小朋友的,命运在自己手中。难道你想等出栋房子或是车子?
31:你的朋友最好以你自己为中心发散,允许少数支点连接,千万不要把朋友圈变成密不透风的多边型,你要为自己留底牌。
32:不喜欢的人少接触,但别在背后说坏话,说是非之人,必定是是非之人,谨记,祸从口出。
33:朋友圈里的你,平时都很忍让,请注意适当拿出你的主见。反之,不要太计较。
34:给老师或者领导留下好印象,他们不会在你沉沦时再踩你几脚,相反可能会拉你一把。在社交中,原则是跌停股,世俗是潜力股。
35:偻嬗蜗罚獠皇呛愦虿怀龇孔映底踊褂信恕=舜笱В徒松缁幔馐浅÷砝伞1本┫衷谝桓鲎┩放咨先ィ蚁吕?,8个研究生受伤,现在的你是否该有点打算。
36:拿出极限,尽力而为。你要想的是成功,而不是失败。所以面对困难首先就是拿出信心。除了你心爱女人的鼓励,这应该是最有用的东西。
37:定时整理书桌书柜,良好的精神面貌可以让你事半功倍。
38:学好英语,那些说学英语没用的暂时可以不去管,他们要么年纪大了,要么就是自己早过了CET6准备托福了,在这里哗众取宠。你可以不拿证,但一定要学好。
39:不是足够热爱你的专业,并且学出来前途不够光明,趁早转业。现在更多人更看重“钱途”
40:知道自己要干什么,寝室的卧谈会的确可以帮你磨嘴皮子,夜深人静,问问自己,将来的打算,并朝着那个方向去实现。
41:偶尔翻翻时尚类的杂志,女朋友和女性朋友都可以从中受益。
42:尽量少看A片,正常的男人即使是单身,也不会成天迷恋肉欲。而每次你SY后都会有大量锌元素流失,此元素与你大脑活动有密切联系。
43:坚持做运动,俯卧撑可以锻炼你的胸肌和腹肌,请记住游泳圈是成功人事才有资格拥有的奢侈品。
44:每天早上一杯水,预防胆结实。睡前一小时不要喝水,否则会过早出现眼袋。
45:宁愿要深色袜子也少买白色的,这样会让人觉得你不够成熟,学生朋友自便。
46:新同事或新朋友请你吃饭,不要觉得理所当然,请礼尚往来,否则你的名声会越来越臭。无论是大学还是公司,很多故事都是听来的。
47:有男友的女人不要碰,即便你想onenightstand也要做好心理准备。后果同上,严重时会出现体肤之痛。
48:朋友的女人不要碰,无论是现在的还是曾经的,后果同上。要知道,男人经营自己就像经营一个公司,要树立品牌文化。想问为什么的朋友请先做个你是受害者的假设,再跟我发短消息讨论。
49:博爱的女人不要碰,往往这种女人连自己要什么都不知道,我想没人愿意和若干成年男性分享自己的爱。天作孽,犹可活,自作孽,不可活。
50:没主见,不上进,懒惰的女人不要碰。就算你有钱,你有的是钱,最终你也会厌烦其中。何况不见得她们个个都是花瓶,何况你还有审美疲劳。
51:不以物喜,不以己悲,我知道这很难,但要成功,这是必修课。
52:空闲时间不要全拿去泡BAR,读点文学作品,学习一些经营流程,管理规范,国际时事,法律常识。这能保证你在任何聚会都有谈资。
53:每年回母校看看那些为你付出过的老师,走上社会你才了解她们才是匏降模绕鹉堑阊Х眩羌蛑碧按罅恕QЩ岣卸鳌?
54:回家帮父母做点简单家务,陪他们买菜,做饭,逛街,冬天送他们一人一件羽绒服,他们并不奢望什么,但他们需要得到你的承认,中国的父母是最苦的,孩子是最幸福的。(离婚除外)
55:大家都年轻,没什么钱,不用太在意谁谁又穿AD,NIKE,或者其他。而GF对于PRADA,蓝寇,CD,LV,的热恋,你也不必放在心上,女人天生和美挂上了勾,她们只是宁愿相信你能够为她们买一样昂贵的礼物,以满足她们的虚荣心,然后在同伴面前炫耀一番。实则她们也是热爱生活的,而当你有能力完成时,也会觉得把她包装得漂漂亮亮的很是欣慰。
56:告诉她,你喜欢的内衣。或者在UNDERWEAR店要打佯时陪她去买。
57:欺负她时,请带上套子,如不习惯,请自行解决,直到无法忍受为止,或者泼自己一身冷水。流产很痛苦,我只是听说。
58:有正义感,但请更理智,你父母不希望养育二十多年的儿子化为泡影。但当她遇到流氓时,请你勇敢的挡在她前面。大声说话可以让你的勇气迅速提升。(这是我答辩时认识到的)
59:最好不要在她面前玩天真,多数MM都不喜欢,除非她要求。
60:接吻前先嚼QTB口香糖,接吻时请闭上眼睛,睁开时,告诉你有多爱她。
61:尊重每一个人,包括为你擦鞋的,卖报的,环卫工人...等等。
62:接到陌生电话请先说,“你好,找哪位”
63:想发脾气时,尽量忍,忍不住就去厕所蹲半个小时,或是找个海拔较高的地方站半个小时。
64:如果GF要跟你吵,尽量克制,不能避免时,跟她吵,吵架是最好的交流方式。你们互相可以得到心里渴望已久的答案。但别带脏字,别把对方的亲戚带出来,最后尽量妥协,有些事,只能暂时妥协。不要把问题留过夜。
65:出差回来给她一个惊喜,并带上礼物。(想在这条上跟我开玩笑的朋友,请私下跟我开)
66:在她兜里放些零钱,在她不常用的兜里放张一百。
67:尊老爱幼,帮助别人后,你会感到无比轻松快乐。
68:去市场买东西,杀价先杀四分之三,现在杀一半行不通了。
69:如果可以,给你的对手留条生路,钱是赚不完的。这个世界上,没有天生的敌人。
70:饮水思源,永远做一个有思想的人,即使你不会有大成就,钱也会足够花。
71:为她学一首歌,如果可能,结婚时当着大家的面唱给她听。
72:要做一件事,成功之前,没必要告诉其他人,成功之后,和他们分享快乐。
73:每年去寺庙为家人点几盏油灯,告诉自己的良心,你不在的时候,同样是爱他们的。
74:学会察言观色,不要意气用事,否则会有许多不必要的麻烦。
75:享受孤独,地球不会因为只有你一个人而停止转动,也许她会很晚才出现,在此之前,你要学会正确利用时间,并且让自己发光发亮。
76:从前的她,深夜给你打电话,如果你还爱她,接电话。如果你不爱她,关机。(没听见不在讨论范围之内)
77:夜里的约会最好不要选择偏僻的地方,有些突发事件,会让你痛不欲生。如果你还爱她的话。
78:公司的东西不要带回家,即使有小便宜,也别参与,在你成为领导前,也别指责,这是你管不到的。
79:开发你的另外一个情感宣泄功能,倾听。
80:朋友之间不要合作做生意,或者办公司。麻烦会接踵而来。你要减轻负担,减小风险,可以,找陌生人。
81:今日事,今日毕,不要日复一日,年复一年。不然到你60岁,你还告诉孙子,爷爷明年一定要毕业!
82:感谢曾经爱过你的人,她祝福你的短信,一定要回。
83:朋友之间发生争执,不要次次都是忍让,每个人都有坚持自己的权利,让他们知道你的想法,你所坚持的。没关系,不出两天,你们又是好朋友。
84:说该说的,不说不该说的。对朋友,也应当有所保留。对她,不要把她和从前那个相提并论,谁都受不了。
85:头发,指甲,胡子,打理好。社会是个排斥性的接受体,这个星球所需要的艺术家极其有限,请不要冒这个险,就算你留长头发比较好看,也要尽量给人干净的感觉。
86:牌局可有可无,那不是年轻人该干的,除非工作需要,否则不要培养这种兴趣。当你看见GF坐在赌博机面前聚精会神的呐喊着某张牌时,你是什么感觉?
87:每学期给自己写总结,上课认真学习,所谓的好好学习,天天向上,学好了,就是最管用的绝招。机会常常伪装成麻烦,从你身边路过,也只会留给做好准备的人。上班的朋友同理。
88:不要整天把国家大事摆在嘴上,去改变你能改变的,接受你无法改变的。
89:选一个生日陪你母亲过,那也是她的受难日。不要年年都和同样一群人过。到头来,全心为你的,只有她。
90:有了手机,尽量少上网,就算你仅仅是看新闻,读文章,大把时间也会不经意从你身边流失。
91:不要以为你是个男人,就不需要保养。至少饮食方面不能太随便,多吃番茄,海产品,韭菜,香蕉,都是对男性健康有益处的食物。你要是看不到价值,我可以告诉你。至少你能把看病节约下来的钱给她多买几盒DIOR。
92:善待小动物,你以后也有子子孙孙,同样是生命,培养一下自己的爱心吧。这并不表示你懦弱。
93:如果考公务员,要有十足的心理准备。早点开始托关系吧,还不见得一定就有收效。
94:力求上进的人,不要总想着靠谁谁,人都是自私的,自己才是最靠得住的人。
95:如果你们相处几年下来,她开始冷落你,对你不闻不问,请别怪她,让她离开。给不了她幸福,给她自由。
96:如果你想和她说分手,请在考试之后,人都是脆弱的。
97:她给你买礼物,你可以高兴,但不要太高兴。人生就是场经营,有人经营感情,有人经营利益,有人经营幸福,而有人经营阴谋。
98:面对失败,不要太计较,天将降大任于斯人也,必先苦其心志,劳其筋骨,饿起体肤....但要学会自责,找到原因,且改掉坏习惯。二十岁没钱,那很正常,三十岁没钱,那是宿命。
99:学会微笑,以后在很多场合都用得上它。如何让微笑好看,首先你得拥有健康的牙齿。如何保证牙齿健康,一,早晚,饭后刷牙;二,每年去探望一次牙科医生;三,少管闲事。
100:看都看完了,留个言吧!!!
2007-04-02
厦门百亿化工项目安危争议-----------谁能救厦门于险境?
人家眼里惟恐避之不及的世界级的垃圾和危险物,在我们这里成了“世界级”的宝贝,非将其插入城市的心脏不可!是谁,彻底匍匐在了资本的脚下,而置人类的自由、尊严、健康与安全于不顾?人类的信念何在?2007年3月19日《中国经营报》报道说:“属危险化学品和高致癌物的PX,原本应该远离城市100公里生产才能确保安全,而腾龙芳烃项目中心地区距离厦门市中心和国家级风景名胜区鼓浪屿均只有7公里,距离拥有5000名学生(大部分为寄宿生)的厦门外国语学校和北师大厦门海沧附属学校仅4公里……项目5公里半径范围内的海沧区人口超过10 万,居民区与厂区最近处不足1.5公里。而10公里半径范围内,覆盖了大部分九龙江河口区,整个厦门西海域及厦门本岛的1/5。而项目的专用码头,就在厦门海洋珍稀物种国家级自然保护区,该保护区的珍稀物种包括中华白海豚、白鹭、文昌鱼。”专栏作家连岳说得好:“一旦投产,将使整个厦门岛,甚至是人口稠密的闽南三角都笼罩在剧毒的化工阴影当中。在极端情境之下,比如战争、恐怖袭击,它就是送给对手及恐怖分子的礼物。只要这个工厂一有闪失(人命就不算了,反正也不怎么值钱),对闽南经济的致命打击,可能将损失天文数字般的GDP。”
据悉,一些厦门市民说,只要风稍稍大一点,海沧那些已经投产的化工厂就在排放一些闻起来味道古怪的气体;他们甚至还把厦门的空气质量几年内由全国第十沦落为2006年福建省九地市倒数第三的原因归结于此。当地媒体给出的标准答案是由于汽车数量的增加,所以空气质量就差了——似乎“全国只有厦门人买车”。(连岳语)
在今年“两会”上,全国政协委员、化学家赵玉芬委员牵头提了叫停厦门PX项目的提案,得到包括原北京航空航天大学校长沈士团委员与厦门大学化学系教授、院士田中群委员等105位委员的联署,成为当之无愧的“政协头号提案”。政协委员们认为此项目存在重大环保隐患,使厦门陷于危险当中,而刚刚开始盖厂房的项目现在叫停,损失不大。然而,国家环保总局似乎对此无能为力,因为一个根本的问题是,项目投产是国家发改委批的,国家环保总局在项目“迁址”问题上根本没有权力。“针对该单个项目的环评早已通过。环保总局现在唯一能做的就是,对厦门市绝不再批新的化工项目。”(3月19日《中国经营报》)说到底是官大一级压死人,而不是法律在说话。
但不是还有公众环评制度吗?国家环保总局在2006年2月22日发布《环评公众参与暂行办法》时特别指出:公众参与是解决中国环境问题的重要途径,而环境信息披露制度是公众参与环境事务的前提。国务院《关于落实科学发展观加强环境保护的决定》指出,“实行环境质量公告制度,定期公布各省市有关环境保护指标,发布城市空气质量、城市噪声、饮用水水源水质、流域水质、近岸海域水质和生态状况评价等环境信息,及时发布环境事故信息,为公众参与制度创造条件。”松花江事件充分说明,在环境安全高风险、环境事件高频发阶段,现有的环境应急处理措施已不能完全应对。只有让潜在的环境风险在事前得到充分有效的关注,才能最大限度地降低环境事故的发生频率。
那么,在腾龙芳烃问题上,缺乏全面有效的环境披露和公众参与,而置民众的安全于险境,又是一种什么样的罪错?
在公共事务上,我国普通公民的缺席已久矣。那么,全国政协难道也没有用吗?105位委员(占与会人数的1/20还强)联署提案(如果交由人大和政协表决,反对票一定会占上风),这么大的力量都叫停不了一个置万民和千秋未来于险境的危险项目,那么,什么样的力量还能保障我们的安全?(童大焕)
来源:中国保险报
NVIDIA Geforce显卡系列驱动 游戏优化驱动
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
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
宫琦俊所有动画片的剧情
古时遭受侵略而移居远方的虾夷族青年阿斯达卡,为了拯救遭受危险的村人,右手被凶煞神诅咒,为了寻找解除诅咒的方法,阿斯达卡决定离开亲人到西方去流浪。 在旅行中他见到了一群由幻姬大人领导的贫穷人们。他们在麒鳞兽的森林开采铁矿,并在森林中建立炼铁厂。然而森林中的种种生物都视他们为敌,总是袭击人类。 有着三百岁智慧的白狼神莫娜和被她养大的人类女孩“幽灵公主”桑更是时刻想杀死幻姬,毁灭人类的城市。阿斯达卡既被桑所深深的吸引,理解“幽灵公主”保护 森林的心情,但同时又想帮助人类。在战斗的过程中阿斯达卡被麒鳞兽所救,立场更加摇摆不定。以疙瘩和尚为首的一批人受领主的命令来杀麒鳞兽,更利用幻姬的 力量与反攻人类的大批山猪作战。幻姬以火枪杀死麒鳞兽,失去头颅的麒鳞兽为了夺回自己的头对森林造成了极大的破坏。阿斯达卡和桑合力将麒鳞兽的头颅从疙瘩 和尚手里多回,并还给了愤怒的麒鳞兽,麒鳞兽的灵魂方才安息,被破坏的大自然又恢复了正常。
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
- Introduction
- WebBrowser Customization Architecture
- IDocHostUIHandler
- IDocHostUIHandler2
- Controlling Navigation
- IDocHostShowUI
- Controlling Download and Execution
- IHostDialogHelper
- Controlling New Windows
- Information Bar
- Conclusion
- Related Topics
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
CComPtrspOleObj;
// 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
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/")
{
CComPtrspBrowser;
CComPtrspDisp = ((*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;
}
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
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;
CComPtrspUnk;
CComPtrspBindCtx;
// SHDOCVW stashes the client site in the bind context.
if (pibc)
{
pibc->GetObjectParam(SZ_HTML_CLIENTSITE_OBJECTPARAM, &spUnk);
if (spUnk)
{
CComQIPtrspSite(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.
CComPtrpSvc;
CComPtrpShb;
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);
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, &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:
Define SBCMDID_MIXEDZONE.
#define SBCMDID_MIXEDZONE 39
Initialize pvaOut with VariantInit.
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.
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;
CComPtrspCT;
CComPtrspWnd;
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, &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, &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;
}
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:
Identifier | Header File |
---|---|
CGID_EditStateCommands | Mshtml.h |
CGID_Explorer | Shlguid.h |
CGID_MSHTML | Mshtmhst.h |
CGID_ShellDocView | Shlguid.h |
IDM_CONTEXT | Mshtmcid.h |
SID_SEditCommandTarget | Mshtml.h |
SID_SShellBrowser | Shlguid.h |
SZ_HTML_CLIENTSITE_OBJECTPARAM | Mshtmhst.h |
原文链接:http://msdn.microsoft.com/workshop/browser/hosting/wbcustomization.asp
精选文章
旧手机变废为宝|五分钟安装Ollama跑开源大模型 - 开发调优 - LINUX DO
旧手机变废为宝|五分钟安装Ollama跑开源大模型 - 开发调优 - LINUX DO 在开始之前,请你先准备好一台旧Android手机以及特殊的网络环境。 1.安装Termux 2.更新软件包及依赖 pkg update && pkg upgrade 3.安...
-
咖啡加牛奶,对健康更有益 : 2023-03-04 10:00:00 咖啡加牛奶的组合,能使免疫细胞抗炎效果加倍。 (视觉中国/图) 咖啡是世界上最流行的饮料之一,各种花式咖啡更是在满足口感的同时让人大饱眼福,现在丹麦哥本哈根大学研究人员的两项研究给我们提...
-
Chrome超越Firefox的20条技巧 说明: sfufoet 推荐 20 Instant Upgrades to Make Chrome Better than Firefox 一文,并建议组织翻译。已经在Google Translator Toolkit发布,有...
-
linmu - 五柳村专递 林牧之女谈《烛烬梦犹虚》出版幕后点滴 【老虎庙按】近日偶然通过微博朋友引介读到了傅国涌发表在“共识网”上的文章《 1949前夜,一代青年误读的代价 》,为林牧遗作读后感。与此同时,我在网上搁置多年的电子版《日月昭昭》(出版用名《烛烬梦犹虚》)下载链接忽...