首页 诗词 字典 板报 句子 名言 友答 励志 学校 网站地图
当前位置: 首页 > 教程频道 > 开发语言 > C++ Builder >

纠错无须独占串口的VC的DEMO转BCB

2012-12-14 
求助纠错无须独占串口的VC的DEMO转BCB早前在本论坛发帖问过如何不独占串口监控串口数据,大家都知道要用API

求助纠错无须独占串口的VC的DEMO转BCB
早前在本论坛发帖问过如何不独占串口监控串口数据,大家都知道要用API,可没人真正玩出来。有个作者jfyes做出了CommMonitor串口监视精灵,该软件可以监控串口数据,无需独占串口,在工作中起了很大的作用。
4.0版的有二次开发SDK接口 DEMO,是DLL,更可惜只有delphi和VC的,因为对VC连入门级都算不上,踉踉跄跄地凑合成了bcb,可是搞得被监控的串口程序(尤其是BCB编制的程序)运行得不是很稳定了,常弹内存警告,请高人指点。
CommMonitor串口监视精灵DEMO界面:
http://www.ceiwei.com/upfile/2010123155902469.jpg

代码下载(内有详细接口说明):
http://www.skycn.com/soft/64411.html
http://www.crsky.com/soft/19798.html



有段源码是借用妖哥的minispy。

头文件:
#ifndef Unit1H
#define Unit1H
//---------------------------------------
#include <Classes.hpp>
#include <Controls.hpp>
#include <StdCtrls.hpp>
#include <Forms.hpp>
#include <ComCtrls.hpp>
#include <ExtCtrls.hpp>
#include <Graphics.hpp>
#define IDC_START        1002
//---------------------------------------
class TForm1 : public TForm
{
__published:// IDE-managed Components
        TComboBox *ComboBox1;
        TComboBox *ComboBox2;
        TLabel *Label3;
        TLabel *Label4;
        TCheckBox *CheckBox1;
        TStatusBar *StatusBar1;
        TButton *Button3;
        TButton *Button4;
        TImage *ImageDrag;
        TTimer *Timer1;
        TRichEdit *RichEdit1;
        void __fastcall ImageDragMouseDown(TObject *Sender,
          TMouseButton Button, TShiftState Shift, int X, int Y);
        void __fastcall ImageDragMouseMove(TObject *Sender,
          TShiftState Shift, int X, int Y);
        void __fastcall ImageDragMouseUp(TObject *Sender,
          TMouseButton Button, TShiftState Shift, int X, int Y);
        void __fastcall FormClose(TObject *Sender, TCloseAction &Action);
        void __fastcall Button3Click(TObject *Sender);
        void __fastcall Timer1Timer(TObject *Sender);
        void __fastcall FormCreate(TObject *Sender);
        void __fastcall Button4Click(TObject *Sender);
private:// User declarations
public:// User declarations
        __fastcall TForm1(TComponent* Owner);
        void OnStartMonitor(HWND hDlg);
        void FindItem(LPCSTR AStr, HWND hComBox);
};
//---------------------------------------
extern PACKAGE TForm1 *Form1;
//---------------------------------------


#endif




.cpp

#include <vcl.h>
#pragma hdrstop
#include <windows.h>
#include "commctrl.h"
#include <RICHEDIT.h>
#include <commdlg.h>
#include <shellapi.h>
#include <stdio.h>
#include <tlhelp32.h>
#include "Unit1.h"
//---------------------------------------
#pragma package(smart_init)
#pragma resource "*.dfm"
#define MAX_LOADSTRING 100

#define  COMM_OPEN    1
#define  COMM_CLOSE   2
#define  COMM_READ    3
#define  COMM_WRITE   4

#pragma pack(push)
#pragma pack(1) //设置为1字节对齐
typedef struct _HookData
{
    BYTE  ComPort;      //串口号
    BYTE  CommState;    //串口状态
    HFILE FileHandle;  //被打开的文件句柄   长整型无符号
    int   DataSize;      //数据大小     长整型有符号
    char  Data [8192] ;   //串口数据
} THookData, *PHookData;
#pragma pack(pop)

//DLL 实例句柄
HINSTANCE  gPMonitorComm = NULL;

typedef  LONG(CALLBACK *TOnData)(LONG lParam);

typedef BOOL(CALLBACK *TMonitorComm)(DWORD Pid, DWORD ComIndex,  TOnData lpCallFunc);
typedef BOOL(CALLBACK *TUnMonitorComm)(void);
typedef void(CALLBACK *TGetAllProcess)(HWND hComBox);

