Delphi ListView快速操作通用實現

Delphi ListView快速操作通用實現

作者:成曉旭

衆所周知,Delphi ListView類直接進行Add、Update、Delete操作的速度是比較慢的,尤其是當數據量較大時,比如數據量達到5000、10000、50000時,速度真是可以說是“慢得驚人”。其實快速操作的方法非常簡單,就當大家都知道了。在本人的工作中,很多項目都用到ListView,並且對速度的響應要求比較高,于是發生了快速操作ListView的代碼散布于多個項目大量模塊中的問題,並且,當界面層數據顯示要求發生改變時,自然發生“重複性代碼的通用問題”。考慮到對以前版本的兼容性問題,也一直沒有引用第三方的成熟組件。鑒于:“程序中的重複代碼最易引發問題,必須消除”的實踐經驗,自己設計了一個比較通用的解決此類問題的類結構。當然,遠不是什麽“通用框架”了(眼下市面上很多人喜歡把自己做的無論什麽東西通稱爲框架)。在采用此結構的項目中,很容易實現MVC模式,達到業務邏輯與界面顯示分離的低級的、基礎的要求。

(因爲,目前CSDN的軟件上傳功能不可用,我只有將部分代碼片斷放在文檔中,有需要完整源碼者,請留言)

類層次結構:

王朝网络

ListView基礎操作封裝在LVControler包中,核心的類是TCXXLVControler:

(說明:LVControler類是被封裝通用類結構內,外部用戶是不需要了解和訪問的,所以不作介紹。)

王朝网络

傳統的ListView操作基類是TLVCommonClass,如果想用傳統的方法增、刪、改ListView中的數據,可以直接從此類繼承。

王朝网络

源碼如下:

具體的一個從此類繼承下來的用于Socket界面顯示的TLVSocket的類Overvivw如下:

王朝网络

源碼如下:

快速的ListView操作基類是TLVQuickClass,如果想用快速方法增、刪、改ListView中的數據,可以直接從此類繼承。

王朝网络

主要方法:(可以看到,裏面沒有真正的Public方法,子類也僅需實現兩個Protected的virtual方法)

王朝网络

源碼如下:

此類中,要求每個具體應用的子類必須實現的方法僅有兩個:CheckFound():根據具體應用檢測的數據是否已經存在;ProcOnDataDetail():客戶端ListView的OnData()事件的數據處理回調方法。下面是幾個具體實現的子類的OverView:

具體的一個從此類繼承下來的用于Socket界面顯示的TLVQuickSocket的類Overvivw如下:

可以看出:子類實現了兩個抽象的虛方法,其它的方法,都是根據業務需要,類用戶自行增加的。

源碼如下:

王朝网络
//------------------------------------------------------------------------------

王朝网络
//

王朝网络
// 産品名稱: 成曉旭的個人軟件Delphi源碼庫

王朝网络
// 産品版本: CXXSoft delphi code source lib 1.0

王朝网络
// 模塊名稱: Delphi之ListView顯示控制類---應用層:Soft socket類定義單元

王朝网络
// 模塊描述:

王朝网络
// 單元文件: unLVSoftSocket.pas-->unLVQuickSocket.pas

王朝网络
// 開發作者: 成曉旭

王朝网络
// 備注: 任何人使用此文件時,請保留此段自述文件,謝謝!

王朝网络
// 開發時間: 2005-09-26

王朝网络
//

王朝网络
// 修改曆史: 2006-06-16

王朝网络
// 修改描述: 增加通過TList來高速增加、更新、刪除數據

王朝网络
// 先用吧,以後再優化和完善

王朝网络
// 修改曆史: 2006-07-10

王朝网络
// 修改描述: 成功地將ListView的OnData事件的List對象移入此類中

王朝网络
// 修改曆史: 2006-07-11

王朝网络
// 修改描述: 重大重構:將此類分成兩個類:TLVSoftSocket-->TLVSoftSocket和TLVQuickSocket

王朝网络
// 以遵循SRP原則

王朝网络
//------------------------------------------------------------------------------

王朝网络
unit unLVQuickSocket;

王朝网络

王朝网络
interface

王朝网络

王朝网络
uses

王朝网络
ComCtrls,Classes,SysUtils,Windows,

王朝网络
unLVQuickClass,unLVDefine;

王朝网络

王朝网络
type

王朝网络
TLVQuickSocket = class(TLVQuickClass)

王朝网络
private

王朝网络

王朝网络
protected

王朝网络
class function CheckFound(const pData:Pointer;const aKey:variant):boolean;override;

王朝网络
class procedure ProcOnDataDetail(const pData:Pointer;var Item: TListItem);override;

王朝网络
public

王朝网络
constructor Create();

王朝网络
destructor Destroy();override;

王朝网络
procedure InitListView(var lvTemp:TListView);

王朝网络

王朝网络
//快速方法

王朝网络
//暫時這樣增加,以後在重構到基類中

王朝网络
procedure AddToLVSocketQuick(const aSocketStatus:TSocketStatusInfo;var lvTemp:TListView);

王朝网络
procedure UpdateLVSocketQuick(const aUniqueID:integer;const aSocketStatus:TSocketStatusInfo;var lvTemp:TListView);

王朝网络
procedure DeleteLVSocketQuick(const aUniqueID:integer;const aSocketStatus:TSocketStatusInfo;var lvTemp:TListView);

王朝网络
procedure DeleteAllLVSocket(var lvTemp:TListView);

王朝网络

王朝网络
procedure OnDataEvent(Item: TListItem);

王朝网络
function GetDataCount():integer;

王朝网络
end;

王朝网络
implementation

王朝网络

王朝网络
王朝网络
...{ TLVQuickSocket }

