通過編寫串口助手工具學習MFC過程——(二)通過“打開串口”按鈕了解基本操作


通過編寫串口助手工具學習MFC過程

因為以前也做過幾次MFC的編程,每次都是項目完成時,MFC基本操作清楚了,但是過好長時間不再接觸MFC的項目,再次做MFC的項目時,又要從頭開始熟悉。這次通過做一個串口助手再次熟悉一下MFC,並做了一下記錄,以便方便以后查閱。做的過程中多是遇到問題直接百度和谷歌搜索來的,所以很多都是不求甚解,知其然不知其所以然。另外做此工具只是為了熟悉了解,許多功能還沒有完善!(開發工具VS2008)

(二)通過“打開串口”按鈕了解基本操作

wps2419.tmp

需要什么控件直接從這個對話框編輯器直接添加即可。

1、添加一個按鈕用於打開串口

wps2458.tmp wps2459.tmp

2、設置按鈕控件的屬性

調出屬性對話框,設置ID

wps245A.tmp

wps246B.tmp

Caption是靜態選項,程序中可以動態設置按鈕顯示的文字,這里修改名字的好處是,方便編寫代碼是查看這個按鈕是什么。

設置這個控件的ID名稱,這樣MFC就會對這個名稱起一個對應的數字真正的ID,可以在工程中Resource.h 查看。

工程中,右鍵.rc文件->選擇”查看代碼”,下圖是部分截圖,就會看對按鈕的尺寸和位置和顯示內容、ID名字。

wps246C.tmp

3、添加按鈕變量

再將這個按鈕向對話框對應的類添加變量,在按鈕上右鍵->選擇添加變量->在變量名的文本框里填入變量名。如下圖:

wps246D.tmp

添加后工程的變化,在對話框的頭文件“serial testDlg.h : 頭文件”,CserialtestDlg類中增加對象成員變量(頭文件名和類名是建立工程時起的)

wps247D.tmp

“serial testDlg.cpp : 實現文件”中

wps247E.tmp

wps247F.tmp

像注釋說明的那樣,按鈕變量m_ComBoComContrl和控件IDC_BUTTON_OPENCOM關聯起來了,以后對此變量操作也就是對該按鈕控件進行操作。

另外一種操作按鈕的方法是CWnd* GetDlgItem(ID)函數,返回窗口中指定參數ID的子元素的句柄,可以通過返回的句柄對相應的控件操作。並且這個操作可以在任何地方使用,按鈕變量只能在對話框類中使用同,相應比獲取句柄方式有局限性,也不夠方便。(個人理解。)

CWnd* GetDlgItem(ID)的應用后面有涉及到。

4、添加按鈕控件響應事件

方法一:在對話框里,雙擊按鈕。

直接跳轉到“serial testDlg.cpp : 實現文件”自動生成如下函數

//串口打開關閉按鈕

void CserialtestDlg::OnBnClickedButtonOpencom()

{

}

大部分的控件通過雙擊都會生成相應的響應事件函數。

方法二:右擊控件按鈕->“添加事件處理函數”

wps2490.tmp

可以修改消息類型,不同的控件里的消息類型不同,此處選擇點擊消息,BN_CLICKED;

函數處理程序名稱設置好,類列表中可以選擇生成在哪個類中,按默認的生成,即在對話框類中生成。

在“serial testDlg.cpp : 實現文件”生成的 消息增加此消息,包括消息類型、控件ID、響應事件的函數指針。

wps2491.tmp

通過以上信息,如果不使用向導增加變量和消息事件,也可以自己添加。

//串口打開關閉按鈕

/*

這個函數主要實現功能是打開串口時,如果沒有創建串口,先創建串口,根據串口原來的狀態,實現串口打開或關閉。同時設置串口按鈕的文字內容“打開或關閉串口”,設置串口顯示的圖片。

將串口參數設置的幾個ComboBox組合框實現使能和失能的控制*/

void CserialtestDlg::OnBnClickedButtonOpencom()

{

// TODO: 在此添加控件通知處理程序代碼

//組織用於CComSerial類指針實例化時的數據,將對話框類的控件變量的地址獲取給CComSerial

//               類,CComSerial類從這些控件獲取相應數據,對串口參數進行設置

struct StruComCWnds stComCWnds;

stComCWnds.pComboBaudActual = this->pComboBaudActual;

stComCWnds.pComboSelSeri = &this->m_ComboSelSeri;

stComCWnds.pComboCheckBit = &this->m_ComboCheckBit;

stComCWnds.pComboDataBit = &this->m_ComboDataBit;

stComCWnds.pComboStopBit = &this->m_ComboStopBit;

if(NULL == pCComSer) //第一次點按鈕時pCComSer為Null

{

pCComSer = new CComSerial(&stComCWnds);

if(NULL == pCComSer)

{

return;

}

}

//判斷點擊前串口是什么狀態,原來連接狀態,現在關閉;原來關閉,現在打開

if(pCComSer->GetConStatus())

{

//原來連接,現在要關閉

pCComSer->CloseComm(); //串口關閉操作

((CButton *)GetDlgItem(IDC_BUTTON_OPENCOM))->SetBitmap(hBitmapComOFF);  //設置按鈕圖片

SetDlgItemText(IDC_BUTTON_OPENCOM, _T("打開串口")); //設置按鈕顯示文字內容

//串口參數設置的組合框使能,可以進行設置

m_ComboSelSeri.EnableWindow(TRUE);

m_ComboBaud.EnableWindow(TRUE);

m_ComboCheckBit.EnableWindow(TRUE);

m_ComboStopBit.EnableWindow(TRUE);

m_ComboDataBit.EnableWindow(TRUE);

m_ComboBaudEdit.EnableWindow(TRUE);

}

else

{

//原來未連接現在要連接

if(pCComSer->OpenComm()) //串口打開操作

{

//打開串口成功,設置按鈕圖片和顯示文字內容

((CButton *)GetDlgItem(IDC_BUTTON_OPENCOM))->SetBitmap(hBitmapComON);  

SetDlgItemText(IDC_BUTTON_OPENCOM, _T("關閉串口"));

//串口參數設置的組合框失能,打開串口后不可以再進行設置

m_ComboSelSeri.EnableWindow(FALSE);

m_ComboBaud.EnableWindow(FALSE);

m_ComboCheckBit.EnableWindow(FALSE);

m_ComboStopBit.EnableWindow(FALSE);

m_ComboDataBit.EnableWindow(FALSE);

m_ComboBaudEdit.EnableWindow(FALSE);

}

}

}