TMonitorComm   MonitorComm;    //启动串口监视
TUnMonitorComm UnMonitorComm;  //关闭串口监视, 返BOOL类型
TGetAllProcess GetAllProcess;  //取得全部进程ID

//////////////////////////////
LONG ReadTotal = 0;
LONG WriteTotal = 0;
HWND hMemo = NULL;
HWND hHex = NULL;
//是否是启动监视
BOOL bActive = FALSE;
HINSTANCE HInst;
BOOL MouseLButtonDown = FALSE;

bool bMouseDown;  // 鼠标按下的标志
bool bScrollFlag;  // 窗体上卷的标志
const int crMy = 1;
HANDLE hWindow, hOldWindow;  // 取得的窗口句柄
TRect ClassRect, OldClassRect;
TForm1 *Form1;
//---------------------------------------
__fastcall TForm1::TForm1(TComponent *Owner)
    : TForm(Owner)
{
}

[解决办法]
//---------------------------------------
int  FormatHex(HWND hHex, char *d, int len, LPSTR lpOutText)
{
    char hex[4] = {0};
    char h = 0;

    if (SendMessage(hHex, BM_GETCHECK, 0, 0) != BST_CHECKED)
    {
        lstrcat(lpOutText, d);
        return len;
    }

    for (int i = 0; i < len; i++)
    {
        //因为是无符号,所以要这右移4位
        int j = (d[i] >> 4) & 0xF;


        if (j <= 9)  h = j + '0';
        else h = j + 'A' - 10;

        memset(hex, 0, sizeof(hex));
        sprintf(hex, "%C", h);
        lstrcat(lpOutText, hex);

        j = d[i] & 0xF;
        if (j <= 9)  h = j + '0';
        else  h = j + 'A' - 10;

        sprintf(hex, "%C ", h);
        lstrcat(lpOutText, hex);
    }
    return lstrlen(lpOutText);
}
DWORD GetPid(LPCSTR lpText)
{
    int len;
    char buf[6];
    len = lstrlen(lpText);
    for (int i = 0; i < len; i++)
    {
        if (lpText[i] == 32)
        {
            buf[i] = 0x00;
            break;
        }
        else
            buf[i] = lpText[i];
    }

    return DWORD(atol(buf));
}
void FindItem(LPCSTR AStr, HWND hComBox)
{
    int  i;
    char buf[24];
    char line[24];
    //首先更新ComBox
    int iCount = SendMessage(hComBox, CB_GETCOUNT, 0, 0);
    for (i = 0; i < iCount; i++)
    {
        int Len = SendMessage(hComBox, CB_GETLBTEXTLEN, i, 0);
        if (Len != CB_ERR)
        {
            memset(line , 0, sizeof(line));
            if (SendMessage(hComBox, CB_GETLBTEXT, i, LONG(&line)) == 0)
                continue;

            memset(buf, 0, sizeof(buf));
            lstrcpyn(buf, line, lstrlen(AStr) + 1);

            if (lstrcmp(buf, AStr) == 0)
            {
                SendMessage(hComBox, CB_SETCURSEL, i, 0);
                break;
            }



        }
    }
}
void GetFromWindowPid(HWND hComBox)
{
    tagPOINT Pt;
    DWORD PID;
    HWND H;
    char Buf[24] = {0};


    //if ActiveCapture then Exit;
    if (!GetCursorPos(&Pt)) return;

    H = WindowFromPoint(Pt);
    if (H > 0)
    {
        GetWindowThreadProcessId(H, &PID);

        if (PID < 5) return;
        memset(Buf, 0, sizeof(Buf));
        sprintf(Buf, "%-8d ", PID);
        FindItem(Buf, hComBox);
    }
}
/*以下三段代码引用自妖哥的minispy开源程序*/
void __fastcall TForm1::ImageDragMouseDown(TObject *Sender,
      TMouseButton Button, TShiftState Shift, int X, int Y)
{
    if(Button == mbLeft)
    {
        hWindow = NULL;
        hOldWindow = NULL;
        ::SetCursor(LoadCursor(HInstance, "MyCur"));
        bMouseDown = true;
        ImageDrag->Hide();
    }
}
//---------------------------------------
void __fastcall TForm1::ImageDragMouseMove(TObject *Sender,
      TShiftState Shift, int X, int Y)
{
    POINT MousePoint, p1, p2;
    char bufClassName[255], bufClassCaption[255];
    int TextLength;

    if(bMouseDown)
    {
        GetCursorPos(&MousePoint);
        hWindow = WindowFromPoint(MousePoint);

        // 所取得的对象句柄必须不属于本程序
        if(hWindow != NULL && hWindow != Handle
                && !PtInRect(BoundsRect, MousePoint) && hWindow != hOldWindow)
        {
            if(hOldWindow != NULL)
            {
                Canvas->Handle = GetWindowDC(hOldWindow);
                Canvas->Pen->Width = 4;
                Canvas->Pen->Mode = pmNotXor;
                Canvas->Brush->Style = bsClear;
                Canvas->Rectangle(0, 0, OldClassRect.Width(), OldClassRect.Height());


            }

            GetWindowRect(hWindow, &ClassRect);
            if(hWindow != NULL)
            {
                Canvas->Handle = GetWindowDC(hWindow);
                Canvas->Pen->Width = 4;
                Canvas->Pen->Color = clRed;
                Canvas->Pen->Mode = pmNotXor;
                Canvas->Brush->Style = bsClear;
                Canvas->Rectangle(0, 0, ClassRect.Width(), ClassRect.Height());
            }

            OldClassRect = ClassRect;
            hOldWindow = hWindow;

            GetClassName(hWindow, bufClassName, 255);
            TextLength = SendMessage(hWindow, WM_GETTEXTLENGTH, 0, 0);
            if(TextLength>256)
                TextLength = 255;
        }
        GetFromWindowPid(ComboBox1->Handle);
    }
}
//--------------------------------------- 

