六月婷婷综合激情-六月婷婷综合-六月婷婷在线观看-六月婷婷在线-亚洲黄色在线网站-亚洲黄色在线观看网站

明輝手游網中心:是一個免費提供流行視頻軟件教程、在線學習分享的學習平臺!

Windows下面向任務欄編程的若干問題

[摘要]趙潔 胡德保一. 引言任務欄是Windows中一個眾所周知的概念,它指的是Windows桌面上顯示已運行程序的一塊條狀區域。一般來說,任務欄是由三個部分組成的:最左邊是“開始”按鈕,中間是已運行程序...
趙潔 胡德保

一. 引言
任務欄是Windows中一個眾所周知的概念,它指的是Windows桌面上顯示已運行程序的一塊條狀區域。一般來說,任務欄是由三個部分組成的:最左邊是“開始”按鈕,中間是已運行程序的顯示區域(Windows98還有一個快捷工具欄),最右邊是任務欄提示區域。所謂的任務欄編程主要指對任務欄提示區進行編程。Windows系統允許用戶在任務欄提示區里放置自己的應用程序圖標并定制自己需要的操作。
在任務欄提示區里放置應用程序圖標一方面方便了用戶與應用程序的交流,另一方面也可使應用程序以更形象的形式給用戶以提示。一般地,將應用程序圖標放置在任務欄提示區中意味著該應用程序是一個后臺程序。例如在Windows中進行后臺打印時,一個打印機圖標就會顯示在任務欄提示區中提示用戶打印機進程正在后臺運行。目前有許多軟件都使用了任務欄編程技術,如Netants、Go!zilla、金山詞霸等,這一方面是由于這些軟件具有某些“后臺”性質,另一方面也是因為將應用程序圖標放在任務欄提示區中使得人機交互更為簡便。
目前有許多編程語言都可以針對任務欄進行編程,如VC++、Delphi、VB等,也已有一些文章對其進行了介紹。但筆者發現很少有文章從原理到程序實現系統地對任務欄編程進行論述,大多數的資料只是給出幾個API函數聲明和一段代碼。但任務欄編程不僅涉及到API,還涉及回調函數等一些更為復雜的問題,因此有必要深入系統地對該問題進行探討。
二. 任務欄編程的實現技術
Windows任務欄編程的基本思路是:(1)通過API函數調用在應用程序啟動時將應用程序圖標放入任務欄提示區,在程序運行時修改圖標特性,并在應用程序關閉時將圖標從任務欄中刪去;(2)通過使用回調函數控制應用程序。本節主要探討通過API來控制圖標的一些問題。下一節將主要探討回調函數。
1. Shell_NotifyIcon函數
其聲明為: Private Declare Function Shell_NotifyIconLib "shell32" Alias "Shell_NotifyIconA" (ByVal dwMessage As Long,pnid As NOTIFYICONDATA) As Long
該函數給系統發送添加、修改、刪除任務欄提示區圖標的消息,系統根據發送的消息進行相應的處理。可以說該函數是任務欄提示區編程的核心,掌握它就可以輕松地編寫出符合要求的程序來。該函數中的參數意義如下:
(1) 參數dwMessage (ByVal dwMessage As Long)
該參數通知系統進行何種操作,取值如下:
NIM_ADD
添加圖標到任務欄提示區
NIM_DELETE
刪除圖標
NIM_MODIFY
發送圖標特性已改變的消息
(2) 參數pnid (pnid As NOTIFYICONDATA)
存儲圖標特性數據,NOTIFYICONDATA定義如下:
Private Type NOTIFYICONDATA
CbSize As Long '該數據結構的大小
hWnd As Long '處理圖標通知消息的窗口句柄
uID As Long '應用程序自定義的圖標ID
uFlags As Long '用來設置uCallbackMessage、hIcon、szTip等三個欄目是否有效,一般取組合NIF_ICON Or NIF_TIP Or NIF_MESSAGE,表示全部有效
uCallbackMessage As Long '消息編號,將來當使用者在圖標上按下鼠標時就會以消息通知消息處理回調函數
hIcon As Long '圖標句柄
szTip As String*64 '提示消息
End Type
2.加入圖標
在啟動窗體的Form_Load()事件中加入以下代碼就可以在程序運行時在任務欄提示區中添加一個圖標:
Dim nid As NOTIFYICONDATA
nid.cbSize = Len(nid)
nid.hwnd = Me.hwnd
nid.uID = 9998
nid.uFlags = NIF_ICON + NIF_TIP + NIF_MESSAGE
nid.hIcon = Me.Icon
nid.uCallbackMessage = WM_USER+100
nid.szTip ="歡迎使用任務欄"
Shell_NotifyIcon NIM_ADD, nid ' 
3.刪除圖標
在Form_Unload()事件中添加以下代碼在程序關閉時刪除圖標,要注意的是這里所使用到的uID和hWnd必須和當初加入圖標時所使用的uID和hWnd完全一致。
Dim nid As NOTIFYICONDATA
nid.cbSize = Len(nid)
nid.hwnd = Me.hwnd
nid.uID = 9998
Shell_NotifyIcon NIM_DELETE, nid
4.修改圖標
下面一段代碼實現圖標的修改。這里的uId和hWnd也必須和當初加入圖標時所使用的 uId和hWnd完全一致。同時還必須正確設置uFlags和hIcon。uFlags必須設置為NIF_ICON,表示修改對圖標有效;hIcon應設為新圖標。
Dim nid As NOTIFYICONDATA
nid.cbSize = Len(nid)
nid.hWnd = Me.hWnd
nid.uID = 9999
nid.uFlags = NIF_ICON
nid.hIcon = Image1.Picture
Shell_NotifyIcon NIM_MODIFY, nid
修改提示消息和消息編號的方法與此類似。不同點是當修改提示消息時須將uFlags設為NIF_TIP,修改消息編號時須將uFlags設為NIF_MESSAGE。
三. 回調函數
在前面已經講到,當用戶在圖標上按下鼠標時,系統將接收并傳遞消息給窗口消息處理回調函數進行具體的處理。用戶可以在回調函數中對不同的消息進行不同的程序處理來定制自己的應用程序的功能(例如鼠標左擊時彈出一個菜單,鼠標右擊時彈出另一個菜單,鼠標雙擊時顯示主窗口等等)。在任務欄提示區中加入圖標時設置的消息編號uMessage就是用來告訴回調函數此消息來自圖標對應的程序,回調函數即可據此進行處理。回調函數是個比較復雜的問題,下面從VB程序的運行機制入手來具體闡述任務欄編程中回調函數的實現方法。
1. VB應用程序的運行機制
VB應用程序的運行是基于Windows的消息傳遞機制的。Windows的工作方式是一種多任務多線程的工作方式,VB程序運行時是受Windows控制的。具體講,一個VB程序運行時Windows的進程管理模塊就會給它創建一個進程。進程與Windows之間的通訊是通過消息傳遞來實現的:進程發送一個消息給Windows并等待,Windows處理完此消息后將結果會傳給進程。由于Windows支持多線程,因此一個進程可以在內部創建多個線程,這些線程共享此進程的地址空間、全局變量、文件以及各種信號。除了共享地址空間外,各個線程是獨立的,每個線程有自己的程序計數器、堆棧、寄存器及狀態(等待、就緒、運行)。VB程序在運行時,通過對其所含的每個控件都創建一個線程來并行地處理控件的事件。一個控件在進程內對應一個線程。這些線程也同樣通過消息與Windows進行通訊。Windows為運行于其上的應用程序提供了確省的消息處理程序。例如在一個VB程序運行時,右擊一個文本框就會彈出一個包含“剪切”、“復制”、“粘貼”等功能的快捷菜單,這就是由Windows的確省消息處理程序來完成的。Windows系統允許用戶截獲應用程序窗口的消息并用自定義的過程來加以處理。這個自定義的過程稱為“回調”函數,用戶可在回調函數中對感興趣的消息進行適當的處理,并將其它的消息交給系統原來的消息處理過程處理。這種“替代”似乎很困難,但實際上卻是完全可以實現的。
2. 用回調函數來處理任務欄提示區的消息
回調函數(Callback Function)是應用程序提供給Windows系統DLL或其它DLL調用的函數,一般用于截獲消息、獲取系統信息或處理異步事件。應用程序把回調函數的地址指針告訴DLL,而DLL在適當的時候會調用該函數。回調函數必須遵守事先規定好的參數格式和傳遞方式,否則DLL一調用它就會引起程序或系統的崩潰。
通常情況下,回調函數采用標準Windows API的調用方式,即_stdcall,當然,DLL編制者可以自已定義調用方式,但客戶程序也必須遵守相同的規定。在_stdcall方式下,函數的參數按從右到左的順序壓入堆棧,除了明確指明是指針或引用外,參數都按值傳遞,函數返回之前自己負責把參數從堆棧中彈出。
將應用程序圖標放入任務欄提示區后,如果用戶要想打開該應用程序窗口,必須到任務欄提示區中去點擊圖標。但這并不意味著用戶點擊后,窗口就會自動顯示出來。每當用戶點擊圖標,系統會以消息方式通知窗口的消息處理回調函數,所以只要在應用程序窗口的回調函數中進行適當的編程就可以實現。
窗口消息回調函數的格式如下所示:
Function WndProc(ByVal hwnd As Long, ByVal Msg As Long, ByVal wParam As Long, ByVal lParam As Long) As Long
因為回調函數是自定義的函數,因此函數名和參數名都可以自定義。各參數的含義如下表所示:
hWnd
窗口句柄
Msg
等于當初調用Shell_NotifyIcon時所設置的uCallbackMessage的值
wParam
等于當初調用Shell_NotifyIcon時所設置的uID的值
lParam
等于鼠標消息,例如WM_LBUTTONDOWN(按下鼠標左鍵)等
在VB使用回調函數存在不少限制:1、回調函數必須放到標準的模塊(Module)中,而不能放在類模塊或窗體代碼中;2、AddressOf運算符只能用于自定義的過程、函數或屬性,不能將其用于Declare語句聲明的外部函數,也不能用于類型庫中的函數;3、寫在AddressOf后面的過程、函數和屬性必須與有關的聲明和過程在同一個工程中;4、由于回調函數要與系統直接交互,所以調試十分困難,如果回調函數中有錯誤,可能會引起非法操作,致使VB運行環境崩潰。
在VB中用回調函數處理任務欄提示區消息的具體步驟如下:
(1)在啟動窗體的Form_Load()事件中加入以下代碼。
prevWndProc = GetWindowLong(Me.hwnd, GWL_WNDPROC) '獲取系統確省的窗口消息處理函數句柄
SetWindowLong Me.hwnd, GWL_WNDPROC, AddressOf WndProc '指定WndProc為新的消息處理函數
'加入圖標
Dim nid As NOTIFYICONDATA
nid.cbSize = Len(nid)
nid.hwnd = Me.hwnd
nid.uID = 9998
nid.uFlags = NIF_ICON + NIF_TIP + NIF_MESSAGE
nid.hIcon = Me.Icon
nid.uCallbackMessage = WM_USER + 100 '定義消息編號
Shell_NotifyIcon NIM_ADD, nid ' 
(2)在模塊中加入回調函數WndProc的代碼
Function WndProc(ByVal hwnd As Long, ByVal Msg As Long, ByVal wParam As Long, ByVal lParam As Long) As Long
If Msg = WM_USER + 100 Then ''該消息等于調用Shell_NotifyIcon時定義的uCallbackMessage
If lParam = WM_LBUTTONDOWN Or lParam = WM_RBUTTONDOWN Then
'當按下鼠標左鍵或右鍵時彈出菜單
frmCaution.PopupMenu frmCaution.mnuaa
End If
End If
'其它的消息交給系統處理,prevWndProc為原來的窗口消息處理函數的句柄
WndProc = CallWindowProc(prevWndProc, hwnd, Msg, wParam, lParam)
End Function
執行以上的代碼時,API函數GetWindowLong()、SetWindowLong()和CallWindowProc()的聲明需要先加入到模塊中,這些聲明可通過VB所帶的“API文本瀏覽器”獲得。
四. 實例分析:一個定時音樂提醒程序
對于一個從事計算機工作的人來說,長時間坐在計算機前面工作是常有的事。持續的屏幕注視往往使得眼睛十分疲勞。最好是能每隔一段時間休息一下。但計算機工作尤其是編程往往會使人全神貫注,忘記了時間。我們可以設計一個定時音樂提醒程序,讓它每隔一段時間就自動提醒自己休息一會兒。
下面就結合前述的任務欄編程思想給出具體的程序實現。該程序具有每隔一段時間就播放一段音樂提醒和到某個特定時刻播放音樂提醒的功能,并可以由用戶自定義提醒時間、提醒內容以及音效。
1、新建一個工程,并加入五個窗體,分別命名為frmCaution、frmTipMess、frmSound、frmChangTime和frmAbout 。其中frmcaution為顯示提醒消息的啟動窗體,frmtipmess為用戶自定義提醒內容的窗體,frmsound為用戶自定義提醒聲音的窗體,frmchangtime為用戶自定義提醒時間方式的窗體,frmabout為“關于”信息顯示窗體。
2、在frmcaution上加入一個菜單“mnuaa”,在“mnuaa”下加入菜單“設置提醒時間……”、“設置提醒消息……”、“音效……”、“關于……”、“退出”。菜單“mnuaa”就作為當單擊圖標時的彈出菜單。在frmcaution中加入一個panel,命名為“pnlmessage”,用于顯示消息。在frmcaution中加入一個多媒體控件,命名為“mm”,用于播放音樂。在frmcaution中加入一個時間控件“Time1”。
3、在工程中加入一個標準模塊mdlCommon,并在其中放置如下代碼:
'API函數聲明
Declare Function Shell_NotifyIcon Lib "shell32.dll" Alias "Shell_NotifyIconA" (ByVal dwMessage As Long, lpData As NOTIFYICONDATA) As Long
Declare Function CallWindowProc Lib "user32" Alias "CallWindowProcA" (ByVal lpPrevWndFunc As Long, ByVal hwnd As Long, ByVal Msg As Long, ByVal wParam As Long, ByVal lParam As Long) As Long
Declare Function GetWindowLong Lib "user32" Alias "GetWindowLongA" (ByVal hwnd As Long, ByVal nIndex As Long) As Long
Declare Function SetWindowLong Lib "user32" Alias "SetWindowLongA" (ByVal hwnd As Long, ByVal nIndex As Long, ByVal dwNewLong As Long) As Long
Public Declare Function SetWindowPos Lib "user32" (ByVal hwnd As Long, ByVal hWndInsertAfter As Long, ByVal x As Long, ByVal y As Long, ByVal cx As Long, ByVal cy As Long, ByVal wFlags As Long) As Long

