关闭

delphi tips

751人阅读 评论(0) 收藏 举报
  • 屏蔽系统功能键
       当你不需要让用户按Alt+Enter、Ctrl+Alt+Del、Ctrl+Esc等功能键的时候加入以下代码:
    Var
    temp:integer;
    begin
    SystemParametersInfo(Spi_screensaverrunning,1,@temp,0);
    end;
       当你要恢复功能键时用以下代码:
    Var
    Temp:integer;
    begin
    SystemParametersInfo(spi_screensaverrunning,0,@temp,0);
    end;

  • 分行提示
       无论你什么时候要分行显示的时候,只需要在字符串中间加入“#13”就可以了,但在属性框里却不能这么干,以下就几种控件加以说明:
    begin
    Label1.caption :='垂'+#13+'直'+#13+'显'+#13+'示';
    Edit1.Hint :='输入框说明:'+#13+'文本的输入';
    end;


  • 任意打印
       有时我们要打印任意排列的表或往已经印好的登记表上对号入座写上数据时,可以新建一个窗体(假设为Form1),再把Form1的BorderStyle设为bsNone、AutoScroll设为True,接下来再创建一个新窗体(假设为Form2),再建个按钮Button1,编写代码:
    procedure TForm2.Button1Click(Sender: TObject);
    begin
    Form1.Width :=900;
    Form1.Height :=800;
    Form1.Print;
    end;
       接下来你在Form1上对应的位置写上数据,运行后按Button1就会一五一十的打印下来了。


  • 运行时生成控件
       ㈠、运行时生成可视控件:以下以TEdit 控件为例
    1.在Form的Public中定义TEdit控件
      Edit1:TEdit;
    2.在需要生成的地方加入以下代码:
      Edit1:=TEdit.Create(Self);
      Edit1.Parent:=Form1;
      Edit1.Left ?:=20;
      Edit1.Top :=20;
      Edit1.Text :='Edit1 Text';
    3.使用完毕后,释放分配的资源
      if Assigned(Edit1) then Edit1.Free;
      ㈡、运行时生成非可视控件:以下以 TTimer控件为例
    1.在Form的Public中定义TTimert控件
      Timer1:TTimber;
    2.在需要生成的地方加入以下代码:
      Timer1:=TTimer.Create(Self);
      Timer1.OnTimer:=YourAction;
    YourAction是自己定义的OnTimer事件,使用
    procedure TForm1.YourAction(Sender:TObject); 完成
    3.使用完毕后,释放分配的资源
      if Assigned(Timer1) then Timer1.Free;

  • 状态条插入可视控件
       首先,在FROM中放置一个状态条控件Status。调节Status.Panels,在其中插入3个状态条嵌板。把第二个嵌板的参数Style设置成psOwnerDraw。这一点很重要,如果没有这样做,将永远无法显示文字以外的东西。然后在状态条的OnDrawPanel事件中插入一行StatusDrawRect:=rect;以记录参数Style设置成psOwnerDraw的嵌板的坐标。
       第二步,在FROM的Private中申明一个TProgressBar类型的变量Progress。然后在一个菜单的消息响应过程中调用Create方法把它建立起来,再设定状态条为该进程条的父窗口,进而设定进程条的一些必要参数。例如:最大值、最小值、原点坐标、高度和宽度等。
       最后编译一下该程序,你就会发现在状态条中被插入了一个运动着的进程条。
       类似地,你还可以在状态条中插入其他可视控件,如:按键、位图和动画控件等等。
    以下是范例程序:
    type
    TForm1 = class(TForm)//定义一个窗口类
    Status: TStatusBar;
    MainMenu1: TMainMenu;
    file1: TMenuItem;
    insertprocressbar1: TMenuItem;
    N1: TMenuItem;
    exit1: TMenuItem;
    procedure FormCreate(Sender: TObject);
    procedure StatusDrawPanel(StatusBar: TStatusBar; Panel:
    TStatusPanel;const Rect: TRect);
    procedure FormDestroy(Sender: TObject);
    procedure exit1Click(Sender: TObject);
    procedure insertprocressbar1Click(Sender: TObject);
    private
    colorindex : integer; BookOpen:Boolean;
    ssbmp:Tbitmap; progress:TProgressbar;
    StatusDrawRect:TRect; //记录要插入状态条特技的坐标范围
    public
    { Public declarations }
    end;

    var
    Form1: TForm1;
    implementation
    {$R *.DFM}
    procedure TForm1.FormCreate(Sender: TObject);
    begin
    end;

    procedure TForm1.StatusDrawPanel(StatusBar: TStatusBar;
    Panel: TStatusPanel; const Rect: TRect);
    begin
    StatusDrawRect:=rect; //记录要实现状态条特技的坐标范围
    end;

    procedure TForm1.exit1Click(Sender: TObject);
    begin
    close;
    end;

    procedure TForm1.insertprocressbar1Click(Sender: TObject);
    var i,count:integer;
    staPanleWidth:integer;
    begin
    progress:=TProgressbar.create(form1);
    count:=3000; //进程条的最大值
    staPanleWidth:=status.Panels.Items[2].width;
    //由于进程条的很宽,所以需要改变状态条嵌板的宽度,这里先保存它的宽度。
    status.Panels.Items[2].width:=150; // 改变宽度
    status.repaint;
    with progress do
    begin
    top:=StatusDrawRect.top;
    left:=StatusDrawRect.left;
    width:=StatusDrawRect.right-StatusDrawRect.left;
    height:=StatusDrawRect.bottom-StatusDrawRect.top;
    //设定进程条的宽度和高度
    visible:=true;
    try
    Parent := status; //该进程条的拥有者为状态条status
    Min := 0; Max := Count; //进程条的最大和最小值
    Step := 1; //进程条的步长
    for i := 1 to Count do
    Stepit; // 累加进程条
    ShowMessage('现在,进程条将要从内存中被释放');
    finally
    Free; //释放进程条
    end; //try
    end; //with
    status.Panels.Items[2].width:=staPanleWidth; //恢复状态条嵌板的宽度
    end; //begin
    end.

  • 临时路径
       有时需要Windows的临时路径来做备份等工作,那么就要知道路径在哪,下面的程序帮你忙:
    var aa:pchar;
    begin
    GetTempPath(20,aa); //返回路径名
    edit1.text:=aa;
    end;

  • 改计算机名
    改变计算机在网络中的名字,重新启动后才生效
    SetComputerName('Hello World');

  • 控制壁纸
       控制Windows 95的壁纸,以下程序使壁纸变为我们想要的位图,如果THEPCHAR为空,那么就取消壁纸,变为Win默认色彩; 但这种方法只是暂时的,在WINDOWS重新启动后还是原来的位图,这时就需要对WIN.INI文件进行写操作,才能保存住我们改动的图片不被替换。
    var THEPCHAR:pchar;
    begin
    THEPCHAR:='e:/a.bmp';
    SystemParametersInfo(SPI_SETDESKWALLPAPER, 0, THEPCHAR, SPIF_SENDWININICHANGE)
    end;

 

  • 计算字段值
    需要对某字段的所有记录求和,使用如下代码:
    var i:double;
    {$R *.DFM}
    procedure TForm1.Table1CalcFields(dataset: Tdataset);
    var
    Goodsgold:double;
    begin
    Goodsgold:=table1.fieldbyname('金额').asfloat;
    i:=i+Goodsgold;
    label1.caption:=formatfloat('0.00',i);
    end;
    其中的i是求得的总和,在必要时才将他复位为0,要不他总是有增无减。

    • 链接的视觉效果
         要有类似WIN98那样指向字体,该字体就出现下划线,鼠标指针变为一支手指,按下后就打开浏览器或邮件编写器的功能,按下列办法做(该方法只是在前面讲的实现超链接的方法上加入一些效果):先在一个窗体中加入一个Label1,加入下列代码
      procedure TForm1.Label1MouseMove(Sender: TObject;shift:Tshiftstate;x,y:integer);
      begin
      Label1.Font.Style:=[fsbold,fsunderline];
      Label1.Font.Color:=clYellow;
      end;

      procedure TForm1.FormMouseMove(Sender: TObject;shift:Tshiftstate;x,y:integer);
      begin
      Label1.Font.Style:=[fsbold];
      Label1.Font.Color :=clmaroon;
      end;

      procedure TForm1.Label1Click(Sender: TObject);
      begin
      Shellexecute(handle,nil,pchar('mailto:guihong@163.net'),nil,nil,sw_shownormal);
      end;
      再将Label1.Cursor设为crHandPoint,Label1的OnMouseMove事件设为Label1MouseMove, Form1的OnMouseMove事件设为FormMouseMove,Label1的OnClick事件设为Label1Click,那么就这种效果了。

    • 替换指定串函数
         一个替换指定串的函数,从一个字符串中找出指定子串,并替换为另一子串。
      function replacing(S,source,target:string):string;
      var site,StrLen:integer;
      begin
      {source在S中出现的位置}
      site:=pos(source,s);
      {source的长度}
      StrLen:=length(source);
      {删除source字符串}
      delete(s,site,StrLen);
      {插入target字符串到S中}
      insert(target,s,site);
      {返回新串}
      replacing:=s;
      end;

     

    • 程序启动Splash封面
         在启动程序之前出现启动画面的方法多得是,但有些是调用“记时器”来延时的,这种方法有时拖慢了程序的启动速度,下面介绍又一方法,给大家参考对比一下。
         建一个启动封面窗体,假设为Form2,先设置好BorderIcons、BorderStyle、FormStyle、Position,接着在窗体上加入图片框、文本框,设置好后在菜单里选Project里的Options,把Form2从Auto-create forms里转到Available forms。再接着就是按Ctrl+F12键,选Project1,出现工程单元,其内容如下
      ...
      Application.CreateForm(TForm1, Form1);
      Application.Run;
      ..
        在Application.CreateForm(TForm1, Form1); 前加入如下语句:
      form2:=tform2.create(application);
      form2.Show;
      form2.Update;
        然后在Application.Run;前面加入如下语句:
      form2.hide;
      form2.free;

    • 丰富多彩的标签
         如果你不满足于Delphi提供的简单的标签提示,想要在标签中有不同的字体,有不同的颜色来丰富我们的表现能力,而且不用第三方提供的控件的话。那么只要巧妙的利用Delphi自己提供的TRichEdit就可以了。
         首先将TRichEdit控件的边框属性RichEdit1.BorderStyle设为bsNone;同时设置只读属性RichEdit1.ReadOnly为True;然后利用Windows提供的“写字板”之类的软件制作好RichText格式的文本,通过以下语句就可以显示出来了:
      RichEdit1.PlainText:False;
      RichEdit1.Lines.LoadFromFile('c:test.rtf');

      称。首先建立一个popmenu,然后以下的代码就可以告诉你刚才右击的对象名称:
      PopupMenu1.PopupComponent.ClassName

    • 控制INI文件
         要利用.INI文件做程序有关数据的存储工作,就需要能读和写.INI文件,所以列了如下方法给大家参考:
      从.INI文件中获取字符串
      var
      strResult:pchar;
      begin
      GetPrivateProfileString(
      'windows', // []中标题的名字
      'NullPort', // =号前的名字
      'NIL', // 如果没有找到字符串时,返回的默认值
      strResult, //存放取得字符
      100, //取得字符的允许最大长度
      'c:/forwin95/win.ini' // 调用的文件名
      );
      edit1.text:=strResult; //显示取得字符串
      从.INI文件中获取整数
      edit1.text:=inttostr(GetPrivateProfileInt(
      'intl', // []中标题的名字
      'iCountry', // =号前的名字
      0,// 如果没有找到整数时,返回的默认值
      'c:/forwin95/win.ini' // 调用的文件名
      ));
      向.INI文件写入字符串
      WritePrivateProfileString(
      'windows', // []中标题的名字
      'load', // 要写入“=”号前的字符串
      'accca', //要写入的数据
      'c:/forwin95/win.ini' // 调用的文件名
      );
      向.INI文件写入整数
      WritePrivateProfileSection(
      'windows', // []中标题的名字
      'read=100', // 要写入的数据
      'c:/forwin95/win.ini' // 调用的文件名
      );

    • 防止Win95显示严重错误
         不管你的程序如何反复调试,交给用户之后,总有可能发生你意想不到的错误,如何避免Win95显示出白色的窗口,告诉你的用户发生了难堪的意外错误呢?我们可以这样做:
      var
      wOldErrorMode:Word;
      begin
      wOldErrorMode:=SetErrorMode(SEM_FAILCRITICALERRORS);
      try
      finally
      SetErrorMode(wOldErrorMode);
      end;
      end;

     

    • 模拟按键
      让 WIN95 模拟按了一个按键,例如按下 ENTER或者 TAB 键?
      PostMessage(Object.Handle, WM_KEYDOWN, VK_TAB, 0);

    • 隐藏桌面上的图标
      var
      hDesktop : THandle;
      begin
      hDesktop := FindWindow('Progman', nil);
      ShowWindow(hDesktop, SW_HIDE);
      end;

    • 返回程序执行参数
         有关 Delphi 传入应用程式的命令列参数, 请参考以下的说明:
      用ParamCount函数取得命令参数的个数:
      呼叫 ParamStr(0), 传回执行档的档名(含路径)
      呼叫 ParamStr(n), 传回第n个参数的内容
      procedure TForm1.FormCreate(Sender: TObject);
      var
      sFileName: string;
      begin
      if ParamCount > 0 then begin (* 有执行参数传入 *)
      sFileName := ParamStr(1); (* 取得参数内容 *)
      if FileExists(sFileName) then
      Memo1.Lines.LoadFromFile(sFileName)
      else
      Application.MessageBox('找不到指定的档案', '讯息', 48);
      end;
      end;

    • 转让控制权
         有时由于长时间的循环语句占用了cpu的处理权,无法运行 其他程序,照成死循环。这时用以下命令转让控制权,让操作系统处理其他事件。
      Application.ProcessMessages;

    • 关闭Windows
         控制WINDOWS的开关:如关闭WINDOWS,重新启动WINDOWS等, ExitWindowsEx(UINT uFlags,DWORD dwReserved);是实现这一功能的API函数
      首先定义常数
      const
      EWX_FORCE=4; //关闭所有程序并以其他用户身份登录
      EWX_LOGOFF=0; //重新启动计算机并切换到MS-DOS方式
      EWX_REBOOT=2; //重新启动计算机
      EWX_SHUTDOWN=1;//关闭计算机
      运行时给How赋值,让他等于EWX_SHUTDOWN或其他,调用以下语句
      ExitWindowsEx(How,0);

    • 实现超级链接
        在程序中实现打开浏览器,打开邮件程序的功能首先要在uses部分加入
      uses Shellapi;
         接着在需要超级链接的地方使用
      SellExecute(handle,nil,pchar('mailto:shalin@163.net'),nil,nil,sw_shownormal);
         其中pchar()中的mailtos是打开邮件程序的,可以换成http://、ftp://、gopher://、new:、telnet:等多种形式
        

    • 限制FORM的大小
      使用过DELPHI的朋友都会注意到DELPHI本身最上面的窗口,当它极大时只占屏幕的一小部分,它是如何实现的呢,请看下面的说明:
      1)在FORM私有声明部分加上如下一行:
      procedure WMGetMinMaxInfo( var Message:TWMGetMinMaxInfo ); message WM_GETMINMAXINFO;
      2)在声明部分加上如下几行:
      procedure TForm1.WMGetMinMaxInfo( var Message :TWMGetMinMaxInfo );
      begin
      with Message.MinMaxInfo^ do
      begin
      ptMaxSize.X := 200; {最大化时宽度}
      ptMaxSize.Y := 200; {最大化时高度}
      ptMaxPosition.X := 99; {最大化时左上角横坐标}
      ptMaxPosition.Y := 99; {最大化时左上角纵坐标}
      end;
      Message.Result := 0; {告诉Windows你改变了 minmaxinfo}
      inherited;
      end;

    • 动态修改显示器分辨率
      Windows提供给我们两个API函数,可以动态调整显示器的分辨率,他们是EnumDisplaySettings() 和ChangeDisplaySettings(),下面这个例子就是了
      function DynamicResolution(X, Y: word): BOOL;
      var
      lpDevMode: TDeviceMode;
      begin
      Result := EnumDisplaySettings(nil, 0, lpDevMode);
      if Result then
      begin
      lpDevMode.dmFields := DM_PELSWIDTH Or DM_PELSHEIGHT;
      lpDevMode.dmPelsWidth := X;
      lpDevMode.dmPelsHeight := Y;
      Result := ChangeDisplaySettings(lpDevMode, 0) = DISP_CHANGE_SUCCESSFUL;
      end
      end;

      procedure TForm1.Button1Click(Sender: TObject);
      begin
      if DynamicResolution(640, 480) then
      ShowMessage('Now is 640*480');
      end;

      procedure TForm1.Button2Click(Sender: TObject);
      begin
      if DynamicResolution(800, 600) then
      ShowMessage('Now is 800*600');
      end;


    • 回车替Tab下移控件
      需要用回车键代替TAB键下移一个控件时,把KeyPress设为True,加入下列代码拦截击键:
      Procedure TForm1.FormKeyPress(Sender:Tobject;Var Key:Char);
      Begin
       if key=#13 then { 判断是按执行键}
       if not (ActiveControl is TDbgrid) Then
       Begin { 不是在TDbgrid控件内}
        key:=#0;
        perform(WM_NEXTDLGCTL,0,0);{移动到下一个控件}
       end else
       if (ActiveControl is TDbgrid) Then{是在 TDbgrid 控件内}
       begin
        With TDbgrid(ActiveControl) Do
        if Selectedindex<(FieldCount-1) then
        Selectedindex:=Selectedindex+1{ 移动到下一字段}
        else Selectedindex:=0;
       end;
      End;
    • 得到Windows用户名和序列号
      如何得到Windows的用户名称和产品序列号呢?
      1. 可以用 WNetGetUser() 这个函数来得到 user name;
      2. Windows 95 的产品序号可以用 TRegistry 到 Registry Database 中找出来;
      // 取得用户名称
      function GetUserName: AnsiString;
      var
      lpName: PAnsiChar;
      lpUserName: PAnsiChar;
      lpnLength: DWORD;
      begin
      Result := '';
      lpnLength := 0;
      WNetGetUser(nil, nil, lpnLength); // 取得字串长度
      if lpnLength > 0 then
      begin
      GetMem(lpUserName, lpnLength);
      if WNetGetUser(lpName, lpUserName, lpnLength) = NO_ERROR then
      Result := lpUserName;
      FreeMem(lpUserName, lpnLength);
      end;
      end; { GetUserName }

      // 取得 Windows 产品序号
      function GetWindowsProductID: string;
      var
      reg: TRegistry;
      begin
      Result := '';
      reg := TRegistry.Create;
      with reg do
      begin
      RootKey := HKEY_LOCAL_MACHINE;
      OpenKey('Software/Microsoft/Windows/CurrentVersion', False);
      Result := ReadString('ProductID');
      end;
      reg.Free;
      end;

    • 实现打开文件
      打开Windows已经注册的文件其实很简单,根据以下代码定义一个过程:
      procedure URLink(URL:PChar);
      begin
      ShellExecute(0, nil, URL, nil, nil, SW_NORMAL);
      end;
      在要调用的地方使用
      URLink('Readme.txt');
      如果是链接主页的话,那么改用
      URLink('http://gui.yeah.net');

    • 得到执行程序的目录
      SysUtils 单元中有 ExtractFileDir 与 ExtractFilePath两个类似的函数, 用哪一个?没有太大的关系。
      不过有以下的差别: ExtractFilePath 传回值的最後一个字元是反斜杠“/”。
      procedure TForm1.Button1Click(Sender: TObject);
      begin
      ShowMessage(ExtractFileDir(Application.Exename));
      // ie: c:/temp
      ShowMessage(ExtractFilePath(Application.Exename));
      // ie: c:/temp/
      end;
      相同点: 如果执行文件在根目录下(如:C:/SAMPLE.EXE)的话, 两者的传回值相同, 且最后一个字符都是“/”。

    • 将鼠标锁定在一定范围
      如何将鼠标锁定在一定的范围内呢?
      请在Form中放置二个 Button, 然後分别为这两个按钮定义OnClick响应事件如下:
      // 限制
      procedure TForm1.Button1Click(Sender: TObject);
      var
      rtButton2: TRect;
      begin
      rtButton2 := Button2.BoundsRect;
      MapWindowPoints(handle, 0, rtButton2, 2); // 座标换算
      ClipCursor(@rtButton2); // 限制鼠标移动区域
      end;

      // 还原
      procedure TForm1.Button2Click(Sender: TObject);
      var
      rtScreen: TRect;
      begin
      rtScreen := Rect(0, 0, Screen.Width, Screen.Height);
      ClipCursor(@rtScreen);
      end;

      end;
      var
      Form1: TForm1;
      implementation
      {$R *.DFM}
      procedure TForm1.Button1Click(Sender: TObject);
      begin
      Close; // 不可少, 因为已经没有其他方法能关闭此窗口了
      end;

      procedure TForm1.WMNCHitTest(var Msg: TMessage);
      begin
      inherited; // 这样,移动就不可能了...
      Msg.Result := HTCLIENT;
      end;
      end.
    • 获得命令行参数
      1. 取得命令列参数的个数: ParamCount 函数
      2. 呼叫 ParamStr(0), 传回执行档的档名(含路径)
      3. 呼叫 ParamStr(n), 传回第n个参数的内容
      例子:
      procedure TForm1.FormCreate(Sender: TObject);
      var
       ix: integer;
      begin
       Memo1.Lines.Clear;
       if ParamCount = 0 then
        Memo1.Lines.Add('??统??.')
       else
       begin
        Memo1.Lines.Add('档名:' + ParamStr(0));
        for ix := 1 to ParamCount do
        Memo1.Lines.Add(ParamStr(ix));
       end;
      end;
    • 查阅可视窗口标题
      下面只是举出一个例子提供参考:运用API函数GetWindow()配合GetWindowText()逐一查出各视窗的标题
      1. File | New Project 开始一个新的工程
      2. 在 Form1 中安排 Button 与 Memo 各一
      3. 在 Button1 的 OnClick 事件中撰写程式如下:
      procedure TForm1.Button1Click(Sender: TObject);
      var
       hCurrentWindow: HWnd;
       szText: array[0..254] of char;
      begin
       hCurrentWindow := GetWindow(Handle, GW_HWNDFIRST);
       while hCurrentWindow <> 0 do
       begin
       if GetWindowText(hCurrentWindow, @szText, 255)>0 then
       Memo1.Lines.Add(StrPas(@szText));
       hCurrentWindow:=GetWindow(hCurrentWindow, GW_HWNDNEXT);
       end;
      end;
    • 关闭外部应用程序
      如何在 Delphi 应用程序中, 去关闭外部已开启的应用程序?下面给出一段在 Delphi 中关闭“计算器”程序为例:
      var
      HWndCalculator : HWnd;
      begin
      // find the exist calculator window
      HWndCalculator := Winprocs.FindWindow(nil, '计算器'); // close the exist Calculator
      if HWndCalculator <> 0 then
      SendMessage(HWndCalculator, WM_CLOSE, 0, 0);
      end;
    • 程序中使用自定义的鼠标
      一.建立工程与一个资源档用Image Editor编辑一个鼠游标  (Fild | New | Resource File)新建一个 CURSOR_1 的 CURSOR, 设定好它的 Hot Spot(Cursor | Set Hot Spot)存档时注意要和建立的Project存在同一个目录在本例我们先假定为 MyCursor.res
      二. 程序部分
      定义一个常数crMyCursor, 这个常数您必须设成大於零
      的任何整数, 以 LoadCursor() 函数将自订的鼠标资源
      load 进来, 以下为源代码:
      // unit.pas
      unit Unit1;
      interface
      uses
      SysUtils, WinTypes, WinProcs, Messages, Classes,
      Graphics, Controls, Forms, Dialogs;
      const
      crMyCursor = 1; (* 宣告一个常数 *)
      type
      TForm1 = class(TForm)
      procedure FormCreate(Sender: TObject);
      private
      { Private declarations }
      public
      { Public declarations }
      end;
      var
      Form1: TForm1;
      {$R mycursor.res}//这行$R不可少, 否则自订的鼠游标就出不来了
      implementation
      {$R *.DFM}
      procedure TForm1.FormCreate(Sender: TObject);
      begin
      //将鼠标资源 load 进来
      Screen.Cursors[crMyCursor] := LoadCursor (hInstance,'CURSOR_1');
      Cursor := crMyCursor;//指定 form1 的 cursor 为自订鼠标
      Button1.Cursor := crMyCursor;//指定Button1的cursor为自订鼠标
      end;
      end.

0
0

查看评论
* 以上用户言论只代表其个人观点,不代表CSDN网站的观点或立场
    个人资料
    • 访问:2641次
    • 积分:34
    • 等级:
    • 排名:千里之外
    • 原创:0篇
    • 转载:3篇
    • 译文:0篇
    • 评论:1条
    文章分类
    文章存档
    最新评论