2次梦幻109跨种族转门派派的间隔时间是多久?例如我昨天跨了一次LG转DT。今天还能再跨一次DT转DF吗?

收藏的论坛
梦幻西游:四大攻击门派对比,以及DT的衰落!
***更多资料进入梦幻西游专区:
***&&&&& ***新版本坐骑天下专题:
***&&&&& ***梦幻西游客户端补丁下载: ***&&&&& ***梦幻西游热点攻略: ***   攻击门派之间的不平衡,以及DT后期衰落  梦幻4大攻击门派——物理DT和ST,法术LG和MW——按道理说应该是齐头并进、各有千秋的,但为什么到了后期大家级别都高起来之后,却拉开了差距、即出现了门派不平衡了呢?(当然你硬要练力WZ、力NE、魔TG、力DF、武僧什么的,那是你的强悍,我只能佩服)  攻击系之所以成为攻击系,是因为他们的作用就是攻击输出、给对手以伤害,所以,要弄清楚上面的问题,必须从伤害输出说起。  伤害输出的高低取决于4个方面:加点、装备、修炼和技能,前3个方面对于所有4个攻击门派都是机会均等的,只有技能不一样。所以,我们认为:造成攻击门派输出伤害差别的根本原因在于门派技能。  首先分析物理系的ST和DT。  第一个方面:STL160的加伤害技能可以加480的伤害,DT因为多了一个加命中的技能,160级技能最终可以加736伤害。显然,在对属性的提升上,DT明显优于ST。技能在这个方面的加成,把ST的设为1的话,那DT的加成就大约是1.5。(此属性加成系数用A代替)  第二方面:以最常用伤害输出最高的鹰击和横扫为例。30技能时,ST鹰2,DT连3——双方出手都有限制,就相互抵消,不比较出手限制的影响;这里选用鹰击主要是为了后期比较的一致性,并不是说30级的ST最常用的是鹰击——双方都是两回合出手一次,那对伤害输出的加成可以看成:ST—1,DT—1.5(此技能加成系数用B代替)。但是,ST的鹰击数目是不断增加的,160的技能时,鹰6,则此系数B就变成了3,而DT160的技能仍旧是B=1.5。  综合起来就是:30级时,技能对总伤害输出的加成,DT是A*B=1.5*1.5=2.25,而ST是1*1=1。但到了后期,大家都满级的时候,此加成变成了DT A*B=1.5*1.5=2.25,ST 1*3=3。也就是说,在相同的装备、加点、修炼、技能情况下,DT即使能够每2回合甩一次3刀,也只能达到ST的75%的攻击输出——这还不考虑DT能否每2回合甩一次三刀,以及ST变身对临时伤害的提升——明白了吧,这就是低级时DT成为攻击系的王者,而随着级别的升高,越来越不如ST的原因。  现在分析法术系的MW和LG。  第一方面:160的加灵力技能,MW可以增加194灵力,LG增加195灵力,几乎相等,则属性加成系数A都等于1。  第2方面:以龙卷雨击和飞沙走石为例。  其伤害公式为:  龙卷雨击=(技能(龙卷)×2.0+灵力差×1.0+武器伤害×0.3)×(10-作用人数)/10  飞沙走石=(技能(飞沙)×2.0+灵力差×1.0+武器伤害×0.3)×(10-作用人数)/10  (转自官方论坛 孤独的愉悦 。我对此公式表示怀疑,实际中,飞沙走石的单个伤害要高于龙卷雨击。不过,少量的误差对我们现在讨论的问题不构成影响)  可以看出,影响法术门派伤害输出的根本是在于技能秒的个数多少。因为法术秒得越多,单个伤害越少,我们在这里再添加一个单个伤害系数C=(10-作用人数)/10(注:官方设定,秒5以后,单个伤害不再减少,即C最小为0.5)。30级时,MW秒1,则系数B=1;龙宫秒2,则系数B=2,C=0.8。而满级时,MW秒5,则B=5,C=0.5;LG秒7,B=7,C=0.5。  总结起来就是:30级时,技能对总伤害输出的加成,MW是1*1=1,LG是1*2*0.8=1.6。到了后期,MW A*B*C=1*5*0.5=2.5,LG 1*7*0.5=3.5。换句话说就是,在相同的装备、加点、修炼、技能情况下,LG做到的伤害输出可以达到MW的1.4倍!!这就是LG一直优于MW、占法术系绝对统治地位的根本原因。  再综合起来比较一下,低级时,以30级为例技能对伤害输出的总加成是:DT 2.25, LG 1.6, ST 1, MW 1, DT&LG&ST=MW,这与DT和LG占统治地位的现实符合得很好。而到了后期服战时代,技能对伤害输出的加成是LG 3.5,ST 3,MW 2.5,DT 2.25 ,LG&ST&MW&DT,这与服战中这几个门派的表现也大体相符。  看明白了吗?技能对伤害输出加成的差异造成个各攻击门派的不平衡,而这个加成还是随着技能的提高而变化的,初期资质较低的ST因为成长高,最终盖过了资质好却只知道吃老本不求进步的DT;资质成长都较高的LG,与都较低的MW之间的差距则是越拉越大……好比宠的成长率,LG和ST是最高成长的,是3.8的瓶子和鬼将,MW成长低,是3.65的蛟龙,自然没法比,而DT则是没有成长,怪哉!  有了上面的分析,我们就可以得出DT后期衰落的根本原因:别的攻击门派随着技能的提高,伤害输出加成也在不断提高着,而只有DT,自始至终都只有3刀可甩——30级可以甩对方3刀,90级继续甩对方3刀,到了155级也还是只能甩3刀!——还不考虑3刀的苛刻出手要求和甩完之后的掉血减防的副作用——也就是说,155级DT的技能伤害输出加成还停留在30级的水平!——DT的衰落与战术无关,与配合无关,而是根源于先天的不足!  广大高级DT玩家是不是有点心凉凉的感觉?别的攻击门派随着技能的提高,伤害输出加成也在不断提高着,而只有可爱可怜的DT,自始至终都只有3刀可甩——30级可以甩对方3刀,90级继续甩对方3刀,到了155级也还是只能甩3刀!!(还不考虑3刀的苛刻出手要求和甩完之后的副作用)  哭吧,感叹吧,去狂扁老徐吧(这个设置是老徐的事,可不能记在我们平庸的小白头上)不过后面更有哭的等着呢——如果继续提升等级上限和技能上限,别的攻击门派将持续发扬光大、飞扬跋扈,DT就请你们还是乖乖的去角落里集体垂泪、共同怀念往日的辉煌吧~~嘎嘎~~  不禁想起了我们的世界历史.封建社会,咱中国多风光啊——就像低级时的DT,而到了资本主义社会——大家级别都高了的服战时代,那些帝国主义——龙宫、ST、MW——小样都快步发展起来了,就只有咱人口最多的老大门派,还在原地踏步着,没有进步、没有发展、没有希望………………谁来拯救你,我的大唐……  我们期待着,网易也能考虑考虑饥寒交迫的广大西部地区的愿望,给DT一点应有的进步和发展。我们的横扫为什么只能永远3下呢?为什么就不能4下、5下?——就算这样的要求不能满足,我们不是还有一个叫“破釜沉舟”的鸡肋技能吗?为什么不能修改一下呢?要么放宽破釜那10%-30%气血上限出手以及复活当回合不能使用的苛刻限制,要么让破釜也能进步一点点,根据技能等级秒5、秒6??!!  我承认在大家等级都不高,具体说就是115级以前的时候,DT是占一定优势的,而且等级越低,优势越明显,越靠近115级,优势越少。(按我的算法,115级时4大门派技能加成系数都是2.5左右)  而在115级以后,ST和LG比起DT和MW来就占了明显的优势了——不仅体现在PK中,平时活动任务烧双都有优势。不要跟我说ST烧双不如DT什么什么的话,那是ST不用技能。  如果梦幻继续提升等级上限和技能上限的话,对DT和MW来说简直就是噩梦——虽然你原地不动,但别人进步了,你就是退步。  而且在后期,PK是很重要很重要的梦幻生活。如果你说自己只练级不PK,那么恭喜你,你有做哈哈——练级机器的潜质。  那些老是提“以前”、“练级”、“赚钱”等等的朋友自己心平气和的算算,是0-115级花的时间精力多呢?还是115-155的时间精力多?  另外,本贴主要讨论的是攻击门派,请不要拿封系对比***更多资料进入梦幻西游专区:
***&&&&& ***新版本坐骑天下专题:
***&&&&& ***梦幻西游客户端补丁下载: ***&&&&& ***梦幻西游热点攻略: ***
近期游戏热闻收藏的论坛
梦幻西游手游期待已经得跨种族转门派放出
  昨天维护过后,测试服的小伙伴就可以跨种族转换门派和角色啦!其它非测试服的小伙伴也不要急,测试都有了,全服开放还会远吗~?梦幻西游手游跨种族转门派已经出来了。那些经常觉得自己门派弱弱的小伙伴,别再哭来哭去了,如果你觉得弱,现在跨种族转门派都来了,你倒是转门派去啊!  首先呢,我们就先来看看跨种族转门派和角色的详细规则吧!  功能介绍:http://my.163.com//.html  近期论坛玩家呼声最高的跨种族门派角色转换放出了!无论你是一个心怀暴力输出梦的辅助,或是一个拥有慈悲救世心的封系,都可以改头换面,拜入新的师门,开始你梦幻的新征程。当然,跨类型的门派转换(例如封系转物理、法系转辅助灯)涉及到装备、法宝等的重新准备,耗费较大,望大家三思而后行。相比而言,同类型的门派转换就显得经济许多,例如普陀和地府、大唐和狮驼、龙宫和魔王互转,不需要太多的装备和法宝的调整,是想体验新门派玩法的玩家的首选哦。  至于方寸呢,你不要急,相信你的竞争对手会在不远的将来出现的~~  我们来一句话总结一下转门派吧,加深你的记忆:  1.不管怎么转,就是不能转性别。  2.转武器要求是前一个角色能使用的才能转。  3.武器转换之后会绑定。  4.门派角色转回去费用减半。  5.法宝不能转。  6.转一次门派宝石可以转12颗。  7.转角色染色会由新角色继承。  你觉得龙宫秒天秒地,要不你也去试试?你觉得地府鬼眼六道小死亡无法无天,怎么也得去尝尝吧?你说大唐三刀太恐怖,马上你也可以一己之力劈开混沌!你说魔神附体人间大炮,魔族走过,不留下一丝生气,要不咱也入魔一回?转门派不久就会开启,口说无凭,刀剑无眼。体验过了强者的战斗方式,各人自有评说!  你是不是最强?由你自己去选择,而不是耍耍嘴皮子。  立下你的诺言,转门派出来的那天,毫不犹豫的转换你认为最强的门派?有人在贴吧里发起了投票,看看有多少想转门派的呢!我们来看看他们的誓言~~我是大唐,我要转龙宫!  1.我要转成龙宫,秒天秒地秒空气!  2.我要转成普陀,慈悲为怀济天下!  3.我要转成地府,鬼眼六道走轮回!  4.我要转成狮驼,人间大炮老司机!  5.我要转成大唐,三刀不死枉为人!  6.我要转成方寸,论胜负意料之中!  7.我要转成魔王,附体魔神灰燃烬!   看这投票的趋势,龙宫和魔王妥妥的领先其他门派啊!!原来法术输出门派这么受欢迎啊~~  ps:以上为玩家观点,不代表官方立场。
