若我为上帝,谁为众生

.net技术及哲学思考
随笔 - 97, 文章 - 72, 评论 - 29, 引用 - 0
数据加载中……

2008年4月20日

看《时光之心》的感受

最近半月都没看小说,再看《时光之心》,一边看着书,一边看着作者对于票和大家关注度低的抱怨,说起来作者的文笔很不错的,小说写的也是行云流水,可是怎么大家关注越来越少呢?

我总结了下,两个问题:
1。行文散漫,中心主题或是目标不明显。作者一直是站在世外的角度去写故事,主角的带入度低,这是第二个问题了,下面再谈,每个小说,都要有个中心的主题,才能凝聚力量,有的放矢。《魔戒》的主题就是“毁灭魔戒”,《无限恐怖》的主题就是“活下去”,《明》的主题就是“平等”,例子很多,我就不多举了。主题可大可小,可复杂可简单,但不能没有。
如果没有,小说就缺乏了向心力,成了游记,而AB的书一直有这种问题,从《数字生命》到《野性之心》,再到《时光之心》,原因何在?因为AB的书是属于那种从一个被改变的假设向外延推论的类型,就好比现在很火的都市异能类型,都是从一个不合逻辑的能力或物品开始推论,到底这种非现实的东西能改变什么,改变从自身开始,向外延伸,改变自己的生活,改变亲戚朋友同学老师的生活,改变一省,改变一国再到整个世界。
这种方式不是不好,而且其优点很多,比如,思维的连贯性,和易写易用什么的。但其缺点也是明显的,就是缺少内容主线的推动力和目标,很多都市异能的书都是失败在了这点上,用异能强壮了自己,也挣了钱了,地位也有了,吃喝不愁了,小弟无数,美女万千,然后呢?就没有目标了,就让人厌烦了。
而这种缺点怎么解决呢?其实很简单——build一个强大的,邪恶(是否邪恶,看作者功力而定,功力足够高强的,可以写不邪恶的,功力不够,那就老老实实的写邪恶的吧,当然,功力最高深的是写出来让你搞不清楚他是否邪恶)的反面BOSS。boss这个东西在小说,游戏,电影,电视剧等多种领域都是不可或缺的,但凡是好的作品,里面都有1到若干个boss,供主角去艰难克服。而刻画好一个主角,只是成功了一半,而刻画好了一个boss,就成功了两倍。

2。人物缺乏带入感,作者总是站在一个现代的视角去控制主角,连带造成了主角也是一种若即若离的态度,对作品中的世界很没有投入的感觉,当然,ab对这个世界的构建也有很大缺陷,很多细节和框架都没有搭建全。以致于写到哪里就描述两句,写不到那里就当看不见。而一个真实完整的世界和其设定,是保证读者能够全身心的投入其中,甚至忘记现实的第一保障。其实想来,时光之心的世界跟随波逐流一代军师的世界架构基本类似,但细节方面的粗糙,造成了整个世界给人的感觉都是模模糊糊的,而主角呢?更是模糊,用一个词来形容——虚无化。主角一直是在一种出世的态度对待这个世界,从未真正的投入进去,是适应这个世界,而是在不顾一切的去改造这个世界,使其接近原来的现实世界。给读者带来了两个麻烦:a。读者无法形成人物的带入感,无法以己身去替换叶韬。b。无法形成对世界的带入感,几乎不能去体验那个世界的历史军事文化民风,甚至是一草一木。

所以说,革命尚未成功,同志仍需努力。

posted @ 2008-04-20 01:05 马维拉的真实之眼 阅读(10) | 评论 (0)编辑

2007年7月15日

zt《异域镇魂曲》简介(看了让人思索良久)

英文名:Planescape: Torment
中文名:异域镇魂曲
开发制作:Interplay/Black Isle
代理发行:台湾英特卫国际有限公司
上市时间:1999年
游戏类型:RPG(角色扮演)
配置要求:
基本配置:
  奔腾 200MMX(或兼容CPU)
  32 MB 内存
  Windows 95,DirectX 5.0以上
  650 MB硬盘空间
  8X CD-ROM
  4 MB显卡
  SB兼容声卡
  鼠标、键盘

  推荐配置:
  奔腾 II 266 MHz(或兼容CPU)
  4 MB内存
  800 MB硬盘空间
  8X CD-ROM
  8 MB显卡


简介:

《异域镇魂曲》作为Gamespot和Computer Gaming World联合评选出的,1999年最佳游戏编剧和年度角色扮演游戏,是续“博德之门”后由Interplay出品的第二款标准的基于TSR的《龙与地下城》系列的角色扮演游戏,这款1999年最佳RPG由着名的Black Isle小组操刀制作,该小组同时也是1997年最佳RPG游戏“辐射”和1998年最佳RPG游戏“博德之门”的制作者。



《异域镇魂曲》是一个神秘而耐人寻味的有着哲学命题和壮丽宏大史诗般的剧情的一个游戏,是一个不用担心死亡而去寻求真正死亡的游戏。,你将在那里遇到难以想象的生物和出人意料的事件,整个故事情节将如同一本精彩绝伦的小说一般展现在你的面前它那神秘的世界,宏伟的场景,华丽的效果画面,变幻莫测的游戏主线,引人入胜的故事情节,创意非凡的物品和NPC设定,冷峻的科幻色彩,诡异的情节,庞大的世界观、AD&D规则和复杂海量140万字的精彩的对话使它盘踞世界游戏排行榜榜首长达半年之久.


这到底是什么样的一个游戏呢?

