关于宏

虽然在C++中推荐使用const代替宏的使用.但是宏还是有它的作用的.比如说##的使用,简单的说是可以在宏里面设置变量.直接上代码:
#include <stdio.h>
#include <process.h>
#define ABC(a,b) ABC_##a(b)  //a就相当于宏里的变量
#define ABC_A(b) (b+b)             //上一句a传A,或B就调用这两句                
#define ABC_B(b) (b*b)

int main(int argc,char *argv[])
{
        printf("%d\n",ABC(A,3));  //a=A 调用ABC_A(3) = 6
        printf("%d\n",ABC(B,3));  //a=B 调用ABC_B(3) = 9
        
        system("pause");
        return 0;
}

好了关于##我所知道的就这个,关于使用,我所知道的是Windwos的消息解析器(<<Windows核心编程>>附录B),一句HANDLE_MSG简化好多问题(不过很少有人直接用SDK编程,都被MFC强奸了),大家直接看HANDLE_MSG的源代码:
/****** Message crackers ****************************************************/

#define HANDLE_MSG(hwnd, message, fn)    \
    case (message): return HANDLE_##message((hwnd), (wParam), (lParam), (fn))
.....
#define HANDLE_WM_CREATE(hwnd, wParam, lParam, fn) \
    ((fn)((hwnd), (LPCREATESTRUCT)(lParam)) ? 0L : (LRESULT)-1L)
.....
就选这么点,使用的时候大家可以
HANDLE_MSG(hwnd,WM_CREATE,OnCreate);
宏会展开成什么大家应该可以根据上面例子展开.

好了在介绍个cl的选项 /P(预处理到文件) /EP(预处理到标准输出,没有 #line)有了这两个选项我们就可以将编译器(cl)的预处理文件保存到文件(*.i)(注意:加了这两个选项后编译器不好生成可执行文件,所以权当学习宏使用) VC6.0没有这个选项要手动加,如图:
VC6.0.JPG 
VS2005就可以可视化选了,如图:
VS2005.JPG 
好了我们可以看看生成的文件了:
直接拖到最后可以看到这一段:
LRESULT __stdcall WndProc(HWND hwnd,UINT uiMsg,WPARAM wParam,LPARAM lParam)
{
        switch(uiMsg)
        {
                case (0x0001): return (((OnCreate))(((hwnd)), (LPCREATESTRUCT)((lParam))) ? 0L : (LRESULT)-1L);
                case (0x0005): return (((OnSize))(((hwnd)), (UINT)((wParam)), (int)(short)((WORD)((DWORD_PTR)((lParam)) & 0xffff)), (int)(short)((WORD)((DWORD_PTR)((lParam)) >> 16))), 0L);
                case (0x0002): return (((OnDestroy))((hwnd)), 0L);
                case (0x000F): return (((OnPaint))((hwnd)), 0L);
        case 0x0318:
                OnPrintClient(hwnd,(HDC)wParam);
                return 0;
        }
        return DefWindowProcA(hwnd,uiMsg,wParam,lParam);
}
对应的源代码是:
LRESULT CALLBACK WndProc(HWND hwnd,UINT uiMsg,WPARAM wParam,LPARAM lParam)
{
        switch(uiMsg)
        {
                HANDLE_MSG(hwnd,WM_CREATE,OnCreate);
                HANDLE_MSG(hwnd,WM_SIZE,OnSize);
                HANDLE_MSG(hwnd,WM_DESTROY,OnDestroy);
                HANDLE_MSG(hwnd,WM_PAINT,OnPaint);
        case WM_PRINTCLIENT:
                OnPrintClient(hwnd,(HDC)wParam);
                return 0;
        }
        return DefWindowProc(hwnd,uiMsg,wParam,lParam);
}
好了大家应该了解##的用途吧.

关于预处理到文件我还想说关于MFC的消息处理MFC消息也是有很多宏的,在头文件上有这句DECLARE_MESSAGE_MAP()
在实现文件里有类似于这样的
BEGIN_MESSAGE_MAP(CMySPYDlg, CDialog)
        //{{AFX_MSG_MAP(CMySPYDlg)
        ON_WM_SYSCOMMAND()
        ON_WM_PAINT()
        ON_WM_QUERYDRAGICON()
        ON_WM_LBUTTONDOWN()
        //}}AFX_MSG_MAP
END_MESSAGE_MAP()
关于具体的MFC原理大家看<<深入浅出MFC>>侯捷的,看到这些宏大家头肯定大了(如果想深入理解MFC的话),还是用预处理到文件,加个/P /EP 选项
看下生成的(.i)文件,
DECLARE_MESSAGE_MAP()展开为
protected:
        
        
        private: static const AFX_MSGMAP_ENTRY _messageEntries[]; protected: static  const AFX_MSGMAP messageMap; static const AFX_MSGMAP* __stdcall _GetBaseMessageMap(); virtual const AFX_MSGMAP* GetMessageMap() const;
----
BEGIN_MESSAGE_MAP(CMySPYDlg, CDialog)
        //{{AFX_MSG_MAP(CMySPYDlg)
        ON_WM_SYSCOMMAND()
        ON_WM_PAINT()
        ON_WM_QUERYDRAGICON()
        ON_WM_LBUTTONDOWN()
        //}}AFX_MSG_MAP
END_MESSAGE_MAP()展开为

const AFX_MSGMAP* __stdcall CMySPYDlg::_GetBaseMessageMap() { return &CDialog::messageMap; } const AFX_MSGMAP* CMySPYDlg::GetMessageMap() const { return &CMySPYDlg::messageMap; }   const AFX_MSGMAP CMySPYDlg::messageMap = { &CMySPYDlg::_GetBaseMessageMap, &CMySPYDlg::_messageEntries[0] };  const AFX_MSGMAP_ENTRY CMySPYDlg::_messageEntries[] = {
        
        { 0x0112, 0, 0, 0, AfxSig_vwl, (AFX_PMSG)(AFX_PMSGW)(void ( CWnd::*)(UINT, LPARAM))&OnSysCommand },
        { 0x000F, 0, 0, 0, AfxSig_vv, (AFX_PMSG)(AFX_PMSGW)(void ( CWnd::*)(void))&OnPaint },
        { 0x0037, 0, 0, 0, AfxSig_hv, (AFX_PMSG)(AFX_PMSGW)(HCURSOR ( CWnd::*)())&OnQueryDragIcon },
        { 0x0201, 0, 0, 0, AfxSig_vwp, (AFX_PMSG)(AFX_PMSGW)(void ( CWnd::*)(UINT, CPoint))&OnLButtonDown },
        
{0, 0, 0, 0, AfxSig_end, (AFX_PMSG)0 } };
虽然乱了点但是比自己慢慢展开来得快,准确.好了大家可以好好学学MFC原理了.

结束.

原文:

http://www.cctry.com/thread-4088-1-11.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值