监控窗体按键,发送相应的串口信息

项目需要 摇杆 控制机器,但是在家里调试 摇杆机构不方便,所以采用了 串口 加 电脑键盘按键

=单片机接收串口消息,生成摇杆信息

监控窗体按键信息的代码如下,本来打算用keyup keydown 事件的,发现不行,必须重写 PreTranslateMessage 函数

BOOL Ckey2comDlg::PreTranslateMessage(MSG* pMSG)
{
      if (pMSG ->message == WM_KEYDOWN)  // If a keydown message
      {
          unsigned char sndkey;
          switch(pMSG ->wParam)
          {
          case 'A':
          case 'S':
          case 'D':
          case 'W':
          case 'O':
          case 'M':
          case 'B':
              sndkey=pMSG ->wParam+'a'-'A';
              myCom.SendData(&sndkey,1);
              break;
          }
      }
      else if (pMSG ->message == WM_KEYUP)  // If a keydown message
      {
          unsigned char sndkey;
          switch(pMSG ->wParam)
          {
          case 'A':
          case 'S':
          case 'D':
          case 'W':
              sndkey=pMSG ->wParam;
              myCom.SendData(&sndkey,1);
              break;
          }
      }
      return CDialogEx::PreTranslateMessage(pMSG);
}


串口代码如下

// Com.cpp: implementation of the CCom class.
//
//
//#include "includes.h"
//#include "stdio.h"
#include "stdafx.h"
//#include "windows.h"
#include "string.h"
#include "com.h"
#pragma warning(disable:4996)
//
// Construction/Destruction
//

CCom::CCom()
{
    //h_Semaphore=CreateSemaphore(NULL,1,1,NULL);
}

CCom::~CCom()
{
    CloseCom();
}

DWORD WINAPI CCom::ReadThread(LPVOID lpParam)
{
    BYTE *pReadData=NULL;
    DWORD dwRead=0;        //,dwErr;
    CCom *pCom=(CCom*)lpParam;
    BOOL ReadState;
    pCom->m_running=TRUE;
    pReadData=new BYTE[256];
    while(pCom->m_running==TRUE)
    {
        //系统读出数据        
        ReadState=ReadFile(pCom->m_hcom,pReadData,256,&dwRead,&pCom->m_osReader);        
        if(!ReadState)
        {
            if(GetLastError()==ERROR_IO_PENDING)
            {
                //等待串口接收结果
                GetOverlappedResult(pCom->m_hcom,&pCom->m_osReader,&dwRead,TRUE);    
                ReadState=TRUE;
            }
        }
        if(ReadState && dwRead)
        {
            if(pCom->fnc!=NULL)    
                pCom->fnc(pReadData,dwRead);
        }
        else Sleep(1);
    }
    delete pReadData;
    return 1;
}

VOID CCom::CloseCom()
{
    if(m_running==TRUE)
    {
        m_running=FALSE;
        Sleep(5);
        CloseHandle(m_osReader.hEvent);
        CloseHandle(m_osWriter.hEvent);
        CloseHandle(m_hcom);
    }
}

DWORD CCom::SendData(const BYTE *src,DWORD len)
{
    DWORD dwWrite;
    BOOL bResult;
    if(m_running==FALSE)    return len;
    //WaitForSingleObject(h_Semaphore,INFINITE);        
    do{
        m_osWriter.Offset=0;
        m_osWriter.OffsetHigh=0;
        dwWrite=0;
        bResult=WriteFile(m_hcom,src,len,&dwWrite,&m_osWriter);
        if(!bResult)
        {
            if(GetLastError()==ERROR_IO_PENDING)
            {
                GetOverlappedResult(m_hcom,&m_osWriter,&dwWrite,TRUE);        //等待异步写完成
                bResult=TRUE;
            }
        }
        len-=dwWrite;
        src+=dwWrite;
    }while(len && bResult==TRUE);
    //ReleaseSemaphore(h_Semaphore,1,NULL);                                    //释放信号量
    return len;
}