与东方人的偏好不同,西方人更喜欢在生与死上动心思,在《异域惊魂曲》中,玩家所扮演的不象其它RPG那样,要么是一个英俊小生,要么是千娇靓女,在这里你将作为一个遍体鳞伤的,在千百世中不断轮回,丑陋的无名氏而存在。在经历了无数次的死而复生后无名氏失去了大部分记忆,游戏开始时你又一次复活,独自一人从l停尸间冰冷的停尸台上醒来,为子找回自己失落的记忆,寻觅自己死而不朽的原因,无名氏开始了探索自我生命之旅。不朽,从另一个角度上意味着无名氏与同伴的不同之处是:不会真的死亡,不必死后就必须重新载入进度,当你的生命降为0以后,会马上从某个特定的地方复活,对无名氏来说,死亡只是一个简单的仪式,有时它甚至可以帮你完成一些看起来不可能的任务. 这个游戏剧情特色还有就是游戏中并没有拯救世界或者与邪恶作战等“宏大”的情节,有的是个人内心的挣扎,冲突,包括主角与各个伙伴对自己“本性”所作的斗争。而这种剧情不仅在游戏中可算是绝无仅有,更是比一般的拯救世界的剧情更加感人,更能震撼人心。 相信,当你进入到这个游戏中时,当你为解开游戏主角的不死之谜而前进时,你会情不自禁的将自己融入到这个魔幻的世界中去,投入到这个貌似丑陋的角色当中去.



经验的取得,通常是与敌人战斗并获胜,虽然《异域镇魂曲》同样有许多的战斗场面与人物培养细节,但它的内容其实更像是个冒险游戏。在游戏中解谜与对话的重要性远超过杀杀砍砍的战斗,而且最大的经验值来源往往是透过适当的对话取得,而非卤莽地将对手杀死.如果某个任务可以用武力和智力,你会发现,用智取胜的好处会大于用武力来解决,包括最终的BOSS也能用智力,也能靠对话来解决.


这个游戏因为它的思想深度而得到了玩过它的人的一致赞扬,被誉为游戏艺术化的真正代表,于灵魂,永生,死亡的探索是深刻而独特的;但是那压抑阴暗的气氛与色调对于那些游戏日式游戏的爱好者来说,它颓废阴暗的美工简直就是美式游戏邋遢肮脏画面的典型,(游戏画面下面有截图)但这正是这个游戏的特色之一,与游戏的内容紧密相合,完全符合环境气氛.游戏刻画了栩栩如生的场景图像,荒凉压抑的外星荒漠,热闹喧哗的繁华都市,阴深幽暗的地下墓穴,庞大庄严的古代要塞,这些堪称精品的场景都是手工精心绘制而成。制作者也修改了魔法的施放画面,场面比起以前的龙与地下城类游戏都要显得宏大,再加上出色的背景音乐制作,“异域惊魂曲”不仅拥有精彩的剧情设置,在视觉和听觉方面也有不俗的表现。


游戏中你会拥有各种奇妙的道具。一个主角的眼珠子也作为装备出现的游戏中(下面有截图)在下怀疑是否还会有人担心游戏的物品不够丰富。没有什么比更换牙齿、挖掉眼珠换钱更酷的了。所以,在这里“武装到牙齿”并不是一句空话。除了必不可少的武器、盾牌、盔甲、皮靴、戒指、耳环、腰带和头盔以外,这里还有一只能让主角的防御上升一个等级的玻璃眼球,附加中毒效果、攻击为4-13的牙齿,每高念一遍咒语就能得到33块钱的耳环,防御等级加一、附加50%防火效果的耗子尾巴,提高敏捷度25%的死人手指骨(这些都是什么玩意!?);除此之外,还有乾枯的骷髅头、自己的内脏、死耗子、缝合伤口而导致3点HP回复的针线……看到这些希奇古怪的东东,在下是不是不用再大费口舌赘述物品的种类繁多了?


游戏中共有4种职业:战士,法师,盗贼和牧师,你可通过特定的人物交谈而转换职业,每次只能拥有一个职业,,也只能合用当前职业的技能,主角一开始从停尸间醒来时是一个3级的战士,其它职业都是一级,一般来说职业选择应以战士为主,法师为辅.


