`
freesoftman
  • 浏览: 318918 次
  • 性别: Icon_minigender_1
  • 来自: 杭州
社区版块
存档分类
最新评论

WIN32下线程和窗口的数据绑定

阅读更多

这是一遍不错的文章,  在转帖前, 赞他一下。 

 

 

文章来自于:http://blog.csdn.net/zhoujianhei/archive/2007/11/19/1891891.aspx

 

 

WIN32下线程和窗口的数据绑定
 
一.     写给自己
我很懒。这是我写的第一篇涉及到编程的文章,也许就是因为太懒的缘故吧。在此之前也有写的冲动可不知为什么没有写成,懒得回忆了。说道记忆,啊,去年我在陈家庄。。。晕,又来了。有些事情我确实懒得记啦,以至于过去苦心钻研的“经--典”代码,现在又得重新研究。后悔当初没有给自己留下点什么痕迹,蛛丝马迹也好啊。本来很懒的我现在又得做重复劳动啊,那么我到底懒不懒啊?唉,总得给自己留下点什么吧,哪怕回忆也好啊。
由于本人记性不好,所以留此文章,已被后查。
 
二.     问题的提出
最近想在WIN32下对窗口封装一下。于是查阅了很多资料并分析了MFC的窗口实现,这才知道MFC的博大(有够大)。同时也使我积累了很多知识和技术,其实经常分析MFC实现对程序的编写和设计是大有益处,高手就在于你看了多少代码。这里不对MFC做过多评价,我们需要的仅是精华部分。
 
三.     线程数据的绑定
有的时候我们需要将一些数据或句柄绑定到当前线程,以供不时只需。
在WIN32编程中,有些系统回调函数并没有准备足够的参数为我们传递数据。而在这些回调函数中就包括WindowProc,TimerProc等。下面介绍一种方法将我们的数据绑定到系统的当前线程中,在线程中的任何一个角落都会取到我们之前绑定的数据,线程到哪我们的数据也就到哪。接下来我们所使用的技术称作线程本地存储(TLS)。
线程本地存储
要将数据(指针、句柄)绑定到线程,我们需要一个全局索引,而这个索引正是通过TlsAlloc分配的。
TlsAlloc
函数功能:分配一个线程局部存储(TLS)索引。该进程的任何线程都可以使用该索引来存储和检取线程中的值。
函数原型:DWORD TlsAlloc(void)
参数:无。
返回值:若函数成功,则返回值为一个TLS索引。失败则返回0XFFFFFFFF。
需要说明的是,进程可以同时分配多个索引,用于存放不同的数据。下面提供进程、线程、索引、存储槽的关系图以便更好地理解。

 

当越过进程边界时,TLS索引变为无效。一个DLL不能假定在一个进程中分配的索引在另一个进程中依然有效。
当一个DLL附加到一个进程时,它使用TlsAlloc分配一个TLS索引。然后,DLL分配一些动态存储单元,并调用TlsSetValue向TLS槽中存储地址。TLS索引存储在DLL的全局或静态变量中。
有了这个索引,我们就可以通过它来取得、设置数据,然而这些数据只对当前线程可见。针对索引系统为每个线程分配一个存储槽,当然我们可以随意的来使用这个槽。下面的函数用于取和设槽置。
TlsGetValue
函数功能:检取调用线程的线程局部存储(TLS)槽的值。对于每个TLS索引,进程的每个线程都有它自己的槽。
函数原型:LPVOID TlsGetValue(DWORD dwTlsIndex)
参数:
dwTlsIndex:由TlsAlloc分配的索引。
返回值:若函数成功,则返回调用线程的TLS槽中的值;失败则返回0。注意,存放在TLS槽中值可以为0,在这种情况下GetLastError返回NO_ERROR。
每个线程的TLS槽被初始化为NULL。
TlsSetValue
函数功能:存储调用线程的线程局部存储(TLS)槽的值。
函数原型:BOOL TlsSetValue(DWORD dwTlsIndex, LPVOID lpTlsValue)
参数:
dwTlsIndex:由TlsAlloc分配的索引。
lpTlsValue:调用线程的线程局部存储(TLS)槽的值。
返回值:若函数成功,则返回值不为0;失败则返回0。
TlsSetValue和TlsGetValue实现以提高速度为目标。这些函数执行最小的参数验证和错误检查。
 
当数据不再有用,我们需要将索引释放,有始有终吗。TlsFree函数不释放任何与TLS相关的动态存储单元。
TlsFree
函数功能:释放调用线程局部存储(TLS)索引。
函数原型:BOOL TlsFree(DWORD dwTlsIndex)
参数:
dwTlsIndex:由TlsAlloc分配的索引。
返回值:若函数成功,则返回值不为0;失败则返回0。
 
四.     窗口数据的绑定
下面介绍窗口数据的绑定,如果在WIN32下经常创建窗口,那么你一定对WindowProc函数不会陌生了,所有的窗口消息都是通过它来分配到窗口的。WindowProc无非就是windows的一个回调函数,下面对该函数做下说明:
WindowProc
函数功能:该函数是一个应用程序定义的函数。它处理发送给窗口的消息。WNDPROC类型定义了一个指向该函数的指针。
函数原型:LRESULT CALLBACK WindowProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
参数:
hWnd:指向窗口的句柄。
uMsg:指定消息。
wParam, lParam:指定uMsg消息的特定信息。
返回值:消息的处理结果,它与发送的消息有关。
所有的回调函数都是全局或静态的,然而根据上面的函数描述并没有给我们留下什么存储空间的指针,那么我们的数据如何绑定到窗口上呢?
 
SetWindowLong
函数功能:改变指定窗口的属性,也将指定的一个32位值设置在窗口的额外存储空间中。
函数原型:LONG SetWindowLong(HWND hWnd, int nIndex, LONG dwNewLong)
参数:
hWnd:窗口句柄。
nIndex:指定大于0的偏移值。可以指定下面的值之一:
GWL_EXISTYLE:设定一个新的扩展风格。GWL_STYLE:设定一个新的窗口风格。
GWL_WNDPROC:为窗口过程设定一个新的地址。GWL_ID:设置一个新的窗口标识符。
GWL_HINSTANCE:设置一个新的应用程序实例句柄。
GWL_USERDATA:设置与窗口有关的32位值。每个窗口均有一个由创建该窗口的应用程序使用的32位值。
当hWnd参数标识了一个对话框时,也可以使用下列值:
DWL_DLGPROC:设置对话框过程的新地址。
DWL_MSGRESULT:设置对话框过程中处理的消息的返回值。
DWL_USER:设置应用程序私有的额外信息,例如一个句柄或指针。
dwNewLong:指定的替换值。
返回值:若成功返回原来的32位值,失败则返回0。
 
GetWindowLong
函数功能:获取指定窗口的属性,也将获取窗口的额外存储空间中的一个32位值。
函数原型:LONG GetWindowLong(HWND hWnd, int nIndex)
参数:
hWnd:窗口句柄。
nIndex:指定大于0的偏移值。可以指定下面的值之一:
GWL_EXISTYLE:获取扩展风格。GWL_STYLE:获取窗口风格。
GWL_WNDPROC:获取窗口过程地址。GWL_ID:获取窗口标识符。
GWL_HINSTANCE:获取应用程序实例句柄。
GWL_USERDATA:获取与窗口有关的32位值。每个窗口均有一个由创建该窗口的应用程序使用的32位值。
当hWnd参数标识了一个对话框时,也可以使用下列值:
DWL_DLGPROC:获取对话框过程地址。
DWL_MSGRESULT:获取对话框过程中一个处理的消息的返回值。
DWL_USER:获取应用程序私有的额外信息,例如一个句柄或指针。
返回值:若成功返回原来的32位值,失败则返回0。
分享到:
评论

相关推荐

    Win32定时器的模拟

    本文将深入探讨如何使用Win32 API来模拟SetTimer和KillTimer的行为,即使不将定时器绑定到特定的窗口句柄,也能实现灵活的定时器功能,并允许在回调函数中传递参数。 首先,让我们了解SetTimer和KillTimer的基本...

    win32程序中使用console窗口

    首先,创建一个Win32程序时,默认情况下,如果它是一个控制台应用程序(比如基于C或C++的程序),Windows会自动为它创建一个console窗口。但如果是其他类型的Win32应用程序(如Windows GUI应用程序),则不会自动...

    dotnet 读 WPF 源代码笔记 使用 Win32 方法修改窗口的坐标和大小对窗口依赖属性的影响.rar

    - 应利用WPF提供的内置机制,如布局系统和数据绑定,来保持代码的可读性和可维护性。 - 在使用Win32 API时,务必考虑到它对WPF依赖属性的影响,并采取适当的措施来防止潜在的问题。 通过深入理解WPF的依赖属性...

    Win32API帮助

    此外,Win32 API还包含了进程和线程管理,如CreateProcess和CreateThread函数用于创建新的进程和线程,WaitForSingleObject和TerminateThread用于线程同步和结束线程。内存管理函数如VirtualAlloc和VirtualFree处理...

    WIN32程序的C++编程

    此外,线程和进程管理也是Win32编程的一部分,包括线程的创建、同步和通信,以及进程的创建和控制。 最后,调试和异常处理是确保程序健壮性的重要环节。Visual Studio等IDE提供了强大的调试工具,可以帮助我们定位...

    最新最全win32API速查手册

    7. **网络编程**:Win32 API还包含了TCP/IP网络编程接口,如`WSAStartup`初始化网络套接字,`socket`创建套接字,`bind`绑定本地地址,`listen`开始监听连接,`accept`接受连接请求,`send`和`recv`传输数据。...

    Win32 API大全

    Win32 API(Application Programming Interface)是微软Windows操作系统的核心组件,为开发者提供了丰富的函数和接口,使得...但Win32 API仍然在某些特定场景下具有不可替代的地位,特别是在系统级编程和性能优化方面。

    delphi可视化控制如何在win32 API创建的窗口程序中通过代码引用使用

    这是因为Win32 API提供了底层的窗口和图形操作能力,可以实现更高效或特定功能的程序。然而,将这两者结合使用需要对Windows编程有深入理解,特别是窗口类和消息处理机制。以下将详细解释如何在Win32 API创建的窗口...

    win32 API大全

    首先,Win32 API是基于C语言的,因此它的函数调用和数据类型都是C风格的。API中的函数涵盖了窗口管理、图形设备接口(GDI)、用户界面、进程与线程管理、内存管理、文件系统操作、网络通信、安全性和系统时钟等多个...

    WIN32API程序设计示例

    7. **网络通信**:`WSAStartup`初始化Winsock库,`socket`创建套接字,`bind`绑定套接字到本地地址,`listen`设置服务器监听,`accept`接受连接,`send`和`recv`发送和接收数据。 8. **错误处理**:所有WIN32API...

    Win32API.rar

    10. **网络通信**:`WSAStartup`初始化网络功能,`socket`创建套接字,`bind`绑定套接字到特定地址,`listen`监听连接请求,`accept`接受连接,`send`和`recv`发送和接收数据。 11. **错误处理**:Win32 API通常...

    Win32 API (最常用的API函数信息)

    尽管Win32 API主要关注桌面应用,但它也包含了一些用于网络通信的函数,如`WSAStartup`初始化网络套接字,`socket`创建套接字,`bind`绑定套接字到本地地址,`connect`建立连接,`recv`和`send`接收和发送数据。...

    win32 中文版api

    8. **网络编程**:使用Winsock库进行TCP/IP通信,如`socket`创建套接字,`bind`绑定端口,`listen`监听连接,`accept`接受连接,`send`和`recv`发送和接收数据。 9. **错误处理**:通过`GetLastError`获取最近一次...

    Win32 API大全.rar

    7. **网络通信**:`WSAStartup`初始化Windows套接字(Winsock),`socket`创建套接字,`bind`绑定套接字到本地地址,`connect`建立连接,`recv`和`send`接收和发送数据。 8. **系统控制**:`GetSystemTime`获取系统...

    Win32API大全+(中文版)

    Win32API涵盖了广泛的编程领域,包括窗口管理、图形设备接口(GDI)、内存管理、进程和线程控制、文件系统操作、网络通信、用户输入处理以及安全和权限管理等。这份中文文档将这些复杂的API函数进行了系统化的整理和...

    新编WIN32API大全.zip_MFC_win32 开发

    《新编WIN32API大全》是一本专为MFC(Microsoft Foundation Classes)和Win32界面开发设计的参考资料,其核心内容涵盖了Windows操作系统下进行应用程序开发所必需的API函数和概念。MFC是微软提供的C++类库,它封装了...

    《对话框》之《MFC和Win32》

    《对话框》之《MFC和Win32》主要探讨了MFC框架如何对Win32 API进行封装,以及MFC对象(MFC Object)与Windows对象(Windows Object)之间的关系。理解这种关系对于深入学习MFC编程至关重要。 1. **MFC Object与...

    WIN32_API大全 WINDOWS_API大全

    1. **系统管理**:WIN32 API提供了诸如进程和线程管理、内存分配和释放、系统时间获取等函数。例如,CreateProcess用于创建新的进程,CreateThread用于创建新线程,VirtualAlloc和VirtualFree用于内存的动态分配和...

    C++win32局域网聊天程序

    本篇将深入解析基于C++2010环境下的Win32局域网聊天程序,探讨其核心技术和实现步骤。 首先,我们要了解C++2010标准为开发提供了哪些新的特性和改进。C++2010引入了lambda表达式、右值引用、自动类型推断等特性,...

    Win32+API函数库.zip

    WSAStartup()初始化Winsock库,socket()创建套接字,bind()绑定IP地址和端口,connect()建立连接,send()和recv()发送和接收数据。 8. **系统信息**:获取系统配置和状态。GetSystemMetrics()获取系统信息,...

Global site tag (gtag.js) - Google Analytics