BOOL CCom::OpenCom(LPCTSTR lpName, DWORD boud,VFNC recdeal)
{
    TCHAR portName[128];
    BOOL UsbMode=FALSE;
    portName[0]=0;
    strcat(portName,lpName);
    if(strlen(portName)==5)
    {
        TCHAR tmp[128]="\\\\.\\";
        strcat(tmp,portName);
        strcpy(portName,tmp);
    }
    m_hcom=CreateFile(portName, GENERIC_READ | GENERIC_WRITE, 0, NULL , OPEN_EXISTING, FILE_FLAG_OVERLAPPED, NULL);    
    if (m_hcom == INVALID_HANDLE_VALUE)
    {
        return FALSE;
    }
    else
    {
        DCB wdcb = {0};
        GetCommState(m_hcom, &wdcb);
        wdcb.BaudRate = boud;    
        wdcb.ByteSize = 8;        

        //设置串口参数
        SetCommState(m_hcom, &wdcb);
        //设置串口超时参数
        COMMTIMEOUTS toUsb =// 串口超时控制参数
        {
            1,        // 读字符间隔超时时间
            1,        // 读操作时每字符的时间
            100,        // 基本的(额外的)读超时时间
            0,        // 写操作时每字符的时间
            0        // 基本的(额外的)写超时时间
        };

        COMMTIMEOUTS toNormal =// 串口超时控制参数
        {
            50,        // 读字符间隔超时时间
            1,        // 读操作时每字符的时间
            50,        // 基本的(额外的)读超时时间
            2,        // 写操作时每字符的时间
            100        // 基本的(额外的)写超时时间
        };
        
        if(UsbMode==TRUE)    SetCommTimeouts(m_hcom, &toUsb);
        else                SetCommTimeouts(m_hcom, &toNormal);
        //设置串口缓冲队列
        SetupComm(m_hcom, 1024, 1024);
        //清空并结束串口当前动作
        PurgeComm(m_hcom, PURGE_TXCLEAR | PURGE_RXCLEAR);
        fnc=recdeal;
        FillMemory(&m_osReader, sizeof(OVERLAPPED),0);    
        FillMemory(&m_osWriter, sizeof(OVERLAPPED),0);
        m_osReader.hEvent = CreateEvent(NULL,TRUE,FALSE,NULL);
        m_osWriter.hEvent = CreateEvent(NULL,TRUE,FALSE,NULL);
        HANDLE hThread =CreateThread(NULL, 0, ReadThread, this, 0, &dwThreadID);
        CloseHandle(hThread);
    }
    return TRUE;
}



### 回答1: 可以使用 Windows API 中的 SendMessage 函数向指定窗体发送键盘消息。具体步骤如下: 1. 定义键盘消息常量: ``` const WM_KEYDOWN = $0100; WM_KEYUP = $0101; VK_F11 = $7A; ``` 2. 使用 SendMessage 函数向指定窗口发送键盘消息: ``` var hWnd: HWND; begin // 获取目标窗口句柄,例如通过窗口标题查找 hWnd := FindWindow(nil, '窗口标题'); // 发送 F11 按键按下消息 SendMessage(hWnd, WM_KEYDOWN, VK_F11, 0); // 发送 F11 按键抬起消息 SendMessage(hWnd, WM_KEYUP, VK_F11, 0); end; ``` 以上代码会向指定窗体发送一个 F11 按键按下消息,然后再发送一个 F11 按键抬起消息,模拟用户按下并松开 F11 键。 ### 回答2: 要向指定窗体发送F11按键,我们可以使用Delphi中的Windows API函数来实现。 首先,我们需要获取指定窗体的句柄(handle)。可以使用FindWindow函数来根据窗体的类名或标题来查找对应窗口的句柄。例如: ```delphi var hWnd: HWND; begin hWnd := FindWindow(nil, '指定窗体的标题'); if hWnd <> 0 then begin // 句柄有效,可以发送按键消息 end; end; ``` 然后,我们可以使用PostMessage函数来发送按键消息。F11键的消息常量为WM_KEYDOWN和WM_KEYUP,对应虚拟键码VK_F11。例如: ```delphi begin // ... PostMessage(hWnd, WM_KEYDOWN, VK_F11, 0); PostMessage(hWnd, WM_KEYUP, VK_F11, 0); end; ``` 最后,如果我们想要模拟按住F11键一段时间,可以使用Sleep函数来延迟一定的时间。例如: ```delphi begin // ... PostMessage(hWnd, WM_KEYDOWN, VK_F11, 0); Sleep(100); // 延迟100毫秒 PostMessage(hWnd, WM_KEYUP, VK_F11, 0); end; ``` 以上就是使用Delphi7向指定窗体发送F11按键的方法。通过查找窗体句柄并发送按键消息,我们可以模拟对窗体的操作,实现自动化或批量处理等需求。 ### 回答3: 在Delphi7中,我们可以通过使用Windows API的SendMessage函数来向指定窗体发送按键消息。具体实现步骤如下: 首先,我们需要定义Windows API中的常量和函数,可以在接口部分或者实现部分进行定义,例如: const WM_KEYDOWN = $0100; function SendMessage(hWnd: HWND; Msg: Integer; wParam: WPARAM; lParam: LPARAM): LRESULT; stdcall; external 'user32.dll'; 然后,我们需要获取指定窗体的句柄,可以使用FindWindow函数来获取指定窗体的句柄,例如: var hwndTarget: HWND; begin hwndTarget := FindWindow(nil, '窗体标题'); // 根据窗体的标题查找句柄 if hwndTarget <> 0 then begin // 向指定窗体发送F11按键消息 SendMessage(hwndTarget, WM_KEYDOWN, VK_F11, 0); end; end; 以上就是使用Delphi7向指定窗体发送F11按键的方法。其中,通过FindWindow函数可以获取指定窗体的句柄,在发送按键消息时使用SendMessage函数发送KeyPress消息。请注意,在使用这些函数时,需要在程序的uses节中引入Windows单元。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值