)進程通訊(使用者自訂訊息,使用者註冊訊息,windows剪貼簿,WM_COPY, 記憶體映射,對目標進程的記憶體)

來源:互聯網
上載者:User
發送端:
建立一個基本對話方塊工程,添加6個文字框控制項,並且關聯控制項變數(CString類型):
 m_strCopyData, m_strFileMap, m_strMem, m_strRegMsg, m_strUserMsg, m_strClipBoard

然後在 CPP 檔案裡面,做如下定義:

#define BUFFER_SIZE  0x100          // 用記憶體位址通訊時分配的最大記憶體.
#define WM_COMM      WM_USER+100
const UINT wm_nRegMsg=RegisterWindowMessage("reg_data");
const UINT wm_nMemMsg=RegisterWindowMessage("mem_data");

添加6個按鈕,在裡面寫入代碼

//使用 WM_COPY 方式進行發送
void CDataSendDlg::OnSendCopydata()
{
    UpdateData();  //更新資料.
    CWnd *pWnd=CWnd::FindWindow(NULL,_T("DataRecv")); // 尋找DataRecv進程.
    if(pWnd==NULL){
        AfxMessageBox(TEXT("Unable to find DataRecv."));
        return;
    }

    COPYDATASTRUCT cpd; // 給COPYDATASTRUCT結構賦值.
    cpd.dwData = 0;
    cpd.cbData = m_strCopyData.GetLength();
    cpd.lpData = (void*)m_strCopyData.GetBuffer(cpd.cbData);
    pWnd->SendMessage(WM_COPYDATA,NULL,(LPARAM)&cpd);// 發送.
}

//使用使用者自訂訊息的方式進行發送
void CDataSendDlg::OnSendUsermsg()
{
    UpdateData();  // 更新資料.
    CWnd *pWnd=CWnd::FindWindow(NULL,_T("DataRecv")); // 尋找DataRecv進程.
    if(pWnd==NULL){
        AfxMessageBox(TEXT("Unable to find DataRecv."));
        return;
    }

    UINT uMsg;
    uMsg=atoi(m_strUserMsg);
    pWnd->SendMessage(WM_COMM,NULL,(LPARAM)uMsg);// 發送.
}

//使用使用者註冊訊息的方式進行發送
void CDataSendDlg::OnSendRegmsg()
{
    UpdateData();  // 更新資料.
    CWnd *pWnd=CWnd::FindWindow(NULL,_T("DataRecv")); // 尋找DataRecv進程.
    if(pWnd==NULL){
        AfxMessageBox("Unable to find DataRecv.");
        return;
    }
    UINT uMsg;
    uMsg=atoi(m_strRegMsg);
    pWnd->SendMessage(wm_nRegMsg,NULL,(LPARAM)uMsg);// 發送.
}

//使用對目標進程記憶體的訪問方式進行發送
void CDataSendDlg::OnSendMem()
{
    UpdateData();  // 更新資料.

    CWnd *pWnd=CWnd::FindWindow(NULL,_T("DataRecv")); // 尋找DataRecv進程.
    if(pWnd==NULL){
        AfxMessageBox("Unable to find DataRecv.");
        return;
    }

    // 擷取進程號.
    DWORD PID;
    GetWindowThreadProcessId(pWnd->m_hWnd, (DWORD*)&PID );
    HANDLE hProcess = OpenProcess (PROCESS_ALL_ACCESS,FALSE,PID);

    // 分配虛擬記憶體.
    LPVOID lpBaseAddress;
    lpBaseAddress = VirtualAllocEx(hProcess, 0, BUFFER_SIZE,
                  MEM_COMMIT, PAGE_READWRITE);       

    char  data[BUFFER_SIZE];
    strcpy(data,m_strMem);

    // 把字串寫入hProcess進程的記憶體.
    WriteProcessMemory(hProcess, lpBaseAddress, data, BUFFER_SIZE, NULL);

    // 發送基址給DataRecv進程.
    pWnd->SendMessage(wm_nMemMsg,NULL,(LPARAM)lpBaseAddress);

    // 等待接收程式接收資料.
    Sleep(100);

    // 釋放虛擬記憶體.
    VirtualFreeEx(hProcess,lpBaseAddress, 0, MEM_RELEASE);
}

