通过编写串口助手工具学习MFC过程

因为以前也做过几次MFC的编程,每次都是项目完成时,MFC基本操作清楚了,但是过好长时间不再接触MFC的项目,再次做MFC的项目时,又要从头开始熟悉。这次通过做一个串口助手再次熟悉一下MFC,并做了一下记录,以便方便以后查阅。做的过程中多是遇到问题直接百度和谷歌搜索来的,所以很多都是不求甚解,知其然不知其所以然。另外做此工具只是为了熟悉了解,许多功能还没有完善!(开发工具VS2008)

(四)添加ComboBox组合框

ComboBox组合框有编辑框和下拉列表框的复合功能。通过该控件的Type属性可以进行相关设置。ComboBOX控件Type属性 :

Dropdown(默认)组合框,可下拉可编辑

Drop List 下拉列表框,只能下拉不能编辑

Drop Simple  编辑框,只能编辑不能下拉。

属性:数据可设置下拉列表显示的内容,数据间隔用英文的分号”;”。下拉列表显示的内容也可以在程序中设置,如果这个下拉列表的内容可能会编辑更改,这里就不要设置,直接在程序在添加就可。

上图中属性Sort也很重要,将他设置成False就不会根据下拉列表的内容自动排列了,下拉列表显示的顺序就是自己想要的定义成的那样。

添加控件、修改属性ID和增加变量部分略,参见按按钮部分。

1、ComboBox的基本功能:

//校验位 无;奇校验;偶校验;

char verifiBuf[][7]={"无","奇校验","偶校验"};

for(int i=0;i<3;i++)

{

m_ComboCheckBit.AddString(A2T(verifiBuf[i]));

}

m_ComboCheckBit.SetCurSel(0);

上面几行代码出现在初始对话框时,默认显示的。

m_ComboCheckBit.AddString(A2T(verifiBuf[i]));

在下拉列表增加字符串,不管原来是什么,直接增加到后面(Sort设置为False)。回值大于等于0时,是列表中项的下标。出错时,返回CB_ERROR,没有足够的空间存放新的字符串时返回CB_ERRSPACE。

A2T()将字符串转为宽字符WCHAR *。char verifiBuf[][7]定义成了二维数组来存储字符串,当然也可以定义成字符串数组来存储字符串。

m_ComboCheckBit.SetCurSel(0); 设置当前选项为第0项,如不设置,此组合框最初什么数值都没有。本函数在组合框的列表框中选择一个字符串,调用成功时返回选中的项的下标。如果nSelect大于列表中项的个数,则返回CB_ERR。如果nSelect为-1,则清除当前的选择并返回CB_ERR。

m_ComboCheckBit.GetCurSel();本函数用于取得组合框中当前选中的项的下标。返回组合框中列表框中当前选中的项的下标。如果没有选中项,则返回CB_ERR。

下面几行代码从组合框中获取字符串

//波特率

int baudIndex = pstComCWnds->pComboBaudActual->GetCurSel(); //波特率序号

pstComCWnds->pComboBaudActual->GetLBText(baudIndex,m_BaudStr); //从组合框的列表框中取得一个字符串(下标,获取字符串存入的cstring类)返回字符串长度

BaudRate = atoi(T2A((LPCTSTR)m_BaudStr)); //获得波特率

这个函数做为获得波特率在编辑自定义的波特率时要判断输入是否是数字,才能这么使用,否则不安全。

这个从组合框获取字符串的函数还有另一个重载。

int GetLBText( int nIndex, LPTSTR lpszText ) const;

返回字符串的字节数,不包括终结符null。如果nIndex指定的值无效,则返回CB_ERR。

(2)实现特殊功能:下拉列表自动调整宽度

串口名字是通过枚举获得的,名字较长,点下拉框时,名字不能完全显示。所以就让下拉框下拉时宽度变宽,从而能显示出完整的名字

当点击ComboBOX的三角使下拉列表展开时,下拉部分自动根据文字长度设置宽度,不改变原大小。

//ComboSelseri 选择串口组合框下拉动作响应将根据下拉选项最大的长度设定下拉框宽度

//控件添加 CbnDropdown 响应事件 下拉框下拉消息

void CserialtestDlg::OnCbnDropdownComboSelseri()