老实说,这不是一款爱情游戏,爱情和它简直不沾边,至多只是绵羊身上的一撮毛,通长意义的恋爱游戏FANS简直一辈子不会去碰它,但是就是那么一点爱情,足可以叫其他游戏黯淡失色。它那超越生死的爱不是其它游戏那些看似幼稚的爱情能比的,这点只有在游戏中慢慢的才能体会.
主角在游戏中有两位女同伴,吸精夜魔失宠和人与恶魔的混血儿阿娜,她们自愿跟着主角冒险,为他吃了不少苦。但是今天我不说她们的故事,我更想提提主角的两个前世情人,为爱情受伤的灵魂戴娜拉和将你变成不死身的夜巫——不死者。戴娜拉拥有透视未来的能力,主角的一个为了利用她的能力而博取了她的爱情,那个前身也成功地进入了悔恨要塞。在要塞前,他唆使戴娜拉自杀,让戴娜拉的灵魂指引他来看穿整个要塞的迷宫。至于戴娜拉有没有看穿前身的用意,游戏里没有说——因为游戏是站在无名氏的角度回忆的,但是从游戏的叙述看无论如何戴娜拉都愿意为爱人牺牲生命。在她死后,戴娜拉的灵魂仍然挂念着主角,主角在一开始的停尸房就可以遇见她。戴娜拉的声音交织着深深的怨恨和同样强烈的爱意,但是如果主角好言以待,她仍然愿意帮助主角,向他透露了一些身世,最后主角进入悔恨要塞时前来警告的也是她,如果游戏失败——这个游戏的失败不是主角的死亡,而是关键线索的丢失——戴娜拉德的灵魂还是默默站在主角的后面,哪怕此时主角已经将她忘得一乾二净。与愿意为了爱情粉身碎骨的戴娜拉不同,夜巫是一个十恶不赦的人,对于前往求助的人,她都会问:“什么才能改变一个人的本质?”没有一个人符合她的心意,于是所有人都被杀了,但是当主角求助的时候,任何答案都不重要,她将无条件的为主角服务——因为她爱上了主角。或许爱情不是真正的解答,真正的谜底在于她已经找到了属于她自己的答案。至少爱情改变了她的一部分本质,在她那丑恶扭曲的心灵宛如沙漠的心灵上开出一朵原属于温室的鲜花。此后夜巫向法印城的统治者——痛苦女士——挑战失败,被拘禁于一个小小的位面中。但是她在法印城的分身依然竭尽所能帮助主角,在最后,他们又重逢了,这个丑陋的老太婆仿佛又变成当日的美丽女子,甚至与失宠和阿娜争风吃醋。在向主角透露了他们的故事后,她心愿已了,在向主角点明去路后借无名氏之手杀死了自己。异域是一个探求信仰的游戏,爱情也是信仰的一个重要部分,它能改变人也能毁掉人,就像无名氏最后与超凡者的对话:是吗?我见过信仰移动城市,使一个人脱离死亡,将邪恶女巫的心转变为仁慈。这整个要塞都是有信仰构筑的。信仰诅咒了一个女人,她的心紧系于希望,希望一个不爱她的人爱她。信仰让一个人追寻不朽,他成功了。而且它让一个鬼魂以为自己不只是我的一部分


对很多玩家来说,长篇的对话是他们不原深入探索游戏的原因,觉得那些对话冗长累牍的,让人受不了,但这恰巧是极为重要的一个内容,也是游戏的精华所在,有些对话可一带而过,但有些对话还是要仔细看清,看明,因为,这就是这个游戏的本质所在.




  异域镇魂曲是一个庞大的游戏,而且允许有很多种不同的玩法。创建一个角色对游戏的进程是否顺利和最终的结局是否美满有很大的关系。建立一个强大角色的关键在于理解各种属性和恰当的分配组合。尽管每个属性的基本含义都很明显,但很多重要的数据是无法仅仅从字面就能读出来的。
下面我将为大家一一分析:


 力量(str):力量除了影响击中和途害目标外,还能够用力量砸开游戏中85%的锁。
在对话选项中,力量值还会 影响你威胁NPC的成功率。任何意图具有高战斗力的玩家都应该在一开始将力量升到18,然后买一 个力量刺身(+1str)达到19str(18str=+1/+3 hit/dam,19str=+3/+7 hit/dam)。

 灵敏(dex):没有必要把灵敏度加到最高,到18就差不多了。

 体质(con):体质在游戏的一开始并不怎么重要,但在后期就慢慢显现出它的威力。
体质影响你体力恢复的速度 ,也决定你的体务值。体质拥有最高值25点的话,你可以在一分钟里恢复100点体力!另外,由于 从第10级开始,每升一级体力值只会增加1-3点而不是之前的1-10点,高体质带来的好处就非同小 可(24点的体质可以使每升一级多加7点的体力),大大加强了你搞打击和战斗的能力。当你的级别步入十级以上以后,每一点体质的改进都会使战斗轻松很多。

 智力(int):除了影响你的魔法咒语数量以外,更高的智力还使角色在与NPC交谈时拥有更多的选项。
一些任务 不仅能提供经验值,如果你的智力足够高的话,还能让你得到永久的属性提高。智力还奖励你的 lore技巧(鉴别物品)。任何魔法师角色都需要较高的智力。

 智慧(wis):不管你在游戏中选择了怎样的职业,智慧都是最重要的属性。
智慧超过20以后,人所能得到的经验值比一般人要高出多达30%。智慧对于解决一些任务也起着重要的作用。另外,智慧的高低也决定 了游戏结局的好坏。

 魅力(cha):与其他属性相比,魅力只能排在最末尾了。
魅力高的玩家可以在买卖货物时有价格方面的优势 ,某些情形下还有更多的谈话选择。魅力值在15以上的话,会造成隐藏属性运气(Luck),在战斗 中会有难度上的降低。

如果你想透彻地了解这个动人的故事,那游戏初期较好的属性选择为:
力量(str)为9
智力(int)为15
智慧(wis)为15
灵敏(dex)为15
体质(con)为15
魅力(cha)为9

posted @ 2007-07-15 13:30 马维拉的真实之眼 阅读(130) | 评论 (0)编辑

2007年7月9日

zt HOW TO:使用 Visual C# .NET 生成 Office COM 外接程序

本文的发布号曾为 CHS302901

概要

Microsoft Office XP 和 Microsoft Office 2003 都支持一种新的统一的设计结构,这种结构用于生成应用程序外接程序以增强和控制 Office 应用程序。这些外接程序叫做 COM 外接程序。本文逐步讨论了 Office COM 外接程序,并介绍了如何使用 Microsoft Visual C# .NET 生成 Office COM 外接程序。

回到顶端

IDTExensibility2 接口

COM 外接程序是一种进程内 COM 服务器或 ActiveX 动态链接库 (DLL),它实现如 Microsoft 外接程序设计器类型库 (Msaddndr.dll) 中所描述的 IDTExensibility2 接口。所有 COM 外接程序都从此接口继承而来,而且都必须实现其五个方法中的每一个方法。

