1. 问题

    error C2664: "BuildCommDCBW": 不能将参数 1 从"char *"转换为"LPCWSTR"经常出现这样的错误?

    对于上面的错误,主要是字符编码设置的问题,修改下面的选项即可:

    http://bbs.csdn.net/topics/310076558 这篇帖子里面有解决方案.

    不能想当然的,就做强制转换,不然可能会出错。下面的做法是错误的。

    正确的解决方案:

    类似下面这种:

    当我们将上面的改为 支持多字符集的时候,我们需要将下面的 OpenEventW (xxxx) 改为:

  2. MFC当中创建线程

    参考文档: http://www.cnblogs.com/mx113/archive/2009/12/03/1616445.html 使用MFC中的AfxBeginThread创建多线程

    用户界面线程和工作线程区别:继承主用户界面进程。

    error C2248: "CObject::operator =": 无法访问 private 成员(在"CObject"类中声明)

    参考资料: http://blog.csdn.net/cxf7394373/article/details/12389507 这种对控件操作的对象最好都声明成指针

    多线程中,数据传递:通过消息机制实现。

    下面这个解释和android当中控件必须在子线程当中的解释几乎一致。

不要在线程函数体内操作MFC控件,因为每个线程都有自己的线程模块状态映射表,在一个线程中操作另一个线程中创建的MFC对象,会带来意想不到的问题。更不要在线程函数里,直接调用UpdataData()函数更新用户界面,这会导致程序直接crash。而应该通过发送消息给主线程的方式,在主线程的消息响应函数里操作控件。

不过,我们虽然不能对控件进行操作,但是我们还是可以操作主界面的。

我们完全可以通过获取 AfxGetApp() -> m_pMainWnd -> GetDC(); 来与主窗体进行联系。

