怎樣建立簡單的任務欄應用程式 |
尚未結案
|
jackkcg
站務副站長 發表:891 回覆:1050 積分:848 註冊:2002-03-23 發送簡訊給我 |
此為轉貼資料 怎樣建立簡單的任務欄應用程式:
Windows 95 和 Windows NT 4.0包含一個令人興奮的特性:任務欄。這個通常位於區域任務條右面的區域能包含小的圖示,這些圖示能引出大的應用程式或者功能表。本篇文章主要討論如何使用Delphi建立這樣的應用程式。 在開始之前,請看下面的需要的介面方面的內容: 從技術方面來說,一個任務欄應用程式非常象普通的應用程式,它有一個消息迴圈,相應Windows的消息來完成相應的功能。 Procedure RunTrayApplication;
Var Msg : TMsg;
Begin
CreateWindow;
AddTrayIcon;
While GetMessage(Msg,0,0,0) do Begin
TranslateMessage(Msg);
DispatchMessage(Msg);
End;
DeleteTrayIcon;
End;
你能看到:所有需要做的工作是創建一個視窗,註冊一個圖示到任務欄,設置它的消息迴圈,最後關閉它。當然,必須還有增加其他代碼完成相應的功能,但是,它是真的不需要擔心。
讓我們從窗口的創建開始。實際上,這個窗口是不是能在任務欄上能見到的窗口。相應的,這個視窗只是處理消息迴圈、其他父類的工作。任務視窗(Windows 95 & NT)控制碼創建消息(例如滑鼠單擊等)和將消息發到我們的視窗。 Procedure CreateWindow;
Var
WC : TWndClass;
W : hWnd;
Begin
With WC do Begin
Style := 0;
lpfnWndProc := @WndProc;
cbClsExtra := 0;
cbWndExtra := 0;
hIcon := 0;
hCursor := 0;
hbrBackground := 0;
lpszMenuName := nil;
lpszClassName := 'MyTrayIconClass';
hInstance := System.hInstance;
end;
RegisterClass(WC);
W := Windows.CreateWindow('MyTrayIconClass','MyVeryOwnTrayIconWindow',
ws_OverlappedWindow,0,0,0,0,0,0,hInstance,nil);
ShowWindow(W,sw_Hide);
UpdateWindow(W);
MainWindow := W;
End;
這個視窗使用普通的視窗函數創建。注意這個窗口的類型是“ws_OverlappedWindow”,但是這個尺寸是0,並且它是隱藏的,所有,它將不會顯示出來。
下一步是加(註冊)我們的圖示。這將需要使用Shell_NotifyIcon這個API函數,這個函數實際上可以完成三個功能,這裏只需要它的增加的特性。 Procedure AddTrayIcon;
Var IconData : TNotifyIconData;
Begin
With IconData do Begin
cbSize := SizeOf(IconData);
Wnd := MainWindow;
uID := 0;
uFlags := nif_Icon Or nif_Message Or nif_Tip;
uCallBackMessage := wm_MyCallBack;
hIcon := LoadIcon(hInstance,'MYICON');
StrCopy(szTip,PChar(TrayIconTip));
End;
Shell_NotifyIcon(nim_Add,@IconData);
End;
這個最重要的事情是TNotifyIconData的資料結構,它是一個設置Window控制碼的資料結構,是一個記錄參數,對我們來說,我們需要設置這個圖示的視窗控制碼(這將定義哪個視窗處理消息迴圈),回調消息號,圖示,工具提示等。一旦這個資料設置了,我們就可以增加一個圖示到任務欄上了。?了完成這個工作,使用nim_Add程式。
現行我們已經加了我們的圖示到任務欄,下面需要決定如何處理消息。 Const
wm_MyCallback = wm_User 1000;
cm_Exit = 100; { we worry about... }
cm_About = 101; { ...these later }
這個實際的窗口處理過程也是相當普通。幾個視窗消息(如wm_NCCreate)必須處理。然而,對我們來說,更重要的事情是處理wm_MyCallback和wm_Command消息:
Function WndProc(Window : hWnd; Msg,WParam,LParam : Integer): Integer; StdCall;
Begin
Result := 0;
Case Msg of
wm_NCCreate : Result := 1;
wm_Destroy : PostQuitMessage(0);
wm_Command : Begin { a command was chosen from the popup menu }
If (WParam = cm_Exit) Then
PostMessage(Window,wm_Destroy,0,0)
Else If (WParam = cm_About) Then
MessageBox(0,'Shell Test Copyright ?'
'Jani J?vinen 1996.',
'About Shell Test',mb_OK)
Else OpenDesktopIcon(WParam-cm_About);
End;
wm_MyCallback : Begin { our icon was clicked }
If (LParam = wm_LButtonDown) Then
ShowIconPopupMenu
Else If (LParam = wm_RButtonDown) Then
ShowAboutPopupMenu;
End;
Else Result := DefWindowProc(Window,Msg,WParam,LParam);
End;
End;
就象你看到的一樣,當用戶單擊圖示時,Windows提示我們。注意我們不使用通常使用的wm_LButtonDown 消息,而使用wm_MyCallback message,詳細的消息資訊存儲在LParam參數中。
當用戶單擊滑鼠右鍵,我們創建一個功能表在桌面上。 Type
TIconData = Array[1..100] of String;
Var
IconData : TIconData;
Procedure ShowIconPopupMenu;
Var
ShellFolder : IShellFolder;
EnumIDList : IEnumIDList;
Result : hResult;
Dummy : ULong;
ItemIDList : TItemIDList;
Pntr : PItemIDList;
StrRet : TStrRet;
PopupMenu : hMenu;
ItemID : Integer;
Pos : TPoint;
Procedure AddToMenu(Item : String);
Var S : String;
Begin
IconData[ItemID-cm_About] := Item;
S := ExtractFileName(Item);
If (System.Pos('.',S) <> 0) Then SetLength(S,System.Pos('.',S)-1);
AppendMenu(PopupMenu,mf_Enabled Or mf_String,ItemID,PChar(S));
Inc(ItemID);
End;
begin
PopupMenu := CreatePopupMenu;
ItemID := cm_About 1;
SHGetDesktopFolder(ShellFolder);
ShellFolder.EnumObjects(MainWindow,SHCONTF_NONFOLDERS,EnumIDList);
Pntr := @ItemIDList;
Result := EnumIDList.Next(1,Pntr,Dummy);
While (Result = NoError) do Begin
ShellFolder.GetDisplayNameOf(Pntr,SHGDN_FORPARSING,@StrRet);
With StrRet do AddToMenu(String(CStr));
Result := EnumIDList.Next(1,Pntr,Dummy);
End;
EnumIDList.Release;
ShellFolder.Release;
GetCursorPos(Pos);
AppendMenu(PopupMenu,mf_Separator,0,'');
AppendMenu(PopupMenu,mf_Enabled Or mf_String,cm_Exit,'E&xit');
SetForegroundWindow(MainWindow);
TrackPopupMenu(PopupMenu,tpm_LeftAlign Or tpm_LeftButton,
Pos.X,Pos.Y,0,MainWindow,nil);
DestroyMenu(PopupMenu);
end;
上面的程式看起來有點複雜,你可以將它分成兩個部分來看:創建和顯示功能表。
列舉創建功能表是用Windows的外殼介面完成的。首先,我們使用SHGetDesktopForlder函數得到使用桌面的IShellFolder介面。使用這個介面,我們能得到另一個介面的實例:IEnumIDList。這個介面通常實現實際的列舉工作。我們簡單的重復調用這個函數直到錯誤值返回(例如:所有的功能表被列舉)。當我們得到一個功能表,我們使用AddToMenu函數加它。 當所有的功能表被列舉和創建後,現在我們需要運行這個功能表。我們將找到的功能表保存到一個全局的List變數中,每一個功能表都擁有它的功能表號。這確保我們能得到它的索引。
OpenDesktopIcon(WParam-cm_About) 當然,WParam中儲存了用戶單擊滑鼠的功能表的功能表號(ID)。 下面我們將處理運行用戶選擇的功能表。 Procedure OpenDesktopIcon(Number : Integer);
Var
S : String;
I : Integer;
begin
S := IconData[Number];
I := ShellExecute(0,nil,PChar(S),nil,nil,sw_ShowNormal);
If (I < 32) Then Begin
S := 'Could not open selected item "' S '". '
'Result was: ' IntToStr(I) '.';
MessageBox(0,PChar(S),'Shell Test',mb_OK);
End;
end;
------
********************************************************** 哈哈&兵燹 最會的2大絕招 這個不會與那個也不會 哈哈哈 粉好 Delphi K.Top的K.Top分兩個字解釋Top代表尖端的意思,希望本討論區能提供Delphi的尖端新知 K.表Knowlege 知識,就是本站的標語:Open our mind |
本站聲明 |
1. 本論壇為無營利行為之開放平台,所有文章都是由網友自行張貼,如牽涉到法律糾紛一切與本站無關。 2. 假如網友發表之內容涉及侵權,而損及您的利益,請立即通知版主刪除。 3. 請勿批評中華民國元首及政府或批評各政黨,是藍是綠本站無權干涉,但這裡不是政治性論壇! |