{

// TODO: 在此添加控件通知处理程序代码

int i = 0;

int originalLen = m_ComboSelSeri.GetDroppedWidth();  //获取原下拉框的宽度(像素)

int lenBuf = originalLen;

int lenTmp = 0;

//声明标识符

USES_CONVERSION; //使用A2T()或T2A()宽字节和多字节转换时使用的

//点开下拉框时,默认选择原来的那个串口

char m_SeriouStr[16] = {0};

CDeviceInfo * pCDeviceInfo = &m_DeviceInfo; //串口设备名字

int m_SeriouCurSel =  m_ComboSelSeri.GetCurSel();; //串口选择按钮,当前选择的序号

memcpy(m_SeriouStr, pCDeviceInfo->stDeviceInfo[m_SeriouCurSel].sDeviceName, sizeof(m_SeriouStr));//串口名字

m_ComboSelSeri.ResetContent(); //下拉列表清除列表项

for(i = 0; i<m_ComboSelSeri.GetCount();i++) //获取下拉列表项数

{

//获取下拉列表每项显示文字的字节数 并转为像素宽度。因为设置下拉列表的宽度单位是像素。此转换方式是用笨法测试出来的。

lenTmp = (m_ComboSelSeri.GetLBTextLen(i)+1)*CHAR_PIXEL_NUM;

if(lenTmp > lenBuf)

{

lenBuf = lenTmp;

}

}

if(lenBuf > originalLen)

m_ComboSelSeri.SetDroppedWidth(lenBuf);    //设置下拉列表的宽度(像素)

}

#define CHAR_PIXEL_NUM 6 //每个字符多少像素 人为根据现象设定

相关函数说明:

CComboBox::GetDroppedWidth
int GetDroppedWidth( ) const;
返回值:
调用成功时,返回允许的最小宽度,否则返回CB_ERR。
说明:
本函数用于取得组合框中的列表框所允许的最小宽度(以像素为单位)。它只对风格为CBS_DROPDOWN或CBS_DROPDOWNLIST的组合框有效。

CComboBox::SetDroppedWidth
int SetDroppedWidth( UINT nWidrh );
返回值:
调用成功时,返回列表框的新宽度。否则返回CB_ERR。
参数:nWidth 组合框的列表框所允许的最小宽度(以像素为单位)。

说明:
本函数用于设置组合框中列表框所允许的最小宽度。只对风格为CBS_DROPD-OWN或CBS_DROPDOWNLIST的组合框有效。

显示效果如下:

(3)实现特殊功能:只能下拉和只能编辑切换属性

组合框只能下拉或只能做编辑功能好办,只需要修改控件的type属性为Drop List 或Drop Simple就能实现。但如果需要在程序运行过程中动态切换这两种属性如何做呢?

方法一:通过一个复选框实现切换功能

//复选框单击事件

void CserialtestDlg::OnBnClickedCheck1()

{

// TODO: 在此添加控件通知处理程序代码

long param ;

if(check1.GetCheck()) //获取复选框1(check1.)是否选中

{

//如果复选框1(check1.)被选中

check2.EnableWindow(FALSE); //另一个实验中  复选框禁止

//修改属性,CBS_DROPDOWN 原属性,CBS_DROPDOWNLIST新的属性

if(TRUE == m_comboBox1.ModifyStyle(CBS_DROPDOWN,CBS_DROPDOWNLIST))

{

printf("1111\n");

}

else

{

printf("2222\n");

}

//m_comboBox1.DestroyWindow();

RecreateComboBox(&m_comboBox1,&param); //修改属性实现,执行此功能才能修改控件属性。

}//m_LcConfig是你的ListCtrl控件变量

else

{

check2.EnableWindow(TRUE);

if(TRUE == m_comboBox1.ModifyStyle(CBS_DROPDOWNLIST,CBS_DROPDOWN))

{

printf("1111\n");

}

else

{

printf("2222\n");

}

//m_comboBox1.DestroyWindow();

RecreateComboBox(&m_comboBox1,&param);

}

}

复选框的功能将在下一节介绍,此函数中有printf()调试时打印语句,在VC的控制台程序中会打印输出,但MFC中默认不会打印输出,以后会介绍如何在MFC中添另控制台用于打印输出。

//RecreateComboBox函数引自://(http://www.codeproject.com/KB/combobox/recreatecombobox.aspx

// recreate the combo box by copying styles etc, and list items

// and applying them to a newly created control

BOOL RecreateComboBox(CComboBox* pCombo, LPVOID lpParam/*=0*/)