但是如何联系里面的控件? 目前还没有好的方法。不过,我觉得肯定是有方法的。

  1. 如何对MFC当中的EDIT控件进行操作。

    这里我们需要通过EDIT控件的ID进行操作。通过其ID我们可以得到很多东西。

    参考文章:http://blog.csdn.net/jiayanhui2877/article/details/7589756 MFC Edit控件操作

  2. 字节,字节,字节

    一定要控制好,昨天闲来没事,改了一个字节,把 unsigned short 改为 unsigned int .折腾好久才搞定。后来,竟然是我自己程序出错。我也是无语了。

  3. 写了一个简单的界面显示:

    左边是C++版本,真是丑。右边是C#版本。

    遇到的问题颇多,下面说说整体结构。

    程序在主线程,也就是 下面这个地方进行开辟2个新的线程进行数据处理:

    上面的代码涉及到 EDIT控件的设置问题,我们可以联想到android当中eidtview的设置问题,其实还是蛮像的。

    当我们在子线程中,想要获取到主线程的东西的话,比较麻烦,可以通过得到其上下文的方式来进行操作。

    如上图的代码就是这样一回事。

    当然,这里就涉及到数据通讯的问题。以及数据共享的问题。

    还有就是主线程一般是用户界面线程,它有消息循环队列,而我们创建的工作线程中没有这种工作机制。

    所以,一般我们想要更新主线程当中的控件的时候,我们一般通过消息队列去通知主线程,然后让主线程去绘制窗体。

    毕竟,我们执行程序的时候,所有的东西都是"被实例化的"

    继续接上面的开了两个线程之后,怎么办?

    线程1:

    虚拟总线初始化,等待用户输入,输入0K之后,我们进入到数据采集部分。

    还有就是m_run 是由主线程提供的。

    线程2:处理线程

    处理线程,专门处理子线程1当中采集到的数据,这里我们用了循环数组来进行线程间的通讯。采集完之后,我们直接显示即可。

    在用画笔绘制图形的过程中,我想强调一点,适当的sleep是必须的,因为绘制需要时间,不然上一个图形还没绘制完,新图形又过来了,

    这样会造成界面的卡顿十分严重。

    两个主要的程序代码:

    Dlg.h

    1. // DatasShowDlg.h : 头文件
    2. //
    3.  
    4. #pragma once
    5. #include "afxwin.h"
    6. #include "VirtualSwitchPlus.h"
    7.  
    8. DWORD WINAPI DealThread(LPVOID pParam);
    9. DWORD WINAPI ReceiverThread(LPVOID pParam);
    10.  
    11. extern char szbuffer[10][arrayBytes];
    12. extern int recvcount;
    13. extern bool m_run;
    14. extern CRect* pictureWH;
    15.  
    16. extern string msgLable;
    17. extern string busNum;
    18.  
    19. typedef struct Point //点转换为矩阵的x与y坐标。
    20. {
    21.    unsigned short x;
    22.    unsigned short y;
    23.    unsigned char value;
    24.    unsigned char U;
    25. } Point;
    26. typedef struct Matrix //稀疏矩阵数据结构
    27. {
    28.    int Num;
    29.    Point point[3000];
    30.  
    31. } Matrix;
    32.  
    33. static const int PointLength = 6; //一个point点的长度
    34. static const int startoffset = 4; //头字节的长度
    35. void DrawPoints(Matrix *marix,LPVOID pParam);
    36.  
    37. // CDatasShowDlg 对话框
    38. class CDatasShowDlg : public CDialogEx
    39. {
    40. // 构造
    41. public:
    42.    CDatasShowDlg(CWnd* pParent = NULL); // 标准构造函数
    43.  
    44. // 对话框数据
    45.    enum { IDD = IDD_DATASSHOW_DIALOG };
    46.  
    47.    protected:
    48.    virtual void DoDataExchange(CDataExchange* pDX); // DDX/DDV 支持
    49.  
    50.  
    51. // 实现
    52. protected:
    53.    HICON m_hIcon;
    54.  
    55.    // 生成的消息映射函数
    56.    virtual BOOL OnInitDialog();
    57.    afx_msg void OnPaint();
    58.    afx_msg HCURSOR OnQueryDragIcon();
    59.    DECLARE_MESSAGE_MAP()
    60. public:
    61.    CButton m_show;
    62.    CEdit m_msgLable;
    63.    CEdit m_busNum;
    64.  
    65.    afx_msg void OnBnClickedOk();
    66.  
    67.  
    68.    CString m_msgLabelNum;
    69.    CString m_busNumValue;
    70. };

    Dlg.cpp

    1. // DatasShowDlg.cpp : 实现文件
    2. //
    3.  
    4. #include "stdafx.h"
    5. #include "DatasShow.h"
    6. #include "DatasShowDlg.h"
    7. #include "afxdialogex.h"
    8.  
    9.  
    10. #ifdef _DEBUG
    11. #define new DEBUG_NEW
    12. #endif
    13.  
    14.  
    15. // CDatasShowDlg 对话框
    16. char szbuffer[10][arrayBytes];
    17. int recvcount;
    18. bool m_run;
    19. CRect* pictureWH = new CRect();
    20. string msgLable;
    21. string busNum;
    22.  
    23. CDatasShowDlg::CDatasShowDlg(CWnd* pParent /*=NULL*/)
    24.    : CDialogEx(CDatasShowDlg::IDD, pParent)
    25.    , m_msgLabelNum(_T(""))
    26.    , m_busNumValue(_T(""))
    27. {
    28.    m_hIcon = AfxGetApp()->LoadIcon(IDR_MAINFRAME);
    29. }
    30.  
    31. void CDatasShowDlg::DoDataExchange(CDataExchange* pDX)
    32. {
    33.    CDialogEx::DoDataExchange(pDX);
    34.    DDX_Control(pDX, IDOK, m_show);
    35.    DDX_Control(pDX, IDC_EDIT1, m_msgLable);
    36.    DDX_Control(pDX, IDC_EDIT2, m_busNum);
    37.    //DDX_Control(pDX, IDC_PICTURE, m_picture);
    38.    DDX_Text(pDX, IDC_EDIT1, m_msgLabelNum);
    39.    DDX_Text(pDX, IDC_EDIT2, m_busNumValue);
    40. }
    41.  
    42. BEGIN_MESSAGE_MAP(CDatasShowDlg, CDialogEx)
    43.    ON_WM_PAINT()
    44.    ON_WM_QUERYDRAGICON()
    45.    ON_BN_CLICKED(IDOK, &CDatasShowDlg::OnBnClickedOk)
    46. END_MESSAGE_MAP()
    47.  
    48.  
    49. // CDatasShowDlg 消息处理程序
    50.  
    51. BOOL CDatasShowDlg::OnInitDialog()
    52. {
    53.    CDialogEx::OnInitDialog();
    54.  
    55.    // 设置此对话框的图标。当应用程序主窗口不是对话框时,框架将自动
    56.    // 执行此操作
    57.    SetIcon(m_hIcon, TRUE); // 设置大图标
    58.    SetIcon(m_hIcon, FALSE); // 设置小图标
    59.  
    60.    // TODO: 在此添加额外的初始化代码
    61.    m_run = false;
    62.    recvcount = 0;
    63.    CRect rect;
    64.    /*m_picture.GetWindowRect(rect);*/
    65.  
    66.    /*pictureWH = ▭ 下面的参数没什么卵用*/
    67.    AfxBeginThread((AFX_THREADPROC)DealThread,(LPVOID)GetSafeHwnd(),THREAD_BASE_PRIORITY_IDLE);
    68.    AfxBeginThread((AFX_THREADPROC)ReceiverThread,NULL,THREAD_BASE_PRIORITY_IDLE);
    69.    //对edit控件赋值
    70.    /*char label[20] = {0};
    71.    char busnum[20] = {0};*/
    72.    SetDlgItemText(IDC_EDIT1,"Path_GPS");
    73.    SetDlgItemText(IDC_EDIT2,"");
    74.  
    75.    return TRUE; // 除非将焦点设置到控件,否则返回 TRUE
    76. }
    77.  
    78. // 如果向对话框添加最小化按钮,则需要下面的代码
    79. // 来绘制该图标。对于使用文档/视图模型的 MFC 应用程序,
    80. // 这将由框架自动完成。
    81.  
    82.  
    83. DWORD WINAPI DealThread(LPVOID pParam)
    84. {
    85.  
    86.    //CRect* rect = (CRect*)pParam;
    87.    while(1)
    88.    {
    89.       if (m_run)
    90.     {
    91.       unsigned char str1[arrayBytes] = {0}; //获取数据
    92.       //开辟两个无符号类型,这里是加了锁机制处理,string 默认并不是无符号类型
    93.  
    94.       for (int i = 0; i < arrayBytes; ++i)
    95.       {
    96.          str1[i] = szbuffer[(recvcount-1+10)%10][i];
    97.       }
    98.       Matrix *matrixH = new Matrix(); //记得释放
    99.       memset(matrixH,0,sizeof(Matrix));
    100.       matrixH->Num = str1[3]*16*16*16*16*16*16*16*16 + str1[2]*16*16*16*16 + str1[1]*16*16 + str1[0];
    101.       int obs1 = 0;
    102.       for (int i = 0; i < matrixH->Num; ++i)
    103.       {
    104.          matrixH->point[obs1].x = str1[startoffset + 1 + i*PointLength]*16*16 + str1[startoffset + 0 + i*PointLength];
    105.          matrixH->point[obs1].y = str1[startoffset + 3 + i*PointLength]*16*16 + str1[startoffset + 2 + i*PointLength];
    106.          matrixH->point[obs1].value = str1[startoffset + 4 + i*PointLength];
    107.          //matrixH->point[obs1].value = 50;
    108.          matrixH->point[obs1].U = str1[startoffset + 5 + i*PointLength];
    109.          obs1++; //注意清零
    110.       }
    111.       DrawPoints(matrixH,pParam);
    112.  
    113.  
    114.       delete matrixH;
    115.       }//end if
    116.       else
    117.       {
    118.          Sleep(1);
    119.       }
    120.    }
    121.  
    122.  
    123.    return 0;
    124. }
    125.  
    126. void DrawPoints(Matrix *marix,LPVOID pParam)
    127. {
    128.    //HWND hWnd = (HWND)pParam;
    129.    CRect rect;
    130.     AfxGetApp()->m_pMainWnd->GetWindowRect(rect);
    131.    int PicW = rect.Width();
    132.    int PicH = rect.Height() - 145;
    133.    //曲线轮廓显示
    134.    //以下是画在主线程中,我们需要画在picture控件中
    135.    CDC* pDC = AfxGetApp()->m_pMainWnd->GetDC(); //通过GetDc()获取的HDC直接与相关设备沟通, CDC* pDC = picture.GetDC();
    136.  
    137.    CDC memDC;
    138.    CBitmap bmp; //本函数创建的DC,则是与内存中的一个表,面相关联。
    139.    memDC.CreateCompatibleDC(pDC); //该函数创建一个与指定设备兼容的内存设备上下文环境(DC)。
    140.    bmp.CreateCompatibleBitmap( pDC, PicW, PicH); //该函数创建与指定的设备环境相关的设备兼容的位图
    141.    memDC.SelectObject(bmp); //该函数选择一对象到指定的设备上下文环境中,该新对象替换先前的相同类型的对象
    142.  
    143.    memDC.SelectStockObject(WHITE_BRUSH);//该语句把终端字体选入设备环境
    144.    memDC.SelectStockObject(WHITE_PEN);
    145.  
    146.    pDC->SelectStockObject(WHITE_BRUSH);
    147.    pDC->SelectStockObject(WHITE_PEN);
    148.  
    149.    int yGap = 10;
    150.    memDC.Ellipse( PicW/2-5, PicH-yGap-5, PicW/2+5, PicH-yGap+5); //小圆形,用来标识雷达
    151.  
    152.    int n = 0;
    153.    int m = 0;
    154.    for (int i = 0; i < marix->Num; ++i)
    155.    {
    156.       n = marix->point[i].x;
    157.       m = marix->point[i].y;
    158.       if ((n > 0 && n < 350) && (m > 0 && m < 100))
    159.       {
    160.          n = n * PicH / 400;
    161.          m = m * PicW / 100;
    162.          memDC.SetPixel(m, n,RGB(255,255,255));
    163.          //memDC.Ellipse( m-5, n-yGap-5, m+5, n-yGap+5); //小圆形,用来标识雷达
    164.       }
    165.    }
    166.  
    167.    pDC->StretchBlt(0,0,PicH,PicH,&memDC,0,0,PicH,PicH,SRCCOPY); //函数从源矩形中复制一个位图到目标矩形
    168.    bmp.DeleteObject(); //必要时按目标设备设置的模式进行图像的拉伸或压缩
    169.  
    170.    /*目标区域左上角点的x坐标
    171.     目标区域左上角点的y坐标
    172.    目标区域的宽度
    173.    目标区域的高度
    174.    源贴图区域DC的指针
    175.    源贴图区域x坐标
    176.    源贴图区域y坐标
    177.    像素直接拷贝模式*/
    178.    memDC.DeleteDC();
    179.    AfxGetApp()->m_pMainWnd->ReleaseDC(pDC);
    180.    Sleep(50);
    181. }
    182.  
    183. DWORD WINAPI ReceiverThread(LPVOID pParam)
    184. {
    185.    VirtualSwitchPlusRecv *vspR;
    186.    while(1) //等待用户输入
    187.     {
    188.       if (m_run)
    189.      {
    190.        int BUSNUM = busNum[0] - '0';
    191.         vspR = new VirtualSwitchPlusRecv(BUSNUM);
    192.        break;
    193.       }
    194.       else
    195.       {
    196.          Sleep(1);
    197.         }
    198.      }
    199.  
    200.  
    201.    while (true)
    202.    {
    203.        vspR->SubMsg(msgLable); //数据必须这样接收,每次判断一次
    204.       for (int i = 0; i < 3000; ++i)
    205.       {
    206.          szbuffer[recvcount][i] = vspR->szbuffer[i];
    207.       }
    208.       int nRet = vspR->nRet;
    209.  
    210.       if (nRet == SOCKET_ERROR)
    211.       {
    212.          cout << "Path_GPS not receive!" << endl;
    213.       }
    214.       if(nRet > 0) //主程序需要循环检测
    215.       {
    216.          cout << "flag0: "<<recvcount<<endl;
    217.          recvcount = (recvcount + 1) % 10;
    218.       }else{
    219.          recvcount = 0;
    220.       }
    221.    }
    222.    delete vspR;
    223. }
    224.  
    225. void CDatasShowDlg::OnPaint()
    226. {
    227.    if (IsIconic())
    228.    {
    229.       CPaintDC dc(this); // 用于绘制的设备上下文
    230.  
    231.       SendMessage(WM_ICONERASEBKGND, reinterpret_cast<WPARAM>(dc.GetSafeHdc()), 0);
    232.  
    233.       // 使图标在工作区矩形中居中
    234.       int cxIcon = GetSystemMetrics(SM_CXICON);
    235.       int cyIcon = GetSystemMetrics(SM_CYICON);
    236.       CRect rect;
    237.       GetClientRect(&rect);
    238.       int x = (rect.Width() - cxIcon + 1) / 2;
    239.       int y = (rect.Height() - cyIcon + 1) / 2;
    240.  
    241.       // 绘制图标
    242.       dc.DrawIcon(x, y, m_hIcon);
    243.    }
    244.    else
    245.    {
    246.       CDialogEx::OnPaint();
    247.    }
    248. }
    249.  
    250. //当用户拖动最小化窗口时系统调用此函数取得光标
    251. //显示。
    252. HCURSOR CDatasShowDlg::OnQueryDragIcon()
    253. {
    254.    return static_cast<HCURSOR>(m_hIcon);
    255. }
    256.  
    257.  
    258.  
    259. void CDatasShowDlg::OnBnClickedOk()
    260. {
    261.    // TODO: 在此添加控件通知处理程序代码
    262.    if (!m_run){
    263.       m_show.SetWindowText(_T("暂停"));
    264.       m_run = true;
    265.       char label[20] = {0};
    266.       char busnum[20] = {0};
    267.       GetDlgItemText(IDC_EDIT1,label,20);
    268.       GetDlgItemText(IDC_EDIT2,busnum,20);
    269.  
    270.       busNum = busnum[0];
    271.       for (int i = 0; i < 20; ++i)
    272.       {
    273.          if (label[i] != 0)
    274.          {
    275.             msgLable += label[i];
    276.          }
    277.       }
    278.    }else{
    279.       m_show.SetWindowText(_T("显示"));
    280.       m_run = false;
    281.    }
    282.  
    283. }
  4. MFC 的生存周期

    参考资料:

