全國最多中醫師線上諮詢網站-台灣中醫網
發文 回覆 瀏覽次數:6922
推到 Plurk!
推到 Facebook!

Delphi編程技巧實例

 
jackkcg
站務副站長


發表:891
回覆:1050
積分:848
註冊:2002-03-23

發送簡訊給我
#1 引用回覆 回覆 發表時間:2003-02-11 19:39:23 IP:61.221.xxx.xxx 未訂閱
此為轉貼資料 http://cn.tech.yahoo.com/021021/31/1abev.html Delphi編程技巧實例 -------------------------------------------------------------------------------- (文章來源:軟體世界) Delphi編程技巧實例 倪天 廣 告 Delphi作?一門新起的Windows編程語言,由於其集?多的優秀特性於一身,因而越來越得到廣大編程人員和發燒友的青睞。以下十則技巧涉及的面比較廣泛,希望能夠對Delphi的愛好者有所裨益。 1.類似於vb.中的doevents功能。 大家或許發現,在Delphi中沒有類似於vb.中的doevents函數,這樣有的時候,我們將無法使Windows回應多個同時發生的事件。其實,在Delphi的applicaQtion物件中包括類似的一個方法:ProcessMessage,你可以通過調用Application.ProcessMessage來完成象vb.中的doevents一樣的功能。 2.在Delphi中調用NetscapeNavigator。 隨著Internet的火爆,有沒有想過在你的Delphi程式中?動Netscape瀏覽器,顯示出你指定的WWW位址的主頁。下面這個程式能夠完成這一功能。 programNetscape; usesDDEMan; procedureGoQtoURL(sURL:string); var dde:TDDEClientConv; begin dde:=TDDEClientConv.Create(nil); withddedo begin //specifythelocationofnetscape.exe ServiceApplication:=′c:\ns32\program\netscape.exe′; //activatetheNetscapeNavigator SetLink(′Netscape′,′WWW—Activate′); RequestData(′0xFFFFFFFF′); //gotothespecifiedURL SetLink(′Netscape′,′WWW—OpenURL′); RequestData(sURL+′,,0xFFFFFFFF,0x3,,,′); CloseLink; end; dde.Free; end; begin GotoURL(′http://www.yahoo.com/′); end. 3.格式化整數輸出。 比較大的數位在輸出時會顯得不易閱讀,在Delphi中顯示帶分節號的數位是相當簡單的一件事,如下即可:xxxxx.caption:ΚFormatFloat(′#′,524667500)。 4.在編譯時獲得提示。 在Delphi2.0中,編譯時,可以讓編譯器告訴你一些提示,比如哪些變數聲明了,卻從來沒有使用過。我們知道,可以通過功能表中的選項來控制是否要Delphi這樣做,但如果由於一些特殊需要,你只要在指定的代碼段需要Delphi這樣的提示,怎?辦呢?請參考如下的程式。 {$HINTON} procedureTform1.Button1Click(Sender:TObject); var X:integer; begin end; {$HINTOFF} 5.更改Windows95的牆紙。 在Delphi中你可以很方便地更改牆紙,請參考以下的程式。 procedureChangeIt; var Reg:TregIniFile; begin Reg:ΚTRegIniFile.Create(′ControlPanel′) ; Reg.WriteString(′desktop′,′Wallpaper′, ′c:\pwin95\forest.bmp′); Reg.WriteString(′desktop′,′TileWallpaper ′,′1′); Reg.Free; SystemParametersInfo(SPI—SETDESKWALLPAPER,0 ,nil,SPIF—SENDWININICHANGE); end; 6.獲得最後使用文件的日期。 在Win95中有一項新的功能,就是可以獲得訪問文件的最後日期。著名的CleanSweapforWin95軟體中就是靠這一功能來作?判斷某個文件是否被經常訪問的依據之一。在Delphi中,我們可以通過下面的程式來達到此功能。 functionGetFileLastAccessTime(sFileName:string):TDateQTime; var ffd:TWin32FindData; dft:DWord; lft:TFileTime; h:THandle; begin //getfileinformation h:ΚWindows.FindFirstFile(PChar(sFileName),ffd); if(INVALID—HANDLE—VALUEΙΛh)then begin //we′relookingforjustonefile,socloseour〃find〃 Windows.FindClose(h); //converttheFILETIMEtolocalFILETIME FileTimeToLocalFileTime(ffd.ftLastAccessTime,lft); //convertFILETIMEtoDOStime FileTimeToDosDateTime(lft,LongRec(dft).Hi,LongRec(dft).Lo); //finally,convertDOStimetoTDateTimeforuseinDelphi′snativedate/timefunctions Result:ΚFileDateToDateTime(dft); end; end; GetFileLastAccessTime()將會以Delphi的TdateTime格式返回你所指定的文件的最後訪問日期。 7.豐富多彩的標簽。 我們已經不滿足於Delphi提供的簡單的標簽,能不能在標簽中有不同的字體,有不同的?色,以此來豐富我們的表現能力。回答是肯定的,並且用不著第三方提供的控制項,我們只要巧妙的利用Delphi自己提供的TRichEdit就可以了。首先將TRichEdit控制項的邊框去除:RichEdQit1.BorderStyle:ΚbsNone;同時設置唯讀屬性?真:RichEdQit1.ReadOnly:ΚTrue;然後,你利用write之類的軟體製作好RichText格式的文本,通過以下語句就可以顯示出來了: RichEdit1.PlainText:ΚFalse; RichEdit1.Lines.LoadFromFile(′c:\test.rtf′); 8.如何防止Win95顯示嚴重錯誤。 不管你的程式如何反復調試,交給用戶之後,總有可能發生你意想不到的錯誤,如何避免Win95顯示出白色的視窗,告訴你的用戶發生了難堪的意外錯誤呢?我們可以這樣做: var wOldErrorQMode:Word; begin //tellwinQdowstoignorecriticalerrorsandsavecurQrenterrormode wOldErrorQMode:ΚSetErQrorMode(SEM—FAILCRITIQCALERRORS); try //codethatmightgenerateacriticalerrorgoeshere... finally //gobacktopreviouserrormode SetErrorMode(wOldErrorMode); end; end; 主要是利用SetErrorMode()來完成這一功能。 9.剛才用滑鼠擊了哪一個物件。 在Win95中,滑鼠的右鍵起到了很大的作用,但是,由於歷史的原因,對於右鍵的使用即使在Delphi中,也還不夠有效,下面的程式可以告訴你如何知道剛才滑鼠右擊的物件名稱。首先建立一個popmenu,然後以下的代碼就可以告訴你剛才右擊的物件名稱:PopupQMenu1.PopupComponent.ClassName。 10.檢測CD-ROM或是其他磁片是否有過變化。 最簡單的檢查CD-ROM或是磁片是否有過變化的方法是檢查其volume號碼。你可以簡單地運用下面的函數來返回磁片的volume系列號碼GetDiskVolSerialID(′E′),函數代碼如下: functionGetDiskVolSerialID(cDriveName:char):DWord; var dwTemp1,dwTemp2:DWord; begin GetVolumeInformation(PChar(cDriveName+′:\′),Nil,0,ΝResult,dwTemp2,dwTemp2,Nil,0); end; 文章來源:軟體世界 ******************************************************************************************* http://www.vclxx.org/DELPHI/AAAT1026.HTM http://www.vclxx.org/DELPHI/D32FREE/PROGRAMTRACKER.ZIP 包裝 CreateProcess API 執行其它可執行檔,並可紀錄傳回的訊息、執行狀態的非視覺化元件 ( 1.0 版,附原始程式碼),作者 : Fredrik ?hman。 ******************************************************************************************* http://www.jjhou.com/letters-2001-02.htm 日期: 2001年2月6日 AM 12:28 > 寫這封信給老師,是想向您請教一個書上的問題。但 > 再還未提出問題前,我要先謝謝老師您寫的書對我的 > 幫助。我是在一年多前因為學業上的需求而開始接觸 > VC 。由於是唸機械系的,而先前只是寫過BASIC及簡單的 > C程式。在剛始下手以MFC寫程式時,真的是瞎子摸 > 象,根本不知如何下手。當時心中真的很!@#$%^&。 > 直到朋友介紹我去買「深入VISUAL C 」,買回來 > 一看,真使我有見到桃花源的那種快感。然而可惜的 > 是此書已不再版,我們實驗室費盡心力才買到了兩本 > ,於是在朋友的建議下,我又去買了「深入淺出MFC > 」。買了看了之後的感想該怎麼形容呢?這兩本書真 > 是我寫MFC時的左輔右弼,有了這兩本書,勝過以往 > 所買的MFC書籍。一本講原理,一本講應用,搭配的 > 很完美。雖然只是看了二個月餘,對MFC的基本原理 > 也還不是很清楚。但已經能夠有具體的概念來撰寫程 > 式,不再像以前一樣亂拼亂湊的。使我的研究工作能 > 夠順利的進行。謝謝您。 > > 再來是我的問題,在您「深入淺出MFC」這本書上的 > 第一章有提到如何由一個程式來啟動另一個程式(也 > 就是API函式 CreateProcess),但我試了很多次還是沒有 > 能成功的開啟另一個程式(如開啟Window下的Notepad.exe) > ,而我看help時其寫得還是很模糊。我所寫的程式如下: > > STARTUPINFO *t=new STARTUPINFO; > LPPROCESS_INFORMATION x; > > CreateProcess("C:\\WINNT\\NOTEPAD.EXE","test.txt",NULL,NULL,TRUE, > CREATE_SUSPENDED,NULL,NULL,t,x); > > 不知我錯在那裏?還有在NT下如在98下是不是有不同? > 還請老師能夠指導我,讓我能夠順利的將這個動作完成, > 謝謝您。 ●侯捷回覆 我的書能帶給你幫助,我很開心。 CreateProcess() 這個函式在 Win32 環境下都可用。 附上檔案兩個,一個為源碼,一個為可執行檔,練習了 CreateProcess()。 此程式取出電腦上的環境變數,然後執行 notepad.exe。我猜你是忘了對 STARTUPINFO 做版本控制: memset(&si,0,sizeof(STARTUPINFO)); si.cb = sizeof(STARTUPINFO); // or use GetStartupInfo(&si) to initialize ******************************************************************************************* http://bbs.ee.ntu.edu.tw/boards/Delphi/5/4/3.html ◇ Windows API --------------------------------------------------------------------------------作者: woju@freebsd.ee.ntu.edu.tw (woju) 標題: DNAPI.html 時間: Sun Mar 2 08:38:12 1997 CAPTION: [INLINE] Delphi 學習筆記之Windows API [返回問答篇] [返回中文首頁] [INLINE] 內容摘要說明 備註事項 類似 VB DoEvents 要怎麼寫? 如何產生程式群組與程式圖像 如何以程式控制輸入法的切換 Win3.1控制WINDOWS的桌布圖形 如何得知系統所有視窗的資訊 以MessageBeep()提醒使用者 自訂滑鼠指標 轉移鍵盤焦點 如何寫一個切換大小寫的小程式? 如何執行外部程式 攔截 Windows95 的按鍵 ? 將 Mouse Pointer 鎖定在指定範圍內 讓 Windows95 跳到 Login 的地方 CWin3.1如何取得第一個輸入法 如何知道輸入法的視窗是開著的 讓視窗成為最前方視窗 讓Window95停止結束 把 Form 控制成不能放大/縮小/移動/關閉 如何得知視窗現為最大或最小化 偵測Win使用者名稱與產品序號 如何使用經 RegisterWindowMessage 註冊的訊息 附範例程式 設定特定檔案類型的關聯執行檔 移動滑鼠指標到指定的元件上方 控制 NUMLOCK 狀態 待續... ______________________________________________________________________ [INLINE] 類似 VB DoEvents 要怎麼寫? 請問DELPHI有無類似 VB 中 DoEvents 這樣的內定Procedure?或者有其它方法解 決. 希望諸Delphi高手能賜教 [INLINE] 我不算是高手, 不過正好知道這件事: 在 Delphi 中有個類似 VB DoEvent 的用法是呼叫 TApplicaton 的 ProcessMessages method, 例: Application.ProcessMessages; [返回文件開頭] ______________________________________________________________________ [INLINE] 如何產生程式群組與程式圖像 如何用delphi 寫一個install 程式,將許多project 組成一個group(程式組), 在程式組裏的icon 各代表一個project,請問要怎麼作??? [INLINE] 要產生群組與圖像, 常用的方法是與程式管理員進行 DDE 對話,呼叫程式管 理員事先預備好的巨集, 關於這些, 以下有一個例子您可以參考看看: (Delphi 1.0 CWindows 3.1, 我在 Windows 95 也試跑一次, ok, it is work) [INLINE] 1. File | New Project [INLINE] 2. 在 Form 中安置一個 TDDEClientConv 元件(在元件盤 System 那個 Tab) [INLINE] 3. 對於 DdeClientConv1, 在 Object Inspector 中點一下 DdeService 這個屬性, 然後點一下在其右方'...'的按鈕, 然後 在 DdeService 這欄填入 ProgMan 在 DdeTopic 這欄填入 Progman [INLINE] 4. 對於 DdeClientConv1 將 ConnectMode 設為 ddeManual [INLINE] 5. 在 Form1 中安排一個 TButton [INLINE] 6. 在 Button1 的 OnClick 事件: procedure TForm1.Button1Click(Sender: TObject); var sMacro: String; szMacro: Array[0..254] of Char; sGroupDesc, sGroupName: String; sProgDesc: String; sProgIcon: String; begin (* 打開對話通路 *) if not DdeClientConv1.OpenLink then begin ShowMessage('無法建立 DDE 連結'); Exit; end; (* 建立組群 *) sGroupDesc := '純測試的 Group'; sGroupName := 'Test'; (* 組成巨集指令 *) sMacro := '[CreateGroup(' sGroupDesc ',' sGroupName ')]'; StrPCopy(szMacro, sMacro); (* 轉成 Null-Term. 字串 *) DdeClientConv1.ExecuteMacro(szMacro, False); (* 執行巨集指令 *) (* 建立 Icon 圖像 *) sProgIcon := 'c:\windows\notepad.exe'; sProgDesc := '記事本'; sMacro := '[AddItem(' sProgIcon ',' sProgDesc ')]'; StrPCopy(szMacro, sMacro); (* 轉成 Null-Term. 字串 *) DdeClientConv1.ExecuteMacro(szMacro, False); (* 關閉 DDE 對話 *) DdeClientConv1.CloseLink; end; [INLINE] 7. 存檔後, 執行看看吧! 當然, 如果要寫一個安裝程式, 最快的方法是如'葛瑞菲'兄所說的,到 Delphi Super Page 中找一些好用的元件, 以上這篇, 純屬研究性質, 順便 試試 DDE 而已 [返回文件開頭] ______________________________________________________________________ [INLINE] 如何以程式控制輸入法的切換 有那位先進: 知道如何在Windows 3.1或Windows 95下,使用那些函數(在那個DLL),可在程 式中自動切換各種輸入法,例如注音'倉頡輸入法? 使用Visual C 1.52, 請 不吝指教,Thanks you!! [INLINE] 關於這個問題, 我曾分別在3.1 與 95 試過, 以下是我目前解法的綱要說 明, 請您參考看看: [INLINE] CWindow 3.1 如果要直接切換到某一種輸入法, 以 WINNLS.DLL中有一個export函式叫 ImpSetIme() 可以直接切換到某一種輸入法。 切換到中文輸入法, 先以 WINNLS.DLL中 的 export 函式 ImpGetIme() 偵測 是否某個中文輸入法已經 Active 在視窗上, 如果沒有, 再附加一個 Ctrl Space 的鍵盤事件到 SystemQueue後(就像是使用者按一次 Ctrl Space 組 合鍵), 讓 CWindows 內部的 IME 管理機制接手, 就可以切換到中文輸入法 了。 [INLINE] Windows 95 對中文輸入的機制有比較 CWin3.1完整的支援, 這部分的參考資料在MSDN一 月份的光碟片中有不錯的說明, 如果只是要切換到中文輸入法: [INLINE] 1. GetKeyboardLayOut() 取得目前執行段(Thread) 的 Keyboard Layout [INLINE] 2. 將取得的 Keyboard Layout Handle 傳入ImmIsIme()(IMM.Dll 的 Export 函數), 依傳回值判斷是否中文輸入法作用中 [INLINE] 3. 如果中文輸入法目前沒有作用, 呼叫 ImmSimulateHotKey()摸 擬一次輸入法切換熱鍵 雖然您問的的是VC , 不過, 下列的 Delphi 程式例子的作法應該仍值得參 考: procedure TCEdit.ToChinese; var hklCurrent: HKL; begin (* 取得目前的 Keyboard Layout Handle *) hklCurrent := GetKeyboardLayOut(0); (* 如果中文輸入法不是作用中 *) if not ImmIsIME(hklCurrent) then (* 摸擬一次中英切換鍵, 切換成中文輸入法 *) ImmSimulateHotKey(Handle, IME_THotKey_IME_NonIME_Toggle); {$70} end; { TCEdit.ToChinese } [返回文件開頭] ______________________________________________________________________ [INLINE] Win3.1控制WINDOWS的桌布圖形 請問如何在VB中控制WINDOWS的桌布圖形, 如果可以的話需要用到那些函數,煩請 告知,謝謝! [INLINE] 要以程式改變 Windows 3.1 版的桌布, 可以呼叫SystemParametersInfo() 這個 API, 以 Delphi實作的例子如下:(很抱歉, 我的 VB 被 Delphi 殺掉 了) procedure TForm1.Button1Click(Sender: TObject); var szBmpFileName: pchar; begin szBmpFileName := 'chitz.bmp'; (* 改變Window Desk Wall paper *) (* 第一個引數為 SPI_SetDeskWallPaper *) (* 第二個引數為 0 *) (* 第三個引數為指向 bmp 檔名字串的指標 *) SystemParametersInfo(SPI_SETDESKWALLPAPER, 0, szBmpFileName, SPIF_UPDATEINIFILE); end; [返回文件開頭] ______________________________________________________________________ [INLINE] 如何得知系統所有視窗的資訊 如果我想要取得Windows環境下的一些資訊, 如現在有幾個視窗正開啟著, 又各個 正在執行的Applications 的名稱為何等等....我要如何做到呢? [INLINE] 謹舉出一個例子提供您參考: 大綱是以 GetWindow() 配合 GetWindowText() 逐一查出各視窗的標題 [INLINE] 1. File | New Project 開始一個新的專案 [INLINE] 2. 在 Form1 中安排 Button 與 Memo 各一 [INLINE] 3. 在 Button1 的 OnClick 事件中撰寫程式如下: procedure TForm1.Button1Click(Sender: TObject); var hCurrentWindow: HWnd; szText: array[0..254] of char; begin hCurrentWindow := GetWindow(Handle, GW_HWNDFIRST); while hCurrentWindow <> 0 do begin if GetWindowText(hCurrentWindow, @szText, 255) > 0 then Memo1.Lines.Add(StrPas(@szText)); hCurrentWindow := GetWindow(hCurrentWindow, GW_HWNDNEXT); end; end; . [在創作篇有一個另以EnumWindows找視窗的範例][返回文件開頭] ______________________________________________________________________ [INLINE] 以MessageBeep()提醒使用者 如何用簡單的指令讓Delphi發出聲音 如speaker的beep或更好聽的聲音 [INLINE] 如果只是用作提醒性質, 最簡單的方法是直接呼叫 MessageBeep() 這個 API, 例:MessageBeep(0); [返回文件開頭] ______________________________________________________________________ [INLINE] 自訂滑鼠指標 小弟我最近i依 delphi online help 寫了增加 cursor 功能,結果沒反應, 是否 少了什麼 ,跟 loadcursor() 有關嗎. [INLINE] 這問題也曾困擾我很久, 參考國外一些 site 的例子(有些也是錯的),才發現 自訂滑鼠指標的部分, 在 OnLine Help 中的說明並沒有提到一些細節, 以下 的例子以前我曾回答過, 後來那位網友也試出來了, 請您參考看看: 一. 建立專案與一個資源檔 [INLINE] 1. File | New Project [INLINE] 2. Fild | Save Project, 將 unit1 與 project1 存起來, 假定 是 c:\temp 目錄 [INLINE] 3. Tools | Image Editor, 利用 Image Editor 新開一個資源 檔( Fild | New | Resource File | Ok ) [INLINE] 4. 在這個資源檔中新建一個 CURSOR_1 的 CURSOR, 並設定好它的 Hot Spot( Image | Hot Spot ) [INLINE] 5. 將資源檔存起來, 存檔時注意要和上述的 Project 存在同一個 目錄, 並且不要與 project 的原資源檔檔名重覆, 在本例我們先假定為 MyCursor.res 二. 程式部分 [INLINE] 6. 宣告一個常數, 這個常數您必須設成大於零的任何整數 [INLINE] 7. 以 LoadCursor() 函數將自訂的滑鼠指標資源 load 進來 (* --------------------------------------------- *) unit Unit1; interface uses SysUtils, WinTypes, WinProcs, Messages, Classes, Graphics, Controls, Forms, Dialogs; const crMyCursor = 1; (* 宣告一個常數 *) type TForm1 = class(TForm) procedure FormCreate(Sender: TObject); private { Private declarations } public { Public declarations } end; var Form1: TForm1; (* 請注意 *) (* 這行 $R 不可少, 否則自訂游標就出不來了 *) {$R mycursor.res} implementation {$R *.DFM} procedure TForm1.FormCreate(Sender: TObject); begin (* 將游標資源 load 進來 *) Screen.Cursors[crMyCursor] := LoadCursor(hInstance, 'CURSOR_1'); (* 指定 form1 的 cursor 為自訂滑鼠指標 *) Cursor := crMyCursor; (* 指定 Button1 的 cursor 為自訂滑鼠指標 *) Button1.Cursor := crMyCursor; end; end. [返回文件開頭] ______________________________________________________________________ [INLINE] 轉移鍵盤焦點 請問如何在delphi中做到像vb中的lostfocus的功能!! [INLINE] 用下列兩列程式可以作到類似 LostFocus 的效果 (* 移往下一個 tabstop 的 WinControl 元件 *) SendMessage(Handle, wm_NextDlgCtl, 0, 0); (* 注意: 第三個引數不為零時, focus 將移往上一個控制項 *) SendMessage(Handle, wm_NextDlgCtl, 1, 0); 另外, 我剛才試作了一個 TTestEdit 元件, 增加了 LostFocus方法, 您可以參考看看: (* -------------------------------------------------- *) (* TestEdit (* ======== (* 功能概述 (* TEdit 加上 LostFocus method 的實驗性元件 (* (* 作者: wolfgang@ms2.hinet.net (* -------------------------------------------------- *) unit TestEdit; interface uses SysUtils, WinTypes, WinProcs, Messages, Classes, Graphics, Controls, Forms, Dialogs, StdCtrls; type TTestEdit = class(TEdit) (* 繼承 TEdit *) private protected public (* 建構函式 *) constructor Create(AOwner: TComponent); override; (* 解構函式 *) destructor Destroy; override; (* 增加一個 LostFocus 方法 *) procedure LostFocus; published end; procedure Register; (* 向 Delphi 註冊這個元件 *) (* -------------------------------------------------- *) implementation (* -------------------------------------------------- *) (* Register (* 向 Delphi 註冊這個元件 (* -------------------------------------------------- *) procedure Register; begin RegisterComponents('Sample', [TTestEdit]); end; (* -------------------------------------------------- *) (* 建構函式 (* -------------------------------------------------- *) constructor TTestEdit.Create(AOwner: TComponent); begin inherited Create(AOwner); (* 呼叫祖先的建構函式建構元件 *) end; { TTestEdit.Create } (* -------------------------------------------------- *) (* 解構函式 (* -------------------------------------------------- *) destructor TTestEdit.Destroy; begin inherited Destroy; (* 呼叫祖先的建構函式 *) end; { of TTestEdit.Destroy } (* -------------------------------------------------- *) (* LostFocus (* -------------------------------------------------- *) procedure TTestEdit.LostFocus; var frmCurrent: TForm; ix: integer; begin SetFocus; (* 本元件獲得鍵盤焦點 *) frmCurrent := GetParentForm(Self); (* 查出元件所屬的 Form *) (* 讓下一個 TabStop WinControl 元件獲得鍵盤焦點 *) SendMessage(frmCurrent.Handle, wm_NextDlgCtl, 0, 0); end; { TTestEdit.LostFocus } end. { of TTestEdit } [返回文件開頭] ______________________________________________________________________ [INLINE] 如何寫一個切換大小寫的小程式? 大家好!小弟目前是以軌跡球來操作電腦,作業環境是 cwindows 3.1,輸入法是 倚天忘形輸入法。此輸入法會在螢幕上顯示一個小鍵盤,可用軌跡球輸入英 文字母、注音符號以及數字等。但是有一個缺點,那就是輸入英文字母時, 沒有辦法切換大小寫。因此小弟想寫一個可以切換大小寫的小程式,想請問 該如何著手進行呢?懇請賜教。小弟在此先謝謝各位。 [INLINE] ok, 小弟手上正好有這麼一個程序, 請您試試看: CapLock(True); (* 大寫 *) CapLock(False); (* 小寫 *) (* 鍵盤大小寫鎖定 *) Procedure CapLock(bLockIt: boolean); Var Level : Integer; KeyState : TKeyBoardState; begin Level := GetKeyState(VK_CAPITAL); GetKeyboardState(KeyState); if bLockIt then KeyState[VK_CAPITAL] := 1 else KeyState[VK_CAPITAL] := 0; setKeyboardState(KeyState); end; [返回文件開頭] ______________________________________________________________________ [INLINE] 如何執行外部程式 I get a component EXECFILE.DCU from SUNSITE.ICM.EDU.PL . They say this component can execute DOS/Win EXE file and wait till it finished. I want it. But I cannot install it. When I install it, I met a message : 'Cannot find module "FXMUTILS.DCU"' But they don't provide me a DCU named that. Does anyone ever met same condition like me? I use Delphi 1.0 [INLINE] 使用這個元件發生的問題, 找元件附的文件或直接去信問原作者可能比較容 易得到解答(因為他是最清楚的人), 不是嗎? 不清楚您提到的元件, 因此我直接回答您使用這個元件的用意好了,5/6 時曾 經在 tw.bbs.comp.language 中寫過以下的程式段, 應該是您要的東西: procedure TForm1.Button1Click(Sender: TObject); var hExeHandle : THandle; begin hExeHandle := WinExec('arj.exe /?', SW_SHOWNORMAL); while GetModuleUsage(hExeHandle) <> 0 do Application.ProcessMessages; (* 您其他的程式 *) end; 這麼作事實上仍然不能'真正的'等待另一個應用程式的結束, 雖然Button 的 OnClick 事件是暫停了, 可是使用者仍然可以點其他按鈕或者在其他的控制 項作任何他(她)想作的事, 因此, 上述的程式可以考慮修改成類似下列的作 法: procedure TForm1.Button1Click(Sender: TObject); var pWindowsList: pointer; hActiveWindow: HWnd; hExeHandle: THandle; begin pWindowsList := DisableTaskWindows(0); hActiveWindow := GetActiveWindow; try hExeHandle := WinExec('arj.exe /?', SW_SHOWNORMAL); while GetModuleUsage(hExeHandle) <> 0 do Application.ProcessMessages; finally EnableTaskWindows(pWindowsList); SetActiveWindow(hActiveWindow); end; (* 您其他的程式 *) end; Hi! 各位朋友, 對不起, 小弟疏忽了一件事, 特此更正: [INLINE] 1. 上述的程式, 在 Delphi 1.0 是正確的, 不管是 Windows 3.1 或 95 都可以編譯執行. [INLINE] 2. 如果您的環境是 Delphi 2.0 Windows 95, 那麼請改用以下 的程式寫 法: (因為 GetModuleUsage 已經從 Win32 API 中刪除了) [INLINE] 這是我的疏忽, 以下是適用於 Delphi 2.0 的程式, 希望幫得上忙 :) procedure TForm1.Button1Click(Sender: TObject); var sCommandLine: string; bCreateProcess: boolean; lpStartupInfo: TStartupInfo; lpProcessInformation: TProcessInformation; begin sCommandLine := 'Arj /?'; bCreateProcess := CreateProcessA(nil, PChar(sCommandLine), nil, nil, True, NORMAL_PRIORITY_CLASS, nil, nil, lpStartupInfo, lpProcessInformation); if bCreateProcess then WaitForSingleObject(lpProcessInformation.hProcess, INFINITE); end; __________________________________________________________________ 如果我把上述的 sCommandLine := 'Arj /?' 改為 sCommandLine := 'xcopy c:\*.* b:'; 如何能讓dos的視窗隱藏 不要顯示出來呢? [INLINE] TStartupInfo 這個結構中有一個 sShowWindow 欄位, 將之設為 SW_HIDE即 可, 同時, dwFlags 旗標中至少需含有 STARTF_USESHOWWINDOW, 否 則CreateProcess 時, sShowWindow 欄位的設定會無效, 以下是修改過的程 式: procedure TForm1.Button1Click(Sender: TObject); var sCommandLine: string; bCreateProcess: boolean; lpStartupInfo: TStartupInfo; lpProcessInformation: TProcessInformation; begin (* sCommandLine 的內容請視您的情況修改 *) sCommandLine := 'Xcopy d:\temp\temp1\*.* d:\temp\temp2 /v/y'; lpStartupInfo.dwFlags := STARTF_USESHOWWINDOW; lpStartupInfo.wShowWindow := SW_HIDE; { lpStartupInfo.wShowWindow := SW_SHOWMINIMIZED; } bCreateProcess := CreateProcess(nil, PChar(sCommandLine), nil, nil, True, HIGH_PRIORITY_CLASS, nil, nil, lpStartupInfo, lpProcessInformation); if bCreateProcess then WaitForSingleObject(lpProcessInformation.hProcess, INFINITE); end; 另外, 我也發現一個問題: 如果上述程式的 lpStartupInfo.wShowWindow;改 成 lpStartupInfo.wShowWindow := SW_SHOWMINIMIZED; 即使 以HIGH_PRIORITY_CLASS CreateProcess, 這個極小化的DOS視窗是幾乎不作 事的, 需要點一下它(讓它還原視窗大小), 才會開始作 Xcopy 的工作, 請問 有人知道原因嗎? [返回文件開頭] ______________________________________________________________________ [INLINE] 攔截 Windows95 的按鍵 ? 這樣說好了,我寫了一支 A 程式,A 程式執行時若按 F1 則 run a1.exe 按 F2 則 run a2.exe 現在我的 A 程式成被擺到背景去了..不管 User 怎麼按 F1/F2, 我寫的 A.exe 就是沒法子知道....因為我沒有控制權了,, 我猜要攔 Windows95 的 Keyboard Event,類似螢幕保護程式的作法. 只是不 知要怎麼作...:) [INLINE] 您的問題看來只好掛上 WH_KEYBOARD 這型的 HOOK 才行了, 我試了一下, 可 以用, 目前設定成每次按下 Ctrl B, 記事本就會被啟動. 有時間的話, 說不 定又可以包裝一個元件出來, 提供一些諸如OnXXXKeyHit之類的事件出 來.... :) Delphi 真是太可愛了, 用它來實作 HOOK 竟然如此簡單. :) 後記: 當時回答的內容已置於達智的學習筆記(創作篇)有關如可實作HOOK的 範例程式 [返回文件開頭] ______________________________________________________________________ [INLINE] 將 Mouse Pointer 鎖定在指定範圍內 請問如何將 mouse pointer 鎖定在一個 Form 或 TWinControl 裏面不讓它跑出 這個範圍呢 ? [INLINE] 請在 Form 中放置二個 Button, 然後分別為這兩個按鈕撰寫 OnClick, 如 下: // DELPHI 2 procedure TForm1.Button1Click(Sender: TObject); var rtButton2: TRect; begin rtButton2 := Button2.BoundsRect; MapWindowPoints(handle, 0, rtButton2, 2); // 座標換算 ClipCursor(@rtButton2); // 限制滑鼠移動區域 end; // 還原 procedure TForm1.Button2Click(Sender: TObject); var rtScreen: TRect; begin rtScreen := Rect(0, 0, Screen.Width, Screen.Height); ClipCursor(@rtScreen); end; [返回文件開頭] ______________________________________________________________________ [INLINE] 讓 Windows95 跳到 Login 的地方 (之前的討論過程請參考DelphiChat討論資料庫) 呼叫 ExitWindowEx() 並且加入 EXW_LogOff 這個X標很奇怪在我這邊不行, ^^^^^^^^^^^ 試試用 EWX_LOGOFF 試試...:) ^^^^^^^^^^ Ya, 這個是我筆誤沒錯. [INLINE] 麻煩請您回覆我三個問題好嗎? [INLINE] 1. 只有 Ewx_Logoff 旗標, 放在'開始|程式集|啟動'中的程式會 啟動嗎? [INLINE] 2. 只有 Ewx_Logoff 旗標, 在桌面右下角那些小圖示會出現嗎? [INLINE] 3. 以 Ewx_LogOff Ewx_Force 或者只有 Ewx_Force 旗標, 您 的'開始'按鈕還在不在? 另外, 方便的話, 請您讓我看一下您的程式好嗎? 看看我是不是疏忽了什麼 事. 查 MSDN(96'07), ExitWindowsEx() 的確有一個問題, 就是呼叫這個 API的 程式, 如果傳入值只有 Ewx_Logoff 旗標時, 這個程式的視窗並不會關閉, 得自已負責關掉. 最後, 我附上我用 Delphi 2 試的程式, 也許您可以告訴我是哪裏不對.謝 謝! :-) [INLINE] 1. Windows 95, 啟動 Delphi 2. [INLINE] 2. D2 主選單: File | New Application [INLINE] 3. 在 form1 上放置五個 TCheckBox, 並分別指定其 Name 屬性 為: chkEwx_Force, chkEwx_LogOff, chkEwx_PowerOff, chkEwx_ReBoot chkEwx_ShowDown [INLINE] 4. 在 form1 上再放置一個 TButton [INLINE] 5. Button1 的 OnClick 事件 procedure TForm1.Button1Click(Sender: TObject); var iFlag: uint; begin iFlag := 0; if chkEwx_Force.Checked then iFlag := iFlag or ewx_Force; if chkEwx_LogOff.Checked then iFlag := iFlag or ewx_Logoff; if chkEwx_PowerOff.Checked then iFlag := iFlag or ewx_PowerOff; if chkEwx_ReBoot.Checked then iFlag := iFlag or ewx_ReBoot; if chkEwx_ShowDown.Checked then iFlag := iFlag or ewx_ShutDown; if ExitWindowsEx(iFlag, 0) then Application.Terminate; end; : [INLINE] 6. 存檔 [INLINE] 7. D2 主選單: Project | Build All [INLINE] 8. 結束 Delphi 2 [INLINE] 9. 建立一個新的捷徑指向(或開始|執行)這個這個剛產生的 EXE. ok, 我這裏, 在信前提到的三個問題, 答案都是否定的. 不知是哪裏疏忽 了, 還請您提撥一下. :) 謝謝! MSDN 光碟片中還有一個例子, 不過它是以 ewx_LogOff ewx_Force ewx_Reboot 示範的, 這樣還是重開機了, 並不是我們話題中的: '開始 |關 機 | 關閉所有程式, 登錄成其他的使用者'. (附帶提一下, 如果沒有'登錄 成其他的使用者'這個選項, 單只傳入ewx_LogOff也是不行的, 所以,恐怕還 是以 ewx_LogOff ewx_Force ewx_Reboot 的方式最穩當吧!) [返回文件開頭] ______________________________________________________________________ [INLINE] CWin3.1如何取得第一個輸入法 因我沒有 MSDN , 是否有哪位先進可告訴我如何可得知 user 在 Windows 3.1 中 文版中預設的輸入法. [INLINE] 可行的方法有兩個. [INLINE] 甲. CWindows 3.1 有關系統已安裝的 IME 資訊記錄在 IMEINFO.INI 檔中, 以 Delphi TIniFiles 中那幾存取 .ini 的函數, 應該 不難取出第一組 IME 的設定資料. [INLINE] 乙. 以 IMPGetFirstIME() 取得 IME 的資訊. 它的 C 原型宣告 是: BOOL WINAPI IMPGetFirstIME(hWnd, lpIMEPro) 您可以在 implementation 節中宣告如下: function IMPGetFirstIME(hWndIme: HWND; lpImePro: pTImePro): BOOL; far; external 'winnls.dll'; 其中, lpIMEPro 指向的結構, 請參考小弟的作品 CEdit26b.zip(達智學習筆 記創作篇), 自解壓縮後, 在 CEdit\IME31\IME31.PAS 這個
------
**********************************************************
哈哈&兵燹
最會的2大絕招 這個不會與那個也不會 哈哈哈 粉好

Delphi K.Top的K.Top分兩個字解釋Top代表尖端的意思,希望本討論區能提供Delphi的尖端新知
K.表Knowlege 知識,就是本站的標語:Open our mind
系統時間:2024-04-28 16:59:35
聯絡我們 | Delphi K.Top討論版
本站聲明
1. 本論壇為無營利行為之開放平台,所有文章都是由網友自行張貼,如牽涉到法律糾紛一切與本站無關。
2. 假如網友發表之內容涉及侵權,而損及您的利益,請立即通知版主刪除。
3. 請勿批評中華民國元首及政府或批評各政黨,是藍是綠本站無權干涉,但這裡不是政治性論壇!