{

if (pCombo == NULL)

return FALSE;

if (pCombo->GetSafeHwnd() == NULL)

return FALSE;

CWnd* pParent = pCombo->GetParent();

if (pParent == NULL)

return FALSE;

// get current attributes

DWORD dwStyle = pCombo->GetStyle();

DWORD dwStyleEx = pCombo->GetExStyle();

CRect rc;

pCombo->GetDroppedControlRect(&rc);

pParent->ScreenToClient(&rc); // map to client co-ords

UINT nID = pCombo->GetDlgCtrlID();

CFont* pFont = pCombo->GetFont();

CWnd* pWndAfter = pCombo->GetNextWindow(GW_HWNDPREV);

// get the currently selected text (and whether it is a valid list selection)

CString sCurText;

int nCurSel = pCombo->GetCurSel();

BOOL bItemSelValid = nCurSel != -1;

if (bItemSelValid)

pCombo->GetLBText(nCurSel, sCurText);

else

pCombo->GetWindowText(sCurText);

// copy the combo box items into a temp combobox (not sorted)

// along with each item's data

CComboBox comboNew;

if (! comboNew.CreateEx(dwStyleEx, _T("COMBOBOX"), _T(""),

dwStyle, rc, pParent, nID, lpParam))

return FALSE;

comboNew.SetFont(pFont);

int nNumItems = pCombo->GetCount();

for (int n = 0; n < nNumItems; n++)

{

CString sText;

pCombo->GetLBText(n, sText);

int nNewIndex = comboNew.AddString(sText);

comboNew.SetItemData(nNewIndex, pCombo->GetItemData(n));

}

// re-set selected text

if (bItemSelValid)

comboNew.SetCurSel(comboNew.FindStringExact(-1, sCurText));

else

comboNew.SetWindowText(sCurText);

// destroy the existing window, then attach the new one

pCombo->DestroyWindow();

HWND hwnd = comboNew.Detach();

pCombo->Attach(hwnd);

// position correctly in z-order

pCombo->SetWindowPos(pWndAfter == NULL ?

&CWnd::wndBottom :

pWndAfter, 0, 0, 0, 0, SWP_NOMOVE | SWP_NOSIZE);

return TRUE;

}

方法二:通过两个组合列表框交替使用来实现

本例中使用了下面的方法,此方法是自己原创(也许不是,只是自己按方法一实现后想到的另一种实现方法而已)

通过两个组合列表框交替使用来实现, 并将使用的赋给程序正常用时的指针变量。pComboBaudActual为程序中使用的指针变量,他保存两个组合列表框中的正在使用的那个地址。

并将正在使用的组合列表框显示,将不在使用的隐藏(这两个组合框位置上重合,程序执行起来就像是同一个组合框一样)。

把当前组合框选中的项,设定为新组合框的选项。通过pComboBaudActual指针实现。

//两个组合框添加  CBN_SELCHANGE事件响应, 控件中的选定内容已更改事件。

//ComboBaud 波特率组合框选中切换某一项动作

void CserialtestDlg::OnCbnSelchangeComboBaud()

{

// TODO: 在此添加控件通知处理程序代码

int i =0;

if((i = pComboBaudActual->GetCurSel()) == 0) //当列表框选择第0项时

{

//切换组合框

pComboBaudActual ->ShowWindow(SW_HIDE);  //原来使用的隐藏

pComboBaudActual = &m_ComboBaudEdit; //将另一个要使用赋值

pComboBaudActual ->SetCurSel(i); //并将选择项赋给新列表

pComboBaudActual->ShowWindow(SW_SHOW); //将新列表框显示

}

}

//ComboBaudedit 波特率组合框选中切换某一项动作

//这是另一个组合框选择程序,功能与上个函数相同

void CserialtestDlg::OnCbnSelchangeComboBaudedit()

{

// TODO: 在此添加控件通知处理程序代码

int i =0 ;

if((i = pComboBaudActual->GetCurSel()) != 0)

{

//切换组合框

pComboBaudActual ->ShowWindow(SW_HIDE);

pComboBaudActual = &m_ComboBaud;

pComboBaudActual ->SetCurSel(i);

pComboBaudActual->ShowWindow(SW_SHOW);

}

}

pComboBaudActual->ShowWindow(SW_SHOW); //将列表框显示

pComboBaudActual ->ShowWindow(SW_HIDE); //将列表框隐藏