http://blog.csdn.net/lesky/article/details/2470907 MFC应用程序的初始化过程

构造全局对象CWinApp è 调用WINMain中的AfxGetAPP

得到全局对象的pApp,然后调用 initInstance,并在里面完成注册,显示窗体。然后执行消息循环。

关于Mfc的好的帖子,值得一看: http://blog.csdn.net/lesky/article/details/2471039 MFC要点概括

导航程序调试1---MFC应用以及数据显示程序的更多相关文章

  1. 【matlab】MATLAB程序调试方法和过程

    3.8  MATLAB程序的调试和优化 在MATLAB的程序调试过程中,不仅要求程序能够满足设计者的设计需求,而且还要求程序调试能够优化程序的性能,这样使得程序调试有时比程序设计更为复杂.MATLAB ...

  2. Linux Bash命令关于程序调试详解

    转载:http://os.51cto.com/art/201006/207230.htm 参考:<Linux shell 脚本攻略>Page22-23 Linux bash程序在程序员的使 ...

  3. 零基础学Python--------第9章 异常处理及程序调试

    第9章 异常处理及程序调试 9.1 异常概述 在程序运行过程中,经常会遇到各种各样的错误,这些错误统称为“异常”.这些异常有的是由于开发者将关键字敲错导致的,这类错误多数产生的是SyntaxError ...

  4. MFC单文档程序架构解析

    MFC单文档程序架构解析 MFC单文档程序架构解析 这里我以科院杨老师的单文档程序来分析一下MFC单文档的程序架构,纯属个人见解,不当之处烦请指教! 首先我们了解到的是 图(一) theApp 是唯一 ...

  5. 052 01 Android 零基础入门 01 Java基础语法 05 Java流程控制之循环结构 14 Eclipse下程序调试——debug2 多断点调试程序

    052 01 Android 零基础入门 01 Java基础语法 05 Java流程控制之循环结构 14 Eclipse下程序调试--debug2 多断点调试程序 本文知识点: Eclipse下程序调 ...

  6. VS2008/2005 MFC程序调试经验

    我的VS2008不知道是有bug还是自己的问题,很多时候变量定义后CTRL+F5运行却没反应,一定要“生成解决方案”下才行? 1.没有可用于当前位置的源代码 将工具->选项->调试-> ...

  7. [安卓][转]Android eclipse中程序调试

    一:断点调试 用eclipse开发android程序的时,跟VS一样是可以断点单步调试的.步骤如下.1 设置断点:在编码窗体的左边框上用鼠标双击,或者右键点击菜单,选择 Toggle Breakpoi ...

  8. VC++ MFC SDI/MDI Ribbon程序的停靠窗格被关闭后如何再次显示

    VC++ 创建基于MFC的SDI应用程序,Visual Studio风格的主界面如下图所示,在该主界面上的视图菜单下包含有队对各个可停靠窗格显示或隐藏的控制菜单项.而基于Ribbon风格的应用程序,所 ...

  9. 如何优雅的写UI——(1)MFC六大核心机制-程序初始化

    很多做软件开发的人都有一种对事情刨根问底的精神,例如我们一直在用的MFC,很方便,不用学太多原理性的知识就可以做出各种窗口程序,但喜欢钻研的朋友肯定想知道,到底微软帮我们做了些什么,让我们在它的框架下 ...

  10. 【系统篇】从int 3探索Windows应用程序调试原理

    探索调试器下断点的原理 在Windows上做开发的程序猿们都知道,x86架构处理器有一条特殊的指令——int 3,也就是机器码0xCC,用于调试所用,当程序执行到int 3的时候会中断到调试器,如果程 ...