近期游戏热闻
类型:3V3 MOBA
厂商:Supercell
类型:MOBA
类型:动作射击
类型:角色扮演
类型:音乐舞蹈
类型:换装养成
类型:休闲益智
类型:ARPG梦幻西游角色跨种族转门派后,角色不变可以吗_百度知道
梦幻西游角色跨种族转门派后,角色不变可以吗
我有更好的答案
梦幻西游中如果角色跨种族转门派角色一定是会变的原因:其实这也是游戏常识,不同种族的角色是不一样,比如你是人族DT逍遥生,想转魔族拜魔王寨,只能变成虎头怪或者巨魔王才可以,目前还没有人物是人族,但是门派是仙族或者魔族的情况,当然双城记看戏变身和游戏BUG除外。跨种族转门派注意事项:1、只能专为同性别的角色,比如人族男性角色转成魔族只能是魔族男性角色2、跨种族转换造型后,武器造型是不会转换的3、跨种族转门派选定一个角色之后,无法在新种族中转换其他角色。比如你是人族逍遥生,转成魔族巨魔王之后,就不能转成虎头怪或者杀破狼,只能转回到人族其他的男性角色。
采纳率:89%
来自团队:
既然你选择了跨种族转门派当然是角色会变的,不可能不变的。
本回答被提问者和网友采纳
玩家需对以下事宜进行确认:跨种族转换角色造型后、静息仙玉、免费仙玉都可:(1)角色等级大于等于60级。(2)不得拥有法宝任务、飞升任务。4,申请进行跨种族角色造型转换。此外,只有当前种族与该角色初始种族相同时,才可以在同种族内进行角色造型转换。确认后、门派、需要消耗的潜能果和仙玉进行确认。支付后,完成跨种族角色造型和门派转换操作。(7)装备栏内(包括当前装备和可换装的3套)不得穿戴任何装备,且法宝栏内不能有门派法宝:任意角色都可以将造型转换为不同种族。3,也无法拜入仅女性角色才可加入的门派。4、同性别的另一个角色造型。跨种族角色造型和门派转换费用:需要根据角色的等级,消耗一定数量的仙玉。灵动仙玉、当角色在跨种族转换门派的目标为角色曾经拜入的门派时,则将多扣除的经验返还到角色当前经验中去。1,龙宫门派。他可以选择转换为逍遥生造型,并转入大唐官府门派。但无法转换为女性角色造型,输入“我确认”后继续后面的步骤。扣除方式:扣除等量的潜能果;需要扣除的经验、选择要转入的角色和门派。例如:玩家为龙太子造型,不可以进行武器造型转换。3,其所扣除的经验为基础经验*10%。但需要支付的仙玉仍与首次进行跨种族转换门派时相同;在扣除潜能果时、门派称谓任务、师门任务,且登录时所用的密保产品必须超过14天。(6)角色不在藏宝阁角色登记期间、渡劫任务、种族任务、跨种族角色造型和门派转换支付费用等级消耗仙玉60-996000个100-1397500个140-1599000个160-17510000个2、跨种族角色造型和门派转换需要额外消耗角色的经验扣除的经验与角色等级、总经验相关:120*人物等级*人物等级*人物等级+人物当前升级经验*0.2+人物总经验*2%。(3)离上一次转换门派(含跨种族和同种族)时间超过15天。(4)全面解锁。(5)必须为密保用户。跨种族门派与角色造型转换流程:1、进入游戏。2。(10)需要满体力、60-89级玩家最多扣除50个潜能果。90级及以上的玩家扣除的上限为10亿点经验。申请跨种族角色造型和门派转换必须满足以下条件,如果潜能果不足扣,则不能进行转门派。(12)不能骑乘种族坐骑,且种族坐骑不能佩戴坐骑饰品。(13)角色不得穿戴角色专用锦衣跨种族门派与角色造型转换功能面向范围,离上一次角色转服成功时间超过15天,并重新选择一个该角色造型可以加入的一个门派,如果潜能果需要的经验&gt。(11)如果角色曾经进行过角色转服。(9)没有报名精武天神,在长安城(173,14)处找到袁守诚,选择选项“跨种族角色造型和门派转换相关”。(8)不在武神坛报名队伍内、对造型、种族坐骑任务、红尘试炼任务。与同种族门派转换的消耗相同
跨种族门派与角色造型转换功能面向范围:任意角色都可以将造型转换为不同种族、同性别的另一个角色造型,并重新选择一个该角色造型可以加入的一个门派。例如:玩家为龙太子造型,龙宫门派。他可以选择转换为逍遥生造型,并转入大唐官府门派。但无法转换为女性角色造型,也无法拜入仅女性角色才可加入的门派。跨种族门派与角色造型转换流程:1、进入游戏,在长安城(173,14)处找到袁守诚,选择选项“跨种族角色造型和门派转换相关”,申请进行跨种族角色造型转换。2、玩家需对以下事宜进行确认:跨种族转换角色造型后,不可以进行武器造型转换。此外,只有当前种族与该角色初始种族相同时,才可以在同种族内进行角色造型转换。确认后,输入“我确认”后继续后面的步骤。3、选择要转入的角色和门派。4、对造型、门派、需要消耗的潜能果和仙玉进行确认。支付后,完成跨种族角色造型和门派转换操作。跨种族角色造型和门派转换费用:需要根据角色的等级,消耗一定数量的仙玉。灵动仙玉、静息仙玉、免费仙玉都可。1、跨种族角色造型和门派转换支付费用等级消耗仙玉60-996000个100-1397500个140-1599000个160-17510000个2、跨种族角色造型和门派转换需要额外消耗角色的经验扣除的经验与角色等级、总经验相关:120*人物等级*人物等级*人物等级+人物当前升级经验*0.2+人物总经验*2%。与同种族门派转换的消耗相同。扣除方式:扣除等量的潜能果,如果潜能果不足扣,则不能进行转门派;在扣除潜能果时,如果潜能果需要的经验&需要扣除的经验,则将多扣除的经验返还到角色当前经验中去。3、当角色在跨种族转换门派的目标为角色曾经拜入的门派时,其所扣除的经验为基础经验*10%。但需要支付的仙玉仍与首次进行跨种族转换门派时相同。4、60-89级玩家最多扣除50个潜能果。90级及以上的玩家扣除的上限为10亿点经验。申请跨种族角色造型和门派转换必须满足以下条件:(1)角色等级大于等于60级。(2)不得拥有法宝任务、飞升任务、门派称谓任务、师门任务、渡劫任务、种族任务、种族坐骑任务、红尘试炼任务。(3)离上一次转换门派(含跨种族和同种族)时间超过15天。(4)全面解锁。(5)必须为密保用户,且登录时所用的密保产品必须超过14天。(6)角色不在藏宝阁角色登记期间。(7)装备栏内(包括当前装备和可换装的3套)不得穿戴任何装备,且法宝栏内不能有门派法宝。(8)不在武神坛报名队伍内。(9)没有报名精武天神。(10)需要满体力。(11)如果角色曾经进行过角色转服,离上一次角色转服成功时间超过15天。(12)不能骑乘种族坐骑,且种族坐骑不能佩戴坐骑饰品。(13)角色不得穿戴角色专用锦衣。注意:涉及的角色造型专用锦衣将会被自动转化为新造型的专用锦衣。角色造型转换后,角色的染色和衣柜内染色信息会同时被转换成目标角色的对应染色。
【角色转换】  为了让玩家能够在游戏过程中获得更多的乐趣与游戏体验,我们在推出“门派转换”的基础上再次推出“角色造型转换”功能。  角色造型转换功能面向范围:  任意角色都可以将造型转换为同性别同种族的另一个造型。  角色造型转换流程:  1、进入游戏,在长安城(173,14)处找到袁守诚申请进行角色造型转换。角色转换选项角色转换选项  2、进行支付确认。您需要在支付确认时的前90分钟内充入足够的点数,确认支付时会进行扣除(充值多余的部分将会变成角色对应帐号点数余额)。角色转换消耗2000点  3、完成角色造型转换操作,重新上线即可看到角色新造型。  角色造型转换费用:  每次角色造型转换消耗2000点点卡。  申请角色造型必须满足以下条件:  1)角色等级大于等于60级。  2)不得拥有渡劫任务。  3)离上一次门派转换时间超过30天。  4)全面解锁。  5)必须为密保用户,且登录时所用的密保产品必须超过14天。  6)角色不在藏宝阁角色登记期间。  7)装备栏内(包括当前装备和可换装的3套)不得穿戴任何装备。  8)不在武神坛报名队伍内。  9)没有报名精武天神。  注意:  涉及的角色造型专用锦衣将会被自动转化为新造型的专用锦衣。  角色造型转换后,角色的染色和衣柜内染色信息会同时被转换成目标角色的对应染色。
这个是不可以的,都知道梦幻分人,仙魔三族,在你转换门派的时候同时会支付角色的仙玉,而且转换门派的话还是有角色等级的高低形成的, 等级越高,要的仙玉就会越多。谢谢。
你想多了吧
这种事儿怎么可能
跨种族的话
人物也必须变更的
方寸转五庄
就必须得在
之中选择一个
其他11条回答
为您推荐:
其他类似问题
梦幻西游角色的相关知识
换一换
回答问题,赢新手礼包
个人、企业类
违法有害信息,请在下方选择后提交
色情、暴力
我们会通过消息、邮箱等方式尽快将举报结果通知您。23:08 by youxin, ... 阅读,
1."属性页的添加:创建对话框的类,该类要从CpropertyPage继承;
然后在要添加该对话框为属性页的类(头文件)里创建CpropertySheet类的一个对象m_tabsheet和新创建的对话框类的对象m_skatch;
最后,在.cpp文件里的OnInitDialog()之类的函数里实现如下代码:
{ m_tabsheet.Create(this, WS_CHILD | WS_VISIBLE, 0);
//使选项卡的按钮在下面
if(m_tabsheet.m_hWnd)
m_tabsheet.ShowWindow(SW_MAXIMIZE);
//显示选项卡
//加入标签,标签名由各个子对话框的标题栏决定
m_tabsheet.AddPage(&m_skatch);
//用Create来创建一个属性页
m_tabsheet.Create(this, WS_CHILD | WS_VISIBLE, WS_EX_CONTROLPARENT);
m_tabsheet.GetWindowRect(&rect);
int width = rect.right - rect.
int height = rect.bottom - rect.
//调整属性页的大小和位置
m_tabsheet.SetWindowPos(NULL, 225, 225, width-82, height,SWP_NOACTIVATE);
//属性页的添加完成。如果要添加多个属性页,则只需要增加多个对象,如下:
m_tabsheet.AddPage(&m_skatch1);
m_tabsheet.AddPage(&m_skatch2);
2."List Control中标题栏(Column)的添加:创建一个List Control,其ID为IDC_LIST,在其Styles属性项下的View项里选择Report、Align项里选择Top、Sort项里选择None.然后在该List所在对话框的类(头文件)里创建ClistCtrl的一个对象m_list
然后在.cpp文件的OnInitDialog()之类的函数里实现如下代码:
CString strname[3];
strname[0]="Screen Name";
strname[1]="Form ID";
strname[2]="Category Path";
for(int i=0;i&3;i++)
m_List.InsertColumn(i,strname[i],LVCFMT_LEFT,130);
在这之前也要将List Control的ID与ClistCtrl的对象m_list在DoDataExchange(CDataExchange* pDX)函数里绑定,如下:
DDX_Control(pDX, IDC_LIST, m_List);
3."ToolBar和StatusBar中控件的添加:方法⑴.只能在ToolBar里创建控件:
首先,在ToolBar中创建一个Button,其ID为ID_TOOL_COMBO(我们要将创建的控件放在该Button的位置上).
其次,新创建一个类CMainToolBar,要从CToolBar继承(创建过程大概如下:选择工程/增加到工程/新的类;也可以选择工程的根,然后点击右键,选择新的类;或者CTL+W,选择增加类/新的类 ---
然后在class type里选择Generic Class,在Name栏里输入新类的名字,Base class里输入CToolBar),创建成功后在该类里创建要增加的控件的对象,如:CComboBox& m_wndMyC&CStatic& m_wndCategory, m_wndCategoryPCButton& m_wndOpenBCedit& m_wndE然后在构造函数里初始化如:m_wndMyCombo.m_hWnd = NULL;m_wndCategory.m_hWnd = NULL;m_wndCategoryPath.m_hWnd = NULL;m_wndOpenButton.m_hWnd = NULL;m_wndEdit.m_hWnd = NULL;接着在CMainframe的头文件里创建CMainToolBar的一个对象m_wndToolBar,最后在.cpp文件的OnCreate函数的最后实现如下:
int index = 0; CR 
// 可定义在头文件当中 // 
//找到指定的工具项
while(m_wndToolBar.GetItemID(index)!=ID_TOOL_COMBO)
//设置指定工具项的宽度并获取新的区域 120是宽度
m_wndToolBar.SetButtonInfo(index, ID_TOOL_COMBO, TBBS_SEPARATOR, 120);
m_wndToolBar.GetItemRect(index, &rect);
//设置位置
rect.top+=1;
rect.bottom += 200;
// 创建并显示控件
if(!m_wndToolBar.m_wndMyCombo.Create(WS_CHILD|WS_VISIBLE| CBS_AUTOHSCROLL|CBS_DROPDOWNLIST | CBS_HASSTRINGS , rect, &m_wndToolBar,ID_TOOL_COMBO))
TRACE0("Failed to create combo-box\n");
return FALSE;
m_wndToolBar.m_wndMyCombo.ShowWindow(SW_SHOW);
//填充内容"
m_wndToolBar.m_wndMyCombo.AddString("25%");
m_wndToolBar.m_wndMyCombo.AddString("50%");
m_wndToolBar.m_wndMyCombo.AddString("75%");
//选择默认项
m_wndToolBar.m_wndMyCombo.SetCurSel(0);
//获取到内容并MSGBOX显示出来
CString strC m_wndToolBar.m_wndMyCombo.GetWindowText(strContent);
index = 0;
其他控件都类似创建(只需要注意一下各自的Create函数的参数即可)。
方法⑵.这种方法创建不太容易控制:直接在CMainframe的头文件中创建要增加的控件的对象,如CButton"的对象m_wndAboutButton,然后创建CToolBar或者CstatusBar的对象,如:CstatusBar的对象_wndStatusBar;再增加几个函数如下:
Protected:
virtual void RecalcLayout(BOOL bNotify = TRUE);
"afx_msg void CMainFrame::OnViewStatusBar();接着在.cpp文件中将StatusBar的ID和OnViewStatusBar 函数绑定在一起,如下所示:
BEGIN_MESSAGE_MAP(CMainFrame, CFrameWnd)   
// {{AFX_MSG_MAP(CMainFrame)   
ON_COMMAND(ID_VIEW_STATUS_BAR, OnViewStatusBar)   
ON_WM_CREATE()   
// }}AFX_MSG_MAP END_MESSAGE_MAP()
然后Create函数的最后(返回值之前)实现如下代码:
VERIFY(m_wndAboutButton.Create(_T("MyAbout"),  
WS_VISIBLE,rc,this,ID_APP_ABOUT));
// TODO: Remove this if you don't want tool tips or a resizeable toolbar
m_wndToolBar.SetBarStyle(m_wndToolBar.GetBarStyle() | CBRS_TOOLTIPS | CBRS_FLYBY | CBRS_SIZE_DYNAMIC);
再在RecalcLayout函数里实现:
if (m_wndStatusBar.m_hWnd)
m_wndStatusBar.GetWindowRect(&rc);
ScreenToClient(&rc);
rc.right -= 50;
m_wndStatusBar.SetWindowPos(NULL,rc.left,rc.top,rc.Width(),rc.Height(), SWP_NOZORDER);
rc.left = rc.
rc.right += 50;
m_wndAboutButton.SetWindowPos(NULL,rc.left,rc.top,rc.Width(),rc.Height(), SWP_NOZORDER);
}最后在OnViewStatusBar()里实现:
BOOL bShow = m_wndStatusBar.GetStyle() & WS_VISIBLE;
m_wndAboutButton.SetWindowPos(NULL, 0, 0, 0, 0,SWP_NOZORDER|SWP_NOMOVE|SWP_NOSIZE|SWP_NOACTIVATE| (bShow ? SWP_SHOWWINDOW : SWP_HIDEWINDOW));
ToolBar中的创建与此相同,只需更改一下句柄即可。
4."通过Control创建的控件,对其属性的动态控制:在对话框类的头文件里创建所要改变属性的控件的对象,如要改变一个Button(其ID为IDC_MyButton)的属性,则需创建Cbutton的对象m_button。然后在.cpp中的DoDataExchange函数里将Button的ID和创建的对象绑定在一起:
//{{AFX_DATA_MAP(CPrintDlg)
// NOTE: the ClassWizard will add DDX and DDV calls here
DDX_Control(pDX, IDC_MyButton, m_button);
//}}AFX_DATA_MAP&然后可以在该函数的最后进行初始化:m_button.EnableWindow(FALSE);到这里已经实现了改变属性。如果要动态改变其属性,可如下实现(通过两个Button的点击改变起属性):// RadioAll Button的点击响应函数
void CPrintDlg::OnRadioAll()
{ // TODO: Add your control notification handler code here
m_button.EnableWindow(TRUE);
// RadioSelect Button的点击响应
void CPrintDlg::OnRadioSelect()
{ // TODO: Add your control notification handler code here
m_button.EnableWindow(FALSE);
也可以通过一个Check Button的点击来改变,在其点击响应函数里实现:m_button.EnableWindow(!m_button.IsWindowEnabled());其余控件属性的改变都如此。
5."窗口的分割与停靠:                        一、新建一个类CMySplitter,基类为CSplitterWnd二、重载该类的OnMouseMove函数:
void CMySplitter::OnMouseMove(UINT nFlags, CPoint point)
// 限制切分条的运动范围。
if(point.x&228||point.x&600)
CWnd::OnMouseMove(nFlags, point);
CSplitterWnd::OnMouseMove(nFlags, point);
三、 然后就可以跟一般的窗口分割那样去做了,if(point.x&228||point.x&600)这里的范围可以随你去设置了 ^_^,够简单吧。四、切分窗口在MaiFram.h建立切分条对象:
protected:
CMySplitter m_wndS
//切分窗口对象
//在MaiFram.cpp中实现窗口切分:
BOOL CMainFrame::OnCreateClient(LPCREATESTRUCT /*lpcs*/,CCreateContext* pContext)
// 创建拆分器窗口
if (!m_wndSplitter.CreateStatic(this, 1, 2))
return FALSE;
if (!m_wndSplitter.CreateView(0, 0, RUNTIME_CLASS(CLeftView),CSize(228,100),pContext) ||!m_wndSplitter.CreateView(0,1, RUNTIME_CLASS(CDataEditView), CSize(100, 100), pContext))
{ m_wndSplitter.DestroyWindow();
return FALSE;
return TRUE;
6.一些重要的问题
①怎样在程序开始的时候让它最大化?②vc++做出来的exe文件在窗体的右上方是没有最大化和最小化按钮的,怎样实现这一功能?&③如何在显示窗口时,使最大化按钮变灰?
①在App类里的C&App::InitInstance()中把m_pMainWnd-&ShowWindow(SW_SHOW)改成m_pMainWnd-&ShowWindow(SW_MAXIMIZE);②在CreateWidnow时用WS_SYSMENU|WS_MINIMIZEBOX|WS_MAXIMIZEBOX 风格.③&第一种方法:
BOOL CMainFrame::PreCreateWindow(CREATESTRUCT& cs)
if( !CFrameWnd::PreCreateWindow(cs) )
return FALSE;
// TODO: Modify the Window class or styles here by modifying // the CREATESTRUCT cs // disable the
maxmini box cs.style &= ~WS_MAXIMIZEBOX;
return TRUE;
第二种方法:
CMenu *pMenu=AfxGetApp()-&m_pMainWnd-&GetSystemMenu(FALSE);
int x=pMenu-&GetMenuItemCount( );
UINT pID=pMenu-&GetMenuItemID(x-1);
pMenu-&EnableMenuItem(pID, MF_DISABLED);
第三种方法:ModifyStyle(WS_MAXIMIZEBOX, 0);&这个函数也可以是最大化按钮失效!并且可以在程序中动态的改变窗口的风格
7. 更改属性页标题
void CProSheet::SetPageTitle(int nPage, int nImage, CString strTitle)
// item.mask = TCIF_TEXT|TCIF_IMAGE;
//设置图标+文字
item.mask = TCIF_IMAGE;
//只设置图标
item.iImage = nI
// item.pszText = strTitle.GetBuffer(0);
//设置文字 GetTabControl ()-&SetItem (nPage, &item);
//要设置文字时就将上面2行有注释符的代码前的注释符去掉
8. 创建动态菜单
void CMainFrame::OnSelectState(NMTOOLBAR* pnmtb, LRESULT *plr)
if(!menu.CreateMenu())
menu.AppendMenu(MF_STRING,0, 开始 );
menu.AppendMenu(MF_STRING,0, 结束 );
m_wndToolBar.SendMessage(TB_GETRECT, pnmtb-&iItem, (LPARAM)&rc);
m_wndToolBar.ClientToScreen(&rc);
menu.TrackMenu( TPM_LEFTALIGN | TPM_LEFTBUTTON | TPM_VERTICAL, rc.left, rc.bottom, this, &rc);
// menu.DestroyMenu();
menu.detach();
9.关于打印1.要打印哪个视就((CMainFrame*)AfxGetMainWnd())-&m_wndSplitter.SetActivePane(...)&//要打印的那个视对应的Pane
2.有一个单文档工程,文档窗口被切分:左视图由CTreeView 的派生类管理,右视图由CListView 的派生类CMyListView(其为风格为LVS_REPORT)管理,我想为右视图添加打印和打印预览,我在MyListView.cpp中添加了
ON_COMMAND(ID_FILE_PRINT,CListView::OnFilePrint)
ON_COMMAND(ID_FILE_PRINT_PREVIEW,CListView::OnFilePrintPreview)
BOOL CMyListView::OnPreparePrinting(CPrintInfo* pInfo)
// TODO: call DoPreparePrinting to invoke the Print dialog box //
return CListView::OnPreparePrinting(pInfo);
pInfo-&SetMaxPage(2);
BOOL bret=DoPreparePrinting(pInfo);
pInfo-&m_nNumPreviewPages=2;
3. 下面是从MSDN中摘出来的一段,是用来改变消息路由的。用了这段代码之后,CView中的消息(菜单,控件,子窗口)将先被CMyShape类来处理。不知道你要的是不是这样的效果。
// This example illustrates extending the framework's standard command
// route from the view to objects managed by the view. This example
// is from an object-oriented drawing application, similar to the
// DRAWCLI sample application, which draws and edits shapes .
BOOL CMyView::OnCmdMsg(UINT nID, int nCode, void* pExtra, AFX_CMDHANDLERINFO* pHandlerInfo)
// Extend the framework's command route from the view to
// the application-specific CMyShape that is currently selected
// in the view. m_pActiveShape is NULL if no shape object
// is currently selected in the view.
if ((m_pActiveShape != NULL) && m_pActiveShape-&OnCmdMsg(nID, nCode, pExtra, pHandlerInfo))
return TRUE;
// If the object(s) in the extended command route don't handle
// the command, then let the base class OnCmdMsg handle it.
return CView::OnCmdMsg(nID, nCode, pExtra, pHandlerInfo);
// The command handler for ID_SHAPE_COLOR (menu command to change
// the color of the currently selected shape) was added to
// the message map of CMyShape (note, not CMyView) using ClassWizard.
// The menu item will be automatically enabled or disabled, depending
// on whether a CMyShape is currently selected in the view, that is,
// depending on whether CMyView::m_pActiveView is NULL. It is not
// necessary to implement an ON_UPDATE_COMMAND_UI handler to enable
// or disable the menu item.
BEGIN_MESSAGE_MAP(CMyShape, CCmdTarget)
//{{AFX_MSG_MAP(CMyShape)
ON_COMMAND(ID_SHAPE_COLOR, OnShapeColor)
//}}AFX_MSG_MAP END_MESSAGE_MAP()
如果你只是想调用OnFilePrint( )函数,可以试一试下面的代码,就和调用其它类中的函数一样。
CMDIFrameWnd *pFrame = (CMDIFrameWnd*)AfxGetApp()-&m_pMainW
// Get the active MDI child window.
CMDIChildWnd *pChild = (CMDIChildWnd *) pFrame-&GetActiveFrame();
// or CMDIChildWnd *pChild = pFrame-&MDIGetActive();
// Get the active view attached to the active MDI child window.
CMyView *pView = (CMyView *) pChild-&GetActiveView();
pView-&OnFilePrint( );
void CMyReportView::OnFileOpen() { char Filter[] = Crystal Report files(*.rpt)|*.rpt|All files(*.*)|*.*|| ; CR CFileDialog OpenDlg(TRUE,0,0,OFN_HIDEREADONLY|OFN_FILEMUSTEXIST,(LPCTSTR)Filter,NULL); if(OpenDlg.DoModal()!=IDOK) ///显示文件对话框 CString m_fName=OpenDlg.GetPathName(); ///取得文件名 if(m_CrystalReport) m_CrystalReport.DestroyWindow(); GetClientRect(rect); ///////////////////创建控件/////////////// if (!m_CrystalReport.Create(AfxRegisterWndClass(0, AfxGetApp()-&LoadStandardCursor(IDC_ARROW)),WS_CHILD|WS_VISIBLE,rect,this,IDC_CRYSTALREPORT1))
AfxMessageBox( 控件创建失败! );
m_CrystalReport.SetWindowParentHandle((long)(this-&m_hWnd));
///设置父窗口
m_CrystalReport.SetWindowBorderStyle(0);
///设置为没有边框
m_CrystalReport.SetWindowLeft(0);
m_CrystalReport.SetWindowTop(0);
///顶部空间
m_CrystalReport.SetWindowControls(FALSE);
///不显示工具条
m_CrystalReport.SetReportFileName(m_fName);
///设置报表文件
m_CrystalReport.SetWindowWidth(rect.Width());
///设置窗口宽度
m_CrystalReport.SetWindowHeight(rect.Height());
///设置窗口高度
m_CrystalReport.SetFormulas(0, Company=\ VC知识库\ );
///将报表中的Company变量的值设置为VC知识库
m_CrystalReport.SetDestination(0);
///设置输出对象是屏幕
m_CrystalReport.PrintReport();
///显示报表
void CMyReportView::OnFilePrint()
if(m_CrystalReport && m_CrystalReport.GetReportFileName() != )
m_CrystalReport.SetDestination(1);
///设置输出对象是打印机
m_CrystalReport.PrintReport();
10. Scroll创建一个基于CScrollview的SDI Project(在第6步中选CScrollview)若你已创建了,这步可以省略。然后:改为如
void CTestView::OnInitialUpdate()
CScrollView::OnInitialUpdate();
CSize sizeT
// TODO: calculate the total size of this view sizeTotal.cx = 1024;
//改这两个
sizeTotal.cy = 768;
SetScrollSizes(MM_TEXT, sizeTotal);
11. 修改主窗口风格AppWizard生成的应用程序框架的主窗口具有缺省的窗口风格,比如在窗口标题条中自动添加文档名、窗口是叠加型的、可改变窗口大小等。要修改窗口的缺省风格,需要重载CWnd::PreCreateWindow(CREATESTRUCT& cs)函数,并在其中修改CREATESTRUCT型参数cs。CWnd::PreCreateWindow 函数先于窗口创建函数执行。如果该函数被重载,则窗口创建函数将使用CWnd::PreCreateWindow 函数返回的CREATESTRUCT cs参数所定义的窗口风格来创建窗口;否则使用预定义的窗口风格。CREATESTRUCT结构定义了创建函数创建窗口所用的初始参数,其定义如下:
typedef struct tagCREATESTRUCT
LPVOID lpCreateP
// 创建窗口的基本参数
// 拥有将创建的窗口的模块实例句柄
// 新窗口的菜单句柄
HWND hwndP
// 新窗口的父窗口句柄
int // 新窗口的高度
int // 新窗口的宽度
int // 新窗口的左上角Y坐标
int // 新窗口的左上角X坐标
LONG // 新窗口的风格
LPCSTR lpszN // 新窗口的名称
LPCSTR lpszC // 新窗口的窗口类名
DWORD dwExS // 新窗口的扩展参数
} CREATESTRUCT;
CREATESTRUCT结构的style域定义了窗口的风格。比如,缺省的MDI主窗口的风格中就包括FWS_ADDTOTITLE(在标题条中显示当前的工作文档名)、FWS_PREFIXTITLE(把文档名放在程序标题的前面)、WS_THICKFRAME(窗口具有可缩放的边框)等风格。由于多种风格参数由逻辑或( | )组合在一起的,因此添加某种风格,就只需用 | 把对应的参数加到CREATESTRUCT结构的style域中;删除已有的风格,则需用 & 连接CREATESTRUCT结构的style域与该风格的逻辑非值。CREATESTRUCT结构的x、y、cx、cy域分别定义了窗口的初始位置和大小,因此,在CWnd::PreCreateWindow 函数中给它们赋值,将能定义窗口的初始显示位置和大小。下例中的代码将主框窗口的大小将固定为1/4屏幕,标题条中仅显示窗口名,不显示文档名。
BOOL CMainFrame::PreCreateWindow(CREATESTRUCT& cs)
// TODO: Modify the Window class or styles here by modifying // the
CREATESTRUCT cs
// 修改主窗风格
cs.style &= ~FWS_ADDTOTITLE;
//去除标题条中的文档名
cs.style &= ~WS_THICKFRAME;
//去除可改变大小的边框
cs.style |= WS_DLGFRAME; //增加不能改变大小的边框
// 确定主窗的大小和初始位置
int cxScreen = ::GetSystemMetrics(SM_CXSCREEN);//获得屏幕宽
int cyScreen = ::GetSystemMetrics(SM_CYSCREEN); //获得屏幕高
cs.x = 0; // 主窗位于左上角
cs.y = 0; cs.cx = cxScreen/2; // 主窗宽为1/2屏幕宽
cs.cy = cxScreen/2; // 主窗高为1/2屏幕高
return CMDIFrameWnd::PreCreateWindow(cs);
12. 控制滚动条
BOOL CDiagramShowView::PreTranslateMessage(MSG* pMsg)
CFileTreeDoc* pDoc = (CFileTreeDoc*)GetDocument();
CPoint point = GetScrollPosition();
if(pMsg-&message == WM_KEYDOWN)
switch(pMsg-&wParam)
case VK_LEFT:
if( point.x & 10)
EndPoint.x = EndPoint.x - 10;
EndPoint.y = EndPoint.y;
EndPoint.x = 0;
EndPoint.y = EndPoint.y;
ScrollToPosition(EndPoint);
InvalidateRect(NULL,TRUE);
case VK_RIGHT:
if( point.x & pDoc-&intDiagramColumnCount * pDoc-&intColumnWidth - 10 )
EndPoint.x = EndPoint.x + 10;
EndPoint.y = EndPoint.y;
EndPoint.y = pDoc-&intDiagramColumnCount * pDoc-&intColumnW
EndPoint.x = EndPoint.x;
ScrollToPosition(EndPoint); InvalidateRect(NULL,TRUE);
case VK_UP:
if( point.y & 10)
{ EndPoint.y = EndPoint.y - 10;
EndPoint.x = EndPoint.x;
EndPoint.y = 0;
EndPoint.x = EndPoint.x;
ScrollToPosition(EndPoint);
InvalidateRect(NULL,TRUE);
case VK_DOWN:
if( point.y & pDoc-&intDiagramRowCount * pDoc-&intRowHeight - 10 )
EndPoint.y = EndPoint.y + 10;
EndPoint.x = EndPoint.x;
EndPoint.y = pDoc-&intDiagramRowCount * pDoc-&intRowH
EndPoint.x = EndPoint.x;
ScrollToPosition(EndPoint);
InvalidateRect(NULL,TRUE);
return FALSE;
// 通过正负号判断是向上还是向下滚动 if(zDelta==120) 向上滚动 if(zDelta==-120) 向下滚动
BOOL CDiagramShowView::OnMouseWheel(UINT nFlags, short zDelta, CPoint pt)
CFileTreeDoc* pDoc = (CFileTreeDoc*)GetDocument();
CPoint point = GetScrollPosition();
if(zDelta==120)
if( point.y &= 20 )
EndPoint.x = point.x;
EndPoint.y = point.y;
EndPoint.x = EndPoint.x;
EndPoint.y = EndPoint.y - 20;
EndPoint.x = EndPoint.x;
EndPoint.y = 0;
if(zDelta==-120)
if( point.y &= pDoc-&intDiagramRowCount * pDoc-&intRowHeight - 20 )
EndPoint.x = point.x;
EndPoint.y = point.y;
EndPoint.x = EndPoint.x;
EndPoint.y = EndPoint.y + 20;
EndPoint.x = EndPoint.x;
EndPoint.y = EndPoint.y;
ScrollToPosition(EndPoint);
InvalidateRect(NULL,TRUE);
return CScrollView::OnMouseWheel(nFlags, zDelta, pt);
13. 属性页处理通知消息CPropertyPageImpl有一个消息映射处理WM_NOTIFY。如果通知代码是PSN_*的值,OnNotify()就会调用相应的通知处理函数。这使用了编译阶段虚函数机制,从而使得派生类可以很容易的重载这些处理函数。由于WTL 3和WTL 7设计的改变,从而存在两套不同的通知处理机制。在WTL 3中通知处理函数返回的值与PSN_*消息的返回值不同,例如,WTL 3是这样处理PSN_WIZFINISH的:
case PSN_WIZFINISH:
lResult = !pT-&OnWizardFinish();
OnWizardFinish()期望返回TRUE结束向导,FALSE阻止关闭向导。这个方法很简陋,但是IE5的通用控件对PSN_WIZFINISH处理的返回值添加了新解释,他返回需要获得焦点的窗口的句柄。WTL 3的程序将不能使用这个特性,因为它对所有非0的返回值都做相同的处理。在WTL 7中,OnNotify() 没有改变 PSN_* 消息的返回值,处理函数返回任何文档中规定的合法数值和正确的行为。当然,为了向前兼容,WTL 3 仍然使用当前默认的工作方式,要使用WTL 7的消息处理方式,你必须在中including atldlgs.h一行之前添加一行定义:
#define&_WTL_NEW_PAGE_NOTIFY_HANDLERS
编写新的代码没有理由不使用WTL 7的消息处理函数,所以这里就不介绍WTL 3的消息处理方式。CPropertyPageImpl 为所有消息提供了默认的通知消息处理函数,你可以重载与你的程序有关的消息处理函数完成特殊的操作。默认的消息处理函数和相应的行为如下:int OnSetActive() - 允许页面成为激活状态BOOL OnKillActive() - 允许页面成为非激活状态int OnApply() - 返回 PSNRET_NOERROR 表示应用操作成功完成void OnReset() - 无相应的动作BOOL OnQueryCancel() - 允许取消操作int OnWizardBack() - 返回到前一个页面int OnWizardNext() - 进行到下一个页面INT_PTR OnWizardFinish() - 允许向导结束void OnHelp() - 无相应的动作BOOL OnGetObject(LPNMOBJECTNOTIFY lpObjectNotify) - 无相应的动作int OnTranslateAccelerator(LPMSG lpMsg) - 返回 PSNRET_NOERROR 表示消息没有被处理HWND OnQueryInitialFocus(HWND hWndFocus) - 返回 NULL 表示将按Tab Order顺序的第一个控件设为焦点状态
14.使工具条上的按钮点击一次为按下,再点击才弹起
bCheck=m_RtfEditToolBar.GetToolBarCtrl().IsButtonChecked(ID_TB_BOLD);
m_RtfEditToolBar.GetToolBarCtrl().CheckButton(ID_TB_BOLD, !bCheck);
15. VC中基于 Windows 的精确定时在工业生产控制系统中,有许多需要定时完成的操作,如定时显示当前时间,定时刷新屏幕上的进度条,上位 机定时向下位机发送命令和传送数据等。特别是在对控制性能要求较高的实时控制系统和数据采集系统中,就更需要精确定时操作。  众所周知,Windows 是基于消息机制的系统,任何事件的执行都是通过发送和接收消息来完成的。这样就带来了一些问题,如一旦计算机的CPU被某个进程占用,或系统资源紧张时,发送到消息队列 中的消息就暂时被挂起,得不到实时处理。因此,不能简单地通过Windows消息引发一个对定时要求 严格的事件。另外,由于在Windows中已经封装了计算机底层硬件的访问,所以,要想通过直接利用访问硬件来完成精确定时,也比较困难。所以在实际应用时,应针对具体定时精度的要求,采取相适 应的定时方法。VC中提供了很多关于时间操作的函数,利用它们控制程序能够精确地完成定时和计时操作。本文详细介绍了 VC中基于Windows的精确定时的七种方式.  方式一:VC中的WM_TIMER消息映射能进行简单的时间控制。首先调用函数SetTimer()设置定时 间隔,如SetTimer(0,200,NULL)即为设置200ms的时间间隔。然后在应用程序中增加定时响应函数 OnTimer(),并在该函数中添加响应的处理语句,用来完成到达定时时间的操作。这种定时方法非常简单,可以实现一定的定时功能,但其定时功能如同Sleep()函数的延时功能一样,精度非常低,最小 计时精度仅为30ms,CPU占用低,且定时器消息在多任务操作系统中的优先级很低,不能得到及时响应,往往不能满足实时控制环境下的应用。只可以用来实现诸如位图的动态显示等对定时精度要求不高的情况。如示例工程中的Timer1。  方式二:VC中使用sleep()函数实现延时,它的单位是ms,如延时2秒,用sleep(2000)。精度非常低,最小计时精度仅为30ms,用sleep函数的不利处在于延时期间不能处理其他的消息,如果时间太长,就好象死机一样,CPU占用率非常高,只能用于要求不高的延时程序中。如示例工程中的Timer2。  方式三:利用COleDateTime类和COleDateTimeSpan类结合WINDOWS的消息处理过程来实现秒级延时。如示例工程中的Timer3和Timer3_1。以下是实现2秒的延时代码:
COleDateTime start_time = COleDateTime::GetCurrentTime();
COleDateTimeSpan end_time= COleDateTime::GetCurrentTime()-&start_
while(end_time.GetTotalSeconds()& 2) //实现延时2秒
GetMessage(&msg,NULL,0,0);
TranslateMessage(&msg); DispatchMessage(&msg);
//以上四行是实现在延时或定时期间能处理其他的消息,
//虽然这样可以降低CPU的占有率,
//但降低了延时或定时精度,实际应用中可以去掉。
end_time = COleDateTime::GetCurrentTime()-&start_
}//这样在延时的时候我们也能够处理其他的消息。   
  方式四:在精度要求较高的情况下,VC中可以利用GetTickCount()函数,该函数的返回值是 DWORD型,表示以ms为单位的计算机启动后经历的时间间隔。精度比WM_TIMER消息映射高,在较 短的定时中其计时误差为15ms,在较长的定时中其计时误差较低,如果定时时间太长,就好象死机一样,CPU占用率非常高,只能用于要求不高的延时程序中。如示例工程中的Timer4和Timer4_1。下列代码可以实现50ms的精确定时:
DWORD dwStart = GetTickCount();
DWORD dwEnd = dwS
dwEnd = GetTickCount()-&dwS
while(dwEnd &50);
//为使GetTickCount()函数在延时或定时期间能处理其他的消息,可以把代码改为:
DWORD dwStart = GetTickCount();
DWORD dwEnd = dwS
MSG GetMessage(&msg,NULL,0,0);
TranslateMessage(&msg);
DispatchMessage(&msg);
dwEnd = GetTickCount()-dwS
while(dwEnd &50);
虽然这样可以降低CPU的占有率,并在延时或定时期间也能处理其他的消息,但降低了延时或定时精度。  方式五:与GetTickCount()函数类似的多媒体定时器函数DWORD timeGetTime(void),该函数定时精 度为ms级,返回从Windows启动开始经过的毫秒数。微软公司在其多媒体Windows中提供了精确定时器的底层API持,利用多媒体定时器可以很精确地读出系统的当前时间,并且能在非常精确的时间间隔内完成一 个事件、函数或过程的调用。不同之处在于调用DWORD timeGetTime(void) 函数之前必须将 Winmm.lib 和 Mmsystem.h 添加到工程中,否则在编译时提示DWORD timeGetTime(void)函数未定义。由于使用该 函数是通过查询的方式进行定时控制的,所以,应该建立定时循环来进行定时事件的控制。如示例工程中的Timer5和Timer5_1。  方式六:使用多媒体定时器timeSetEvent()函数,该函数定时精度为ms级。利用该函数可以实现周期性的函数调用。如示例工程中的Timer6和Timer6_1。函数的原型如下:
MMRESULT timeSetEvent( UINT uDelay, UINT uResolution, LPTIMECALLBACK lpTimeProc, WORD dwUser, UINT fuEvent )
  该函数设置一个定时回调事件,此事件可以是一个一次性事件或周期性事件。事件一旦被激活,便调用指定的回调函数, 成功后返回事件的标识符代码,否则返回NULL。函数的参数说明如下:uDelay:以毫秒指定事件的周期。Uresolution:以毫秒指定延时的精度,数值越小定时器事件分辨率越高。缺省值为1ms。LpTimeProc:指向一个回调函数。DwUser:存放用户提供的回调数据。FuEvent:指定定时器事件类型:TIME_ONESHOT:uDelay毫秒后只产生一次事件TIME_PERIODIC :每隔uDelay毫秒周期性地产生事件。     具体应用时,可以通过调用timeSetEvent()函数,将需要周期性执行的任务定义在LpTimeProc回调函数 中(如:定时采样、控制等),从而完成所需处理的事件。需要注意的是,任务处理的时间不能大于周期间隔时间。另外,在定时器使用完毕后, 应及时调用timeKillEvent()将之释放。  方式七:对于精确度要求更高的定时操作,则应该使用QueryPerformanceFrequency()和 QueryPerformanceCounter()函数。这两个函数是VC提供的仅供Windows 95及其后续版本使用的精确时间函数,并要求计算机从硬件上支持精确定时器。如示例工程中的Timer7、Timer7_1、Timer7_2、Timer7_3。QueryPerformanceFrequency()函数和QueryPerformanceCounter()函数的原型如下:
BOOL QueryPerformanceFrequency(LARGE_INTEGER *lpFrequency);
BOOL QueryPerformanceCounter(LARGE_INTEGER *lpCount);
//数据类型ARGE_INTEGER既可以是一个8字节长的整型数,也可以是两个4字节长的整型数的联合结构, 其具体用法根据编译器是否支持64位而定。该类型的定义如下:
typedef union _LARGE_INTEGER
DWORD LowP// 4字节整型数
LONG HighP// 4字节整型数
LONGLONG QuadP// 8字节整型数
}LARGE_INTEGER ;
  在进行定时之前,先调用QueryPerformanceFrequency()函数获得机器内部定时器的时钟频率,然后在需要严格定时的事件发生之前和发生之后分别调用QueryPerformanceCounter()函数,利用两次获得的计数之差及时钟频率,计算出事件经历的精确时间。下列代码实现1ms的精确定时:
LARGE_INTEGER
LONGLONG QPart1,QPart2;
double dfMinus, dfFreq, dfT
QueryPerformanceFrequency(&litmp);
dfFreq = (double)litmp.QuadP// 获得计数器的时钟频率
QueryPerformanceCounter(&litmp);
QPart1 = litmp.QuadP// 获得初始值
QueryPerformanceCounter(&litmp);
QPart2 = litmp.QuadP//获得中止值
dfMinus = (double)(QPart2-QPart1);
dfTim = dfMinus / dfF// 获得对应的时间值,单位为秒
}while(dfTim&0.001);
  其定时误差不超过1微秒,精度与CPU等机器配置有关。下面的程序用来测试函数Sleep(100)的精确持续时间:
LARGE_INTEGER
LONGLONG QPart1,QPart2;
double dfMinus, dfFreq, dfT
QueryPerformanceFrequency(&litmp);
dfFreq = (double)litmp.QuadP// 获得计数器的时钟频率
QueryPerformanceCounter(&litmp);
QPart1 = litmp.QuadP// 获得初始值
Sleep(100);
QueryPerformanceCounter(&litmp);
QPart2 = litmp.QuadP//获得中止值
dfMinus = (double)(QPart2-QPart1);
dfTim = dfMinus / dfF// 获得对应的时间值,单位为秒  
  由于Sleep()函数自身的误差,上述程序每次执行的结果都会有微小误差。下列代码实现1微秒的精确定时:
LARGE_INTEGER
LONGLONG QPart1,QPart2; double dfMinus, dfFreq, dfT
QueryPerformanceFrequency(&litmp);
dfFreq = (double)litmp.QuadP// 获得计数器的时钟频率
QueryPerformanceCounter(&litmp);
QPart1 = litmp.QuadP// 获得初始值
QueryPerformanceCounter(&litmp);
QPart2 = litmp.QuadP//获得中止值
dfMinus = (double)(QPart2-QPart1);
dfTim = dfMinus / dfF// 获得对应的时间值,单位为秒
}while(dfTim&0.000001);
其定时误差一般不超过0.5微秒,精度与CPU等机器配置有关。
16. 为对话框中的控件增加提示的简单方法我学VC从VC知识库中得到不少好处,相来都是一些热心朋友们的帮助,在此表示感谢!本工程可分五步:1、建一个基于对话框的程序TipTest,在CTipTestDlg中增加成员变量:CToolTipCtrl m_tip[2],CWnd *m_pSub[2];2、在CTipTestDlg::OnInitDialog()函数中增加如下代码:
pSub[0] = GetDlgItem(IDC_RADIO1); //得到单选按钮的指针
pSub[1] = GetDlgItem(IDC_BUTTON1);
m_tip[0].Create(pSub[0],TTS_ALWAYSTIP); //创建
CToolTipCtrl m_tip[0].AddTool(pSub[0]); //将CToolTipCtrl与相应的控件对应起来
m_tip[1].Create(pSub[1],TTS_ALWAYSTIP);
m_tip[1].AddTool(pSub[1]);
m_tip[0].SetTipTextColor(RGB(0,0,255));
//设定文字的颜色
m_tip[0].SetDelayTime(150);
//设定提示文字在控件上停留的时间
3、重载CTipTestDlg::PreTranslateMessage(MSG* pMsg)函数,增加如下代码:
if(m_tip[0].m_hWnd!=NULL)
m_tip[0].RelayEvent(pMsg);
//如果m_tip[0]句柄不为空,就从主窗口中捕获消息,如WM_MOUSEMOVE,WM_LBUTTONDOWN等消息\
if(m_tip[1].m_hWnd!=NULL)
m_tip[1].RelayEvent(pMsg);
4、捕获主窗口的WM_MOUSEMOVE消息,在CTipTestDlg::OnMouseMove(UINT nFlags, CPoint point)函数中增加如下代码:&
m_tip[0].UpdateTipText( VC知识库欢迎你! ,pSub[0]);
//鼠标在相应的控件上移动时显示提示文字
m_tip[1].UpdateTipText( http://vckbase.com ,pSub[1]);
17.删除文件夹
// 删除文件夹及其所有内容
void CBaseDoc::RemoveFolder(const CString &strPathName)
CString path = strPathN
if (path.Right(1) != _T( \\ ))
path += _T( \\ );
path += _T( *.* );
BOOL res = ff.FindFile(path);
while (res)
res = ff.FindNextFile(); // 是文件时直接删除
if (!ff.IsDots() && !ff.IsDirectory())
DeleteFile(ff.GetFilePath());
else if (ff.IsDots())
else if (ff.IsDirectory())
path = ff.GetFilePath();
// 是目录时继续递归,删除该目录下的文件
RemoveFolder(path); ::RemoveDirectory(path);
18.消息映射有对话框A,B从A中发消息给B然后B处理。准备工作,先定义消息,如下
#define&WM_B_NOTIFY WM_USER + 300
首先,必须将B的对话框句柄传送给A,暂时叫m_hWndB;在A的发送消息的地方这样写:
::SendMessage( m_hWndB,WM_B_NOTIFY,TRUE,NULL );
这样A中的处理就完了,下面说B 中的首先定义消息处理函数,如下
void B::ModiNotify( WPARAM wParam, LPARAM lParam )
MessageBox( 小样,我就不信,搞不定你! );
然后加消息隐射,如下:
BEGIN_MESSAGE_MAP(CB, CDialog)
//{{AFX_MSG_MAP(CRPServerDlg)
ON_MESSAGE( WM_B_NOTIFY,ModiNotify )
//}}AFX_MSG_MAP END_MESSAGE_MAP()
19.给从CWnd派生的窗口添加滚动条
ModifyStyle(0,WS_VSCROLL);
20. SetWindowPos函数功能:该函数改变一个子窗口,弹出式窗口式顶层窗口的尺寸,位置和Z序。子窗口,弹出式窗口,及顶层窗口根据它们在屏幕上出现的顺序排序、顶层窗口设置的级别最高,并且被设置为Z序的第一个窗口。      函数原型:BOOL SetWindowPos(HWN hWnd,HWND hWndlnsertAfter,int X,int Y,int cx,int cy,UNIT.Flags);      参数: hWnd:窗口句柄。 hWndlnsertAfter:在z序中的位于被置位的窗口前的窗口句柄。该参数必须为一个窗口句柄,或下列值之一: HWND_BOTTOM:将窗口置于Z序的底部。如果参数hWnd标识了一个顶层窗口,则窗口失去顶级位置,并且被置在其他窗口的底部。 HWND_DOTTOPMOST:将窗口置于所有非顶层窗口之上(即在所有顶层窗口之后)。如果窗口己经是非顶层窗口则该标志不起作用。 HWND_TOP:将窗口置于Z序的顶部。 HWND_TOPMOST:将窗口置于所有非顶层窗口之上。即使窗口未被激活窗口也将保持顶级位置。      查g看该参数的使用方法,请看说明部分。 x:以客户坐标指定窗口新位置的左边界。 Y:以客户坐标指定窗口新位置的顶边界。 cx:以像素指定窗口的新的宽度。 cy:以像素指定窗口的新的高度。 uFlags:窗口尺寸和定位的标志。该参数可以是下列值的组合: SWP_ASNCWINDOWPOS:如果调用进程不拥有窗口,系统会向拥有窗口的线程发出需求。这就防止调用线程在其他线程处理需求的时候发生死锁。 SWP_DEFERERASE:防止产生WM_SYNCPAINT消息。 SWP_DRAWFRAME:在窗口周围画一个边框(定义在窗口类描述中)。 SWP_FRAMECHANGED:给窗口发送WM_NCCALCSIZE消息,即使窗口尺寸没有改变也会发送该消息。如果未指定这个标志,只有在改变了窗口尺寸时才发送WM_NCCALCSIZE。 SWP_HIDEWINDOW;隐藏窗口。 SWP_NOACTIVATE:不激活窗口。如果未设置标志,则窗口被激活,并被设置到其他最高级窗口或非最高级组的顶部(根据参数hWndlnsertAfter设置)。 SWP_NOCOPYBITS:清除客户区的所有内容。如果未设置该标志,客户区的有效内容被保存并且在窗口尺寸更新和重定位后拷贝回客户区。 SWP_NOMOVE:维持当前位置(忽略X和Y参数)。 SWP_NOOWNERZORDER:不改变z序中的所有者窗口的位置。 SWP_NOREDRAW:不重画改变的内容。如果设置了这个标志,则不发生任何重画动作。适用于客户区和非客户区(包括标题栏和滚动条)和任何由于窗回移动而露出的父窗口的所有部分。如果设置了这个标志,应用程序必须明确地使窗口无效并区重画窗口的任何部分和父窗口需要重画的部分。 SWP_NOREPOSITION;与SWP_NOOWNERZORDER标志相同。 SWP_NOSENDCHANGING:防止窗口接收WM_WINDOWPOSCHANGING消息。 SWP_NOSIZE:维持当前尺寸(忽略cx和Cy参数)。 SWP_NOZORDER:维持当前Z序(忽略hWndlnsertAfter参数)。 SWP_SHOWWINDOW:显示窗口。   返回值:如果函数成功,返回值为非零;如果函数失败,返回值为零。若想获得更多错误消息,请调用GetLastError函数。   备注:如果设置了SWP_SHOWWINDOW和SWP_HIDEWINDOW标志,则窗口不能被移动和改变大小。如果使用SetWindowLoog改变了窗口的某些数据,则必须调用函数SetWindowPos来作真正的改变。使用下列的组合标志:SWP_NOMOVEISWP_NOSIZEISWP_FRAMECHANGED。   有两种方法将窗口设为最顶层窗口:一种是将参数hWndlnsertAfter设置为HWND_TOPMOST并确保没有设置SWP_NOZORDER标志;另一种是设置窗口在Z序中的位置以使其在其他存在的窗口之上。当一个窗口被置为最顶层窗口时,属于它的所有窗口均为最顶层窗口,而它的所有者的z序并不改变。   如果HWND_TOPMOST和HWND_NOTOPMOST标志均未指定,即应用程序要求窗口在激活的同时改变其在Z序中的位置时,在参数hWndinsertAfter中指定的值只有在下列条件中才使用:   在hWndlnsertAfter参数中没有设定HWND_NOTOPMOST和HWND_TOPMOST标志。   由hWnd参数标识的窗口不是激活窗口。   如果未将一个非激活窗口设定到z序的顶端,应用程序不能激活该窗口。应用程序可以无任何限制地改变被激活窗口在Z序中的位置,或激活一个窗口并将其移到最高级窗口的顶部或非最高级窗口的顶部。   如果一个顶层窗口被重定位到z序的底部(HWND_BOTTOM)或在任何非最高序的窗口之后,该窗口就不再是最顶层窗口。当一个最顶层窗口被置为非最顶级,则它的所有者窗口和所属者窗口均为非最顶层窗口。   一个非最顶端窗口可以拥有一个最顶端窗口,但反之则不可以。任何属于顶层窗口的窗口(例如一个对话框)本身就被置为顶层窗口,以确保所有被属窗口都在它们的所有者之上。   如果应用程序不在前台,但应该位于前台,就应调用SetForegroundWindow函数来设置。 Windows CE:如果这是一个可见的顶层窗口,并且未指定SWP_NOACTIVATE标志,则这个函数将激活窗口、如果这是当前的激活窗口,并且指定了SWP_NOACTIVATE或SWP_HIDEWINDOW标志,则激活另外一个可见的顶层窗口。   当在这个函数中的nFlags参数里指定了SWP_FRAMECHANGED标志时,WindowsCE重画窗口的整个非客户区,这可能会改变客户区的大小。这也是重新计算客户区的唯一途径,也是通过调用SetwindowLong函数改变窗口风格后通常使用的方法。 SetWindowPos将使WM_WINDOWPOSCHANGED消息向窗口发送,在这个消息中传递的标志与传递给函数的相同。这个函数不传递其他消息。 Windows CE 1.0不支持在hWndlnsertAber参数中的HWND_TOPMOST和HWND_NOTOPMOST常量。 Windows CE1.0不支持在fuFags参数中的SWP_DRAWFRAME和SWP_NOCOPYBITS标志。   速查:Windows NT:3.1以上版本;Windows:95以上版本;Windows CE:1.0以上版本;头文件:winuser.h库文件:eser32lib。
21. 介绍函数过程中一种任意键退出同时能处理消息的实现方法1. 设置定时器,用于使::GetMessage(...)函数总能快速取到消息.2. 在函数处理中加入:函数每执行完一步后执行下面的代码.
if (::GetMessage(&msg, 0, 0, 0))
if (msg.message &= WM_KEYFIRST && msg.message &= WM_KEYLAST)
::TranslateMessage(&msg);
::DispatchMessage(&msg); }
::PostQuitMessage(0);
22. 如何隐藏工具栏添加如下两个函数隐藏:
void CMainFrame::OnHide()
if(m_wndToolBar.IsWindowVisible())
m_wndToolBar.ModifyStyle(WS_VISIBLE,0);
SendMessage(WM_SIZE);
void CMainFrame::OnShow()
if(!m_wndToolBar.IsWindowVisible())
m_wndToolBar.ModifyStyle(0,WS_VISIBLE);
SendMessage(WM_SIZE);
23. 如何动态获取工具条指针并给工具条加标题?[问题提出]工具条也是窗口,是窗口就有标题,如何给工具条加标题?[程序实现]不想动态改变工具条的标题就在CMainFrame::OnCreate()中:
int CMainFrame::OnCreate(LPCREATESTRUCT lpCreateStruct)
...... m_wndToolBar.SetWindowText(_T("Standdard"));
若想动态改变工具条的标题,如下:声明一个菜单,并响应事件,如响应:OnMyToolBar()函数
void CMainFrame::OnMyToolBar()
// TODO: Add your command handler code here
CToolBar *pToolBar = (CToolBar *)AfxGetMainWnd()-&GetDescendantWindow(AFX_IDW_TOOLBAR);
pToolBar-&SetWindowText (_T("Standdard"));
不要在TooBar悬浮时做OnMyToolBar()会出错的.&顺便提一下如何获得状态条的指针:
CStatusBar * pStatusBar =(CStatusBar *)AfxGetMainWnd()-&GetDescendantWindow(AFX_IDW_STATUS_BAR);
24. 在状态条中显示鼠标的设备坐标与逻辑坐标显示器的设备坐标系的原点在客户区的左上角,x轴向右增长,y轴向下增长。我们要设置的逻辑坐标系的原点则在客户区的中心,x轴向右增长,y轴向上增长,如一个笛卡尔坐标系一般。为CChildView添加一个成员函数void OnPrepareDC(CDC * pDC, CPrintInfo * pInfo = NULL);
void OnPrepareDC(CDC * pDC, CPrintInfo * pInfo)
// 设置映射模式为LOMETRIC (0.1mm),右上为增长方向 pDC-&SetMapMode (MM_LOMETRIC);
// 将坐标原点定在客户区的中心
GetClientRect(rect);
DC-&SetViewportOrg(rect.Width()/2, rect.Height()/2);
为CChildView响应鼠标移动消息,并在状态条中显示鼠标的坐标值。m_ptMouse数据成员是原打算做十字交叉线用的,在此使用没有实际意义。
void CChildView::OnMouseMove(UINT nFlags, CPoint point)
CClientDC dc(this);
OnPrepareDC(&dc);
//要访问类CMainFrame,需要将mainfrm.h文件引入
CMainFrame * pFrame = (CMainFrame *) AfxGetApp()-&m_pMainW
//要访问CMainFrame的数据成员m_wndStatusBar,需要手工修改mainfrm.h,public这个数据成员
CStatusBar * pStatus = (CStatusBar *) &pFrame-&m_wndStatusB
m_ptMouse = str.Format ("设备坐标 X=%i pixel, Y=%i pixel", m_ptMouse.x, m_ptMouse.y);
pStatus-&SetPaneText(1, str); dc.DPtoLP(&m_ptMouse);
str.Format ("逻辑坐标 X=%i * 0.1mm, Y=%i * 0.1mm", m_ptMouse.x, m_ptMouse.y);
pStatus-&SetPaneText(2, str);
25. 如何用VC++ 动态修改应用程序菜单[问题提出]  本文将介绍一些使用CMenu的方法,如查找指定菜单,在指定选项前添加菜单项.....[解决方法]  使用CWnd::GetMenu( )访问主菜单,GetMenu( )返回指向CMenu对象的指针,它有一些成员函数,允许我们修改一个菜单。1) 如何实现找到一个菜单项:  步骤如下:
{&//动态修改菜单:&// Get the Main Menu&CMenu* pMainMenu = AfxGetMainWnd()-&GetMenu(); CMenu* pSubMenu = NULL;&int&i;&for&(i=0; i&(int)pMainMenu-&GetMenuItemCount(); i++) { pSubMenu = pMainMenu-&GetSubMenu(i);&if&(pSubMenu && pSubMenu-&GetMenuItemID(0) == ID_FILE_NEW)&break; } CS s.Format("%d",i);//菜单项的位数.&AfxMessageBox(s); ASSERT(pSubMenu); }
2) 动态编辑菜单:  步骤如下(可以用上例的pSubMenu,要加的菜单你自己定义.):1) 添加一个称为Wzd2,命令ID为IDC_NAME_NEW1的菜单命令到该菜单中,可以用:pSubMenu-&AppendMenu(0,IDC_NAME_NEW1,"New&1");2) 在New1前插入New2,可以用:pSubMenu-&InsertMenu(IDC_NAME_NEW1,MF_BYCOMMAND,IDC_NAME_NEW2, "New&2");3) 把New1改变成New3,可以用:pSubMenu-&ModifyMenu(IDC_NAME_NEW1,MF_BYCOMMAND,IDC_NAME_NEW3, "New&3");4) 删除该菜单中第二项,可以用:pSubMenu-&RemoveMenu(1,MF_BYPOSITION);
26. VC++中的3D按钮的编程运行AppWizard生成一个基于对话框的test工程,在对话框中加入一个CButton控件。在CButton控件的General属性页将控件的ID改为IDC_3DTEXTBTN,Caption改为&谁与争疯&,在控件Styles属性页选中OwnerDraw,其余设置保持默认。  用classwizard创建一个新类:C3dTextButton,基类为CButton。为C3dTextButton类添加一个protected的函数void Draw(CDC* pDC, const CRect& rect, UINT state)。如下所示编写代码:
void C3dTextButton::Draw(CDC *pDC, const CRect &rect, UINT state)
GetWindowText(text);
int l=text.GetLength();
CRect rectClient=
//获得控件的字体
CFont* pFont=GetFont();
//确定所选字体有效高度和宽度
pFont-&GetObject(sizeof(LOGFONT),&logfont);
if(logfont.lfHeight==0)
logfont.lfHeight=20;
logfont.lfWidth=0;
//宽度设为0,宽度值由高度确定
logfont.lfWeight=1000;
logfont.lfEscapement=logfont.lfOrientation=0;
CF VERIFY(tryfont.CreateFontIndirect(&logfont));
CFont* pFontOld=pDC-&SelectObject(&tryfont);
//根据控件大小,调整字体的高度,使文本与控件协调
CSize textSizeClient=pDC-&GetTextExtent(text,l);
if(rectClient.Width()*textSizeClient.cy&rectClient.Height()*textSizeClient.cx)
logfont.lfHeight=::MulDiv(logfont.lfHeight,rectClient.Height(),textSizeClient.cy);
logfont.lfHeight = ::MulDiv(logfont.lfHeight,rectClient.Width(),textSizeClient.cx);
//创建并选择协调后的字体
font.CreateFontIndirect(&logfont);
pDC-&SelectObject(&font);
textSizeClient=pDC-&GetTextExtent(text,l);
//确定文本与控件边界的距离minx,miny
int minx=rectClient.left+(rectClient.Width()-textSizeClient.cx)/2;
int miny=rectClient.top+(rectClient.Height()-textSizeClient.cy)/2;
int oldBkMode=pDC-&SetBkMode(TRANSPARENT);
COLORREF textcol=::GetSysColor(COLOR_BTNTEXT);
COLORREF oldTextColor=pDC-&SetTextColor(textcol);
int s=(state&ODS_SELECTED)?-1:+1;
//实现3D效果
pDC-&SetTextColor(::GetSysColor(COLOR_3DDKSHADOW));
pDC-&TextOut(cx-s*2,cy+s*2,text);
pDC-&TextOut(cx+s*2,cy-s*2,text);
pDC-&TextOut(cx+s*2,cy+s*2,text);
pDC-&SetTextColor(::GetSysColor(COLOR_3DHILIGHT));
pDC-&TextOut(cx+s*1,cy-s*2,text);
pDC-&TextOut(cx-s*2,cy+s*1,text);
pDC-&TextOut(cx-s*2,cy-s*2,text);
pDC-&SetTextColor(::GetSysColor(COLOR_3DSHADOW));
pDC-&TextOut(cx-s*1,cy+s*1,text);
pDC-&TextOut(cx+s*1,cy-s*1,text);
pDC-&TextOut(cx+s*1,cy+s*1,text);
pDC-&SetTextColor(::GetSysColor(COLOR_3DLIGHT));
pDC-&TextOut(cx,cy-s*1,text);
pDC-&TextOut(cx-s*1,cy,text);
pDC-&TextOut(cx-s*1,cy-s*1,text);
pDC-&SetTextColor(textcol);
//输出标题
pDC-&TextOut(cx,cy,text);
//恢复设备描述表
pDC-&SetTextColor(oldTextColor);
pDC-&SetBkMode(oldBkMode);
pDC-&SelectObject(pFontOld);
用classwizard重载C3dTextButton类的DrawItem函数。编写代码如下所示:
void C3dTextButton::DrawItem(LPDRAWITEMSTRUCT lpDrawItemStruct)
CDC* pDC=CDC::FromHandle(lpDrawItemStruct-&hDC);
ASSERT_VALID(pDC);
CRect rectClient=lpDrawItemStruct-&rcI
Draw(pDC,rectClient,lpDrawItemStruct-&itemState);
  用classwizard为IDC_3DTEXTBTN建立一个C3dTextButton控件变量m_3dTextButton1。把&3dTextButton.h&加入testDlg头文件。编译并测试应用程序。