void __fastcall TForm1::ImageDragMouseUp(TObject *Sender,
      TMouseButton Button, TShiftState Shift, int X, int Y)
{
    if(bMouseDown)
    {
        if(hOldWindow != NULL)
        {
            Canvas->Handle = GetWindowDC(hOldWindow);
            Canvas->Pen->Width = 4;
            Canvas->Pen->Mode = pmNotXor;
            Canvas->Brush->Style = bsClear;
            Canvas->Rectangle(0, 0, OldClassRect.Width(), OldClassRect.Height());
        }

        ::SetCursor(LoadCursor(NULL, IDC_ARROW));
        ImageDrag->Cursor = crHandPoint;
        bMouseDown = false;
        ImageDrag->Show();
    }        
}
int GetMemoCount(HWND hMemo)


{
int Result = SendMessage(hMemo, EM_GETLINECOUNT, 0, 0);
        if(SendMessage(hMemo,
       EM_LINELENGTH,
       SendMessage(hMemo, EM_LINEINDEX, Result - 1, 0),
0) == 0)
  Result--;
return Result;


}
void MemoPut(HWND hMemo, int Index, char *data)
{
      SendMessage(hMemo, EM_SETSEL, 666536+Index, 666536);
      SendMessage(hMemo, EM_REPLACESEL, true,  (LPARAM)data);
}

LONG CALLBACK AOnData(LONG lParam)  //THookData* p
{
    PHookData p = NULL;
    p = PHookData(lParam);
    
    if (p)
    {
        char buf[255] = {0};
        char data[8912*3+64] = {0};
        if (p->CommState == COMM_OPEN)
        {
            sprintf(buf, "打开 COM%d \r\n",  p->ComPort);
        }
        else if (p->CommState == COMM_CLOSE)
        {
            sprintf(buf, "关闭 COM%d \r\n",  p->ComPort);
        }
        else if ((p->CommState == COMM_READ) 
[解决办法]
 (p->CommState == COMM_WRITE))
        {
            if (p->CommState == COMM_READ)
            {
                sprintf(buf, "COM%d, Read: %d(Bytes) ", p->ComPort, p->DataSize);
                ReadTotal += p->DataSize;
            }
            else
            {
                sprintf(buf, "COM%u, Write: %d(Bytes) ", p->ComPort, p->DataSize);
                WriteTotal += p->DataSize;
            }

            lstrcat(data, buf);
            FormatHex(hHex, p->Data, p->DataSize, data);
            lstrcat(data, "\r\n");

            MemoPut(hMemo, GetMemoCount(hMemo) + 1, data);


            return IDOK;
        }
        MemoPut(hMemo, GetMemoCount(hMemo) + 1, buf);
    }
    return IDOK;
}

