萬泉河
WX:ZHO6371995,歡迎+
級別: 略有小成
|
1225 【跨新年】【萬泉河】WINCC中獲取窗口變量前綴以及跨窗口操控的方法 近段時間,不約而同的,網站論壇和煙臺方法學員中都有提出這樣的問題。 比如: l 用C腳本如何獲得窗口中對象的變量前綴? 用VBS如何獲得? l 用C腳本如何實現在一個窗口中操控父窗口下的另一個窗口內的控件? l 用VBS如何實現? 這些問題,都有個特點,提問的時候先把編程語言給限定了。 而咱就不太有辦法拒絕。畢竟,人家有可能是在完成一個更復雜的工作,已經在選定的語言下實現了大部分的功能,現在就在這一點點功能搞不定被卡主了,過不去了,才來求助的。 而如果不指定語言的話,其實我都早就有答案,特別是VBS的解決方案,都寫在《西門子WINCC入門到精通》的書里了,所以只需要從書柜里把我自己的書拿出來,找到頁碼,把頁碼號告訴對方就可以了。 而且會發現,大部分提問者其實是有我的那本書的,只是通讀不夠細致,沒發現,或者沒記住有這方面的介紹。驗證了一個道理,對一本書,最了解的還是作者自己。 當然,我也發現了我寫書時候遺漏的該寫而未寫的技巧知識點。可能潛意識里面,我自己覺得反正另一條路上有解決方案了,這邊這一條就沒必要去重復啰嗦實現了。特別是C腳本,對西門子來說自從20年前的WINCC版本支持VBS之后,官方逐漸在弱化C腳本的地位,我自己也逐漸淡化對其的研究和使用。想一碗水端平是永遠不可能的。 在此先提醒大家,提問問題的時候,盡可能不要限定編程語言。那樣的答案多的是,可以唾手可得。而非要限定語言了,尋找起來就會有一些難度。 所以,我這里做了個例子,進行了測試,可以把這些坑填上了。也算是對我自己著作中遺漏部分的補充。 主畫面中是2個按鈕,分別演示了VBS腳本和C腳本彈出窗口的方法。 而彈出的窗口外觀相同,然而內部的程序語言不同,分別有按鈕按下后可以彈出對話框提示讀取得到了前綴。 而后,將上述2個按鈕分別放到另一個叫做“窗口中操控”的窗口(PDL文件),腳本經過稍微修改,實現了上述同樣的功能。 l 按鈕11的單擊鼠標中的VBS程序為: Sub OnClick(ByVal Item) ScreenItems("畫面窗口1").TagPrefix="M001_" ScreenItems("畫面窗口1").PictureName=Item.Text ScreenItems("畫面窗口1").Visible=True End Sub 而窗口中有2個獲取前綴的按鈕,同樣可以得到結果,腳本分別為: Sub OnClick(Byval Item) 'MsgBOX(ITEM.Parent.Parent.TagPrefix) MsgBOX(Parent.TagPrefix) End Sub 注釋掉的腳本也同樣可以執行。 Sub OnClick(Byval Item) Dim name name=HMIRuntime.Tags("aa").Name Dim TagPrefix TagPrefix=Split(name,"_")(0) MsgBOX(TagPrefix) End Sub 這里取了一個不存在的aa后綴的變量,然而也絲毫不影響功能。因為語法本身獲取的是變量名字,對變量是否有值是否合法根本不在意。 也注意兩種方式得到的前綴分別有分隔符和無分隔符的區別。 標準的用法當然不能每次都通過腳本來獲取,而是會在子窗口打開時即執行腳本,獲取到前綴后,賦值到一個靜態文本中,窗口中任何需要的地方,可以通過讀取文本內容得到。 Sub OnOpen() 'MsgBOX(Parent.TagPrefix) ScreenItems("窗口前綴").Text=Parent.TagPrefix End Sub 而如果畫面窗口中不需要顯示這個前綴,可以設置靜態文本為隱藏。這是官方例程中慣用的手法。 l 按鈕12的單擊鼠標中的C程序為: #include "apdefap.h" void OnClick(char* lpszPictureName, char*lpszObjectName, char* lpszPropertyName) { SetPropChar(lpszPictureName, "畫面窗口1","PictureName","窗口12-C獲取前綴.Pdl"); SetPropChar(lpszPictureName, "畫面窗口1","TagPrefix", "M002_"); SetPropBOOL(lpszPictureName, "畫面窗口1","Visible", TRUE); } 窗口內獲取按鈕的腳本: #include "apdefap.h" void OnClick(char* lpszPictureName, char*lpszObjectName, char* lpszPropertyName) { char Name[20]; HWND hwnd=NULL; hwnd=FindWindow(NULL,"WinCC-運行系統 -"); //獲得句柄 strcpy(Name,GetPropChar(GetParentPicture(lpszPictureName),GetParentPictureWindow(lpszPictureName),"TagPrefix")); //Return-Type: char* MessageBox(hwnd,Name,"OK",MB_OK); } 畫面打開事件中文本內容得到的方法: #include "apdefap.h" void OnOpenPicture(char* lpszPictureName,char* lpszObjectName, char* lpszPropertyName) { char Name[20]; strcpy(Name,GetPropChar(GetParentPicture(lpszPictureName),GetParentPictureWindow(lpszPictureName),"TagPrefix")); //Return-Type: char* SetPropChar(lpszPictureName,"窗口前綴","Text",Name); //Return-Type: BOOL } 這里C腳本實現的核心是一個GetParentPicture的函數,可以得到窗口的父窗口的文件名字。而這個函數是個神仙函數,各種幫助資料中都沒有見過介紹。所以只有從已有的使用演示程序中獲取。 l 窗口中按鈕11的單擊鼠標中的VBS程序為: Sub OnClick(ByVal Item) Parent.Parent.ScreenItems("畫面窗口1").TagPrefix="M001_" Parent.Parent.ScreenItems("畫面窗口1").PictureName=Item.Text Parent.Parent.ScreenItems("畫面窗口1").Visible=True End Sub l 窗口中按鈕12的單擊鼠標中的C程序為: #include "apdefap.h" void OnClick(char* lpszPictureName, char*lpszObjectName, char* lpszPropertyName) { char szParentPicture[512]; strncpy (szParentPicture,GetParentPicture(lpszPictureName), sizeof(szParentPicture)); SetPropChar(szParentPicture, "畫面窗口1","PictureName","窗口12-C獲取前綴.Pdl"); SetPropChar(szParentPicture, "畫面窗口1","TagPrefix", "M002_"); SetPropBOOL(szParentPicture, "畫面窗口1","Visible", TRUE); } 分別實現了上述同樣的功能。 當然,我們也可以隨意的組合搭配按鈕和窗口內的程序,都可以實現同樣的功能。比如即便你程序的主體語言是C的或者VBS,然而窗口中的文本獲得前綴部分可以用VBS簡單得到。 最后,這些具體產品知識點的技巧內容我近幾年確實很少觸及了。因為在我看來那都是基本功。我甚至也不去記憶具體的函數名字,比如上面的name還是tagname, TagPrefix還是Prefix,都記不住的。我即便要使用,也都直接找現成的程序模塊看一眼,抄來用下即可。 而事實上,隨著標準化模塊化的推進,這些技能已經很少用到了,因為早就封裝完善在模塊中了。 有一些年輕人看到我近年來寫各種科普文章,很少提及這些具體的技術技能技巧,懷疑我從來沒掌握這些技能,DISS我,甚至來跟我PK,只能是他們眼光太短淺了,你要從事技術工作,不是要把一項項的技能從年輕到年老記憶地牢牢的,以隨時使用。相反的是,大部分技能是需要封裝的,封裝以后直接使用,甚至自己要主動把這些具體技能都遺忘掉,才可以有更多的精力去掌握更高層的知識。 最后,給大家的建議是,要盡量少自己從頭造輪子。 雖然我自己在成長過程中,是摸著石頭過河每個輪子逐個造過來的,遇到任何問題,也都抑制不住要自己親自造輪子的沖動。輪子的每一個細節,如果不親自掌握,就會抓耳撓腮睡覺都不安心。 然而仍然要提醒同行后來者,這是一種非常低效率的行為。你可以有好奇心,精力充沛的情況下可以對別人造好的輪子仔細研讀原理,自己可以從中掌握些基本功,然而自己從頭造輪子這件事,就要盡量避免了。 上述例程的實現方法,西門子官方的例子中其實原本就有,而且功能比我這里介紹的要全面而細致得多得多。 西門子官方例程中, BST例程較多的是使用了C腳本,而LBP例程(或者叫做BPL)相同的功能則更多是用VBS實現的。 這些例程我都已經寫文章推薦過多次了。這回就不再提供鏈接以及親自提供文件了,而只提供名字,需要者自己辛苦一點去找到并學習了解。看來太容易得到的資料通常都不珍惜,只有自己辛苦一點,千辛萬苦得到的才會更加倍的去學習。 另外,考慮到上面的乏味的語言講述不夠直觀,有可能很多人看了并不能理解。 我有計劃在元旦期間做2次視頻直播講座,專門講解展示這個例程的實現方法。第一次直播會在煙臺方法學員群中,第二次直播會面向大眾。有感興趣者請關注公眾號、朋友圈,及時獲取通知。 |
---|---|
本帖最近評分記錄: |