结构体类型指针强制类型转换的问题
【楼主位】 wangtao03
两个结构体类型
typedef struct _MSG
{
/** the handle to the window which receives this message. */
HWND hwnd;
/** the message identifier. */
MESSAGE_ENUM message;
/** The first parameter of the message (32-bit integer). */
WPARAM wParam;
/** The second parameter of the message */
//LPARAM lParam;
//U32 time;
} MSG;
typedef MSG* PMSG;
typedef struct _PAINT_PARAM
{
GRAPHIC_DC dc;
RECT * rect; //rectangle of current drawing UI control
RECT * rect_invalidate; //rectangle of invalid region of current redrawing
//U8 u8ConstantAlpha; //0xFF for disable alpha...
BOOLEAN bIsFocus;
BOOLEAN bIsDisable;
BOOLEAN bIsVisible; //MSG_PAINT on invisible state??
} PAINT_PARAM;
S32 MApp_ZUI_CTL_DynamicColorTextWinProc(HWND hWnd, PMSG pMsg)
{
switch(pMsg->message)
{
case MSG_PAINT:
{
U16 u16TxtComponentIndex;
LPTSTR pStr;
DRAWSTYLE_TYPE ds_type;
//get buffer GC for offline drawing...
PAINT_PARAM * param = (PAINT_PARAM*)pMsg->wParam;
//find all static text => dynamic text
if (param->bIsDisable)
{
param->dc.u8ConstantAlpha = MApp_ZUI_API_GetDisableAlpha(hWnd);
ds_type = DS_DISABLE;
}
else if (param->bIsFocus) //the same focus group
{
param->dc.u8ConstantAlpha = MApp_ZUI_API_GetFocusAlpha(hWnd);
ds_type = DS_FOCUS;
}
else
{
param->dc.u8ConstantAlpha = MApp_ZUI_API_GetNormalAlpha(hWnd);
ds_type = DS_NORMAL;
}
请问这一句PAINT_PARAM * param = (PAINT_PARAM*)pMsg->wParam;怎么理解?希望有高手能解答我的困惑.
2011-01-02,09:26:56
资料 邮件 回复 引用回复 ↑↑ ↓↓ 编辑 删除
【1楼】 luo496724812
pMsg->wParam有一个值,这个值的类型暂时不论(不过不是32位的话不排除编译器报错的可能),这个语句执行完成之后,定义了一个指针变量param,它的值等于pMsg->wParam的值(无论pMsg->wParam本身是不是一个指针),PAINT_PARAM * param指明param是一个PAINT_PARAM类型的指针,也就是说以后通过*param所引用的的值是PAINT_PARAM类型的。
举个例子
typedef struct_eg
{
int x;
int y;
}eg;
int point = 0x30000000;
eg *peg = (eg*)point;
可以看到point本身只是个整型变量,但是这样的赋值是合法的,peg->x的值是0x30000000开始的四字节,peg->y是0x30000004开始的四字节
【2楼】 wangtao03
谢谢楼上的回复。我还有一事不明就是param虽然它的值等于pMsg->wParam的值。也就是PAINT_PARAM定义的结构体变量要放在地址为pMsg->wParam开始的地方,才能用param指针去引用变量。不知我分析的对不对?
【3楼】 luo496724812
回复【2楼】wangtao03
谢谢楼上的回复。我还有一事不明就是param虽然它的值等于pmsg->wparam的值。也就是paint_param定义的结构体变量要放在地址为pmsg->wparam开始的地方,才能用param指针去引用变量。不知我分析的对不对?
-----------------------------------------------------------------------
不是说某个地址有那个结构体你才能引用,即使没有,你也能引用,因为你已经告诉了编译器param变量就是指向一个PAINT_PARAM结构体的变量并且指明了param的值,机器码的眼中是没有数据结构一说的,它只是机械的按照指令的要求从内存地址取值,那刚才的例子来说,peg->x,peg->y的引用无论0x30000000是否存在一个eg结构体都是合法的,如果0x30000000开始的8个字节存在eg结构体,那么引用的就是这个结构体的值,如果这个位置是未定义的值,那么引用的结果就是这8个字节中的未定义值,内存位置总是存在的,而对内存中值的引用就是从这些内存位置对应的内存单元取值。
【4楼】 wangtao03
按着你的说法那么
if (param->bIsDisable)
{
param->dc.u8ConstantAlpha = MApp_ZUI_API_GetDisableAlpha(hWnd);
ds_type = DS_DISABLE;
}
else if (param->bIsFocus) //the same focus group
{
param->dc.u8ConstantAlpha = MApp_ZUI_API_GetFocusAlpha(hWnd);
ds_type = DS_FOCUS;
}
(param->bIsDisable)
(param->bIsFocus)
这些值是那里来的呢?还是不明白。
【5楼】 ufbycd
param->bIsDisable : 将 pMsg->wParam 所指向的内存单元以 PAINT_PARAM 的分布方式(利用 param )取得偏移为 bIsDisable 的值。
结构体声明如何内存的分布,
结构体指针声明结构体的首地址,
结构体成员声明该成员在结构体中的偏移地址。
【6楼】 luo496724812
按着你的说法那么
if (param->bisdisable)
{
param->dc.u8constantalpha = mapp_zui_api_getdisablealpha(hwnd);
ds_type = ds_disable;
}
else if (param->bisfocus) //the same focus group
{
param->dc.u8constantalpha = mapp_zui_api_getfocusal......
-----------------------------------------------------------------------
首先要明确param本身有一个值(在32位机上一般是32位),这个值代表着某个内存地址,比如这个值是0x30000000,由于param被定义为PAINT_PARAM,那么编译器在编译源文件时就会认为param指向的是一个PAINT_PARAM结构,这个结构的内容由一段连续的内存存储,(param->bIsDisable)
(param->bIsFocus)
在PAINT_PARAM的定义中肯定是存在bIsDisable,bIsFocus的,这两个变量对一个PAINT_PARAM结构的地址偏移量是固定的,也就是说只要知道一个PAINT_PARAM结构的起始地址,就能计算出这个结构所包含的bIsDisable,bIsFocus的地址,由于param地址已知(编译器知道这个地址),param所含的bIsDisable离param的偏移量已知,那么就能通过param实现对bIsDisable的取值,在编译器编译C文件的时候并不管param中的bIsDisable是否定义。
param被定义为PAINT_PARAM,而PAINT_PARAM中又包含bIsDisable,那么编译器就认为param所指向的结构中存在bIsDisable。
param->bIsDisable如果不发生保护错误,总是能取到一个值(这个值就是对param偏移一定距离的内存单元中的值),只是这个值不能确定是否是你期望的值。
再次提醒,变量的值是存储在内存中的,每个内存字节对应一个内存地址,而内存存储的值本身是没有整型,指针,字符等的区别的,区别的存在是因为我们对它们有不同的解读,param的值就是一个32位值,并且存储在某个内存单元中,通过这个32位值就能找到param所指向的结构的起始地址,通过这个起始地址和各个结构所包含变量离起始地址的偏移对这些变量进行引用,param->bIsDisable只是这种引用更易读的写法,只要param是指向PAINT_PARAM的指针,那么param的值就肯定存在,param存在,偏移量已知,那么param->bIsDisable就肯定存在,只是要记住,param->bIsDisable只是代表了对param一定偏移地址的值。
【8楼】 wangtao03
假如pMsg->wParam 的值是0x30000000也就是param指向了以0x30000000为首地址的一片内存单元,这片内存单元以 PAINT_PARAM 的方式分布。那么我想问的是里面的各个字段的值是哪里来的?因为这段内存单元中值是没有被初始化过的。
【9楼】 luo496724812
回复【8楼】wangtao03
谢谢各位的热心解答。可是我还是有点不明白
假如pmsg->wparam 的值是0x30000000也就是param指向了以0x30000000为首地址的一片内存单元,这片内存单元以 paint_param 的方式分布。那么我想问的是里面的各个字段的值是哪里来的?因为这段内存单元中值是没有被初始化过的。
-----------------------------------------------------------------------
如果从来没有代码对这段内存进行过操作,那么其值就是系统上电启动之后的内存的默认值,如果有其他程序使用过,那么其值就是其他程序执行后在这段内存中留下的值,总之,每个正常工作的内存单元中都是有值的,无论这些值是否是我们所需要的,它们始终是存在的。你可以把内存想象成一个大数组,当你在程序中定义了一个数组,但是并没有初始化,但是你也可以引用数组元素,只是引用的值是未知的,道理是类似的
【10楼】 hemjidn 捱多年
pMsg->wParam??的值当然是调用这个函数WinProc(HWND??hWnd,??PMSG??pMsg)的父函数提供啦。