本程序利用的控件主要是Button 控件、Panel 控件、DriveComboBox 控件、DirectoryListBox 控件、FileListBox 控件和ListBox 控件等。DriveComboBox 、DirectoryListBox 和FileListBox 控件用來浏覽和選擇屏保程序文件。ListBox 控件用來顯示當前預覽的屏保程序列表。Windows 的屏保程序是後綴為.SCR 的程序,調用相關Windows API 函數可以實現對這類程序的預覽。
程序界面效果:
該程序涉及Windows 底層函數的操作,比較復雜,主要需要解決以下幾個問題:
(1)屏幕保護預覽接口:屏幕保護預覽接口的使用很簡單,這是通過傳給屏幕保護程序的命令行參數來實現的,該命令行參數格式為:screensaver.exe /p ##### (其中#####為一個有效的窗口句柄的10 進制表示)。這個窗口我們可以稱之為預覽窗口。實際上,支持預覽接口的屏幕保護程序是將自己的窗口創建為預覽窗口的子窗口來實現預覽功能的。
(2)畫面布局:我們這個程序的窗口分為三部分,下左部分列出所有可用的屏幕保護程序,下右部分列出所有正在預覽的屏幕保護程序,上面當然是預覽窗口了。用Delphi實現時,首先在Form 裡放2 個TPanel 組件,Panel1 對齊方式為頂部對齊,Panel2 為撐滿用戶區,再在Panel1 中TFileListBox 組件和TListBox 組件。
(3)列出屏幕保護程序:將FileListBox1 的Mask 屬性設為’*.scr’,這是屏幕保護程序的擴展名。在FormCreate 方法中將FileListBox1.directory 設為Windows 系統目錄GetSystemDirectory,這一點我們可以根據自己操作系統的文件而進行修改。
(4)預覽屏幕保護程序:在FileListBox1DblClick 方法中運行該屏幕保護程序。 同時還要增加一些特性:隱藏、顯示和關閉屏保程序。
1.新建工程
(1)啟動Delphi 6.0 程序。選擇“文件”菜單下的“新建”命令,從彈出的子菜單中選擇Application 選項,則出現新建工程的Form1 窗口。
(2)選擇“文件”菜單下的“工程另存為”命令,彈出Save Unit1 As 對話框。在“保存在”列表框中選擇需要存放該窗口文件所在的目錄名;在“文件名”編輯框中填寫文件名,這裡填寫“Unit1”,點擊“保存”按鈕,保存上面的選項。
(3)執行上一步後,將彈出“工程另存為”對話框。在“保存在”列表框中選擇需要存放該工程的目錄名,最好和第(2)步選取相同的目錄;在“文件名”編輯框中填寫保存處理該工程的源代碼的文件名,這裡填寫“Project1”,點擊“保存”按鈕,保存上面的選項。
2.修改窗口:
(1)激活Form1 窗口,在“屬性”面板中設置該窗體的Caption 屬性為“屏保程序預覽”,Color 屬性設置為“clBtnFace”。
(2)選擇“標准”頁上的Panel 選項,在窗體中添加Panel 控件,調整其合適的大小和位置。在“標准”面板中設置其Align 屬性分別為“alTop”,BevelInner 屬性為“bvRaised”,BevelOuter 屬性為“bvLowered”,BevelWidth 為1,BorderStyle 屬性為“bsSingle”,BorderWidth 設置為1。
(3)選擇“標准”頁上的Panel 選項,在窗體中添加Panel 控件,調整其合適的大小和位置。在“屬性”面板上設置其Align 屬性為“alClIEnt”,BevelInner 屬性為“bvNone”,BevelOuter 屬性為“bvRaised”,BevelWidth 為1,BorderStyle 屬性為“bsNone”,BorderWidth設置為0。
(4)選擇Win 3.1 頁上的DriveComboBox 選項,在窗體中添加DriveComboBox 控件,調整其合適的大小和位置。在“屬性”面板上設置其Color 屬性為“clWindow”,Name屬性為DriveComboBox1”。
(5)按照步驟(4),在窗體中添加其它控件:DirectoryListBox 和FileListBox,調整其合適的大小和位置。在“屬性”面板上設置其Color 屬性均為“clWindow”,Name 屬性分別是“DirectoryListBox”和“FileListBox”。選中FileListBox 控件,在“屬性”面板上設置其Mask 屬性為“*.scr”。
(6)選擇“標准”頁上的ListBox 選項,在窗體中添加ListBox 控件,在Object Inspecter面板上設置其Color 屬性為“clWindow”,設置其Name 屬性為“ListBox1”。
(7)選擇“標准”頁上的Button 選項,在Panel2 上添加4 個Button 控件。在“屬性”面板上設置其Caption 屬性分別為“隱藏屏保”、“顯示屏保”、“關閉屏保”和“退出”。按下Shift 鍵,同時選中這4 個Button 控件,選擇“編輯”菜單下的“對齊”命令,從彈出的對話框中為Button 控件選擇合適的對齊方式。
具體的代碼設計步驟:
(1)當點擊屏保程序列表時,屏保程序進入ListBox,ListBox 需要響應不同的事件,進行更新,需要增加兩個函數,用於更新ListBox。
function EnumProc(h : HWND; l:integer): boolean;stdcall; //更新ListBox1 的內容 // h:子窗口的句柄 l:運行函數的定義 var buf : array[0..255] of char; begin GetWindowText(h, buf, Sizeof(buf)- 1); if iswindowVisible(h) then Form1.ListBox1.Items.add(’-’+strpas(buf)+’:’+inttostr(h)) else Form1.ListBox1.Items.add(’-’+strpas(buf)+’:’+inttostr(h)); Result := true; end; procedure TForm1.Fresh1; //更新ListBox1 的內容 begin ListBox1.Clear; enumChildWindows(Panel2.handle, TFNWndEnumProc(@enumproc), 0); end;
(2)在程序運行時,自動獲取屏保程序所在路徑。這需要在TForm1.FormCreate()事件中添加相應代碼。
procedure TForm1.FormCreate(Sender: TObject); begin FileListBox1.directory :=’C:\Windows\SYSTEM’; //讀者可以查看自己的屏保程序的位置,重新設置路徑 end;
(3)雙擊屏保程序列表中的屏保文件時,該屏保的預覽效果在窗體的上部分顯示,同時,正在預覽的屏保程序進入ListBox 列表中。
procedure TForm1.FileListBox1DblClick(Sender: TObject); //運行屏保程序 begin WinExec(pchar(FileListBox1.FileName + ’ /p ’ + inttostr(Panel2.handle)), SW_Show); //預覽屏保 Fresh1;//更新ListBox end;
(4)在ListBox 中選中正在預覽的屏保程序文件後,點擊“隱藏屏保”按鈕,可以在預覽窗口中隱藏正在預覽的屏保。這需要利用函數ShowWindow(h, SW_HIDE);
procedure TForm1.Button2Click(Sender: TObject);//隱藏屏保 var h : integer; s : string; begin if ListBox1.ItemIndex = -1 then exit; s := Listbox1.Items[ListBox1.ItemIndex]; h := strtoint(copy(s, pos(’:’, s) + 1, length(s))); ShowWindow(h, SW_HIDE); //隱藏屏保 Fresh1; //更新ListBox1 end;
(5)顯示屏保需要利用函數ShowWindow(h, SW_SHOW),關閉屏保需要利用函數PostMessage(h, WM_QUIT, 0, 0),代碼如下:
procedure TForm1.Button3Click(Sender: TObject);//顯示屏保 var h : integer; s : string; begin if ListBox1.ItemIndex = -1 then exit; s := Listbox1.Items[ListBox1.ItemIndex]; h := strtoint(copy(s, pos(’:’, s) + 1, length(s))); ShowWindow(h, SW_SHOW); //顯示屏保 Fresh1; //更新ListBox1 end; procedure TForm1.Button4Click(Sender: TObject); //關閉屏保 var h : integer; s : string; begin if ListBox1.ItemIndex = -1 then exit; s := Listbox1.Items[ListBox1.ItemIndex]; h := strtoint(copy(s, pos(’:’, s) + 1, length(s))); PostMessage(h, WM_QUIT, 0, 0); //關閉屏保 Fresh1; //更新ListBox1 end;
(6)退出程序只需用Close 語句即可實現。相關代碼如下:
procedure TForm1.Button1Click(Sender: TObject); //退出程序 begin close; end;
該屏幕保護完整代碼:
vIEw source