OnConnection

每当连接 COM 外接程序时,都会激发 OnConnection 事件。外接程序可以在启动时连接、由最终用户连接或者通过自动化来连接。如果 OnConnection 成功地返回,就表明已加载了外接程序。如果返回错误消息,那么宿主应用程序就立即释放其对该外接程序的引用,而且该对象将被销毁。

OnConnection 使用下列四个参数:
Application — 一个对宿主应用程序对象的引用。
ConnectMode — 一个指定外接程序连接方式的常量。外接程序可以采取下列几种方式连接:
ext_cm_AfterStartup — 外接程序由最终用户从 COM 外接程序 对话框启动。
ext_cm_CommandLine — 外接程序从命令行连接。注意,此方式不适用于生成 Office 应用程序的 COM 外接程序。
ext_cm_External — 外接程序由外部应用程序通过自动化连接。请注意,此方式不适用于生成 Office 应用程序的 COM 外接程序。
ext_cm_Startup — 外接程序由宿主在应用程序启动时启动。此行为由注册表中的设置来控制。
AddInInst — 一个对 COMAddIn 对象的引用,它引用宿主应用程序的 COMAddIns 集合中的此外接程序。
Custom — 一个包含 Variant 类型值的数组,它可以存储用户定义的数据。

OnDisconnection

当 COM 外接程序断开连接并且在它从内存中卸载之前,将激发 OnDisconnection 事件。外接程序应在此事件中执行所有资源清理操作,并还原对宿主应用程序所做的任何更改。

OnDisconnection 使用下列两个参数:
RemoveMode — 一个指定外接程序断开连接的方式的常量。外接程序可以采用下列方式断开连接:
ext_dm_HostShutdown —外接程序在宿主应用程序关闭时断开连接。
ext_dm_UserClosed — 外接程序由最终用户或自动化控制器断开连接。
Custom — 一个包含 Variant 类型值的数组,它可以存储用户定义的数据。

OnAddInsUpdate

当注册的 COM 外接程序集发生变化时,将激发 OnAddInsUpdate 事件。换言之,每当安装 COM 外接程序或者从宿主应用程序中删除 COM 外接程序时,都会激发此事件。

OnStartupComplete 和 OnBeginShutdown

当宿主应用程序在忙于向内存中加载自身或者从内存中卸载自身时应避免用户交互,而 OnStartupCompleteOnBeginShutdown 方法都是在宿主应用程序已离开或正要进入这一状态时被调用的。只有在启动期间已连接了外接程序的情况下才调用 OnStartupComplete,只有宿主在关闭过程中要断开与外接程序的连接的情况下才调用 OnBeginShutdown

由于在激发这些事件时宿主应用程序的用户界面是完全活动的,因此它们可能是执行某些操作的唯一途径,以其他途径将无法从 OnConnectionOnDisconnection 中执行这些操作。

回到顶端

COM 外接程序注册

除了正常的 COM 注册外,COM 外接程序还需要向其运行所在的每一个 Office 应用程序注册自身。为了向特定应用程序注册其自身,外接程序应使用其 ProgID 作为项名称在以下位置下创建一个子项:
HKEY_CURRENT_USER\Software\Microsoft\Office\OfficeApp\Addins\ProgID
外接程序可以在此项的位置为好记的显示名称和完整的说明提供值。此外,外接程序应使用一个名为 LoadBehavior 的 DWORD 值指定所希望的加载行为。此值确定宿主应用程序如何加载外接程序,而且它由下列值的组合组成:
0 = Disconnect — 未加载。
1 = Connected — 已加载。
2 = Bootload — 在应用程序启动时加载。
8 = DemandLoad — 只在由用户请求时加载。
16 = ConnectFirstTime — 只加载一次(在下次启动时)。
通常指定 0x03 (Connected | Bootload) 这一典型的值。

实现了 IDTExtensibility2 的外接程序还应指定一个名为 CommandLineSafe 的 DWORD 值,以指出外接程序对于不支持用户界面的操作是否安全。值为 0x00 表示 False,值为 0x01 则表示 True。

回到顶端

如何使用 Visual C# .NET 生成 COM 外接程序

如上文所述,Office COM 外接程序是由 Office 应用程序通过 COM 运行时层激活的进程内 COM 服务器。因此,为了在 .NET 中开发 COM 外接程序,外接程序组件需要在 .NET 中实现,然后通过 COM interop 层向 COM 客户端(即 Office 应用程序)公开。

要在 Visual C# .NET 中创建 COM 外接程序,请按照下列步骤操作:
1. 在 Visual C# .NET 中,创建一个类库项目。
2. 添加一个对实现了 IDTExtensibility2 的类型库的引用。此项的主 interop 程序集已经出现在 Extensibility 名称下。
3. 添加一个对 Microsoft Office 对象库的引用。此项的主 interop 程序集已经出现在 Office 名称下。
4. 在实现了 IDTExtensibility2 的类库中创建一个公共类。
5. 生成该类库之后,将该库向 COM interop 进行注册。为此,需要为此类库生成一个使用强名称的程序集,然后将它注册到 COM interop。可以使用 Regasm.exe 来向 COM interop 注册 .NET 组件。
6. 创建注册表条目以使 Office 应用程序可以识别并加载外接程序。
您可以选择完成所有这些步骤,或可以创建类型为共享的外接程序 的 .NET 项目。这将启动“扩展性向导”,该向导可帮助您在 .NET 中创建 COM 外接程序。

