『绝对原创 飞飞』
unit mmslibrarypage;
interface
uses
Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
Dialogs, ImgList, VirtualTrees, ComCtrls, ToolWin, mpToolBar,basicModal,DataModal,
database,myScroll,insertdemon,mysql,newmmsForlibrary;
type
TMMSLibraryForm = class(TPageForm)
mainToolBar: TmpToolBar;
btnNewMMS: TToolButton;
btnDelete: TToolButton;
DataTree: TVirtualStringTree;
ilImages: TImageList;
btnImport: TToolButton;
btn2: TToolButton;
btn3: TToolButton;
btn4: TToolButton;
btn5: TToolButton;
btnExport: TToolButton;
btnRefresh: TToolButton;
procedure FormCreate(Sender: TObject);
procedure btnNewMMSClick(Sender: TObject);
procedure btnDeleteClick(Sender: TObject);
procedure btnImportClick(Sender: TObject);
procedure btnExportClick(Sender: TObject);
procedure FormShow(Sender: TObject);
procedure btnRefreshClick(Sender: TObject);
procedure FormDestroy(Sender: TObject);
procedure DataTreeGetText(Sender: TBaseVirtualTree; Node: PVirtualNode;
Column: TColumnIndex; TextType: TVSTTextType;
var CellText: WideString);
procedure DataTreeInitNode(Sender: TBaseVirtualTree; ParentNode,
Node: PVirtualNode; var InitialStates: TVirtualNodeInitStates);
private
{ Private declarations }
stringlist:TStringList;
public
procedure refreshtree();
end;
procedure GetMMSFromLibrary(dparam: TStringList; mysql_rows: PMYSQL_ROW);
type
PMMSTreeNode=^TMMStreeNode;
//自定义的datatree的结构
TMMStreeNode=record
mmsid:string;
mmstype:string;
mmssmil:string;
mmssize:Integer;
mmssubject:string;
end;
var
MMSLibraryForm: TMMSLibraryForm;
implementation
{$R *.dfm}
procedure TMMSLibraryForm.FormCreate(Sender: TObject);
begin
Self.Font:=Application.MainForm.Font; //保持程序中字体一致
stringlist:=TStringList.Create; //保存要显示的数据
DataTree.NodeDataSize:=SizeOf(TMMStreeNode); //初始化datatree的节点大小
end;
procedure TMMSLibraryForm.FormShow(Sender: TObject);
var
pdbinfo: PDatabaseInfo;
column : TVirtualTreeColumn;
Header : TStrings;
i : Integer;
node : PVirtualNode;
data : PINT;
sql : string;
pnode1 : PMMSTreeNode;
begin
Header:=TStringList.Create;
//添加显示的列名
if trim(Header.Text)='' then
begin
Header.Add('ID');
Header.Add('Type');
Header.Add('Smil 1.0/2.0');
Header.Add('Size(B)');
Header.Add('Subject');
end;
//设置列的显示
for i:=0 to Header.Count-1 do
begin
column:= DataTree.Header.Columns.Add;
column.Text:= Header[I];
column.Width:=dataTree.ClientWidth div 6;
if i=4 then
column.Width:= dataTree.ClientWidth div 3-10;
end;
// 连接数据库,获取指定的数据库(是不是忒简单
)pdbinfo:=currentdatabase.databases.GetByIndex(0);
Refreshtree;
end;
procedure TMMSLibraryForm.refreshtree();
var
sql : string;
begin
DataTree.Clear;
stringlist.Clear;
sql:='select MMS_ID,MMS_Type,MMS_Smil,MMS_Size,MMS_Subject from mmslibrary';
//回调函数:让被调用者调用调用者自身的函数。执行ExeuteSQlQurey时调用了GetMMSFromLibrary
(***********************************************************************************************************
procedure TDatabase.ExeuteSQlQurey(dparam: Pointer; sql: string; callback: TDbDataCallBack);
var
aHandle, db: pmysql;
qresult: PMYSQL_RES;
mysql_rows: PMYSQL_ROW;
iRtn, fcount, i: Integer;
begin
try
aHandle := mysql_init(nil);
//mysql_real_connect(aHandle, nil, nil, nil, nil, 0, nil, 0);
if commonconfig.remotemode = 0 then
db := mysql_real_connect(aHandle, nil, nil, nil, PAnsichar(FCurrentDataBase), 0, nil, 0)
else
db := mysql_real_connect(aHandle, PAnsichar(RHost), PAnsichar(RUser), PAnsichar(RPassword), PAnsichar(FCurrentDataBase), 0, nil, 0);
if db <> nil then
begin
iRtn := mysql.mysql_query(db, Pchar(sql));
if iRtn = 0 then
begin
qresult := mysql.mysql_store_result(db);
if qresult <> nil then
begin
fcount := mysql.mysql_num_rows(qresult);
for i := 0 to fcount - 1 do
begin
mysql_rows := mysql.mysql_fetch_row(qresult);
callback(dparam, mysql_rows);
end;
end;
mysql.mysql_free_result(qresult);
end;
end;
finally
mysql_Close(db);
end;
end;
*************************************************************************************************************)
currentdatabase.ExeuteSQlQurey(stringlist,sql,@GetMMSFromLibrary);
DataTree.RootNodeCount:=stringlist.Count div 5 ; //小技巧啦
DataTree.Refresh;
end;
//daparam即是currentdatabase.ExeuteSQlQurey(stringlist,sql,@GetMMSFromLibrary);中的stringlist,
//即用被调用者的值(mysql_rows )初始化调用者的参数
//这个观点很重要,使用也很广泛和特殊
procedure GetMMSFromLibrary(dparam: TStringList; mysql_rows: PMYSQL_ROW);
begin
dparam.Add(mysql_rows[0]);
dparam.Add(mysql_rows[1]);
dparam.Add(mysql_rows[2]);
dparam.Add(mysql_rows[3]);
dparam.Add(mysql_rows[4]);
end;
procedure TMMSLibraryForm.btnNewMMSClick(Sender: TObject);
begin
NewMMS:=TNewMMS.Create(MMSLibraryForm);
if NewMMS.ShowModal= mrok then
refreshtree;
end;
procedure TMMSLibraryForm.btnDeleteClick(Sender: TObject);
var
node:PVirtualNode;
sql:string;
begin
if DataTree.FocusedNode=nil then Exit;
node:=DataTree.FocusedNode;
sql:='delete from mmslibrary where MMS_ID="'+ stringlist[node.index * 5]+'"';
currentdatabase.ExecuteSqlNoQurey(sql);
RefreshTree;
end;
procedure TMMSLibraryForm.btnImportClick(Sender: TObject);
var
dl:TOpenDialog;
begin
dl.Filter:='eml files|*.eml';
end;
procedure TMMSLibraryForm.btnExportClick(Sender: TObject);
begin
//
end;
procedure TMMSLibraryForm.btnRefreshClick(Sender: TObject);
begin
RefreshTree;
end;
procedure TMMSLibraryForm.FormDestroy(Sender: TObject);
begin
stringlist.Free;
inherited;
end;
procedure TMMSLibraryForm.DataTreeGetText(Sender: TBaseVirtualTree;
Node: PVirtualNode; Column: TColumnIndex; TextType: TVSTTextType;
var CellText: WideString);
var
i:Integer;
begin
//这是关键的步骤:将stringlist和datatree绑定。这个函数的解释如下:
(**********************************************************************************************************
property OnGetText: TVSTGetTextEvent;
Description
This is one of the fundamental string tree events which must always be handled. The string tree will fire this event every time when it needs to know about the text of a specific node and column. This is mainly the case when the node appears in the visible area of the tree view (in other words it is not scrolled out of view) but also on some other occasions, including streaming, drag and drop and calculating the width of the node.
The node text is distinguished between two text types:
Normal text: If TextType is ttNormal return the main node caption for the specified column. Static text: All text that you return when TextType is ttStatic will be displayed right beside the normal text (or left to it if the column's BidiMode is not bdLeftToRight, i.e. the column has right-to-left layout). Static text is used only for informational purposes; it cannot be selected or dragged and if the column is not wide enough to show all text it will not be shortened with an ellipsis (...) as normal text. The string tree will only query for static text if the StringOptions (see TreeOptions) include toShowStaticText. This is off by default. When this event is fired the text parameter will always be initialized with the value of property DefaultText. To handle the event get your node data and then extract the string for the appropriate column and TextType.
Notes
Be sure that your event handler only contains absolutely necessary code. This event will be fired very often - easily a
few hundred times for medium sized trees with some columns defined when the tree is repainted completely.
For example it is far too slow to use Locate() on some Dataset, a database query result or table, and then get the text
from some TField. This may only work with in-memory tables or a client dataset. When you initialize your node data do
some caching and use these cached values to display the data.
************************************************************************************************************)
for i:=0 to stringlist.Count div 5 -1 do
begin
case Column of
0:CellText:=stringlist[node.index * 5];
1:CellText:=stringlist[node.index * 5+1];
2:CellText:=stringlist[node.index * 5+2];
3:CellText:=stringlist[node.index * 5+3];
4:CellText:=stringlist[node.index * 5+4];
end;
end;
end;
//这个函数居然可以不用也可以连数据库,奇怪?
procedure TMMSLibraryForm.DataTreeInitNode(Sender: TBaseVirtualTree;
ParentNode, Node: PVirtualNode;
var InitialStates: TVirtualNodeInitStates);
var
Data: ^Int64;
begin
// Data := Sender.GetNodeData(Node);
// Data^ := Node.Index;
end;
end.