內存映射實現進程間通信

示例通過內存映射實現從服務器加載bmp位圖到內存,客戶端從內存讀取並顯示。

//服務器部分代碼
void CServerDlg::OnCreateFileMap() 
{
	// TODO: Add your control notification handler code here
	CButton* pButton = (CButton*)GetDlgItem(IDC_BUTTON1);
	pButton->EnableWindow(false);
	CString filename = _T("image\\3.bmp");
	//1.加載文件
	m_hFile = CreateFile(filename,GENERIC_READ,FILE_SHARE_READ,NULL,OPEN_EXISTING,FILE_ATTRIBUTE_NORMAL,NULL);
	if (m_hFile == INVALID_HANDLE_VALUE)
	{
		MessageBox(_T("文件加載失敗!!!"),NULL,MB_OK);
		return;
	}
	m_hMap = CreateFileMapping(m_hFile, NULL, PAGE_READONLY, NULL, NULL, _T("myjpg"));
	//2.映射整個文件到
	m_pBaseMapFile = MapViewOfFile(m_hMap,FILE_MAP_READ,0,0,0);
}

void CServerDlg::OnCloseFileMap() 
{
	// TODO: Add your control notification handler code here
	CButton* pButton = (CButton*)GetDlgItem(IDC_BUTTON2);
	pButton->EnableWindow(false);
	if (m_pBaseMapFile)
	{
		UnmapViewOfFile(m_pBaseMapFile);
	}
	if (m_hMap)
	{
		CloseHandle(m_hMap);
	}
	if (m_hFile)
	{
		CloseHandle(m_hFile);
	}
}

//客戶端部分代碼

void CClientView::OnOpenFileMap() 
{
	// TODO: Add your command handler code here
	m_hMapFile =OpenFileMapping(FILE_MAP_READ, FALSE,_T("myjpg"));
	if(m_hMapFile == NULL)
	{
		MessageBox(_T("文件映射打開失敗!"));
		return;
	}
	m_pBaseMapFile=MapViewOfFile(m_hMapFile, FILE_MAP_READ, 0,0,0);
	
	SetBitsToBmp((BYTE*)m_pBaseMapFile);
}

void CClientView::OnCloseFileMap() 
{
	// TODO: Add your command handler code here
	if (m_pBaseMapFile) 
	{ 
		UnmapViewOfFile(m_pBaseMapFile);  
	}
	if(m_hMapFile)
	{
		CloseHandle(m_hMapFile);
	}
}

void CClientView::SetBitsToBmp(LPBYTE lpBase)
{
	BITMAPFILEHEADER *pFileHeader; // bitmap file-header
	BITMAPINFO *pInfoHeader; // bitmap info-header
	pFileHeader = (BITMAPFILEHEADER*)lpBase;
	if(pFileHeader->bfType != MAKEWORD('B', 'M'))
	{ 
		MessageBox(_T("本程序僅讀取BMP 文件!"));
		::UnmapViewOfFile(lpBase);
		::CloseHandle(m_hMapFile);
		return;
	}
	BYTE *pBits = (BYTE*)lpBase + pFileHeader->bfOffBits;
	pInfoHeader = (BITMAPINFO*)((BYTE*)lpBase + sizeof(BITMAPFILEHEADER));
	m_nHeight = pInfoHeader->bmiHeader.biHeight;
	m_nWidth = pInfoHeader->bmiHeader.biWidth;

	CClientDC dc(this);

	// 創建一個與指定DC 兼容的未初始化的位圖,選入到內存兼容DC 中
	m_hMemDC = CreateCompatibleDC(dc);
	HBITMAP hBitmap = ::CreateCompatibleBitmap(dc, m_nWidth, m_nHeight);
	::SelectObject(m_hMemDC, hBitmap);
	
	//1.正常顯示
	SetDIBitsToDevice(m_hMemDC,0, 0, m_nWidth,m_nHeight,0, 0,0, m_nHeight, pBits, pInfoHeader,DIB_RGB_COLORS); 
	
	//2.縮放模式
	/*RECT rc;
	GetClientRect(&rc);
	int nWidth = rc.right - rc.left;
	int nHeight = rc.bottom - rc.top;
	StretchDIBits(m_hMemDC, 0, 0, nWidth, nHeight, 0, 0, m_nWidth, m_nHeight, pBits, pInfoHeader,DIB_RGB_COLORS,SRCCOPY);*/
	
	InvalidateRect(NULL, TRUE);
	::DeleteObject(hBitmap);
}

void CClientView::OnDraw(CDC* pDC)
{
	CClientDoc* pDoc = GetDocument();
	ASSERT_VALID(pDoc);
	// TODO: add draw code for native data here
	BitBlt(pDC->m_hDC,0, 0, m_nWidth, m_nHeight, m_hMemDC,0,0,SRCCOPY);
}


發佈了21 篇原創文章 · 獲贊 9 · 訪問量 12萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章