Win32API学习笔记第八章

这次是上半本书的最后一部分了,因为上半本主要是了解各种各样的消息,所以不详细,之后就主要是记录下版本的多线程与任务系统论了(之后就进入到系统的驱动开发上面),这一部分完了就开始记录每天一道CrackMe160里面的题,每天一到两道(视难度而定),并且会新开《加密与解密(看雪)》的学习笔记。
这次剪切板就稍作整理吧:

剪切板

写入

剪切板其实就是一个内存块,而且这个内存块由剪切板从根本上拥有它,我们要写入剪切板内容就需要对这块内存写入,在C语言中我们的内存分配函数是malloc但是剪切板是程序之间共享保存的(这个实在保护模式下的程序,如果在实模式下的话就可以直接malloc达到目的了),所以此时要用到Windows提供的一个内存分配的API:
GlobalAlloc(Flag,size),这个函数的返回值是一个HGLOBAL型的句柄,前面的标志位的话就不细记了。
GlobalReAlloc(HGLOBAL,size,Flag)这个就是一个扩大分配的函数。
同样的可以获取到相应大小:GlobalSize(HGLOBAL)以及释放相应的内存:GlobalFree(HGLOBAL)
同时,我们也可以直接获取到相关内存的地址:
GlobalLock(HGLOBAL)这个函数就直接通过相关的句柄返回了相应的内存块的void ,此时只需要对其强制转换即可。(执行了这个函数之后内存块被锁定,此时Windows就可以吧相应的虚拟地址返回)访问结束后调用GlobalUnlock就可以了,如果你有了虚拟地址的指针,不知道HGLOBAL的话可以通过GlobalHandle(void )获取到相应句柄。(句柄不变,而虚拟地址会变,所以要求在锁定时才可以安全的使用那一块内存)
那么写入到剪切板呢?
首先要调用hGlobal = GlobalAlloc(GHND|GMEM_SHARE,iLength + 1);
这一句的意义就是分配一个有iLength + 1大小的内存块并且该内存块共享且初始化全为0
之后就是pGlobal = GlobalLock(hGlobal);获取锁定时内存的虚拟地址。
然后就是对这个地址内容进行修改。
之后GlobalUnlock(hGlobal);此时我们的内存块内就是一个以NULL结尾的字符串了。
然后用OpenCilpboard(hWnd);打开剪切板
然后EmptyClipborad();将剪切板清空
然后利用一个巧妙地宏定义:

#ifdef UNICODE 
#define CF_TCHAR CF_UNICODETEXT
#else
#define CF_TCHAR CF_TEXT
#endif

这个宏定义就是兼容了Unicode下和ASCI模式下的写进剪切板的工作
然后调用SetClipboardData(CF_CHAR,hGlobal);此时应该注意的是,这个函数之后不能在访问这个内存块了,应为此时这个内存块已经不属于用户程序,如果要继续访问则可以使用两个方法:
一:将剪切板的内容读出做一个副本,然后操作完成重新写入。
二:用一个HGLOBAL接受SetClipboardData的返回值,然后在CloseClipborad之前锁定这个内存以继续访问和修改,然后解锁调用CloseClipborad();就可以了

读出:

这个其实就只是变换了一下:
首先确定剪切板是否有目标类型的数据:
IsClipboradFormatAcailable(CF_CHAR);这个函数返回一个BOOL变量,用于表示是否有这类数据。
然后确认了以后直接打开剪切板:OpenCilpboard(hWnd);
然后通过GetClipboardData(CF_CHAR);此时返回的就是一个HGLOBAL的类型了
然后此时就可以直接按照之前的转换方法读获取到虚拟地址然后再malloc一个GlobalSize返回的大小的空间然后复制进去就做到了将剪切版的内容复制到用户程序,此时注意,我们无法直接通过指针修改这个数据或将其释放(在GetClipboradData到CloseClipborad之间这个句柄有效)。

你可能感兴趣的:(windows程序设计)