WPF注销系统与退出系统实现

WPF在系统设计的时候少不了登陆,登出,退出系统!

那么注销系统和退出系统究竟该怎样做呢!

首先行不通的事情就是直接关闭登陆页面,也就是起始页面,这样的话系统真的就退出,因此采用的方法应该是在登陆成功之后,隐藏掉登陆页面。

那么我们又怎样来进行登出操作呢?退出系统操作呢?

WPF注销系统与退出系统实现

 

在关闭的时候,我们可能在MainWindow中直接有退出系统按钮,那么我们在点击的时候直接调用Application.Current.ShutDownOK,关闭了,没有问题,但是如果我们不是点击的退出系统按钮,而是直接点击Window自带的关闭呢,结果是什么?可想而知,我们只是退出了当前的主页,而没有退出系统,因为还有登陆页面在隐藏。

因此我们用上面的关闭方法是行不通的,那么到底该怎样做呢,其实很简单,我们知道每个窗体都有Closing的事件,只要我们捕捉到加以利用,一切就OK了,因此我们在MianWindow窗体初始化的时候就监听它的Closing事件,这样无论我们点击了什么,只要当前的窗体关闭了,就相当于关闭了整个系统。

问题还是存在,那么如果我们又想注销系统怎么办呢?当然我们得关闭MainWindow,但是我们不是真想关闭系统而是想显示Login窗体,这样我们以上的做法不是不合理了?难道要改套路不成?

不是的,我们可以设置在MianWindow中设置一个bool的全局变量,默认值为trueClosing事件中,我们只需要判断一下这个变量就可以了,如果为true,那么就关闭系统,如果为false,则显示Login窗体,(当然,在那个页面进行控制,则在哪个页面就应该传递过来Login窗体的对象,我认为比较好用的方法是定义一个属性,通过传递来进行,例如在Login打开MianWidow的时候,我们就将MainWindow.Login=this),清空该用户的信息,OK,那么我们什么时候设置那个全局变量呢?当然是在我们点击注销按钮的时候了,在点击注销按钮的时候,就两个动作,一个是将全局的变量设置成False,另一重要,就是关闭自身,this.close()OK 这样就完成了。

InstallShield中Basic MSI工程类型如何调用InstallScript脚本

这是一个Basic MSI基础知识,有不少网友问,所以我再啰嗦一遍。

A. 首先在Installation Designer/Behavior and Logic/InstallScript视图中,选中Files点击鼠标右键选择“New Script File”,默认会生成一个setup.rul的文件,并有一个MyFunction的函数声明和。

B. 之后我们在MyFunction函数内添加一行代码:MessageBox(“MyFunction”, INFORMATION);

当然,你也可以修改函数名,用更有实际意义字符串代替。

C. 在Installation Designer/Behavior and Logic/Custom Actions and Sequences视图中,选中顶端的Custom Actions点击鼠标右键选择“Custom Action Wizard”(这里的Custom Action我们经常也简称为CA),下面按着向导逐步说明。

  1.  第一个界面是Custom Action Wizard欢迎界面。
  2. 在第二个Basic Information界面中,选择CA的Name,而Comment可忽略。
  3. 在第三个Action Type界面中,在Type的下拉菜单中选择Run InstallScript Code。(这里你会发现你可以通过CA调用托管代码,其他可执行程序,以及JScript,VBScript等)
  4. 在第四个Action Parameters界面中,在Source的下拉菜单选择的MyFunction。(如果脚本Setup.rul中你有多个函数声明,你会发现都会显示到下拉菜单中)
  5. 之后的界面都按照默认设置,直到点击Finish结束。

D. 在同一树状结构中,Sequences/Installation/Execute,选中Execute点击鼠标右键选择Insert,你会看到在C中你添加的CA,选中你的CA,然后设置Condition。(注意如果是想在安装时执行:Not Installed;如果是卸载执行:Installed)

E. 有关我们的CA在Sequence中的位置, 可根据情况调整位置。

CA可以在Sequence中被调用,也可以在各个Dialog中被调用执行。

installscript 工程学习 一些知识点的解答

怒了啊。。。 刚才编辑了那么多,结果一个误点,就把所有的东西都弄没了。。。我勒个。。。。。

好吧好吧好吧,,我重新写,我重新写。。。

以前没有做过 installscript工程的项目,只做过Basic MSI工程的,所以好多难点都要自己重新来找解决方案。下面就一一分享一下我的成果。

1. installscript 如何判断当前为哪种安装语言?

主要是没有找,用正宗的方法怎么去判断,而是自己想出来的一个方法,不过还是很管用的,首先,a.在string editor里面添加一个string  ID_STRING_LANGUAGE, b.然后在英文的里面输入 1033,中文里面输入2052,c.最后在installscript 中引用 @ID_STRING_LANGUAGE字符串,然后做什么操作就看你的需求了。

2. installscript 双语安装包如何在中英文安装下出现不同的license内容。

我们第一想到的就是加载不同的文件喽~~ 嗯,你猜对了,确实应该加载不同的文件,其实我首先想到的是去 dialog里面寻找license的对话框,然后在相应控件上加载相应的 rtf文件,结果验证是出现乱码的。。。。 然后我就想,应该在代码里面写,然后又去代码里面OnFirstUIBefore 下的 Dlg_SdLicense2 里面的 szLicenseFile 这个的值根据语言变化而变化,加载的是rtf文件,但是发现还是有问题。 后来发现有rtf和txt两种文件。我尝试着把rtf改成了txt文件,结果真的可以了,表示不太懂这是为什么?有懂的可否解释一下???

3. installscript 快捷方式的创建???

创建普通的快捷方式,跟basic msi 一样,去System configuration下面的shortcuts进行创建,但是此快捷方式的icon和target只能从 安装目录下选择,Icon File 我是这样写的:<TARGETDIR>\XDict.exe 。 Target: <TARGETDIR>\XDict.exe。如果还有其他的需求,可以

对其他的设置进行修改。

现在说一下卸载的快捷方式,着实难了一下呢。

a. 可以 将UNINSTALL_STRING 里面的内容的前半部分的 setup.exe路径写到 Target下面。然后参数写 -unist。

b.  也可以自己制作卸载程序,但是其实自己制作卸载程序也是调用的上面的那个路径。制作卸载程序的方法,我接下来会放下载链接。(其实制作程序是借鉴的别人的,不是我自己写的。)

4. 如何修改安装程序的任务栏图标呢?

默认都是installshield的,这个真的很讨厌。找了好多资料,都没找到,最后是问的一个大侠。这个不能通过installshield来修改,只能自己写外部代码来改变,这个大侠用的c++的代码来修改的。在installscript里面进行修改。外部代码源文件以及实例文件,一会儿我会全部奉上。

5. 如何判断当前为卸载过程??

这个也着实难了一下,怎么判断呢?百度出来一个判断 UNINSTAL_STRING是否为空 ,结果试了一下,不管用。

后来我就测试script脚本里面的代码,貌似卸载的时候会走 OnMaintUIBefore 函数,里面有判断REMOVE的地方 —— Dlg_Start 下面。 大家可自行查找。

其实却是有标识当前状态为卸载状态的 :REMOVEALL。可以这样判断: if( REMOVEALL){}    嗯嗯,就是这样。

6. 如何使一个feature 必选呢?不能去掉??

这样来操作,创建一个空的feature,然后将其设置为 No visiable,然后将必选的那个feature的必须feature为空的那个feature,就这样就可以了。

7. 比如我安装过程中,又调用了其他的安装包,而且是静默安装,这时候肯定会卡死好长时间?怎么办??? 怎么让它不卡死,而且把进度条显示出来。

我的需求是,选择了某个feature,然后安装其中相对应的安装包,哦,有人说,你这个需求是怎么设置的?可以在feature设置里面的 feature event下面 有一个 OnInstalling,在其里面进行加载相应的函数。(自己可把安装安装包写在一个函数里面)。

然后在函数里面加载如下代码:SetStatusWindow( 20, @ID_STRING16 ); 前面的那个参数是显示进度条显示多少,设置20表示已经安装20%.   Enable(STATUSEX);    StatusUpdate( ON, 100 );   我的理解是 那个100应该是更新走到 100%。

示例代码下载处:  http://url.cn/RiRdX0

冰与火之歌第八季大结局剧透!!!

还记得GOT第七季的剧透吗?

截止目前西班牙泄露的第6集,是不是跟之前的剧透都一一对应了?

还是同样的黑客泄露,第八季大结局简直惨不忍睹。



 

前方高能

第八季简单剧情概要:

