WINCE下进程间通信常用的方式有:剪贴板(Clipboard),网络套接字(Socket),WM_COPYDATA消息,共享内存,管道(消息队列),注册表等

剪贴板

    ///////////////////////////剪贴板发送数据//////////////////////////////////
    )
    {    //把数据放入剪贴板,并发送一个键盘粘贴消息给当前获得焦点的输入框。
        HGLOBAL hMemClip;                                     //指向分配的内存块
        if (AfxGetMainWnd()->OpenClipboard())                 //打开剪贴板
        {    EmptyClipboard();                                //清空剪贴板
            hMemClip = GlobalAlloc(GHND,nlen*);              //分配可移动内存块
            WCHAR *buff_dest=(WCHAR *)GlobalLock(hMemClip);   //锁定内存块
            memcpy(buff_dest,szBuf,nlen*);                   //数据装入内存块
            GlobalUnlock(hMemClip);                           //解锁内存块
            SetClipboardData(CF_UNICODETEXT,hMemClip);        //将存放有数据的内存块放入剪贴板的资源管理中
            CloseClipboard();                                 //关闭剪贴板

            //向有光标焦点的控件发送虚拟键盘消息“CTRL + V”再加一个回车
            keybd_event(, , );                    //V
            keybd_event(, , );                    //CTRL
            keybd_event(, KEYEVENTF_KEYUP, );
            keybd_event(, KEYEVENTF_KEYUP, );
            keybd_event(, , );                    //Enter
            keybd_event(, KEYEVENTF_KEYUP, );
        }
    }

!!以下部分转自http://blog.csdn.net/firehood_/article/details/6269310  以下代码未作测试详细请看博客原地址

谢谢firehood

WM_COPYDATA消息

// 发送端////////////////////////////////////////////////////////////////////////
void SendMsg(HWND hwnd,LPVOID lpData,DWORD dwSize)
{
    // 填充COPYDATASTRUCT结构
    COPYDATASTRUCT cpd;
    cpd.cbData = dwSize;
    cpd.lpData = lpData; 

    // 向指定窗口发送WM_COPYDATA消息,不能用PostMessage方式发送
    ::SendMessage(hwnd, WM_COPYDATA, NULL,(LPARAM)&cpd);
}