“扩展性向导”将创建一个 Visual C# .NET 类库项目,同时创建一个实现了 IDTExtensibility2 接口的 Connect 类。它还会生成实现 IDTExtensibility 的空成员的主干代码。此项目具有对 Extensibility 和 Office 程序集的引用。该项目的生成设置中已选中了注册 COM interop。将生成程序集密钥 (.snk) 文件,并在 Assemblyinfo.vb 文件的 AssemblyKeyfile 属性中进行引用。

除类库项目外,该向导还将生成一个安装项目,该项目可用于在其他计算机上部署 COM 外接程序。在需要时可以删除此项目。

回到顶端

分步示例

1. 在 Microsoft Visual Studio .NET 的文件菜单上,单击新建,然后单击项目
2. 新建项目对话框中,展开项目类型下的其他项目,选择扩展性项目,然后选择共享的外接程序模板。
3. 键入 MyCOMAddin 作为该外接程序的名称,然后单击确定
4. “扩展性向导”出现后,请按照下列步骤操作:
a. 在第 1 页,选择使用 Visual C# 创建外接程序,然后单击下一步
b. 在第 2 页,选择下面的宿主应用程序,然后单击下一步
Microsoft Word
Microsoft PowerPoint
Microsoft Outlook
Microsoft Excel
Microsoft Access
c. 在第 3 页上,输入该外接程序的名称和描述,然后单击下一步

注意:该外接程序的名称和描述出现在 Office 应用程序的 COM 加载项对话框中。

d. 在第 4 页,选择所有可用的选项,然后单击下一步
e. 单击完成
5. 项目菜单上,单击添加引用。单击组件列表中的 System.Windows.Forms.DLL,单击选择,然后单击确定
6. 将下列代码添加到 Connect 类中的名称空间列表中:
using System.Reflection;
7. 将下列成员添加到 Connect 类中:
private CommandBarButton MyButton; 
8. Connect 类中实现 IDTExtensibility2 的成员的代码,如下所示:
public void OnConnection(object application, Extensibility.ext_ConnectMode connectMode, object addInInst, ref System.Array custom) {
            applicationObject = application;
            addInInstance = addInInst;
            if(connectMode != Extensibility.ext_ConnectMode.ext_cm_Startup)
            {
            OnStartupComplete(ref custom);
            }
            }
            public void OnDisconnection(Extensibility.ext_DisconnectMode disconnectMode, ref System.Array custom) {
            if(disconnectMode != Extensibility.ext_DisconnectMode.ext_dm_HostShutdown)
            {
            OnBeginShutdown(ref custom);
            }
            applicationObject = null;
            }
            public void OnAddInsUpdate(ref System.Array custom)
            {
            }
            public void OnStartupComplete(ref System.Array custom)
            {
            CommandBars oCommandBars;
            CommandBar oStandardBar;
            try
            {
            oCommandBars = (CommandBars)applicationObject.GetType().InvokeMember("CommandBars", BindingFlags.GetProperty , null, applicationObject ,null);
            }
            catch(Exception)
            {
            // Outlook has the CommandBars collection on the Explorer object.
            object oActiveExplorer;
            oActiveExplorer= applicationObject.GetType().InvokeMember("ActiveExplorer",BindingFlags.GetProperty,null,applicationObject,null);
            oCommandBars= (CommandBars)oActiveExplorer.GetType().InvokeMember("CommandBars",BindingFlags.GetProperty,null,oActiveExplorer,null);
            }
            // Set up a custom button on the "Standard" commandbar.
            try
            {
            oStandardBar = oCommandBars["Standard"];
            }
            catch(Exception)
            {
            // Access names its main toolbar Database.
            oStandardBar = oCommandBars["Database"];
            }
            // In case the button was not deleted, use the exiting one.
            try
            {
            MyButton = (CommandBarButton)oStandardBar.Controls["My Custom Button"];
            }
            catch(Exception)
            {
            object omissing = System.Reflection.Missing.Value ;
            MyButton = (CommandBarButton) oStandardBar.Controls.Add(1, omissing , omissing , omissing , omissing);
            MyButton.Caption = "My Custom Button";
            MyButton.Style = MsoButtonStyle.msoButtonCaption;
            }
            // The following items are optional, but recommended.
            //The Tag property lets you quickly find the control
            //and helps MSO keep track of it when more than
            //one application window is visible. The property is required
            //by some Office applications and should be provided.
            MyButton.Tag = "My Custom Button";
            // The OnAction property is optional but recommended.
            //It should be set to the ProgID of the add-in, so that if
            //the add-in is not loaded when a user presses the button,
            //MSO loads the add-in automatically and then raises
            //the Click event for the add-in to handle.
            MyButton.OnAction = "!<MyCOMAddin.Connect>";
            MyButton.Visible = true;
            MyButton.Click += new Microsoft.Office.Core._CommandBarButtonEvents_ClickEventHandler(this.MyButton_Click);
            object oName = applicationObject.GetType().InvokeMember("Name",BindingFlags.GetProperty,null,applicationObject,null);
            // Display a simple message to show which application you started in.
            System.Windows.Forms.MessageBox.Show("This Addin is loaded by " + oName.ToString()   , "MyCOMAddin");
            oStandardBar = null;
            oCommandBars = null;
            }
            public void OnBeginShutdown(ref System.Array custom)
            {
            object omissing = System.Reflection.Missing.Value ;
            System.Windows.Forms.MessageBox.Show("MyCOMAddin Add-in is unloading.");
            MyButton.Delete(omissing);
            MyButton = null;
            }
            private void MyButton_Click(CommandBarButton cmdBarbutton,ref bool cancel) {
            System.Windows.Forms.MessageBox.Show("MyButton was Clicked","MyCOMAddin"); }
            