王朝网络

王朝网络
procedure TLVQuickSocket.AddToLVSocketQuick(

王朝网络
const aSocketStatus: TSocketStatusInfo;var lvTemp:TListView);

王朝网络
begin

王朝网络
AddItemDataToListView(@aSocketStatus,sizeof(aSocketStatus),lvTemp);

王朝网络
end;

王朝网络

王朝网络
class function TLVQuickSocket.CheckFound(const pData: Pointer;

王朝网络
const aKey: variant): boolean;

王朝网络
var

王朝网络
p:^TSocketStatusInfo;

王朝网络
begin

王朝网络
p := pData;

王朝网络
Result := (p.UniqueID = aKey);

王朝网络
end;

王朝网络

王朝网络
constructor TLVQuickSocket.Create;

王朝网络
begin

王朝网络
inherited Create();

王朝网络
end;

王朝网络

王朝网络
procedure TLVQuickSocket.DeleteAllLVSocket(var lvTemp: TListView);

王朝网络
begin

王朝网络
DeleteAllListView(lvTemp);

王朝网络
end;

王朝网络

王朝网络
procedure TLVQuickSocket.DeleteLVSocketQuick(const aUniqueID:integer;

王朝网络
const aSocketStatus: TSocketStatusInfo;var lvTemp:TListView);

王朝网络
begin

王朝网络
DeleteItemDataToListView(aUniqueID,@aSocketStatus,sizeof(aSocketStatus),lvTemp);

王朝网络
end;

王朝网络

王朝网络
destructor TLVQuickSocket.Destroy;

王朝网络
begin

王朝网络
inherited Destroy;

王朝网络
end;

王朝网络

王朝网络
function TLVQuickSocket.GetDataCount(): integer;

王朝网络
begin

王朝网络
Result := Self.GetLVListCount();

王朝网络
end;

王朝网络

王朝网络
procedure TLVQuickSocket.InitListView(var lvTemp: TListView);

王朝网络
begin

王朝网络
InitListViewColumns(SocketStrBuffer,SocketWidthBuffer,lvTemp);

王朝网络
end;

王朝网络

王朝网络
procedure TLVQuickSocket.OnDataEvent(Item: TListItem);

王朝网络
begin

王朝网络
Self.OnDataToListView(Item);

王朝网络
end;

王朝网络

王朝网络
class procedure TLVQuickSocket.ProcOnDataDetail(const pData: Pointer;var Item: TListItem);

王朝网络
var

王朝网络
pSocket:^TSocketStatusInfo;

王朝网络
begin

王朝网络
//這兩個有什麽不同?

王朝网络
//CopyMemory(pSocket,pData,sizeof(TSocketStatusInfo));

王朝网络
pSocket := pData;

王朝网络
Item.Caption := IntToStr(pSocket.GroupID);

王朝网络
Item.SubItems.Add(IntToStr(pSocket.UniqueID));

王朝网络
Item.SubItems.Add(pSocket.IPAddress);

王朝网络
Item.SubItems.Add(pSocket.SubItemName);

王朝网络
Item.SubItems.Add(pSocket.LoginTime);

王朝网络
Item.SubItems.Add(pSocket.SendNumber);

王朝网络
Item.SubItems.Add(pSocket.RecNumber);

王朝网络
Item.SubItems.Add(pSocket.Remark);

王朝网络
end;

王朝网络

王朝网络
procedure TLVQuickSocket.UpdateLVSocketQuick(const aUniqueID:integer;

王朝网络
const aSocketStatus: TSocketStatusInfo;var lvTemp:TListView);

王朝网络
begin

王朝网络
UpdateItemDataToListView(aUniqueID,@aSocketStatus,sizeof(aSocketStatus),lvTemp);

王朝网络
end;

王朝网络

王朝网络
end.

小結:

應用此類結構實現ListView快速數據操作的優勢:

1、 可以快速實現MVC模式,達到界面顯示與業務邏輯的分離。在Controllor類中,實例化數據顯示子類,調用相應方法即可實現顯示數據的增、刪、改。

2、 與原始的快速方法相比,封裝了內存數據List,大大簡化了List對象的操作(尤其是當有很多相同或者類似數據要求在不同Form的ListView中顯示時),並減少了List的創建、數據操作、釋放等操作時發生錯誤的可能性。

3、 簡化了多個相同、類似數據顯示的控制代碼,針對每個份要顯示的數據及ListView,只需要實例化一個顯示子類,避免了直接應用原始的快速方法時,控制代碼分散在每一個具體Form類中的問題。

4、 對顯示數據的業務信息份進行了集中,當要求顯示的信息發生變化時,只需在數據顯示子類這一個類中更改即可。

此通用類結構仍有些不足之處,歡迎有興趣的朋友繼續完善:

1、每個應用層類的外部調用方式非常類似(請參考開發的示例源碼),表明,有些通用的方法沒有進行更好的抽象。

2、快速訪問基類對其子類的行爲抽象不充分,導致子類的應用層調用代碼非常類似。當初這樣設計的目的是想保持類結構有充分的可擴展性。其實完全可以將基類進行改良:將抽象的虛方法更換成接口,這樣,基類實現的更好的封裝,並且更好地滿足了“向穩定的方向依賴”和“針對接口編程”的設計原則。這樣,應用層還是要實例化一個自己業務需要的類來實現此接口。但Delphi的接口用起來不像是真正的接口,通常要從TInterfacedObject等類繼承,大大限制了類結構層次的演化。(因爲在不支持多繼承的語言環境中,如果還想增加更高層次的抽象就不那麽容易了)。

3、當前的版本還沒有提供針對某列進行數據排序的功能。