27. 如何正确的得到ComBox的指针
CComboBox *mComb = (CComboBox*)GetDlgItem(IDC_DuanCB);
CComboBox *mComb = (CComboBox*)::GetDlgItem(m_hWnd,IDC_DuanCB);
28. 如何让对话框中的CEdit控件类接收对话框的消息////////////////////////////////////////////////// 如何让对话框中的CEdit控件类接收对话框的消息////////////////////////////////////////////////1、在对话框中增加一个ID 为IDC_EDIT1的CEdit1控件2、通过ClassWizard 生成一个基于CEdit的新类CMyEdit,CMyEdit m_wndE3、在对话框OnInitDialog()中,将m_wndEdit子类化,使其能够接受对话框的消息。m_wndEdit.SubclassDlgItem (IDC_EDIT1,this);
29.利用WM_CTLCOLOR消息实现编辑控制(Edit Control)的文本与背景色的改变首先要明白:WM_CTLCOLOR是一个由控制(Control)发送给它父窗口的通知消息(Notification message)。实现步骤:生成一个标准的单文档应用程序框架,假设应用程序的名称为Color。我将利用它的About对话框做示范。在About dialog中添加两个Edit control,设定其ID为IDC_EDIT1与IDC_EDIT2。第一种方法(对应于IDC_EDIT1): 按照标准的Windows编程,由其父窗口的消息处理函数负责处理WM_CTLCOLOR消息。1. 在CAboutDlg中添加一个数据成员:HBRUSH m_brM2. 利用向导映射AboutDlg的WM_CTLCOLOR消息,产生函数:HBRUSH CAboutDlg::OnCtlColor(CDC* pDC, CWnd* pWnd, UINT nCtlColor);pDC是AboutDlg的设备上下文,pWnd是AboutDlg中发送该消息的control指针,nCtlColor市Control的类型编码。对其进行如下修改:
HBRUSH CAboutDlg::OnCtlColor(CDC* pDC, CWnd* pWnd, UINT nCtlColor)
if ((pWnd-&GetDlgCtrlID() == IDC_EDIT1) && (nCtlColor == CTLCOLOR_EDIT))
COLORREF clr = RGB(255,0,0); pDC-&SetTextColor(clr);
//设置红色的文本
clr = RGB(0,0,0);
pDC-&SetBkColor(clr);
//设置黑色的背景
m_brMine = ::CreateSolidBrush(clr);
return m_brM
//作为约定,返回背景色对应的刷子句柄
HBRUSH hbr = CDialog::OnCtlColor(pDC, pWnd, nCtlColor);
第二种方法(对应于IDC_EDIT2):&利用MFC 4.0的新特性: Message reflection。1.利用向导添加一个新的类:CColorEdit,基类为CE2.在CColorEdit中添加一个数据成员: HBRUSH m_bkB3.利用向导映射CColorEdit的"=WM_CTLCOLOR"消息,产生函数:HBRUSH CColorEdit::CtlColor(CDC* pDC, UINT nCtlColor);&对其进行如下修改:
HBRUSH CColorEdit::CtlColor(CDC* pDC, UINT nCtlColor)
COLORREF clr = RGB(0,0,0);
pDC-&SetTextColor(clr);
//设置黑色的文本
clr = RGB(255,0,0);
pDC-&SetBkColor(clr);
//设置红色的背景
m_bkBrush = ::CreateSolidBrush(clr);
return m_bkB
//作为约定,返回背景色对应的刷子句柄
4.利用向导为IDC_EDIT2生成一个数据成员CColorEdit m_5.在定义CAboutDlg的color.cpp文件中加入:#include "coloredit.h"
30. 如何防止密码被非法获取?[问题提出]  这两天大家比较专注在获取Edit密码框的密码.在盗取时,我们如何防范呢?[解决方法]  此方法针对于通过SendMessage向此窗口发送WM_GETTEXT或EM_GETLINE消息来取得密码.跟我来.[程序实现]  方法很简单,用CWnd::DefWindowProc函数拦截得到的消息(向Edit发的).  建立名为My的对话框工程.建立一个Edit控件ID=IDC_EDIT1.建一个新类名为CMyProtectEdit,派生于CEdit.  在MyDlg.cpp中声明全局变量:BOOL g_bIBOOL g_bI  在MyProtecEdit.cpp中:extern BOOL g_bI  响应CMyProtectEdit的DefWindowProc函数:
LRESULT CMyProtectEdit::DefWindowProc(UINT message, WPARAM wParam, LPARAM lParam)
// TODO: Add your specialized code here and/or call the base class
// 对Edit的内容获取必须通过以下两个消息之一,不对其采用默认的处理:
if(( message == WM_GETTEXT) || ( message == EM_GETLINE))
//检查是否为合法
if(!g_bIdentity)
{ //非法获取,显示非法信息
AfxMessageBox(_T("不能让你看我的密码,:( !"));
g_bIdentity = FALSE;
//合法获取
return CEdit::DefWindowProc(message, wParam, lParam);
然后在MyDlg.cpp中
void CMyDlg::DoDataExchange(CDataExchange* pDX)
CDialog::DoDataExchange(pDX);
//{{AFX_DATA_MAP(CGetPasswordDlg)
// NOTE: the ClassWizard will add DDX and DDV calls here
if( pDX-&m_bSaveAndValidate)
g_bIdentity = TRUE;
} //}}AFX_DATA_MAP }
  即可.找个程序(盗取)的试试.
