内存管理:在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);