TCHAR *data=_T("要发送的内容");
SendMsg(::FindWindow(NULL,_T();

// 接收端////////////////////////////////////////////////////////////////////////
LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
{
    PAINTSTRUCT ps;
    HDC hdc;
    TCHAR data[]={};

    switch (message)
    {
        case WM_COPYDATA:
            {
                COPYDATASTRUCT *pCopyDataStruct=(COPYDATASTRUCT *)lParam;
                memcpy(data,pCopyDataStruct->lpData,pCopyDataStruct->cbData);
            }
            break;
        // ...
   }
   return DefWindowProc(hWnd, message, wParam, lParam);
}

共享内存

共享内存顾名思义是在内存中创建一个公共区域,供不同的进程间的数据共享。因为是直接对内存进行读写操作,效率非常高,所以共享内存特别适用于大批量的数据传输且实时性要求比较高的场合。

具体操作步骤如下:

1.进程A调用CreateFileMapping创建一个内存映射文件。

2.进程A调用MapViewOfFile获取到映射到文件的内存起始地址,调用memcpy往内存中拷贝数据。

3.进程B调用CreateFileMapping打开进程A创建的内存映射文件。

4.进程B调用MapViewOfFile获取到映射到文件的内存起始地址,调用memcpy从内存中读出数据。

5.通信完后进程A,B分别调用UnmapViewOfFile,CloseHandle取消内存映射和关闭内存映射对象句柄。

为了简化操作,这里封装了一个共享内存操作类,参考代码如下:

头文件CShareMemory.h:    

/*******************************************************************
 filename: CShareMemory.h
 purpose:    封装了共享内存操作类
 author:    firehood
 created:    2011.03.16
********************************************************************/
#ifndef _SHARE_MEMORY_H
#define _SHARE_MEMORY_H

class CShareMemory
{
public:
    CShareMemory();
    ~CShareMemory();
public:
    /**********************************************************
    函数名:Open
    功能:  创建或打开内存映射文件
    参数:
            [in]szMapName:        要创建的共享内存名称
            [in]dwSize:            创建共享内存的大小
    返回值:
            0:        失败
            1:        创建成功
            2:      文件已存在
    ***********************************************************/
    DWORD Open(LPCTSTR szMapName,DWORD dwSize);

    /**********************************************************
    函数名:Read
    功能:  从共享内存指定位置读取数据
    参数:
            [out]pBuf:            存放读取的数据
            [in]dwSize:            读取数据的大小
            [in]dwOffset        距共享内存起始位置的偏移量
    返回值:
            TRUE: 成功 FALSE:失败
    ***********************************************************/
    BOOL Read();

    /**********************************************************
    函数名:Write
    功能:  从共享内存指定位置写入数据
    参数:
            [in]pBuf:            待写入的数据指针
            [in]dwSize:            写入数据的大小
            [in]dwOffset        距共享内存起始位置的偏移量
    返回值:
            TRUE: 失败 FALSE:失败
    ***********************************************************/
    BOOL Write();
    void Close(void);
private:
    HANDLE m_hShareMemory;
    LPVOID m_pMapBuffer;
    HANDLE m_hAccessMutex;
};

#endif

源文件CShareMemory.cpp:    

#include "stdafx.h"
#include "CShareMemory.h"

CShareMemory::CShareMemory()
{
    m_hShareMemory = NULL;
    m_pMapBuffer = NULL;
    m_hAccessMutex =NULL;
}

CShareMemory::~CShareMemory()
{
    Close();
}

DWORD CShareMemory::Open(LPCTSTR szMapName,DWORD dwSize)
{
    DWORD dwRet = ;
    if(szMapName == NULL)
        ;

    if(m_hShareMemory)
    {
        Close();
    } 

    // 创建内存映射文件对象
    m_hShareMemory = CreateFileMapping(INVALID_HANDLE_VALUE,NULL,PAGE_READWRITE,,dwSize,szMapName);
    if(!m_hShareMemory)
    {
        ;
    }
    // 内存映射文件对象已存在
    if(GetLastError() == ERROR_ALREADY_EXISTS)
    {
        dwRet = ;
    }
    // 获取内存映射文件指针
    m_pMapBuffer = MapViewOfFile(m_hShareMemory,FILE_MAP_ALL_ACCESS,,,);
    if(!m_pMapBuffer)
    {
        CloseHandle(m_hShareMemory);
        ;
    }

    // 创建互斥体,用于读写同步
    TCHAR szMutexName[MAX_PATH];
    _tcscpy(szMutexName, szMapName);
    _tcscat(szMutexName, _T("_Mutex"));
    m_hAccessMutex=CreateMutex(NULL, FALSE, szMutexName);
    if(!m_hAccessMutex)
    {
        Close();
        ;
    }
    return dwRet;
}

BOOL CShareMemory::Read(void* pBuf,DWORD dwSize,DWORD dwOffset)
{
    BOOL bRet;
    if(!m_pMapBuffer) return FALSE;

    if(WaitForSingleObject(m_hAccessMutex,INFINITE)==WAIT_OBJECT_0)
    {
        memcpy(pBuf,(BYTE*)m_pMapBuffer+dwOffset,dwSize);
        bRet = TRUE;
    }
    ReleaseMutex(m_hAccessMutex);
    return bRet;
}

BOOL CShareMemory::Write(const void* pBuf,DWORD dwSize,DWORD dwOffset)
{
    BOOL bRet;
    if(!m_pMapBuffer) return FALSE;

    if(WaitForSingleObject(m_hAccessMutex,INFINITE)==WAIT_OBJECT_0)
    {
        memcpy((BYTE*)m_pMapBuffer+dwOffset,pBuf,dwSize);
        bRet = TRUE;
    }
    ReleaseMutex(m_hAccessMutex);
    return TRUE;
}

void CShareMemory::Close(void)
{
    if(m_hShareMemory)
    {
        UnmapViewOfFile(m_pMapBuffer);
        CloseHandle(m_hShareMemory);
        m_pMapBuffer = NULL;
        m_hShareMemory = NULL;

    }
    if(m_hAccessMutex)
    {
        CloseHandle(m_hAccessMutex);
        m_hAccessMutex = NULL;
    }
}

管道(消息队列)

WINCE并不支持类似于PC机上匿名管道、命名管道的通信方式,但CE下提供了一种点对点消息队列的方法,其工作原理与管道非常类似:在通信的两端分别建立一个读队列和写队列,写进程往消息队列一端写入数据,读进程从消息队列另一端读取数据。

消息队列相关的系统API主要有:CreateMsgQueue()、ReadMsgQueue()、WriteMsgQuue()和CloseMsgQueue()。为了方便消息队列的操作,封装了一个消息队列操作类,参考代码如下:

头文件(CMsgQueue.h)

  

/*******************************************************************
 filename: CMsgQueue.h
 purpose:    封装了WINCE下消息队列操作类
 author:    firehood
 created:    2011.03.23
********************************************************************/
#ifndef _MSG_QUEUE_H
#define _MSG_QUEUE_H

// 消息队列访问模式
enum ACCESSMODE
{
    ReadMode = ,
    WriteMode
};

// 定义消息回调函数
typedef BOOL (CALLBACK *MsgQueueCallBack)(PVOID pData, DWORD dwSize);

class CMsgQueue
{
public:
    CMsgQueue();
    CMsgQueue(LPCWSTR lpQueueName,DWORD dwSize,ACCESSMODE accessMode);
    ~CMsgQueue();
public:
    /**********************************************************************
    函数名:Create
    功能:  创建或打开消息队列
    参数:
            [in]lpQueueName:    消息队列名称
            [in]dwSize:            每条消息的最大长度
            [in]accessMode      消息队列访问模式 ReadMode:只读  WriteMode:只写
    返回值:
            成功:TRUE  失败:FALSE
    **********************************************************************/
    BOOL Create(LPCWSTR lpQueueName,DWORD dwSize,ACCESSMODE accessMode);

    /**********************************************************************
    函数名:Read
    功能:  从消息队列中读取一条消息
    参数:
            [out]lpBuffer:              存放读取的数据
            [in] dwSize:              读取数据的大小
            [out]lpNumberOfBytesRead  实际读取数据的大小
            [in] dwTimeout            读取超时时间(ms) 0 立即返回  INFINITE 永远等待直至消息队列中有数据
    返回值:
            成功:TRUE  失败:FALSE
    ***********************************************************************/
    BOOL Read(LPVOID lpBuffer,DWORD dwSize,LPDWORD lpNumberOfBytesRead,DWORD dwTimeout = );

    /**********************************************************************
    函数名:Write
    功能:  向消息队列中写入一条消息
    参数:
            [in]lpBuffer:       待写入的数据
            [in]dwSize:           写入数据的大小
    返回值:
            成功:TRUE  失败:FALSE
    **********************************************************************/
    BOOL Write(LPVOID lpBuffer,DWORD dwSize);

    // 设置消息回调函数
    BOOL SetMsgCallBack(MsgQueueCallBack pCallBackFun, PVOID pParam);
    // 关闭消息队列
    void Close(void);
private:
    // 开启读取消息线程
    BOOL StartRevMsgThread(void);
    // 停止读取消息线程
    BOOL StopRevMsgThread(void);
    // 读取消息线程
    static void WINAPI RevMsgThread(LPVOID pParam);
private:
    HANDLE m_hMsgQueue;
    DWORD m_dwQueueSize;
    MsgQueueCallBack m_MsgCallBack;
    HANDLE m_hRevMsgThread;
    BOOL m_bThreadExit;
};
#endif

源文件(CMsgQueue.cpp)

#include "stdafx.h"
#include "CMsgQueue.h"

CMsgQueue::CMsgQueue()
{
    m_hMsgQueue = NULL;
    m_dwQueueSize = ;
    m_hRevMsgThread = NULL;
    m_bThreadExit = FALSE;
    m_MsgCallBack = NULL;
}

CMsgQueue::CMsgQueue(LPCWSTR lpQueueName,DWORD dwSize,ACCESSMODE accessMode)
{
    Create(lpQueueName,dwSize,accessMode);
}

CMsgQueue::~CMsgQueue()
{
    Close();
}

BOOL CMsgQueue::Create(LPCWSTR lpQueueName,DWORD dwSize,ACCESSMODE accessMode)
{
    if(!m_hMsgQueue)
    {
        m_hRevMsgThread = NULL;
        m_bThreadExit = FALSE;
        m_MsgCallBack = NULL;
        m_dwQueueSize = dwSize;
        // 创建消息队列
        MSGQUEUEOPTIONS options;
        options.dwSize = sizeof(options);
        options.dwFlags = MSGQUEUE_NOPRECOMMIT|MSGQUEUE_ALLOW_BROKEN;
        options.dwMaxMessages = ;
        options.cbMaxMessage = dwSize;
        options.bReadAccess = (accessMode==ReadMode) ? TRUE : FALSE;
        m_hMsgQueue =::CreateMsgQueue(lpQueueName,&options);
    }
    return TRUE;
}

void CMsgQueue::Close(void)
{
    if(m_hMsgQueue)
    {
        ::CloseMsgQueue(m_hMsgQueue);
        m_hMsgQueue = NULL;
    }
    // 注销回调函数
    SetMsgCallBack(NULL,NULL);
}

BOOL CMsgQueue::Read(LPVOID lpBuffer,DWORD dwSize,LPDWORD lpNumberOfBytesRead,DWORD dwTimeout)
{
    if(m_hMsgQueue == NULL || lpBuffer == NULL)
    {
        return FALSE;
    }
    DWORD dwFlag = ;
    // 从消息队列头部读出数据
    if(!::ReadMsgQueue(m_hMsgQueue,lpBuffer,dwSize,lpNumberOfBytesRead,dwTimeout,&dwFlag))
    {
        return FALSE;
    }
    return TRUE;
}
BOOL CMsgQueue::Write(LPVOID lpBuffer,DWORD dwSize)
{
    if(m_hMsgQueue == NULL || lpBuffer == NULL)
    {
        return FALSE;
    }
    // 向消息队列尾部写入数据
    ,))
    {
        return FALSE;
    }
    return TRUE;
}