9. 生成并测试该 COM 外接程序。为此,请按照下列步骤操作:
a. 生成菜单上,单击生成解决方案。请注意,生成 COM 外接程序的过程中实际上就向 COM interop 注册了 .NET 类。
b. 启动一个您选作外接程序的宿主应用程序的 Office 应用程序(例如,Microsoft Word 或 Microsoft Excel)。
c. 外接程序启动之后,将激发其 OnStartupComplete 事件,您会收到一个消息框。请关闭该消息框。请注意,外接程序向标准工具栏中添加了一个新的标题为“My Custom Button”(我的自定义按钮)的自定义按钮。
d. 单击 My Custom Button(我的自定义按钮)。该按钮的 Click 事件将由外接程序来处理,而且您会收到一个消息框。请关闭该消息框。
e. 退出该 Office 应用程序。
f. 退出该应用程序时,将激发 OnBeginShutDown 事件,您会收到一个消息框。关闭该消息框以结束演示。
这篇文章中的信息适用于:
Microsoft Visual C# .NET 2003 标准版
Microsoft Visual C# .NET 2002 标准版
Microsoft Office Excel 2003
Microsoft Excel 2002 标准版
Microsoft Office Outlook 2003
Microsoft Outlook 2002 标准版
Microsoft Office PowerPoint 2003
Microsoft PowerPoint 2002 标准版
Microsoft Office Word 2003
Microsoft Word 2002 标准版

posted @ 2007-07-09 15:27 马维拉的真实之眼 阅读(135) | 评论 (0)编辑

2007年7月7日

.net 2.0 里面操作配置文件 的问题 (读取另外的配置文件的时候的疑问)

有一个问题,遍寻网上而不见.

在vs2005中,如果不读取默认的app.config文件,而是读取自定义的配置文件.

需要用system.configuration.configuration a=configurationmanager.openexeconfiguration(配置文件路径);

然后我获取appsettings,

string appPath = System.Windows.Forms.Application.StartupPath;
            
string configPath = appPath + "\\DocAddin.dll.config";
            System.Configuration.Configuration config
= System.Configuration.ConfigurationManager.OpenExeConfiguration(configPath);            

            
string dbPath=config.AppSettings.Settings["DBPath"].Value;

 结果发现appsettings的settings集合里面是空的.根本一个键值对都没有.

我的config文件里面是这样定义的

 

<?xml version="1.0" encoding="utf-8" ?>
<configuration>
<appSettings>    
      
<add key="DBPath" value="D:\Program Files\默认公司名称\SetupForDocAddin\DOCDB.mdb"/>
      
<add key="MachineID" value="DefaultMachine"/>      
  
</appSettings>
</configuration>

最后发现:
 ConfigurationSettings .AppSettings
ConfigurationManager.AppSettings
Configuration.AppSettings.都不一样 .

正在继续研究中 .

posted @ 2007-07-07 11:35 马维拉的真实之眼 阅读(103) | 评论 (0)编辑

2007年6月19日

zt西游记IT团队的裁人问题

为了节约成本,要在西游记团队中栽一个你会裁掉哪位?

背景:为了完成西天取经任务,组成取经团队,成员有唐僧、孙悟空、猪八戒、沙和尚。其中唐僧是项目经理、孙悟空是技术核心、猪八戒和沙和尚是普通团员。这人团队的高层领导是观音。

团队的组成很有意思。唐僧作为项目经理PM,有很坚韧的品性和极高的原则性,不达目的不罢休,又很得上司支持和赏识(直接得到唐太宗的任命,既给袈裟,又给金碗;又得到以观音为首的各路神仙的广泛支持和帮助)。

沙和尚言语不多,任劳任怨,承担了项目中挑担这种粗笨无聊的工作。

猪八戒这个成员,看起来好吃懒做,贪财好色,又不肯干活,最多牵下马,好象留在团队里没有什么用处,其实他的存在还是有很大用处的,因为他性格开朗,能够接受任何批语而毫无负担压力,在项目组中承担了润滑油的作用。

最关键的还是孙悟空,由于孙悟空是这个取经团队里的核心,但是他的性格极极端,回想他那大闹天空的历史,恐怕作为普通人来说没有人会让这种人呆在团队里。

那就请分析一下:为了节约成本,需要在这个团队里裁掉一个队员,你会裁哪一位?为什么?

呵呵,这个话题现在很火,咱给加个白龙马。白龙马的工作职责更简单,就是负责伺候唐僧。团队里起到一个小蜜的角色,唐僧能好好干活,全靠小蜜拉!领导的小蜜能随便裁嘛?

posted @ 2007-06-19 09:30 马维拉的真实之眼 阅读(50) | 评论 (0)编辑

2007年6月2日

研究了一下SqlExpress中的外键约束

以前用数据库,一般都建表关系,但是这些关系建好了往往没有用到.

这次写一个项目,涉及到多表的外键约束和级联删除的问题,才研究了一下.

用的vs2005里面自带的SqlExpress,在VS里面作数据库,感觉不是很方便(废话,都方便了,那sqlserver2005 dev 卖给谁去!)

我建了表,然后建了关系,设定了外键约束.

然后就以为万事大吉了,去写代码,画界面去了.

把代码和界面搞定后,一试验删除,删除的级联链中间的一个表的数据,然后就报错.

Title

DELETE 语句与 REFERENCE 约束"FK_课程扩展信息表_教师表"冲突。该冲突发生于数据库"x:\xxx.MDF",表"dbo.课程扩展信息表", column '教师编号'。
语句已终止。



