登录
首页 » C# » listview 分页示例

listview 分页示例

于 2013-10-02 发布
0 209
下载积分: 1 下载次数: 0

代码说明:

listview 分页示例

下载说明:请别用迅雷下载,失败请重下,重下不扣分!

发表评论

0 个回复

  • windows hook 技术
    对于HOOK函数的一点认识一、序言对大多数的Windows开发者来说,如何在Win32系统中对API函数的调用进行拦截一直是项极富挑战性的课题,因为这将是对你所掌握的计算机知识较为全面的考验,尤其是一些在如今使用RAD进行软件开发时并不常用的知识,这包括了操作系统原理、汇编语言甚至是关于机器指令代码的(听上去真是有点恐怖,不过这是事实)。当前广泛使用的Windows操作系统中,像Win 9x和WinNT/2K,都提供了一种比较稳健的机制来使得各个进程的内存地址空间之间是相互独立,也就是说一个进程中的某个有效的内存地址对另一个进程来说是无意义的,这种内存保护措施大大增加了系统的稳定性。不过,这也使得进行系统级的API拦截的工作的难度也大大加大了。                 当然,我这里所指的是比较文雅的拦截方式,通过修改可执行文件在内存中的映像中有关代码,实现对API调用的动态拦截;而不是采用比较暴力的方式,直接对可执行文件的磁盘存储中机器代码进行改写。                   二、API钩子系统一般框架通常,我们把拦截API的调用的这个过程称为是安装一个API钩子(API Hook)。一个API钩子至少有两个模块组成:一个是钩子服务器(Hook Server)模块,一般为EXE的形式;一个是钩子驱动器Hook Driver)模块,一般为DLL的形式。                                   服务器主要负责向目标进程注入驱动器,使得驱动器工作在目标进程的地址空间中,这是关键的第一步。驱动器则负责实际的API拦截工作,以便在我们所关心的API函数调用的前后能做一些我们需要的工作。                                   一个大家比较常见的API钩子的例子就是一些实时翻译软件(像金山词霸)中必备的的功能:屏幕抓词,它主要是对一些GDI函数进行了拦截,获取它们的输入参数中的字符串,然后在自己的窗口中显示出来。针对上述的两个部分,有以下两点需要我们重点考虑的:选用何种DLL注入技术采用何种API拦截机制                   三、注入技术的选用由于在Win32系统中各个进程的地址是互相独立的,因此我们无法在一个进程中对另一个进程的代码进行有效的修改。而你要完成API钩子的工作就必须进行这种操作。因此,我们必须采取某种独特的手段,使得API钩子(准确的说是钩子驱动器)能够成为目标进程中的一部分,才有较大的可能来对目标进程数据和代码进行有控制的修改。                  通常有以下几种注入方式:1.利用注册表如果我们准备拦截的进程连接了User32.dll,也就是使用了User32中的API(一般图形界面的应用程序都符合这个条件),那么就可以简单把你的钩子驱动器DLL的名字作为值添加在下面注册表的键下:                 HKEY_LOCAL_MACHINESoftwareMicrosoftWindowsNTCurrentVersionWindowsAppInit_DLLs                 值的形式可以为单个DLL的文件名,或者是一组DLL的文件名,相邻的名称之间用逗号或空格间隔。所有由该值标识的DLL将在符合条件的应用程序启动的时候装载。这是一个操作系统内建的机制,相对其他方式来说危险性较小,但它有一些比较明显的缺点:该方法仅适用于NT/2K操作系统。看看键的名称你就应该明白为了激活或停止钩子的注入,必须重新启动Windows。这个就似乎太不方便了不能用此方法向没有使用User32的应用程序注入DLL,例如控制台应用程序不管需要与否,钩子DLL将注入每一个GUI应用程序,这将导致整个系统性能的下降                                   2.建立系统范围的Windows钩子要向某个进程注入DLL,一个十分普遍也是比较简单的方法就是建立在标准的Windows钩子的基础上。Windows钩子一般是在DLL中实现的,这是一个全局性的Windows钩子的基本要求,这也符合我们的需要。当我们成功地调用SetWindowsHookEx函数之后,便在系统中安装了某种类型的消息钩子,这个钩子可以是针对某个进程,也可以是针对系统中的所有进程。一旦某个进程中产生了该类型的消息,操作系统会自动把该钩子所在的DLL映像到该进程的地址空间中,从而使得消息回调函数(在SetWindowsHookEx的参数中指定)能够对此消息进行适当的处理,在这里,我们所感兴趣的当然不是对消息进行什么处理,因此在消息回调函数中只需把消息钩子向后传递就可以了,但是我们所需的DLL已经成功地注入了目标进程的地址空间,从而可以完成后续工作。                                   我们知道,不同进程中使用的DLL之间是不能直接共享数据的,因为它们活动在不同的地址空间中。但在Windows钩子DLL中,有一些数据,例如Windows钩子句柄HHook,这是由SetWindowsHookEx函数返回值得到的,并且作为参数将在CallNextHookEx函数和UnhookWindoesHookEx函数中使用,显然使用SetWindowsHookEx函数的进程和使用CallNextHookEx函数的进程一般不会是同一个进程,因此我们必须能够使句柄在所有的地址空间中都是有效的有意义的,也就是说,它的值必须必须在这些钩子DLL所挂钩的进程之间是共享的。为了达到这个目的,我们就应该把它存储在一个共享的数据区域中。                  在VC 中我们可以采用预编译指令#pragma data_seg在DLL文件中创建一个新的段,并且在DEF文件中把该段的属性设置为“shared”,这样就建立了一个共享数据段。对于使用Delphi的人来说就没有这么幸运了:没有类似的比较简单的方法(或许是有的,但我没有找到)。不过我们还是可以利用内存映像技术来申请使用一块各进程可以共享的内存区域,主要是利用了CreateFileMapping和MapViewOfFile这两个函数。这倒是一个通用的方法,适合所有的开发语言,只要它能使用Windows的API。                  在Borland的BCB中有一个指令#pragma codeseg与VC 中的#pragma data_seg指令有点类似,应该也能起到一样的作用,但我试了一下,没有没有效果,而BCB的联机帮助中对此也提到的不多,不知怎样才能正确的使用。一旦钩子DLL加载进入目标进程的地址空间后,在我们调用UnHookWindowsHookEx函数之前是无法使它停止工作的,除非目标进程关闭。                  这种DLL注入方式有两个优点: 这种机制在Win 9x/Me和WinNT/2K中都是得到支持的,预计在以后的版本中也将得到支持.                 钩子DLL可以在不需要的时候,可由我们主动的调用UnHookWindowsHookEx来卸载,比起使用注册表的机制来说方便了许多 尽管这是一种相当简洁明了的方法,但它也有一些显而易见的缺点:                 首先值得我们注意的是,Windows钩子将会降低整个系统的性能,因为它额外增加了系统在消息处理方面的时间                 其次,只有当目标进程准备接受某种消息时,钩子所在的DLL才会被系统映射到该进程的地址空间中,钩子才能真正开始发挥作用。因此如果我们要对某些进程的整个生命周期内的API调用情况进行监控,用这种方法显然会遗漏某些API的调用                   3.使用CreateRemoteThread函数在我看来这是一个相当棒的方法,然而不幸的是,CreateRemoteThread这个函数只能在WinNT/2K系统中才得到支持,虽然在Win9x中这个API也能被安全的调用而不出错,但它除了返回一个空值之外什么也不做。整个DLL注入过程十分简单。我们知道,任何一个进程都可以使用LoadLibrary来动态地加载一个DLL。但问题是,我们如何让目标进程在我们的控制下来加载我们的钩子DLL(也就是钩子驱动器)呢?这里有一个API函数CreateRemoteThread,通过它可在一个进程中可建立并运行一个远程的线程。                  调用该API需要指定一个线程函数指针作为参数,该线程函数的原型如下:Function ThreadProc(lpParam: Pointer):DWORD;我们再来看一下LoadLibrary的函数原型:Function LoadLibrary(lpFileName: PChar):HModule;可以看出,这两个函数原型实质上是完全相同的(其实返回值是否相同关系不大,因为我们是无法得到远程线程函数的返回值的),只是叫法不同而已,这种相同使得我们可以把直接把LoadLibrary当做线程函数来使用,从而在目标进程中加载钩子DLL。                                   类似的,当我们需要卸载钩子DLL时,也可以FreeLibrary作为线程函数来使用,在目标进程中移去钩子DLL。一切看来是十分的简洁方便。通过调用GetProcAddress函数,我们可以得到LoadLibrary函数的地址。由于LoadLibrary是Kernel32中的函数,而这个系统DLL的映射地址对每一个进程来说都是相同的,因此LoadLibrary函数的地址也是如此。这点将确保我们能把该函数的地址作为一个有效的参数传递给CreateRemoteThread使用。 AddrOfLoadLibrary :=  GetProcAddress(GetModuleHandle(‘Kernel32.dll’),‘LoadLibrary’); HremoteThread := CreateRemoteThread(HTargetProcess,nil,0,AddrOfLoadLibrary,HookDllName,0,nil);                                   要使用CreateRemoteThread,我们需要目标进程的句柄作为参数。当我们用OpenProcess函数来得到进程的句柄时,通常是希望对此进程有全权的存取操作,也就是以PROCESS_ALL_ACCESS为标志打开进程。但对于一些系统级的进程,直接这样显然是不行的,只能返回一个的空句柄(值为零)。为此,我们必须把自己设置为拥有调试级的特权,这样将具有最大的存取权限,从而使得我们能对这些系统级的进程也可以进行一些必要的操作。                   4.通过BHO来注入DLL 有时,我们想要注入DLL的对象仅仅是Internet Explorer。幸运的是,Windows操作系统为我们提供了一个简单的归档的方法(这保证了它的可靠性)―― 利用Browser Helper Objects(BHO)。一个BHO是一个在DLL中实现的COM对象,它主要实现了一个IObjectWithSite接口,而每当IE运行时,它会自动加载所有实现了该接口的COM对象。                   四、拦截机制在钩子应用的系统级别方面,有两类API拦截的机制――内核级的拦截和用户级的拦截。内核级的钩子主要是通过一个内核模式的驱动程序来实现,显然它的功能应该最为强大,能捕捉到系统活动的任何细节,但难度也较大,不在我们探讨的范围之内(尤其对我这个使用Delphi的人来说,还没涉足这块领域,因此也无法探讨);                                   而用户级的钩子则通常是在普通的DLL中实现整个API的拦截工作,这才是我们现在所重点关注的。拦截API函数的调用,一般可有以下几种方法: 1.代理DLL(特洛伊木马)一个容易想到的可行的方法是用一个同名的DLL去替换原先那个输出我们准备拦截的API所在的DLL。当然代理DLL也要和原来的一样,输出所有函数。如果想到DLL中可能输出了上百个函数,我们就应该明白这种方法的效率是不高的。另外,我们还得考虑DLL的版本问题。                                   2.改写执行代码有许多拦截的方法是基于可执行代码的改写。其中一个就是改变在CALL指令中使用的函数地址,这种方法有些难度,也比较容易出错。它的基本思路是检索出在内存中所有你所要拦截的API的CALL指令,然后把原先的地址改成为你自己提供的函数的地址。                                   另外一种代码改写的方法的实现方法更为复杂,它的主要的实现步骤是先找到原先的API函数的地址,然后把该函数开始的几个字节用一个JMP指令代替(有时还不得不改用一个INT指令),使得对该API函数的调用能够转向我们自己的函数调用。实现这种方法要牵涉到一系列压栈和出栈这样的较底层的操作,显然对我们的汇编语言和操作系统底层方面的知识是一种考验。这个方法倒和很多病毒的感染机制相类似。                                   3.以调试器的身份进行拦截另一个可选的方法是在目标函数中安置一个调试断点,使得进程运行到此处就进入调试状态。然而这样一些问题也随之而来,其中较主要的是调试异常的产生将把进程中所有的线程都挂起。它也需要一个额外的调试模块来处理所有的异常,整个进程将一直在调试状态下运行,直至它运行结束。                 4.改写输入地址表这种方法主要得益于现如今Windows系统中所使用的可执行文件(包括EXE文件和DLL文件)的良好结构――PE文件格式(Portable Executable File Format),因此它相当稳健,又简单易行。要理解这种方法是如何运作的,首先你得对PE文件格式有所理解。                  一个PE文件的结构大致如下图所示:                 一般PE文件一开始是一段DOS程序,当你的程序在不支持Windows的环境中运行时,它就会显示“This Program cannot be run in DOS mode”这样的警告语句,接着这个DOS文件头,就开始真正的PE文件内容了。首先是一段称为“IMAG E_NT_HEADER”的数据,其中是许多关于整个PE文件的消息,在这段数据的尾端是一个称为Data Directory的数据表,通过它能快速定位一些PE文件中段(section)的地址。在这段数据之后,则是一个“IMAGE_SECTION_HEADER”的列表,其中的每一项都详细描述了后面一个段的相关信息。接着它就是PE文件中最主要的段数据了,执行代码、数据和资源等等信息就分别存放在这些段中。                                   在所有的这些段里,有一个被称为“.idata”的段(输入数据段)值得我们去注意,该段中包含着一些被称为输入地址表(IAT,Import Address Table)的数据列表。每个用隐式方式加载的API所在的DLL都有一个IAT与之对应,同时一个API的地址也与IAT中一项相对应。当一个应用程序加载到内存中后,针对每一个API函数调用,相应的产生如下的汇编指令:JMP DWORD PTR [XXXXXXXX]                  如果在VC 中使用了_delcspec(import),那么相应的指令就成为 CALL DWORD PTR [XXXXXXXX]。                                   不管怎样,上述方括号中的总是一个地址,指向了输入地址表中一个项,是一个DWORD,而正是这个DWORD才是API函数在内存中的真正地址。因此我们要想拦截一个API的调用,只要简单的把那个DWORD改为我们自己的函数的地址,那么所有关于这个API的调用将转到我们自己的函数中去,拦截工作也就宣告顺利的成功了。这里要注意的是,自定义的函数的调用形式应该是API的调用方式,也就是stdcall方式,而Delphi中默认的是pascal的调用方式,也就是register方式,它们在参数的传递方式等方面存在着较大的区别。                                   另外,自定义的函数的参数形式可以和原先的API函数相同的,不过这也不是必须的,而且这样的话在有些时候也会出现一些问题,我在后面将会提到。因此要拦截API的调用,首先我们就要得到相应的IAT的地址。系统把一个进程模块加载到内存中,其实就是把PE文件几乎是原封不动的映射到进程的地址空间中去,而模块句柄HModule实际上就是模块映像在内存中的地址,PE文件中一些数据项的地址,都是相对于这个地址的偏移量,因此被称为相对虚拟地址(RVA,Relative Virtual Address)。                                   于是我们就可以从HModule开始,经过一系列的地址偏移而得到IAT的地址。不过我这里有一个简单的方法,它使用了一个现有的API函数                 ImageDirectoryEntryToData,它帮助我们在定位IAT时能少走几步,省得把偏移地址弄错了,走上弯路。不过纯粹使用RVA从HModule开始来定位IAT的地址其实并不麻烦,而且这样还更有助于我们对PE文件的结构的了解。上面提到的API函数是在DbgHelp.dll中输出的(这是从Win2K才开始有的,在这之前是由ImageHlp.dll提供的),有关这个函数的详细介绍可参见MSDN。                                   在找到IAT之后,我们只需在其中遍历,找到我们需要的API地址,然后用我们自己的函数地址去覆盖它。下面给出一段对应的源码: procedure RedirectApiCall; var ImportDesc:PIMAGE_IMPORT_DESCRIPTOR; FirstThunk:PIMAGE_THUNK_DATA32; sz:DWORD; begin //得到一个输入描述结构列表的首地址,每个DLL都对应一个这样的结构 ImportDesc:=ImageDirectoryEntryToData(Pointer(HTargetModule),true,IMAGE_DIRECTORY_ENTRY_IMPORT,sz); while Pointer(ImportDesc.Name)nil do      begin //判断是否是所需的DLL输入描述        if StrIComp(PChar(DllName),PChar(HTargetModule ImportDesc.Name))=0            then begin            //得到IAT的首地址            FirstThunk:=PIMAGE_THUNK_DATA32(HTargetModule ImportDesc.FirstThunk);            while FirstThunk.Funcnil do                begin                if FirstThunk.Func=OldAddressOfAPI then 
    2020-12-06下载
    积分:1
  • Csharp winform抽奖程序 源码下载
    Csharp winform抽奖程序 源码下载
    2015-02-27下载
    积分:1
  • C#程序的157个建议(含源代码)
    目录前 言第一部分 语言篇第1章 基本语言要素 / 2建议1:正确操作字符串 / 2建议2:使用默认转型方法 / 6建议3:区别对待强制转型与as和is / 9建议4:TryParse比Parse好 / 12建议5:使用int?来确保值类型也可以为null / 15建议6:区别readonly和const的使用方法 / 16建议7:将0值作为枚举的默认值 / 19建议8:避免给枚举类型的元素提供显式的值 / 20建议9:习惯重载运算符 / 22建议10:创建对象时需要考虑是否实现比较器 / 23建议11:区别对待==和Equals / 27建议12:重写Equals时也要重写GetHashCode / 29建议13:为类型输出格式化字符串 / 32建议14:正确实现浅拷贝和深拷贝 / 36建议15:使用dynamic来简化反射实现 / 40第2章 集合和LINQ / 43建议16:元素数量可变的情况下不应使用数组 / 43建议17:多数情况下使用foreach进行循环遍历 / 45建议18:foreach不能代替for / 51建议19:使用更有效的对象和集合初始化 / 53建议20:使用泛型集合代替非泛型集合 / 54建议21:选择正确的集合 / 57建议22:确保集合的线程安全 / 61建议23:避免将List作为自定义集合类的基类 / 64建议24:迭代器应该是只读的 / 67建议25:谨慎集合属性的可写操作 / 68建议26:使用匿名类型存储LINQ查询结果 / 70建议27:在查询中使用Lambda表达式 / 73建议28:理解延迟求值和主动求值之间的区别 / 75建议29:区别LINQ查询中的IEnumerable和IQueryable / 78建议30:使用LINQ取代集合中的比较器和迭代器 / 80建议31:在LINQ查询中避免不必要的迭代 / 83第3章 泛型、委托和事件 / 86建议32:总是优先考虑泛型 / 86建议33:避免在泛型类型中声明静态成员 / 88建议34:为泛型参数设定约束 / 90建议35:使用default为泛型类型变量指定初始值 / 92建议36:使用FCL中的委托声明 / 94建议37:使用Lambda表达式代替方法和匿名方法 / 96建议38:小心闭包中的陷阱 / 99建议39:了解委托的实质 / 103建议40:使用event关键字为委托施加保护 / 106建议41:实现标准的事件模型 / 108建议42:使用泛型参数兼容泛型接口的不可变性 / 109建议43:让接口中的泛型参数支持协变 / 111建议44:理解委托中的协变 / 112建议45:为泛型类型参数指定逆变 / 114第4章 资源管理和序列化 / 116建议46:显式释放资源需继承接口IDisposable / 116建议47:即使提供了显式释放方法,也应该在终结器中提供隐式清理 / 119建议48:Dispose方法应允许被多次调用 / 120建议49:在Dispose模式中应提取一个受保护的虚方法 / 121建议50:在Dispose模式中应区别对待托管资源和非托管资源 / 123建议51:具有可释放字段的类型或拥有本机资源的类型应该是可释放的 / 124建议52:及时释放资源 / 125建议53:必要时应将不再使用的对象引用赋值为null / 127建议54:为无用字段标注不可序列化 / 131建议55:利用定制特性减少可序列化的字段 / 136建议56:使用继承ISerializable接口更灵活地控制序列化过程 / 137建议57:实现ISerializable的子类型应负责父类的序列化 / 140第5章 异常与自定义异常 / 144建议58:用抛出异常代替返回错误代码 / 144建议59:不要在不恰当的场合下引发异常 / 147建议60:重新引发异常时使用Inner Exception / 150建议61:避免在finally内撰写无效代码 / 151建议62:避免嵌套异常 / 157建议63:避免“吃掉”异常 / 160建议64:为循环增加Tester-Doer模式而不是将try-catch置于循环内 / 161建议65:总是处理未捕获的异常 / 162建议66:正确捕获多线程中的异常 / 166建议67:慎用自定义异常 / 168建议68:从System.Exception或其他常见的基本异常中派生异常 / 170建议69:应使用finally避免资源泄漏 / 172建议70:避免在调用栈较低的位置记录异常 / 175第6章 异步、多线程、任务和并行 / 177建议71:区分异步和多线程应用场景 / 177建议72:在线程同步中使用信号量 / 180建议73:避免锁定不恰当的同步对象 / 184建议74:警惕线程的IsBackground / 188建议75:警惕线程不会立即启动 / 189建议76:警惕线程的优先级 / 191建议77:正确停止线程 / 193建议78:应避免线程数量过多 / 194建议79:使用ThreadPool或BackgroundWorker代替Thread / 196建议80:用Task代替ThreadPool / 198建议81:使用Parallel简化同步状态下Task的使用 / 202建议82:Parallel简化但不等同于Task默认行为 / 204建议83:小心Parallel中的陷阱 / 205建议84:使用PLINQ / 208建议85:Task中的异常处理 / 209建议86:Parallel中的异常处理 / 214建议87:区分WPF和WinForm的线程模型 / 216建议88:并行并不总是速度更快 / 220建议89:在并行方法体中谨慎使用锁 / 222第二部分 架构篇 第7章 成员设计 / 226建议90:不要为抽象类提供公开的构造方法 / 226建议91:可见字段应该重构为属性 / 226建议92:谨慎将数组或集合作为属性 / 227建议93:构造方法应初始化主要属性和字段 / 228建议94:区别对待override和new / 229建议95:避免在构造方法中调用虚成员 / 235建议96:成员应优先考虑公开基类型或接口 / 236建议97:优先考虑将基类型或接口作为参数传递 / 237建议98:用params减少重复参数 / 237建议99:重写时不应使用子类参数 / 238建议100:静态方法和实例方法没有区别 / 239建议101:使用扩展方法,向现有类型“添加”方法 / 240第8章 类型设计 / 243建议102:区分接口和抽象类的应用场合 / 243建议103:区分组合和继承的应用场合 / 245建议104:用多态代替条件语句 / 248建议105:使用私有构造函数强化单例 / 251建议106:为静态类添加静态构造函数 / 253建议107:区分静态类和单例 / 255建议108:将类型标识为sealed / 255建议109:谨慎使用嵌套类 / 256建议110:用类来代替enum / 257建议111:避免双向耦合 / 260建议112:将现实世界中的对象抽象为类,将可复用对象圈起来就是命名空间 / 262第9章 安全性设计 / 264建议113:声明变量前考虑最大值 / 264建议114:MD5不再安全 / 265建议115:通过HASH来验证文件是否被篡改 / 268建议116:避免用非对称算法加密文件 / 269建议117:使用SSL确保通信中的数据安全 / 273建议118:使用SecureString保存密钥等机密字符串 / 284建议119:不要使用自己的加密算法 / 289建议120:为程序集指定强名称 / 289建议121:为应用程序设定运行权限 / 291第三部分 编码规范及习惯 第10章 命名规范 / 296建议122:以.为命名空间命名 / 296建议123:程序集不必与命名空间同名 / 296建议124:考虑在命名空间中使用复数 / 297建议125:避免用FCL的类型名称命名自己的类型 / / 297建议126:用名词和名词组给类型命名 / 298建议127:用形容词组给接口命名 / 299建议128:考虑让派生类的名字以基类名字作为后缀 / 300建议129:泛型类型参数要以T作为前缀 / 300建议130:以复数命名枚举类型,以单数命名枚举元素 / 301建议131:用PascalCasing命名公开元素 / 302建议132:考虑用类名作为属性名 / 302建议133:用camelCasing命名私有字段和局部变量 / 303建议134:有条件地使用前缀 / 304建议135: 考虑使用肯定性的短语命名布尔属性 / 305建议136:优先使用后缀表示已有类型的新版本 / 306建议137:委托和事件类型应添加上级后缀 / 307建议138:事件和委托变量使用动词或形容词短语命名 / 308建议139:事件处理器命名采用组合方式 / 309第11章 代码整洁 / 311建议140:使用默认的访问修饰符 / 311建议141:不知道该不该用大括号时,就用 / 312建议142:总是提供有意义的命名 / 314建议143:方法抽象级别应在同一层次 / 315建议144:一个方法只做一件事 / 316建议145:避免过长的方法和过长的类 / 317建议146:只对外公布必要的操作 / 318建议147:重构多个相关属性为一个类 / 319建议148:不重复代码 / 320建议149:使用表驱动法避免过长的if和switch分支 / 321建议150:使用匿名方法、Lambda表达式代替方法 / 324建议151:使用事件访问器替换公开的事件成员变量 / 325建议152:最少,甚至是不要注释 / 326建议153:若抛出异常,则必须要注释 / 326第12章 规范开发行为 / 327建议154:不要过度设计,在敏捷中体会重构的乐趣 / 327建议155:随生产代码一起提交单元测试代码 / 336建议156:利用特性为应用程序提供多个版本 / 342建议157:从写第一个界面开始,就进行自动化测试 / 344
    2015-09-15下载
    积分:1
  • wpf 漂亮的UI界面(含左侧导航菜单)
    wpf 漂亮的UI界面(含左侧导航菜单)
    2019-03-19下载
    积分:1
  • C# 二进制文件读写示例(dat文件)
    C# 二进制文件读写示例(dat文件)
    2018-06-08下载
    积分:1
  • C#右下角弹窗提醒 例子源码
    C#右下角弹窗提醒 例子源码
    2015-06-26下载
    积分:1
  • PSO粒子群算法(亲测可以运行)
    PSO粒子群算法,加上罚函数,解决有边界的优化模型的方程问题,C 语言,仅有一个cpp,有注释,方便理解。亲测可以运行,效果不错,跑出来结果拿到一个小公司的数据挖掘实习生岗位!
    2019-07-16下载
    积分:1
  • wcf 异步通知事件 示例源码
    有服务器端和客户端 的完整源码
    2014-03-25下载
    积分:1
  • C#多线程学习
    C#多线程例子
    2013-10-31下载
    积分:1
  • 自动登录刷票
    自动登录刷票
    2016-07-10下载
    积分:1
  • 696516资源总数
  • 106571会员总数
  • 2今日下载