delphi – 如何在线程内更新listview项索引

我正在创建允许多用户登录并在listview中添加详细信息的项目,但我遇到了问题,但首先是我的线程代码与注释实现
type
  TUPDATEAFTERDOWNLOAD = class(TThread)
  private
    FListView: TListView;
    FListViewIdx: Integer;
    FMs: TMemoryStream;
    FURL: String;
    procedure UpdateVisual; // update after download
    function DownloadToStream: Boolean; // download function
    function CheckURL(const URL: Widestring): Boolean;
    // Check if its http url using urlmon
  protected
    procedure Execute; override;
  public
    property URL: String read FURL write FURL;
    property ListView: TListView read FListView write FListView;
    property ListViewIdx: Integer read FListViewIdx write FListViewIdx;
  end;

function TUPDATEAFTERDOWNLOAD.CheckURL(const URL: Widestring): Boolean;
begin
  if IsValidURL(nil,PWideChar(URL),0) = S_OK then
    Result := True
  else
    Result := False;
end;

function TUPDATEAFTERDOWNLOAD.DownloadToStream: Boolean;
var
  aIdHttp: TIdHttp;
begin
  Result := False;
  if CheckURL(URL) = False then
    exit;
  aIdHttp := TIdHttp.Create(nil);
  try
    aIdHttp.Request.UserAgent :=
      'Mozilla/5.0 (Windows NT 6.1; WOW64; rv:12.0) Gecko/20100101 Firefox/12.0';
    aIdHttp.Get(FURL,FMs);
    Result := FMs.Size > 0;
  finally
    aIdHttp.Free;
  end;
end;

// procedure to start adding items then download image then update image to current item index
Procedure TForm1.Add_Item(strCaption: String; ListView: TListView;
  strFile: String; strUniqueID: String);
begin
  With ListView.Items.Add do
  begin
    Caption := '';
    SubItems.Add(strCaption); // subitem 0
    SubItems.AddObject('IMA',TObject(aGif)); // subitem 1
    SubItems.Add(strUniqueID); // subitem 2 // Client id
    SubItems.Add('-'); // subitem 3 // Next User Idx (beside)
    With TUPDATEAFTERDOWNLOAD.Create(False) do
    begin
      FreeOnTerminate := True;
      URL := strFile;
      ListView := ListView1;
      ListViewIdx := ListView1.Items.Count - 1;
      // this for define index of item that just added
      Application.ProcessMessages;
    end;
  end;
end;

procedure TForm1.Button1Click(Sender: TObject);
var
  Strname,image,strUniqueID: String;
begin
  Strname := 'Matrin';
  Add_Item(Strname,ListView1,strUniqueID);
end;

// Execute thread
procedure TUPDATEAFTERDOWNLOAD.Execute;
begin
  FMs := TMemoryStream.Create;
  if DownloadToStream then
  // if download done then start update the visual inside list view
    synchronize(UpdateVisual);
end;

procedure TUPDATEAFTERDOWNLOAD.UpdateVisual;
var
  ResStream: TResourceStream;
  i: Integer;
begin

  FMs.Position := 0;

  begin
    aGif := TGifImage.Create;
    aGif.LoadFromStream(FMs);
    aGif.Transparent := True;
    FListView.Items[FListViewIdx].SubItems.Objects[1] := TObject(aGif);
    if Streamin = True then
    begin
      for i := 0 to ListView.Items.Count - 1 do
        if ListView.Items[i].SubItems[3] = IntToStr(IDCLIENT) then
        begin
          ExchangeItems(ListView,FListViewIdx,0);
        end;
    end;
  end;
  FMs.Free;

end;

当我尝试使用ExchangeItems(ListView,0)时,每一件工作都很好我只会遇到问题;文本交换但总是图像保持在错误的索引,如果有5或10个客户端,我认为我这样做的方式是错过了

忘记添加Exchange项目功能

procedure ExchangeItems(lv: TListView; i,j: Integer);
var
  tempLI: TListItem;
