|
|
3/10/2007 没有钱就疯狂追求性价比。呵呵
今天刚刚以1300入手maya v7 17寸液晶显示器。感觉还不错。
纪念下,钱挣了就是花D。 12/11/2006 来广州已经3 个月了,也当了3个月的计算机老师了,总的说来感觉还很不错。
和老师同学的关系处理的也还不错。已经理出点头绪来了。努力向前,绝不后退。 6/27/2006 今天是到公司一年的纪念日,一年很快就过去了。总体来说收获不少。最重要的收获是碰到了好同事。现在的心情很平静,创业的梦想始终没有熄灭。该出手时就出手。需要做的准备真的太多了,只能一步一步向目标前进。现在终于感受到了,不是世界不给你机会,只是你还没有准备好。加油! 6/15/2006 时间过的真快,五一回家看见爸爸妈妈又老了许多。真想多点时间陪他们。 11/14/2005
//打开新的窗体
Response.Redirect("WebMain.aspx");
//弹出一个新窗体
Response.Write("<script>window.open(\"WebMain.aspx\")</script>")
//弹出一个只有确定按钮的提示框
Response.Write("<script>alert(\"用户名或密码错误\");</script>");
//关闭窗体不提示信息
Response.Write("<script>window.opener=null;window.close();</script>");
//关闭窗体提示一条信息
Response.Write("<script>window.close();</script>");
//关闭窗体提示两条信息
Response.Write("<script>if(confirm(\"确定退出?\")==true){window.close();}</script>"); 手机刚周末突然停机,妈妈呼叫未果。急之~,找到我在武汉的高中同学,最后终于把我找到。
后来我回电话给妈妈。妈妈说,你在不回电话我马上来武汉了。我倒~~~ 这么大的人了,妈
还这么担心,可怜天下父母心!
在坛子里经常看到一些关于Session的问题,下面做一个总结,希望对大家有所帮助:
问:为什么Session在有些机器上偶尔会丢失? 答:可能和机器的环境有关系,比如:防火墙或者杀毒软件等,尝试关闭防火墙。
问:为什么当调用Session.Abandon时并没有激发Session_End方法? 答:首先Session_End方法只支持InProc(进程内的)类型的Session。其次要激发Session_End方法,必须存在Session(即系统中已经使用Session了),并且至少要完成一次请求(在这次请求中会调用该方法)。
问:为什么当我在InProc模式下使用Session会经常丢失? 答:该问题通常是由于应用程序被回收导致的,因为当使用进程内Session时,Session是保存在aspnet_wp进程中,当该进程被回收Session自然也就没有了,确定该进程是否被回收可以通过查看系统的事件查看器获得信息。 具体信息请参考: Session variables are lost intermittently in ASP.NET applications http://support.microsoft.com/default.aspx?scid=kb;en-us;Q316148 在1.0的时候也有一个bug会导致工作进程被回收并重启,该bug已经在1.1和sp2中修复。 关于该bug的详细信息请参考: ASP.NET Worker Process (Aspnet_wp.exe) Is Recycled Unexpectedly. http://support.microsoft.com/default.aspx?scid=kb;en-us;Q321792
问:为什么当Session超时或者Abandoned后,新Session的ID和原来的相同? 答:因为SessionID是保存在客户端浏览器的实例里,当Session超时在服务器重新建立Session时,将使用浏览器传来的SessionID,所以当Session超时后,再重新建立后SessionID并不变。
问:为什么每次请求的SessionID都不相同? 答:该问题可能是没有在Session里面保存任何信息引起的,即程序中任何地方都没有使用Session。当Session中保存信息之后SessionID将一直和浏览器相关,此时的SessionID将不会在变化。
问:ASP和ASP.NET之间是否可以共享Session? 答:可以。但是这是一个比较复杂的过程,微软提供了官方的解决方案,请参考:http://msdn.microsoft.com/library/default.asp?url=/library/en-us/dnaspp/html/ConvertToASPNET.asp
问:什么类型的对象可以保存在Session里? 答:这依赖使用的Session的模式,当使用的是进程内(InProc)的Session那么可以轻松的保存任何对象。如果你使用了非InProc的模式,则只能保存可以序列化和反序列化的对象,如果此时保存的对象不支持序列化,则不能保存到这种模式(非InProc)的Session里。
问:为什么在Session_End中不能使用Response.Redirect和Server.Transfer方法跳转页面? 答:Session_End是一个在服务器内部激发的事件处理函数。它是基于一个服务器内部的计时器的,在激发该事件时服务器上并没有相关的HttpRequest对象,因此此时并不能使用Response.Redirect和Server.Transfer方法。
问:在Session_End中是否可以获得HttpContext对象? 答:不行,因为这个事件并没有和任何的请求(Request)相关联,没有基于请求的上下文。
问:在Web Service中该如何使用Session? 答:为了在Web Service中使用Session,需要在Web Service的调用方做一些额外的工作,必须保存和存储调用Web Service时使用的Cookie。详细信息请参考MSDN文档的HttpWebClientProtocol.CookieContainer属性。然而,如果你使用代理服务器访问Web Service由于框架的限制,两者不能共享Session。
问:在自定义自己的HttpHandler的时候,为什么不能使用Session? 答:在实现自己的HttpHandler的时候,如果希望使用Session必须实现下面的两个标记接口中的一个:IRequiresSessionState和IReadOnlySessionState,这些接口没有任何方法需要实现,只是一个标记接口和使用INamingContainer接口的方法一样。
问:当我使用webfarm时,当我重定向到其他的Web服务器时Session为什么会丢失? 答:详细信息请参考: PRB: Session State Is Lost in Web Farm If You Use SqlServer or StateServer Session Mode http://support.microsoft.com/default.aspx?scid=kb;en-us;325056
问:为什么我的Session在Application_OnAcquireRequestState方法中无效? 答:Session只有在HttpApplication.AcquireRequestState事件调用以后才会有效。 详细信息请参考: http://msdn.microsoft.com/library/default.asp?url=/library/en-us/cpguide/html/cpconhandlingpublicevents.asp
问:如果使用了cookieless,我该如何从HTTP页面定向到HTTPS? 答:请尝试下面的方法: String originalUrl = "/fxtest3/sub/foo2.aspx"; String modifiedUrl = "https://localhost" + Response.ApplyAppPathModifier(originalUrl); Response.Redirect(modifiedUrl);
问:Session在global.asax中的那些事件中有效? 答:Session只有在AcquireRequestState事件之后有效,该事件之后的事件都可以使用Session。
问:如何获得当前Session中保存的所有对象? 答:可以通过遍历所有的Session.Keys来获得。代码如下: ArrayList sessionCollection = new ArrayList(); foreach (string strKey in Session.Keys){ sessionCollection.Add(Session[strKey]); } 问:是否可以在不同的应用程序中共享Session? 答:不能直接共享。可以参考如何在ASP和ASP.NET之间共享Session。
问:Session.Abandon和Session.Clear有何不同? 答:主要的不同之处在于当使用Session.Abandon时,会调用Session_End方法(InProc模式下)。当下一个请求到来时将激发Session_Start方法。而Session.Clear只是清除Session中的所有数据并不会中止该Session,因此也不会调用那些方法。 问:为了可以顺序访问Session的状态值,Session是否提供了锁定机制? 答:Session实现了Reader/Writer的锁机制: 当页面对Session具有可写功能(即页面有<%@ Page EnableSessionState="True" %>标记),此时直到请求完成该页面的Session持有一个写锁定。 当页面对Session具有只读功能(即页面有<%@ Page EnableSessionState="ReadOnly" %>标记),此时知道请求完成该页面的Session持有一个读锁定。 读锁定将阻塞一个写锁定;读锁定不会阻塞读锁定;写锁定将阻塞所有的读写锁定。这就是为什么两个框架中的同一个页面都去写同一个Session时,其中一个要等待另一个(稍快的那个)完成后,才开始写。
问:Session平滑超时意味着什么? 答:Session平滑超时意味着只要你的页面访问(使用)了Session,超时时间将被刷新(可以理解为重新计时),即从该页面请求开始,将重新计算超时时间。但是,该页面不能禁用Session。它会自动的访问当前页面的Session,刷新超时时间。 问:在global.asax中的事件处理函数中Session为什么无效? 答:依赖于在哪个事件处理函数中使用Session,Session在AcquireRequestState事件之后才有效,该事件之后的所有事件处理函数都可以使用Session,之前的则不能。
问:当我写一个依赖于当前应用的Session的组件时,为什么不能直接使用Session["Key"]获得其值? 答:Session["Key"]实际上是this.Session["Key"],它是作为Page的一个属性提供的,所以在你的组件中不能直接使用这个属性。你可以通过下面的方式使用Session: HttpContext.Current.Session["Key"] = "My Seesion Value";
问:当我使用InProc模式保存Session时,此时的Session是保存在哪里? 答:不同的IIS的处理方式不同, 当使用的是IIS5的时候Session是保存在aspnet_wp.exe的进程空间里的。 当使用的是IIS6时,默认情况下所有的应用程序共享应用程序池,Session保存在w3wp.exe的进程空间中。
问:Session的超时设置是分钟还是秒? 答:是分钟,默认为20分钟。
问:当页面出现错误后我的Session是否将被保存?我需要在Session_End中处理一些清理工作,但是失败了,为什么? 答:Session_End只有在Session运行在InProc模式下才会被执行。Session_End使用的帐号是运行aspnet_wp工作进程的帐号(这个可以在machine.config中设置)。因此,如果在Session_End方法里,使用集成安全性链接到SQL,它将使用aspnet_wp进程的帐号打开链接,此时成功与否则依赖于你的SQL的安全性设置。 问:为什么当我设置cookieless为true是我在重定向的时候会丢失Session? 答:当使用cookieless时,你必须使用相对路径替换程序中的绝对路径,如果使用绝对路径ASP.NET将无法在URL中保存SessionID。 例如:将\myDir\mySubdir\default.aspx换成..\default.aspx即可。
问:如何将SortedList存储到Session或者Cache里? 答:请参考下面的方法: SortedList x = new SortedList(); x.Add("Key1", "ValueA"); x.Add("Key2", "ValueB"); 保存到Session中: Session["SortedList1"] = x; 使用下面方法获得之: SortedList y = (SortedList) Session["SortedList1"]; Chahe则同理。 问:我为什么会获得这样的错误信息“Session state can only be used when enableSessionState is set to true, either in a configuration file or in the Page directive”? 答:这个问题可能在一个已经安装了Microsoft Visual Studio .NET开发环境的机器上,再安装Window Sharepoint Server(WSS)后出现。 WSS ISAPI过滤器会处理所有的请求。当你通过虚拟目录浏览一个ASP.NET的应用程序时,ISAPI过滤器不会给文件夹目录分配URL。 解决方法是:不要再安装了WSS的机器上使用Session。 详细信息请参考: Session state cannot be used in ASP.NET with Windows SharePoint Services http://support.microsoft.com/default.aspx?scid=kb;en-us;837376
问:如何删除Session变量? 答:想要删除Session变量可以使用HttpSessionState.Remove()方法。 问:是否有办法知道应用程序的Session在运行时占用了多少内存? 答:没有。目前这个值时无法考证的,至少我现在还没有看到这方面的资料。但是可以通过性能监视器以及程序代码大概估算出来一个值。 问:当页面中是否了frameset,发现在每个frame中显示页面的SessionID在第一次请求时都不相同,为什么? 答:原因是你的frameset是放在一个htm页面上而不是ASPX页面。 在一般情况下,如果frameset是aspx页面,当你请求页面时,它首先将请求发送到Web服务器,此时已经获得了SessionID,接着浏览器会分别请求Frame中的其他页面,这样所有页面的SessionID就是一样的,就是FrameSet页面的SessionID。 然而如果你使用Html页面做FrameSet页面,第一个请求将是HTML页面,当该页面从服务器上返回是并没有任何Session产生,接着浏览器会请求Frame里面的页面,这样这些页面都会产生自己的SessionID,所以在这种情况下就会出现这种问题。当你重新刷新页面时,SessionID就会一样,并且是最后一个请求页面的SessionID。 问:是否可以将不同应用程序的Session保存在相同的SQL Server服务器的不同数据库上。 答:可以,请参考: FIX: Using one SQL database for all applications for SQL Server session state may cause a bottleneck http://support.microsoft.com/default.aspx?scid=kb;en-us;836680
问:在Session_End是我是否可以获得有效的HttpSessionState和HttpContext对象? 答:你可以在这个方法中获得HttpSessionState对象,可以直接使用Session来访问即可。但是不能获得HttpContext对象,因为该事件并没有和任何请求相关联,因此不存在上下文对象。
问:在SQLServer模式下使用Session,为什么我的Session不过期? 答:在SqlServer模式下,Session的过期是通过SQL Agent的注册工作完成的,请检查你的SQL Agent是否运行? 问:当我设置EnableSessionState为“ReadOnly”后,但是我在InProc模式下依然可以修改Session的值,这是为什么? 答:即使EnableSessionState标示为ReadOnly,但是在InProc模式下用户依然可以编辑Session。唯一不同的是,在请求过程中Session将不会被锁住。
问:我如何才能避免在链接SQL时指定密码? 答:使用信任链接或者使用加密的链接串。有关这方面的详细信息请参考: How To Use the ASP.NET Utility to Encrypt Credentials and Session State Connection Strings http://support.microsoft.com/default.aspx?scid=kb;en-us;329290
问:我在我自己的类中该如何使用Session呢? 答:可以使用HttpContext.Current.Session方式使用,具体方法如下: HttpContext.Current.Session["SessionKey"] = "SessionValue"; 类似的你还可以使用这种方式使用Application对象。
问:为什么在切换成SQLServer模式后我的请求被挂起了? 答:检查在Session里面是否都保存的是可以保存在SQLServer模式下的对象,即这些对象必须支持序列化。
问:当Session设置成cookieless后会有什么影响? 答:当把cookieless设置成true时,主要会有下面的约束: 1、在页面中不能使用绝对链接 2、在应用程序中在除了Http和Https之间的切换时需要完成一些其他的步骤。 如果发送一个链接给其他人,此时的URL里面将包含Session ID的信息,所以两个人将公用一个Session。
问:是否可以将Session保存在数据库中? 答:当然可以,详细信息请参考:http://support.microsoft.com/default.aspx?scid=kb;en-us;311209 11/13/2005 买了一张2000盘,买了一套.NET,买了一张SQLSERVER.回家一试,还好就数据库盘子是坏的
,其他的都装好了。HOHO ,最近在忙一个武钢的项目。忙完了估计就1月份了。时间过的真的是快
的不行。
6/20/2005 第一个例子:
char* ss = "0123456789"; sizeof(ss) 结果 4 ===》ss是指向字符串常量的字符指针 sizeof(*ss) 结果 1 ===》*ss是第一个字符 char ss[] = "0123456789"; sizeof(ss) 结果 11 ===》ss是数组,计算到\0位置,因此是10+1 sizeof(*ss) 结果 1 ===》*ss是第一个字符 char ss[100] = "0123456789"; sizeof(ss) 结果是100 ===》ss表示在内存中的大小 100×1 strlen(ss) 结果是10 ===》strlen是个函数内部实现是用一个循环计算到\0为止之前 int ss[100] = "0123456789"; sizeof(ss) 结果 400 ===》ss表示再内存中的大小 100×4 strlen(ss) 错误 ===》strlen的参数只能是char* 且必须是以''\0''结尾的 char q[]="abc"; char p[]="a\n"; sizeof(q),sizeof(p),strlen(q),strlen(p); 结果是 4 3 3 2 第二个例子: class X { int i; int j; char k; }; X x; cout<<sizeof(X)<<endl; 结果 12 ===》内存补齐 cout<<sizeof(x)<<endl; 结果 12 同上 第三个例子: char szPath[MAX_PATH] 如果在函数内这样定义,那么sizeof(szPath)将会是MAX_PATH,但是将szPath作为虚参声明时(void fun(char szPath[MAX_PATH])),sizeof(szPath)却会是4(指针大小)
- 1.sizeof操作符的结果类型是size_t,它在头文件中typedef为unsigned int类型。该类型保证能容纳实现所建立的最大对象的字节大小。
- 2.sizeof是算符,strlen是函数。
- 3.sizeof可以用类型做参数,strlen只能用char*做参数,且必须是以''\0''结尾的。sizeof还可以用函数做参数,比如: short f(); printf("%d\n", sizeof(f())); 输出的结果是sizeof(short),即2。
- 4.数组做sizeof的参数不退化,传递给strlen就退化为指针了。
- 5.大部分编译程序 在编译的时候就把sizeof计算过了 是类型或是变量的长度这就是sizeof(x)可以用来定义数组维数的原因 char str[20]="0123456789"; int a=strlen(str); //a=10; int b=sizeof(str); //而b=20;
- 6.strlen的结果要在运行的时候才能计算出来,时用来计算字符串的长度,不是类型占内存的大小。
- 7.sizeof后如果是类型必须加括弧,如果是变量名可以不加括弧。这是因为sizeof是个操作符不是个函数。
- 8.当适用了于一个结构类型时或变量, sizeof 返回实际的大小, 当适用一静态地空间数组, sizeof 归还全部数组的尺 寸。 sizeof 操作符不能返回动态地被分派了的数组或外部的数组的尺寸
- 9.数组作为参数传给函数时传的是指针而不是数组,传递的是数组的首地址,如: fun(char [8]) fun(char []) 都等价于 fun(char *) 在C++里传递数组永远都是传递指向数组首元素的指针,编译器不知道数组的大小如果想在函数内知道数组的大小, 需要这样做:进入函数后用memcpy拷贝出来,长度由另一个形参传进去 fun(unsiged char *p1, int len) { unsigned char* buf = new unsigned char[len+1] memcpy(buf, p1, len); } 有关内容见: C++ PRIMER?
- 10.计算结构变量的大小就必须讨论数据对齐问题。为了CPU存取的速度最快(这同CPU取数操作有关,详细的介绍可以参考一些计算机原理方面的书),C++在处理数据时经常把结构变量中的成员的大小按照4或8的倍数计算,这就叫数据对齐(data alignment)。这样做可能会浪费一些内存,但理论上速度快了。当然这样的设置会在读写一些别的应用程序生成的数据文件或交换数据时带来不便。MS VC++中的对齐设定,有时候sizeof得到的与实际不等。一般在VC++中加上#pragma pack(n)的设定即可.或者如果要按字节存储,而不进行数据对齐,可以在Options对话框中修改Advanced compiler页中的Data alignment为按字节对齐。
- 11.sizeof操作符不能用于函数类型,不完全类型或位字段。不完全类型指具有未知存储大小的数据类型,如未知存储大小的数组类型、未知内容的结构或联合类型、void类型等。如sizeof(max)若此时变量max定义为int max(),sizeof(char_v) 若此时char_v定义为char char_v [MAX]且MAX未知,sizeof(void)都不是正确形式
6/1/2005 一、攻击力(Attack Power,简称AP)的计算公式: Warrior/Paladin:AP=角色等级*3+力量*2-20 Hunter/Rogue:AP=角色等级*2+力量+敏捷-20 Shaman:AP=角色等级*2+力量*2-20 Druid:AP=力量*2-20 Mage/Priest/Warlock:AP=力量-10 角色DPS=AP/14+武器DPS 单次攻击伤害(最小/最大)=攻击速度*AP/14+武器伤害(最小/最大)+技能附加伤害 二、防御力(Armor)的计算公式: 1敏捷(Agilty)=2Armor Armor减少伤害%=0.75%*防御力/(攻击方等级+9) 例:防御力5000的角色, 被61级敌人攻击时,可以减少伤害0.75%*5000/(61+9)=53.6% 被51级敌人攻击时,可以减少伤害0.75%*5000/(51+9)=62.5% 伤害减小值的封顶值是75%,这时角色的防御力为100*(敌人等级+9),也就是说杀62级敌人时防御要在7100以上才能达到封顶效果。我不知道现在最高防御能达到多少,但在绝大多数情况下,杀同等级敌人是不可能达到封顶值的。 三、敏捷对物理攻击重击(crit)、闪避(Dodge)几率影响的计算公式: 在不计装备和天赋影响的情况下,重击和闪避几率受以下因素影响: 1.重击/闪避的基础值和变化值 角色的重击/闪避几率中,有一部分是不受敏捷影响的(这里称为基础值),另外一部分受敏捷影响(这里称为变化值)。 角色重击/闪避的计算公式为:基础值+变化值*角色的敏捷/敏捷标准值。 对一般的职业来说,当角色敏捷等于标准值的时候,重击/闪避几率为5%。也就是说基础值+变化值=5%。变化值越高表示敏捷对这个职业的影响越大。 敏捷标准值是与等级和职业相关的一个参数。1级时一般职业的标准值为20,盗贼和猎人为23。60级的时候战士敏捷标准值100,即敏捷100时重击/闪避几率为5%。 敏捷标准值似乎没有计算公式,是通过查表获得的,也可以自己推算,我在后面会附上算法,大家有兴趣可以自己计算。 各个职业的重击/闪避基础值和变化值: Rogue:重击基础值0%,变化值10%;闪避基础值0%,变化值20% Hunter:重击基础值0%,变化值5%;闪避基础值0%,变化值10% Warrior:基础值0%,变化值5% Paladin:基础值0.7%,变化值4.3% Druid:基础值0.9%,变化值4.1% Shaman:基础值1.7%,变化值3.3% Warlock:基础值2%,变化值3% Priest:基础值3%,变化值2% Mage:基础值3.2%,变化值1.8% 2.角色的武器技能等级(熟练度)和防御技能等级 即属性栏里显示的attack和defense。其中attack影响角色重击几率,defense影响角色闪避几率。具体来说就是重击/闪避受一个(attack(或defense)*0.04-等级/5)%的修正。 大家知道角色每升一级attack/defense上限会增加5级,正好和等级/5抵消,也就是说如果把attack/defense修满,重击/闪避几率就不受任何惩罚,如果没有修满,则每差一个等级减少0.04%的重击/闪避几率.。反之如果通过装备把attack/defense加的超过上限就会有额外奖励。 例:一个60级战士,敏捷90,defense330级,那么他的闪避为0+5%*90/100+(330*0.04-60/5)%=5.7% 四、格挡几率(Block)和招架几率(Parry) 基本几率5%,受防御技能(defense)的影响,每级防御技能增加0.04%格挡/招架几率。或者说同闪避一样受(defense*0.04-等级/5)%的修正 附:角色敏捷标准值的算法 首先注意把与重击/闪避或者防御技能相关的装备都拿掉,最好不要加任何天赋,战士不能出于,以免引起混乱。 记录敏捷值A和闪避/重击几率D。将attack/defense对D值的修正还原,如你的角色武器技能差N级达到上限,就在D上加N*0.04%。 敏捷标准值=敏捷A/(1+(闪避或重击几率D值-5%)/闪避或重击变化值) 最后,可以更换一下敏捷装备,使敏捷发生变化,再根据上面给的公式检验一下计算结果是否正确。 重击几率可以在角色的基本技能“Attack”上查看,闪避几率可以在角色的基本技能“Dodge”上查看
5/30/2005 BOOL CDlgReportOut::PreTranslateMessage(MSG* pMsg) { // TODO: Add your specialized code here and/or call the base class CWnd *pNextWnd = NULL; CWnd *pPrevWnd = NULL; CEdit *pEdit = NULL; CButton *pButton = NULL; CComboBox *pCmbBox = NULL; CListBox *pListBox = NULL; int m_nType = -1, m_nNextType = -1; bool m_bEditLeft = false;; bool m_bEditRight = false; CString str; pPrevWnd = GetFocus(); if(!pPrevWnd) return CDialog::PreTranslateMessage(pMsg); if(pMsg->message == WM_KEYDOWN && pMsg->wParam == VK_RETURN && pPrevWnd->GetDlgCtrlID() == IDC_BUTTON_PRINT) { PostMessage(WM_COMMAND, MAKELONG(pPrevWnd->GetDlgCtrlID(), BN_CLICKED), 0L); return TRUE; } if(pMsg->message == WM_KEYDOWN && pMsg->wParam == VK_RETURN && pPrevWnd->GetDlgCtrlID() == IDC_CHECK_WORK)// First button { ((CButton*)GetDlgItem(IDC_CHECK_WORK))->SetCheck(!((CButton*)GetDlgItem(IDC_CHECK_WORK))->GetCheck()); //OnCheckAttendinfo(); return TRUE; } if(pMsg->message == WM_KEYDOWN && (pMsg->wParam == VK_RETURN || pMsg->wParam == VK_LEFT || pMsg->wParam == VK_RIGHT || pMsg->wParam == VK_UP || pMsg->wParam == VK_DOWN)) { if(pPrevWnd->IsKindOf(RUNTIME_CLASS(CEdit))) { int nX, nY; pEdit = (CEdit*)pPrevWnd; pEdit->GetWindowText(str); pEdit->GetSel(nX, nY); if(nX == nY && nY == 0) m_bEditLeft = true; if(nX == nY && nY == str.GetLength()) m_bEditRight = true; if(str.GetLength() <= 0) m_bEditRight = m_bEditLeft = true; m_nType = 1; } else if(pPrevWnd->IsKindOf(RUNTIME_CLASS(CButton))) { pButton = (CButton*)pPrevWnd; m_nType = 2; } else if(pPrevWnd->IsKindOf(RUNTIME_CLASS(CComboBox))) { pCmbBox = (CComboBox*)pPrevWnd; m_nType = 3; } else if(pPrevWnd->IsKindOf(RUNTIME_CLASS(CListBox))) { pListBox = (CListBox*)pPrevWnd; m_nType = 4; } switch(pMsg->wParam) { case VK_RETURN: pNextWnd = GetNextDlgTabItem(pPrevWnd, FALSE); break; case VK_LEFT: if((m_nType == 1 && m_bEditLeft) || m_nType == 2) pNextWnd = GetNextDlgTabItem(pPrevWnd, TRUE); break; case VK_RIGHT: if((m_nType == 1 && m_bEditRight) || m_nType == 2) pNextWnd = GetNextDlgTabItem(pPrevWnd, FALSE); break; case VK_UP: if(m_nType == 1 || m_nType == 2) pNextWnd = GetNextDlgTabItem(pPrevWnd, TRUE); break; case VK_DOWN: if(m_nType == 1 || m_nType == 2) pNextWnd = GetNextDlgTabItem(pPrevWnd, FALSE); break; default: break; } if(pNextWnd) { if(pNextWnd->IsKindOf(RUNTIME_CLASS(CEdit))) { pEdit = (CEdit*)pNextWnd; pEdit->SetSel(0, -1); m_nNextType = 1; } else if(pNextWnd->IsKindOf(RUNTIME_CLASS(CButton))) { pButton = (CButton*)pNextWnd; m_nNextType = 2; } else if(pNextWnd->IsKindOf(RUNTIME_CLASS(CComboBox))) { pCmbBox = (CComboBox*)pNextWnd; m_nNextType = 3; } else if(pNextWnd->IsKindOf(RUNTIME_CLASS(CListBox))) { pListBox = (CListBox*)pNextWnd; m_nNextType = 4; } pNextWnd->SetFocus(); } } return CDialog::PreTranslateMessage(pMsg); } 5/27/2005 VC编程规范-程序员应该这样写代码 基本要求 1.1 程序结构清析,简单易懂,单个函数的程序行数不得超过100行。 1.2 打算干什么,要简单,直接了当,代码精简,避免垃圾程序。 1.3 尽量使用标准库函数和公共函数。 1.4 不要随意定义全局变量,尽量使用局部变量。 1.5 使用括号以避免二义性。
2.可读性要求 2.1 可读性第一,效率第二。 2.2 保持注释与代码完全一致。 2.3 每个源程序文件,都有文件头说明,说明规格见规范。 2.4 每个函数,都有函数头说明,说明规格见规范。 2.5 主要变量(结构、联合、类或对象)定义或引用时,注释能反映其含义。 2.7 常量定义(DEFINE)有相应说明。 2.8 处理过程的每个阶段都有相关注释说明。 2.9 在典型算法前都有注释。 2.10 利用缩进来显示程序的逻辑结构,缩进量一致并以Tab键为单位,定义Tab为 6个字节。 2.11 循环、分支层次不要超过五层。 2.12 注释可以与语句在同一行,也可以在上行。 2.13 空行和空白字符也是一种特殊注释。 2.14 一目了然的语句不加注释。 2.15 注释的作用范围可以为:定义、引用、条件分支以及一段代码。 2.16 注释行数(不包括程序头和函数头说明部份)应占总行数的 1/5 到 1/3 。
3. 结构化要求 3.1 禁止出现两条等价的支路。 3.2 禁止GOTO语句。 3.3 用 IF 语句来强调只执行两组语句中的一组。禁止 ELSE GOTO 和 ELSE RETURN。 3.4 用 CASE 实现多路分支。 3.5 避免从循环引出多个出口。 3.6 函数只有一个出口。 3.7 不使用条件赋值语句。 3.8 避免不必要的分支。 3.9 不要轻易用条件分支去替换逻辑表达式。
4. 正确性与容错性要求 4.1 程序首先是正确,其次是优美 4.2 无法证明你的程序没有错误,因此在编写完一段程序后,应先回头检查。 4.3 改一个错误时可能产生新的错误,因此在修改前首先考虑对其它程序的影响。 4.4 所有变量在调用前必须被初始化。 4.5 对所有的用户输入,必须进行合法性检查。 4.6 不要比较浮点数的相等, 如: 10.0 * 0.1 == 1.0 , 不可靠 4.7 程序与环境或状态发生关系时,必须主动去处理发生的意外事件,如文件能否逻辑锁定、打印机是否联机等。 4.8 单元测试也是编程的一部份,提交联调测试的程序必须通过单元测试。
5. 可重用性要求 5.1 重复使用的完成相对独立功能的算法或代码应抽象为公共控件或类。 5.2 公共控件或类应考虑OO思想,减少外界联系,考虑独立性或封装性。 5.3 公共控件或类应建立使用模板。
附:C++ 编程规范,delphi作相应的参考 .1适用范围 本标准适用于利用Visul C++ ,Borland C++进行软件程序开发的人员.。 .2变量命名 命名必须具有一定的实际意义,形式为xAbcFgh,x由变量类型确定,Abc、Fgh表示连续意 义字符串,如果连续意义字符串仅两个,可都大写.如OK. 具体例程: BOOL类型 bEnable; ch * char chText c * 类对象 cMain(对象实例) h * Handle(句柄) hWnd i * int n * 无符号整型 p * 指针 sz,str * 字符串 w WORD x,y 坐标 Char或者TCHAR类型 与Windows API有直接联系的用szAppName[10]形式否则用 FileName[10]形式,单个字符也可用小写字母表示; Int类型 nCmdShow; LONG类型 lParam; UINT类型 uNotify; DWORD类型 dwStart; PSTR类型 pszTip; LPSTR类型 lpCmdLine LPTSTR类型 lpszClassName; LPVOID类型 lpReserved WPARAM类型 wParam, LPARAM类型 lParam HWND类型 hDlg; HDC类型 hDC; HINSTANCE类型 hInstance HANDLE类型 hInstance, HICON类型 hIcon; int iTmp float fTmp DWORD dw* String , AnsiString str * m_ 类成员变量 m_nVal, m_bFlag g_ 全局变量 g_nMsg, g_bFlag 局部变量中可采用如下几个通用变量:nTemp,nResult,I,J(一般用于循环变量)。其他资源句柄同上 .3常量命名和宏定义 常量和宏定义必须具有一定的实际意义; 常量和宏定义在#include和函数定义之间; 常量和宏定义必须全部以大写字母来撰写,中间可根据意义的连续性用下划线连接,每一条定义的右侧必须有一简单的注释,说明其作用; 资源名字定义格式: 菜单:IDM_XX或者CM_XX 位图:IDB_XX 对话框:IDD_XX 字符串:IDS_XX DLGINIT:DIALOG_XX ICON:IDR_XX .4函数命名 函数原型说明包括引用外来函数及内部函数,外部引用必须在右侧注明函数来源: 模块名及文件名, 如是内部函数,只要注释其定义文件名; 第一个字母必须使用大写字母,要求用大小写字母组合规范函数命名,必要时可用下划线间隔,示例如下: void UpdateDB_Tfgd (TRACK_NAME); //Module Name :r01/sdw.c void PrintTrackData (TRACK_NAME); //Module Name :r04/tern.c void ImportantPoint (void); //Module Name :r01/sdw.c void ShowChar (int , int , chtype); //Local Module void ScrollUp_V (int , int); //Local Module .5结构体命名 结构体类型命名必须全部用大写字母,原则上前面以下划线开始;结构体变量命名必须用大小写字母组合,第一个字母必须使用大写字母,必要时可用下划线间隔。对于私有数据区,必须注明其所属的进程。全局数据定义只需注意其用途。
示例如下: typedef struct { char szProductName[20]; char szAuthor[20]; char szReleaseDate[16]; char szVersion[10]; unsigned long MaxTables; unsigned long UsedTables; }DBS_DATABASE; DBS_DATABASE GdataBase; 6 控件的命名: 用小写前缀表示类别 用小写前缀表示类别: fm 窗口 cmd 按钮 cob combo,下拉式列表框 txt 文本输入框 lab labal,标签 img image,图象 pic picture grd Grid,网格 scr 滚动条 lst 列表框 frm fram 7注释 原则上注释要求使用中文; 文件开始注释内容包括:公司名称、版权、作者名称、时间、模块用途、背景介绍等,复杂的算法需要加上流程说明; 函数注释包括:输入、输出、函数描述、流程处理、全局变量、调用样例等,复杂的函数需要加上变量用途说明; 程序中注释包括:修改时间和作者、方便理解的注释等; 引用一: 文件开头的注释模板 /****************************************************************** ** 文件名: ** Copyright (c) 1998-1999 *********公司技术开发部 ** 创建人: ** 日 期: ** 修改人: ** 日 期: ** 描 述: ** ** 版 本: **-------------------------------------------------------------------------- --- ******************************************************************/ 引用二: 函数开头的注释模板 /***************************************************************** ** 函数名: ** 输 入: a,b,c ** a--- ** b--- ** c--- ** 输 出: x--- ** x 为 1, 表示... ** x 为 0, 表示... ** 功能描述: ** 全局变量: ** 调用模块: ** 作 者: ** 日 期: ** 修 改: ** 日 期: ** 版本 ****************************************************************/ 引用三: 程序中的注释模板 /*----------------------------------------------------------*/ /* 注释内容 */ /*----------------------------------------------------------*/ 8 程序 a. 程序编码力求简洁,结构清晰,避免太多的分支结构及太过于技巧性的程序,尽量不采用递归模式。 b. 编写程序时,亦必须想好测试的方法,换句话说,”单元测试” 的测试方案应在程序编写时一并拟好。 c. 注释一定要与程序一致。 d. 版本封存以后的修改一定要将老语句用/* */ 封闭,不能自行删除或修改,并要在文件及函数的修改记录中加以记录。 e. 程序中每个block 的开头 ”{" 及 "}” 必须对齐,嵌套的block 每进一套,缩进一个tab,TAB 为4个空格,block类型包括if、for、while、do等关键字引出的。 f. 对于比较大的函数,每个block 和特殊的函数调用,都必须注明其功能,举例如下 : count.divisor = 1193280 / freq; // compute the proper count OutByte((unsigned short)67, (unsigned char)182); // tell 8253 that a count is coming OutByte((unsigned short)66, count. c[0]); // send low-order byte OutByte((unsigned short)66, count. c[1]); // send high-order byte ××××××××××××××××××××××××××××××××××××××× bcb,delphi中的变量命名: 遵循匈牙利命名法,命 名必须有意义,制定如下规定 窗体: 以大写的W开始,如About版权窗体, 命名为WAbout 文件:以大写的F开始,如About版权窗体,文件命名为FAbout.cpp 按钮(Button):如退出按钮,命名为btnExit …… 基类: 加base标记,如报表基类,窗体命名为:WBaseRep, 文件命名为FBaseRep.cpp  if (ShowMessageBox(m_hWnd,"W02-02000")==IDYES) { CString strDW; strDW.Format("\r\n"); CString strFile; CString strContent; COleDateTime currentDate=COleDateTime::GetCurrentTime(); static char BASED_CODE szFilter[]="CSV Files (*.csv)|*.csv|All Files (*.*)|*.*||"; strFile = currentDate.Format("%Y%m%d")+"_設計書(様式甲) 金額あり」.csv"; CFileDialog dlg(FALSE,NULL,strFile,OFN_HIDEREADONLY|OFN_OVERWRITEPROMPT,szFilter,NULL); if(dlg.DoModal()==IDOK) { CString fileName=dlg.GetPathName(); if(fileName.Find(".csv")==-1) fileName+=".csv"; CString strQiJian,strDataRifu,strYearMon; strDataRifu.Format("%d%d%d",m_arDesignFirData[0].m_limit_design.GetYear(),m_arDesignFirData[0].m_limit_design.GetMonth(),m_arDesignFirData[0].m_limit_design.GetDay()); strQiJian.Format("%d,",m_arDesignFirData[0].m_period_design); strYearMon.Format("%d%d%d",m_arDesignFirData[0].m_drawdate_design.GetYear(),m_arDesignFirData[0].m_drawdate_design.GetMonth(),m_arDesignFirData[0].m_drawdate_design.GetDay()); CFile file((LPCTSTR)strFile,CFile::modeNoTruncate|CFile::modeCreate|CFile::modeReadWrite); strContent+="設計書(様式甲),"+strDW file.SeekToBegin(); file.Write((void*)(LPCTSTR)strContent,strContent.GetLength()); file.Close(); } } 5/26/2005 CString strD; (char *)(LPCTSTR)m_arQiDongData[0].m_name_design (char *)(LPCTSTR)strD 5/25/2005 这段时间工作特别忙,我为了不加班,白天使劲工作。把加班才能干完的事情在白天给解决掉了,我发现这样做很累,至少精神上很累。好想好好休息下。 5/21/2005 一个善于沟通的人,一个人际关系良好的人,是每个人都愿意去交往的,但是现实往往不是这样,因为下属和上师之间存在着位置差异,存在背景差异。要想合理的处理人际关系,必须学会换位思考。同样一件事,站在领导者的角度,也许这样做是合理的,但是站在员工的角度也许这样做并不合理。这时该怎么办呢?我认为,在出现分歧的时候,领导者要注重领导的艺术,也就是说,一个关心下属,爱护下属,为下属着想的领导是个好领导。这里非常重要的就是领导的沟通能力,领导必须十分了解下属的工作情况,以及思想动态,这样才能站在员工的角度与之沟通。才能有效的教育下属,鼓舞下属。做为员工,说话,做事因该有分寸,因为你的一举一动很可能在你不经意的情况下得罪了你的上师,也许你的举动,让上司感觉你不合群体,影响整个团队。这样势必会在以后的共事中出现冲突,小则给你穿小鞋,大则让你背包走人。如果你是一个不善于沟通的人,那么结果估计比较难堪,如果你及早的和上司沟通协调估计能处理好之间的关系。让其大则化小,小则化了。 最后一点最关键:在公司上班, 做为一个程序员 因该少说话,多做事。积极和经理沟通工作情况,其他的观点最好不要发表。有什么不满直接找老总去沟通吧(如果你够有种的话),不要因为你的不满而影响到整个团队的不满。 我想只要你善于去一点点的改善自己,你会比其他人先到达成功彼岸。做事先做人,这点很关键。 5/20/2005 1、不说“不可能”; 2、凡事第一反应: 找方法,不找借口; 3、遇到挫折对自己说声:太好了,机会来了! 4、不说消极的话,不落入消极的情绪,一旦发生立即正面处理; 5、凡事先订立目标; 6、行动前,预先做计划; 7、工作时间,每一分、每一秒做有利于生产的事情; 8、随时用零碎的时间做零碎的事情; 9、守时; 10、写点日记,不要太依靠记忆; 11、随时记录想到的灵感; 12、把重要的观念、方法写下来,随时提示自己; 13、走路比平时快30%,肢体语言健康有力,不懒散、萎靡; 14、每天出门照镜子,给自己一个自信的微笑; 15、每天自我反省一次; 16、每天坚持一次运动; 17、听心跳一分钟,在做重要的事情,疲劳时,紧张时,烦躁时。。。。 18、开会做前排; 19、微笑; 20、用心倾听,不打断对方的话; 21、说话有力,感觉自己的声音能产生感染力的磁场; 22、说话之前,先考虑一下对方的感觉; 23、每天有意识赞美别人三次以上; 24、即使表示感谢,如果别人帮助了你的话; 25、控制住不要让自己作出为自己辩护的第一反应; 26、不用训斥、指责的口吻与别人说话; 27、每天做一件”分外事“; 28、不关任何方面,每天必须至少做一次”进步一点点“,并且有意识的提高; 29、每天提前15分上班,推迟30分下班; 30、每天下班前5分钟做一下今天的整理工作; 31、定期存钱; 32、节俭; 33、时常运用”头脑风暴“,利用脑力激荡提升自己创新能力; 34、恪守诚信; 35、学会原谅。 5/19/2005 #include stdio.h int BinarySearch(const int A[], int key, int N) { int Low, Mid, High; Low = 0; High = N - 1; while(Low <= High) { Mid = (Low + High) / 2; if(A[Mid] < key) Low = Mid + 1; else if(A[Mid] > key) High = Mid - 1; else return Mid; } } void main() { int temp,size; int a[]={1,5,3,6,7}; for(int i = 0;i < 4; i++) { for(int j = 0;j < 4-i; j++) { if(a[j] > a[j+1]) { temp = a[j]; a[j] =a[j+1]; a[j+1] = temp; } } } printf("BinarySearch: %d\n", BinarySearch(a[], 7, 4)); } 5/18/2005 为了原创点子能出现,你必须让它们在内心世界里渗透,让它们在那里不受我们自己的愿望和自己的方针所约束。然后通过一些未知的,随机组合力量的推动,而让它们出现。正是经过这种重新组合,而不是人为的直接推动,新生事物才会涌现。 void CAdditionSystemPrtView::OnBeginPrinting(CDC* pDC, CPrintInfo* pInfo) { // TODO: 印刷前の特別な初期化処理を追加してください。 CFormView::OnBeginPrinting(pDC, pInfo); } void CAdditionSystemPrtView::OnEndPrinting(CDC* pDC, CPrintInfo* pInfo) { // TODO: 印刷後の後処理を追加してください。 CFormView::OnEndPrinting(pDC, pInfo); } BOOL CAdditionSystemPrtView::OnPreparePrinting(CPrintInfo* pInfo) { return DoPreparePrinting(pInfo); } void CAdditionSystemPrtView::OnPrint(CDC* pDC, CPrintInfo* pInfo) { } ON_COMMAND(ID_FILE_PRINT, CFormView::OnFilePrint) ON_COMMAND(ID_FILE_PRINT_DIRECT, CFormView::OnFilePrint) ON_COMMAND(ID_FILE_PRINT_PREVIEW, CFormView::OnFilePrintPreview) CWnd *pWnd = NULL ; void CAdditionSystemPrtView::OnButtonPrintcsv() { CString sBuf ; sBuf.Empty() ; pWnd = AfxGetMainWnd(); if(pWnd) { pWnd->ModifyStyle(NULL, WS_MAXIMIZEBOX | WS_THICKFRAME, SWP_NOMOVE); pWnd->ShowWindow(SW_SHOWMAXIMIZED); sBuf.Format ("%s - %s - Preview", "設計積算システム", "AdditionSystemPrt"); pWnd->SetWindowText(sBuf); } AfxGetMainWnd()->SendMessage(WM_COMMAND, ID_FILE_PRINT_PREVIEW); } 准备好了就可以弹出打印预览框了。如果你的打印按钮并不在view中 那你怎么调用view中的打印预览呢,很简单,只需要在你的对话框中获取 view的指针对象,然后调用相应的消息处理函数就行了。 首先在view中定义 int m_nTop, m_nRight, m_nLeft, m_nBottom; int m_nTopMargin, m_nRightMargin, m_nLeftMargin, m_nBottomMargin; int m_nCurPageWork;//记录当前页面 int m_nMaxPage;//分页的最大页面 在OnPrint(CDC* pDC, CPrintInfo* pInfo)中对打印位置进行初始化。 CRect prtrect; pDC->SetMapMode(MM_LOMETRIC); prtrect.top = pInfo->m_rectDraw.top; prtrect.left = pInfo->m_rectDraw.left; prtrect.right = pInfo->m_rectDraw.right; prtrect.bottom = pInfo->m_rectDraw.bottom; pDC->DPtoLP(&prtrect); m_nTop = prtrect.top; m_nRight = prtrect.right; m_nLeft = prtrect.left; m_nBottom = prtrect.bottom; m_nLeftMargin = (m_nRight - m_nLeft - RECT_HEIGHT) / 2; m_nTopMargin = (m_nTop - m_nBottom - RECT_WIDTH) / 2; m_nRightMargin = m_nLeftMargin; m_nBottomMargin = m_nTopMargin; 初始化好了 m_nCurPageWork=pInfo->m_nCurPage; m_nMaxPage=pInfo->GetMaxPage(); 就可以写 相应的Draw 函数了。 int nLeftline = m_nLeft + m_nLeftMargin; int nTopline = m_nTop - m_nTopMargin; int nRightline = m_nRight - m_nRightMargin; int nBottomline = m_nBottom + m_nBottomMargin; int nRightlineGrid = nRightline; int nLeftlineGrid = nLeftline; int nToplineGrid = nTopline -180; int nBottomlineGrid = nBottomline ; int nGW = (nRightlineGrid - nLeftlineGrid)/35; int nGH = (-nBottomlineGrid + nToplineGrid)/42; 画好表单之后,就可以组织表单的数据结构了,一般的帐票输出系统组织数据结构 不外乎就是建立模版数组。 class CDesignListData { public: CDesignListData(); virtual ~CDesignListData(); CString m_name_level2; //--レベル2名称(merge要素) CString m_id_cost; //--コード CString m_name_level3; //レベル3名称(項目1) CString m_name_cost; //--レベル4名称(項目2) CString m_std_cost; //--レベル5名称(規格) CString m_num_design_detail; //--数量 CString m_name_list; //--単位 CString m_price_cost; //--単価(円) CString m_price_design_detail; //--金額(円) CString m_remarks_design_detail;//--備考 }; typedef CArray<CDesignListData,CDesignListData&> CDesignListDataArray; 注意在别处定义你的数组对象的时候要把头文件加上哦~~~定义好数组后,你就可以连接数据库将数据读入到内存中来了。 CDBC 和 ADO 两种方式都可以访问数据库。各有优缺点。以后再慢慢分析。数据读出来之后。就可以将数据打印到相应的表单中了。现在就会遇到分页的问题。不要紧 我们有m_nCurPageWork=pInfo->m_nCurPage来记录当前页面。下面给个例子。 if (m_arDesignListData.GetSize()<=16) { for (i=0,k=0;i <m_arDesignListData.GetSize();i++,k++) { } } else { for (i = (m_nCurPageWork-1)*16;i<m_nCurPageWork*16&&i< m_arDesignListData.GetSize();i++,k++) { } } 这是最简单的打印预览,以后介绍复杂点的打印预览的动态统计功能,及相应的按天分页等等。学无止境。 5/17/2005 喜欢吸烟的我,更喜欢品烟。先从常抽的道来。个人觉得性价比最高,也适合于长期抽得为4.5圆一包的红金龙。 焦油含量1.5mg 烟气烟碱量 1.1mg,该烟为典型的烤烟型,烟丝卷的比较整齐,吸食起来味道比较纯正。555的香烟分为KING 和 LIGHT型,后者比较清淡,前者劲比较大,提神醒脑作用强。偶尔也抽抽摩尔的香烟,该烟味为薄荷型。适合于清新下自己的口气(玩笑咯),但是长期抽会让人感觉到腻人。就像肥肉吃多了一样的感觉,因此仅限于好玩的时候抽抽。有人说,抽烟要抽淡的, 别人推荐说抽中南海比较好,但是我觉得中南海的烟味道怪怪的,的确焦油含量小,但我感觉那不像在吸烟。到东北去了一段时间,抽得最多的就是人民大会堂。该烟不是很纯,劲比较大,适合于烟龄烟瘾较大的人。云南的烟我也比较喜欢。像红塔山,云烟都是以前抽得比较多的。湖南的烟给我的感觉就是醇香,像白沙的烟我的影响很深刻。还有芙蓉后,芙蓉王更是让我心醉。去年12月份在东北,我买了一盒雪茄,没想到雪茄真是太美味了。吸食起来比较费劲,但是的确会让你精神焕发。建议小烟民不要去尝试。(小心晕倒) 嘿嘿 就说这么多了。还有很多以后再写吧。 5/16/2005 武汉的夏日又悄悄来临。热气弥漫着整个城市,中午吃了碗牛肉炒饭回公司后已是大汗淋漓,公司的空调又不争气,缓缓的呼吸着。一个字 热 !
|
|
|
|