2013-08-30 9 views
3

我們有一個由300多種不同形式組成的大型遺留數據庫驅動的VCL應用程序。我們希望提供一個練習(虛擬)數據庫以及與其生產數據庫一起安裝的軟件 - 可以在它們之間切換(用於培訓/練習等)。如何在不修改每個表單的代碼的情況下爲我的應用程序中的每個表單添加邊框?

的問題是,當用戶在使用實踐模式,我們必須做出一些非常明確站出來給他們,讓他們知道他們是在練習模式下工作。最理想的解決方案是在每個表單的內部邊緣放置一個紅色邊框。但有很多形式,我不想修改它們中的每一個。

如何,我可以添加這樣一個框架(Windows的邊框內,不在外面)沿着從一個全局的地方整個應用程序的所有形式的邊緣?

我不能使用VCL樣式,否則我會從那裏執行。我正在尋找一些可能迭代每個表格並繪製這個邊框的全球級別的東西。但是,這也意味着捕捉每個表單的調整大小信息並重新繪製這個邊界。

我可以看到最簡單的方法是創建具有此功能的基本形式,並從這個基本形式繼承整個系統的每個表單。但這仍然意味着確保每一種形式都是基於此。過去我們還有其他問題修改了現有表單的基本表單(另一個主題),所以如果還有另一個更簡單的解決方案,我想避免這種解決方案。

+3

你的表格不是基於自己的基類嗎? – bummi

+1

如果我從頭開始設計這個系統,我肯定會製作一個基礎表單。問題是,軟件大約有20年的歷史,並且規模巨大。許多不同的形式已經多次繼承。 –

+1

因此插入一個基礎表單。什麼東西阻止你? –

回答

4

有辦法通過重寫TComponent.ReadState爲您的形式將事件處理程序添加到TReader處理您的流掛鉤到形式流媒體系統,例如,但它們需要你真正在有問題的窗體類更改代碼。在整個計劃中似乎沒有任何方法可以全局修改行爲。因此,如果沒有您應用中所有表單的實際基本表單類,就沒有簡單的方法來執行此操作。

即使試圖在內存中修補TComponent.ReadState也很難做到正確,因爲它是一種虛擬方法,並且TCustomForm不會被覆蓋,所以您所做的任何更改都可能會影響所有組件,而不僅僅是表單。

老實說,處理這個問題的最好方法很可能就是硬着頭皮對class(TForm運行代碼庫的全局搜索,並將它們全部更改爲某些自定義窗體類的子類,以展示您正在查看的行爲對於。理論上可能有其他方法來完成它,但它們需要一些非常毛茸茸的運行時間技巧,可能會產生不可預測的副作用。

+0

你知道嗎,這裏的兩個答案都包含了我需要的最終解決方案,但是這個更詳細一些。我將繼續並實施一種基本形式,可自動檢測它是在生產模式還是在練習模式下運行。 「咬子彈」是我必須在這裏做的。 –

+1

@JerryDodge我承認,每次我看到*'我要*'都會陷入三個字母的收縮時,它仍然令我驚訝。它必須是某種記錄。 –

+0

@J ...這就是我喜歡英語的原因:D –

4

你需要在裏面插入一個基類。 TMyBorderForm繼承自TForm,它具有邊界行爲。然後讓所有表單繼承自TMyBorderForm,而不是直接從TForm繼承。

+4

我沒有downvote (只是看到了這個問題),但這可能是因爲這個問題明確地要求一個不需要修改每個表單的解決方案,並且這個答案100%無法「不需要」部分。因此,這不是以任何方式提出的問題的答案,也不應該作爲一個發佈。 (請參閱現有的評論,以適當的方式提供此解決方案 - 將其作爲評論發佈) –

+0

這就是我所做的,因爲更多的解釋而接受了其他答案。 –

0

有克里斯的回答的變化,假設你有你的DFM存儲爲文本。

  1. 定義一個窗體,你的窗體都是從窗體繼承而來的。
  2. 您加載所有的PAS文件在文本編輯器和帶班替換類(TForm的)(TMyBaseForm)
  3. IIRC你也必須修改你所有的DFM文件 - 有一個字符串「對象」改變成「繼承」。先試用一個測試應用程序,因爲我基於過去做過的事情寫這篇文章,但我不確定這個答案是否完整。
  4. 您添加邊框功能(開/關)至TMyBaseForm

嚴格地說,這需要你「通過所有形式」,而是「打開選定的文件」和「替換所有打開的文件」並不是什麼大不了的;-)

唯一的缺點是,如果你還沒有將你的DFMs存儲爲文本,你必須先改變它。

[對於大型項目來說,繼承自己的'基本形式'往往是件好事。我們使用例如對於沒有我們想要的默認屬性的第三方組件,如果開發人員忘記更改默認屬性,則基本表單中的運行時代碼將更新它]。

+0

DFMs?你的意思是表格PAS文件正確嗎? DFM不包含該代碼。 –

+0

對不起,應該是DFM和PAS。編輯。 –

+0

不,DFM包含窗體已經更改的類名,而不是'TForm' –

相關問題