Delphi編程技巧實例 |
|
jackkcg
站務副站長 發表:891 回覆:1050 積分:848 註冊:2002-03-23 發送簡訊給我 |
此為轉貼資料 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 |
本站聲明 |
1. 本論壇為無營利行為之開放平台,所有文章都是由網友自行張貼,如牽涉到法律糾紛一切與本站無關。 2. 假如網友發表之內容涉及侵權,而損及您的利益,請立即通知版主刪除。 3. 請勿批評中華民國元首及政府或批評各政黨,是藍是綠本站無權干涉,但這裡不是政治性論壇! |