然后研究了下外键约束.到底是怎么回事.网上搜到一篇定义:
Title
FOREIGN KEY 约束
  • 如果在 FOREIGN KEY 约束的列中输入非 NULL 值,则此值必须在被引用的列中存在,否则将返回违反外键约束的错误信息。

  • FOREIGN KEY 约束应用于前面所讲的列,除非指定了源列。

  • FOREIGN KEY 约束仅能引用位于同一服务器上的同一数据库中的表。数据库间的引用完整性必须通过触发器实现。有关更多信息,请参见 CREATE TRIGGER

  • FOREIGN KEY 可以引用同一表中的其它列(自引用)。

  • 列级 FOREIGN KEY 约束的 REFERENCES 子句仅能列出一个引用列,且该列必须与定义约束的列具有相同的数据类型。

  • 表级 FOREIGN KEY 约束的 REFERENCES 子句中引用列的数目必须与约束列列表中的列数相同。每个引用列的数据类型也必须与列表中相应列的数据类型相同。

  • 如果 timestamp 类型的列是外键或被引用键的一部分,则不能指定 CASCADE。

  • 可以在相互间具有引用关系的表上组合使用 CASCADE 和 NO ACTION。如果 SQL Server 遇到 NO ACTION,将终止执行语句并回滚相关的 CASCADE 操作。当 DELETE 语句导致 CASCADE 和 NO ACTION 组合操作时,在 SQL Server 检查 NO ACTION 操作之前将执行所有 CASCADE 操作。

  • 一个表最多可包含 253 个 FOREIGN KEY 约束。

  • 对于临时表不强制 FOREIGN KEY 约束。

  • 每个表在其 FOREIGN KEY 约束中最多可以引用 253 个不同的表。

  • FOREIGN KEY 约束只能引用被引用表的 PRIMARY KEY 或 UNIQUE 约束中的列或被引用表上 UNIQUE INDEX 中的列。

仍然不解其意.

然后在关系图中的关系上点击右键,查看属性,发现其"INSERT 和 UPDATE 规范类别 "内都是"无操作",感觉应该是这里的问题.
上msdn上搜索了一下,发现了这篇文章: 可视化数据库工具-外键列属性
ms-help://MS.MSDNQTR.v80.chs/MS.MSDN.v80/MS.VisualStudio.v80.chs/dv_vdt01/html/2cb23e81-6342-4390-9d0e-b7a4805eca0f.htm
关键的几句在这里:

Title
INSERT 和 UPDATE 规范类别

展开以显示有关该关系的“删除规则”和“更新规则”的信息。

删除规则

指定当数据库的最终用户尝试删除某一行,而该行包含外键关系所涉及的数据时所发生的情况。如果设置为:

  • 无操作   显示一条错误信息,告知用户不允许执行该删除操作,DELETE 将被回滚。

  • 级联   删除包含外键关系中所涉及的数据的所有行。

  • 设置空   如果表的所有外键列都可接受空值,则将该值设置为空。仅适用于 SQL Server 2005。

  • 设置默认值   如果表的所有外键列均已定义默认值,则将该值设置为列定义的默认值。仅适用于 SQL Server 2005。

更新规则

指定当数据库的用户尝试更新某一行,而该行包含外键关系所涉及的数据时所发生的情况。如果设置为:

  • 无操作   显示一条错误信息,告知用户不允许执行该删除操作,DELETE 将被回滚。

  • 级联   删除包含外键关系中所涉及的数据的所有行。

  • 设置空   如果表的所有外键列都可接受空值,则将该值设置为空。仅适用于 SQL Server 2005。

  • 设置默认值   如果表的所有外键列均已定义默认值,则将该值设置为列定义的默认值。仅适用于 SQL Server 2005。



总算是明白了:
1.在vs2005中,外键约束的属性窗口中它不叫"级联",叫"层叠",估计是翻译错误.
2.vs2005中,在关系图中建立外键约束,它"默认的INSERT 和 UPDATE 规范"都是"无操作".
   也就是说,你只要更新或删除,它都会报错.
3.解决的方法:
   a.删除的时候好办,级联删除就可以了.但更新的时候还得好好考虑.
   b.或者干脆去掉外键约束,自己考虑,然后写transcation sql.










posted @ 2007-06-02 23:01 马维拉的真实之眼 阅读(817) | 评论 (2)编辑

2007年5月30日

zt最专业的关于ACCESS数据库的文章!

access数据库规格问题,如表能放多少字段,多大。。。

地址:http://access911.net/fixhtm/72FAB01E17DC.htm?tt=

posted @ 2007-05-30 10:23 马维拉的真实之眼 阅读(45) | 评论 (0)编辑

2007年5月4日

ztCreateUserWizard输入密码和设置安全问题

使用CreateUserWizard来创建用户很方便,但使用的方式很难理解,“密码最短长度为 7,其中必须包含以下非字母数字字符: 1。”的问题,其实这句话的实际意思是:“密码最短长度为 7,其中必须包含至少1个非字母数字字符。”。非字母数字字符就是!@#等字符,实际上这提示可以在InvalidPasswordErrorMessage属性上修改的,比如“密码最短长度为 {0},其中必须至少包含{1}个非字母数字字符:。”参数一表示最短密码长度,参数2表示至少包含的非字母数字字符,那么如果我不需要这些设置怎么办呢?在控件上设置吗?很遗憾微软并没有提供这个方便,需要到web.config里面去修改。
往providers节添加:
minRequiredPasswordLength="3"
minRequiredNonalphanumericCharacters="0"
这两个属性,从名字就可以看出来了:第一个属性表示密码的最少长度,第二个属性表示至少输入的非字母数字字符个数,设为0就OK了。

