用VC++編寫 網絡計時計費工具
發表于:2007-07-14來源:作者:點擊數:
標簽:
我們每次在 Windows 中撥號上網之后?撥號程序都會最小化到系統托盤區里面。當我們把鼠標移到它的圖標上時,就會顯示出接收和發送的數據流量,但我們最關心的往往是我們已經上網有多長時間了以及上網費用。下面筆者將向你介紹如何用VC++編寫一個有這些功能
我們每次在
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 = sizeof?NOTIFYICONDATA??
nc.hIcon = AfxGetApp??->LoadIcon?IDR_MAINFRAME??
nc.hWnd = m_hWnd?
lstrcpy?nc.szTip,″hello″??
nc.uCallbackMessage = WM_NC?//自定義的消息
nc.uID = IDC_NC?
nc.uFlags = NIF_TIP | NIF_MESSAGE | NIF_ICON?
Shell_NotifyIcon?NIM_ADD,&nc?? //在托盤區顯示IDR_MAINFRAME對應的圖標
ShowWindow?false??//隱藏窗口
然后在NetTimerDlg.cpp的文件頭部寫入?
#define WM_NC 1001
#define IDC_NC 1002
以上代碼中關鍵的函數是Shell_NotifyIcon,第一個參數表示你要增加、修改還是刪除圖標;第二個參數是一個NOTIFYICONDATA結構變量對應的地址,它的主要作用是提供必要的信息,使托盤區圖標能夠正常工作。需要注意的一點是一定要把原先默認的CButton?OnOk?語句從函數里刪除?否則程序會在每次按下回車之后就自動退出。
下面代碼是雙擊圖標時的響應函數
void CNetTimerDlg??OnNc?WPARAM wParam,LPARAM lParam?
? switch?lParam?
? case WM_LBUTTONDBLCLK?//如果是雙擊圖標
ShowWindow?true??//顯示窗口
break?
case WM_MOUSEMOVE?//如果鼠標移動到了圖標對應的矩形區域
NOTIFYICONDATA nc? //以下代碼用來顯示當前連接時間和上網費用,如果沒有連接則顯示“未連接”
nc.cbSize = sizeof?NOTIFYICONDATA??
nc.hIcon = AfxGetApp??->LoadIcon?IDR_MAINFRAME??
nc.hWnd = m_hWnd?
nc.uCallbackMessage = WM_NC?
nc.uFlags = NIF_MESSAGE | NIF_TIP | NIF_ICON?
nc.uID = IDC_NC?
if?m_bConnected?
lstrcpy?nc.szTip,m_strTime + ″\n″ + m_strFee??
else
lstrcpy?nc.szTip,″未連接″??
Shell_NotifyIcon?NIM_MODIFY,&nc??
break
別忘了在NetTimerDlg.h里定義函數:
afx_msg void OnNc?WPARAM wParam ,LPARAM lParam
同時在NetTimerDlg.cpp的BEGIN_MESSAGE_MAP?CNetTimerDlg,CDialog?和BEGIN_MESSAGE_MAP?CNetTimerDlg,CDialog?之間插入ON_MESSAGE?WM_NC,OnNc?,用來申明對該消息的響應函數為OnNc。
下面在CNetTimerDlg的OnInitDialog函數后部?return TRUE?語句前?加入?
SetTimer?1 1000 NULL?? //設置一個時鐘 編號是1 每過1秒鐘響應一次。
用ClassWizard為WM_TIMER加一個響應函數 代碼如下?
void CNetTimerDlg??OnTimer?UINT nIDEvent?
? m_bConnected = ??Inte
.netGetConnectedState?flags NULL?? //判斷是否連網的API
if?m_bConnected? //如果連網
OnConnected???//處理連網情況下的函數
else//如果沒有連網
OnDisconnected???//處理未連網情況下的函數
CDialog??OnTimer?nIDEvent
以上代碼中的InternetGetConnectedState是一個API函數,用來判斷當前是否處于連網狀態。它的第一個參數是一個指向DWORD類型的指針,用于接收上網方式的信息。第二個參數由系統保留,指定為NULL。
由于我們用到了有關
網絡的函數 所以在文件頭部得添加一句?
#include ″afxinet.h″
接下去分別定義OnConnected和OnDisconnected函數:
void CNetTimerDlg??OnConnected??
? 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?? //格式化數據
SetDlgItemText?IDC_EDIT_SHOWTIME m_strTime??//顯示連網時間
switch??flags? //判斷以什么方式上網
? case INTERNET_CONNECTION_MODEM?//撥號上網
SetDlgItemText?IDC_EDIT_METHOD ″撥號上網″??
break?
case INTERNET_CONNECTION_LAN?//通過局域網上網
SetDlgItemText?IDC_EDIT_METHOD ″通過局域網上網″??
break?
case INTERNET_CONNECTION_PROXY? //通過代理
服務器
SetDlgItemText?IDC_EDIT_METHOD ″通過代理服務器上網″??
break?
case INTERNET_CONNECTION_MODEM_BUSY?//Modem忙于其他
SetDlgItemText?IDC_EDIT_METHOD ″Modem正忙 但不是上網″??
break??
double value?//以下用于顯示上網費用
m_strFee = AfxGetApp?? ->GetProfileString?″Fee section″ ″fee″ NULL??
//得到保存在文件中的相應數據
value = atof?m_strFee??
//調用atof函數將文字信息轉化為double類型
value = value ? m_iTime / 3600?
m_strFee.Format?″%lf元″ value??
SetDlgItemText?IDC_EDIT_FEE m_strFee??
//顯示費用?
void CNetTimerDlg??OnDisconnected??
? SetDlgItemText?IDC_EDIT_SHOWTIME ″未連接″??//在編輯框中顯示“非連接”
m_iTime = 0??
然后分別在NetTimerDlg.h中定義如下?
public?
void OnDisconnected???
void OnConnected???
下一步為ID號為IDD_DIALOG1的對話框建立一個新類CFeeDlg 并且在NetTimerDlg.cpp頭部添加?
#include ″FeeDlg.h″
然后為它的“確定”按鈕添加響應函數如下?
void CFeeDlg??OnOK??
? CString text?
GetDlgItemText?IDC_EDIT_YUAN text??//獲取編輯框IDC_EDIT_YUAN中的輸入:
AfxGetApp?? ->WriteProfileString?″Fee section″ ″fee″ text??//寫入文件
CDialog??OnOK????
然后回過頭來為CNetTimerDlg的“設置”按鈕添加響應函數如下?
void CNetTimerDlg??OnButtonSetup??
? CFeeDlg FeeDlg?
FeeDlg.DoModal
最后 別忘了做一些必要的編譯設置? 因為我們用到了wininet.lib庫 所以要在“工程/設置”菜單下的link選項卡里將“對象/庫模塊”一項設為Wininet.lib。
OK 最后到網上
下載個漂亮的圖標替代VC默認的那個圖標 編譯工程文件 一個屬于你自己的網絡計時工具就產生了?以后在上網時使用這個工具 只要輸入ISP的每小時收費值,在任何時候,只要用鼠標點出系統托盤區的程序主窗口,就能對自己的上網時間和費用一目了然了。
注:文本程序在Windows 98 Visual C++6.0下通過。
原文轉自:http://www.kjueaiud.com