通過窗體Handle獲取窗體名稱 |
答題得分者是:RootKit
|
crw_web
一般會員 發表:2 回覆:9 積分:2 註冊:2008-03-13 發送簡訊給我 |
我有創建ProcessTHandle Function可以正確的獲取當前激活的窗體名稱.
目前是我們使用的主程式下面會包含五,六個可能更多的子窗口,我們希望能知道USER在這些子窗口中具體有使用到哪些窗口介面. 所以我想通過窗體的Handle來獲取當前激活的窗體名稱並將其名窗體名稱保存起來. 我現在的問題是: 我現在需要把這個Function放在程式的什麽位置來追蹤USER有激活某個子窗口時執行這個Function, 首先肯定不能放在各個子窗體中去,那樣的話就沒有使用意義了. 也不能使用Timer元件來處理,因這個會占用太多內存資源了. 希望有知道如何處理或有什麽好的建意的大大們幫忙..... 這個急呀...... type PEnumInfo = ^TEnumInfo; TEnumInfo = record ProcessID: DWORD; HWND: THandle; end; function EnumWindowsProc(Wnd: DWORD; var EI: TEnumInfo): Bool; stdcall; var PID: DWORD; begin GetWindowThreadProcessID(Wnd, @PID); Result := (PID <> EI.ProcessID) or (not IsWindowVisible(WND)) or (not IsWindowEnabled(WND)); if not result then EI.HWND := WND; end; function FindMainWindow(PID: DWORD): DWORD; var EI: TEnumInfo; begin EI.ProcessID := PID; EI.HWND := 0; EnumWindows(@EnumWindowsProc, Integer(@EI)); Result := EI.HWND; end; function TTHandle_Frm.ProcessTHandle(out oName, oMsg: string): Boolean; var H: THandle; begin try Result := False; H := FindMainWindow(GetCurrentProcessId); if H > 0 then begin SetLength(oStr, 255); GetWindowText(H, PChar(oName), 255); SetLength(oName, StrLen(PChar(oName))); Result := True; end else begin oMsg := 'No Find!'; end; except on e: exception do begin oMsg := 'ProcessTHandle Exception:' e.Message; end; end; end; 編輯記錄
crw_web 重新編輯於 2008-03-31 10:37:16, 註解 無‧
|
tcSweey
一般會員 發表:7 回覆:19 積分:15 註冊:2005-01-04 發送簡訊給我 |
|
crw_web
一般會員 發表:2 回覆:9 積分:2 註冊:2008-03-13 發送簡訊給我 |
|
RootKit
資深會員 發表:16 回覆:358 積分:419 註冊:2008-01-02 發送簡訊給我 |
一般不會這樣處理。
處理過專案的老手,通常會為這個專案建立基礎的 BaseFrom 。 因此較正確的作法,是在BaseForm 中 Procedure WMACTIVATE(Var Msg:TMessage);Message WM_ACTIVATE 用訊息攔截就可得知 機活的是誰並配合參數。另外也可以統籌分配共用檢查機制。 另外一點也可透過 Screen.OnActiveFormChange 事件得知視窗焦點異動情形。 補充!不需要勞駕用到 EnumWindows ,因為這些視窗都是已知的。 |
crw_web
一般會員 發表:2 回覆:9 積分:2 註冊:2008-03-13 發送簡訊給我 |
謝謝RootKit 的講解,
確實通過建立基礎的BaseFrom的做法會很方更, 但目前我們的程式無法去這樣做,所以只有在這想別的辦法了. ===================引 用 RootKit 文 章=================== 一般不會這樣處理。 處理過專案的老手,通常會為這個專案建立基礎的 BaseFrom 。 因此較正確的作法,是在BaseForm 中 Procedure WMACTIVATE(Var Msg:TMessage);Message WM_ACTIVATE 用訊息攔截就可得知 機活的是誰並配合參數。另外也可以統籌分配共用檢查機制。 另外一點也可透過 Screen.OnActiveFormChange 事件得知視窗焦點異動情形。 補充!不需要勞駕用到 EnumWindows ,因為這些視窗都是已知的。 |
RootKit
資深會員 發表:16 回覆:358 積分:419 註冊:2008-01-02 發送簡訊給我 |
|
crw_web
一般會員 發表:2 回覆:9 積分:2 註冊:2008-03-13 發送簡訊給我 |
我有嘗試用創建一個基礎的 BaseFrom,再在這裏面加上Procedure CMACTIVATE(Var Msg:TMessage);Message CM_ACTIVATE
來攔截,目前我又碰到一個問題,就是當在主窗體的FormStyle:=fsMDIForm 子窗體的FormStyle:=fsMDIChild時,我想獲取到子窗體的名稱 可總是獲取到的是主窗體的名稱,請問我該如何去獲取子窗體的名稱呢? ===================引 用 RootKit 文 章=================== 一般不會這樣處理。 處理過專案的老手,通常會為這個專案建立基礎的 BaseFrom 。 因此較正確的作法,是在BaseForm 中 Procedure WMACTIVATE(Var Msg:TMessage);Message WM_ACTIVATE 用訊息攔截就可得知 機活的是誰並配合參數。另外也可以統籌分配共用檢查機制。 另外一點也可透過 Screen.OnActiveFormChange 事件得知視窗焦點異動情形。 補充!不需要勞駕用到 EnumWindows ,因為這些視窗都是已知的。
編輯記錄
crw_web 重新編輯於 2008-04-02 10:52:19, 註解 無‧
|
crw_web
一般會員 發表:2 回覆:9 積分:2 註冊:2008-03-13 發送簡訊給我 |
這個問題解決了.
但目前我們還是不能采用這種方法,工作量太大了. ===================引 用 crw_web 文 章=================== 我有嘗試用創建一個基礎的 BaseFrom,再在這裏面加上Procedure CMACTIVATE(Var Msg:TMessage);Message CM_ACTIVATE 來攔截,目前我又碰到一個問題,就是當在主窗體的FormStyle:=fsMDIForm 子窗體的FormStyle:=fsMDIChild時,我想獲取到子窗體的名稱 可總是獲取到的是主窗體的名稱,請問我該如何去獲取子窗體的名稱呢? ===================引 用 RootKit 文 章=================== 一般不會這樣處理。 處理過專案的老手,通常會為這個專案建立基礎的 BaseFrom 。 因此較正確的作法,是在BaseForm 中 Procedure WMACTIVATE(Var Msg:TMessage);Message WM_ACTIVATE 用訊息攔截就可得知 機活的是誰並配合參數。另外也可以統籌分配共用檢查機制。 另外一點也可透過 Screen.OnActiveFormChange 事件得知視窗焦點異動情形。 補充!不需要勞駕用到 EnumWindows ,因為這些視窗都是已知的。 |
RootKit
資深會員 發表:16 回覆:358 積分:419 註冊:2008-01-02 發送簡訊給我 |
範例:
procedure TForm1.ActiveFormChange(Sender: TObject); var ActForm : TForm; begin ActForm := TScreen(Sender).ActiveForm; if ActForm <> Nil then Caption := '(' ActForm.Caption ')'; end; procedure TForm1.FormCreate(Sender: TObject); begin Screen.OnActiveFormChange := ActiveFormChange; end; ........... |
crw_web
一般會員 發表:2 回覆:9 積分:2 註冊:2008-03-13 發送簡訊給我 |
謝謝 RootKit 的回複,
現在的想法是想能不能把這個Function寫到TForm裏面去...... ===================引 用 RootKit 文 章=================== 範例: procedure TForm1.ActiveFormChange(Sender: TObject); var ActForm : TForm; begin ActForm := TScreen(Sender).ActiveForm; if ActForm <> Nil then Caption := '(' ActForm.Caption ')'; end; procedure TForm1.FormCreate(Sender: TObject); begin Screen.OnActiveFormChange := ActiveFormChange; end; ........... |
malanlk
尊榮會員 發表:20 回覆:694 積分:577 註冊:2004-04-19 發送簡訊給我 |
不知道你是否了解 Rootkit 大大的解法!!
EnumWindows 本來就是個耗時的 API,放在哪裡都一樣.... Screen本身是一個Global變數,用來給開發人員一個處理視窗變化的切入點,以下是 Delphi Help 裡的解說 TScreen introduces properties that keep track of What forms and data modules have been instantiated by the application. The active form, and the active control within that form. The size and resolution of the screen. The cursors and fonts available for the application to use. The monitors on which the application forms can appear, including their dimensions. There is a global variable, Screen, of type TScreen, which is already instantiated for use by GUI applications. Use Screen to obtain information about the current state of the screen in an application. 照您的需求來看只要在激活視窗轉換時去做個紀錄,這個就是Screen物件提供OnActiveFormChange事件的初衷。 ===================引 用 crw_web 文 章=================== 謝謝 RootKit 的回複, 現在的想法是想能不能把這個Function寫到TForm裏面去...... ==> 看不出有何必要! ===================引 用 RootKit 文 章=================== 範例: procedure TForm1.ActiveFormChange(Sender: TObject); var ActForm : TForm; begin ActForm := TScreen(Sender).ActiveForm; if ActForm <> Nil then Caption := '(' ActForm.Caption ')'; end; procedure TForm1.FormCreate(Sender: TObject); begin Screen.OnActiveFormChange := ActiveFormChange; end; ........... |
crw_web
一般會員 發表:2 回覆:9 積分:2 註冊:2008-03-13 發送簡訊給我 |
謝謝Malanlk的回複,
我有明白Rootkit大大的意思,我現在可以使用Screen.ActiveForm.Caption來獲取窗體的名稱. 我想的是把這個保存窗體名稱的function寫到哪裏面去,因為之前Rootkit說的解法對我們來說更新程式的工作量會太大, 所以我才想可不可以把這樣的一個function寫到TForm裏面去,這樣的話我們就只要把這個修改後TForm複蓋掉之前的TForm, 再去編譯一下程式就好了. 不知道我這樣說Malanlk,Rootkit大大有明白嗎? ===================引 用 malanlk 文 章=================== 不知道你是否了解 Rootkit 大大的解法!! EnumWindows 本來就是個耗時的 API,放在哪裡都一樣.... Screen本身是一個Global變數,用來給開發人員一個處理視窗變化的切入點,以下是 Delphi Help 裡的解說 TScreen introduces properties that keep track of What forms and data modules have been instantiated by the application. The active form, and the active control within that form. The size and resolution of the screen. The cursors and fonts available for the application to use. The monitors on which the application forms can appear, including their dimensions. There is a global variable, Screen, of type TScreen, which is already instantiated for use by GUI applications. Use Screen to obtain information about the current state of the screen in an application. 照您的需求來看只要在激活視窗轉換時去做個紀錄,這個就是Screen物件提供OnActiveFormChange事件的初衷。 ===================引 用 crw_web 文 章=================== 謝謝 RootKit 的回複, 現在的想法是想能不能把這個Function寫到TForm裏面去...... ==> 看不出有何必要! ===================引 用 RootKit 文 章=================== 範例: procedure TForm1.ActiveFormChange(Sender: TObject); var ActForm : TForm; begin ActForm := TScreen(Sender).ActiveForm; if ActForm <> Nil then Caption := '(' ActForm.Caption ')'; end; procedure TForm1.FormCreate(Sender: TObject); begin Screen.OnActiveFormChange := ActiveFormChange; end; ........... |
malanlk
尊榮會員 發表:20 回覆:694 積分:577 註冊:2004-04-19 發送簡訊給我 |
|
crw_web
一般會員 發表:2 回覆:9 積分:2 註冊:2008-03-13 發送簡訊給我 |
謝謝Malanlk大大提供的Sample,現在明白了.
非常感謝malanlk and Rootkit兩位大大的幫忙和講解! 這Delphi還要好好的學習. ===================引 用 malanlk 文 章=================== 看來你還是沒完全了解 Rootkit 大大的解法.. 我寫個範例.. 範例中 有改寫 Create 建構式,以便在子視窗建立時就有指定的 Caption。 如果你的子視窗原來就有唯一的Caption 那就不必改寫建構式了。 www.newsclipping.url.tw/Test.rar |
crw_web
一般會員 發表:2 回覆:9 積分:2 註冊:2008-03-13 發送簡訊給我 |
再次感謝malanlk大大,結案了,我就把分數就給Rootkit大大了喲.
繼續學習了...... ===================引 用 malanlk 文 章=================== 看來你還是沒完全了解 Rootkit 大大的解法.. 我寫個範例.. 範例中 有改寫 Create 建構式,以便在子視窗建立時就有指定的 Caption。 如果你的子視窗原來就有唯一的Caption 那就不必改寫建構式了。 www.newsclipping.url.tw/Test.rar |
本站聲明 |
1. 本論壇為無營利行為之開放平台,所有文章都是由網友自行張貼,如牽涉到法律糾紛一切與本站無關。 2. 假如網友發表之內容涉及侵權,而損及您的利益,請立即通知版主刪除。 3. 請勿批評中華民國元首及政府或批評各政黨,是藍是綠本站無權干涉,但這裡不是政治性論壇! |