begin
  lv.Items.BeginUpdate;
  try
    tempLI := TListItem.Create(lv.Items);
    tempLI.Assign(lv.Items.Item[i]);
    lv.Items.Item[i].Assign(lv.Items.Item[j]);
    lv.Items.Item[j].Assign(tempLI);
    tempLI.Free;
  finally
    lv.Items.EndUpdate
  end;
end;

更新的信息

我试图将GIF图像移动到TListItem.Data属性,但图像现在显示为空

procedure TFORM1.UpdateVisual(Sender: TObject; AUserData: Pointer; var AImage: TGifImage);
var
 Item: TListItem;
i : integer;
begin
 Item := TListItem(AUserData);

  if ListView1.Items.IndexOf(Item) = -1 then
    Exit;

  Item.Data:= AImage;// iam not sure if this right or wrong
  AImage := nil;

if recorder.Active = True then
      begin
       for i := 0 to ListView1.Items.Count-1
     do if ListView1.Items[i].SubItems[3] = IntToStr(UniqueID)
     then
     begin
     ExchangeItems(ListView1,Item.Index,0);
     ListView1.Invalidate;
     SendCommandWithParams(TCPClient,'Streamin',IntToStr(UniqueID) + Sep);
     end;
   end;
end;

这就是我在listview OnDrawitem事件中使用gif的方式

procedure TFORM1.ListView1DrawItem(Sender: TCustomListView; Item: TListItem;
  Rect: TRect; State: TOwnerDrawState);
Var
  xOff,yOff : Integer;
  R: TRect;
  i : Integer;
  NewRect : TRect;
begin
    // Client image
      NewRect := Rect;
      NewRect.Right  := Sender.Column[0].Width - 4; // for Right Justify
      NewRect.Left   := NewRect.Right  - ImageList1.Width;
      NewRect.Top    := NewRect.Top + 2;
      NewRect.Bottom := NewRect.Bottom;
      Sender.Canvas.StretchDraw( NewRect,TGIFImage( Item.data) );
end;

同样对于gif动画我正在使用计时器重新绘制listview

procedure TFrom1.Timer1Timer(Sender: TObject);
{$j+}
  Const iCount : Cardinal = 0;
{$j-}
begin
  inc(iCount);
  if (iCount * TTimer(Sender).Interval) > 500 then
  begin
    iCount := 0;
  end;
  ListView1.Invalidate; // This is for animation over ListView Canvas
end;

当我向其他客户发送流应该发生的事情时

procedure TFORM1.Streamin;
var
i : integer;
begin
for i := 0 to ListView1.Items.Count-1
    do if ListView1.Items[i].SubItems[3] = Trim(CLIENTID) then
  begin
  R:= listview1.Items[i].Index;
   ExchangeItems( ListView1,R,0);
  end;
   Panel2.Top  := xSelItemTop;
   panel2.Visible := true;
   panelmeter.Visible := True;
end;

我发布了我项目中的所有内容我跟随雷米建议并回答这个问题似乎非常复杂我不能抓住编码中的任何错误希望有人知道怎么了什么

更新

通过使用wininet问题减少但当执行请求太快时问题是从计时器发生的?

更新

创建独立应用程序后,唯一的问题是在交换项目中它通过以下代码更改交换项目有一些错误的索引

procedure ExchangeItems(lv: TListView; ItemFrom,ItemTo: Word);
var
 Source,Target: TListItem;
begin
  lv.Items.BeginUpdate;
  try
 Source := lv.Items[ItemFrom];
 Target := lv.Items.Insert(ItemTo);
 Target.Assign(Source);
 Source.Free;
  finally
    lv.Items.EndUpdate
  end;
end;

它工作得很好,但有时它插入空项目和应用程序中止,直到重新交换发生

更新了mcve

unit Unit1;

interface

uses
  Winapi.Windows,Winapi.Messages,System.SysUtils,System.Variants,System.Classes,Vcl.Graphics,Vcl.Controls,Vcl.Forms,Vcl.Dialogs,Vcl.StdCtrls,Vcl.ComCtrls,Vcl.ExtCtrls,JPEG,Vcl.Imaging.pngimage,GIFImg,GraphUtil,Vcl.ImgList;