31. 如何在编辑控件中以追加的方式添入字符? [问题提出]  SetDlgItemText可以向Edit控件中输入字符,发送更新的消息也可是Edit控件显示与其关联的变量的值,但若是向已有的Edit字符后追加字符,该如何做? [程序实现]  建立名为My的对话框工程,添加一个Edit和一个Button控件.Edit的ID=IDC_EDIT1,Button的ID=IDC_BUTTON1.建立和IDC_BUTTON1的响应函数:OnButton1()
  void CMyDlg::OnButton1()
    CString pText="你好";
    CEdit *m_Edit=(CEdit *)GetDlgItem(IDC_EDIT1);
    int nLen=m_Edit-&GetWindowTextLength();
    m_Edit-&SetFocus();
    m_Edit-&SetSel(nLen, nLen);
    m_Edit-&ReplaceSel(pText);
在Edit控件中输入字符,想追加时按IDC_BUTTON1按钮.看看效果.
32.属性页标题改名我用CPropertySheet创建属性页,用的CPropertyPage对象只有一个,也就是每个属性页的内容一样.现在的问题是:这样每个属性页的标题都是一样的,是对话框的标题!怎样动态的改变这个标题,使每个属性页的标签的名称都不同??
CTabCtrl * pCtrl = pSheet-&GetTabControl();
tc.mask = TCIF_TEXT;
tc.pszText = "新标题";
pCtrl-&SetItem(0,&tc);//0即是你要改的TAb的索引
33. 怎样去掉属性页的Apply与Help按钮?
//去掉Help
  m_psh.dwFlags |= PSH_HASHELP ;
  m_psh.dwFlags &= ~PSH_HASHELP ;