BOOL CMsgQueue::SetMsgCallBack(MsgQueueCallBack pCallBackFun, PVOID pParam)
{
    m_MsgCallBack = pCallBackFun;
    if (m_MsgCallBack)
    {
        if (m_hRevMsgThread == NULL)
        {
            // 开启读取线程
            return StartRevMsgThread();
        }
    }
    else
    {
        if (m_hRevMsgThread)
        {
            // 关闭读取线程
            return StopRevMsgThread();
        }
    }
    return TRUE;
}

BOOL CMsgQueue::StartRevMsgThread(void)
{
    if(m_hRevMsgThread == NULL)
    {
        // 创建读取消息线程
        m_hRevMsgThread = CreateThread(NULL, , (LPTHREAD_START_ROUTINE)CMsgQueue::RevMsgThread, , NULL);
    }
    return (m_hRevMsgThread ? TRUE : FALSE);
}

BOOL CMsgQueue::StopRevMsgThread(void)
{
    if(m_hRevMsgThread)
    {
        m_bThreadExit = TRUE;
        // 等待线程成功退出
        WaitForSingleObject(m_hRevMsgThread,INFINITE);
        CloseHandle(m_hRevMsgThread);
        m_hRevMsgThread = NULL;
        m_hRevMsgThread = FALSE;
    }
    return ((m_hRevMsgThread==NULL) ? TRUE : FALSE);
}