通过编写串口助手工具学习MFC过程——(四)添加ComboBox组合框的更多相关文章

  1. 通过编写串口助手工具学习MFC过程--(十一)弹出模态型对话框

    通过编写串口助手工具学习MFC过程 因为以前也做过几次MFC的编程,每次都是项目完成时,MFC基本操作清楚了,但是过好长时间不再接触MFC的项目,再次做MFC的项目时,又要从头开始熟悉.这次通过做一个 ...

  2. 通过编写串口助手工具学习MFC过程——(十)UpdateData()用法和编辑框的赋值、取值

    通过编写串口助手工具学习MFC过程 因为以前也做过几次MFC的编程,每次都是项目完成时,MFC基本操作清楚了,但是过好长时间不再接触MFC的项目,再次做MFC的项目时,又要从头开始熟悉.这次通过做一个 ...

  3. 通过编写串口助手工具学习MFC过程——(九)自动识别串口的方法

    通过编写串口助手工具学习MFC过程 因为以前也做过几次MFC的编程,每次都是项目完成时,MFC基本操作清楚了,但是过好长时间不再接触MFC的项目,再次做MFC的项目时,又要从头开始熟悉.这次通过做一个 ...

  4. 通过编写串口助手工具学习MFC过程——(八)遇到的一些问题

    通过编写串口助手工具学习MFC过程 因为以前也做过几次MFC的编程,每次都是项目完成时,MFC基本操作清楚了,但是过好长时间不再接触MFC的项目,再次做MFC的项目时,又要从头开始熟悉.这次通过做一个 ...

  5. 通过编写串口助手工具学习MFC过程——(六)添加Edit编辑框控件

    通过编写串口助手工具学习MFC过程 因为以前也做过几次MFC的编程,每次都是项目完成时,MFC基本操作清楚了,但是过好长时间不再接触MFC的项目,再次做MFC的项目时,又要从头开始熟悉.这次通过做一个 ...

  6. 通过编写串口助手工具学习MFC过程——(七)添加Tab Control控件

    通过编写串口助手工具学习MFC过程 因为以前也做过几次MFC的编程,每次都是项目完成时,MFC基本操作清楚了,但是过好长时间不再接触MFC的项目,再次做MFC的项目时,又要从头开始熟悉.这次通过做一个 ...

  7. 通过编写串口助手工具学习MFC过程——(五)添加CheckBox复选框

    通过编写串口助手工具学习MFC过程 因为以前也做过几次MFC的编程,每次都是项目完成时,MFC基本操作清楚了,但是过好长时间不再接触MFC的项目,再次做MFC的项目时,又要从头开始熟悉.这次通过做一个 ...

  8. 通过编写串口助手工具学习MFC过程——(三)Unicode字符集的宽字符和多字节字符转换

    通过编写串口助手工具学习MFC过程 因为以前也做过几次MFC的编程,每次都是项目完成时,MFC基本操作清楚了,但是过好长时间不再接触MFC的项目,再次做MFC的项目时,又要从头开始熟悉.这次通过做一个 ...

  9. 通过编写串口助手工具学习MFC过程——(二)通过“打开串口”按钮了解基本操作

    通过编写串口助手工具学习MFC过程 因为以前也做过几次MFC的编程,每次都是项目完成时,MFC基本操作清楚了,但是过好长时间不再接触MFC的项目,再次做MFC的项目时,又要从头开始熟悉.这次通过做一个 ...

随机推荐

  1. Python3学习笔记(六):字符串

    一.基本字符串操作 所有标准的序列操作(索引.分片.乘法.判断成员资格.求长度.取最小值和最大值)对字符串同样适用.但是字符串是不可改变的. 二.字符串格式化 字符串格式化使用字符串格式化操作符(%) ...

  2. vue 在移动端实现红包雨 (兼容性好)

    下面是代码:<template>    <div class="ser_home">        <ul class="red_packe ...

  3. Java并发编程的艺术笔记(二)——wait/notify机制

    一.概述 一个线程修改了一个对象的值,另一个线程感知到变化从而做出相应的操作.前者是生产者,后者是消费者. 等待/通知机制,是指一个线程A调用了对象O的wait()方法进入等待状态,而另一个线程B调用 ...

  4. [LeetCode]-DataBase-Customers Who Never Order

    Suppose that a website contains two tables, the Customers table and the Orders table. Write a SQL qu ...

  5. spring cloud:gateway-eureka-filter

    Spring Cloud Gateway 的 Filter 的生命周期不像 Zuul 的那么丰富,它只有两个:“pre” 和 “post”. PRE: 这种过滤器在请求被路由之前调用.我们可利用这种过 ...

  6. JavaScript DOM位置尺寸API

    我们需要了解几个基础概念,每个HTML元素都有下列属性 offsetWidth clientWidth scrollWidth offsetHeight clientHeight scrollHeig ...

  7. Tomcat部署时war和war exploded区别以及平时踩得坑

    war和war exploded的区别 在使用IDEA开发项目的时候,部署Tomcat的时候通常会出现下边的情况: 是选择war还是war exploded 这里首先看一下他们两个的区别: war模式 ...

  8. 好书推荐:OpenSuse

    现在正值暑期,有大把的空闲时间,觉得有必要好好琢磨琢磨,进一步学习认识网站相关的东东. 之前,出于某种考虑,购买了一年的搬瓦工虚拟主机(vps),每月有500G的流量.单纯使用Shadowsocks, ...

  9. 基于球分割的空间二叉树检索算法(sphere-kdtree)

    sphere-kdtree算法思路说明 具体思路如下: 第一.球半径分割,即利用不同的球半径,将三维空间点(向量)分割成多块.所以首先要求确定的就是分割多少块,怎么设置半径最合理. 第二.三维空间点平 ...

  10. mysql执行拉链表操作

    拉链表需求: 1.数据量比较大 2.变化的比例和频率比较小,例如客户的住址信息,联系方式等,比如有1千万的用户数据,每天全量存储会存储很多不变的信息,对存储也是浪费,因此可以使用拉链表的算法来节省存储 ...