异鬼大军攻破临冬城继续南下,最终在鹰巢城被人类战胜。另一方面瑟曦和攸伦结婚后被杀,攸伦坐上铁王座,琼恩和詹姆等人不服率兵攻打君临。

—主要人物最终命运:

死亡角色:

布兰·史塔克:在异鬼大军攻占临冬城的战役中被异鬼杀死在神木林。

雷哥:在异鬼大军攻占临冬城的战役中雷哥由布兰控制作战,在布兰被杀后雷哥坠落被尸鬼所杀,死后尸体被卓耿火化因此没变成冰龙。

梅拉·黎德:在异鬼大军攻占临冬城的战役中为保护布兰而死。

霍兰·黎德:告知琼恩·雪诺他的真实身份之后在与异鬼的战斗中战死。

波德瑞克:在异鬼大军攻占临冬城的战役中战死。

托蒙德:在异鬼大军攻占临冬城的战役战死。

灰虫子:在异鬼大军攻占临冬城的战役战死。

莱安娜·莫尔蒙:在向熊岛转移的途中遇异鬼军队袭击死亡。

席恩·葛雷乔伊:在攸伦攻打派克岛的战斗中被攸伦杀死。

布蕾妮:在异鬼大军攻占鹰巢城的战役中被异鬼杀死。

冰龙韦塞里昂:在异鬼大军攻占鹰巢城的战役中被卓耿杀死并火化。

夜王:在异鬼大军攻占鹰巢城的战役中被卓耿杀死并火化。

瑟曦·兰尼斯特:和攸伦结婚后,攸伦买通千面神殿刺杀瑟曦,最终被假扮成科本艾莉亚·史塔克杀死。

科本:被艾莉亚·史塔克杀死

格雷果·克里冈:被桑铎·克里冈重伤等死。

丹妮莉丝·坦格利安:生下与琼恩·雪诺的女儿莱安娜·坦格利安后失血过多,恳求瓦里斯结束了她的生命,死后尸体被黄金团带到君临示众。

瓦里斯:在攸伦的黄金团攻陷龙石岛后被黄金团杀死。

梅丽珊卓:回到维斯特洛,想烧琼恩·雪诺和丹妮莉丝的孩子,琼恩·雪诺判死刑,经过自己请求后被龙焰烧死。

卓耿:在最终君临战斗中战斗中受重伤,最后喷出龙焰点君临地下的野火,被炸死,同时被炸死的有:攸伦·葛雷乔伊、詹姆·兰尼斯特、乔拉·莫尔蒙、桑铎·克里冈、琼恩·雪诺。

幸存角色:

莱安娜·坦格利安:丹妮莉丝和雪诺之女,七国女王。

提利昂·兰尼斯特:首相,辅佐莱安娜·坦格利安,同时掌管凯岩城。

弥桑黛:莱安娜·坦格利安监护人,与提利昂·兰尼斯特成了一对(是否结婚未知)。

艾莉亚·史塔克:雪诺死后心灰意冷和娜梅莉亚一起乘船离开维斯特洛再无音讯。

珊莎·史塔克:临冬城领主和谷地领主,与詹德利·拜拉席恩结婚。

詹德利·拜拉席恩:与珊莎·史塔克结婚,风息堡领主。

艾德慕·徒利:河间领主,他的其中一个儿子捡到了艾莉亚·史塔克的缝衣针,艾莉亚之前把剑丢掉了。

山姆威尔·塔利:河湾领主,和山姆的妈妈、小山姆以及吉莉住在一起,同时吉莉怀了山姆的孩子。

雅拉·葛雷乔伊:铁群领主。

波隆:娶了多恩领主,奥伯伦的某个女儿。

戴佛斯·席渥斯:得知雪诺死后和山姆说想回家找老婆去了之后就再无音讯。

—剧终彩蛋:

在极寒之地,布兰被一个异鬼复活成为新的夜王。


看了以上的剧透是不是感觉到炸裂???

下面是分剧情介绍哦!


来源:知乎

著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。

权力的游戏?S08 E05?泄露剧本

HBO LEAK

NOTE:这同样是个预印本,很多情节未必会和剧集播出时相同。

NOTE:时长100 min上下

第一个场景只有?R.Djawadi?的配乐,前?5 min?没有对话。

第一个镜头是谷地骑士在为大战做必要的准备,由詹姆、提利昂、艾德慕、波隆领军的兰尼斯特家族、徒利家族和史塔克家族的军队正向谷地进发。黄金团登上攸伦·葛雷乔伊的船只(起航前往龙石岛)。暴风雪侵来,约恩·罗伊斯命令谷地骑士备好龙晶长枪迎敌,罗宾·艾林在其侧共同作战。罗伊斯爵士对小罗宾指挥他的将士颇感不满,你几乎可以从他的脸色上看出这一点。在罗伊斯督促谷地备战时,尸鬼大军偏便已然攻入血门,罗宾·艾林试图对弓箭手下令,但弓箭手们没有听他的。在鹰巢城内我们会看见珊莎、詹德利和塔斯的布蕾妮,詹德利向珊莎告别随后就加入战斗,珊莎则告诉詹德利自己希望他能平安归来,詹德利则觉得自己很可能会战死沙场。布蕾妮也希望加入战斗而珊莎对此表示异议。,珊莎希望布蕾妮能待在她身边,但布蕾妮说尸鬼攻破鹰巢城之时,她将谁也保护不了。她曾发誓誓死保护珊莎,但此时最好的方法就是去守卫谷地的门户以阻止夜王的军队进攻鹰巢城。珊莎抱了抱布蕾妮,感谢她在一路上为史塔克家族的所作所为,随后布蕾妮便离开鹰巢城加入了战斗。下一个镜头是龙石岛,黄金团渡海来擒丹妮莉丝女王的消息传到了这里。丹妮命令她手下仅存的无垢者和多斯拉克骑兵抵御入侵,瓦里斯建议丹妮立刻逃离龙石岛,但他的建议未被采纳。丹妮察觉到自己的羊水已破,随时可能临盆,弥桑黛和山姆威尔则帮丹妮作必要的休息。山姆威尔忧心忡忡,因为丹妮的孩子随时都可能出生。三名异鬼在远处静静地看着亡者军团击溃谷地骑士,夜王骑御韦赛里昂高高在上俯视着这壮观的景象。韦赛里昂(在先前的战斗中)失去了一只眼并有一只翅膀受了重伤。布蕾妮拼死一战,罗宾·艾林被几只尸鬼围攻但他成功逃入鹰巢城。珊莎对罗宾说他曾经发誓要为子民而战,罗宾则说自己毫不关心他们的死活。布蕾妮、罗伊斯爵士和詹德利仍然在奋战,但胜利的天平正逐渐倾向亡灵那方。异鬼最终攻入鹰巢城,不死之龙的怒号响彻八方。独眼韦赛里昂飞临罗伊斯爵士和谷地骑士上空,喷出烈火将其化为灰烬。此时一声龙吟响起,琼恩·雪诺身骑卓耿驾临战场。琼恩协助谷地骑士撤出,身下是混乱中的兰尼斯特家族、徒利家族和北境的军士。许多尸鬼(在与维斯特洛的军队作战时)葬身卓耿的烈焰之下,但龙焰似乎并不能对异鬼造成伤害。波隆用两根龙晶长枪杀死了一名异鬼,布蕾妮独战一名异鬼落于下风并最终被冰刃击中下腹,目睹此景的詹姆变得疯狂并从背后摧毁了异鬼。詹姆抱着正在死去的布蕾妮悲伤得不能自已,布蕾妮希望詹姆能护珊莎和艾莉亚周全,一如自己向凯特琳夫人保证的那样。詹姆承诺说自己将会为她去保护那两个女孩,布蕾妮的最后遗言是她认为詹姆是个有荣誉感的人,说罢布蕾妮便在詹姆的怀中死去了。艾莉亚、猎狗和娜梅莉亚进入大雪纷飞的君临,猎狗说自己一点也不想念这臭烘烘的城市,艾莉亚同意他的看法。艾莉亚路过被炸毁的贝勒大圣堂时注意到君临相比她离开时早已截然不同,在这里她想起了父亲奈德·史塔克,她告诉猎狗是时候让兰尼斯特血债血偿了。丹妮莉丝开始分娩,山姆威尔和弥桑黛为她助产。瓦里斯目睹小股黄金团登陆,无垢者们则竭力阻止他们登上通往龙石岛宫殿的阶梯,多斯拉克人与黄金团在海岸上正面冲突。乔拉和部分北境军队也加入了保卫战,乔拉试图进入城堡去保护丹妮。由于艾德慕和提利昂的指挥若定,在鹰巢城的尸鬼大军随着时间流逝而逐渐减少,夜王不再骑在韦赛里昂背上而是试图与另一名异鬼进入鹰巢城,韦赛里昂则尝试攻击詹德利并向他喷吐火焰,詹德利将一柄龙晶长枪插入韦赛里昂口中。冰龙从血门的岩石上坠落在地,卓耿给了夜王和韦塞里昂最后一击并用龙焰将韦塞里昂的尸体点燃。乔拉撤入宫殿时发现丹妮正在生产,情况对丹妮似乎并不乐观,悲伤的山姆说母子不能同时幸存,他只能救一个。乔拉希望丹妮能活下来但丹妮不愿放弃孩子,之后丹妮成功诞下婴儿。山姆威尔告诉丹妮她生下了一个女孩并让丹妮为她取个名字,虚弱的丹妮给孩子取名为莱安娜,一如琼恩所愿。弥桑黛、瓦里斯和乔拉意识到丹妮的生命正在流失,黄金团则在战斗中取得上风并攻至宫殿外的阶梯,丹妮向乔拉告别并感谢他能一直陪伴在身边,乔拉则向丹妮表达爱意,丹妮请求乔拉能继续他的誓言并和弥桑黛一起保护自己的女儿。丹妮恳求乔拉能杀了自己结束痛苦,乔拉则说自己永远不会做那样的事。最后瓦里斯举起山姆的族剑碎心,一剑洞穿了丹妮的心脏。瑟曦和魔山在王座厅会见科本,科本将丹妮莉丝战败的消息告知瑟曦。瑟曦狂笑并为其胜利而痛饮,片刻之后瑟曦开始感到眩晕(这时观众应该都意识到了科本是艾莉亚假扮的,她用贾坤的毒药毒杀瑟曦),科本直视着瑟曦,瑟曦也意识到事情有怪。艾莉亚摘下面具、亮出身份,她呵斥瑟曦说即使是雄狮也不应与群狼为敌。瑟曦命令魔山杀死艾莉亚但艾莉亚告诉她那是无用之举,因为她带了娜梅莉亚和猎狗来解决魔山。娜梅莉亚将瑟曦咬成重伤而猎狗则与魔山战作一团,随后艾莉亚切开了瑟曦的喉咙,娜梅莉亚与猎狗则击败了魔山。魔山似乎不会死,他的头盔在战斗中掉下,猎狗抓住机会用火将点燃魔山的脸。猎狗、艾莉亚和娜梅莉亚离开红堡,留下魔山在那里孤独的等死。黄金团的团长迈进宫殿,他命令瓦里斯交出丹妮,瓦里斯告诉他丹妮已死。黄金团的团长将瓦里斯推开并捅死了他,随后他们找到了丹妮的尸体并将她带回君临献给瑟曦。山姆威尔则和丹妮的孩子、弥桑黛躲藏起来。黄金团撤出龙石岛,返航回到君临。攸伦回到君临发现瑟曦已死,但他假装为瑟曦之死而悲伤。琼恩·雪诺和珊莎·史塔克回到龙石岛却发现所有人都死了,山姆威尔在宫殿的阶梯上见到琼恩并将孩子交还给他。琼恩开始啜泣并问丹妮是否还活着,山姆将那悲伤的事实告诉了琼恩,他还告诉他丹妮为他们的女儿取名为莱安娜·坦格利安。此集最后一个镜头是葛雷乔伊家族的攸伦一世登基,是为七国国王。阵亡:罗伊斯爵士、塔斯的布蕾妮、罗宾·艾林、冰龙韦塞里昂、丹妮莉丝·坦格利安女王、夜王、科本、瑟曦·兰尼斯特女王、魔山和瓦里斯。