王朝网络
//------------------------------------------------------------------------------

王朝网络
//

王朝网络
// 産品名稱: 成曉旭的個人軟件Delphi源碼庫

王朝网络
// 産品版本: CXXSoft delphi code source lib 1.0

王朝网络
// 模塊名稱: Delphi之ListView顯示控制類---外部應用層通用類定義單元

王朝网络
// 模塊描述: ListView快速操作方法類

王朝网络
// 單元文件: unLVCommonClass.pas--->unLVQuickClass.pas

王朝网络
// 開發作者: 成曉旭

王朝网络
// 備注: 任何人使用此文件時,請保留此段自述文件,謝謝!

王朝网络
// 開發時間: 2005-09-26

王朝网络
// 修改曆史: 2006-05-31

王朝网络
// 修改描述: 解決GetLVItemOrderByValue()的參數不靈活的問題

王朝网络
// 並解決Method 'Create' hides virtual method of base type 'TComponent'的問題

王朝网络
// 修改曆史: 2006-06-16

王朝网络
// 修改描述: 增加通過TList來高速增加、更新、刪除數據

王朝网络
// 先用吧,以後再優化和完善

王朝网络
// 修改曆史: 2006-07-10

王朝网络
// 修改描述: 成功地將ListView的OnData事件的List對象移入此類中,並將其上移到其類

王朝网络
// 修改曆史: 2006-07-11

王朝网络
// 修改描述: 重大重構:將此類分成兩個類:TLVCommonClass-->TLVCommonClass和TLVQuickClass,

王朝网络
// 以遵循SRP原則

王朝网络
//------------------------------------------------------------------------------

王朝网络
unit unLVQuickClass;

王朝网络

王朝网络
interface

王朝网络

王朝网络
uses

王朝网络
SysUtils,Classes,ComCtrls,Windows,Variants,

王朝网络
unLVControler;

王朝网络

王朝网络
const

王朝网络
SpecialItemOrder = -1;

王朝网络
CSImg_Normal = 0;

王朝网络
CSImg_Running = 1;

王朝网络

王朝网络
GetColumnOrder = 0;

王朝网络
type

王朝网络
TLVQuickClass = class(TInterfacedObject)

王朝网络
private

王朝网络
cxxLVC:TCXXLVControler;

王朝网络
lvDataList: TList;

王朝网络

王朝网络
//爲ListView的Item的Data屬性查詢關鍵數據在TList中的索引號

王朝网络
class function GetListDataIndexByKey(const listData:TList;const aKey: variant):integer;

王朝网络
//快速

王朝网络
procedure ClearLVDataList();

王朝网络
protected

王朝网络
//注意:約定最後一項一定是ImageIndex

王朝网络
//tmpList:TStringList;

王朝网络
function InitListViewColumns(const displayName: array of string;

王朝网络
const displayWidth: array of integer;

王朝网络
var lvTemp:TListView):boolean;

王朝网络

王朝网络
//子類必須實現

王朝网络
class function CheckFound(const pData:Pointer;const aKey:variant):boolean;virtual; abstract;

王朝网络
class procedure ProcOnDataDetail(const pData:Pointer;var Item: TListItem);virtual; abstract;

王朝网络

王朝网络
//快速方法

王朝网络
//[注意:新方法中lvList不要求傳遞參數,保留以兼容舊客戶端版本]

王朝网络
//將pData數據加入List中,實現向ListView增加數據行

王朝网络
function AddItemDataToListView(const pData:Pointer;const dataNumber:integer;

王朝网络
var lvTemp:TListView):boolean;

王朝网络
//; var lvList: TList=nil):boolean;

王朝网络
//以aKey爲關鍵值查找,並用pData數據更新List中滿足條件的內存塊,實現向ListView更新數據行

王朝网络
function UpdateItemDataToListView(const aKey:variant;const pData:Pointer;const dataNumber:integer;

王朝网络
var lvTemp:TListView):boolean;

王朝网络
//; var lvList: TList=nil):boolean;

王朝网络
//以aKey爲關鍵值查找,並用pData數據刪除List中滿足條件的內存塊,實現向ListView刪除數據行

王朝网络
function DeleteItemDataToListView(const aKey:variant;const pData:Pointer;const dataNumber:integer;

王朝网络
var lvTemp:TListView):boolean;

王朝网络
//; var lvList: TList=nil):boolean;

王朝网络
//刪除List中所有內存區,實現將ListView清空所有數據行

王朝网络
procedure DeleteAllListView(var lvTemp:TListView);

王朝网络

王朝网络
//ListVisw的OnData事件處理

王朝网络
procedure OnDataToListView(var Item: TListItem);

王朝网络
//ListVisw的OnData事件的List Count

王朝网络
function GetLVListCount():integer;

王朝网络
public

王朝网络
constructor Create();overload;

王朝网络
destructor Destroy();override;

王朝网络
end;

王朝网络

王朝网络
implementation

王朝网络

王朝网络
王朝网络
...{ TLVQuickClass }

王朝网络

王朝网络
function TLVQuickClass.AddItemDataToListView(const pData: Pointer;

王朝网络
const dataNumber: integer; var lvTemp: TListView):boolean;

王朝网络
//; var lvList: TList):boolean;

王朝网络
var

王朝网络
pTemp:Pointer;

王朝网络
begin

王朝网络
//注意:要影響性能

王朝网络
//lvTemp.Items.BeginUpdate();

王朝网络
Result := false;

王朝网络
if NOT (Assigned(pData) and Assigned(lvTemp) and Assigned(lvDataList)) then Exit;

王朝网络
//new(pTemp);

王朝网络
GetMem(pTemp,dataNumber);

王朝网络
lvTemp.OwnerData := true;

王朝网络
CopyMemory(pTemp,pData,dataNumber);

王朝网络
lvDataList.Add(pTemp);

王朝网络
Result := true;

王朝网络
//注意:要影響性能

王朝网络
//lvTemp.Items.Count := lvList.Count;

王朝网络
//lvTemp.Items.EndUpdate();

王朝网络
end;

王朝网络

王朝网络
procedure TLVQuickClass.ClearLVDataList();

王朝网络
var

王朝网络
Loop:integer;

王朝网络
pTemp:Pointer;

王朝网络
begin

王朝网络
if NOT (Assigned(lvDataList) and (lvDataList.Count > 0)) then Exit;

王朝网络
for Loop := 0 to lvDataList.Count - 1 do

王朝网络
begin

王朝网络
pTemp := (lvDataList.Items[Loop]);

王朝网络
if Assigned(pTemp) then

王朝网络
FreeMem(pTemp);

王朝网络
end;

王朝网络
end;

王朝网络

王朝网络
constructor TLVQuickClass.Create;

王朝网络
begin

王朝网络
inherited Create();

王朝网络
cxxLVC := TCXXLVControler.Create();

王朝网络
//tmpList := TStringList.Create();

王朝网络
lvDataList := TList.Create();

王朝网络
end;

王朝网络

王朝网络
procedure TLVQuickClass.DeleteAllListView(var lvTemp: TListView);

王朝网络
begin

王朝网络
if NOT (Assigned(lvTemp) and Assigned(lvDataList) and (lvDataList.Count > 0)) then Exit;

王朝网络
lvTemp.OwnerData := true;

王朝网络
lvTemp.Items.BeginUpdate();

王朝网络
while (lvDataList.Count > 0) do

王朝网络
begin

王朝网络
Dispose(lvDataList[0]);

王朝网络
lvDataList.Delete(0);

王朝网络
end;

王朝网络
lvTemp.Items.Count := lvDataList.Count;

王朝网络
lvTemp.Items.EndUpdate();

王朝网络
end;

王朝网络

王朝网络
function TLVQuickClass.DeleteItemDataToListView(const aKey: variant;

王朝网络
const pData: Pointer; const dataNumber: integer; var lvTemp: TListView):boolean;

王朝网络
//var lvList: TList): boolean;

王朝网络
var

王朝网络
colIndex:integer;

王朝网络
begin

王朝网络
//注意:要影響性能

王朝网络
//lvTemp.Items.BeginUpdate();

王朝网络
Result := false;

王朝网络
if NOT (Assigned(pData) and Assigned(lvTemp) and Assigned(lvDataList) and (lvDataList.Count > 0)) then Exit;

王朝网络
colIndex := GetListDataIndexByKey(lvDataList,aKey);

王朝网络
if (colIndex <> SpecialItemOrder) and (colIndex >= 0) and (colIndex <= lvDataList.Count - 1) then

王朝网络
begin

王朝网络
Dispose(lvDataList[colIndex]);

王朝网络
lvDataList.Delete(colIndex);

王朝网络
Result := true;

王朝网络
end;

王朝网络
//注意:要影響性能

王朝网络
//lvTemp.Items.Count := lvList.Count;

王朝网络
//lvTemp.Items.EndUpdate();

王朝网络
end;

王朝网络

王朝网络
destructor TLVQuickClass.Destroy;

王朝网络
begin

王朝网络
ClearLVDataList();

王朝网络
if Assigned(lvDataList) then

王朝网络
FreeAndNil(lvDataList);

王朝网络
if Assigned(cxxLVC) then

王朝网络
FreeAndNil(cxxLVC);

王朝网络
//if Assigned(tmpList) then

王朝网络
// FreeAndNil(tmpList);

王朝网络
inherited Destroy;

王朝网络
end;

王朝网络

王朝网络
class function TLVQuickClass.GetListDataIndexByKey(const listData: TList;

王朝网络
const aKey: variant): integer;

王朝网络
var

王朝网络
Loop:integer;

王朝网络
begin

王朝网络
Result := SpecialItemOrder;

王朝网络
if NOT Assigned(listData) then Exit;

王朝网络
if listData.Count <= 0 then Exit;

王朝网络
for Loop := 0 to listData.Count - 1 do

王朝网络
begin

王朝网络
if CheckFound(listData[Loop],aKey) then

王朝网络
begin

王朝网络
Result := Loop;

王朝网络

break;

王朝网络
end;

王朝网络
end;

王朝网络
end;

王朝网络

王朝网络
function TLVQuickClass.GetLVListCount(): integer;

王朝网络
begin

王朝网络
Result := 0;

王朝网络
if Assigned(lvDataList) then

王朝网络
Result := lvDataList.Count;

王朝网络
end;

王朝网络

王朝网络
function TLVQuickClass.InitListViewColumns(const displayName: array of string;

王朝网络
const displayWidth: array of integer; var lvTemp: TListView): boolean;

王朝网络
begin

王朝网络
Result := false;

王朝网络
if Assigned(cxxLVC) then

王朝网络
begin

王朝网络
cxxLVC.InitLVColumns(displayName,displayWidth,lvTemp);

王朝网络
end;

王朝网络
end;

王朝网络

王朝网络
procedure TLVQuickClass.OnDataToListView(var Item: TListItem);

王朝网络
var

王朝网络
pTemp:Pointer;

王朝网络
begin

王朝网络
//以後要移到類中,做成回調

王朝网络
if NOT Assigned(lvDataList) then Exit;

王朝网络
if lvDataList.Count <= 0 then Exit;

王朝网络
if Item.Index > lvDataList.Count then Exit;

王朝网络

王朝网络
pTemp := lvDataList[Item.Index];

王朝网络
ProcOnDataDetail(pTemp,Item);

王朝网络

王朝网络
Item.ImageIndex := 1;

王朝网络
Item.Data := pTemp;

王朝网络
end;

王朝网络

王朝网络
function TLVQuickClass.UpdateItemDataToListView(const aKey: variant;

王朝网络
const pData: Pointer; const dataNumber: integer; var lvTemp: TListView):boolean;

王朝网络
//var lvList: TList):boolean;

王朝网络
var

王朝网络
colIndex:integer;

王朝网络
begin

王朝网络
//注意:要影響性能

王朝网络
//lvTemp.Items.BeginUpdate();

王朝网络
Result := false;

王朝网络
if NOT (Assigned(pData) and Assigned(lvTemp) and Assigned(lvDataList) and (lvDataList.Count > 0)) then Exit;

王朝网络
colIndex := GetListDataIndexByKey(lvDataList,aKey);

王朝网络
if (colIndex <> SpecialItemOrder) and (colIndex >= 0) and (colIndex <= lvDataList.Count - 1) then

王朝网络
begin

王朝网络
CopyMemory(lvDataList[colIndex],pData,dataNumber);

王朝网络
Result := true;

王朝网络
end;

王朝网络
//注意:要影響性能

王朝网络
//lvTemp.Items.Count := lvList.Count;

王朝网络
//lvTemp.Items.EndUpdate();

王朝网络
end;

王朝网络

王朝网络
end.

王朝网络
//------------------------------------------------------------------------------

王朝网络
//

王朝网络
// 産品名稱: 成曉旭的個人軟件Delphi源碼庫

王朝网络
// 産品版本: CXXSoft delphi code source lib 1.0

王朝网络
// 模塊名稱: Delphi之ListView顯示控制類---應用層:Soft socket類定義單元

王朝网络
// 模塊描述:

王朝网络
// 單元文件: unLVSoftSocket.pas-->unLVSocket.pas

王朝网络
// 開發作者: 成曉旭

王朝网络
// 備注: 任何人使用此文件時,請保留此段自述文件,謝謝!

王朝网络
// 開發時間: 2005-09-26

王朝网络
//

王朝网络
// 修改曆史: 2006-06-16

王朝网络
// 修改描述: 增加通過TList來高速增加、更新、刪除數據

王朝网络
// 先用吧,以後再優化和完善

王朝网络
// 修改曆史: 2006-07-10

王朝网络
// 修改描述: 成功地將ListView的OnData事件的List對象移入此類中

王朝网络
// 修改曆史: 2006-07-11

王朝网络
// 修改描述: 重大重構:將此類分成兩個類:TLVSoftSocket-->TLVSocket和TLVQuickClass

王朝网络
// 以遵循SRP原則

王朝网络
//------------------------------------------------------------------------------

王朝网络
unit unLVSocket;

王朝网络

王朝网络
interface

王朝网络

王朝网络
uses

王朝网络
ComCtrls,Classes,SysUtils,Windows,

王朝网络
unLVCommonClass,unLVDefine;

王朝网络

王朝网络
type

王朝网络
TLVSocket = class(TLVCommonClass)

王朝网络
private

王朝网络
//注意:此方法與順序嚴重藕合

王朝网络
function SaveSerialStatusToStringList(const aSocketStatus:TSocketStatusInfo):boolean;

王朝网络
protected

王朝网络
class function CheckFound(const pData:Pointer;const aKey:variant):boolean;override;

王朝网络
class procedure ProcOnDataDetail(const pData:Pointer;var Item: TListItem);override;

王朝网络
public

王朝网络
constructor Create();

王朝网络
destructor Destroy();override;

王朝网络
procedure InitListView(var lvTemp:TListView);

王朝网络

王朝网络
//傳統方法

王朝网络
procedure AddToLVSocket(const aSocketStatus:TSocketStatusInfo;var lvTemp:TListView);

王朝网络
procedure UpdateLVSocket(const aSocketStatus:TSocketStatusInfo;var lvTemp:TListView);

王朝网络
procedure DeleteLVSocket(const aSocketStatus:TSocketStatusInfo;var lvTemp:TListView);

王朝网络

王朝网络
end;

王朝网络
implementation

王朝网络

王朝网络
王朝网络
...{ TLVSocket }

王朝网络

王朝网络
procedure TLVSocket.AddToLVSocket(

王朝网络
const aSocketStatus: TSocketStatusInfo; var lvTemp: TListView);

王朝网络
begin

王朝网络
if SaveSerialStatusToStringList(aSocketStatus) then

王朝网络
begin

王朝网络
AddDataToListView(tmpList,lvTemp);

王朝网络
end;

王朝网络
end;

王朝网络

王朝网络
class function TLVSocket.CheckFound(const pData: Pointer;

王朝网络
const aKey: variant): boolean;

王朝网络
var

王朝网络
p:^TSocketStatusInfo;

王朝网络
begin

王朝网络
p := pData;

王朝网络
Result := (p.UniqueID = aKey);

王朝网络
end;

王朝网络

王朝网络
constructor TLVSocket.Create;

王朝网络
begin

王朝网络
inherited Create();

王朝网络
end;

王朝网络

王朝网络
procedure TLVSocket.DeleteLVSocket(

王朝网络
const aSocketStatus: TSocketStatusInfo; var lvTemp: TListView);

王朝网络
begin

王朝网络
if SaveSerialStatusToStringList(aSocketStatus) then

王朝网络
begin

王朝网络
DeleteDataFromListView(tmpList,lvTemp);

王朝网络
end;

王朝网络
end;

王朝网络

王朝网络
destructor TLVSocket.Destroy;

王朝网络
begin

王朝网络
inherited Destroy;

王朝网络
end;

王朝网络

王朝网络
procedure TLVSocket.InitListView(var lvTemp: TListView);

王朝网络
begin

王朝网络
InitListViewColumns(SocketStrBuffer,SocketWidthBuffer,lvTemp);

王朝网络
end;

王朝网络

王朝网络
class procedure TLVSocket.ProcOnDataDetail(const pData: Pointer;var Item: TListItem);

王朝网络
var

王朝网络
pSocket:^TSocketStatusInfo;

王朝网络
begin

王朝网络
//這兩個有什麽不同?

王朝网络
//CopyMemory(pSocket,pData,sizeof(TSocketStatusInfo));

王朝网络
pSocket := pData;

王朝网络
Item.Caption := IntToStr(pSocket.GroupID);

王朝网络
Item.SubItems.Add(IntToStr(pSocket.UniqueID));

王朝网络
Item.SubItems.Add(pSocket.IPAddress);

王朝网络
//Item.SubItems.Add(IntToStr(pSocket.CommServerPort));

王朝网络
Item.SubItems.Add(pSocket.SubItemName);

王朝网络
Item.SubItems.Add(pSocket.LoginTime);

王朝网络
Item.SubItems.Add(pSocket.SendNumber);

王朝网络
Item.SubItems.Add(pSocket.RecNumber);

王朝网络
Item.SubItems.Add(pSocket.Remark);

王朝网络
//Item.SubItems.Add(pSocket.IPAddress);

王朝网络
//Item.SubItems.Add(pSocket.IPAddress);

王朝网络
end;

王朝网络

王朝网络
function TLVSocket.SaveSerialStatusToStringList(

王朝网络
const aSocketStatus: TSocketStatusInfo): boolean;

王朝网络
begin

王朝网络
Result := false;

王朝网络
if Assigned(tmpList) then

王朝网络
begin

王朝网络
tmpList.Clear();

王朝网络
tmpList.Add(IntToStr(aSocketStatus.GroupID));

王朝网络
tmpList.Add(IntToStr(aSocketStatus.UniqueID));

王朝网络
tmpList.Add(aSocketStatus.IPAddress);

王朝网络
tmpList.Add(aSocketStatus.SubItemName);

王朝网络
tmpList.Add(aSocketStatus.LoginTime);

王朝网络
tmpList.Add(aSocketStatus.SendNumber);

王朝网络
tmpList.Add(aSocketStatus.RecNumber);

王朝网络
tmpList.Add(IntToStr(CSImg_Running));

王朝网络
Result := true;

王朝网络
end;

王朝网络
end;

王朝网络

王朝网络
procedure TLVSocket.UpdateLVSocket(

王朝网络
const aSocketStatus: TSocketStatusInfo; var lvTemp: TListView);

王朝网络
begin

王朝网络
if SaveSerialStatusToStringList(aSocketStatus) then

王朝网络
begin

王朝网络
UpdateDataFromListView(tmpList,lvTemp);

王朝网络
end;

王朝网络
end;

王朝网络

王朝网络
end.

王朝网络
//------------------------------------------------------------------------------

王朝网络
//

王朝网络
// 産品名稱: 成曉旭的個人軟件Delphi源碼庫

王朝网络
// 産品版本: CXXSoft delphi code source lib 1.0

王朝网络
// 模塊名稱: Delphi之ListView顯示控制類---外部應用層通用類定義單元

王朝网络
// 模塊描述: ListView傳統操作方法類

王朝网络
// 單元文件: unLVCommonClass.pas

王朝网络
// 開發作者: 成曉旭

王朝网络
// 備注: 任何人使用此文件時,請保留此段自述文件,謝謝!

王朝网络
// 開發時間: 2005-09-26

王朝网络
// 修改曆史: 2006-05-31

王朝网络
// 修改描述: 解決GetLVItemOrderByValue()的參數不靈活的問題

王朝网络
// 並解決Method 'Create' hides virtual method of base type 'TComponent'的問題

王朝网络
// 修改曆史: 2006-06-16

王朝网络
// 修改描述: 增加通過TList來高速增加、更新、刪除數據

王朝网络
// 先用吧,以後再優化和完善

王朝网络
// 修改曆史: 2006-07-10

王朝网络
// 修改描述: 成功地將ListView的OnData事件的List對象移入此類中,並將其上移到其類

王朝网络
// 修改曆史: 2006-07-11

王朝网络
// 修改描述: 重大重構:將此類分成兩個類:TLVCommonClass-->TLVCommonClass和TLVQuickClass

王朝网络
// 以遵循SRP原則

王朝网络
//------------------------------------------------------------------------------

王朝网络
unit unLVCommonClass;

王朝网络

王朝网络
interface

王朝网络

王朝网络
uses

王朝网络
SysUtils,Classes,ComCtrls,Windows,Variants,

王朝网络
unLVControler,unLVInterface;

王朝网络

王朝网络
const

王朝网络
SpecialItemOrder = -1;

王朝网络
CSImg_Normal = 0;

王朝网络
CSImg_Running = 1;

王朝网络

王朝网络
GetColumnOrder = 0;

王朝网络
type

王朝网络
TLVCommonClass = class(TInterfacedObject,ILVControllor)

王朝网络
private

王朝网络
cxxLVC:TCXXLVControler;

王朝网络

王朝网络
class function StrIsNumber(const str:PChar):boolean;

王朝网络
function GetLVItemOrderByValue(const lvTemp:TListView;const aKeyValue:string;const columnOrder:integer=SpecialItemOrder):integer;

王朝网络
procedure CommonListItemProcess(const dataList: TStringList;var liTemp:TListItem; const isUpdate: boolean);

王朝网络

王朝网络
protected

王朝网络
//注意:約定最後一項一定是ImageIndex

王朝网络
tmpList:TStringList;

王朝网络
function InitListViewColumns(const displayName: array of string;

王朝网络
const displayWidth: array of integer;

王朝网络
var lvTemp:TListView):boolean;

王朝网络
function AddDataToListView(const dataList:TStringList;var lvTemp:TListView):boolean;

王朝网络
function UpdateDataFromListView(const dataList:TStringList;var lvTemp:TListView):boolean;

王朝网络
//注意:刪除的鍵值默認以SubItem[0]爲標准

王朝网络
function DeleteDataFromListView(const dataList:TStringList;var lvTemp:TListView):boolean;

王朝网络
//子類必須實現

王朝网络
class function CheckFound(const pData:Pointer;const aKey:variant):boolean;virtual; abstract;

王朝网络
class procedure ProcOnDataDetail(const pData:Pointer;var Item: TListItem);virtual; abstract;

王朝网络

王朝网络

王朝网络
public

王朝网络
constructor Create();overload;

王朝网络
destructor Destroy();override;

王朝网络
end;

王朝网络

王朝网络
implementation

王朝网络

王朝网络
王朝网络
...{ TLVCommonClass }

王朝网络

王朝网络
function TLVCommonClass.AddDataToListView(const dataList: TStringList;

王朝网络
var lvTemp: TListView): boolean;

王朝网络
var

王朝网络
liTemp:TListItem;

王朝网络
begin

王朝网络
Result := false;

王朝网络
if dataList.Count > 0 then

王朝网络
begin

王朝网络
lvTemp.Items.BeginUpdate();

王朝网络
liTemp := lvTemp.Items.Add();

王朝网络
CommonListItemProcess(dataList,liTemp,false);

王朝网络
//liTemp.Caption := dataList.Strings[dataIndex];

王朝网络
//Inc(dataIndex);

王朝网络
//while (dataIndex < dataList.Count) do

王朝网络
//begin

王朝网络
// liTemp.SubItems.Add(dataList.Strings[dataIndex]);

王朝网络
// Inc(dataIndex);

王朝网络
//end;

王朝网络
lvTemp.Items.EndUpdate();

王朝网络
Result := true;

王朝网络
end;

王朝网络
end;

王朝网络

王朝网络

王朝网络
procedure TLVCommonClass.CommonListItemProcess(const dataList: TStringList;

王朝网络
var liTemp: TListItem; const isUpdate: boolean);

王朝网络
var

王朝网络
dataIndex:integer;

王朝网络
begin

王朝网络
dataIndex := 0;

王朝网络
liTemp.Caption := dataList.Strings[dataIndex];

王朝网络
Inc(dataIndex);

王朝网络
while (dataIndex < dataList.Count) do

王朝网络
begin

王朝网络
if (dataIndex = dataList.Count - 1) and StrIsNumber(PChar(dataList.Strings[dataIndex])) then

王朝网络
begin

王朝网络
liTemp.ImageIndex := StrToInt(dataList.Strings[dataIndex]);

王朝网络
end

王朝网络
else

王朝网络
begin

王朝网络
if isUpdate then

王朝网络
liTemp.SubItems[dataIndex-1] := dataList.Strings[dataIndex]

王朝网络
else

王朝网络
liTemp.SubItems.Add(dataList.Strings[dataIndex]);

王朝网络
end;

王朝网络
Inc(dataIndex);

王朝网络
end;

王朝网络
end;

王朝网络

王朝网络
constructor TLVCommonClass.Create;

王朝网络
begin

王朝网络
inherited Create();

王朝网络
cxxLVC := TCXXLVControler.Create();

王朝网络
tmpList := TStringList.Create();

王朝网络
end;

王朝网络

王朝网络
function TLVCommonClass.DeleteDataFromListView(

王朝网络
const dataList: TStringList; var lvTemp: TListView): boolean;

王朝网络
var

王朝网络
colIndex:integer;

王朝网络
// liTemp:TListItem;

王朝网络
begin

王朝网络
Result := false;

王朝网络
if dataList.Count > 0 then

王朝网络
begin

王朝网络
colIndex := GetLVItemOrderByValue(lvTemp,dataList.Strings[GetColumnOrder+1],GetColumnOrder);

王朝网络
if (colIndex <> SpecialItemOrder) and Assigned(cxxLVC)then

王朝网络
begin

王朝网络
cxxLVC.DeleteItemByIndex(lvTemp,colIndex);

王朝网络
Result := true;

王朝网络
end;

王朝网络
end;

王朝网络
end;

王朝网络

王朝网络
destructor TLVCommonClass.Destroy;

王朝网络
begin

王朝网络
if Assigned(cxxLVC) then

王朝网络
FreeAndNil(cxxLVC);

王朝网络
if Assigned(tmpList) then

王朝网络
FreeAndNil(tmpList);

王朝网络
inherited Destroy;

王朝网络
end;

王朝网络

王朝网络
function TLVCommonClass.GetLVItemOrderByValue(const lvTemp: TListView;

王朝网络
const aKeyValue: string; const columnOrder: integer): integer;

王朝网络
var

王朝网络
Loop:integer;

王朝网络
isOK:boolean;

王朝网络
begin

王朝网络
Result := SpecialItemOrder;

王朝网络
isOK := false;

王朝网络
for Loop := 0 to lvTemp.Items.Count - 1 do

王朝网络
begin

王朝网络
if columnOrder <> SpecialItemOrder then

王朝网络
begin

王朝网络
if (columnOrder >= 0) and (columnOrder < lvTemp.Columns.Count) then

王朝网络
isOK := (lvTemp.Items[Loop].SubItems[columnOrder] = aKeyValue);

王朝网络
end

王朝网络
else

王朝网络
isOK := (lvTemp.Items[Loop].Caption = aKeyValue);

王朝网络
if isOK then

王朝网络
begin

王朝网络
Result := Loop;

王朝网络

break;

王朝网络
end;

王朝网络
end;

王朝网络
end;

王朝网络

王朝网络
function TLVCommonClass.InitListViewColumns(const displayName: array of string;

王朝网络
const displayWidth: array of integer; var lvTemp: TListView): boolean;

王朝网络
begin

王朝网络
Result := false;

王朝网络
if Assigned(cxxLVC) then

王朝网络
begin

王朝网络
cxxLVC.InitLVColumns(displayName,displayWidth,lvTemp);

王朝网络
end;

王朝网络
end;

王朝网络

王朝网络
class function TLVCommonClass.StrIsNumber(const str: PChar): boolean;

王朝网络
var

王朝网络
p:Char;

王朝网络
i:integer;

王朝网络
function CheckHex(p:Char):boolean;

王朝网络
var

王朝网络
k:Byte;

王朝网络
begin

王朝网络
k := Ord(P);

王朝网络
Result := ((k >= 48) and (k <= 57)) or ((k >= 65) and (k <= 70)) or ((k >= 97) and (k <= 102));

王朝网络
end;

王朝网络
begin

王朝网络
try

王朝网络
Result := false;

王朝网络
for i := 0 to Length(str)-1 do

王朝网络
begin

王朝网络
p := str[i];

王朝网络
Result := CheckHex(p);

王朝网络
if NOT Result then

王朝网络

break;

王朝网络
end;

王朝网络
except

王朝网络
Result := false;

王朝网络
end;

王朝网络
end;

王朝网络

王朝网络
function TLVCommonClass.UpdateDataFromListView(

王朝网络
const dataList: TStringList; var lvTemp: TListView): boolean;

王朝网络
var

王朝网络
colIndex:integer;

王朝网络
liTemp:TListItem;

王朝网络
begin

王朝网络
Result := false;

王朝网络
if dataList.Count > 0 then

王朝网络
begin

王朝网络
colIndex := GetLVItemOrderByValue(lvTemp,dataList.Strings[GetColumnOrder+1],GetColumnOrder);

王朝网络
if (colIndex <> SpecialItemOrder) then

王朝网络
begin

王朝网络
lvTemp.Items.BeginUpdate();

王朝网络
liTemp := lvTemp.Items[colIndex];

王朝网络
CommonListItemProcess(dataList,liTemp,true);

王朝网络
//liTemp.Caption := dataList.Strings[dataIndex];

王朝网络
//Inc(dataIndex);

王朝网络
//while (dataIndex < dataList.Count) do

王朝网络
//begin

王朝网络
// liTemp.SubItems[dataIndex-1] := dataList.Strings[dataIndex];

王朝网络
// Inc(dataIndex);

王朝网络
//end;

王朝网络
lvTemp.Items.EndUpdate();

王朝网络
Result := true;

王朝网络
end;

王朝网络
end;

王朝网络
end;

王朝网络

王朝网络
end.

 
用delphi實現冰河的遠程屏幕操作功能
  分爲服務端和客戶端兩個部分,雖然不是一個完整的delphi工程,但是我們關心的其中有用的代碼,對吧?下面是服務端unit ServerDlg;interfaceusesWindows, Messages, SysUtils, Classes, Graphics, Controls, Form...查看完整版>>用delphi實現冰河的遠程屏幕操作功能
 
Delphi編程實現Ping操作
在Delphi中使用TidIcmpClient控件可以非常簡單的實現圖形界面的Ping!新建一個工程,命名爲PingGUI.dpr,窗口命名爲“frmPing”,加入如下組件: lstReplies: TListBox; ICMP: TIdIcmpClient; Pa...查看完整版>>Delphi編程實現Ping操作
 
delphi編程實現圖像的淡入淺出-C/C++
下面是關鍵代碼,需要引用的單元,自己添加上去就可以~function IntToByte(i:Integer): Byte;begin if i 255 then Result := 255 else if i else Result := i;end;procedure Lightness1(var clip: tbitmap; Amo...查看完整版>>delphi編程實現圖像的淡入淺出-C/C++
 
Delphi中正常窗口的實現
Delphi中正常窗口的實現摘要 在Delphi的VCL庫中,爲了使用以及實現的方便,應用對象Application創建了一個用來處理消息響應的隱藏窗口。而正是這個窗口,使得用VCL開發出來的程序存在著與其他窗口不能正常排列平鋪等...查看完整版>>Delphi中正常窗口的實現
 
Delphi多層應用程序的實現
鄭州電力高等專科學校 馬保立 等 ---- 隨著Internet/intranet的發展,多層應用和分布式瘦客戶數據庫應用程序逐漸得到廣泛應用。在多層應用的開發方式中,Delphi提供了Midas構件,第三方提供了Asta 、Midware等。經過...查看完整版>>Delphi多層應用程序的實現
 
· 臨近國慶,李小璐與女兒在天安門前合影

http://image.wangchao.net.cn/users/...

· 震驚!原來酒駕處罰這麽嚴重

酒駕處罰標准 不要有任何一絲僥幸心理! http://image....

· 把年齡相仿的獅虎熊放一起,誰更厲害?結果出人意料

很多人都想知道獅子、老虎和熊打起來誰最厲害,于是便有好事之人把這三種動物關在一起...