//使用記憶體映射的方式進行發送
void CDataSendDlg::OnSendFilemap()
{
    UpdateData();  // 更新資料.

    // 建立記憶體映像對象.
    HANDLE hMapping;  
    LPSTR lpData;  
    hMapping=CreateFileMapping((HANDLE)0xFFFFFFFF,NULL,
                          PAGE_READWRITE,0,BUFFER_SIZE,"MYSHARE");  
    if(hMapping==NULL)  
    {  
        AfxMessageBox("CreateFileMapping() failed.");
        return;
    }

    // 將檔案的視圖映射到一個進程的地址空間上,返回LPVOID類型的記憶體指標.
    lpData=(LPSTR)MapViewOfFile(hMapping,FILE_MAP_ALL_ACCESS,0,0,0);  
    if(lpData==NULL)  
    {  
        AfxMessageBox("MapViewOfFile() failed.");
        return;
    }

    // 給這段映像記憶體寫資料.
    sprintf(lpData,m_strFileMap);  
   
    // 釋放映像記憶體.
    UnmapViewOfFile(lpData);  
}

//使用windows剪貼簿的方式進行發送
void CDataSendDlg::OnSendClipboard()
{
    UpdateData();                    // 更新資料.
    CString strData=m_strClipBoard;  // 獲得資料.

    // 開啟系統剪貼簿.
    if (!OpenClipboard()) return;

    // 使用之前,清空系統剪貼簿.
    EmptyClipboard();

    // 分配一記憶體,大小等於要拷貝的字串的大小,返回的記憶體控制控制代碼.
    HGLOBAL hClipboardData;
    hClipboardData = GlobalAlloc(GMEM_DDESHARE, strData.GetLength()+1);
   
    // 記憶體控制控制代碼加鎖,傳回值為指向那記憶體控制控制代碼所在的特定資料格式的指標.
    char * pchData;
    pchData = (char*)GlobalLock(hClipboardData);
   
    // 將本地變數的值賦給全域記憶體.
    strcpy(pchData, LPCSTR(strData));
   
    // 給加鎖的全域記憶體控制控制代碼解鎖.
    GlobalUnlock(hClipboardData);
   
    // 通過全域記憶體控制代碼將要拷貝的資料放到剪貼簿上.
    SetClipboardData(CF_TEXT,hClipboardData);
   
    // 使用完後關閉剪貼簿.
    CloseClipboard();
}

至此,完成發送端

接收端:
建立一個基本對話方塊工程( DataRecv )
添加6個文字框控制項,並且關聯控制項變數(CString類型):
m_strCopyData,m_strFileMap,m_strMem,m_strUserMsg,m_strRegMsg,m_strClipBoard

然後在 CPP 檔案裡面,做如下定義:

#define BUFFER_SIZE  0x100        // 用記憶體位址通訊時分配的最大記憶體.
#define WM_COMM      WM_USER+100
const UINT wm_nRegMsg=RegisterWindowMessage("reg_data");
const UINT wm_nMemMsg=RegisterWindowMessage("mem_data");

添加兩個按鈕,並寫入代碼:

//控制項 ID 為 IDC_RECV_CLIPBOARD 將取得的值賦給 m_strFileMap
//使用windows剪貼簿的方式進行接收
void CDataRecvDlg::OnBnClickedRecvClipboard()
{
    // TODO: 在此添加控制項通知處理常式代碼
    // 開啟系統剪貼簿.
    if (!OpenClipboard()) return;

    // 判斷剪貼簿上的資料是否是指定的資料格式.
    if (IsClipboardFormatAvailable(CF_TEXT)|| IsClipboardFormatAvailable(CF_OEMTEXT))
    {
        // 從剪貼簿上獲得資料.
        HANDLE hClipboardData = GetClipboardData(CF_TEXT);
   
        // 通過給記憶體控制代碼加鎖,獲得指向指定格式資料的指標.
        char *pchData = (char*)GlobalLock(hClipboardData);
   
        // 本地變數獲得資料.
        m_strClipBoard = pchData;
   
        // 給記憶體控制代碼解鎖.
        GlobalUnlock(hClipboardData);
    }
    else
    {
        AfxMessageBox("There is no text (ANSI) data on the Clipboard.");
    }
   
    // 使用完後關閉剪貼簿.
    CloseClipboard();

    // 更新資料.
    UpdateData(FALSE);
}

