設置靜態文本框控件的背景色,文本框中字體、顏色:數組
HBRUSH CUDPDlg::OnCtlColor(CDC* pDC, CWnd* pWnd, UINT nCtlColor) { HBRUSH hbr = CDialog::OnCtlColor(pDC, pWnd, nCtlColor); // TODO: Change any attributes of the DC here if (pWnd->GetDlgCtrlID()==IDC_STATIC_TITLE) { //設置繪圖dc的背景模式爲透明模式. pDC->SetBkMode(TRANSPARENT);//設置透明窗口, pDC->SetTextColor(RGB(255,255, 0));//設置背景顏色爲(藍色) //pWnd->SetFont(cFont);//設置字體 HBRUSH B = CreateSolidBrush(RGB(125,125,255)); return (HBRUSH) B;//做爲約定,返回背景色對應的刷子句柄 //return (HBRUSH)::GetStockObject(RGB(125,125,255)); // 設置背景色 GetDlgItem(IDC_STATIC_TITLE)->GetParent()->RedrawWindow();//不重疊 } if (pWnd->GetDlgCtrlID()==IDC_RECV_LEN1) { //設置繪圖dc的背景模式爲透明模式. pDC->SetTextColor(RGB(255,0, 0));//設置文本顏色爲(紅色) //pWnd->SetFont(cFont);//設置字體 HBRUSH B = CreateSolidBrush(RGB(255,255,255)); return (HBRUSH) B;//做爲約定,返回背景色對應的刷子句柄 GetDlgItem(IDC_RECV_LEN1)->GetParent()->RedrawWindow();//不重疊 } // TODO: Return a different brush if the default is not desired return hbr; }
設置文本框內文本的字體:緩存
void CUDPDlg::SetEditFont() { CFont font; LOGFONT lf; memset(&lf,0,sizeof(LOGFONT)); lf.lfHeight=-14; //字體大小 font.CreateFontIndirect(&lf); GetDlgItem(IDC_RECV_LEN1)->SetFont (&cfont);
}
主對話框的源文件中:服務器
CFont cfont; //這個是全局的。放到include的下面就能夠了 int size=16; unsigned char iPbuf[2];//2個字節用於存放ip最後一段的值 CString strDataWrong="故障";//故障顯示 #define BUFFER_LEN 512//接收緩存大小 #define RIGHT_LEN 6//下發的數據長度 unsigned char rightdata[RIGHT_LEN];//無符號字符緩存 unsigned int port;//端口號 CHAR recBuf[BUFFER_LEN];//接收緩存
數據的一些 初始化:網絡
// CUDPDlg dialog CUDPDlg::CUDPDlg(CWnd* pParent /*=NULL*/) : CDialog(CUDPDlg::IDD, pParent) { //{{AFX_DATA_INIT(CUDPDlg) m_localPortNum =12345;//本地端口號 m_peerPortNum = 1234;//遠端端口號 m_disp1 = _T(""); m_disp2 = _T(""); m_s_1 = _T(""); m_dataToSend = _T(""); //}}AFX_DATA_INIT // Note that LoadIcon does not require a subsequent DestroyIcon in Win32 m_hIcon = AfxGetApp()->LoadIcon(IDR_MAINFRAME); //初始化socket對象爲無效 m_pSocket = NULL; //socket鏈接狀態,未鏈接 m_bIsConnected = FALSE; }
對話框的初始大小設定:less
void CUDPDlg::DoDataExchange(CDataExchange* pDX) { CDialog::DoDataExchange(pDX); SetWindowPos(NULL,0,0,900,680,SWP_NOMOVE | SWP_NOZORDER);
初始化函數:socket
//加載通訊狀態圖標 m_hIconOff = AfxGetApp()->LoadIcon(IDI_ICON_OFF); m_hIconOn = AfxGetApp()->LoadIcon(IDI_ICON_ON); //設置下發到的ip地址,目的ip m_peerIPaddr.SetAddress(1,1,1,1); //m_localIPaddr.SetAddress(127,0,0,1);//本地ip //獲取本地ip並顯示ip到界面 GetDispIP(); //設置要發送的數據,添加ip兩個字節,變量 // m_Edit2.SetWindowText("F5A0A10506075F"); //設置界面顯示的字體,藍色背景 cfont.CreateFont(16,0,0,0,FW_SEMIBOLD,FALSE,FALSE,0, ANSI_CHARSET,OUT_DEFAULT_PRECIS, CLIP_DEFAULT_PRECIS,DEFAULT_QUALITY, DEFAULT_PITCH&FF_SWISS,"Arial"); //獲取靜態文本框的指針變量 CWnd* pWnd = GetDlgItem(IDC_STATIC_TITLE); //設置字體 pWnd->SetFont(&cfont); //設置40個文本框顯示的字體 SetEditFont(); return TRUE; // return TRUE unless you set the focus to a control }
//獲取本地ip並顯示ip到界面 GetDispIP();
int CUDPDlg::GetDispIP() { int nRetCode; CString m_sHostName,m_sIPAddress; //1 nRetCode = StartUp(); TRACE1("StartUp RetCode: %d\n", nRetCode); //2獲取主機名 nRetCode = GetLocalHostName(m_sHostName); TRACE1("GetLocalHostName RetCode: %d\n", nRetCode); //3根據主機名獲取ip賦值到m_sIPAddress nRetCode = GetIPAddress(m_sHostName, m_sIPAddress); //顯示本地地址m_sIPAddress m_localIPaddr.SetWindowText(m_sIPAddress); TRACE1("GetIPAddress RetCode: %d\n", nRetCode); //4 nRetCode = CleanUp(); TRACE1("CleanUp RetCode: %d\n", nRetCode); UpdateData(FALSE); return 0; }
上面程序中獲取本地ip用到的函數:ide
int CUDPDlg::StartUp() { WORD wVersionRequested; WSADATA wsaData; int err; wVersionRequested = MAKEWORD( 2, 0 ); err = WSAStartup( wVersionRequested, &wsaData ); if ( err != 0 ) { // Couldn't find a usable WinSock DLL. */ return err; } // Confirm that the WinSock DLL supports 2.0. // Note that if the DLL supports versions greater // than 2.0 in addition to 2.0, it will still return // 2.0 in wVersion since that is the version we // requested. if ( LOBYTE( wsaData.wVersion ) != 2 || HIBYTE( wsaData.wVersion ) != 0 ) { // Couldn't find a usable WinSock DLL. WSACleanup( ); return WSAVERNOTSUPPORTED; } // The WinSock DLL is acceptable return 0; } int CUDPDlg::CleanUp() { int nRetCode; nRetCode = WSACleanup(); if (nRetCode != 0) { // An error occured. return WSAGetLastError(); } return 0; } int CUDPDlg::GetLocalHostName(CString &sHostName) { char szHostName[256]; int nRetCode; nRetCode = gethostname(szHostName, sizeof(szHostName)); if (nRetCode != 0) { // An error has occurred sHostName = _T("Not available");; return WSAGetLastError(); } sHostName = szHostName; return 0; } int CUDPDlg::GetIPAddress(const CString &sHostName, CString &sIPAddress) { struct hostent FAR *lpHostEnt = gethostbyname (sHostName); if (lpHostEnt == NULL) { // An error occurred. sIPAddress = _T(""); return WSAGetLastError(); } LPSTR lpAddr = lpHostEnt->h_addr_list[0]; if (lpAddr) { struct in_addr inAddr; // iPbuf[0]=127; // iPbuf[0] = inAddr.S_un.S_un_b.s_b4; memmove (&inAddr, lpAddr, 4); short iPsend=(short)(inAddr.S_un.S_un_b.s_b4); ShortToBytes(SendAone,iPsend); //short變成2字節 iPbuf[0] =SendAone[0]; iPbuf[1] =SendAone[1]; //ciPbuf[0] =SendAone[0];har sendip; //sendip=inAddr.s_b4;//LPSTR是一個字符串指針類型 sIPAddress = inet_ntoa (inAddr); if (sIPAddress.IsEmpty()) sIPAddress = _T("Not available"); } return 0; }
定時器函數:函數
void CUDPDlg::OnTimer(UINT nIDEvent) { // TODO: Add your message handler code here and/or call default switch(nIDEvent) { case 1: { //判斷變量,若是變爲1,則 鏈接成功,爲0,則鏈接失敗,彈出提示。 // if (1) // { // AfxMessageBox("鏈接失敗,請從新檢查!"); // KillTimer(1); // } break; } case 2: { //AfxMessageBox("定時器2!"); //數據包發送 OnBtnSendData(); break; } default: break; } CDialog::OnTimer(nIDEvent); }
創建網絡鏈接按鈕:字體
void CUDPDlg::OnBtnCtrlConn() { // TODO: Add your control notification handler code here //若是(有m_pSocket對象存在) if (NULL != m_pSocket) { //關閉socket連接 m_pSocket->Close(); //刪除socket對象 delete m_pSocket; //清零處理 m_pSocket = NULL; } //若是沒連接,則連接 if (!m_bIsConnected) { //置位連接標誌 m_bIsConnected = TRUE; // UpdateData(TRUE); // BYTE field[4]; //目的地址 m_peerIPaddr.GetAddress(field[0], field[1], field[2], field[3]); //目的地址 m_strPeerIPaddr.Format(TEXT("%d.%d.%d.%d"), field[0], field[1], field[2], field[3]); //服務器的功能:監聽本地port //建立socket對象 m_pSocket = new CUdpSocket(this);//接收顯示數據 //建立socket連接 m_pSocket->Create(m_localPortNum, SOCK_DGRAM);//本地端口號,udp //鏈接目的ip,port: //也能夠不綁定socket鏈接,只須要在接收數據的時候解析 源ip和port就能夠了。 //綁定socket連接() m_pSocket->Bind(m_peerPortNum, m_strPeerIPaddr);//端口,ip //按鈕文本 GetDlgItem(IDC_BTNCTRLCONN)->SetWindowText(TEXT("斷開鏈接")); //定時發送 SetTimer(2,3000,NULL); } else//若是鏈接,則斷開鏈接 { KillTimer(2); //復位連接標誌 countOne=0; m_bIsConnected = FALSE; //按鈕文本 GetDlgItem(IDC_BTNCTRLCONN)->SetWindowText(TEXT("創建鏈接")); } //本地端口號 GetDlgItem(IDC_LOCALPORTNUM)->EnableWindow(!m_bIsConnected); //本地ip GetDlgItem(IDC_LOCALIPADDR)->EnableWindow(!m_bIsConnected); //目的端口號 GetDlgItem(IDC_PEERPORTNUM)->EnableWindow(!m_bIsConnected); //目的ip GetDlgItem(IDC_PEERIPADDR)->EnableWindow(!m_bIsConnected); //發送按鈕 GetDlgItem(IDC_BTNSENDDATA)->EnableWindow(m_bIsConnected); //發送文本框 GetDlgItem(IDC_DATATOSEND)->EnableWindow(m_bIsConnected); }
發送數據按鈕:ui
void CUDPDlg::OnBtnSendData() { // TODO: Add your control notification handler code here UpdateData(TRUE); //判斷是否有CUdpSocket對象,是否連接 if (NULL == m_pSocket || !m_bIsConnected) { AfxMessageBox(TEXT("還沒有打開端口!")); return; } //要發送的數據 char m_Array[6]; m_Array[0]= (char)0xF5; m_Array[1]= (char)0xA0; // sockaddr_in m_clientAddr // m_Array[3]= m_clientAddr.sin_addr.S_un.S_un_b.s_b4; m_Array[2]= iPbuf[0];//高字節 m_Array[3]= iPbuf[1];//低字節 //校驗 char result=0; for(int i=1; i<4; i++) { result=result^m_Array[i]; } m_Array[4]=result; m_Array[5]=(char)0x5F; //幀尾 //CString m_send1="F5 A0 A1 01 01 5F 5F"; //經過socket發送到網絡 //要發送的數據,數據長度,目的端口號,目的ip // m_pSocket->SendTo(COleVariant(m_Array), 7, //m_dataToSend.GetLength() // m_peerPortNum, m_strPeerIPaddr); m_pSocket->SendTo(m_Array, 6, //m_dataToSend.GetLength() m_peerPortNum, m_strPeerIPaddr); //能夠取本地ip的最後一個整數值,變成2個字節,發送出去。 }
void CUDPDlg::OnReceive(CUdpSocket *psock) { int len = sizeof(SOCKADDR_IN); // 接收區,slen是緩衝區寫到的位置 int r_d_len=6; //清空接收緩存 ZeroMemory(recBuf, sizeof(recBuf)); CString SAddress;//接收數據來源的ip地址,port,BUFFER_LEN緩存長度,RcvBuffer接收的緩存m_localPortNum //接收數據 recBytes=psock->ReceiveFrom(recBuf,BUFFER_LEN,SAddress,m_peerPortNum,0); //recBytes =psock->ReceiveFrom(recBuf, BUFFER_LEN, (SOCKADDR*)&m_clientAddr, &len, 0); if (0 == recBytes) { AfxMessageBox(TEXT("UDP鏈接已經關閉!")); } else if (SOCKET_ERROR == recBytes) { AfxMessageBox(TEXT("接收數據失敗!")); } else if (recBytes>=83) { // for (int i=0;i<recBytes;i++) // { // rightdata[i]=recBuf[i]; // } //將recBuf中的數據寫入緩存 //校驗 char result=0; for(int j=1; j<82; j++) { result=result^recBuf[j]; } //檢測幀頭是否正確 //if (rightdata[0]==(char)0xF5 && rightdata[1]==(char)0xA1 && rightdata[4]==result ) if (recBuf[0]==(char)0xF5 && recBuf[1]==(char)0xA1 && recBuf[82]==result && recBuf[83]==(char)0x5F) { //解析數據 DataProcessing(); } } //清空接收緩存 for (int i=0; i<BUFFER_LEN; i++ ) { recBuf[i]=0; } }
數據解析部分:
void CUDPDlg::DataProcessing() { if (recBuf[2]==(char)0xff && recBuf[3]==(char)0xff ) { //顯示故障 m_ctrOnOFF_1.SetIcon(m_hIconOff);//接收圖標 SetDlgItemText(IDC_DISP_1,strDataWrong);//故障 wrong1++;//故障數 strTemp.Format("%d",wrong1); SetDlgItemText(IDC_S_1,strTemp);//顯示故障數 return; } else//數據正確 { BYTE Hdata = *(char *)(recBuf+2); BYTE Ldata = *(char *)(recBuf+3); strTemp.Format("%d",wrong1); //無端障 SetDlgItemText(IDC_S_1,strTemp); //鏈接關閉圖標 m_ctrOnOFF_1.SetIcon(m_hIconOn); //解析地址1的數據 int IpData=Hdata*256+Ldata; //直接顯示到文本框 CString strData; strData.Format("%d",IpData); //刷新實時數據顯示 SetDlgItemText(IDC_DISP_1,strData); //CString strTemp; //RcvBuffer接收緩存中保存接收到的數據。 //將接收到的數據以文本格式顯示。 //%02x 中間放一個空格 //strTemp.Format("%02x %02x %02x %02x %02x %02x",rightdata[0],rightdata[1],rightdata[2],rightdata[3],rightdata[4],rightdata[5]); // void MakeUpper( ); //使全部小寫字母變爲大寫 //strTemp.MakeUpper(); //將文本顯示到文本框 //SetDlgItemText(IDC_DISP_1,strTemp); //顯示計數countOne CString strlen; countOne++;//接收計數 strlen.Format(TEXT("%d"),countOne); ((CUDPDlg*)(AfxGetApp()->m_pMainWnd))->GetDlgItem(IDC_RECV_LEN1)->SetWindowText(strlen);//顯示計數 //顯示接收到的字節數 //CString strlen; //strlen.Format(TEXT("%d"),recBytes); //((CUDPDlg*)(AfxGetApp()->m_pMainWnd))->GetDlgItem(IDC_RECV_LEN1)->SetWindowText(strlen); } }
2個字節的短整形分解爲兩個字節
//2個字節的短整形分解爲兩個字節 void CUDPDlg::ShortToBytes(BYTE bytes[], SHORT num) { for(int i = 0; i < 2; i++) { bytes[i] = (BYTE)(num >> (8 - i * 8)); } }
清空顯示:
void CUDPDlg::OnClear() { // TODO: Add your control notification handler code here countOne=0; CString strlen; strlen.Format(TEXT("%d"),countOne); ((CUDPDlg*)(AfxGetApp()->m_pMainWnd))->GetDlgItem(IDC_RECV_LEN1)->SetWindowText(strlen); m_ctrOnOFF_1.SetIcon(m_hIconOff);
CString strClear= " ";
SetDlgItemText(IDC_DISP_1,strClear);
}
主對話框的頭文件:引入本身寫的網絡通訊類頭文件
#include "UdpSocket.h"
函數、變量、指針、數組 定義:
void ShortToBytes(BYTE bytes[], SHORT num); void DataProcessing(); void OnReceive(CUdpSocket *psock);//網絡數據接收函數 CUDPDlg(CWnd* pParent = NULL); // standard constructor CUdpSocket *m_pSocket;//建立CUdpSocket類對象指針 int GetDispIP(); int GetIPAddress(const CString &sHostName, CString &sIPAddress); int GetLocalHostName(CString &sHostName); int CleanUp(); int StartUp(); char *pCirBuf;//緩存指針 int startPos,endPos;//頭指針,尾指針 BYTE SendAone[2];//存放兩個字節的數組 int recBytes;//接收字節計數 SOCKADDR_IN m_clientAddr;// HICON m_hIconOff;//斷開鏈接圖標 HICON m_hIconOn;//創建鏈接圖標
// Implementation protected: HICON m_hIcon; CString m_strPeerIPaddr;//目的ip BOOL m_bIsConnected;//是否鏈接
重載的虛擬函數:
afx_msg void OnVScroll(UINT nSBCode, UINT nPos, CScrollBar* pScrollBar); afx_msg HBRUSH OnCtlColor(CDC* pDC, CWnd* pWnd, UINT nCtlColor);
用於網絡通訊的 UdpSocket.h 文件中程序:
//主對話框類 class CUDPDlg; ///////////////////////////////////////////////////////////////////////////// // CUdpSocket command target class CUdpSocket : public CSocket { // Attributes public: // Operations public: CUdpSocket(); //重載構造函數 CUdpSocket(CUDPDlg* p_hwnd); virtual ~CUdpSocket(); // Overrides public: //建立主對話框類的指針變量p_dlgwnd CUDPDlg* p_dlgwnd; // SOCKADDR_IN m_clientAddr; // ClassWizard generated virtual function overrides //{{AFX_VIRTUAL(CUdpSocket) public: virtual void OnReceive(int nErrorCode); //}}AFX_VIRTUAL // Generated message map functions //{{AFX_MSG(CUdpSocket) // NOTE - the ClassWizard will add and remove member functions here. //}}AFX_MSG // Implementation protected: };
CUdpSocket類的源文件中:
引入主對話框資源:
//引入主對話框資源 #include "UDPDlg.h"
重載構造函數:
// CUdpSocket CUdpSocket::CUdpSocket() { } //重載構造函數 CUdpSocket::CUdpSocket(CUDPDlg* p_hwnd) { //主對話框的句柄 p_dlgwnd=p_hwnd; } CUdpSocket::~CUdpSocket() { //socket是有效套接字,則關閉socket鏈接 if (INVALID_SOCKET != this->m_hSocket) { //關閉socket鏈接 Close(); } }
數據接收函數:
void CUdpSocket::OnReceive(int nErrorCode) { // TODO: Add your specialized code here and/or call the base class CSocket::OnReceive(nErrorCode); //觸發主對話框實現文件中的函數 p_dlgwnd->OnReceive(this); }
主對話框垂直滾動條的響應函數:
void CUDPDlg::OnVScroll(UINT nSBCode, UINT nPos, CScrollBar* pScrollBar) { // TODO: Add your message handler code here and/or call default SCROLLINFO scrollinfo; GetScrollInfo(SB_VERT,&scrollinfo,SIF_ALL); switch (nSBCode) { case SB_BOTTOM: ScrollWindow(0,(scrollinfo.nPos-scrollinfo.nMax)*10); scrollinfo.nPos = scrollinfo.nMax; SetScrollInfo(SB_VERT,&scrollinfo,SIF_ALL); break; case SB_TOP: ScrollWindow(0,(scrollinfo.nPos-scrollinfo.nMin)*10); scrollinfo.nPos = scrollinfo.nMin; SetScrollInfo(SB_VERT,&scrollinfo,SIF_ALL); break; case SB_LINEUP: scrollinfo.nPos -= 1; if (scrollinfo.nPos<scrollinfo.nMin) { scrollinfo.nPos = scrollinfo.nMin; break; } SetScrollInfo(SB_VERT,&scrollinfo,SIF_ALL); ScrollWindow(0,10); break; case SB_LINEDOWN: scrollinfo.nPos += 1; if (scrollinfo.nPos>scrollinfo.nMax) { scrollinfo.nPos = scrollinfo.nMax; break; } SetScrollInfo(SB_VERT,&scrollinfo,SIF_ALL); ScrollWindow(0,-10); break; case SB_PAGEUP: scrollinfo.nPos -= 5; if (scrollinfo.nPos<scrollinfo.nMin) { scrollinfo.nPos = scrollinfo.nMin; break; } SetScrollInfo(SB_VERT,&scrollinfo,SIF_ALL); ScrollWindow(0,10*5); break; case SB_PAGEDOWN: scrollinfo.nPos += 5; if (scrollinfo.nPos>scrollinfo.nMax) { scrollinfo.nPos = scrollinfo.nMax; break; } SetScrollInfo(SB_VERT,&scrollinfo,SIF_ALL); ScrollWindow(0,-10*5); break; case SB_ENDSCROLL: // MessageBox("SB_ENDSCROLL"); break; case SB_THUMBPOSITION: // ScrollWindow(0,(scrollinfo.nPos-nPos)*10); // scrollinfo.nPos = nPos; // SetScrollInfo(SB_VERT,&scrollinfo,SIF_ALL); break; case SB_THUMBTRACK: ScrollWindow(0,(scrollinfo.nPos-nPos)*10); scrollinfo.nPos = nPos; SetScrollInfo(SB_VERT,&scrollinfo,SIF_ALL); break; } CDialog::OnVScroll(nSBCode, nPos, pScrollBar); }