现在的位置: 首页 > 综合 > 正文

指针转换

2013年08月19日 ⁄ 综合 ⁄ 共 2094字 ⁄ 字号 评论关闭

/*ScreenToClient 用来转两次把屏幕rect该为clientrect*/

BOOL ScreenToClient(LPRECTlpRect) const throw()

{

ATLASSERT(::IsWindow(m_hWnd));

if(!::ScreenToClient(m_hWnd,(LPPOINT)lpRect))

return FALSE;

return::ScreenToClient(m_hWnd, ((LPPOINT)lpRect)+1);

}                                                                    

/*******************************************************************

 

论证上述(LPPOINT)lpRect),((LPPOINT)lpRect)+1转换的正确性,第一次调用是把point(lpRect->left,lpRect->top)转换为客户坐标,第二次转换把point(lpRect-> right, lpRect->bottom)转换为客户坐标,通过两次转换即把一个屏幕rect转换为客户端rect。下面例子通过反汇编来论证。

 

#include "stdafx.h"

#include <iostream>

using namespace std;

 

struct A

{

    long a;

    long b;

};

 

typedef A* LPA;

struct B

{

    long a;

    long b;

    long c;

    long d;

};

 

typedef B* LPB;

 

int _tmain(int argc, _TCHAR* argv[])

{

    B b = {1, 2, 3,4};

    /*  

    0041417E  mov         dword ptr [b],1

    00414185  mov         dword ptr [ebp-10h],2

    0041418C  mov         dword ptr [ebp-0Ch],3

    00414193  mov         dword ptr [ebp-8],4

    */

    LPA a = (LPA)&b; // a地址跟b地址相同,见汇编

    /*

    0041419A  lea         eax,[b]  //把b的地址赋给eax

    0041419D  mov         dword ptr [a],eax  //把eax的地址赋给a

    */

    cout<<&b<<"\t"<<a<<endl;

    ///////////////////////////////////////////

    cout<<a->a<<"\t"<<a->b<<endl;

    /*

    004141F3  mov         esi,esp

    004141F5  mov         eax,dword ptr [__imp_std::endl(41A310h)]

    004141FA  push        eax 

    004141FB  mov         edi,esp

    004141FD  mov         ecx,dword ptr [a]

    00414200  mov         edx,dword ptr [ecx+4]  //edx 为2,存储的是a->b的值,a->b地址是a地址加

    00414203  push        edx 

    00414204  push        offset string "\t" (4177FCh)

    00414209  mov         ebx,esp

    0041420B  mov         eax,dword ptr [a]

    0041420E  mov         ecx,dword ptr [eax]  //ecx 为1,存储的是a->a的值,a->a地址是a地址

    00414210  push        ecx 

    00414211  mov         ecx,dword ptr [__imp_std::cout(41A30Ch)]

    00414217  call        dword ptr[__imp_std::basic_ostream<char,std::char_traits<char>>::operator<< (41A300h)]

    */

        LPA aa = ((LPA)&b) +1; //aa地址跟b.c地址相同,见汇编

    /*

    00414258  lea         eax,[ebp-0Ch] //[ebp-0Ch] 就是b.c的地址,见行

    0041425B  mov         dword ptr [aa],eax //aa的地址跟b.c地址相同

    */

    cout<<aa->a<<"\t"<<aa->b<<endl; //同 cout<<a->a<<"\t"<<a->b<<endl;的反汇编

 

 

    return 0;

}

 

 

 

抱歉!评论已关闭.