Public prevWndProc As Long '原有的窗口消息處理函數
Public Message As String '消息內容
Public TipInterval As Integer '提示時間間隔
Public TipTime As String '提示時間
Public Time As Integer '累計時間

Function WndProc(ByVal hwnd As Long, ByVal Msg As Long, ByVal wParam As Long, ByVal lParam As Long) As Long
If Msg = WM_USER + 100 Then
If lParam = WM_LBUTTONDOWN Or lParam = WM_RBUTTONDOWN Then
'當按下鼠標左鍵或右鍵時彈出菜單
frmCaution.PopupMenu frmCaution.mnuaa
End If
End If
'其它的消息交給系統處理,prevWndProc為原來的窗口消息處理函數的句柄
WndProc = CallWindowProc(prevWndProc, hwnd, Msg, wParam, lParam)
End Function
以上程序限于篇幅略去了數據結構和常量的定義。該定義可從“API文本瀏覽器”中獲得。
4、編寫frmcaution的Form_Load()過程。
Private Sub Form_Load()
Load frmSound
prevWndProc = GetWindowLong(Me.hwnd, GWL_WNDPROC) '獲取系統確省的窗口消息處理函數句柄
SetWindowLong Me.hwnd, GWL_WNDPROC, AddressOf WndProc '指定WndProc為新的消息處理函數
'加入圖標
Dim nid As NOTIFYICONDATA
nid.cbSize = Len(nid)
nid.hwnd = Me.hwnd
nid.uID = 9998
nid.uFlags = NIF_ICON + NIF_TIP + NIF_MESSAGE
nid.hIcon = Me.Icon
nid.uCallbackMessage = WM_USER + 100 '定義消息編號
Shell_NotifyIcon NIM_ADD, nid
'設置顯示界面
pnlMessage.Left = (Me.ScaleWidth - pnlMessage.Width) / 2
pnlMessage.Top = (Me.ScaleHeight - pnlMessage.Height) / 2
TipInterval = 30 '提醒時間間隔默認為30分鐘
TipTime = "" '提醒時間默認為空
Time = 0
Message = "親愛的主人,建議您先休息5分鐘!"
mm.Filename = frmSound!filSound.List(0)
End Sub
5、編寫frmcaution的Form_Unload()過程。
Private Sub Form_Unload(Cancel As Integer)
Dim nid As NOTIFYICONDATA
'恢復原來的窗口消息處理函數
SetWindowLong Me.hwnd, GWL_WNDPROC, prevWndProc
'刪除圖標
nid.cbSize = Len(nid)
nid.hwnd = Me.hwnd
nid.uID = uID
Shell_NotifyIcon NIM_DELETE, nid
mm.Command = "close"
End Sub
6、編寫Timer1_Timer()過程。
Private Sub Timer1_Timer()
If TipInterval <> 0 Then '若設置了提醒間隔
Time = Time + 1 '累計時間加1秒
If Time >= TipInterval * 60 Then '提醒時間間隔已到
pnlMessage.Caption = Message
Timer1.Enabled = False
mm.Filename = mm.Filename
mm.Command = "open"
mm.Command = "play"
Time = 0
frmCaution.Show
'窗口總顯示在最前
SetWindowPos Me.hwnd, HWND_TOPMOST, 0, 0, 0, 0, SWP_NOSIZE Or SWP_NOMOVE
End If
End If
If TipTime <> "" Then '若設置了定時
Dim NowTime As Date
Dim DestTime As Date
NowTime = Format(Now(), "hh:nn:ss")
DestTime = Format(TipTime, "hh:nn:ss")
If NowTime = DestTime Then '定時時間已到
pnlMessage.Caption = Message
Timer1.Enabled = False
mm.Filename = mm.Filename
mm.Command = "open"
mm.Command = "play"
frmCaution.Show
SetWindowPos Me.hwnd, HWND_TOPMOST, 0, 0, 0, 0, SWP_NOSIZE Or SWP_NOMOVE
End If
End If
End Sub

