剪贴板(进程通信)

内存管理:在64位操作系统中,32位程序占多大内存空间:4GB

64位程序在64位操作系统中占的内存空间:16TB

用户模式:

内核模式:

发送消息三种方式:SendMessage,PostMessage,PostThreadMessage(需要线程ID)

进程间通信:消息

用户消息:

1. 自定义一个消息UM_MSG 为 WM_USER+1

2.发送变量i , i= -1 , 使用参数WPARAM还是LPARAM?

//WPARAM == unsigned int     //LPARAM == long    由于参数为负数,所以使用LPARAM来发送

 按钮Button1的执行代码如下:

void CProcessADlg::OnBnClickedButton1()
{
    HWND hwnd = ::FindWindow(NULL , _T("ProcessB"));//不加::是MFC类中的窗口
    //WPARAM == unsigned int
    //LPARAM == long
    int i = -1;
    ::SendMessage(hwnd,UM_MSG,0,i);
}

3 .ProcessB中

1>在进程B中定义函数:LRESULT OnMsg(WPARAM wparam , LPARAM lparam);

2>添加映射表ON_MESSAGE(UM_MSG ,&CProcessBDlg::OnMsg ) // 但进程B不识别UM_MSG ,因为这是在进程A中定义的,怎么办呢?

     在进程同级目录下添加sys.txt文件(.txt的编码形式与.h   .cpp相同),然后在加载该文件:#include "../sys.txt"

3>文件中#define UM_MSG WM_USER+1

4>函数OnMsg的函数实现

LRESULT CProcessBDlg::OnMsg(WPARAM wparam , LPARAM lparam)
{
    CString str;
    str.Format(_T("%d"),lparam);
    MessageBox(str);
    return 0;
}

验证结果:先在ProcessA中下断点运行,右键ProcessB ->调试 -> 运行新实例

 内核消息:WM_COPYDATA

发送字符串:

ProcessA:

    TCHAR szbuf[] = _T("hello");
    COPYDATASTRUCT cs;
    cs.dwData = 0;
    cs.cbData = sizeof(szbuf);
    cs.lpData = szbuf;
    ::SendMessage(hwnd,WM_COPYDATA,(WPARAM)m_hWnd,(LPARAM)&cs);

ProcessB:添加消息,WM_COPYDATA

消息函数:

BOOL CProcessBDlg::OnCopyData(CWnd* pWnd, COPYDATASTRUCT* pCopyDataStruct)
{
    TCHAR* pSzbuf = (TCHAR*)pCopyDataStruct->lpData;
    MessageBox(pSzbuf);
    return CDialogEx::OnCopyData(pWnd, pCopyDataStruct);
}

进程间通信:剪贴板

内存中共享的区域,需要自己动态的申请空间(不是new和delete),由于大家都可以访问,所以要加锁(进程间的锁)互斥量

一.,粘贴复制字符串类型:

ProcessA:

void CProcessADlg::OnBnClickedButton2()
{
    CString str;
    m_editStr.GetWindowText(str);//获取编辑框里的内容
    int nlen = sizeof(TCHAR)* (str.GetLength()+1);//TCHAR的大小,+1位‘/0’
    try
    {
        if(!OpenClipboard())    //1.打开剪贴板
        {
            throw(_T("OpenClipboard failed!"));
        }
        if(!EmptyClipboard())    //2.清空剪贴板
        {
            throw(_T("EmptyClipboard failed!"));
        }
        //3.申请空间
        HGLOBAL hglobal  = GlobalAlloc(GPTR ,nlen) ;//返回值为新申请空间的句柄
        if(hglobal == NULL)
        {
            throw _T("GlobalAlloc failed!");
        }
        //4.加锁
        TCHAR* StartAddress = (TCHAR*) GlobalLock(hglobal);//返回值为内存块的首地址
        if(StartAddress == NULL)
        {
            throw _T("GlobalLock failed!");
        }
        //5.写入数据
        wcscpy_s(StartAddress,str.GetLength()+1,str);//把编辑框里的东西拷贝到内存块中
        //6.解锁
        GlobalUnlock(hglobal);
        //7.数据类型
        SetClipboardData(CF_UNICODETEXT ,hglobal);//以Unicode的形式交给剪贴板
        //8.关闭剪贴板
        CloseClipboard();
    }
    catch(TCHAR* szbuf)
    {
        MessageBox(szbuf);
    }
}

ProcessB:

void CProcessBDlg::OnBnClickedButton1()
{
    try
    {
        if(!OpenClipboard())    //1.打开剪贴板
        {
            throw(_T("OpenClipboard failed!"));
        }
        if(!IsClipboardFormatAvailable(CF_UNICODETEXT))    //2.校验格式
        {
            throw(_T("IsClipboardFormatAvailable failed!"));
        }
        //3.获取数据
        HGLOBAL hglobal  = GetClipboardData(CF_UNICODETEXT) ;//返回值为空间的句柄
        if(hglobal == NULL)
        {
            throw _T("GetClipboardData failed!");
        }
        //4.加锁
        TCHAR* StartAddress = (TCHAR*) GlobalLock(hglobal);//返回值为内存块的首地址
        if(StartAddress == NULL)
        {
            throw _T("GlobalLock failed!");
        }
        m_editCtrl.SetWindowText(StartAddress);
        //5.解锁
        GlobalUnlock(hglobal);

        //6.关闭剪贴板
        CloseClipboard();
    }
    catch(TCHAR* szbuf)
    {
        MessageBox(szbuf);
    }
}

二 . 粘贴图片:

ProcessA:

void CProcessADlg::OnBnClickedButton3()
{
    try
    {
        if(!OpenClipboard())    //1.打开剪贴板
        {
            throw(_T("OpenClipboard failed!"));
        }
        if(!EmptyClipboard())    //2.清空剪贴板
        {
            throw(_T("EmptyClipboard failed!"));
        }
        //windows资源不需要申请空间,找到句柄即可
        CBitmap bitmap;
        bitmap.LoadBitmap(IDB_BITMAP1);
        //7.数据类型
        SetClipboardData(CF_BITMAP  ,bitmap);//以Unicode的形式交给剪贴板
        //8.关闭剪贴板
        CloseClipboard();
    }
    catch(TCHAR* szbuf)
    {
        MessageBox(szbuf);
    }
}

 ProcessB:

void CProcessBDlg::OnBnClickedButton2()
{
        try
    {
        if(!OpenClipboard())    //1.打开剪贴板
        {
            throw(_T("OpenClipboard failed!"));
        }
        if(!IsClipboardFormatAvailable(CF_BITMAP))    //2.校验格式
        {
            throw(_T("IsClipboardFormatAvailable failed!"));
        }
        //3.获取数据
        HGLOBAL hglobal  = GetClipboardData(CF_BITMAP) ;//返回值为空间的句柄
        if(hglobal == NULL)
        {
            throw _T("GetClipboardData failed!");
        }
        CClientDC dc(this);
        CDC cdc;
        cdc.CreateCompatibleDC(&dc);
        cdc.SelectObject(hglobal);
        dc.BitBlt(0,0,100,100,&cdc,0,0,SRCCOPY);
        //6.关闭剪贴板
        CloseClipboard();
    }
    catch(TCHAR* szbuf)
    {
        MessageBox(szbuf);
    }
}

三 . 粘贴文件(延迟拷贝)

复制时,拷贝的为文件的路径,

原因:文件放在内存中太大了。

设置数据时,将第二个参数设为NULL,即为延迟拷贝

例如:SetClipboardData(CF_BITMAP  ,NULL);

原文地址:https://www.cnblogs.com/Lune-Qiu/p/8467735.html