第5集集终。


权力的游戏?S08 E06?泄露剧本

HBO LEAK

NOTE:对于那些关心戴佛斯·席渥斯在第五集境遇的人而言——他在那一集中并不是关键角色,但他的确出现了而且和琼恩、詹姆以及詹德利等人并肩作战。他并未对主要的事件产生影响,但他确实在那一集中参与了战斗。

FINAL EPISODE:(最终集)注意这是预印本,很多情节可能会在实拍时改变。

时长:110 min?上下

第一场景发生在龙石岛,詹姆、波隆、詹德利、提利昂和戴佛斯爵士得胜归来,艾德慕应该是返回了奔流城。琼恩接待了众人并将丹妮的死讯告知他们,提利昂悲痛欲绝,随后他与琼恩在龙石岛的悬崖上有一段对话。提利昂告诉琼恩自己曾是那么信任丹妮,坚信她能将这该死的世界变得更好而现在他却只能放弃这个不切实际的梦想。提利昂问琼恩丹妮死于谁手。琼恩说丹妮因难产而死,尸体被黄金团带走献给瑟曦。然后提利昂问及孩子的情况,琼恩则回答说孩子一切安好。提利昂苦笑一番但他随后又看到一条葛雷乔伊的船靠上岛屿,琼恩和提利昂走向那条船,原来是雅拉·葛雷乔伊抵达了龙石岛。雅拉将自己逃出攸伦魔爪但失去了所有军队的事情告知两人,琼恩问她席恩的下落,雅拉回答说席恩在亡者军团袭来之前就已战死。下一个镜头是悬在君临城墙上的丹妮的尸体,君临的民众向丹妮的尸体扔掷粪便、嘲笑羞辱她的遗骸,猎狗和艾莉亚在附近的一个啤酒店里得知攸伦称王、君临即将遭到围攻的消息。艾莉亚想帮助琼恩、与他并肩而战但猎狗认为自己的事情已经解决了(想尽早离开),最终猎狗同意与艾莉亚留在君临助琼恩一臂之力。之后我们会看见攸伦·葛雷乔伊与黄金团的团长在王座厅交谈,他感谢黄金团将龙女王的尸首带来但他认为黄金团没能活捉她是他们的耻辱,攸伦说如果他们将她活着带来自己本会操她的(fucked her),但他们令他失望了。攸伦期望着自己对北境伪王琼恩·雪诺的审判早日到来,因为北方佬们将首先对君临发起进攻。攸伦命令新学士放出所有信鸦并要求各大王国的领主对其宣誓效忠,否则他威胁将用自己在君临的佣兵团一个一个将其摧毁。琼恩、詹姆、波隆、提利昂、乔拉、珊莎、詹德利、戴佛斯、弥桑黛、山姆威尔以及雅拉齐聚龙石岛的议事厅讨论如何应对来自攸伦的威胁,就是瑟曦惨死之后自立为王的攸伦。詹姆认为攸伦是杀死瑟曦的凶手并因此暴怒,雅拉同意詹姆的看法,戴佛斯则认为攸伦这个疯子不应统治七大王国,而他们应该聚集所有力量回击他。詹德利表达了自己对攸伦以及他夺走自己已遭灭门的拜拉席恩家族王位(或权位)的仇恨,提利昂和詹姆则想用兰尼斯特家族亲兵来攻击攸伦。提利昂同时认为他们应该说服效忠丹妮的人们为琼恩和丹妮的孩子而战,因而我们有北境军队、兰尼斯特军队、残存的多斯拉克人和无垢者以及卓耿为琼恩而战。山姆威尔再度提起琼恩的身世,但琼恩似乎不愿他人知道此事。琼恩再次清楚地声明自己的追求并非铁王座。戴佛斯爵士为琼恩担保,他告诉其他人琼恩是他们从攸伦的魔掌中救出黎民百姓最后的机会而且他相信琼恩将会成为一个真正的好国王。琼恩是他们唯一的希望。其他人同意戴佛斯的说法,琼恩最终接受了黄袍加身。龙石岛议事厅之后,琼恩与珊莎有过一段对话。珊莎对琼恩的身世感到疑惑并且她很难相信父亲自始至终都在欺骗整个家族,无论是对母亲凯特琳还是对琼恩。琼恩请求珊莎统治好北境和临冬城,因为她是临冬城的继承人。她答应了琼恩并告诉他自己早已准备好离开龙石岛了,两人拥抱彼此,之后分道扬镳。弥桑黛将红袍女再次来到龙石岛的消息告诉了琼恩,梅丽珊卓告诉琼恩自己已经准备好为自己的罪孽赎罪并打算向他揭露自己的真实身份。她说自己已经完成了使命,预言也已都应验。梅丽珊卓指出自己曾劝说丹妮将孩子献祭给光之王,戴佛斯则说自己曾发誓要处死她,詹德利也是如此想法。琼恩本打算绞死梅丽珊卓但红袍女则希望自己能死于烈火,因为那是最纯粹的死亡。红袍女被带往龙石岛外处决,最终如她所愿死于卓耿的龙焰之下。舰队从龙石岛出发前往黑水湾,提利昂、弥桑黛、戴佛斯、山姆威尔和小莱安娜则留守龙石岛。我们会看到乔拉、詹德利以及波隆的登舰镜头。琼恩恳请提利昂和弥桑黛照料好小莱安娜以防自己身遭不测,琼恩与山姆告别,感谢他能始终忠诚的陪在自己身边。攸伦伫立在君临的城墙上目迎坦格利安舰队而来,丹妮腐烂的尸体摇曳在下方。我们会发现琼恩身着坦格利安-史塔克双色战甲驾驭卓耿飞翔在蒙冲斗舰之上,攸伦则带来了按照他的命令重新设计的射龙毒蝎。兰尼斯特军队首先登陆并开始进攻,黄金团则守卫着君临的城墙。两名黄金团的团长骑着大象碾碎兰尼斯特士兵,北境的军队加入战斗协助兰尼斯特军,多斯拉克骑兵则从侧翼杀出。琼恩和卓耿加入战斗,卓耿连人带象一起焚化了黄金团的一名团长。垂死之象在火焰中挣扎并在死前杀死了几个不知名的士兵。雅拉挥舞着巨斧砍杀,詹德利甩动着重锤击碎敌军的头颅。攸伦命令手下人用毒蝎射杀巨龙,他共有三架巨弩,卓耿躲开了一箭但很快就被另外两箭击中双翼,卓耿迅速摔落地面。兰尼斯特军、史塔克军、多斯拉克人和无垢者最终突破了城门,琼恩则试图带着卓耿逃到龙穴(因为他注意到卓耿身受重伤、很难继续飞行)。艾莉亚看到卓耿飞向龙穴的同时猎狗加入詹姆、波隆、乔拉的战斗,詹德利和雅拉以为攸伦将会藏身红堡,所以他们准备一路拼杀到那儿。但实际上攸伦正在命令他的军队前往龙穴去处死琼恩·雪诺和他的那只野兽,波隆和詹姆发觉攸伦与黄金团一并前往龙穴并尾随他们。詹姆意识到琼恩正在极度危险之中,因为除他之外只有提利昂知道龙穴之下还埋藏着大量野火,如果卓耿在那里喷出龙焰,野火将摧毁整个龙穴和在那里的所有人和物。艾莉亚和娜梅莉亚进到龙穴时琼恩正在照看卓耿的伤势,琼恩试图将插在龙翼上的长箭拔出(但失败了)。琼恩尽管对见到艾莉亚非常惊奇但他随后要求艾莉亚立刻离开君临,艾莉亚一开始并不想离开,暗示琼恩自己想与他一起战斗。艾莉亚拍了拍卓耿并说自己小时候总是梦想着像传说中的坦格利安勇士那样驭龙飞翔,琼恩微微一笑但他随后强烈地劝阻艾莉亚让她离开,因为他们正身处险境。艾莉亚最终听取了琼恩的劝告,两人拥抱告别。艾莉亚对离开琼恩很是失望沮丧。雅拉和詹德利杀入红堡却发现攸伦早已逃往龙穴,雅拉为此非常恼怒,因为她迫切想亲手结果了叔叔。攸伦和黄金团冲进龙穴,攸伦和琼恩一对一单挑。詹姆、猎狗、乔拉以及一小股兰尼斯特士兵冲入龙穴企图救出琼恩,波隆不愿冒险并待在原地。詹姆从背后捅伤了攸伦,当时攸伦几乎杀死琼恩·雪诺,攸伦受了致命伤。詹姆尝试将琼恩带离龙穴,乔拉和猎狗则与剩余的佣兵战斗为琼恩平安离开扫清障碍。黄金团的佣兵们向卓耿投掷长枪,卓耿垂死挣扎。突然,卓耿毫无预兆地释放烈焰,龙穴开始震动,詹姆意识到卓耿的火焰点燃了深埋地下的野火,他喝令琼恩快跑逃生。受了致死伤的攸伦狂笑,告诉所有人今日他们都将惨死于此。野火在琼恩、猎狗、詹姆和乔拉逃离之前炸飞了龙穴,无人幸存。雅拉和詹德利在远处惊恐地望着野火的爆炸,民众则在更多野火被点燃之前加速逃离君临。下一个镜头是龙石岛,提利昂看见几艘坦格利安战船逃回到这里。雅拉和詹德利将君临的野火爆炸,琼恩、哥哥詹姆以及乔拉未能生还的消息告诉了提利昂、戴佛斯、山姆威尔和弥桑黛。提利昂听到消息时彻底崩溃,而戴佛斯和山姆听闻琼恩的死讯后同样如此。山姆威尔和戴佛斯进行了短暂的交谈,山姆询问戴佛斯日后的打算,戴佛斯则说自己可能会回到自己离开太久的妻子身边。山姆笑了笑,说自己同样如此。我们接下来会看到艾莉亚和娜梅莉亚准备登船的镜头。艾莉亚告诉船长自己已与维斯特洛毫无瓜葛,当船长问一个女孩和一匹狼离开平和的维斯特洛到厄斯索斯做什么时,艾莉亚答道:“Valar Morghulis.”我们目送艾莉亚乘船东去,我们再看到众人已经是三年以后了。下一个镜头是山姆正在教小山姆读书识字,吉莉·塔利女士,这就是她现在的名字,现在是河湾王国的女主。山姆的母亲、妹妹塔拉和吉莉交谈着分享彼此的爱,山姆来到女士们之间询问她们在说些什么,但山姆的母亲笑说这是女生之间的私密话。最后一个镜头是山姆和吉莉,吉莉告诉山姆一个好消息——她怀了他的孩子,山姆得知自己与吉莉有了一个孩子开心得不知所以,他告诉吉莉自己将永远视小山姆为长子,而他也将有一天会从自己手中继承河湾王国。再下一个镜头则带我们来到了临冬城,我们看到珊莎夫人和詹德利公爵在一起。珊莎与詹德利、艾德慕和萝斯琳看着自己的孩子们彼此嬉戏打闹、训练拳脚。艾德慕仍为奔流城公爵。珊莎注意到艾德慕的一个孩子腰上带着艾莉亚的佩剑缝衣针,她问艾德慕是如何找回那柄剑的。艾德慕答说是自己的儿子威廉在打猎途中从丛林中找到的,他问珊莎艾莉亚是否还活着,珊莎回答说她大概还活着吧。毕竟,艾莉亚总能绝处逢生。珊莎和詹德利下到临冬城的地窖里,琼恩的雕像矗立于斯。詹德利问珊莎琼恩是否属于这里,珊莎说这就是他真正的归宿,埋葬于他真正的父亲奈德和兄弟身边。詹德利开玩笑说他实际上甚至都不叫“琼恩”,珊莎则答说对她而言他永远是琼恩·雪诺。珊莎说自己同时身为临冬城夫人和谷地女主有很多事要做并问詹德利将打算怎么处置已成空城的风息堡,詹德利则说自己很快就会着手处理这件事了,因为他现在已被摄政王合法化为一个真正的拜拉席恩。之后我们将会看到摄政王、莱安娜·坦格利安女王的女王之手提利昂·兰尼斯特,提利昂正看着弥桑黛为莱安娜读睡前故事,那是蕾妮斯和维桑尼亚·坦格利安的传说。莱安娜问弥桑黛自己的妈妈是否也曾驾驭巨龙,弥桑黛回答说丹妮莉丝就是那么一个无畏的勇士。下一个镜头是提利昂和弥桑黛两人共枕而眠,他们说着有关莱安娜的事情。莱安娜并不是一个好相处的孩子,但提利昂开玩笑说她将很好地传递坦格利安家族的香火。(这里理解成莱安娜生育能力极佳似较为妥当)弥桑黛大笑说作为琼恩和丹妮莉丝的孩子,提利昂就不要指望莱安娜这个了。提利昂夸赞弥桑黛在莱安娜的教育中发挥了极好的作用,之后两人便鱼水缠绵、共享云雨之乐。最后一个场景是提利昂和莱安娜站在巨幅的维斯特洛地图前,提利昂告诉莱安娜终有一日她将真正的君临七国。他向莱安娜解释七国的情况,北境和谷地正在珊莎·史塔克夫人的治下,她是史塔克家族仅存的后人而且她嫁给了风暴地的领主詹德利·拜拉席恩公爵;河间地由奔流城公爵艾德慕·塔利统治,而空荡荡的凯岩城则掌握在提利昂手中;蓝道·塔利之子山姆威尔·塔利公爵统领着河湾王国,雅拉·葛雷乔伊则手握铁群岛大权。莱安娜问及多恩,提利昂则回答说多恩领的领袖是红毒蛇奥柏伦·马泰尔的一个私生女,而她则嫁给了一个总是梦想着能有一个庄严华美的宫殿作屋、一位高贵美丽的女士为妻的男人,现在这个男人美梦成真了。提利昂和莱安娜并肩走向铁王座,提利昂警告莱安娜权力的游戏不是小孩子玩的把戏,涉身其中总要付出代价。当然,提利昂向莱安娜保证她将永远不会在权力的游戏中孤军奋战,因为自己会永远在她身边。最后,莱安娜和提利昂一起凝望着铁王座,目光久久不移。结束的镜头将我们拉往极北的永冬之地,一个异鬼骑马而过带着布兰·史塔克的尸体前往祭坛。异鬼按照特定的仪式将一片龙晶刺入布兰的胸膛,布兰睁开了眼睛,双眼闪着幽蓝的光芒。异鬼将一顶王冠戴在布兰头上,祭坛渐渐被冰霜覆盖。凛冬将至……