type
  TForm1 = class(TForm)
    ListView1: TListView;
    Additem: TButton;
    Exchange: TButton;
    Timer1: TTimer;
    ImageList1: TImageList;
    Panel2: TPanel;
    Shape1: TShape;
    Edit1: TEdit;
    AddToSTringlistFirst: TButton;
    procedure FormCreate(Sender: TObject);
    procedure AdditemClick(Sender: TObject);
    procedure ListView1DrawItem(Sender: TCustomListView; Item: TListItem;
      Rect: TRect; State: TOwnerDrawState);
    procedure Timer1Timer(Sender: TObject);
    procedure ExchangeClick(Sender: TObject);
    procedure AddToSTringlistFirstClick(Sender: TObject);
  private
     namelist: TList;
    { Private declarations }
  public
    { Public declarations }
    procedure Add_Item(strCaption: String; ListView: TListView; strFile: String;
    boolBlink: Boolean; strUniqueID,Currentstatus: string);
    procedure UpdateVisual(Sender: TObject; AUserData: Pointer;
      var AImage: TGifImage);
  end;

    type
  TDownloadUpdateVisualEvent = procedure(Sender: TObject; AUserData: Pointer; var AImage: TGifImage) of object;

  type
  TURLDownload = class(TThread)
  private
    FGif         : TGifImage;
    FOnUpdateVisual: TDownloadUpdateVisualEvent;
    FUserData: Pointer;
    FURL         : String;
    procedure DoUpdateVisual;
  protected
    procedure Execute; override;
  public
  constructor Create(const AUrl: String; AOnUpdateVisual: TDownloadUpdateVisualEvent; AUserData: Pointer); reintroduce;
  end;


  Tcollectlist = class(TObject)
  Name: String;
  icon:string;
  UniqueID : Dword;
  end;

var
  Form1: TForm1;
  xProcessingTime : Boolean = False;
  aGIF : TGifImage;
  jpg : TJPEGImage;
  png : TPngImage;
  Status : string = '-';
  xSelItemLeft   : Integer = 0;
  xSelItemTop    : Integer = 0;
  recorder : Boolean;
  UniqueID : Dword;
  xboolBlink : Boolean = False;
  listMS: TMemoryStream;


implementation

uses wininet;

{$R *.dfm}

{$j+}
  Const boolblink : boolean = false;
  Const Sep = '#$%^&';
{$j-}



constructor TURLDownload.Create(const AUrl: String; AOnUpdateVisual: TDownloadUpdateVisualEvent; AUserData: Pointer);
begin
  inherited Create(False);
  FreeOnTerminate := True;
  FUrl := AUrl;
  FOnUpdateVisual:= AOnUpdateVisual;
  FUserData := AUserData;
end;


procedure ExchangeItems(lv: TListView; ItemFrom,Target: TListItem;
begin
  lv.Items.BeginUpdate;
  try
 Source := lv.Items[ItemFrom];
    Target := lv.Items.Insert(ItemTo);
    Target.Assign(Source);
    Source.Free;
  finally
    lv.Items.EndUpdate
  end;
end;


procedure TForm1.FormCreate(Sender: TObject);
begin
namelist := TList.Create;
  // This is for repaint the ListView and so for the animation
    Timer1.Interval       := 10;
    Timer1.Enabled        := true;

  // This is for enlarge the ListView height
  //   ImageList1.Width      := 50;
  //   ImageList1.Height     := 30;
  With ListView1 do
  begin
    SmallImages    := ImageList1;
    ViewStyle      := vsReport;
    RowSelect      := True;
    ReadOnly       := True;
    OwnerDraw      := True;
    DoubleBuffered := True;
    With Columns.Add do Width := (ImageList1.Width+4)*2; // Caption
    With Columns.Add do Width := ListView1.Width - ListView1.Columns[0].Width;  // 0 Name
  end;
end;

procedure TForm1.ListView1DrawItem(Sender: TCustomListView; Item: TListItem;
  Rect: TRect; State: TOwnerDrawState);
Var
  xOff,yOff : Integer;
  i : Integer;
    R: TRect;
  NewRect : TRect;
begin
  With TListView(Sender).Canvas do
  begin
    if Item.Selected then
    begin
          SetRect(R,Rect.Left,Rect.Top,Rect.Right,Rect.Bottom-( (Rect.Bottom-Rect.Top) div 2 ) );
      SetRect(R,Rect.Bottom-( (Rect.Bottom-Rect.Top) div 2 ),Rect.Bottom );
      Sender.Canvas.Brush.Style := bsClear;
      Sender.Canvas.Pen.Width   := 0;

      //Sender.Canvas.Font.Color  := clBlue;
      //Sender.Canvas.Brush.Color := clYellow;
      //Sender.Canvas.FillRect(Rect);
      Rectangle( Rect.Left,Rect.Top + ImageList1.Height);
    end;
    xSelItemTop    := sender.Top + ImageList1.Height;
    Sender.Canvas.Brush.Style := bsClear;
    // User State Image
     if (Item.SubItems[5] <> '-') then
     begin
      if Panel2.Visible AND (Item.Index = 0) then
     else
     ImageList1.Draw( Sender.Canvas,StrToInt(Item.SubItems[5]) );
      end;
    // User Image
      NewRect := Rect;
      NewRect.Right  := Sender.Column[0].Width - 4; // for Right Justify
      NewRect.Left   := NewRect.Right  - ImageList1.Width;
      NewRect.Top    := NewRect.Top + 2;
      NewRect.Bottom := NewRect.Bottom;
      Sender.Canvas.StretchDraw( NewRect,TGIFImage( Item.data) );

    // Image - Beside User
      if Item.SubItems[4] <> '-' then
      begin
        NewRect := Rect;
        NewRect.Left   := NewRect.Left  + ImageList1.Width; // after StateImage offset
        NewRect.Right  := NewRect.Left  + ImageList1.Width;
        NewRect.Top    := NewRect.Top    + 4;
        NewRect.Bottom := NewRect.Bottom - 4;
        Sender.Canvas.StretchDraw( NewRect,TGIFImage( TListView(Sender).Items[StrToInt(Item.SubItems[4])].SubItems.Objects[1]) );
      end;

    // --- Caption and Text --- //
    xOff := Rect.Left;
    for i := 1 to TListView(sender).Columns.Count-1 do // 1,2,3,4,5,6
    begin
      xOff := xOff + TListView(Sender).Columns[i-1].Width;
      yOff := Rect.Top + ((ImageList1.Height-Canvas.TextHeight('H')) div 2);
      if xboolBlink or ( Item.SubItems[2] = '' )
        then sender.canvas.font.color := clgray
        else sender.canvas.font.color := clred;
      TextOut( xOff,yOff,Item.SubItems[i-1] );
    end;
  end;
end;

procedure TForm1.Timer1Timer(Sender: TObject);
{$j+}
  Const iCount : Cardinal = 0;
{$j-}
begin
  inc(iCount);
  if (iCount * TTimer(Sender).Interval) > 500 then
  begin  // this is for blink text which subitem[2] contains 'blink'
    xboolBlink := NOT xboolBlink;
    iCount := 0;
  end;
  ListView1.Invalidate; // This is for animation over ListView Canvas
end;


procedure parselist(Line: string; var strName,strUniqueID,icon: string);
var
  P,I: Integer;
begin
  I := 0;
  repeat
    P := Pos(Sep,Line);
    if P <> 0 then
    begin
      Inc(I);
      case I of
        1: strName     := Copy(Line,1,P - 1);
        2: strUniqueID := Copy(Line,P - 1);
        3: icon  := Copy(Line,P - 1);
      end;
      Delete(Line,P + Length(Sep) - 1);
    end;
  until (I = 3) or (P = 0) or (Line = '')
end;


procedure TForm1.AdditemClick(Sender: TObject);
var
I : integer;
Line: string;
strName,icon : String;
strSelectedUID : String;
Sl : Tstringlist;
begin
  if ListView1.Selected <> nil
      then strSelectedUID := Listview1.Selected.SubItems[3]
      else strSelectedUID := '';
    listview1.Items.BeginUpdate;
    try
    ListView1.Items.Clear;
finally
    listview1.Items.EndUpdate;
  end;
    if Assigned(listms) then
    SL := TStringList.Create;
    begin
      try
        listms.Position := 0;
        Sl.LoadFromStream(listms);
        for I := 0 to SL.Count -1  do
        begin
            Line := SL.Strings[I];
            parselist(Line,strName,icon);
            boolblink := True;
           Add_Item( strName,icon,boolblink,Status);
        end;
      finally
       Sl.Free
      end;
      listms.Free;

    if strSelectedUID <> '' then
      begin
        for i := 0 to ListView1.Items.Count-1
          do if ListView1.Items[i].SubItems[3] = strSelectedUID
            then Listview1.Items[i].Selected := True;
      end;
    end;
end;


procedure TForm1.AddToSTringlistFirstClick(Sender: TObject);
var
  I: Integer;
  image : string;
  collectlist : Tcollectlist;
  MS: TMemoryStream;
  Sl : Tstringlist;
begin
collectlist := Tcollectlist.Create;
SL := TStringList.Create;
image := edit1.Text;
collectlist.Name := 'Martinloanel';
collectlist.UniqueID :=  StrToint('5555' + intTostr(1));
collectlist.icon := image;
namelist.Add(collectlist);

 try
    // Collect List
    for I := 0 to namelist.Count - 1 do
    begin
      collectlist := Tcollectlist(namelist.Items[I]);
      SL.Add(collectlist.Name + Sep + IntToStr(collectlist.UniqueID) + Sep +  collectlist.icon + Sep);
    end;
// Send List
    for I := 0 to namelist.Count - 1 do
    begin
      collectlist := Tcollectlist(namelist.Items[I]);
      if (SL.Count > 0) then
      begin
        MS := TMemoryStream.Create;
        listms :=  TMemoryStream.Create;
        try
          SL.SaveToStream(MS);
          MS.Position := 0;
          listms.LoadFromStream(MS);

        finally
         MS.Free;
        end;
      end;
    end;
  finally
    Sl.Free
  end;
end;

Procedure TForm1.Add_Item( strCaption: String; ListView : TListView; strFile: String; boolBlink : Boolean; strUniqueID:String; Currentstatus: string);
var
  Item: TListItem;
begin
Currentstatus := Status;
  begin
    Item := ListView1.Items.Add;
    Item.Caption   := '';
    Item.SubItems.Add( strCaption ); // subitem 0
    Item.SubItems.AddObject( 'IMA',nil); // subitem 1
    if boolBlink
      then  Item.SubItems.Add( 'blink' ) // subitem 2
      else  Item.SubItems.Add( '' );     // subitem 2
      Item.SubItems.Add( strUniqueID );                  // subitem 3 // UniqueID
      UniqueID := strToint(strUniqueID);
    Item.SubItems.Add('-');                            // subitem 4 // Next User Idx (beside)
    Item.SubItems.Add(Currentstatus);                              // subitem 5 // StateIdx
    TURLDownload.Create(strFile,UpdateVisual,Item);
    end;
  end;



  procedure TForm1.ExchangeClick(Sender: TObject);
begin
recorder := True;
end;

procedure TURLDownload.DoUpdateVisual;
begin
  if Assigned(FOnUpdateVisual) then
    FOnUpdateVisual(Self,FUserData,FGif);
end;

procedure TURLDownload.Execute;
var
  aMs: TMemoryStream;
  hSession     : HINTERNET;
  hService     : HINTERNET;
  lpBuffer     : array[0..1023] of Byte;
  dwBytesRead  : DWORD;
  dwBytesAvail : DWORD;
  dwTimeOut    : DWORD;
begin
  FGif := TGifImage.Create;
  try
  aMs := TMemoryStream.Create;
  hSession := InternetOpen('anyname',INTERNET_OPEN_TYPE_PRECONFIG,nil,0);
  if not Assigned(hSession) then Exit;
    try
      hService := InternetOpenUrl(hSession,PChar(FUrl),0);
    if hService = nil then
      Exit;
      try
      dwTimeOut := 60000;
      InternetSetOption(hService,INTERNET_OPTION_RECEIVE_TIMEOUT,@dwTimeOut,SizeOf(dwTimeOut));
      if InternetQueryDataAvailable(hService,dwBytesAvail,0) then
      repeat
      if not InternetReadFile(hService,@lpBuffer[0],SizeOf(lpBuffer),dwBytesRead) then
      Break;
      if dwBytesRead <> 0 then
      aMs.WriteBuffer(lpBuffer[0],dwBytesRead);
      until dwBytesRead = 0;
      finally
       InternetCloseHandle(hService);
      end;
      aMs.Position := 0;
      FGif.LoadFromStream(aMs);
      FGif.Transparent := True;
    finally
      aMs.Free;
      InternetCloseHandle(hSession);
    end;
    if Assigned(FOnUpdateVisual) then
    begin
      Synchronize(DoUpdateVisual);
    end;
  finally
    FGif.Free;
  end;
end;




  procedure TForm1.UpdateVisual(Sender: TObject; AUserData: Pointer; var AImage: TGifImage);
var
 Item: TListItem;
i : integer;
begin
 Item := TListItem(AUserData);

  if ListView1.Items.IndexOf(Item) = -1 then
    Exit;

  Item.Data := AImage;
  AImage := nil;

if recorder = True then
      begin
       for i := 0 to ListView1.Items.Count-1
     do if ListView1.Items[i].SubItems[3] = IntToStr(UniqueID)
     then
     begin
     ExchangeItems(ListView1,0);
     ListView1.Invalidate;
     end;
   end;
end;


end.

解决方法

尝试更像这样的东西:
type
  TDownloadImageReadyEvent = procedure(Sender: TObject; AUserData: Pointer; var AImage: TGifImage) of object;

  TDownloadImage = class(TThread)
  private
    FURL: String;
    FGif: TGifImage;
    FOnImageReady: TDownloadImageReadyEvent;
    FUserData: Pointer;
    procedure DoImageReady;
  protected
    procedure Execute; override;
  public
    constructor Create(const AUrl: String; AOnImageReady: TDownloadImageReadyEvent; AUserData: Pointer); reintroduce;
  end;

constructor TDownloadImage.Create(const AUrl: String; AOnImageReady: TDownloadImageReadyEvent; AUserData: Pointer);
begin
  inherited Create(False);
  FreeOnTerminate := True;
  FUrl := AUrl;
  FOnImageReady := AOnImageReady;
  FUserData := AUserData;
end;

procedure TDownloadImage.Execute;
var
  aMs: TMemoryStream;
  aIdHttp: TIdHttp;
begin
  FGif := TGifImage.Create;
  try
    aMs := TMemoryStream.Create;
    try
      aIdHttp := TIdHttp.Create(nil);
      try
        aIdHttp.Request.UserAgent := 'Mozilla/5.0 (Windows NT 6.1; WOW64; rv:12.0) Gecko/20100101 Firefox/12.0';
        aIdHttp.Get(FURL,aMs);
      finally
        aIdHttp.Free;
      end;
      aMs.Position := 0;
      FGif.LoadFromStream(aMs);
      FGif.Transparent := True;
    finally
      aMs.Free;
    end;
    if Assigned(FOnImageReady) then
      Synchronize(DoImageReady);
    end;
  finally
    FGif.Free;
  end;
end;

procedure TDownloadImage.DoImageReady;
begin
  if Assigned(FOnImageReady) then
    FOnImageReady(Self,FGif);
end;
procedure TForm1.Add_Item(const strCaption,strFile,strUniqueID: String);
var
  Item: TListItem;
begin
  Item := ListView1.Items.Add;
  Item.Caption := '';
  Item.SubItems.Add(strCaption); // subitem 0
  Item.SubItems.Add('IMA'); // subitem 1
  Item.SubItems.Add(strUniqueID); // subitem 2 // Client id
  Item.SubItems.Add('-'); // subitem 3 // Next User Idx (beside)
  Item.Data := nil;
  TDownloadImage.Create(strFile,ImageReady,Item);
end;

procedure TForm1.ListView1Deletion(Sender: TObject; Item: TListItem);
begin
  TGifImage(Item.Data).Free;
end;

procedure TForm1.Button1Click(Sender: TObject);
var
  Strname,strUniqueID: String;
begin
  Strname := 'Matrin';
  image := ...;
  strUniqueID := ...;
  Add_Item(Strname,strUniqueID);
end;

procedure TForm1.ImageReady(Sender: TObject; AUserData: Pointer; var AImage: TGifImage);
var
  Item: TListItem;
  i: Integer;
  sClientID: string;
begin
  Item := TListItem(AUserData);

  if ListView1.Items.IndexOf(Item) = -1 then
    Exit;

  Item.Data := AImage;
  AImage := nil;

  if Streamin then
  begin
    sClientID := IntToStr(IDCLIENT);
    for i := 0 to ListView1.Items.Count - 1 do
    begin
      if ListView.Items[i].SubItems[3] = sClientID then
      begin
        ExchangeItems(ListView1,0);
        Exit;
      end;
    end;
  end;
end;

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。

相关推荐


 从网上看到《Delphi API HOOK完全说明》这篇文章,基本上都是大家转来转去,原文出处我已经找不到了。这篇文章写的很不错,但最后部分“PermuteFunction 的终极版本”描述的不太清楚,完全按照该文章代码执行,是不行的。可能是作者故意这样做的?本文最后提供修正后的下载地址。原文如下:一、关于API Hook1.什么是API Hook不知道大家是否还记得,在DO
  从网上看到《Delphi API HOOK完全说明》这篇文章,基本上都是大家转来转去,原文出处我已经找不到了。 这篇文章写的很不错,但最后部分“PermuteFunction 的终极版本”描述的不太清楚,完全按照该文章代码执行,是不行的。需要修改mess.pas中代码才行。其实文中提到的一个结构,代码中并没有使用typePIMAGE_IMPORT_DESCRIPTOR = ^IMA
ffmpeg 是一套强大的开源的多媒体库 一般都是用 c/c++ 调用, 抽空研究了一下该库的最新版 ,把部分api 翻译成了dephi版的 记录一下 地址 ffmpegvcl.zip
32位CPU所含有的寄存器有:4个数据寄存器(EAX、EBX、ECX和EDX)2个变址和指针寄存器(ESI和EDI) 2个指针寄存器(ESP和EBP)6个段寄存器(ES、CS、SS、DS、FS和GS)
1 mov dst, src dst是目的操作数,src是源操作数,指令实现的功能是:将源操作数送到目的操作数中,即:(dst) &lt;--(src) 1.dst和src类型必须匹配,即必须同为字节
有三个API函数可以运行可执行文件WinExec、ShellExecute和CreateProcess。 1.CreateProcess因为使用复杂,比较少用。 2.WinExec主要运行EXE文件。如:WinExec('Notepad.exe Readme.txt', SW_SHOW); 3.ShellExecute不仅可以运行EXE文件,也可以运行已经关联的文件。 首先必须引用shellapi
API原型: Declare Function MoveFileEx& Lib "kernel32" Alias "MoveFileExA" (ByVal lpExistingFileName As String, ByVal lpNewFileName As String, ByVal dwFlags As Long) 参数 类型及说明 lpExistingFileName String,欲移
附带通用控件安装方法: ---------- 基本安装 1、对于单个控件,Componet-->install component..-->PAS或DCU文件-->install; 2、对于带*.dpk文件的控件包,File-->Open(下拉列表框中选*.dpk)-->install即可; 3、对于带*.bpl文件的控件包,Install Packages-->Add-->bpl文件名即可; 4
type   TRec=Record     msg:string;     pic:TMemoryStream; end; procedure TForm2.BitBtn1Click(Sender: TObject); var   ms:TMemoryStream;   Rec1,Rec2:TRec;   cc:tmemorystream;   jpg:TJPEGImage; begin   R
program Project1; { Types and Structures Definition } type   WNDCLASSEX = packed record     cbSize: LongWord;     style: LongWord;     lpfnWndProc: Pointer;     cbClsExtra: Integer;     cbWndExtra: In
   在Windows大行其道的今天,windows界面程序受到广大用户的欢迎。对这些程序的操作不外乎两种,键盘输入控制和鼠标输入控制。有时,对于繁杂 的,或重复性的操作,我们能否通过编制程序来代替手工输入,而用程序来模拟键盘及鼠标的输入呢?答案是肯定的。这主要是通过两个API函数来实现的。      下面以Delphi为例来介绍一下如何实现这两个功能。模拟键盘我们用Keybd_event这个ap
delphi中经常见到以下两种定义 Type TMouseProc = procedure (X,Y:integer); TMouseEvent = procedure (X,Y:integer) of Object; 两者样子差不多但实际意义却不一样, TMouseProc只是单一的函数指针类型; TMouseEvent是对象的函数指针,也就是对象/类的函数/方法 区
Windows 2000/XP和2003等支持一种叫做"服务程序"的东西.程序作为服务启动有以下几个好处:     (1)不用登陆进系统即可运行.     (2)具有SYSTEM特权.所以你在进程管理器里面是无法结束它的.     笔者在2003年为一公司开发机顶盒项目的时候,曾经写过课件上传和媒体服务,下面就介绍一下如何用Delphi7创建一个Service程序.     运行Delphi7,选
方法一: 1.调试delphi 写的服务程序,有这么一个办法。原来每次都是用attach to process方法,很麻烦。并且按照服务线程的执行线路,可能会停不到想要的断点。笨办法是,在procedure TsvcFrm.ServiceExecute(Sender: TService);中想要下断的语句前加个人定胜天的sleep(20000),但实际上这种办法是主观臆测的。可行,没问题。记得大学
Delphi For iOS开发指南(17):让应用程序禁止竖屏(也就是只显示横屏)     最近好多人问,怎么样让Delphi For iOS开发的应用程序禁止竖屏,也就是想让它一直横屏显示,横屏是好,一行可以放好几个控件,表格的话也可以多显示几列,看起来方便。 只要一句代码就可以让Delphi For iOS开发的应用程序禁止竖屏,如下: Application.FormFactor.Orie
一个比较完整的Inno Setup 安装脚本,增加了对ini文件设置的功能,一个安装包常用的功能都具备了。 [Setup] ; 注: AppId的值为单独标识该应用程序。 ; 不要为其他安装程序使用相同的AppId值。 ; (生成新的GUID,点击 工具|在IDE中生成GUID。) AppId={{A9861883-31C5-4324-BD9A-DC3271EEB675} ;程序名 AppName
在Delphi自带的Indy控件中其实是提供了MD2,MD4,MD5对象的,我们可以直接使用它们来完成MD5的签名算法。而不需要再去找其它的DLL或是Pas了。 在Uses单元中引用 IdHashMessageDigest,IdGlobal, IdHash 单元,再写如下代码即可以达到MD5的实现。 示例代码 procedure TForm1.Button1Click(Sender: TObjec
在Delphi 7下要制作系统托盘,只能制作一个比较简单的系统托盘,因为ShellAPI文件定义的TNotifyIconData结构体是比较早的版本。定义如下: 1 2 3 4 5 6 7 8 9 _NOTIFYICONDATAA = record    cbSize: DWORD;    Wnd: HWND;    uID: UINT;    uFlags: UINT;    uCallback
声明: 1. type Name = Existing type; 2. type Name = type Existing type; 3. type Name = (EnumValue1 [=value], EnumValue2 [=value] ...); 4. type Name = Expression1..Expression2; 5. type Name = ^Existing ty