void WINAPI CMsgQueue::RevMsgThread(LPVOID pParam)
{
     CMsgQueue *pMsgQueue=(CMsgQueue*)pParam;
     LPVOID lpBuffer;
     DWORD dwReadNums=;
     lpBuffer=(LPVOID)malloc(pMsgQueue->m_dwQueueSize);
     while(!pMsgQueue->m_bThreadExit)
     {
         if(!pMsgQueue->m_hMsgQueue )
             break;
         // 从消息队列中读取一条消息(阻塞模式)
         BOOL ret=pMsgQueue->Read(lpBuffer,pMsgQueue->m_dwQueueSize,&dwReadNums,INFINITE);
         printf("Read ret=%d,dwReadNums=%d/n",ret,dwReadNums);
         )
         {
             // 调用回调函数
             if(pMsgQueue->m_MsgCallBack)
                 pMsgQueue->m_MsgCallBack(lpBuffer,dwReadNums);
         }
     }
     printf("RevMsgThread exit.../n");
     free(lpBuffer);
}

使用CMsgQueue类实现进程间通信:

// 发送进程
//////////////////////////////////////////////////////////////////////////////////
// 创建只写消息队列
CMsgQueue cMsgQueue(L,WriteMode);
// 往消息队列写数据
cMsgQueue.Write(L);
cMsgQueue.Close();
//////////////////////////////////////////////////////////////////////////////////

// 接收进程
//////////////////////////////////////////////////////////////////////////////////
// 声明消息回调函数
BOOL CALLBACK RecvMsgProc(PVOID pData, DWORD dwSize);

// 创建只读消息队列
CMsgQueue cMsgQueue(L,ReadMode);
// 设置消息回调函数
cMsgQueue.SetMsgCallBack(RecvMsgProc,NULL);

// 处理消息
BOOL CALLBACK RecvMsgProc(PVOID pData, DWORD dwSize)
{
    printf("RecvMsgProc:Rev data Size=%d/n",dwSize);
    wchar_t data[];
    memcpy(data, pData,dwSize);
    return TRUE;
}
//////////////////////////////////////////////////////////////////////////////////