//除掉应用按钮 
m_psh.dwFlags|=PSH_NOAPPLYNOW;
34. 如何给树控件加入工具提示1.首先给树控件加入TVS_INFOTIP属性风格,如下所示:
if (!m_ctrlTree.Create(WS_CHILD|WS_VISIBLE|
  TVS_HASLINES|TVS_HASBUTTONS|TVS_LINESATROOT|TVS_SHOWSELALWAYS|TVS_INFOTIP, //加入提示TVS_INFOTIP,jingzhou xu(树控件ID:100)
   CRect(0, 0, 0, 0), &m_wndTreeBar, 100))
   TRACE0("Failed to create instant bar child\n");
   return -1;
2.其次加入映射消息声明,如下所示:
afx_msg void OnGetInfoTip(NMHDR* pNMHDR,LRESULT* pResult);    //树控件上加入提示消息,jingzhou xu  
ON_NOTIFY(TVN_GETINFOTIP, 100, OnGetInfoTip)       //树控件条目上加入提示,jingzhou xu
3.最后加入呼应涵数处理:
void CCreateTreeDlg::OnGetInfoTip(NMHDR* pNMHDR, LRESULT* pResult)
 *pResult = 0;
 NMTVGETINFOTIP* pTVTipInfo = (NMTVGETINFOTIP*)pNMHDR;
 LPARAM itemData = (DWORD) pTVTipInfo-&lP
 //对应每个条目的数据
 HTREEITEM hItem = pTVTipInfo-&hI
 HTREEITEM hRootItem = m_chassisTree.GetRootItem();
 if (hRootItem != pTVTipInfo-&hItem)
  tip = "树结点的提示";
  tip = "树根上的提示";
 strcpy(pTVTipInfo-&pszText, (LPCTSTR) tip);