//控制項 ID 為 IDC_RECV_FILEMAP, 將取得的值賦給 m_strClipBoard
//使用記憶體映射的方式進行接收
void CDataRecvDlg::OnBnClickedRecvFilemap()
{
    // TODO: 在此添加控制項通知處理常式代碼
    // 建立記憶體映像對象.
    HANDLE hMapping;
    LPSTR lpData;
    hMapping=CreateFileMapping((HANDLE)0xFFFFFFFF,
                      NULL,PAGE_READWRITE,0,0x100,"MYSHARE");
    if(hMapping==NULL)
    {
        AfxMessageBox("CreateFileMapping() failed.");
        return;
    }

    // 將檔案的視圖映射到一個進程的地址空間上,返回LPVOID類型的記憶體指標.
    lpData=(LPSTR)MapViewOfFile(hMapping,FILE_MAP_ALL_ACCESS,0,0,0);
    if(lpData==NULL)
    {
        AfxMessageBox("MapViewOfFile() failed.");
        return;
    }
   
    // 給這段映像記憶體的資料賦給本地變數.
    m_strFileMap.Format("%s",lpData);

    // 釋放映像記憶體.
    UnmapViewOfFile(lpData);
   
    // 更新資料.
    UpdateData(FALSE);
}

然後在 DataRecvDlg.cpp 中添加訊息映射
BEGIN_MESSAGE_MAP(CDataRecvDlg, CDialog)
    //}}AFX_MSG_MAP
    ON_BN_CLICKED(IDC_RECV_CLIPBOARD, OnBnClickedRecvClipboard)
    ON_BN_CLICKED(IDC_RECV_FILEMAP, OnBnClickedRecvFilemap)
    ON_WM_COPYDATA()
    ON_MESSAGE(WM_COMM,OnUserReceiveMsg)
    ON_REGISTERED_MESSAGE(wm_nRegMsg,OnRegReceiveMsg)
    ON_REGISTERED_MESSAGE(wm_nMemMsg,OnRegMemMsg)
END_MESSAGE_MAP()

在 DataRecvDlg.h 中添加響應訊息
afx_msg BOOL OnCopyData(CWnd* pWnd, COPYDATASTRUCT* pCopyDataStruct);
afx_msg LRESULT OnUserReceiveMsg(WPARAM wParam,LPARAM lParam);
afx_msg LRESULT OnRegReceiveMsg(WPARAM wParam,LPARAM lParam);
afx_msg LRESULT OnRegMemMsg(WPARAM wParam,LPARAM lParam);

最後在 DataRecvDlg.cpp 中補全訊息相應函數

//使用 WM_COPY 方式進行接收
BOOL CDataRecvDlg::OnCopyData(CWnd* pWnd, COPYDATASTRUCT* pCopyDataStruct)
{
    m_strCopyData=(LPSTR)pCopyDataStruct->lpData;

    // 獲得實際長度的字串.
    m_strCopyData=m_strCopyData.Left(pCopyDataStruct->cbData);

    // 更新資料.
    UpdateData(FALSE);
    return CDialog::OnCopyData(pWnd, pCopyDataStruct);
}

//使用使用者自訂訊息的方式進行接收
LRESULT CDataRecvDlg::OnUserReceiveMsg(WPARAM wParam,LPARAM lParam)
{
    m_strUserMsg.Format("%d/n",int(lParam));
    // 更新資料.
    UpdateData(FALSE);
    return TRUE;
}

//使用使用者註冊訊息的方式進行接收
LRESULT CDataRecvDlg::OnRegReceiveMsg(WPARAM wParam,LPARAM lParam)
{
    m_strRegMsg.Format("%d/n",int(lParam));
    // 更新資料.
    UpdateData(FALSE);
    return TRUE;
}

//使用對目標進程記憶體的訪問方式進行接收
LRESULT CDataRecvDlg::OnRegMemMsg(WPARAM wParam,LPARAM lParam)
{
    LPVOID lpBaseAddress=(LPVOID)lParam;

    // 把字串寫入hProcess進程的記憶體.
    HANDLE hProcess=GetCurrentProcess();

    char data[BUFFER_SIZE];
    ReadProcessMemory(hProcess, lpBaseAddress, data,BUFFER_SIZE, NULL);
    m_strMem=data;

    // 更新資料.
    UpdateData(FALSE);

    return TRUE;
}

至此,完成接收端

需要注意的是,接收端必須先運行,使用者自訂訊息、註冊訊息只能發送長整型的資料,其他方式可以發送字串資料.使用 記憶體映射 和 windows剪貼簿 進行資料接收時,需要點擊按紐才能接收到資料,其他方式會自動接收資料.

相關文章

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.