此處注意,在這里動態分配了內存,pCComSer = new CComSerial(&stComCWnds);

所以在銷毀對話框時也要釋放此內存,可在對話框類的析構函數里增加對動態內存分配的釋放。因為這個類是MFC自動生成的,在WINDOWS的銷毀工作里會自動調用系統自動生成類的析構函數,所以把釋放功能增加到這個函數里。

CserialtestDlg::~CserialtestDlg()

{

//pCComSer->CloseComm();

if(pCComSer != NULL)

{

delete pCComSer;

pCComSer = NULL;

}

}

因為C++還在學習過程中,對類的設置不好。函數中實現了幾個功能,下面介紹一下:

(1)控件的使能和失能

控件的EnableWindow(TRUE)和EnableWindow(FALSE)實現控件的使能和失能。函數執行效果。

wps24A1.tmp wps24A2.tmp

(2)按鈕顯示文字

SetDlgItemText(IDC_BUTTON_OPENCOM, _T("關閉串口"));

從函數和名字中可以看出SetDlgItemText();設置控件的文本顯示,第一個參數就是控件的ID號,第二個參數是文本信息。下面這幾行代碼也可以實現同樣的功能。

CString str ;

str.Format(_T("串口打開"));

SetDlgItemText(IDC_BUTTON_OPENCOM,str);

百度這個函數:Windows API宏,在WinUser.h中根據是否已定義Unicode被分別定義為SetWindowTextW和SetWindowTextA,這兩個函數改變指定窗口的標題欄的文本內容(如果窗口有標題欄)。如果指定窗口是一個控件,則改變控件的文本內容。特別需要引起重視的是,【SetWindowText函數不改變在其他應用程序中的控件的文本內容,如果需要可以用另外一個SendMessage函數發送一條WM_SETTEXT消息】

查看定義,都是三個定義的參數,沒有發現有兩個參數的重載,不知原因。

_T("關閉串口")作用將字符串轉為當前環境的字符寬度。如本工程設置的是Unicode寬字符。

和此功能類似的函數GetWindowText(),從函數名字可以看出此功能是獲取控件文本內容的。從文本編輯框edit控件中讀取數據就是用的這個方法。介紹文本編輯框時再詳細介紹。

CString str;

GetDlgItem(IDC_EDIT_DATASEND)->GetWindowText(str); //從發送框讀數據

(3)按鈕顯示圖片

往上查找說有三種方法,本例中用其中之一,

a、將圖片導入到資源管理器中,ID設置為IDB_BITMAP_COMON和IDB_BITMAP_COMOFF。

如何導入,右鍵工程->添加->資源->選擇”BITMAP”。注意BITMAP文件必須確實是轉換成此格式的,不能只改后綴名,那樣圖片格式不對是不能實現功能的。

b、在顯示圖片前加載圖片,下面兩行代碼。

//按鈕開關

hBitmapComON = LoadBitmap(AfxGetInstanceHandle(), MAKEINTRESOURCE(IDB_BITMAP_COMON)); // IDB_BITMAP_TEST為資源圖片ID

hBitmapComOFF = LoadBitmap(AfxGetInstanceHandle(), MAKEINTRESOURCE(IDB_BITMAP_COMOFF)); // IDB_BITMAP_TEST為資源圖

hBitmapComON變量和 hBitmapComOFF變量在CserialtestDlg中定義,如下圖所示。這兩個變量就是這兩個圖片的句柄。

wps24C3.tmp

c、然后獲得按鈕句柄並調用SetBitmap即可。

((CButton *)GetDlgItem(IDC_BUTTON_OPENCOM))->SetBitmap(hBitmapComON);

此處再次使用GetDlgItem()函數來獲取按鈕控件的句柄,相應的改成變量也能實現相同功能。

m_ComboComContrl.SetBitmap(hBitmapComON);

此句與上句功能相同,一個獲得控件句柄來操作,一個用控件變量來操作。

(4)按鈕Bitmap屬性對顯示圖片效果的影響

wps24C4.tmp wps24C5.tmp

wps24D5.tmp wps24D6.tmp

我的工程在unicode字符集下上面添加圖片的方法,可行,但是在使用多字節字符集就不行了。為此我選擇了使用Unicode字符集(寬字符)。

VC++6.0  默認是多字節字符集,VS2005以后默認是使用Unicode字符集。

使用unicode字符集編譯出的軟件 就像windows vista之后的軟件,使用多字節字符集編譯出的就像是XP時代的軟件,但看到有人用VS2013|的多字節字符集編譯的效果也是像vista之后的效果。

Unicode字符集和多字節字符集中的字符寬度不同,前者是寬字符,一個字符兩個字節,后者是一個字節。操作過程中需要多注意。

wps24D7.tmp


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM