Delphi 透過 DDE 讀取 YesWin 的即時資訊出現亂碼 |
答題得分者是:aftcast
|
bestlong
站務副站長 發表:126 回覆:734 積分:512 註冊:2002-10-19 發送簡訊給我 |
看到網路上有在寫程式讀取下單軟體的即時資訊
想說來試一試結果資料是讀到了不過卻附上亂碼 畫面如下: [code delphi] procedure TForm1.FormCreate(Sender: TObject); begin ddeClientItem1.Lines.Clear; ddeClientItem2.Lines.Clear; ddeClientItem3.Lines.Clear; ddeClientItem4.Lines.Clear; ddeClientConv1.ConnectMode := ddeAutomatic; ddeClientConv1.FormatChars := True; ddeClientConv1.FormatChars := False; ddeClientConv1.SetLink('YES','DQ'); DdeClientItemTime.DdeConv := ddeClientConv1; DdeClientItemTime.DdeItem := 'Time'; ddeClientItem1.DdeConv := ddeClientConv1; ddeClientItem1.DdeItem := '$TWT.Name'; ddeClientItem2.DdeConv := ddeClientConv1; ddeClientItem2.DdeItem := '$TWT.Price'; ddeClientItem3.DdeConv := ddeClientConv1; ddeClientItem3.DdeItem := 'TXF1.Name'; ddeClientItem4.DdeConv := ddeClientConv1; ddeClientItem4.DdeItem := 'TXF1.Price'; end; procedure TForm1.DdeClientItemTimeChange(Sender: TObject); var i: integer; begin Label1.Caption := DDEClientItemTime.Text; Label3.Caption := IntToStr(Length(DDEClientItemTime.Text)); Label8.Caption := ''; for i := 1 to Length(DDEClientItem2.Text) do begin Label8.Caption := Label8.Caption ' ' IntToStr(Ord(DDEClientItemTime.Text[i])); end; Label8.Caption := Trim(Label8.Caption) end; procedure TForm1.ddeClientItem1Change(Sender: TObject); begin Edit1.Text := DDEClientItem1.Text; Label4.Caption := IntToStr(Length(DDEClientItem1.Text)); end; procedure TForm1.ddeClientItem2Change(Sender: TObject); var i: integer; begin Edit2.Text := ddeClientItem2.Text; Label5.Caption := IntToStr(Length(DDEClientItem2.Text)); Edit5.Clear; for i := 1 to Length(DDEClientItem2.Text) do begin Edit5.Text := Edit5.Text ' ' IntToStr(Ord(DDEClientItem2.Text[i])); end; Edit5.Text := Trim(Edit5.Text); end; procedure TForm1.ddeClientItem3Change(Sender: TObject); begin Edit3.Text := ddeClientItem3.Text; Label6.Caption := IntToStr(Length(DDEClientItem3.Text)); end; procedure TForm1.ddeClientItem4Change(Sender: TObject); var i: integer; begin Edit4.Text := ddeClientItem4.Text; Label7.Caption := IntToStr(Length(DDEClientItem4.Text)); Edit6.Clear; for i := 1 to Length(DDEClientItem4.Text) do begin Edit6.Text := Edit6.Text ' ' IntToStr(Ord(DDEClientItem4.Text[i])); end; end; [/code] 不知道站友是否有處理的經驗,能開釋一下嗎?
------
http://blog.bestlong.idv.tw/ http://www.bestlong.idv.tw/ http://delphi-ktop.bestlong.idv.tw/ 編輯記錄
bestlong 重新編輯於 2009-03-20 14:12:34, 註解 無‧
|
GrandRURU
站務副站長 發表:240 回覆:1680 積分:1874 註冊:2005-06-21 發送簡訊給我 |
|
aftcast
站務副站長 發表:81 回覆:1485 積分:1763 註冊:2002-11-21 發送簡訊給我 |
照我的經驗與看法:
結構體(delphi叫record?)裡的一些char[ ]之類的資料在轉入ansistring時,沒用使用AnsiString(char*,n) 這個方法建構,而使用一般的AnsiString(char*), 就會導致有"垃圾"。 應該不是送來的資料本身有怪字,而是指到自己程式裡的額外的記憶體。所以才有會 tedit? 什麼之類的…還有規則的 垂垂… 應該都是指到不該指的位置造成。 是在server端的處理時可能就轉不正確造成。
------
蕭沖 --All ideas are worthless unless implemented-- C++ Builder Delphi Taiwan G+ 社群 http://bit.ly/cbtaiwan |
mephise
高階會員 發表:4 回覆:149 積分:205 註冊:2004-02-09 發送簡訊給我 |
|
GrandRURU
站務副站長 發表:240 回覆:1680 積分:1874 註冊:2005-06-21 發送簡訊給我 |
過了快四年才找到解……
底下是我使用 Delphi 2009 測出來不會有亂碼的程式片斷: var myAnsiPChar: PAnsiChar; begin myAnsiPChar := DdeClientConv1.RequestData($TWT.Name); Caption := string(myAnsiPChar); 或許 DdeClientItem 有什麼不為人知的 Bug 吧。 希望這回覆不會太晚...Orz
編輯記錄
GrandRURU 重新編輯於 2014-05-23 16:28:27, 註解 無‧
|
aftcast
站務副站長 發表:81 回覆:1485 積分:1763 註冊:2002-11-21 發送簡訊給我 |
以下是放在我部落格裡的備份 http://aftcast.pixnet.net/blog/post/32351223 RuRu再度燃起追其真正的原因,經三小時以上的研究,終於解開迷題了!!!! 果與我最開始的猜測有相關性 (之前的回覆) 原因: TDDEClientItem的Text屬性在某些情形下會得到亂碼加在資料的後面。原因追到VCL源碼去後發現,Text的值與下面的函式有關: procedure TDdeCliItem.StoreData(DdeDat: HDDEData); var Len: Longint; Data: string; I: Integer; begin if DdeDat = 0 then begin RefreshData; Exit; end; Data := PChar(AccessData(DdeDat, @Len)); 這裡就是問題的所在/ // len 1 Move(pData^, Result^, len); // data is binary, may contain nulls Result[len] := #0; 自己在最後面塞值,讚啦SetLength(Data, Len); //! delphi可測。 FCtrl.Lines.Text := Data; 至於改好後,要怎麼來變更delphi的library ? 這又是另一個題目…我認為應該是將ddeman.pas檔照上面改好後,在delphi裡,用install component的功能,選ddeman.pas檔,然後compile,然後會出錯,但沒關係,會得到ddeman.dcu,然後把這個檔去蓋delphi安裝目錄下的那個。請自行試看看。因我沒有delphi,我都是用c builder,故無法驗證後再保證沒錯啦! 請見諒! 結論: 不知這樣的結果算不算是bug? 假使寫server的人,用vc 寫,也注意到要含null一起copy到記憶體區塊,那就不會出事。但,最佳的解法是依DdeAccessData(hData, @Len); 中的len來決定一個正確的字串,而不是依null值的所在位置。(因null值可能是在正確字串後的任何一個地方出現的)。我會找時間去Embarcadero report這個bug?,希望在未來的版本得到修正! 後記: yeswin這程式的人員,肯定就是我說的沒注意到長度要包含null,才會造成這樣的情形。假使他有注意,那應該也不會出現亂碼附在後面了! ===================引 用 GrandRURU 文 章=================== 或許 DdeClientItem 有什麼不為人知的 Bug 吧。
------
蕭沖 --All ideas are worthless unless implemented-- C++ Builder Delphi Taiwan G+ 社群 http://bit.ly/cbtaiwan |
herbert2
尊榮會員 發表:58 回覆:640 積分:894 註冊:2004-04-16 發送簡訊給我 |
===================引 用 aftcast 文 章=================== .... RuRu再度燃起追其真正的原因,經三小時以上的研究,終於解開迷題了!!!! 果與我最開始的猜測有相關性 (之前的回覆) .... 結論: 不知這樣的結果算不算是bug? 後記: yeswin這程式的人員,肯定就是我說的沒注意到長度要包含null,才會造成這樣的情形。假使他有注意,那應該也不會出現亂碼附在後面了! 如果 Embarcadero 的團隊有人肯用心 debug,新加坡來的業務經理就不會這麼難為了! 這些深入核心的動作,還是蕭大俠功夫深。 我只能簡單的 trace 一下 if else,但就看到 TCustomGrid 配合 Runtime Themes 新功能時, 有部分變數用錯了,還有些 TWincontrol VCL 元件應該也有類似 bug; 若是自創新元件,還勉強可應付局部修改與擴增,但那麼底層的 bug,真不知要從何改起呀! 網路找到的一些討論: http://codeverge.com/embarcadero.delphi.non-tech/vcl-bug-affects-many-vcl-componen/1073429 VCL bug affects many VCL components 2009/12/17 http://codeverge.com/embarcadero.delphi.vcl.using/vcl-styles- -dbgrid-many-bugs/1074901 VCL Styles DbGrid = many bugs 2011/09/26 |
GrandRURU
站務副站長 發表:240 回覆:1680 積分:1874 註冊:2005-06-21 發送簡訊給我 |
蕭大俠是正解無誤!實在太強大!
=== 因為 TDdeCliItem 放在 implementation 建議還是直接 Copy Add Edit DdeMan.pas 到有使用 Dde 元件的專案裡 這樣專案會優先使用專案裡同名的檔案 等哪一天 EMBT 心情好,在某一版 XXXE 修了這個 Bug 後,再刪掉吧 提外話: 目前 富邦e01 也會有這樣的問題,可能是券商的工程師跳槽過去的吧 XD 話說, Debug 的時間快和開發時間比多了,換了新版情況也好不到哪裡去, 所以,按上述的推理,我很認真的懷疑現在在 EMBT 的 RD,或許是 M$ 派過去的 SPY.... ===================引 用 aftcast 文 章=================== 以下是放在我部落格裡的備份 http://aftcast.pixnet.net/blog/post/32351223 ...43... |
本站聲明 |
1. 本論壇為無營利行為之開放平台,所有文章都是由網友自行張貼,如牽涉到法律糾紛一切與本站無關。 2. 假如網友發表之內容涉及侵權,而損及您的利益,請立即通知版主刪除。 3. 請勿批評中華民國元首及政府或批評各政黨,是藍是綠本站無權干涉,但這裡不是政治性論壇! |