随机推荐

  1. 【读书笔记】iOS-对象初始化

    一,分配对象. 分配是一个样的对象诞生的过程.最美好的时刻,是从操作系统获得一块内存并将其指定为存放对象的实例变量的位置.向某个类发送alloc消息的结果,就是为该类分配一块足够大的内存,以存放该内的 ...

  2. 【读书笔记】iOS-查看一个软件ipa包的内容

    一,打开itunes----->我的iPhone应用程序. 二,右键点击app---->在Finder中显示---->出现下图所示界面. 三,将上图中的ipa包拷贝到桌面,如下图所示 ...

  3. 关于 xib 的使用

    前两天写百度地图的时候要添加 一个标注的泡泡view  但有些复杂所以想用xib 拖拽出一个View ,拖拽出来之后发现添加不到Controller中 ,郁闷!! 终于找到了方法: //先获取NIb ...

  4. Cocos2d-X-3.0之后的版本的环境搭建

    由于cocos2d游戏开发引擎更新十分频繁,官方文档同步不够及时和完善.所以不要照着官方文档来照做生成工程. <点击图片就能进入网站> 具体的步骤: 1.获取cocos2d-X的源码v3. ...

  5. 每日Scrum--No.5

    Yesterday:学习并编写代码 Today:组织小组开一次阶段性的总结会议:讨论需求分析中存在的问题:继续学习和编写代码:总结前阶段代码出现的问题 Problem:编程要注意很多的特殊情况,程序成 ...

  6. Effective Java 61 Throw exceptions appropriate to the abstraction

    Exception translation: higher layers should catch lower-level exceptions and, in their place, throw ...

  7. postfix删除队列中的邮件

    Postfix中有一套Mail Queue Management机制,所有队列中的邮件都可以全自动的处理,但在发送大量邮件的时候,有必要对这个队列进行手工的维护处理,比如说,删除队列中的邮件. 以下是 ...

  8. Bootstrap(转)

    Bootstrap 随着互联网的不断成熟以及我们越来越多的用各种移动端的设备访问互联网,Web设计师和Web开发者的工作也变得越来越复杂. 十年前,一切都还简单得多.那个时候,大部分用户都是坐在桌子前 ...

  9. PHP验证码

    设计一个验证码类,在需要的时候可以随时调用 验证码类,保存为ValidateCode.class.php <?php //验证码类 session_start(); class Validate ...

  10. 华硕飞行堡垒zx50安装Ubunutu折腾记

    今年8月入手了华硕zx50,配置不错,作为一个合格的Linux爱好者,没买来一台电脑肯定得装上Linux编个程序什么的吧,,可恶的是,笔记本安装Linux系统往往比较麻烦,必须折腾很久才安装上,我手上 ...