[解决办法]
void TForm1::OnStartMonitor(HWND hDlg)
{

    if (!bActive)
    {
        char buf[255] = {0};
        StrCopy(buf,ComboBox1->Text.c_str() );

        DWORD Pid = GetPid(buf);
        DWORD ComID = SendMessage(ComboBox2->Handle, CB_GETCURSEL, 0, 0);

        if (Pid < 5)
        {
            memset(buf, 0, sizeof(buf));
            sprintf(buf, "无效的进程ID: %d", Pid);
            MessageBox(hDlg, buf, "提示", MB_OK 
[解决办法]
 MB_ICONERROR);
            return;
        }

        bActive = MonitorComm(Pid,  ComID, (TOnData)AOnData);
        if (bActive)
        {
            Button3->Caption ="停止监视";
            char p[64] = {0};
            memset(buf, 0, sizeof(buf));
            SendMessage(ComboBox1->Handle, CB_GETLBTEXT, 0, (LPARAM)p);
            sprintf(buf, "打开监视成功, %s\r\n", p);
            StatusBar1->Panels->Items[0]->Text=buf;

        }
    }
    else
    {
        UnMonitorComm();
        bActive = FALSE;
        MemoPut(hMemo, GetMemoCount(hMemo) + 1, "成功关闭监视\r\n");
        Button3->Caption ="启动监视";

    }
    ComboBox1->Enabled=bActive;
    return;

}

void TForm1::FindItem(LPCSTR AStr, HWND hComBox)
{
    int  i;
    char buf[24];
    char line[24];
    //首先更新ComBox
    int iCount = SendMessage(hComBox, CB_GETCOUNT, 0, 0);
    for (i = 0; i < iCount; i++)
    {
        int Len = SendMessage(hComBox, CB_GETLBTEXTLEN, i, 0);


        if (Len != CB_ERR)
        {
            memset(line , 0, sizeof(line));
            if (SendMessage(hComBox, CB_GETLBTEXT, i, LONG(&line)) == 0)
                continue;

            memset(buf, 0, sizeof(buf));
            lstrcpyn(buf, line, lstrlen(AStr) + 1);

            if (lstrcmp(buf, AStr) == 0)
            {
                SendMessage(hComBox, CB_SETCURSEL, i, 0);
                break;
            }
        }
    }
}
void __fastcall TForm1::FormClose(TObject *Sender, TCloseAction &Action)
{
if (MessageBox(Handle, "确定要退出吗?", "提示", MB_OKCANCEL 
[解决办法]
 MB_ICONINFORMATION) != IDOK)
return;

if (bActive)  OnStartMonitor(Handle);
    //释放DLL库
    FreeLibrary(gPMonitorComm);
}
//---------------------------------------

void __fastcall TForm1::Button3Click(TObject *Sender)
{
      OnStartMonitor(Handle);
}
//---------------------------------------

void __fastcall TForm1::Timer1Timer(TObject *Sender)
{
  GetAllProcess(ComboBox1->Handle);

  if (bActive)
  if (SendMessage(ComboBox1->Handle, CB_GETCURSEL, 0, 0) < 0)
      PostMessage(ComboBox1->Handle, WM_COMMAND, IDC_START, 0);
}
//---------------------------------------

void __fastcall TForm1::FormCreate(TObject *Sender)
{
    hMemo= RichEdit1->Handle;
    hHex = CheckBox1->Handle;
    Button4->Caption ="清空";
    CheckBox1->Caption="HEX/ASC";
    SendMessage(hHex, BM_SETCHECK, 1, 0);
    gPMonitorComm = LoadLibrary("PMonitorComm4.dll");
    if (!gPMonitorComm)
    {

        MessageBox(GetForegroundWindow(), "加载PMonitorComm.dll失败,请检察该DLL是否存在。", "提示", MB_OK 
[解决办法]
 MB_ICONERROR);
        return;
    }
    //取得func地址
    MonitorComm   = (TMonitorComm)GetProcAddress(gPMonitorComm, "MonitorComm");
    UnMonitorComm = (TUnMonitorComm)GetProcAddress(gPMonitorComm, "UnMonitorComm");


    GetAllProcess = (TGetAllProcess)GetProcAddress(gPMonitorComm, "GetAllProcess");

    if (!MonitorComm)
    {
        MessageBox(0, "MonitorComm function address无效。", "提示", MB_OK 
[解决办法]
 MB_ICONERROR);
        return;
    }

    if (!UnMonitorComm)
    {
        MessageBox(0, "UnMonitorComm function address无效。", "提示", MB_OK 

热点排行