我們每次在Windows中撥號上網之后撥號程序都會最小化到系統托盤區里面。當我們把鼠標移到它的圖標上時,就會顯示出接收和發送的數據流量,但我們最關心的往往是我們已經上網有多長時間了以及上網費用。下面筆者將向你介紹如何用VC++編寫一個有這些功能的軟件,希望能對你有所幫助。
我們的程序界面,當按下確定時,它會最小化到系統托盤區。將鼠標移到它的圖標上,如果你已經連到了網上,就會顯示連網的時間和費用 如果你沒有連網,那么就顯示“未連接”。圖中的三個編輯框分別顯示連接時間,上網方式有撥號上網、局域上網等和即時費用。按下設置鍵,會彈出一個對話框,要求你輸入每小時的費率。
下面我們來一步一步實現這個程序的各項功能。
用AppWizard建立一個基于對話框的MFC應用程序NetTimer。我們先將程序外觀和變量定義的工作做完。
在資源編輯區內編輯對話框,最終結果如圖1。設置三個靜態文本的ID分別為IDC_STATIC_SHOWTIME,IDC_STATIC_METHOD和IDC_STATIC_FEE,三個編輯框的ID分別為IDC_EDIT_SHOWTIME,IDC_EDIT_METHOD和IDC_EDIT_FEE“確定”按鈕的ID是IDOK,“設置”按鈕是IDC_BUTTON_SETUP。添加一個新的對話框IDD_DIALOG1,編輯框的ID號是IDC_EDIT_YUAN.
在NetTimerDlg.h的protected區添加如下變量 CString m_strFee CString m_strTime int m_iTime BOOL m_bConnected LPDWORD flags 在它的構造函數里分別初始化如下 m_bConnected = FALSE m_iTime = 0 m_strTime = ″″ flags = new DWORD m_strFee = ″″ 首先實現程序最小化時在系統區顯示圖標的功能。為“確定”按鈕對應的OnOk事件響應函數寫入如下代碼 NOTIFYICONDATA nc nc.cbSize = sizeofNOTIFYICONDATA nc.hIcon = AfxGetApp->LoadIconIDR_MAINFRAME nc.hWnd = m_hWnd lstrcpync.szTip,″hello″ nc.uCallbackMessage = WM_NC//自定義的消息 nc.uID = IDC_NC nc.uFlags = NIF_TIP | NIF_MESSAGE | NIF_ICON Shell_NotifyIconNIM_ADD,&nc //在托盤區顯示IDR_MAINFRAME對應的圖標 ShowWindowfalse//隱藏窗口 然后在NetTimerDlg.cpp的文件頭部寫入 #define WM_NC 1001 #define IDC_NC 1002
以上代碼中關鍵的函數是Shell_NotifyIcon,第一個參數表示你要增加、修改還是刪除圖標;第二個參數是一個NOTIFYICONDATA結構變量對應的地址,它的主要作用是提供必要的信息,使托盤區圖標能夠正常工作。需要注意的一點是一定要把原先默認的CButtonOnOk語句從函數里刪除否則程序會在每次按下回車之后就自動退出。 下面代碼是雙擊圖標時的響應函數
void CNetTimerDlgOnNcWPARAM wParam,LPARAM lParam switchlParam case WM_LBUTTONDBLCLK//如果是雙擊圖標 ShowWindowtrue//顯示窗口 break case WM_MOUSEMOVE//如果鼠標移動到了圖標對應的矩形區域 NOTIFYICONDATA nc //以下代碼用來顯示當前連接時間和上網費用,如果沒有連接則顯示“未連接” nc.cbSize = sizeofNOTIFYICONDATA nc.hIcon = AfxGetApp->LoadIconIDR_MAINFRAME nc.hWnd = m_hWnd nc.uCallbackMessage = WM_NC nc.uFlags = NIF_MESSAGE | NIF_TIP | NIF_ICON nc.uID = IDC_NC ifm_bConnected lstrcpync.szTip,m_strTime + ″\n″ + m_strFee else lstrcpync.szTip,″未連接″ Shell_NotifyIconNIM_MODIFY,&nc break
別忘了在NetTimerDlg.h里定義函數:
afx_msg void OnNcWPARAM wParam ,LPARAM lParam
同時在NetTimerDlg.cpp的BEGIN_MESSAGE_MAPCNetTimerDlg,CDialog和BEGIN_MESSAGE_MAPCNetTimerDlg,CDialog之間插入ON_MESSAGEWM_NC,OnNc,用來申明對該消息的響應函數為OnNc。 下面在CNetTimerDlg的OnInitDialog函數后部return TRUE語句前加入 SetTimer1 1000 NULL //設置一個時鐘 編號是1 每過1秒鐘響應一次。 用ClassWizard為WM_TIMER加一個響應函數 代碼如下 void CNetTimerDlgOnTimerUINT nIDEvent m_bConnected = InternetGetConnectedStateflags NULL //判斷是否連網的API ifm_bConnected //如果連網 OnConnected//處理連網情況下的函數 else//如果沒有連網 OnDisconnected//處理未連網情況下的函數 CDialogOnTimernIDEvent
以上代碼中的InternetGetConnectedState是一個API函數,用來判斷當前是否處于連網狀態。它的第一個參數是一個指向DWORD類型的指針,用于接收上網方式的信息。第二個參數由系統保留,指定為NULL。
由于我們用到了有關網絡的函數 所以在文件頭部得添加一句 #include ″afxinet.h″ 接下去分別定義OnConnected和OnDisconnected函數: void CNetTimerDlgOnConnected int hour = 0//定義小時 分 秒 int minute = 0 int second = 0 if m_iTime < 60 //如果總的時間小于60秒... hour = 0 minute = 0 second = m_iTime if m_iTime >= 60 && m_iTime < 3600//如果大于等于60小于3600 hour = 0 minute = m_iTime / 60 second = m_iTime - minute 60 if m_iTime >= 3600 //如果大于等于3600 hour = m_iTime / 3600 minute = m_iTime - hour 3600 / 60 second = m_iTime - 60 minute - 3600 hour m_iTime ++//累加 m_strTime.Format″%d小時 %d分 %d秒″ hour minute second //格式化數據 SetDlgItemTextIDC_EDIT_SHOWTIME m_strTime//顯示連網時間 switchflags //判斷以什么方式上網 case INTERNET_CONNECTION_MODEM//撥號上網 SetDlgItemTextIDC_EDIT_METHOD ″撥號上網″ break case INTERNET_CONNECTION_LAN//通過局域網上網 SetDlgItemTextIDC_EDIT_METHOD ″通過局域網上網″ break case INTERNET_CONNECTION_PROXY //通過代理服務器 SetDlgItemTextIDC_EDIT_METHOD ″通過代理服務器上網″ break case INTERNET_CONNECTION_MODEM_BUSY//Modem忙于其他 SetDlgItemTextIDC_EDIT_METHOD ″Modem正忙 但不是上網″ break double value//以下用于顯示上網費用 m_strFee = AfxGetApp ->GetProfileString″Fee section″ ″fee″ NULL //得到保存在文件中的相應數據 value = atofm_strFee //調用atof函數將文字信息轉化為double類型 value = value m_iTime / 3600 m_strFee.Format″%lf元″ value SetDlgItemTextIDC_EDIT_FEE m_strFee //顯示費用 void CNetTimerDlgOnDisconnected SetDlgItemTextIDC_EDIT_SHOWTIME ″未連接″//在編輯框中顯示“非連接” m_iTime = 0 然后分別在NetTimerDlg.h中定義如下 public void OnDisconnected void OnConnected 下一步為ID號為IDD_DIALOG1的對話框建立一個新類CFeeDlg 并且在NetTimerDlg.cpp頭部添加 #include ″FeeDlg.h″ 然后為它的“確定”按鈕添加響應函數如下 void CFeeDlgOnOK CString text GetDlgItemTextIDC_EDIT_YUAN text//獲取編輯框IDC_EDIT_YUAN中的輸入: AfxGetApp ->WriteProfileString″Fee section″ ″fee″ text//寫入文件 CDialogOnOK 然后回過頭來為CNetTimerDlg的“設置”按鈕添加響應函數如下 void CNetTimerDlgOnButtonSetup CFeeDlg FeeDlg FeeDlg.DoModal
最后 別忘了做一些必要的編譯設置 因為我們用到了wininet.lib庫 所以要在“工程/設置”菜單下的link選項卡里將“對象/庫模塊”一項設為Wininet.lib。
OK 最后到網上下載個漂亮的圖標替代VC默認的那個圖標 編譯工程文件 一個屬于你自己的網絡計時工具就產生了以后在上網時使用這個工具 只要輸入ISP的每小時收費值,在任何時候,只要用鼠標點出系統托盤區的程序主窗口,就能對自己的上網時間和費用一目了然了。
注:文本程序在Windows 98 Visual C++6.0下通過。
|