这个剧透是知乎上翻译的黑客泄露剧本,也就是跟泄露的第七季剧透是一样的出处,相信看过第七季剧透的都知道准到什么程度吧。

现在的悬念就是本来第八季的后几集剧本也不是最终定稿,再加上泄露,可能会有怎样的调整(但结局走向应该是跟作者靠好了的)。

如果维持这个结局的话真tm的太虐了!!!!

C# WPF 中用代码模拟鼠标和键盘的操作

原文地址
C#开发者都知道,在Winform开发中,SendKeys类提供的方法是很实用的。但是可惜的是,在WPF中不能使用这个方法了。
我们知道,在WPF中非UI线程刷新UI线程,需要使用Dispatcher.Invoke((Action)delegate { /* Your
code is put here */ });
方法。这里调用System.Windows.Forms.SendKeys.Send()方法会报错。

下面这个代码文件做了一个很好的包装,可以下载后参考:
Simulation.zip

如何使用呢?
很简单, 要敲一个键, 比如回车:
Keyboard.Press(Key.Enter);
Keyboard.Release(Key.Enter);

要敲一个组合键:比如Alt+F4:
Keyboard.Press(Key.LeftAlt);
Keyboard.Press(Key.F4);
Keyboard.Release(Key.LeftAlt);
Keyboard.Release(Key.F4);

