Windos核心编程学习笔记


1、获取错误信息
   1)GetLastError(),FormatMessage();
   2)在VS的Watch窗口中使用$err,hr来查找当前线程的“上一个错误代码”;
2、缓冲区溢出,这个是处理字符串时的典型错误;
3、字符串或者字符前面加上字母L,则通知编译器该字符串或者字符应该编译成为一个Unicode的字符串或者字符,比如L"A String",L'A';
4、errno.h ERANGE范围错误发生,STRUNCATE字符截断;
5、ShellExecute(NULL,"open",NULL,NULL,m_strPath.c_str(),SW_SHOWNORMAL);打开当前的文件夹;
6、在任务条上显示图标是利用系统API函数Shell_NotifyIcon()来将一个图标显示在任务栏的通告区中;
7、GetExitCodeProcess()获取指定进程的状态,或者其退出的信息;
8、GetCurrentProcessId(),GetProcessId(),GetThreadId();获得进程或者线程的ID;
9、 PostMessage只把消息放入队列,不管其他程序是否处理都返回,然后继续执行,这是个异步消息投放函数。
10、SendMessage必须等待其他程序处理消息完了之后才返回,继续执行,这是个同步消息投放函数。而且,PostMessage的返回值表示PostMessage函数执行是否正确;而SendMessage的返回值表示其他程序处理消息后的返回值。
11、创建线程后返回了线程句柄,新创建的线程内核对象的使用计数是2,一个是线程本身,一个是创建线程的线程,创建线程的线程closehandle后,新的线程的内核对象使用计数为1,当这个新线程结束运行后内核对象的使用计数还要减1,这时内核对象的使用计数是0,则系统会自动删除新线程的内核对象,这是正常的处理流程。
12、进程或线程对象会在停止运行时被触发;
13、Microsoft选择在已分配的CPU时间到期时,才将作业的状态变成已触发;
14、CreateThread()函数是用于创建线程的Windows函数,beginthreadex是Microsoft C++运行库函数。
15、在用findfirst()和findnext()函数去查找磁盘文件时经常使用的一个数据结构WIN32_FIND_DATA的成员变量里包含了以上所有的文件属性,因此可以通过这个结构作为获取和更改文件属性的手段。
16、HANDLE GetCurrentProcess(),GetCurrentThread(),返回的都是伪句柄,通过CloseHandle只是简单的忽略此调用,并返回FALSE;线程的伪句柄是一个指向当前线程的句柄,如果把父线程的伪句柄传递给子线程,那么在子线程中对此父线程的伪句柄进行操作,实际上是对子线程的操作;故需要通过DuplicateHandle()(增加线程的使用计数)将伪句柄转换成真正的句柄,并且使用完这个函数之后还要先调用CloseHandle来减少线程的使用计数。
17、尽量使用C/C++运行库函数_beginthreadex和_endthreadex来创建线程和销毁线程,因为这类函数内部自己维护了一个线程的内存块。
18、WaiteForDebugEvent()返回的调试事件时,Windwos将冻结被调试进程中的所有线程,直至调试器调用ContinueDebugEvent,目前没有直接挂起进程的函数,可以自己编写。
19、睡眠:Sleep(0),告诉系统,主调线程放弃了时间片的剩余时间,强制系统调用其他线程。Sleep(0)只会调入优先级大于等于主线程的其它线程,而辅助线程的优先级低,那么应该来说根本就轮不到调用它,从2003 server开始,Sleep(0)变成了调度所有可调度线程,跟SwitchToThread差不多了
20、切换到其他线程:Switchtothread当调用这个函数的时候,系统要查看是否存在一个迫切需要CPU时间的线程。如果没有线程迫切需要CPU时间,SwitchToThread就会立即返回FALSE。如果存在一个迫切需要 CPU时间的线程,SwitchToThread就对该线程进行调度(该线程的优先级可能低于调用 SwitchToThread的线程)。
21、关键段(对共享资源进行“原子”访问)的最大好处在于它们非常容易使用,而且它们在内部也使用了Interlocked函数,因此执行速度非常快。最大的缺点在于它们无法用来在多个进程之间对线程进行同步。
22、DestroyWindow()非模态对话框的窗口销毁;
EndDialog(IDCANCEL) ; //模态对话框的窗口销毁。
23、 volatile 关键字只在 Release 模式下才发挥了它的作用,当使用 volatile 声明的变量的值的时候,系统总是重新从它所在的内存读取数据,而不会对其优化。
24、对于关键代码段而言,对于同时使用对个锁的时候,我们必须在代码中的任何地方以完全相同顺序来获得资源的锁。但是在调用LeaveCritoCalSection的时候顺序无关紧要,这是因为该函数从来不会让线程进入等待状态。
25、WaiteForMultiPleObject(,,false,)函数如果等到一个内核对象以后,需要将这个已触发的句柄从数组中移除,否.在每次调用的时候都会直接返回。
26、CreateWaitableTimer(),TRUE手动定时器,需要调用SetWaitableTimer才能将定时器变成信号,如果FALSE,自动定时器,需要调用WaitForSingleObject即可实现定时器信号的重置。WaitforsingleObject即使有回调函数也是不会执行的
27、SetWaitableTimer如果值是正的,代表一个特定的时刻。如果值是负的,代表以100纳秒为单位的相对时间。
28、PtrToUlong;
29、MoveMemory将一段内存移到什么位置。
30、就类对象而言,相同类型的类对象是通过拷贝构造函数来完成整个复制过程的。拷贝构造函数是一种特殊的构造函数,函数的名称必须和类名称一致,它的唯一的一个参数是本类型的一个引用变量,该参数是const类型,不可变的,例如:类X的拷贝构造函数的形式为X(X& x)。
以下情况都会调用拷贝构造函数:
一个对象以值传递的方式传入函数体
一个对象以值传递的方式从函数返回
一个对象需要通过另外一个对象进行初始化。
31、接收I/O请求完成通知的方法:触发设备内核对象,触发事件内核对象,I/O完成端口
32、QueueUserAPC,允许手动地将一项添加到APC队列中,,他可以非常高效的进行线程间通信,甚至能够跨越进程的界限,但是只能传递一个值。
33、当线程被挂起的时候,如果我们等待的那个(或那些)内核对象被触发,或线程的APC队列中出现了一项,那么线程都将被唤醒,所以我们可以通过调用QueueUserAPC函数,手动地向指定线程的APC队列中添加一项,如果线程(或者GetLastError)返回的是WAIT_IO_COMPLETION,那么我们就知道线程得以继续执行的原因是线程至少处理了APC队列中的一项,如果返回的WAIT_OBJECT_0,那证明线程等待的内核对象被触发,处于有信号状态。
34、GetQueuedCompletionStatus的任务基本上就是将调用线程切换到睡眠的状态,直到指定的完成端口的I/O完成队列中出现一项,或者等待的时间已经超出了指定的时间。
35、在C++编译器里不用extern “C”括起C代码,会导致编译器不知道该如何为 C 代码描述内存布局。
36、PostQueuedCompletionStatus(),可以用来唤醒正在等待完成端口但又没有已完成的I/O请求的所有线程,使得线程退出,不用再继续等待。
37、SetFilePointerEx(hFileDst, liFileSizeSrc, NULL, FILE_BEGIN);从文件的开始位置,将文件指针移动liFileSizeSrc个字节
    SetEndOfFile(hFileDst);将当前文件指针所在的位置设置为文件的结尾,从文重新设置了文件的大小。
38、HWND hwnd = GetForegroundWindow();//获取调用者进程当前正在使用的那个窗口的句柄
    HDC hdc = GetDC(hwnd);//转换成窗口所对应的hdc
24.2.3 暂停全局展开 看到这里了
    // Nonbuffered I/O requires sector-sized transfers.
      // I'll use buffer-size transfers since it's easier to calculate.
      liFileSizeDst.QuadPart = chROUNDUP(liFileSizeSrc.QuadPart, BUFFSIZE);
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值