CE 进程间通信的更多相关文章

  1. WINCE下进程间通信(二)

    WINCE下进程间通信(二) 接着前面的文章<WINCE下进程间通信(一)>,现在介绍进程间通信的另一种方法. 三.管道(消息队列) WINCE并不支持类似于PC机上匿名管道.命名管道的通 ...

  2. CE修改器修改DNF 测试视频 阿修罗提升智力增加攻击力

    使用CE修改器来修改网络游戏,如DNF 测试视频: CE修改器:指的是Cheat Engine,字面上的意思指的是作弊引擎的意思,是一款内存修改编辑工具.通过修改游戏的内存数据来得到一些原本无法实现的 ...

  3. PreEmptive Dotfuscator and Analytics CE

    PreEmptive Dotfuscator and Analytics CE Dotfuscator 是领先的 .NET 模糊处理程序和压缩程序,有助于防止程序遭到反向工程,同时使程序更小更高效.D ...

  4. C++进程间通信

    # C++进程间通信 # 进程间通讯的四种方式:剪贴板.匿名管道.命名管道和邮槽 ## 剪切板 ## //设置剪切板内容 CString str; this->GetDlgItemText(ID ...

  5. android:使用Messenger进行进程间通信(一)

    Messenger简介 Messenger和AIDL是实现进程间通信(interprocess communication)的两种方式. 实际上,Messenger的实现其实是对AIDL的封装. Me ...

  6. PHP 进程间通信——消息队列(msg_queue)

    PHP 进程间通信--消息队列 本文不涉及PHP基础库安装.详细安装说明,请参考官网,或期待后续博客分享. 1.消息队列函数准备 <?php//生成一个消息队列的key$msg_key = ft ...

  7. WM_COPYDATA实现的不同进程间通信

    进程间通信,通过SendMessage向另一进程发送WM_COPYDATA消息,实现不同进程间的消息通信. 需求:已写好一个工具软件,想在不更改当前的软件开发的前提下,实现为后面新开发的软件提供数据推 ...

  8. Linux学习笔记(12)-进程间通信|匿名管道

    Linux的进程间通信有几种方式,包括,管道,信号,信号灯,共享内存,消息队列和套接字等-- 现在一个个的开始学习! ----------------------------------------- ...

  9. Visual Studio 2005 搭建Windows CE 6.0环境之准备

    Microsoft Visual Studio 2005 Visual Studio 2005 Professional 官方90天试用版英文版:http://download.microsoft.c ...

随机推荐

  1. QT_BEGIN_NAMESPACE和QT_END_NAMESPACE的作用

    本文根据在网上找到的一些资料总结来的,并加入了一些自己的想法. 在源代码中是这样定义的: # define QT_BEGIN_NAMESPACE namespace QT_NAMESPACE { # ...

  2. 关于 unsigned 型变量在计算过程中发生的事情

    运行环境:CentOS release 5.8 (Final) #include<stdio.h> #include<iostream> using namespace std ...

  3. Levenberg-Marquardt算法基础知识

    Levenberg-Marquardt算法基础知识 (2013-01-07 16:56:17) 转载▼   什么是最优化?Levenberg-Marquardt算法是最优化算法中的一种.最优化是寻找使 ...

  4. 设置Windows 7 防火墙端口规则

    http://jingyan.baidu.com/article/c843ea0b7d5c7177931e4ab1.html?qq-pf-to=pcqq.c2c 主要解决手机访问pc站点的问题(pc和 ...

  5. IOS开发:监听来电状态的改变。

    #import <CoreTelephony/CTCallCenter.h> #import <CoreTelephony/CTCall.h> @property(nonato ...

  6. It will affect staff as well.

    Premier Foods has reduced its number of suppliers dramatically in the last 12 months. In 2013 it mad ...

  7. ios安装app提示【未受信任的企业级开发者】。在设置中信任此开发者

     最近在测试app,ios安装app后点击提示如下图: 解决方法: 1 点击 [设置] >[通用] >[设备管理]   2 点击企业级应用 > 信任该开发者 > 信任.设置之后 ...

  8. Outlook查找未读邮件

    1.查找新邮件的未读邮件,可以在下图中查找 2.恢复已删除邮件,如果邮件是未读邮件,在上图中是查找不到,只能通过视图去查找 步骤2内容摘自百度

  9. taginput ,complete使用笔记

    页面用到自动完成功能及需要taginput控件去展示,查资料的过程中发现 有两个类似的jQuery类库,到现在我也没搞明白它们两个有啥关联,jquery.tagsinput.js和bootstrap- ...

  10. Oracle 数据库--一个用户同步的sql

    用户同步的sql: insert into crm_customer_user ,username,,,,,id, from sys_user where username not in (selec ...