以上就給出了定時音樂提醒程序的大致過程。該程序運行時,確省情況下每隔30分鐘就會跳出一個提醒窗口,同時播放一段音樂。當用戶單擊任務欄提示區中的圖標就會彈出一個菜單,然后用戶可以選擇需要執行的功能。該程序的一些其它功能如“設置提醒時間形式”、“設置音效”等因與本文主題沒多少聯系在此不再細述。
定時音樂提醒程序在Microsoft Visual Basic 6.0中文企業版、Windows98環境下調試通過。讀者若需要完整的源程序請E-mail Martinet@sohu.com與筆者聯系。


主站蜘蛛池模板: 五月丁六月停停 | 日韩美女在线播放 | 视频一区二区免费 | 青娱乐视觉盛宴在线视频 | 四虎在线精品免费高清在线 | 色狠狠狠色噜噜噜综合网 | 亚洲不卡在线播放 | 中文字幕国产精品 | 婷婷丁香五月中文字幕 | 亚洲你懂得 | 日韩精品欧美激情国产一区 | 一二三四免费观看在线影视大全 | 亚洲第一视频网站 | 日韩永久在线观看免费视频 | 热久久国产欧美一区二区精品 | 在线免费视频a | 污污视频在线播放 | 日狠狠| 日韩精品特黄毛片免费看 | 在线视频一区二区 | 羞羞漫画在线阅读页面漫画入口页面弹窗无限 | 视频在线二区 | 日本一区二区在线 | 色婷婷久久合月综 | 四虎影院最新网址 | 青草草在线观看免费视频 | 青春草视频在线观看免费 | 午夜在线播放免费人成无 | 亚洲专区欧美专区 | 午夜大片在线观看 | 日韩精品在线观看视频 | 四虎综合| 思思久久99热只有精品 | 青草影院在线观看免费版 | 三级在线免费观看 | 天天射天天操天天 | 欧美一区高清 | 亚洲专区路线一路线二 | 色美女在线 | 青草视频网站 | 青春草在线视频观看 |