那么如果我也想去掉安全问题呢?
再加上:
requiresUniqueEmail="false" 
requiresQuestionAndAnswer="false"
问题就解决了

posted @ 2007-05-04 17:28 马维拉的真实之眼 阅读(43) | 评论 (0)编辑

2007年4月18日

寻觅在office(确切的说是word) 的工具栏中添加控件的方法,找到了这个控件列表

需要在office2003的工具条(CommandBar)上面添加一个label和一个textbox,找了半天没找到.

在msdn里面找到了这个:
Members
Member name Description
msoControlActiveX ActiveX control.
msoControlAutoCompleteCombo Combo box in which the first matching choice is automatically filled in as the user types. Cannot be created through the object model.
msoControlButton Command button.
msoControlButtonDropdown Drop-down button. Cannot be created through the object model.
msoControlButtonPopup Pop-up button. Cannot be created through the object model.
msoControlComboBox Combo box.
msoControlCustom Custom control. Cannot be created through the object model.
msoControlDropdown Drop-down list.
msoControlEdit Text box.
msoControlExpandingGrid Expanding grid. Cannot be created through the object model.
msoControlGauge Gauge control. Cannot be created through the object model.
msoControlGenericDropdown Generic drop-down list. Cannot be created through the object model.
msoControlGraphicCombo Graphic combo box. Cannot be created through the object model.
msoControlGraphicDropdown Graphic drop-down list. Cannot be created through the object model.
msoControlGraphicPopup Graphic pop-up menu. Cannot be created through the object model.
msoControlGrid Grid. Cannot be created through the object model.
msoControlLabel Label. Cannot be created through the object model.
msoControlLabelEx Extended label. Cannot be created through the object model.
msoControlOCXDropdown OCX drop-down list. Cannot be created through the object model.
msoControlPane Pane. Cannot be created through the object model.
msoControlPopup Pop-up.
msoControlSpinner Spinner. Cannot be created through the object model.
msoControlSplitButtonMRUPopup Most Recently Used (MRU) pop-up. Cannot be created through the object model.
msoControlSplitButtonPopup Split button pop-up. Cannot be created through the object model.
msoControlSplitDropdown Split drop-down list. Cannot be created through the object model.
msoControlSplitExpandingGrid Split expanding grid. Cannot be created through the object model.
msoControlWorkPane Work pane. Cannot be created through the object model.


这就是在office上面的控件的enum值.后面标注了是否可以创建,但可惜,大部分都不能创建(Cannot be created through the object model.).

最后还有段话:

Remarks

Used with the Add method of the CommandBarControls object. Only a limited set of the control types can be created via the CommandBars object model: msoControlButton, msoControlEdit, msoControlDropdown, msoControlComboBox, msoControlPopup, and msoControlActiveX. Other control types may exist on built-in or add-in command bars, but cannot be created via the object model.


遗憾啊遗憾啊.

注:来自ms-help://MS.VSCC.v80/MS.MSDN.v80/MS.VisualStudio.v80.chs/offio11ref/html/T_Microsoft_Office_Core_MsoControlType.htm

posted @ 2007-04-18 16:33 马维拉的真实之眼 阅读(166) | 评论 (0)编辑

2007年4月11日

vs2005,combox 数据绑定和SelectedIndexChanged事件触发 引发的问题

昨天前天,都在折腾一个问题,vs2005里面自带的combox(winform)的问题.

这个问题是这样的,我从数据库中读取出表中的数据,每行填充到预设的类中,再把这些类数据,填充到这个类的集合中,然后combox的dataSouce指向这个类集合.然后设置这个combox的显示和值为其名称属性和编号属性.

这样没有问题.

但当我在combox的SelectedIndexChanged事件中写了获取当前combox的已选择的类的编号属性的时候,发现总在报错.

找了半天原因,才发现:

combox的SelectedIndexChanged事件,在datasouce指定的时候就被触发了,这时候数据还没有绑定好,自然会报错.

我认为这是不合理的.SelectedIndexChanged不应该在绑定数据的中间被触发.

我最后解决办法是设置了一个标志符isLoaded,bool类型,在填充方法完毕后,设为true.允许SelectedIndexChanged被触发.

代码如下:

/// <summary>
        
/// 绑定cmbdoc数据的方法
        
/// </summary>
private void FillCmbDoc()
        {
            
//新建文档类的集合
            Class.ClassDocCollection items1 = new DocAddin.Class.ClassDocCollection();
            
//提取所有文档数据,填充到集合
            items1.FillInAllDoc();

            cmbDoc.DataSource 
= items1;
            cmbDoc.DisplayMember 
= "S名称";
            cmbDoc.ValueMember 
= "I编号";
            
//设置标志符,true说明该combox已经绑定好了,允许SelectedIndexChanged事件被触发了.
            isLoaded = true;
           
        }

private void cmbDoc_SelectedIndexChanged(object sender, EventArgs e)
        {
            
//如果绑定完毕,并且选择的不为空
            if (cmbDoc.SelectedItem!=null && isLoaded==true)
            {
                
//获得文档类的编号
                int docid = int.Parse(cmbDoc.SelectedValue.ToString());
                
//由编号从数据库中提取出该编号的文档类对象
                Class.ClassDoc cd = new DocAddin.Class.ClassDoc(docid);

                tbPath.Text 
= cd.S路径;

                
if (tbName.Text.Trim()=="")
                {
                    tbName.Text 
= cd.S名称 + "-";                    
                }
            }
        }

posted @ 2007-04-11 08:51 马维拉的真实之眼 阅读(744) | 评论 (1)编辑