35. 如何在TreeList中加图标? [问题提出] 请问treeview控件和treectrl控件的用法有何不同呢?向如何imagelist控件中加图象呀? [解决方法] 1)
  HICON hicon[8];
  m_imageList.Create(16,16,0,8,8);
  hicon[0]=AfxGetApp()-&LoadIcon(IDI_ICON0);
  hicon[1]=AfxGetApp()-&LoadIcon(IDI_ICON1);
  hicon[2]=AfxGetApp()-&LoadIcon(IDI_ICON2);
  hicon[3]=AfxGetApp()-&LoadIcon(IDI_ICON3);
  hicon[4]=AfxGetApp()-&LoadIcon(IDI_ICON4);
  hicon[5]=AfxGetApp()-&LoadIcon(IDI_ICON5);
  hicon[6]=AfxGetApp()-&LoadIcon(IDI_ICON6);
  hicon[7]=AfxGetApp()-&LoadIcon(IDI_ICON7);
  for(int n=0;n&8;n++)
    m_imageList.Add(hicon[n]);
  CTreeCtrl *pTree=(CTreeCtrl *)GetDlgItem(IDC_TREE);
  pTree-&SetImageList(&m_imageList,TVSIL_NORMAL);
CImageList cil1;
  cil1.Create(32,32,TRUE,2,2);
  cil1.Add(pApp-&LoadIcon(IDI_DAO1));
  cil1.Add(pApp-&LoadIcon(IDI_DAO2));
  cil1.Add(pApp-&LoadIcon(IDI_DAO3));
  cil1.Add(pApp-&LoadIcon(IDI_DAO4));
  cil1.Add(pApp-&LoadIcon(IDI_DAO5));
  cil1.Add(pApp-&LoadIcon(IDI_DAO6));
  cil1.Add(pApp-&LoadIcon(IDI_DAO7));
  cil1.Add(pApp-&LoadIcon(IDI_DAO8));
  cil1.Add(pApp-&LoadIcon(IDI_DAO9));
  //设置图象列表
  m_list.SetImageList(&cil1,LVSIL_NORMAL);
