程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
 程式師世界 >> 編程語言 >> C語言 >> 關於C語言 >> Visual C#編程技巧兩則(2)

Visual C#編程技巧兩則(2)

編輯:關於C語言

ISynchronizeInvoke不僅僅用於WinForm中。例如,一個Calculator類提供了將兩個數字相加的Add()方法,它就是通過ISynchronizeInvoke來實現的。用戶必須確定ISynchronizeInvoke.Invoke()方法的調用是執行在正確的線程中的。

或許你並不想進行同步調用,因為它被打包發送到另一個線程中去了。你可以通過BeginInvoke()和EndInvoke()方法來實現它。你可以依照通用的.Net非同步編程模式(asynchronous programming model)來使用這些方法:用BeginInvoke()來發送調用,用EndInvoke()來實現等待或用於在完成時進行提示以及收集返回結果。 還值得一提的是ISynchronizeInvoke方法並非安全類型。 類型不符會導致在執行時被拋出異常,而不是編譯錯誤。所以在使用ISynchronizeInvoke時要格外注意,因為編輯器無法檢查出執行錯誤。

實現ISynchronizeInvoke要求你使用一個代理來在後期綁定(late binding)中動態地調用方法。每一種代理類型均提供DynamicInvoke()方法: public object DynamicInvoke(object[] args);

理論上來說,你必須將一個方法代理放到一個需要提供對象運行的真實的線程中去,並使Invoke() 和BeginInvoke()方法中的代理中調用DynamicInvoke()方法。ISynchronizeInvoke的實現是一個非同一般的編程技巧,本文附帶的源文件中包含了一個名為Synchronizer的幫助類(helper class)和一個測試程序,這個測試程序是用來論證列表A中的Calculator類是如何用Synchronizer類來實現ISynchronizeInvoke的。Synchronizer是ISynchronizeInvoke的一個普通實現,你可以使用它的派生類或者將其本身作為一個對象來使用,並將ISynchronizeInvoke實現指派給它。

用來實現Synchronizer的一個重要元素是使用一個名為WorkerThread的嵌套類(nested class)。WorkerThread中有一個工作項目(work item)查詢。WorkItem類中包含方法代理和參數。Invoke()和BeginInvoke()用來將一個工作項目實例加入到查詢裡。WorkerThread新建一個.Net worker線程,它負責監測工作項目的查詢任務。查詢到項目之後,worker會讀取它們,然後調用DynamicInvoke()方法。 —J.L.

問題:處理Html文檔和剪貼板(clipboard)

我的程序需要將HTML文檔放進剪貼板中,但我不知道要怎樣處理才能使其他程序也能使用它。我查看了一些關於HTML Clipboard Format (CF_Html)的參考說明,但我還是找不到准確的定義。請問我該如何操作?

解答:

使用帶有Windows 剪貼板的CF_HTML Clipboard Format的確容易讓人搞胡塗,一部分是因為它不是clipboard format中自帶的剪貼板;它是一個注冊格式(registered format),所以不是一個常量,因為它的值會因為系統的不同而產生變化。你可以通過一個簡單的API調用 -- RegisterClipboardFormat來獲得一個注冊剪貼板格式的值。這個函數的首次調用會通過一個給定的字符串來執行,它返回一個范圍在C000-FFFF之間的唯一值。每一個在系統上處理的後續調用(subsequent call)會返回同樣的值。用於這種格式中的關鍵字符串就是“Html Format”:

Private Declare Function _
RegisterClipboardFormat _
Lib "user32" _
Alias "RegisterClipboardFormatA" _
(ByVal lpString As String) As Long
Dim CF_Html As Long
Const RegHtml As String = "Html Format"
CF_Html = _
RegisterClipboardFormat(RegHtml)

你必須首先構建一個描述性的header,並在將HTML數據放入剪貼板之前先把它放到數據中。這個header會給其他程序提供描述版本信息、HTML起始數據的偏移量(offset),以及有關實際選擇范圍(actual selection)起始地方的信息。用戶可能會選擇的HTML文檔的一部分甚至只是一個元素(比如一個table中的幾行)作為一個選擇區域。頁面的其他部分,比如內聯樣式定義(inline style definitions)則可能會被要求進行完全渲染(render)。你不僅需要將最初所選擇的Html區域放入剪貼板,而且還需要放入一個header,它看起來就像是這樣:

Version:1.0
StartHtml:000000258
EndHtml:000001491
StartFragment:000001172
EndFragment:000001411

應用程序通過StartFragment和EndFragment屬性來決定哪些數據需要粘貼,這些數據或許會(也可能不會)用剩下的HTML對所選擇的部分進行格式安排。你必須將Html注釋放入數據中以便將來對所選部分進行識別。很明顯,你必須在構建最後的header之前完成它,否則偏移量會有變化。一個用於所選數據的opening/closing注釋標簽分別是“<!--StartFragment-->”和“<!--EndFragment-->”。

在這裡我無法對這個header的各個方面都進行詳細的介紹,所以我只能講解一些要點,你可以參考范例代碼以及進行更深入的了解(見資源)。你必須記住幾個要點。Header中的偏移量是以零為基准的,因此你必須以此來調節你的字符串操作程序(string-manipulation routine )。而且,如果你不僅需要讀取而且需要編寫header,你則必須了解字符數(number of digits )(比如Internet Explorer [IE] 是9,Word是10)。

最後,如果你只是將CF_HTML放入剪貼板,那麼諸如Word和FrontPage等程序就處理不了了。你必須同時給剪貼板提供一個格式化的HTML的純文本編譯(plain-text rendition)以實現你所希望的結果。許多用來執行HTML-to-text轉換的工具或是Macho可能都需要執行自帶的剖析器。但是Windows程序員是不需要對Html進行手動解析的。你可以用OS來取代這個日常任務:

Public Function Html2Text(ByVal Data _
As String) As String
Dim obj As Object
On Error Resume Next
Set obj = _
CreateObject("Htmlfile")
obj.Open
obj.Write Data
Html2Text = obj.Body.InnerText
End Function

升級IE並不是解析Html最快的方法,但卻是相當好用的方法。 —K.E.P.

  1. 上一頁:
  2. 下一頁:
Copyright © 程式師世界 All Rights Reserved