要敲一段文字:
Keyboard.Type(“notepad”);

鼠标与之类似,比如:
Mouse.MoveTo(new System.Drawing.Point(x, y));
Mouse.Click(MouseButton.Right);

Simulation类的定义如下:

//定义是这样的:

[DllImport("user32.dll", SetLastError = true)]
internal static extern int SendInput(int nInputs, ref INPUT mi, int cbSize);

//其中的INPUT结构表示一个键盘或鼠标操作:

[StructLayout(LayoutKind.Sequential)]
internal struct INPUT
{
internal int type;
internal INPUTUNION union;
};
[StructLayout(LayoutKind.Explicit)]
internal struct INPUTUNION
{
[FieldOffset(0)]
internal MOUSEINPUT mouseInput;
[FieldOffset(0)]
internal KEYBDINPUT keyboardInput;
};
[StructLayout(LayoutKind.Sequential)]
internal struct MOUSEINPUT
{
internal int dx;
internal int dy;
internal int mouseData;
internal int dwFlags;
internal int time;
internal IntPtr dwExtraInfo;
};
[StructLayout(LayoutKind.Sequential)]
internal struct KEYBDINPUT
{
internal short wVk;
internal short wScan;
internal int dwFlags;
internal int time;
internal IntPtr dwExtraInfo;
};
[Flags]
internal enum SendMouseInputFlags
{
Move = 0x0001,
LeftDown = 0x0002,
LeftUp = 0x0004,
RightDown = 0x0008,
RightUp = 0x0010,
MiddleDown = 0x0020,
MiddleUp = 0x0040,
XDown = 0x0080,
XUp = 0x0100,
Wheel = 0x0800,
Absolute = 0x8000,
};

WPF DocumentViewer隐藏工具栏和搜索栏

<Style x:Key=”{x:Type DocumentViewer}” TargetType=”{x:Type DocumentViewer}”>

<Setter Property=”Foreground” Value=”{DynamicResource {x:Static SystemColors.WindowTextBrushKey}}” />

<Setter Property=”Background” Value=”{DynamicResource {x:Static SystemColors.ControlBrushKey}}” />

<Setter Property=”FocusVisualStyle” Value=”{x:Null}” />

<Setter Property=”Template”>

<Setter.Value>

<ControlTemplate TargetType=”{x:Type DocumentViewer}”>

<Border BorderThickness=”{TemplateBinding BorderThickness}” BorderBrush=”{TemplateBinding BorderBrush}” Focusable=”False”>

<Grid KeyboardNavigation.TabNavigation=”Local”>

<Grid.Background>

<SolidColorBrush Color=”{DynamicResource ControlLightColor}” />

</Grid.Background>

<Grid.RowDefinitions>

<RowDefinition Height=”Auto” />

<RowDefinition Height=”*” />

<RowDefinition Height=”Auto” />

</Grid.RowDefinitions>

<ScrollViewer Grid.Row=”1″ CanContentScroll=”true” HorizontalScrollBarVisibility=”Auto” x:Name=”PART_ContentHost” IsTabStop=”true”>

<ScrollViewer.Background>

<LinearGradientBrush EndPoint=”0.5,1″ StartPoint=”0.5,0″>

<GradientStop Color=”{DynamicResource ControlLightColor}” Offset=”0″ />

<GradientStop Color=”{DynamicResource ControlMediumColor}” Offset=”1″ />

</LinearGradientBrush>

</ScrollViewer.Background>

</ScrollViewer>

</Grid>

</Border>

</ControlTemplate>

</Setter.Value>

</Setter>

</Style>

Installshield 打包安装程序时写入注册表,及运行bat文件

一、写入注册表

1. 打开project assistant –> Project Registry

可以像注册表里一样操作,其中[INSTALLDIR]是指的安装路径

 

二、 运行bat文件

网上很多介绍如何运行bat的方法,但我这个是limted 版本,不适用。

1. 打开 Define Setup Requirements and Actions –> Custom Actions

2. 右健 After Register Product –> New Exe

installshield中如何执行批处理 还有设置环境变量

如何执行批处理

 

我们可以在事件中使用方法 来执行  installshield提供了该方法LaunchAppAndWait 来调用应用程序

 

 

//执行卸载脚本
function ExecuteUnstall()
string cmdline;
begin
if(AskYesNo(“您确定要卸载吗”,YES)=NO)  then
abort;
endif;
cmdline=”cmd /c /””+TARGETDIR+”//tools//uninstall.bat/””;
if (LaunchAppAndWait (“”,cmdline, WAIT) < 0) then
MessageBox (“Unable to launch cmd “^cmdline^”.”,SEVERE);
endif;

end;

 

 

设计环境变量  环境变量 可以从注册表中设置

用户变量的位置是 :HKEY_CURRENT_USER/Environment

系统变量的位置是:HKEY_LOCAL_MACHINE/SYSTEM/CurrentControlSet/Control/Session Manager/Environment

 