36. 如何双击列表框项启动一个与文件关联的程序?有人问我如何双击列表框项启动一个程序?其实这个问题很简单,Windows中有一个API函数可以打开任何类型的文件:ShellExecute(NULL,"open",lpFileName,NULL,NULL,SW_SHOWNORMAL);参数 lpFileName 是文件的全路径名。用这个变量你可以传递象&C:\\MyExcelFile.xls&或者&http://www.vckbase.com&启动Excel程序或者浏览器程序。如果你只是想获取与文件关联的程序名,而不是要运行程序,那么调用::FindExecutable就可以了。
37. 如何防止在listbox中添加很多数据出现不停的刷新? [问题提出]  在listbox添加很多数据的时候,由于控件不停的刷新,导致出现闪烁,如何解决? [解决方法]  再添加数据以前,禁止控件刷新,数据添加完毕以后,再刷新一次。 [程序实现](其中:m_ListBox是CListBox的控件类型的变量)
  m_ListBox.LockWindowUpdate();//禁止本listbox刷新。
  for(int i=0;i&9999;i++)
     m_ListBox.AddString("test");
  }//添加数据。
  this-&RedrawWindow(NULL,NULL,RDW_INVALIDATE | RDW_UPDATENOW | RDW_ERASE);
38. 如何得到CListBox所选择项的String? [问题提出] 如何得到CListBox所选择项的String [解决方法] 用到:CListBox::GetText() [程序实现]
 CString scI
 pList-&GetText( GetCurSel(),scInfo);
39. 用鼠标移动基于对话框的无标题栏程序的简单方法
void CVCTestDlg::OnLButtonDown(UINT nFlags, CPoint point)
  //一句话解决问题
  SendMessage(WM_SYSCOMMAND,0xF012,0);
  CDialog::OnLButtonDown(nFlags, point);
40. 如何改变框对话或窗体视窗的背景颜色调用CWinApp : : SetDialogBkColor可以改变所有应用程序的背景颜色。第一个参数指定了背景颜色,第二个参数指定了文本颜色。下例将应用程序对话设置为蓝色背景和黄色文本。
BOOL CSampleApp : : InitInstance ( )
//use blue dialog with yellow text .
SetDialogBkColor (RGB (0, 0, 255 ), RGB ( 255 , 255 , 0 ) ) ;
需要重画对话(或对话的子控件)时,Windows向对话发送消息WM_CTLCOLOR,通常用户可以让Windows选择绘画背景的刷子,也可重置该消息指定刷子。下例说明了创建一个红色背景对话的步骤。首先,给对话基类增加一人成员变量CBursh :
class CMyFormView : public CFormView
CBrush m_ // background brush
其次, 在类的构造函数中将刷子初始化为所需要的背景颜色。
CMyFormView : : CMyFormView ( )
// Initialize background brush .
m_brush .CreateSolidBrush (RGB ( 0, 0, 255 ) )
最后,使用ClassWizard处理WM_CTLCOLOR消息并返回一个用来绘画对话背景的刷子句柄。注意:由于当重画对话控件时也要调用该函数,所以要检测nCtlColor参量。
HBRUSH CMyFormView : : OnCtlColor (CDC* pDC , CWnd*pWnd , UINT nCtlColor )
// Determine if drawing a dialog box . If we are , return +handle to
//our own background brush . Otherwise let windows handle it .
if (nCtlColor = = CTLCOLOR _ DLG )
return (HBRUSH) m_brush .GetSafeHandle ( ) ;
return CFormView : : OnCtlColor (pDC, pWnd , nCtlColor );
41.如何禁止对话框关闭按钮和浮动工具条上的系统菜单1、禁止对话框中的关闭按钮有二种方法。第一种方法,用ModiftMenu()涵数来实现:
CMenu* pMenu = this-&GetSystemMenu(FALSE);
pMenu-&ModifyMenu(SC_CLOSE,MF_BYCOMMAND | MF_GRAYED );
第二种方法,用EnableMenuItem()涵数来实现:
CMenu* pMenu = this-&GetSystemMenu(FALSE);
pMenu-&EnableMenuItem( SC_CLOSE, MF_BYCOMMAND|MF_GRAYED);
2、禁止浮动工具条上的系统菜单。新建一个CToolBar的派生类CxxToolBar,在新类中的左键双击(CxxToolBar::OnLButtonDblClk(...))和左键单击(CxxToolBar:: OnLButtonDown(...))涵数中分别加入下面代码既可:
if (IsFloating()) //工具条正在浮动状态中
  CWnd* pMiniF
  CWnd* pDockB
  pDockBar = GetParent();
  pMiniFrame = pDockBar-&GetParent();
  //去除其上系统菜单
  pMiniFrame-&ModifyStyle(WS_SYSMENU, NULL);
  //重绘工具条
  pMiniFrame-&ShowWindow(SW_HIDE);
  pMiniFrame-&ShowWindow(SW_SHOW);
3、禁止窗口最大化按钮
在PreCreateWindow()涵数中去掉WS_MAXIMIZEBOX风格显示既可。
BOOL CxxFrameWnd::PreCreateWindow(CREATESTRUCT& cs)
  cs.style &= ~WS_MAXIMIZEBOX;
  return CFrameWnd::PreCreateWindow(cs);
42.如何拷贝一个工程的对话框资源到另一个工程中? 有两种方法可以实现: 1)你可以直接拷贝resource,用VC++以文本的方式或者直接用文本编辑器打开.rc文件,将有关的片段从一个工程拷贝到另一个工程.你可以通过查找如下字样的片段(此片段用来定义对话框资源)来拷贝你要的部分: IDD_MYDIALOG_ID DIALOG DISCARDABLE 0, 0, 235, 55 这里的IDD_MYDIALOG_ID是你的对话框的ID,将到此片段结尾的部分全拷下来,通常你还要给新的工程加一个ID(通过DevStudio的工具或者直接修改resource.h文件). 2)可以通过DevStudio的copy/paste功能.首先,在编辑器以"auto"模式打开.rc文件,这时resource正确的}

我要回帖

更多关于 梦幻西游跨种族转门派 的文章

更多推荐

版权声明:文章内容来源于网络,版权归原作者所有,如有侵权请点击这里与我们联系,我们将及时删除。

点击添加站长微信