function SetEnvironment()
begin
RegDBSetDefaultRoot (HKEY_CURRENT_USER);
RegDBSetKeyValueEx (“Environment” , “JAVA_HOME” , REGDB_STRING_EXPAND , TARGETDIR+”//Java” , -1);
RegDBSetKeyValueEx (“Environment” , “CATALINA_HOME” , REGDB_STRING_EXPAND ,TARGETDIR+”//tomcat” , -1);
RegDBSetKeyValueEx (“Environment” ,”JRE_HOME” , REGDB_STRING_EXPAND ,TARGETDIR+”//Java//jre1.5.0_18″ , -1);

//这个地方nzType千万不要直接用 REGDB_STRING    否则会编译出错 日
//if (RegDBGetKeyValueEx (szKey, “Path”, nzType, svOld, nsize) < 0) then
//        MessageBox (“RegDBGetKeyValueEx failed.”, SEVERE);
//        abort;
//endif;
// svNew=svOld+”;”+TARGETDIR+”//Java//bin”;
//RegDBSetKeyValueEx (“Environment” , “Path” , REGDB_STRING ,svNew , -1);

end;

C#实现软件注册码算法

Microsoft.NET的应用程序的代码文件,与Java生成的文件类似,它们都没有本地代码,而是一种类似于汇编的代码。这样,只要有合适的工具,就可以完整的把别人写出来的程序反编译成自己需要的程序文件。

我所知道的.Net下的反汇编程序是Salamander 和 Refelector两个工具,他们都可以对.Net的程序集反编译成你需要的语言。

那么,我们写的程序,做的项目,如何进行正版的许可证管理,有许多方法。

最好的方案,是几个方法的综合。下面我说一下单独的许可验证方法。

最简单的方法,就是使用许可存储。方法是用户输入正版的注册码,通过程序中专门的算法程序进行验算,得出的结果与事先保存在程序中的结果比对,比对一致表示输入正确。然后把结果保存在存储中,如注册表或者专门的许可文件中,程序许可通过。

这个方法使用的人/公司最多,但是缺点也是最多的,只要使用上面的工具把验算注册码的算法给弄清楚,就可以自己写一个生成序列号的注册机,这个注册方法就形同虚设了。

还有一个比较好的方法,就是仿照WindowsXP的激活机制,客户的程序自动访问互联网的一个专门设定的服务器,通过Tcp/Ip或者WebService远程访问服务器上的许可程序,许可后把结果保存在客户端计算机上。这个方法的好处是许可验证代码保存在开发者控制的计算机上,客户端无法获取验证算法,而且可以通过数据库管理用户,非常方便。

但是这个方法也有缺点,首先是可靠的Internet连接。如果要防止用户使用盗版,则必须在客户端的程序中添加一个随机访问远程许可服务器验证的功能,这样不但需要一个24小时的Internet连接,而且经常进行验证也会干扰程序的正常运行。还有就是如果有人通过研究客户端的接收返回信息的代码,弄一个虚拟的验证服务器,这个功能也会完蛋。

那么,所有的焦点都聚集在客户端的验证算法上,只要这个客户端的验证算法被人弄清楚了,整个程序的许可可以说就不存在了,所以许多开发者/开发公司费好大的力气,弄一个足够复杂的验证算法出来,用算法的复杂度来抵抗破解。但是再复杂的算法,只要有人写得出来,就有人能破解得出来,这个道理我想大家都明白。

那是否有加密算法与解密算法不同的办法呢?有。而且.Net自带的类库里面就有这个算法。
这个算法的原理是不对称加密的原理。不对称加密原理大家基本上都了解。加密的密码(密钥)分为两个部分,公钥和私钥。通过私钥加密的密文只能通过公钥解密。根据这个特性,我们可以发现只要开发者保存好私钥,即使算法代码被客户端破解,因客户端不知道保存在开发者处的私钥,也无法生成注册码。

这个算法就是 System.Security.Cryptography 名称空间的RSAPKCS1SignatureFormatter 类(用来生成注册码)和 RSAPKCS1SignatureDeformatter类(用来在客户端验证注册码)。验证过程如下:
首先,需要生成一个公钥和私钥对,当然,依靠人是无法生成的,我们可以通过 System.Security.Cryptography名称空间的RSACryptoServiceProvider 类来生成公钥/私钥对。

using(RSACryptoServiceProvider rsa = new RSACryptoServiceProvider())
{
// 公钥
stringpubkey =rsa.ToXmlString(false);
// 私钥
stringprikey =rsa.ToXmlString(true);
}

获取私钥以后,可以用 RSAPKCS1SignatureFormatter 类来生成注册码,代码如下(引用名称空间略)

using(RSACryptoServiceProvider rsa = new RSACryptoServiceProvider())
{
rsa.FromXmlString(prikey);;
//加密对象
RSAPKCS1SignatureFormatter f = new RSAPKCS1SignatureFormatter(rsa);
  f.SetHashAlgorithm("SHA1");
byte[] source =System.Text.ASCIIEncoding.ASCII.GetBytes(txtIn.Text);
SHA1Managed sha= new SHA1Managed();
byte[] result =sha.ComputeHash(source);
byte[] b =f.CreateSignature(result);
11 msg.Text =Convert.ToBase64String(b);
}

上面的代码是一个示例aspx页面的代码,页面包括一个id为msg的Label控件,一个ID为txtIn的TextBox控件,一个ID为btnOK的Button控件,上面的代码就是btnOK的事件处理程序的内容。大家可以非常清楚的看出处理流程,生成一个RsaCryptoServiceProvider类实例,然后把这个类实例的加密密钥指定为包含私钥的prikey字符串因为加密解密的公钥/私钥必须是对应的。然后获取txtIn输入的内容,生成密钥后在msg控件上显示。

下面是使用 RSAPKCS1SignatureDeformatter 类来验证输入: 

using(RSACryptoServiceProvider rsa = new RSACryptoServiceProvider())
{
  rsa.FromXmlString(pubkey);
  RSAPKCS1SignatureDeformatter f = new RSAPKCS1SignatureDeformatter(rsa);
  f.SetHashAlgorithm("SHA1");
  byte[] key =Convert.FromBase64String(txtKey.Text);
   SHA1Managed sha= new SHA1Managed();
  byte[] name =sha.ComputeHash(ASCIIEncoding.ASCII.GetBytes(txtIn.Text));
  if(f.VerifySignature(name,key))
   msg.Text ="验证成功";
  else
   msg.Text ="不成功";
}

上面的代码也很好理解,就是多了一个ID为txtKey的TextBox控件,他通过同时获取用户名/加密密钥来进行验证。重点是RSA类的FromXmlString()方法,注意上面的这个方法获取的是公钥,表示这段验证代码是保存在客户端的,客户端代码是没有私钥的,即使有人把程序集的代码反编译了也没有用。

上面两段代码需要注意的就是生成的公钥/私钥必须匹配,我使用RSA对象生成密钥对后保存成为字符串常量,就可以解决这个问题。

上面这个方法仍然无法解决客户使用ildasm反编译后暴力修改IL代码,只有靠可靠的强名称以及数字证书来保证程序集不被修改了。

关于 WPF PrintDialog 设置打印纸张高度与宽度问题。

    • 问题如下:

      我通过WPF进行打印,WPF中PrintDialog默认纸张大小应该是A4,宽度是700多左右,高度是1000多。当我想要在X轴1000的位置打印文字时,总是打印不出来。因此我想通过设置打印纸张的大小来让X轴1000处的文字打印出来。代码如下。设置PageMediaSize为 ISOA0,应该是3000*4000多。但是我还是无法将X轴1000处的文字打印出来。网上搜了很久无果。因此在这里提问。希望能解决这个问题。代码如下。

      private void button_SinglePointPrint_Click(object sender, RoutedEventArgs e)
      {
      PrintDialog pDialog = new PrintDialog();
      pDialog.PrintTicket = pt;
      pDialog.PrintQueue = pq;
      pDialog.PrintTicket.PageMediaSize = new PageMediaSize(PageMediaSizeName.ISOA0);
      if (pDialog.ShowDialog() == true)
      {
      pt = pDialog.PrintTicket;
      pq = pDialog.PrintQueue;

      DrawingVisual vis = new DrawingVisual();
      DrawingContext dc = vis.RenderOpen();

      dc.DrawText(pLib.GetFormattedText(textBox_SinglePointText.Text, TextAlignment.Center, new Typeface(fontName), fontSize), new Point(1000,100));
      dc.Close();

      pDialog.PrintVisual(vis, “TestSinglePoint”);
      }
      }

      2014年4月21日 15:38
      kouxuelong 的头像

      0 分数

答案

  • 你好,

    你可以通过设置PrintTicket.PageMediaSizeSize,然后Transform你的窗体大小。请查看下面代码:

     private void _print()
     {
          PrintDialog printDlg = new System.Windows.Controls.PrintDialog();
    
           PrintTicket pt = printDlg.PrintTicket;
           Double printableWidth = pt.PageMediaSize.Width.Value;
           Double printableHeight = pt.PageMediaSize.Height.Value;
    
           Double xScale = (printableWidth - xMargin * 2) / printableWidth;
           Double yScale = (printableHeight - yMargin * 2) / printableHeight;
    
           this.Transform = new MatrixTransform(xScale, 0, 0, yScale, xMargin, yMargin);
    
        //now print the visual to printer to fit on the one page.
         printDlg.PrintVisual(this, "Print Page");
     }

    谢谢!

WPF的DataGrid单元格回车往右拐的方法

最后一个可编辑的单元格按下回车时增加一行个人感觉太繁琐了点  最好是直接给Grid加一行 而不是给对应的集合加一行 寻求更好的解决方案

/// <summary>
/// Grid最后一列加行和往右拐
/// </summary>
/// <typeparam name=”Tresult”></typeparam>
/// <param name=”dataGrid”></param>
/// <param name=”sender”></param>
/// <param name=”e”></param>
/// <param name=”li”></param>
public static void Grid_Right<Tresult>(this DataGrid dataGrid, object sender, KeyEventArgs e) where Tresult : class, new()
{
var uie = e.OriginalSource as UIElement;
if (e.Key == Key.Enter)
{
e.Handled = true;
uie.MoveFocus(new TraversalRequest(FocusNavigationDirection.Next));
dataGrid.BeginEdit();
if (dataGrid.CurrentColumn != null)
{
if (dataGrid.CurrentColumn.IsReadOnly == true)
{

for (int b = dataGrid.CurrentColumn.DisplayIndex; b < dataGrid.Columns.Count; b++)
{
for (int k = 0; k < dataGrid.Columns.Count; k++)
{
if (dataGrid.Columns[k].DisplayIndex == b)
{
if (dataGrid.Columns[k].IsReadOnly == false && dataGrid.Columns[k].Visibility == Visibility.Visible)
{
dataGrid.CurrentColumn = dataGrid.Columns[k];
dataGrid.SelectedItem = dataGrid.CurrentItem;
dataGrid.BeginEdit();
return;
}
else if (k == dataGrid.Columns.Count – 1 && (dataGrid.Columns[k].IsReadOnly == true || dataGrid.Columns[k].Visibility == Visibility.Hidden))
{
if (dataGrid.SelectedIndex != dataGrid.Items.Count – 1)
{
dataGrid.SelectedIndex = dataGrid.SelectedIndex + 1;
dataGrid.CurrentColumn = dataGrid.Columns[0];
dataGrid.CurrentItem = dataGrid.SelectedItem;
b = 0;
}
else
{
//PropertyInfo p = dataGrid.CurrentItem.GetType();
ModelObservableCollection<Tresult> li = dataGrid.ItemsSource as ModelObservableCollection<Tresult>;
li.Insert(dataGrid.SelectedIndex + 1, new Tresult());
dataGrid.SelectedIndex = dataGrid.SelectedIndex + 1;
dataGrid.CurrentColumn = dataGrid.Columns[0];
dataGrid.CurrentItem = dataGrid.SelectedItem;
b = 0;
}

}
}
}

}
}
}
}
}

WPF小知识,MessageBox的多种用法

我们在程序中经常会用到MessageBox。

现将其常见用法总结如下:

1.MessageBox.Show(“Hello~~~~”);

最简单的,只显示提示信息。

2.MessageBox.Show(“There are something wrong!”,”ERROR”);

可以给消息框加上标题。

3.if (MessageBox.Show(“Delete this user?”, “Confirm Message”, MessageBoxButtons.OKCancel) == DialogResult.OK)

{

//delete

}

询问是否删除时会用到这个。

4.if (MessageBox.Show(“Delete this user?”, “Confirm Message”, MessageBoxButtons.OKCancel,MessageBoxIcon.Question) == DialogResult.OK)

{

//delete

}

可以给MessageBox加上一个Icon,.net提供常见的Icon共选择。

5.if (MessageBox.Show(“Delete this user?”, “Confirm Message”, MessageBoxButtons.OKCancel, MessageBoxIcon.Question,MessageBoxDefaultButton.Button2) == DialogResult.OK)

{

//delete

}

可以改变MessageBox的默认焦点,如下:

6.if (MessageBox.Show(“Delete this user?”, “Confirm Message”, MessageBoxButtons.OKCancel, MessageBoxIcon.Question,MessageBoxDefaultButton.Button2,MessageBoxOptions.RtlReading) == DialogResult.OK)

{

//delete

}

反向显示:

7.if (MessageBox.Show(“Delete this user?”, “Confirm Message”, MessageBoxButtons.OKCancel, MessageBoxIcon.Question, MessageBoxDefaultButton.Button2, MessageBoxOptions.RightAlign,true) == DialogResult.OK)

{

//delete

}

添加Help按钮:

8.if (MessageBox.Show(“Delete this user?”, “Confirm Message”, MessageBoxButtons.OKCancel, MessageBoxIcon.Question, MessageBoxDefaultButton.Button1, MessageBoxOptions.RtlReading, @”/folder/file.htm”) == DialogResult.OK)

{

//delete

}

指定帮助文件的路径,点击即可打开该路径下的帮助文件。

9.//HelpNavigator指定常数来指示要显示的帮助文件元素。Find 帮助文件将打开到搜索页。

if (MessageBox.Show(“Delete this user?”, “Confirm Message”, MessageBoxButtons.OKCancel, MessageBoxIcon.Question, MessageBoxDefaultButton.Button1, MessageBoxOptions.RtlReading, @”/folder/file.htm”, HelpNavigator.Find) == DialogResult.OK)

{

//delete

}

还有一些用法,不是太实用这里就不一一介绍了,有兴趣的朋友可以参考下这里:MSDN的MessageBox类。

========================================================================
【函数】 <整型> MessageBox(<字符串> Text, <字符串> Title, <整型> nType,MessageBoxIcon);
【函数说明】 弹出一个消息框。
【语法】
参数:
Text <字符串>,消息框的正文;
Title <字符串>,消息框的标题;
nType <整型>,消息框的类型。
返回值:<整型>,用户在消息框上点击关闭时的选择的按钮。 MessageBoxIcon:对话框上显示的图标样式。

【说明】
MessageBox(“消息内容”, “返回值 确定1”,MessageBoxButtons.OK,MessageBoxIcon.Question);
MessageBox(“消息内容”,, “返回值 确定1 取消2”,MessageBoxButtons.OKCancel, MessageBoxIcon.Asterisk);
MessageBox(“消息内容”, “返回值 终止3 重试4 忽略5”,MessageBoxButtons.AbortRetryIgnore, MessageBoxIcon.Error);
MessageBox(“消息内容”, “返回值 是6 否7 取消2”,MessageBoxButtons.YesNoCancel, MessageBoxIcon.Exclamation);
MessageBox(“消息内容”, “返回值 是6 否7”,MessageBoxButtons.YesNo, MessageBoxIcon.Hand);
MessageBox(“消息内容”, “返回值 重试4 取消2”,MessageBoxButtons.RetryCancel, MessageBoxIcon.Information);

MessageBoxIcon: 所有图标样式

MessageBoxIcon.Question MessageBoxIcon.Asterisk MessageBoxIcon.Information MessageBoxIcon.Error MessageBoxIcon.Stop MessageBoxIcon.Hand MessageBoxIcon.Exclamation MessageBoxIcon.Warning MessageBoxIcon.None

MessageBox函数MessageBox()函数MessageBox是标准的windows Api函数只能在CWnd类的继承类中使用,在C#中使用时,通常用MessageBox的show方法来实现对话框的弹出,命名空间System.Windows.Forms

应用实例:

DialogResult 是枚举类可以用枚举值直接比较MessageBox的返回值也可以转换为整型后再比较。如下:DialogResult r1 = MessageBox.Show ( “是否确定?” , “垃圾处理!” , MessageBoxButtons.AbortRetryIgnore , MessageBoxIcon.Question ) ;
int ss1=(int)r1 ;
if ( ss1==3 ){ }
if ( ss1==4 ){ }
if ( ss1==5){ }

或者是

if (DialogResult.Yes == MessageBox.Show(“232”, “”, MessageBoxButtons.YesNo, MessageBoxIcon.Information,MessageBoxDefaultButton.Button1))
{
MessageBox.Show(“122”);
}

WPF有一个 button, button 的背景是一张图片, 当我运行程序后, 点击button的时候, button会有按下的效果,但同时 背景图片也消失了, 等松开鼠标的时候,背景图片又回来了,

回复次数:4

WPF自定义控件与样式(1) – 图标字体

一、图标字体

阿里巴巴开源字体网址:http://www.iconfont.cn/

使用方法:

       1、新浪微博账号登录

       2、点击图标 -> “添加入库”

       3、库->下载代码

界面如下:

      

4、下载的代码中的 *.ttf 文件,在WPF中用

文件如下:

 

二、WPF 中使用图标字体

1、iconfont.ttf 添加到Resources文件夹

iconfont.ttf属性如下:

2、XAML代码

<Window x:Class=”WpfApplication2.MainWindow”
xmlns=”http://schemas.microsoft.com/winfx/2006/xaml/presentation”
xmlns:x=”http://schemas.microsoft.com/winfx/2006/xaml”
Title=”MainWindow” Height=”350″ Width=”525″>
<Window.Resources>
<Style x:Key=”FIcon” TargetType=”TextBlock”>
<Setter Property=”FontFamily” Value=”/程序集名称;component/Resources/#iconfont”></Setter>
<Setter Property=”Foreground” Value=”Green”></Setter>
<Setter Property=”TextAlignment” Value=”Center”/>
<Setter Property=”HorizontalAlignment” Value=”Center”/>
<Setter Property=”VerticalAlignment” Value=”Center”/>
<Setter Property=”FontSize” Value=”20″/>
</Style>
</Window.Resources>
<StackPanel>
<TextBlock Text=”&#xe607;” Style=”{StaticResource FIcon}” FontSize=”30″ Margin=”3″ ></TextBlock>
<TextBlock Text=”&#xe612;” Style=”{StaticResource FIcon}” FontSize=”30″ Margin=”3″ ></TextBlock>
</StackPanel>
</Window>

效果:

异常处理之ThreadException、unhandledException及多线程异常处理

一:ThreadException和unhandledException的区别

处理未捕获的异常是每个应用程序起码有的功能,C#在AppDomain提供了UnhandledException 事件来接收未捕获到的异常的通知。常见的应用如下:

复制代码

代码

staticvoid Main(string[] args)
{
AppDomain.CurrentDomain.UnhandledException +=new UnhandledExceptionEventHandler(CurrentDomain_UnhandledException);
}

staticvoid CurrentDomain_UnhandledException(object sender, UnhandledExceptionEventArgs e)
{
Exception error = (Exception)e.ExceptionObject;
Console.WriteLine(“MyHandler caught : “+ error.Message);
}

复制代码

未捕获的异常,通常就是运行时期的BUG,于是我们可以在UnhandledException 的注册事件方法CurrentDomain_UnhandledException中将未捕获异常的信息记录在日志中。值得注意的是,UnhandledException提供的机制并不能阻止应用程序终止,也就是说,CurrentDomain_UnhandledException方法执行后,应用程序就会被终止。

上面我们举的例子来自于控制台程序,UnhandledException可以在任何应用程序域中使用,在某些应用程序模型,如windows窗体程序,还存在ThreadException来处理 Windows 窗体线程中所发生的其未经处理的异常。即,在windows窗体程序中,使用 ThreadException 事件来处理 UI 线程异常,使用 UnhandledException 事件来处理非 UI 线程异常。ThreadException可以阻止应用程序终止。具体使用方法如下:

复制代码

代码

[STAThread]
staticvoid Main()
{
Application.ThreadException +=new ThreadExceptionEventHandler(UIThreadException);
Application.SetUnhandledExceptionMode(UnhandledExceptionMode.CatchException);
AppDomain.CurrentDomain.UnhandledException +=
new UnhandledExceptionEventHandler(CurrentDomain_UnhandledException);
Application.Run(new ErrorHandlerForm());
}

privatestaticvoid UIThreadException(object sender, ThreadExceptionEventArgs t)
{
try
{
string errorMsg =”Windows窗体线程异常 : \n\n”;
MessageBox.Show(errorMsg + t.Exception.Message + Environment.NewLine + t.Exception.StackTrace);
}
catch
{
MessageBox.Show(“不可恢复的Windows窗体异常,应用程序将退出!”);
}
}

privatestaticvoid CurrentDomain_UnhandledException(object sender, UnhandledExceptionEventArgs e)
{
try
{
Exception ex = (Exception)e.ExceptionObject;
string errorMsg =”非窗体线程异常 : \n\n”;
MessageBox.Show(errorMsg + ex.Message + Environment.NewLine + ex.StackTrace);
}
catch
{
MessageBox.Show(“不可恢复的非Windows窗体线程异常,应用程序将退出!”);
}
}

复制代码

除了Windows窗体程序,再来说一下WPF程序。WPF的UI线程和Windows的UI线程有点不一样。WPF的UI线程是交给一个叫做调度器的类:Dispatcher。代码如下:

复制代码

代码

public App()
{
this.DispatcherUnhandledException +=new DispatcherUnhandledExceptionEventHandler(Application_DispatcherUnhandledException);
AppDomain.CurrentDomain.UnhandledException +=new UnhandledExceptionEventHandler(CurrentDomain_UnhandledException);
}

void CurrentDomain_UnhandledException(object sender, UnhandledExceptionEventArgs e)
{
try
{
Exception ex = e.ExceptionObject as Exception;
string errorMsg =”非WPF窗体线程异常 : \n\n”;
MessageBox.Show(errorMsg + ex.Message + Environment.NewLine + ex.StackTrace);
}
catch
{
MessageBox.Show(“不可恢复的WPF窗体线程异常,应用程序将退出!”);
}
}

privatevoid Application_DispatcherUnhandledException(object sender, DispatcherUnhandledExceptionEventArgs e)
{
try
{
Exception ex = e.Exception;
string errorMsg =”WPF窗体线程异常 : \n\n”;
MessageBox.Show(errorMsg + ex.Message + Environment.NewLine + ex.StackTrace);
}
catch
{
MessageBox.Show(“不可恢复的WPF窗体线程异常,应用程序将退出!”);
}
}

复制代码

无论是Windows窗体程序还是WPF程序,我们都看到捕获的异常当中分为”窗体线程异常”和”非窗体线程异常”。如在Windows窗体程序中,如果在窗体线程中,

thrownew Exception(“窗体线程异常”);

将会触发ThreadException事件。

Thread t =new Thread((ThreadStart)delegate
{
thrownew Exception(“非窗体线程异常”);
});
t.Start();

将会触发UnhandledException事件,然后整个应用程序会被终止。

 

二:多线程异常处理

 

多线程的异常处理,要采用特殊的做法。以下的处理方式会存在问题:

复制代码

代码

try
{
Thread t =new Thread((ThreadStart)delegate
{
thrownew Exception(“多线程异常”);
});
t.Start();
}
catch (Exception error)
{
MessageBox.Show(error.Message + Environment.NewLine + error.StackTrace);
}
复制代码

应用程序并不会在这里捕获线程t中的异常,而是会直接退出。从.NET2.0开始,任何线程上未处理的异常,都会导致应用程序的退出(先会触发AppDomain的UnhandledException)。上面代码中的try-catch实际上捕获的还是当前线程的异常,而t是属于新起的异常,所以,正确的做法应该是:

复制代码

代码

Thread t =new Thread((ThreadStart)delegate
{
try
{
thrownew Exception(“多线程异常”);
}
catch (Exception error)
{
MessageBox.Show(“工作线程异常:”+ error.Message + Environment.NewLine + error.StackTrace);
}
});
t.Start();
复制代码

也就是说,新起的线程中异常的捕获,可以将线程内部代码全部try起来。原则上来说,每个线程自己的异常应该在自己的内部处理完毕,不过仍旧有一个办法,可以将线程内部的异常传递到主线程。

在Windows窗体程序中,可以使用窗体的BeginInvoke方法来将异常传递给主窗体线程:

复制代码

代码

Thread t =new Thread((ThreadStart)delegate
{
try
{
thrownew Exception(“非窗体线程异常”);
}
catch (Exception ex)
{
this.BeginInvoke((Action)delegate
{
throw ex;
});
}
});
t.Start();
复制代码

上文的代码将最终引发主线程的Application.ThreadException。最终的结果看起来有点像:

 

在WPF窗体程序中,你可以采用如下的方法将工作线程的异常传递到主线程:

代码

Thread t =new Thread((ThreadStart)delegate
{
try
{
thrownew Exception(“非窗体线程异常”);
}
catch (Exception ex)
{
this.Dispatcher.Invoke((Action)delegate
{
throw ex;
});
}
});
t.Start();

WPF窗体程序的处理方式与Windows窗体程序比较,有两个很有意思的地方:

第一个是,在Windows窗体中,我们采用的是BeginInvoke方法。你会发现使用Invoke方法,并不能引发主线程的Application.ThreadException。而在WPF窗体程序中,无论是调度器的Invoke还是BeginInvoke方法都能将异常传递给主线程。

第二个地方就是InnerException。WPF的工作线程异常将会抛到主线程,变成主线程异常的InnerException,而Windows窗体程序的工作线程异常,将会被吃掉,直接变为null,只是在异常的Message信息中保存工作线程异常的Message。

 

三:ASP.NET异常处理

我们都知道ASP.NET的全局异常处理方法是Global中的Application_Error方法。我曾经查过ASP.NET的Appdomain.CurrentDomain.unhandledException,结果用反射得到的结果,unhandledException所注册的事件方法根本不是这个方法。联想到ASP.NET页面,包括这个全局处理类,都是交给aspnet_isapi.dll处理的,而aspnet_isapi.dll不是一个托管程序集。所以,应该理解为,ASP.NET的未捕获异常的处理,不同于托管异常(即CLR异常),而是交给aspnet_isapi.dll这个非托管DLL处理的。