delphi2007 教程

delphi2007 教程

首页 新随笔 联系 聚合 管理
  1013 Posts :: 0 Stories :: 28 Comments :: 0 Trackbacks

#

dll动态调用出错了 Delphi / Windows SDK/API
http://www.delphi2007.net/DelphiAPI/html/delphi_20061120120653194.html
我在动态调用dll时老出现如下错误  
      Project'     'raise   too     many   consecutive   exceptions   'access   violation   at   0X00000000:read   of     address   0X0000000'  
   
      调用代码:重要是在Log.dll中包含窗体,通过LoadSearchForm调出窗体  
     
      unit   dlltest;  
   
  interface  
   
  uses  
      Windows,   Messages,   SysUtils,   Variants,   Classes,   Graphics,   Controls,   Forms,  
      Dialogs,   StdCtrls;  
   
  type  
          TForm1   =   class(TForm)  
          Button1:   TButton;  
          procedure   Button1Click(Sender:   TObject);  
      private  
          {   Private   declarations   }  
      public  
          {   Public   declarations   }  
      end;  
  type  
    TLoadSearchForm=procedure   (Handle:Thandle);stdcall;  
  var  
      Form1:   TForm1;  
   
   
  implementation  
   
  {$R   *.dfm}  
   
  procedure   TForm1.Button1Click(Sender:   TObject);  
   
  var  
    handle:Thandle;  
    LoadSearchForm:TLoadSearchForm;  
  begin  
    handle:=Loadlibrary(pchar('Log.dll'));  
    try  
    if   handle<>0   then  
      @LoadSearchForm:=GetProcAddress(handle,pchar('LoadSearchForm'));  
    if   Assigned(@LoadSearchForm)   then  
      begin  
      LoadSearchForm(Application.Handle);  
        end  
      else  
        RaiseLastOSError;  
    finally  
      FreeLibrary(handle);  
    end;  
  end;  
   
  end.

1.改一下你的代码  
   
      ...  
    if   handle<>0   then  
          LoadSearchForm:=GetProcAddress(handle,pchar('LoadSearchForm'));//不用加@  
    if   Assigned(LoadSearchForm)   then   //不用加@  
      ...  
   
  2.贴一下你dll中LoadSearchForm的代码,看看有什么问题

procedure   LoadSearchForm(Handle:THandle);  
   
    begin  
      Application.Handle:=Handle;  
      Form1:=TForm1.Create(nil);  
      try  
        Form1.ShowModal;  
        finally  
        Form1.Close;  
        end;  
    end;  
   
  我在窗体中加了个按钮,写了form.close,  
  是不是写了这个后,点击按钮就不用在调用单元写freelibrary(handle);了

搞不懂,怎么这么多人喜欢把窗体或DELPHI控件的调用写成DLL方式?

搞定被我说中了,  
  为了好用啊,要不然一人写一个,那别人怎么调用我写的东西啊!  
 

结贴,把分都给你吧


文章来源:http://www.delphi2007.net/DelphiAPI/html/delphi_20061120120653194.html
posted @ 2008-11-27 21:11 delphi2007 阅读(255) | 评论 (0)编辑 收藏

跟随鼠标移动的图像 Delphi / Windows SDK/API
http://www.delphi2007.net/DelphiAPI/html/delphi_20061120102940195.html
一个图片跟随鼠标移动,  
  要求是不能用窗体跟随鼠标的方法,只能在屏幕上画图,鼠标移动后,擦除图像,根据新位置在画,  
  高手来

//参考如下代码  
  type  
      TForm1   =   class(TForm)  
          Timer1:   TTimer;  
          Image1:   TImage;  
          procedure   Timer1Timer(Sender:   TObject);  
          procedure   FormCreate(Sender:   TObject);  
          procedure   FormDestroy(Sender:   TObject);  
      private  
          {   Private   declarations   }  
          FRect:   TRect;  
          FBitmap:   TBitmap;  
      public  
          {   Public   declarations   }  
      end;  
   
  var  
      Form1:   TForm1;  
   
  implementation  
   
  {$R   *.dfm}  
   
  procedure   TForm1.Timer1Timer(Sender:   TObject);  
  var  
      vDesktopCanvas:   TCanvas;  
  begin  
      if   (FRect.Left   =   Mouse.CursorPos.X)   and   (FRect.Top   =   Mouse.CursorPos.Y)   then   //   鼠标没有移动  
          Exit;  
   
      vDesktopCanvas   :=   TControlCanvas.Create;  
      with   vDesktopCanvas   do   try  
          Handle   :=   GetWindowDC(GetDesktopWindow);  
          if   FRect.Left   >=   0   then   Draw(FRect.Left,   FRect.Top,   FBitmap);   //   恢复上次屏幕  
          FRect   :=   Bounds(Mouse.CursorPos.X,   Mouse.CursorPos.Y,  
              Image1.Picture.Width,   Image1.Picture.Height);  
          FBitmap.Canvas.CopyRect(FBitmap.Canvas.ClipRect,   vDesktopCanvas,   FRect);   //   保存本次绘制  
   
          Draw(FRect.Left,   FRect.Top,   Image1.Picture.Graphic);  
      finally  
          vDesktopCanvas.Free;  
      end;  
  end;  
   
  procedure   TForm1.FormCreate(Sender:   TObject);  
  begin  
      Timer1.Interval   :=   10;  
      FBitmap   :=   TBitmap.Create;  
      FBitmap.Width   :=   Image1.Picture.Width;  
      FBitmap.Height   :=   Image1.Picture.Height;  
      FRect.Left   :=   -1;  
  end;  
   
  procedure   TForm1.FormDestroy(Sender:   TObject);  
  begin  
      FBitmap.Free;  
  end;  
 

抢分!

伴水占了位置,过来接分。

。。。。。。。


文章来源:http://www.delphi2007.net/DelphiAPI/html/delphi_20061120102940195.html
posted @ 2008-11-27 21:11 delphi2007 阅读(350) | 评论 (0)编辑 收藏

SetWindowsHookEx 怎么能识别 alt 键 Delphi / Windows SDK/API
http://www.delphi2007.net/DelphiAPI/html/delphi_20061120101814196.html
SetWindowsHookEx如何才能监视alt啊?其他案件都能监视,就识别不了alt,怎么弄?

没人知道?

我也不懂啊   LY   有例子~~   找他要~~~~

alt是WM_SYSKEYDOWN事件。你拦截WM_SYSKEYDOWN试试


文章来源:http://www.delphi2007.net/DelphiAPI/html/delphi_20061120101814196.html
posted @ 2008-11-27 21:11 delphi2007 阅读(222) | 评论 (0)编辑 收藏

roundto函数带来的问题 Delphi / Windows SDK/API
http://www.delphi2007.net/DelphiAPI/html/delphi_20061120094828197.html
single类型的四字节浮点数,用roundto(asingle,-2)保留两位小数,这时出现个一个问题,是如果asingle小于或大于一个值的时候,asingle就用科学计数法表示,在用roundto就会有错误,现在想知道这个界限值,怎么判断这个值避免这个问题

能不能避免用科学计数法表示

最好的办法是用FloatToStr,然后再对字符串操作,精度上不会出现xx.xx9999999999这样的情况。

学习;

对付这类问题,比较灵活的办法是自己编程处理。你可以看看roundto的源码  
   
  function   RoundTo(const   AValue:   Double;   const   ADigit:   TRoundToRange):   Double;  
  var  
      LFactor:   Double;  
  begin  
      LFactor   :=   IntPower(10,   ADigit);  
      Result   :=   Round(AValue   /   LFactor)   *   LFactor;  
  end;  
   
  其中intpower   原型:  
  function   intpower(base:float;const   exponent:Integer):float    
  功能:返回base的exponent次方  
   
 

今天起得早,运动完后做下数学题,由于没有相关准确资料,   我用硬代码测试了一下,这个临界值=92233722601930753。(aSingle   >=   临界值则roundto(asingle,-2)出现异常).   希望是正确的。

如果带小数点的话,   临界值   =   92233722601930752.005

roundto   建议少用  
   
  还是用FloatToStr   好用点

我写了个1E15,不管精确度了

1E15小了一些。


文章来源:http://www.delphi2007.net/DelphiAPI/html/delphi_20061120094828197.html
posted @ 2008-11-27 21:11 delphi2007 阅读(229) | 评论 (0)编辑 收藏

怎么自动把窗体显示出来? Delphi / Windows SDK/API
http://www.delphi2007.net/DelphiAPI/html/delphi_20061119181326198.html
当窗体当前没有焦点,或者窗体被最小化了,在该窗体得到某一事件怎么显示窗体呀?让窗体得到焦点。我用以下代码不行:  
  procedure   TForm1.WndProc(var   message:   TMessage);  
  var  
      dataStruct:   PCOPYDATASTRUCT;  
      passingMessage:   PMessage;  
  begin  
      inherited;  
      if   message.Msg   =   WM_COPYDATA   then   begin  
          dataStruct   :=   PCOPYDATASTRUCT(message.LParam);  
          passingMessage   :=   PMessage(dataStruct.lpData);  
          if   (passingMessage^.Msg   =   WM_KEYDOWN)   then   begin  
              //listBox1.Items.Add('message='   +   IntToStr(passingMessage^.WParam));  
              if   (passingMessage^.wParam   =   VK_HOME)   then  
              begin  
                  ShowWindow(self.Handle,   SW_SHOWNORMAL   or   SW_RESTORE);  
                  BringWindowToTop(self.Handle);  
                  SetForegroundWindow(self.Handle);  
              end;  
          end;  
      end;  
  end;  
   
  窗体在任务栏一闪一闪得,就是不提前现实。

试下:  
  ShowWindow(Application.Handle,   SW_SHOWNORMAL   or   SW_RESTORE);

帮顶

试了ShowWindow(Application.Handle,   SW_SHOWNORMAL   or   SW_RESTORE);  
  也是一样,就是不提前显示出来

有用了,我发现如果最小化得时候采用Application.Handle就行了,哈哈,我再试试  
  目前处于别得窗体之后还不行

加上BringWindowToTop和SetForegroundWindow呢?用Application.Handle

我也是都在后面2函数上加上才能在最小化状态把窗体置前得。但是处于别得窗体之后还是不行。不知道怎么回事

不是你想SetForegroundWindow谁就可以SetForegroundWindow谁的。  
   
  (msdn只说win98/me是这样,其实2k/xp也一样)  
  the   system   restricts   which   processes   can   set   the   foreground   window.   A   process   can   set   the   foreground   window   only   if   one   of   the   following   conditions   is   true:    
   
  The   process   is   the   foreground   process.    
  The   process   was   started   by   the   foreground   process.    
  The   process   received   the   last   input   event.    
  There   is   no   foreground   process.    
  The   foreground   process   is   being   debugged.    
  The   foreground   is   not   locked   (see   LockSetForegroundWindow).    
  The   foreground   lock   time-out   has   expired   (see   SPI_GETFOREGROUNDLOCKTIMEOUT   in   SystemParametersInfo).    
  No   menus   are   active.    
  不信可以自己试验,  
  搞一个程序只有:  
  void   __fastcall   TForm1::Timer1Timer(TObject   *Sender)  
  {  
          SetForegroundWindow(Handle);          
  }  
  保存起来,运行它然后把窗体放在后面,这时它只能在任务栏里闪。  
   
  再搞一个程序:  
  void   __fastcall   TForm1::Button1Click(TObject   *Sender)  
  {  
        WinExec("C:\\Documents   and   Settings\\Ray\\桌面\\新建文件夹\\project1.exe",SW_SHOW);//运行上一个程序  
  }  
  这时按Button1就可以调到前面来。

学习接分;;;;;;;;;;;

leonatcs(LeonKennedy)(时常逛一逛csdn,有益身心健康。)    
  真是这样,只在任务栏里闪,但是有没有办法直接掉到前面来?如果不开新进程。因为这个进程要一直开着,比如游戏外挂。我看到别得游戏外挂可以做到。

谢谢


文章来源:http://www.delphi2007.net/DelphiAPI/html/delphi_20061119181326198.html
posted @ 2008-11-27 21:11 delphi2007 阅读(258) | 评论 (0)编辑 收藏

HOOK其它程序窗体按键 Delphi / Windows SDK/API
http://www.delphi2007.net/DelphiAPI/html/delphi_20061118224824199.html
unit   Unit1;  
   
  interface  
   
  uses  
      Windows,   Messages,   SysUtils,   Variants,   Classes,   Graphics,   Controls,   Forms,  
      Dialogs,   StdCtrls;  
   
  type  
      TForm1   =   class(TForm)  
          Edit1:   TEdit;  
          ButtonHook:   TButton;  
          ButtonUnhook:   TButton;  
          Label1:   TLabel;  
          Memo1:   TMemo;  
          procedure   ButtonHookClick(Sender:   TObject);  
          procedure   ButtonUnhookClick(Sender:   TObject);  
      private  
          {   Private   declarations   }  
      public  
          {   Public   declarations   }  
      end;  
   
  var  
      Form1:   TForm1;  
      hookHandle:   HHook;  
   
  function   KeyboardCallback(code,   wParam,   lParam:   Integer):   HRESULT;   stdcall;  
   
  implementation  
   
  {$R   *.dfm}  
   
  procedure   TForm1.ButtonHookClick(Sender:   TObject);  
  var  
      threadId:   Integer;  
  begin  
      threadId   :=   StrToInt(edit1.Text);  
      hookHandle   :=   SetWindowsHookEx(WH_KEYBOARD,   @KeyboardCallback,   HInstance,   threadId);  
      if   (hookHandle   =   0)   then  
          ShowMessage('hook   error');  
  end;  
   
  procedure   TForm1.ButtonUnhookClick(Sender:   TObject);  
  begin  
      if   (hookHandle   <>   0)   then   begin  
          UnhookWindowsHookEx(hookHandle);  
          hookHandle   :=   0;  
      end;  
  end;  
   
  function   KeyboardCallback(code,   wParam,   lParam:   Integer):   HRESULT;   stdcall;  
  begin  
      if   wParam   =   WM_KEYDOWN   then   begin  
          if   lParam   =   VK_F1   then   begin  
              Form1.Memo1.Text   :=   'okokok';  
          end;  
      end;  
      Result   :=   CallNextHookEx(hookHandle,   code,   wParam,   lParam);  
  end;  
   
  end.  
  =====================  
  以上是我得代码,晕死,搞了1天没搞明白,进行了HOOK之后在被HOOK窗体按F1就提示程序错误。哪位高手给个代码呀?

我不想搞出个DLL得方法,想使用一个文件。

不用DLL要钩住其他程序的按键,只能用日志钩子。  
  具体用法请看这里:  
  blog.csdn.net/linzhengqun  
  找钩子及其应用。

hookHandle   :=   SetWindowsHookEx(WH_KEYBOARD,   @KeyboardCallback,   HInstance,   threadId);  
  这一行代码,用了HInstance,后面一个参数就要设置为0   ,如果后面一个参数设置为险程ID,那么前一个参数就要设置成0  
   
  下面是正确的  
  hookHandle   :=   SetWindowsHookEx(WH_KEYBOARD,   @KeyboardCallback,   0,   GetCurrentThreadID);  
  hookHandle   :=   SetWindowsHookEx(WH_KEYBOARD,   @KeyboardCallback,   HInstance,   0);

上面的可能还有点不清楚,帮助里面是这么说的  
  hMod  
   
  Identifies   the   DLL   containing   the   hook   procedure   pointed   to   by   the   lpfn   parameter.   The   hMod   parameter   must   be   set   to   NULL   if   the   dwThreadId   parameter   specifies   a   thread   created   by   the   current   process   and   if   the   hook   procedure   is   within   the   code   associated   with   the   current   process.    
   
  dwThreadId  
   
  Specifies   the   identifier   of   the   thread   with   which   the   hook   procedure   is   to   be   associated.   If   this   parameter   is   zero,   the   hook   procedure   is   associated   with   all   existing   threads.


文章来源:http://www.delphi2007.net/DelphiAPI/html/delphi_20061118224824199.html
posted @ 2008-11-27 21:11 delphi2007 阅读(227) | 评论 (0)编辑 收藏

Delphi中调用SelectDirectory弹出的浏览文件夹的对话框为何总是在右下角 Delphi / Windows SDK/API
http://www.delphi2007.net/DelphiAPI/html/delphi_20061118203649200.html
Delphi中调用SelectDirectory弹出的浏览文件夹的对话框为何总是在右下角?不会是Delphi封装的bug吧,请高手指点如何简单的控制位置

http://topic.csdn.net/t/20021115/21/1180989.html

看看


文章来源:http://www.delphi2007.net/DelphiAPI/html/delphi_20061118203649200.html
posted @ 2008-11-27 21:11 delphi2007 阅读(738) | 评论 (0)编辑 收藏

编译通过,可是运行时报错!!! VCL组件开发及应用
http://www.delphi2007.net/DelphiVCL/html/delphi_20061224154701151.html
大家帮忙看看,这个错误提示是什么意思?  
   
  Error   reading   PrintDBGridEh1.PageFooter.TitleFont.Charset:Property   TitleFont   does   not   exist.  
   
 

这个可能是读取了以前存储的文件,而控件版本不一致引起的。

你打开的是别人写的程序吧,或者重装机器了?  
  将字体重新设置一下应该就没有问题了。

对,别人以前是在2000下编译的,我是在winxp下编译的。

字体重新设置?

问题已经解决了,原来他用的是默认字体,我把他改成GB2312就行了。谢谢heluqing(鉴之小河〖挣大钱娶美女〗)(越来越硬)   提醒了一下。

posted @ 2008-11-18 14:34 delphi2007 阅读(180) | 评论 (0)编辑 收藏

移动窗体时,如何实时行到窗体的位置 VCL组件开发及应用
http://www.delphi2007.net/DelphiVCL/html/delphi_20061224150251152.html
procedure   Tfrm_Design.WMNCHitTest(var   Msg:   TMessage);  
  begin  
      Caption:=IntToStr(Self.Left);  
      inherited;  
  end;  
   
  获得了WM_NCHITTEST消息,但只是在移动结束后才行到,想在移动的过程中实时得到位置,应该用什么消息???

procedure   OnMoving(var   Msg:   TWMMoving);   message   WM_MOVING;  
   
  ..........  
   
  procedure   TFormDemo.OnMoving(var   Msg:   TWMMoving);  
  begin  
      Caption   :=   IntToStr(msg.lpRect^.Left);  
      inherited;  
  end;

更详细的内容(上下左右)  
   
  Caption   :=   IntToStr(msg.lpRect^.Left)+':'+  
                        IntToStr(msg.lpRect^.Top)+':'+  
                        IntToStr(msg.lpRect^.Right)+':'+  
                        IntToStr(msg.lpRect^.Bottom);

posted @ 2008-11-18 14:34 delphi2007 阅读(168) | 评论 (0)编辑 收藏

我的table有一备注型字段,我现在能在Dbrid中显示这字段,但是不能在Dbgrid上编辑,如何才能编辑该字段? VCL组件开发及应用
http://www.delphi2007.net/DelphiVCL/html/delphi_20061224133933153.html
我的table有一备注型字段,我现在能在Dbrid中显示这字段,但是不能在Dbgrid上编辑,如何才能编辑该字段?

用一个TDBMemo编辑组件。

上面的方法很简单。   也可以在DBGRID中编辑,但要写点代码,修改一下DBGRID  
   
 

点击DBgrid对应的列出现新窗口,   新窗口上放入DBMEMO控件,跟DMGRID采用同一数据源,这样就可以查看和编辑了

 
  点击DBgrid对应的列出现新窗口,   新窗口上放入DBMEMO控件,跟DMGRID采用同一数据源,这样就可以查看和编辑了  
   
  楼上的?“点击DBgrid对应的列出现新窗口”,点击如何会出来新窗口啊?

双击DBGRID     from1.show;

posted @ 2008-11-18 14:34 delphi2007 阅读(277) | 评论 (0)编辑 收藏

初来乍到,请多多指教!先请教一个控件问题 VCL组件开发及应用
http://www.delphi2007.net/DelphiVCL/html/delphi_20061224131514154.html
SendMessage(panel2.Handle,LB_SETHORIZONTALEXTENT,   panel2.Width+30,       0);  
  这个方式可以给LISTBOX添加横向滚动条,但是换成PANEL就不行了,为什么,论坛中说是可以的,但是我就是实现不了,请教是什么原因,我用的是DELPHI7,谢谢。  
   
  顺便再问一下,想学习VCL控件开发,有没有比较合适的书籍?

TPanel应该没有处理LB_SETHORIZONTALEXTENT这条消息的HANDLER吧。这条消息是专门针对LISTBOX的。   看前缀LB_就是这个意思了。但是SendMessage(panel2.Handle,LB_SETHORIZONTALEXTENT,   panel2.Width+30,       0);  
  还是可以实现panel2.Width+30的。

TFormDemo   =   class(TForm)  
          Panel:   TPanel;  
          ButtonDemo:   TButton;  
          procedure   FormCreate(Sender:   TObject);  
          procedure   ButtonDemoClick(Sender:   TObject);  
      private  
          OldPanelWndProc:   TWndMethod;  
          procedure   NewPanelWindowProc(var   Message:   TMessage);  
      public  
          {   Public   declarations   }  
      end;  
   
  var  
      FormDemo:   TFormDemo;  
   
  implementation  
   
  {$R   *.dfm}  
   
  procedure   TFormDemo.FormCreate(Sender:   TObject);  
  begin  
      OldPanelWndProc   :=   Panel.WindowProc;  
      Panel.WindowProc   :=   NewPanelWindowProc;  
  end;  
   
  procedure   TFormDemo.NewPanelWindowProc(var   Message:   TMessage);  
  begin  
      if   Message.Msg   =   LB_SETHORIZONTALEXTENT   then  
          Panel.Width   :=   Message.WParam;  
      OldPanelWndProc(Message);  
  end;  
   
  procedure   TFormDemo.ButtonDemoClick(Sender:   TObject);  
  begin  
      SendMessage(Panel.Handle,LB_SETHORIZONTALEXTENT,   Panel.Width+30,   0);  
  end;  
   
 

但是实现归实现,   与LB_SETHORIZONTALEXTENT这条消息没有什么直接的关系啊,   发送这条消息和发送其他的消息没有什么区别的。

谢谢   sanmaotuo(老冯)     的回答,对我帮助很大  
 

问题的点数是不是要像在大富翁里一样分发啊,不知道怎么发:(

posted @ 2008-11-18 14:34 delphi2007 阅读(154) | 评论 (0)编辑 收藏

这个STRING会结果显示什么 ? VCL组件开发及应用
http://www.delphi2007.net/DelphiVCL/html/delphi_20061224123020155.html
procedure   TForm1.Button1Click(Sender:   TObject);  
  var   s:   string[8]   ;  
  begin  
      s[0]   :=   'a'   ;  
      s[1]   :=   'b'   ;  
      s[2]   :=   'c'   ;  
      showmessage(s);  
  end;  
   
  procedure   TForm1.Button1Click(Sender:   TObject);  
  var   s:   string[8]   ;  
  begin  
      s[0]   :=   'a'   ;  
      s[1]   :=   'b'   ;  
      s[2]   :=   'c'   ;  
      s[3]   :=   'd'   ;  
      showmessage(s);  
  end;  
   
   
  初识DELPHI,有点晕

好问题。可能初学DELPHI的都会忽略这个里面的很多内涵。

var   s:   string[8]   ;  
  其内容是从s[1]开始的。  
  s[0]是字符串长度值。

1、S[0]   等同于SetLength(S,   Ord(S[0])   在你的例子中相当于SetLength(S,   97)  
  2、由于你没有对S做初始化,所以你的SHOWMESSAGE(S)会是这样的结果  
        bcd+随机的乱字符,并且显示的字符串长度是97  
 

不要把string   当char   str[x];  
  用

var   s:   shortString   ;  
  begin  
      s[0]   :=   'a'   ;  
      s[1]   :=   'b'   ;  
      showmessage(s)   ;  
      caption   :=   inttostr(length(s))   ;  
  end    
   
  结果相同     长度为97   Ord('a')  
   
  String   结构:AllocationSize|RefCount|Length|B|C|D|#0  
  ShortString   结构:|Length|B|C|D  
   
  不管怎么样   S[0]   都是指向   Length   ;  
   
  还有没有类似的题目,最近在打基础;  
   
  感觉写比较大的商务项目时,可以小心用变量,  
  而不用去了解这些底层,  
  直接用现有的类和结构,开发比较快速;  
  因为这些结构也挺多,挺复杂的;如   Variant   变体类型   ;  
  还有很多第三方控件要学习;  
   
  没有做过整套的软件   ;   不知道接下来要怎么走   ...  
 

我买的书是   D6   开发人员指南   是不是另外有一本D5   开发人员指南更好些;  
  第二章   Object   Pascal语言   就看了好几天了,还是挺难看懂的   ...

不错的帖子。

原来是这样呀,一直以为string[i]实际存放的是string[1..i]的内容。

还没结贴啊~

posted @ 2008-11-18 14:34 delphi2007 阅读(161) | 评论 (0)编辑 收藏

请问如何在Delphi环境下传参数给exe file? VCL组件开发及应用
http://www.delphi2007.net/DelphiVCL/html/delphi_20061224104751156.html
一个已经单独编译好的exe,是否可以在其他exe运行时传参数给它,更改一些值.  
   
  在winexec调用exe时可以实现吗?  
   
  谢谢!

ping   127.0.0.1  
  ping是程序名,   127.0.0.1   是參數名  
  將整個winexec("ping   127.0.0.1")就好了.  
   
 

我所知道的ping是测试网络连通的  
   
  winexec(c:/...exe,default...);//调用exe file.  
   
  winexec的执行格式应该是象上面的这样吧,不知道你写的是什么意思,能否详细解释下,谢谢了

windows.WinExec(PChar('ping       127.0.0.1'),1)   ;  
  用winexec就這麼做.  
 

楼上所说的方法需要在exe中处理cmd参数

說得這麼清楚,樓主還犯糊塗麼

sendmessage可以啊.

可以  
   
  ShellExecute(Self.Handle,'Open','AAA.exe',pChar(sIP),'',SW_SHOWNORMAL);   //sIP   就是传进去的参数  
 

posted @ 2008-11-18 14:34 delphi2007 阅读(306) | 评论 (0)编辑 收藏

像那些付费软件的注册算法一般是用什么算法? VCL组件开发及应用
http://www.delphi2007.net/DelphiVCL/html/delphi_20061224100656157.html
像那些付费软件的注册算法一般是用什么算法?如果我想给我的软件加密,使用那种算法比较好?前辈们给点意见啊

//转贴  
   
  DELPHI程序注册码设计  
     
    当你辛辛苦苦用DELPHI做好了一个你认为十分不错的程序,你是否想把它发布出去成为共享软件呢?   做为一个共享软件,注册码肯定是少不了的,你可以通过判断程序是否注册来进行功能,时间或一些其它限制.现在就介绍一种简单的注册码制造方法.思路是这样的:程序运行时先检测注册表,如果找到注册项,则表明已经注册,如果没有找到注册项,则提示要求注册.    
  <注册例程>  
  在DELPHI下新建一工程,放置Edit1,Edit2,Label1,Label2,Button1组件.具体代码如下:  
  unit   Unit1;  
  interface  
  uses  
  Windows,   Messages,   SysUtils,   Classes,   Graphics,   Controls,   Forms,   Dialogs,  
  StdCtrls,Registry;//在此加上Registry以便调用注册表.  
  type  
  TForm1   =   class(Tform)  
  Button1:   Tbutton;  
  Edit1:   Tedit;  
  Edit2:   Tedit;  
  Label1:   Tlabel;  
  Label2:   Tlabel;  
  procedure   Button1Click(Sender:   Tobject);  
  procedure   FormCreate(Sender:   Tobject);  
  private  
  Function   Check():Boolean;  
  Procedure   CheckReg();  
  Procedure   CreateReg();  
  {   Private   declarations   }  
  public  
  {   Public   declarations   }  
  end;  
  var  
  Form1:   TForm1;  
  Pname:string;   //全局变量,存放用户名和注册码.  
  Ppass:integer;  
  implementation  
  {$R   *.DFM}  
  Procedure   TForm1.CreateReg();//创建用户信息.  
  var   Rego:Tregistry;  
  begin  
  Rego:=Tregistry.Create;  
  Rego.RootKey:=HKEY_USERS;  
  rego.OpenKey('.DEFAULT\Software\AngelSoft\Demo',True);//键名为AngelSoft\Demo,可自行修改.  
  Rego.WriteString('Name',Pname);//写入用户名.  
  Rego.WriteInteger('Pass',Ppass);//写入注册码.  
  Rego.Free;  
  ShowMessage('程序已经注册,谢谢!');  
  CheckReg;   //刷新.  
  end;  
  Procedure   TForm1.CheckReg();//检查程序是否在注册表中注册.  
  var   Rego:Tregistry;  
  begin  
  Rego:=Tregistry.Create;  
  Rego.RootKey:=HKEY_USERS;  
  IF   Rego.OpenKey('.DEFAULT\Software\AngelSoft\Demo',False)   then  
  begin  
  Form1.Caption:='软件已经注册';  
  Button1.Enabled:=false;  
  Label1.Caption:=rego.ReadString('Name');//读用户名.  
  Label2.Caption:=IntToStr(Rego.ReadInteger('Pass'));   //读注册码.  
  rego.Free;  
  end  
  else   Form1.Caption:='软件未注册,请注册';  
  end;  
  Function   TForm1.Check():Boolean;//检查注册码是否正确.  
  var  
  Temp:pchar;  
  Name:string;  
  c:char;  
  I,Long,Pass:integer;  
  begin  
  Pass:=0;  
  Name:=edit1.Text;  
  long:=length(Name);  
  for   I:=1   to   Long   do  
  begin  
  temp:=pchar(copy(Name,I,1));  
  c:=temp^;  
  Pass:=Pass+ord(c);   //将用户名每个字符转换为ASCII码后相加.  
  end;  
  if   StrToInt(Edit2.Text)=pass   then  
  begin  
  Result:=True;  
  Pname:=Name;  
  Ppass:=Pass;  
  end  
  else   Result:=False;  
  end;  
  procedure   TForm1.Button1Click(Sender:   Tobject);  
  begin  
  if   Check   then   CreateReg  
  else   ShowMessage('注册码不正确,无法注册');  
  end;  
  procedure   TForm1.FormCreate(Sender:   Tobject);  
  begin  
  CheckReg;  
  end;  
  end.  
  <注册器>  
  在DELPHI下新建一工程,放置Edit1,Edit2,Button1组件.具体代码如下:  
  unit   Unit1;  
  interface  
  uses  
  Windows,   Messages,   SysUtils,   Classes,   Graphics,   Controls,   Forms,   Dialogs,  
  StdCtrls;  
  type  
  TForm1   =   class(Tform)  
  Button1:   Tbutton;  
  Edit1:   Tedit;  
  Edit2:   Tedit;  
  procedure   Button1Click(Sender:   Tobject);  
  private  
  {   Private   declarations   }  
  public  
  {   Public   declarations   }  
  end;  
  var  
  Form1:   TForm1;  
  implementation  
  {$R   *.DFM}  
  procedure   TForm1.Button1Click(Sender:   Tobject);  
  var  
  Temp:pchar;  
  Name:string;  
  c:char;  
  I,Long,Pass:integer;  
  begin  
  Pass:=0;  
  Name:=edit1.Text;  
  long:=length(Name);  
  for   I:=1   to   Long   do  
  begin  
  temp:=pchar(copy(Name,I,1));  
  c:=temp^;  
  Pass:=Pass+ord(c);  
  end;  
  edit2.text:=IntToStr(pass);  
  end;  
  end.  
    从<注册器>中取得注册码,便可在<注册例程>中进行注册.原理是使用ORD函数取得用户名每单个字符的ASCII码值,并进行相加得到注册码.当然,这十分容易并破解,你可以用XOR进行异或操作,或者倒取反值...具体的要看你怎么实现了.总之,本文章只抛砖引玉罢了.  
 

也可以用专门的控件来做  
  Regware

破解只是时间和兴趣的问题  
   
  软件没有写成功之前考虑加密是白搭  
  一个写的差的软件就是开源给别人都没人用  
   
  加密之前提起别人破解的兴趣先

烂软件不加密也没人用,好软件加密了照样破!  
  WinRAR加密足够牛了吧,有几个软件可以做到这个程度的?还不照样被干掉  
  共享软件作者还是提高自己的软件先,别尚未成功就开始防破解,精力用错地方了。

找到的一个:  
   
   
  给你一个,不过是检测注册表中的值进行判断是否已经注册:  
  当然这程序中的注册码是随便写的...  
  procedure   TE_Mainf.FormCreate(Sender:   TObject);  
  var   re_id:   integer;  
      registerTemp:   TRegistry;  
      inputstr,get_id:   string;  
      dy,   clickedok:   boolean;  
      i:   double;  
  label   Y,   N;  
  begin  
      dy   :=   false;//软件是否已到注册期、及是否允许继续使用的标志,当值为FALSE是为允许使用  
      registerTemp   :=   TRegistry.Create;                 //准备使用注册表  
      with   registerTemp   do  
      begin  
          RootKey   :=   HKEY_LOCAL_MACHINE;                 //存放在此根下  
          if   OpenKey('Software\Microsoft\Windows\CurrentVersion\Mark',   True)   then   //   建一目录,存放标志值。当然也可以存放在已存在的目录下。  
          begin  
              if   valueexists('gc_id')   then                     //用gc_id的值作为标志,首先判断其存在否  
              begin  
                  re_id   :=   readinteger('gc_id');                       //读出标志值  
                  if   (re_id   <>   0)   and   (re_id   <>   100)   then     //若标志值为0,则说明已注册     ,若不为0且值不到100,说明虽未注册,但允许使用的次数尚未达到。  
                  begin  
                      re_id   :=   re_id   +   5;         //允许标志的最大值为100,每次加5,则最多只可用20次  
                      writeinteger('gc_id',   re_id);                     //将更新后的标志值写入注册表中  
                      i   :=   (100   -   re_id)   /   5;  
                      if   application.MessageBox(PAnsiChar('您使用的软件没有注册,还有   '   +   floattostr(i)   +   '   次使用次数,现在要注册吗?'),   '提示信息',   mb_yesno   +   mb_iconwarning)   =   idyes   then  
                      begin  
                          if   i   =   0   then  
                              application.Terminate  
                          else  
                              goto   y;  
                      end;  
                  end;  
                  if   re_id   =   0   then   goto   N;  
                  if   re_id   =   100   then   dy   :=   true;                     //若标志值已达到100,则应当注册  
              end  
              else  
                  Writeinteger('gc_id',   5);                                 //建立标志,并置初始标志值  
              re_id   :=   readinteger('gc_id');  
              i   :=   (100   -   re_id)   /   5;  
              if   Application.MessageBox(PAnsiChar('您使用的软件没有注册,还有   '   +   floattostr(i)   +   '   次使用次数,现在要注册吗?'),   '提示信息',   mb_yesno   +   mb_iconwarning)   =   idyes   then  
              begin  
                  if   i   =   0   then  
                      application.Terminate  
                  else  
                      goto   Y;  
              end;  
          end;  
          if   dy   then  
              Y:   begin                                 //若dy值为TRUE,则应提示用户输入注册码,进行注册  
              clickedok   :=   InputQuery('系统提示',   '请输入注册码:',   inputstr);  
              if   clickedok   then  
              begin  
                  get_id   :=   inttostr(83392582   *   2);   //注册码为166785164,够简单的......  
                  if   get_id   =   inputstr   then  
                  begin  
                      Writeinteger('gc_id',   0);         //若输入的注册码正确,则将标志值置为0,即已注册  
                      Application.MessageBox('恭喜你,软件注册成功!',   '提示',   MB_OK);  
                      CloseKey;  
                      Free;  
                  end  
                  else  
                  begin  
                      application.messagebox('注册码错误!请与作者联系!',   '警告',   mb_ok   +   mb_iconstop);  
                      CloseKey;  
                      Free;  
                      application.terminate;                                   //中止程序运行,拒绝让其继续使用  
                  end;  
              end  
              else  
              begin  
                  CloseKey;  
                  Free;  
                  application.terminate;                                       //中止程序运行,拒绝让其继续使用  
              end;  
          end;  
      end;  
      N:   datamodule1   :=   tdatamodule1.Create(self);  
      if   not   assigned(E_loginf)   then  
          E_loginf   :=   tE_loginf.Create(self);  
      E_loginf.ShowModal;  
      if   E_loginf.ModalResult   =   mrCancel   then//检查返回模式,如果是关闭或是取消,则中止运行  
      begin  
              Application.Terminate;  
              exit;  
      end;  
  不知有没达到你要求~~  
 

楼主,好像这个问题没固定的答案.  
  每个人都可以想个算法.

同意4星

呵呵,还有硬件加密狗可以加密的.

算法自然越私有越好了  
  不然别人直接根据公开算法就算出来,你的加密就没啥意义了

posted @ 2008-11-18 14:34 delphi2007 阅读(168) | 评论 (0)编辑 收藏

关于TTreeView添加节点的函数 VCL组件开发及应用
http://www.delphi2007.net/DelphiVCL/html/delphi_20061224095004158.html
procedure   TForm1.FindLeechDom(Leechdomname:   String;node:   TTreeNode);  
  var  
      temp:   TQuery;  
      node1:   TTreeNode;  
  begin  
      Try  
          temp   :=   TQuery.Create(Self);  
          temp.DatabaseName   :=   ExtractFilePath(Application.ExeName);  
          With   temp   do  
          begin  
              Close;  
              SQL.Clear;  
              SQL.Add('select   *   from   leechdom.db   where   上级编码   =   :Value');  
              ParamByName('value').AsString   :=   Leechdomname;  
              Open;  
          end;  
          while   Not   Temp.Eof   do  
          begin  
              node1   :=   TreeView1.Items.AddChild(node,temp.FieldByName('药品类别').AsString);  
              FindLeechDom(temp.FieldByName('药品类别').AsString,node1);  
              temp.Next;  
          end;  
      Finally  
          temp.Free;  
      end;  
  end;  
   
   
  为什么在FindLeechDom函数的声明里还能用FindLeechDom这个函数呢?  
  我都看不懂这段程序是什么意思?有没有高手解释一下??  
 

递归调用

谁能给我解释一下啊??  
   
  谢谢了

很明显递归调用

解释一下,这个程序好吗??  
   
  看不懂。

递归

。。。递归调用。。要看基础。

这是一个递归函数,是将数据库中的药品项目全部罗列出来了!  
  例如:1、外科类-分5种药,每种还可以再分N种,依次分下去。层次是不固定的,但是每个项目都有一个对应的父项目。最顶层的没有父项目

连递归都不懂,还做程序,趁早改行

递归  
   
   
  不过这样递归不好,  
  应该一次把数据取出来,  
  对本地DataSet遍历进行递归

procedure   TForm1.FindLeechDom(Leechdomname:   String;node:   TTreeNode);  
  var  
      temp:   TQuery;  
      node1:   TTreeNode;  
  begin  
      Try  
          temp   :=   TQuery.Create(Self);  
          temp.DatabaseName   :=   ExtractFilePath(Application.ExeName);  
          With   temp   do  
          begin  
              Close;  
              SQL.Clear;  
              SQL.Add('select   *   from   leechdom.db   where   上级编码   =   :Value');  
              ParamByName('value').AsString   :=   Leechdomname;  
              Open;  
          end;  
          while   Not   Temp.Eof   do  
          begin  
              node1   :=   TreeView1.Items.AddChild(node,temp.FieldByName('药品类别').AsString);  
              FindLeechDom(temp.FieldByName('药品类别').AsString,node1);   //添加当前node1的子节点  
              temp.Next;  
          end;  
      Finally  
          temp.Free;  
      end;  
  end;

posted @ 2008-11-18 14:34 delphi2007 阅读(277) | 评论 (0)编辑 收藏

……OleContainer中嵌入WORD后,用什么办法显示滚动条???…… VCL组件开发及应用
http://www.delphi2007.net/DelphiVCL/html/delphi_20061224024201159.html
如题,谢谢

同时保持原有左边窗口不变!

放一个ScrollBox,然后把OLE放上去.

OleContainer1.CreateObjectFromFile(Edit1.Text,   False);  
      OleContainer1.DoVerb(ovPrimary);

posted @ 2008-11-18 14:34 delphi2007 阅读(1586) | 评论 (0)编辑 收藏

Timer控制问题 VCL组件开发及应用
http://www.delphi2007.net/DelphiVCL/html/delphi_20061223220551160.html
现有2个过程A和B,A使用Timer控制每隔一定时间T执行一次,执行完成以后再执行B过程,如果B执行时间超过A的时间间隔T,这时Timer执行A的定时到了,程序会怎么处理?有没有其它好的方法去控制?线程吗

哈,进入Timer就enabled   :=   False;   B执行完了再True.

//会出现冲突  
  //建议判断一下是否在处理中  
   
  procedure   TForm1.Timer1Timer(Sender:   TObject);  
  begin  
      if   FRunning   then   Exit;  
      FRunning   :=   True;  
      try  
          A;  
          B;  
      finally  
          FRunning   :=   False;  
      end;  
  end;

楼上的方法也不错,用线程一样会碰到这样的问题

用消息传递来控制执行顺序和时间间隔最适宜

const  
      WM_A   =   WM_User   +   1;  
      WM_B   =   WM_User   +   2;  
   
  type  
      TFormDemo   =   class(TForm)  
          procedure   FormCreate(Sender:   TObject);  
      private  
          FTickCount:   LongInt;  
          procedure   A(var   Msg:   TMessage);   Message   WM_A;  
          procedure   B(var   Msg:   TMessage);   Message   WM_B;  
      public  
          {   Public   declarations   }  
      end;  
   
  var  
      FormDemo:   TFormDemo;  
   
  implementation  
   
  {$R   *.dfm}  
   
  {   TFormDemo   }  
   
  procedure   TFormDemo.FormCreate(Sender:   TObject);  
  begin  
      PostMessage(Handle,   WM_A,   0,   0);  
  end;  
   
  procedure   TFormDemo.A(var   Msg:   TMessage);  
  begin  
      FTickCount   :=   GetTickCount;  
      {ProcessA}  
      PostMessage(Handle,   WM_B,   0,   0);  
  end;  
   
  procedure   TFormDemo.B(var   Msg:   TMessage);  
  var  
      Interval:   Integer;  
  begin  
      {ProcessB}  
      Interval   :=   GetTickCount   -   FTickCount;  
      while   Interval   <   10000   do   //假设A的执行间隔为10秒  
      begin  
          Interval   :=   GetTickCount   -   FTickCount;  
          Application.ProcessMessages;  
      end;  
      postMessage(Handle,   WM_A,   0,   0);  
  end;

我一般是设一个全局变量,A完成后设1.B发现变量为1,则进行下一步,然后再设为2.A发现为2,则下一步.

那就不要用Time来控制,用递归!

我一般是设一个全局变量,A完成后设1.B发现变量为1,则进行下一步,然后再设为2.A发现为2,则下一步.  
  //////////////////////////////////////////////////  
  不牵扯到多线程当然可以这样,你这样做还会有问题吗?应该能够解决了!

posted @ 2008-11-18 14:34 delphi2007 阅读(192) | 评论 (0)编辑 收藏

控件绑定的问题 VCL组件开发及应用
http://www.delphi2007.net/DelphiVCL/html/delphi_20061223191633161.html
我动态创建了TCPServer,ADOonnection,一个socket对应一个数据库连接,想将TCPServer和ADOonnection绑定,  
  如下:  
   
  for   i   :=   0   to   5   do  
  begin  
      ADOConn[i]   :=   TADOConnection.Create(nil);  
      TCPserver[i]   :=   TTCPserver.Create(ADOConn[i]);  
    TCPserver[i].BlockMode   :=   bmThreadBlocking;  
  .......TCPserver和ADOConnection的初始化信息.....  
  end;  
   
  在TcpServerAccept(Sender:   TObject;  
      ClientSocket:   TCustomIpClient);事件中写如下:  
   
  var   ADOCon   :   TADOConnection;  
  begin  
      ADOCon   :=   TADOConnection(sender);  
        while   ClientSocket.ReceiveBuf(Datahead,sizeof(Datahead))>0   do  
          begin  
          ......处理接收到的数据....  
          end  
   
  我在while处理完后,第二次运行到while时,提示地址访问错误。  
   
  我想是我的ADOCon   :=   TADOConnection(sender);不对,但我不知道怎样才对。  
   
  大家帮忙指点一下  
 

我做了以下修正,就可以了:  
  创建部分:  
      ......  
            ADOConn[i]   :=   TADOConnection.Create(nil);  
            ADOConn[i].Tag   :=   i;  
             
            TCPserver[i]   :=   TTCPserver.Create(ADOConn[i]);  
            TCPserver[i].Tag   :=   i;  
    .......  
  接收部分:  
  .....  
          TCPs   :=   TCPserver(sender);  
          ADOC   :=   ADOConn[TCPs.tag];  
   
  OK了。  
  大家进来分分了。  
 

自己解决了  
  JF

关于控件动态邦定、有这方面的经验的各位发发言,我一会结贴。

posted @ 2008-11-18 14:29 delphi2007 阅读(218) | 评论 (0)编辑 收藏

如何屏蔽汉字输入 VCL组件开发及应用
http://www.delphi2007.net/DelphiVCL/html/delphi_20061223175511162.html
请问有没有方法使Tedit不能输入汉字.或者选中该Tedit的时候就filter输入法.

//包括粘贴也会过滤掉  
  procedure   TForm1.Edit1Change(Sender:   TObject);  
  var  
      S:   WideString;  
      I,   J:   Integer;  
      vSelStart:   Integer;  
  begin  
      vSelStart   :=   TEdit(Sender).SelStart;  
      S   :=   TEdit(Sender).Text;  
      J   :=   0;  
      for   I   :=   Length(S)   downto   1   do  
          if   Length(string(S[I]))   >=   2   then  
          begin  
              if   vSelStart   <=   Length(string(Copy(S,   1,   I)))   then   Inc(J,   2);  
              Delete(S,   I,   1);  
          end;  
      TEdit(Sender).Text   :=   S;  
      TEdit(Sender).SelStart   :=   vSelStart   -   J;  
  end;

谢谢zswang.  
  因为工作缘故这几天才学delphie的,以前都是用C.对TEdit(sender)不是很明白.  
  是暂时产生一个对象吗?>?还是就是被触发事件的Tedit.把S声明为Wstring这样对其操作的函数(如Delete)不用改变成支持Wstring的函数吗?  
  其实我是这么想的.用C的话.只要Editchange事件触发,判断新加上去的字符是否是一个字节大小就行了,因为数字和字母都是一个字节.(你觉得怎么样)  
 

Sender就是事件的触发者  
  即:就是被触发事件的TEdit  
  TEdit(Sender)相当于C里的(TEdit   *)Sender  
  其实就是vSelStart   :=   Edit1.SelStart;  
  这样做法更通用一些,不受控件名的限制  
  Length()、Delete()会判断参数中的字符串类型  
   
      for   I   :=   Length(S)   downto   1   do  
          if   S[I]   >   #255   then   //   这样判断更简洁一些  
          begin  
              if   vSelStart   <=   Length(string(Copy(S,   1,   I)))   then   Inc(J,   2);  
              Delete(S,   I,   1);  
          end;  
 

太麻烦了,判断你的输入框里是否是汉字,可以利用,字符串类型,string和widestring的占位,1个是1个字节为单位的,1个是2个字节为单位的  
  function   CheckInputStrIsChinese(Var   S:string):boolean;  
  var  
      Str:Widestring;  
  begin  
        Str:=S;  
        if   length(Str)=2*length(S)   then  
        result:=false     //没有汉字  
   else   result:=true;   //有了!   
  end;

用string和widestring获得的length值是否相同可以判断出text中是否有全角字符,并不能保证只要不符就是有汉字(全角的,   。日本字,韩国字)。  
  但是每字检查ASCII码的范围就可以确切判断是否汉子,但是稍微显得效率不高。  
 

mark

谢谢   zswang   ,也谢谢其他几位觉   得zswang   的蛮好的.  
    winxkm   中的判断:if   length(Str)=2*length(S)   then应该不能满足我的要求.至少用粘贴的话不行.  
  我结贴.

如果明天大家都没有什么新的想法,我就结贴了!谢谢

type  
      TForm1   =   class(TForm)  
          Edit1:   TEdit;  
          procedure   FormCreate(Sender:   TObject);  
      private  
          {   Private   declarations   }  
          OldWndProc:   TWndMethod;  
          procedure   EditWndProc(var   Message:   TMessage);  
      public  
          {   Public   declarations   }  
      end;  
   
  var  
      Form1:   TForm1;  
   
  implementation  
   
  {$R   *.dfm}  
   
  procedure   TForm1.EditWndProc(var   Message:   TMessage);  
  var  
      ch:   Word;  
  begin  
      if   (Message.Msg   =   WM_PASTE)   or   (Message.Msg   =   WM_CUT)  
                  or   ((Message.Msg   =   WM_CHAR)   and   (Message.WParam   >   127))   then    
          Exit;  
      OldWndProc(Message);  
  end;  
   
  procedure   TForm1.FormCreate(Sender:   TObject);  
  begin  
      OldWndProc   :=   Edit1.WindowProc;  
      Edit1.WindowProc   :=   EditWndProc;  
  end;  
 

type  
      TForm1   =   class(TForm)  
          Edit1:   TEdit;  
          procedure   FormCreate(Sender:   TObject);  
      private  
          {   Private   declarations   }  
          OldWndProc:   TWndMethod;  
          procedure   EditWndProc(var   Message:   TMessage);  
      public  
          {   Public   declarations   }  
      end;  
   
  var  
      Form1:   TForm1;  
   
  implementation  
   
  {$R   *.dfm}  
   
  procedure   TForm1.EditWndProc(var   Message:   TMessage);  
  begin  
      if   (Message.Msg   =   WM_PASTE)   or   (Message.Msg   =   WM_CUT)  
                  or   ((Message.Msg   =   WM_CHAR)   and   (Message.WParam   >   127))   then    
          Exit;  
      OldWndProc(Message);  
  end;  
   
  procedure   TForm1.FormCreate(Sender:   TObject);  
  begin  
      OldWndProc   :=   Edit1.WindowProc;  
      Edit1.WindowProc   :=   EditWndProc;  
  end;  
 

真不错.maozefa(阿发伯)子类化窗口过程,我就是用C做window编程的.  
  分不够发了.大家委屈点吧.

posted @ 2008-11-18 14:29 delphi2007 阅读(165) | 评论 (0)编辑 收藏

动态循环,个数可变的for语句 VCL组件开发及应用
http://www.delphi2007.net/DelphiVCL/html/delphi_20061223173939163.html
比如说:  
   
      iArr:   array   of   Integer;   //长度可变  
      //---------------------------------------------  
      //假如长度为3:  
      iArr[0]   :=   4;  
      iArr[1]   :=   5;  
      iArr[2]   :=   6;  
      for   i   :=   0   to   4   do   begin  
          for   j   :=   0   to   5   do   begin  
              for   k   :=   0   to   6   do   begin  
                  ......  
              end;  
          end;  
      end;  
      //---------------------------------------------  
      //假如长度为4:  
      iArr[0]   :=   4;  
      iArr[1]   :=   5;  
      iArr[2]   :=   6;  
      iArr[3]   :=   7;  
      for   i   :=   0   to   4   do   begin  
          for   j   :=   0   to   5   do   begin  
              for   k   :=   0   to   6   do   begin  
                  for   l   :=   0   to   7   do   begin  
                      ......  
                  end;  
              end;  
          end;  
      end;  
      //---------------------------------------------  
      //假如长度为5:  
      iArr[0]   :=   4;  
      iArr[1]   :=   5;  
      iArr[2]   :=   6;  
      iArr[3]   :=   7;  
      iArr[4]   :=   8  
          for   i   :=   0   to   4   do   begin  
          for   j   :=   0   to   5   do   begin  
              for   k   :=   0   to   6   do   begin  
                  for   l   :=   0   to   7   do   begin  
                      for   n   :=   0   to   8   do   begin  
                          ......  
                      end;  
                  end;  
              end;  
          end;  
      end;

iArr的长度未知  
  有没有相关预编译之类的命令?  
   
  比如:  
  {$..   }  
  for   i:0=Length(iArr)-1   do  
  {$..   for   itmpArr[i]:=0   to   iArr[i]-1   do   begin}  
  {$..}  
  ...   ...//处理段  
  {$..}  
  {$..   end}  
  ------------------------------------------------------  
  就是实现动态地写for语句的个数  
  程序自己for循环体

procedure   ForProc(Arr,   Loop:   array   of   Integer;   Index,   Param:   Integer);  
  var  
      I:   Integer;  
      S:   string;  
  begin  
      if   Index   >=   Length(Arr)   then  
      begin  
          S   :=   '';  
          for   I   :=   0   to   Length(Arr)   -   1   do  
              S   :=   S   +   ','   +   IntToStr(Loop[I]);  
          Delete(S,   1,   1);  
          {   TODO   :   Loop为当前下标   }  
          TForm1(Param).Memo1.Lines.Add(S);  
      end   else  
          for   I   :=   0   to   Arr[Index]   do  
          begin  
              Loop[Index]   :=   I;  
              ForProc(Arr,   Loop,   Index   +   1,   Param);  
          end;  
  end;  
   
  procedure   TForm1.Button2Click(Sender:   TObject);  
  var  
      iArr:   array   of   Integer;   //长度可变  
      iLoop:   array   of   Integer;   //长度可变  
  begin  
      SetLength(iArr,   3);  
      SetLength(iLoop,   3);  
      iArr[0]   :=   4;  
      iArr[1]   :=   5;  
      iArr[2]   :=   6;  
      ForProc(iArr,   iLoop,   0,   Integer(Self));  
  end;

0,0,0  
  0,0,1  
  0,0,2  
  0,0,3  
  0,0,4  
  0,0,5  
  0,0,6  
  0,1,0  
  0,1,1  
  0,1,2  
  0,1,3  
  0,1,4  
  0,1,5  
  0,1,6  
  0,2,0  
  0,2,1  
  0,2,2  
  0,2,3  
  0,2,4  
  0,2,5  
  0,2,6  
  0,3,0  
  0,3,1  
  0,3,2  
  0,3,3  
  0,3,4  
  0,3,5  
  0,3,6  
  0,4,0  
  0,4,1  
  0,4,2  
  0,4,3  
  0,4,4  
  0,4,5  
  0,4,6  
  0,5,0  
  0,5,1  
  0,5,2  
  0,5,3  
  0,5,4  
  0,5,5  
  0,5,6  
  1,0,0  
  1,0,1  
  1,0,2  
  1,0,3  
  1,0,4  
  1,0,5  
  1,0,6  
  1,1,0  
  1,1,1  
  1,1,2  
  1,1,3  
  1,1,4  
  1,1,5  
  1,1,6  
  1,2,0  
  1,2,1  
  1,2,2  
  1,2,3  
  1,2,4  
  1,2,5  
  1,2,6  
  1,3,0  
  1,3,1  
  1,3,2  
  1,3,3  
  1,3,4  
  1,3,5  
  1,3,6  
  1,4,0  
  1,4,1  
  1,4,2  
  1,4,3  
  1,4,4  
  1,4,5  
  1,4,6  
  1,5,0  
  1,5,1  
  1,5,2  
  1,5,3  
  1,5,4  
  1,5,5  
  1,5,6  
  2,0,0  
  2,0,1  
  2,0,2  
  2,0,3  
  2,0,4  
  2,0,5  
  2,0,6  
  2,1,0  
  2,1,1  
  2,1,2  
  2,1,3  
  2,1,4  
  2,1,5  
  2,1,6  
  2,2,0  
  2,2,1  
  2,2,2  
  2,2,3  
  2,2,4  
  2,2,5  
  2,2,6  
  2,3,0  
  2,3,1  
  2,3,2  
  2,3,3  
  2,3,4  
  2,3,5  
  2,3,6  
  2,4,0  
  2,4,1  
  2,4,2  
  2,4,3  
  2,4,4  
  2,4,5  
  2,4,6  
  2,5,0  
  2,5,1  
  2,5,2  
  2,5,3  
  2,5,4  
  2,5,5  
  2,5,6  
  3,0,0  
  3,0,1  
  3,0,2  
  3,0,3  
  3,0,4  
  3,0,5  
  3,0,6  
  3,1,0  
  3,1,1  
  3,1,2  
  3,1,3  
  3,1,4  
  3,1,5  
  3,1,6  
  3,2,0  
  3,2,1  
  3,2,2  
  3,2,3  
  3,2,4  
  3,2,5  
  3,2,6  
  3,3,0  
  3,3,1  
  3,3,2  
  3,3,3  
  3,3,4  
  3,3,5  
  3,3,6  
  3,4,0  
  3,4,1  
  3,4,2  
  3,4,3  
  3,4,4  
  3,4,5  
  3,4,6  
  3,5,0  
  3,5,1  
  3,5,2  
  3,5,3  
  3,5,4  
  3,5,5  
  3,5,6  
  4,0,0  
  4,0,1  
  4,0,2  
  4,0,3  
  4,0,4  
  4,0,5  
  4,0,6  
  4,1,0  
  4,1,1  
  4,1,2  
  4,1,3  
  4,1,4  
  4,1,5  
  4,1,6  
  4,2,0  
  4,2,1  
  4,2,2  
  4,2,3  
  4,2,4  
  4,2,5  
  4,2,6  
  4,3,0  
  4,3,1  
  4,3,2  
  4,3,3  
  4,3,4  
  4,3,5  
  4,3,6  
  4,4,0  
  4,4,1  
  4,4,2  
  4,4,3  
  4,4,4  
  4,4,5  
  4,4,6  
  4,5,0  
  4,5,1  
  4,5,2  
  4,5,3  
  4,5,4  
  4,5,5  
  4,5,6  
 

递归

同上

posted @ 2008-11-18 14:29 delphi2007 阅读(130) | 评论 (0)编辑 收藏

Image组件加载图片出现错误后如何让程序继续正常的运行? VCL组件开发及应用
http://www.delphi2007.net/DelphiVCL/html/delphi_20061223162659164.html
请问,   Image组件加载图片出现错误后如何让程序继续正常的运行?  
  谢谢!

try  
      try  
      {Load   Image}  
      except    
      //不做任何处理  
      end;  
      {继续你的工作}  
      ...  
  finally  
      ...  
  end;

我不想在出错后显示提示窗口,也想让程序继续运行。  
  可是这种情况下却不行了:  
  一个BMP图片,改后缀为JPG  
  用Image装载的时候出现了错误提示。  
  可是我不想出现任何错误提示,有什么办法吗?  
  不光加载图片出错时不显示错误提示,其他错误也不想显示。

使用ApplicationEvents,然后处理OnException事件

try  
  except

当进行如下操作的时候,加入try...except也会报错。  
   
  1、   在C盘建立一个BMP图片文件,改名为   a.jpg  
  2、   建立一个空Project,加入一个按钮和图片框  
  3、   引用Jpeg单元。  
   
  这时候即使用   try...except   也会报错。这是为什么呢?应该怎么解决?  
  我找了一下午的原因才找到的,去掉   Jpeg   单元就不会报错。  
   
   
   
  unit   Unit1;  
   
  interface  
   
  uses  
      Windows,   Messages,   SysUtils,   Variants,   Classes,   Graphics,   Controls,   Forms,  
      Dialogs,   StdCtrls,   ExtCtrls,   jpeg;  
   
  type  
      TForm1   =   class(TForm)  
          Image1:   TImage;  
          Button1:   TButton;  
          procedure   Button1Click(Sender:   TObject);  
      private  
          {   Private   declarations   }  
      public  
          {   Public   declarations   }  
      end;  
   
  var  
      Form1:   TForm1;  
   
  implementation  
   
  {$R   *.dfm}  
   
  procedure   TForm1.Button1Click(Sender:   TObject);  
  begin  
      try  
          Image1.Picture.LoadFromFile('C:\a.jpg');  
      except  
      end;  
  end;  
   
  end.

在C盘建立一个BMP图片文件,改名为   a.jpg  
  ============================================================================  
  手工将bmp改为jpg,企图用TJPEGImage去装入是错误的。  
 

回   maozefa(阿发伯)  
  为什么其他错误try能捕捉到并不显示消息框。而经过刚才那样的操作却不能捕获或者说消息框不能被“隐藏”呢。  
  不能排除用户使用程序时恰巧遇到了我说的那种情况

编译为exe文件,独立运行,就不会显示错误消息了,在IDE环境,可以选择Tools->Debugger中去掉Stop   on   Dephi   Exceptions这个选项也不会显示了。

我就是编译为EXE的,提示是   JPEG   error   #42

我就是编译为EXE的,提示是   JPEG   error   #42  
  ===========================================================  
  说明这个错误不是通过Delphi的Exception机制发出的,或者说是运行时刻错误,这就无法捕捉到了。  
 

你可以用try   finally,应该不会报错的。而且,反正调用图片失败了,Image也没用了,就FREE掉。

:Louis_WH()    
  还是报错的  
   
   
  maozefa(阿发伯)  
  可是,如果不引用   Jpeg   就没有提示消息,引用就有了。  
   
  另外,虽然引用了   jpeg   ,怎么找不到这个单元文件呢?应该到那里去找这个东东(叫单元文件?找不到。叫类?又不知到他在哪)

如果不引用   Jpeg   就没有提示消息,引用就有了。  
  ============================================================================  
          jpeg.pas登录了文件格式类型jpg和jpeg,包含这个文件后,当Image.Picture装入图片时,按登录类型自动调用TJPEGImage,去掉这个文件,只能用缺省的TBitmap了。  
          jpeg.pas文件在D安装盘某个目录中(忘记目录名了,你可以搜索一下安装盘),没按装到系统中。

非常感谢   maozefa(阿发伯)    
  我有点明白了。  
  那个文件搜索了,安装盘那里,还是没有,我只是想看看里面的乾坤。。。。。。

procedure   TForm1.Button1Click(Sender:   TObject);  
  var  
      b2:     TBitmap;  
  begin  
      try  
          b2   :=   TBitmap.Create;  
          b2.LoadFromFile('C:\a.jpg');  
          Image1.Picture.Assign(b2);  
          b2.Free;  
      except  
      end;  
  end;  
   
   
  这样即使引用了   Jpeg   也不报错,和   maozefa(阿发伯)     说的一样。  
  请教一下这样的代码规范吗?谢谢

在安装光盘的Info\Extras\Jpeg目录,上面代码基本是规范的,但是手工改bmp为jpg后,总觉得怪怪的。  
  procedure   TForm1.Button1Click(Sender:   TObject);  
  var  
      b2:     TBitmap;  
  begin  
      try  
          b2   :=   TBitmap.Create;  
          try  
              b2.LoadFromFile('C:\a.jpg');  
              Image1.Picture.Assign(b2);  
          finally  
              b2.Free;  
          end;  
      except  
      end;  
  end;  
 

谢谢maozefa(阿发伯)    
  但是手工改bmp为jpg后,总觉得怪怪的。  
  ----------  
  我从网上下载的一些图片就是被乱改了后缀的,比如GIF改成了jpg,jpg改成了bmp等等。很奇怪。不知为何。  
  因为这个原因。才考虑了这么多。

posted @ 2008-11-18 14:29 delphi2007 阅读(232) | 评论 (0)编辑 收藏

这个是delphi的bug嘛??我晕了。 VCL组件开发及应用
http://www.delphi2007.net/DelphiVCL/html/delphi_20061223145902165.html
for   iLen   :=   0   to   sNetDrivers.Count   -   1   do  
              begin  
                  for   idrv   :=   0   downto   24   do  
  这样一个两层循环:  
  设置断点调试:  
  第一次执行的时候idrv的值居然是24,  
   
  然后改成这样:  
    for   iLen   :=   0   to   sNetDrivers.Count   -   1   do  
              begin  
                  for   idrv   :=   24   downto   0   do  
  第一次后,   idrv的值居然是-25  
   
  晕了。.

写错了点,应该是这样的:  
   
  for   iLen   :=   0   to   sNetDrivers.Count   -   1   do  
              begin  
                  for   idrv   :=   0   to   24   do  
  这样一个两层循环:  
  设置断点调试:  
  第一次执行的时候idrv的值居然是24,  
   
  然后改成这样:  
    for   iLen   :=   0   to   sNetDrivers.Count   -   1   do  
              begin  
                  for   idrv   :=   24   downto   0   do  
  第一次后,   idrv的值居然是-25  
   
  晕了。.  
 

正常不是Bug是编译时优化开关打开的原因。  
  因为你没有用到循环变量的值,所以它是几对你来说不重要。  
  如果引用了循环变量,它的值会是正确的。  
  还有如果把编译优化开关关闭,它的值总是会正确的。

你能发现delphi的bug,佩服,哈哈,

posted @ 2008-11-18 14:29 delphi2007 阅读(186) | 评论 (0)编辑 收藏

新人有问题请教:怎样删除txt文件中不需要的行! VCL组件开发及应用
http://www.delphi2007.net/DelphiVCL/html/delphi_20061223140901166.html
如:我有3个txt的文件.分别为:1.txt;2.txt和3.txt.  
  <<1.txt>>  
  %yyy                   //第一行  
  *xxx  
  ..  
   
  (kkkk                 //第十五行  
  f:   50.00     70.00     90.00      
  k:   80.00       90.00     70.00  
  <<2.txt>>  
  %yyy                   //第一行  
  *xxx  
  ..  
   
  (kkkk                 //第十五行  
  y:   100.00   500.00   10.00  
   
  <<3.txt>>  
  %yyy                   //第一行  
  *xxx  
  ..  
   
  (kkkk                 //第十五行  
  g:100.00   500.00   80.00  
  k:10.00     20.00   30.00  
   
  问题是:若我要求删除1-3.txt文件中的1--15行.只要求剩余的行数就可以了  
  还有如果要把1-3.txt已经删除了1-15行的文件在合并成为一个文件为yyy.txt并  
  保存在c盘下为   c:\yyy.txt.  
  最后的情况就像:  
   
  <<yyy.txt>>  
  f:   50.00     70.00     90.00         //第一行  
  k:   80.00       90.00     70.00       //第二行  
  y:   100.00   500.00   10.00  
  g:100.00   500.00   80.00  
  k:10.00     20.00   30.00         //第n行  
   
  若我的txt文件不只有3个.而是20个txt文件,又该怎么办呢?  
  且每个.txt文件必须删除1-15行后在合并为一个文件.  
   
  望大哥能给想点办法!  
  为谢!  
 

操作文本文件的思路就是全部取到内存中,作为string或者stringlist来操作,合并完了再存回去。

TStringList的Delete方法

用delete方法就行

可以详细点说下吗?因为我是外行人.根本就不懂这些!  
  补充.每个txt文件1-15行不要后只有5行了!  
  可以帮忙写个教程什么的!  
  拜托!  
  期望能写个.exe文件就^_^了!

procedure   TForm1.Button1Click(Sender:   TObject);  
  var  
      vStringList:   TStringList;  
      vStringListYYY:   TStringList;  
      I,   J:   Integer;  
  begin  
      vStringList   :=   TStringList.Create;  
      vStringListYYY   :=   TStringList.Create;  
      try  
          for   I   :=   1   to   3   do  
          begin  
              vStringList.LoadFromFile(Format('c:\%d.txt',   [I]));  
              for   J   :=   1   to   15   do  
              begin  
                  if   vStringList.Count   <=   0   then   Break;  
                  vStringListYYY.Add(vStringList[0]);  
                  vStringList.Delete(0);  
              end;  
              //vStringList.SaveToFile(Format('c:\%d.txt',   [I]));//   先看看是不是想要的结果,别错了也覆盖掉  
              vStringList.SaveToFile(Format('c:\%d_test.txt',   [I]));   //   测试用  
          end;  
          vStringListYYY.SaveToFile('c:\yyy.txt');  
      finally  
          vStringList.Free;  
          vStringListYYY.Free;  
      end;  
  end;  
 

如果文本文件只要20行,倒是可以用更简洁一点的办法。  
  思路:  
  读取文本文件第5行之后的所有字符;  
  字符串连接;  
  写到新文件中。  
   
  使用TStringList对象,感觉中间多了一层

posted @ 2008-11-18 14:29 delphi2007 阅读(347) | 评论 (0)编辑 收藏

SHFileOperation 能不能做到当有相同文件或文件夹时,给出提示,是否覆盖? VCL组件开发及应用
http://www.delphi2007.net/DelphiVCL/html/delphi_20061223120233167.html
RT

可以的。  
   
  fFlags   :=   FOF_ALLOWUNDO;  
   
  --------------测试  
   
  procedure   TFormDemo.ButtonAPIClick(Sender:   TObject);  
  var  
      shellinfo:   TSHFileOpStructA;  
  begin  
      with   shellinfo   do  
      begin  
          wnd       :=   Application.Handle;  
          wFunc   :=   FO_COPY;  
          pFrom   :=   PChar('c:\abc.txt');  
          pTo       :=   PChar('d:\');  
          fFlags   :=   FOF_ALLOWUNDO;  
      end;  
      SHFileOperation(shellinfo);  
  end;  
   
 

谢谢,多添了一个标志.MSDN有点读不理解

Q

posted @ 2008-11-18 14:29 delphi2007 阅读(386) | 评论 (0)编辑 收藏

关于TobjectList的一点疑问 VCL组件开发及应用
http://www.delphi2007.net/DelphiVCL/html/delphi_20061223112301168.html
我用了一个TObjectList,我想将自己定义的类对象加进去(包含多个对象)  
  对象含有多个字段(属性),最后我要将各个对象,以某字段的值进行排序  
   
  下面是程序代码片段----------  
  CoDeskList   :=   TObjectList.Create;  
  CoDesKList.OwnsObjects   :=   false;//这个地方采用默认值还是false  
   
  while   not   eof   do//数据库读出的记录  
                  begin  
                          SvDesk   :=   TSvDesk.Create;//自定义对象  
                          SvDesk.DCoID:=   Trim(fieldbyname('servdeskcoid').AsString);  
                          SvDesk.Length   :=   fieldbyname('inorderqueuecurrlength').AsInteger;  
                          SvDesk.Pri   :=   fieldbyname('pri').AsInteger;  
                          CoDeskList.Add(SvDesk);  
                          SvDesk.Free;//释放  
                          next;  
                  end;  
   
      MaxPri   :=   TSvDesk(CoDeskList.Items[0]).Pri;//TSvDesk强制转换   调试过,有值  
      ID:=   TSvDesk(CoDeskList.Items[0]).DcoID;//这里为什么读不出来呢  
                  For   i:=   0   TO   Sum_a   Do   //找出服务台的最高优先级值  
                  begin  
                          if   MaxPri   <   TSvDesk(CoDeskList.Items[i]).Pri   then  
                                  MaxPri   :=   TSvDesk(CoDeskList.Items[i]).Pri;  
                  end;  
  最后  
          CoDeskList.Clear;  
          CoDeskList.Free;  
  还有一个很严重的问题就是CoDeskList里有两条记录,但都是最后一条记录的值(第一条被覆盖掉了),为什么呢?????????

type  
      TSvDesk   =   class  
      private  
          FDCoID:   string;  
          FLength:   Integer;  
          FPri:   Integer;  
      protected  
      public  
          property   DCoID:   string   read   FDCoID   write   FDCoID;  
          property   Length:   Integer   read   FLength   write   FLength;  
          property   Pri:   Integer   read   FPri   write   FPri;  
      end;  
   
      TFormDemo   =   class(TForm)  
          ADOQuery:   TADOQuery;  
          ButtonDemo:   TButton;  
          procedure   ButtonDemoClick(Sender:   TObject);  
      private  
          {   Private   declarations   }  
      public  
          {   Public   declarations   }  
      end;  
   
  var  
      FormDemo:   TFormDemo;  
   
  implementation  
   
  {$R   *.dfm}  
  //排序函数(降序)  
  function   ComparePri(Item1,   Item2:   TObject):   Integer;  
  begin  
      if   TSvDesk(Item1).Pri   >   TSvDesk(Item2).Pri   then  
          Result   :=   -1;  
      if   TSvDesk(Item1).Pri   =   TSvDesk(Item2).Pri   then  
          Result   :=   0;  
      if   TSvDesk(Item1).Pri   <   TSvDesk(Item2).Pri   then  
          Result   :=   1;  
  end;  
   
  procedure   TFormDemo.ButtonDemoClick(Sender:   TObject);  
  var  
      CoDeskList:   TObjectList;  
      SvDesk:   TSvDesk;  
      MaxPri:   Integer;  
      ID:   Integer;  
  begin  
      CoDeskList   :=   TObjectList.Create;  
      //CoDesKList.OwnsObjects   :=   False;   //Default   =   True  
      try  
          with   ADOQuery   do  
          begin  
              while   not   Eof   do//数据库读出的记录  
              begin  
                  SvDesk   :=   TSvDesk.Create;//自定义对象  
                  SvDesk.DCoID:=   Trim(FieldByName('ServDeskCoID').AsString);  
                  SvDesk.Length   :=   FieldByName('InOrderQueueCurrLength').AsInteger;  
                  SvDesk.Pri   :=   FieldByName('Pri').AsInteger;  
                  CoDeskList.Add(SvDesk);  
                  //SvDesk.Free;//不要释放  
                  Next;  
              end;  
          end;  
          CoDeskList.Sort(@ComparePri);  
          MaxPri   :=   TSvDesk(CoDeskList.Items[0]).Pri;  
      finally  
        CoDeskList.Free;  
      end;  
  end;

DELPHI   HELP  
   
  OwnsObjects:  
   
  Allows   TObjectList   to   free   objects   when   they   are   deleted   from   the   list   or   the   list   is   destroyed.  
   
  OwnsObjects   allows   TObjectList   to   control   the   memory   of   its   objects.   If   OwnsObjects   is   true   (the   default),  
   
  calling   Delete   or   Remove   frees   the   deleted   object   in   addition   to   removing   it   from   the   list.  
  calling   Clear   frees   all   the   objects   in   the   list   in   addition   to   emptying   the   list.  
  calling   the   destructor   frees   all   the   objects   in   the   list   in   addition   to   destroying   the   TObjectList   itself.  
  assigning   a   new   value   to   an   index   in   Items   frees   the   object   that   previously   occupied   that   position   in   the   list.

还有一个很严重的问题就是CoDeskList里有两条记录,但都是最后一条记录的值(第一条被覆盖掉了),为什么呢?????????  
  ------------------------------------  
  呵呵。   一切都是指针惹的祸。

posted @ 2008-11-18 14:29 delphi2007 阅读(328) | 评论 (0)编辑 收藏

非常有挑战性的问题,提高时实刷新速度 VCL组件开发及应用
http://www.delphi2007.net/DelphiVCL/html/delphi_20061223094700169.html
 
      非常有挑战性的问题,提高时实刷新速度  
   
      比如做一套类试影吧的系统,需要一个时实监视客户端的一个收费软件  
   
      监视台用StringGrid   控件实现,时实(每秒钟一次)刷新数据库中的一个由Server后台写好  
   
      好的一个临时表,StringGrid判断字段值改变时才重画,  
   
      这种方法,起初数据表这有几十条,占用CPU   时间才8%左右,但数据库加到  
   
      2000多条时,CPU   时间马上升到   70%,  
   
      我估计主要的时间是用在ADOQuery.open上了  
   
      还有StringGrid是通过   for   循环给每行赋值的。  
   
      请问,有没有提供好的思路和方法!

每次传输2000条记录能不慢吗?  
  第一次连接传递完整的记录  
  之后只传递变化的记录  
   
  每一条记录有一个唯一的标识,用来区别  
  变化只有三种情况  
  1、添加  
  2、修改  
  3、删除  
  发送这些变化就可以保证客户端和服务器一致了。

第一次连接传递完整的记录  
  之后只传递变化的记录  
   
  -------------  
  哈哈,   问题是客户端如何知道哪些记录被改变了??

关注此类问题

fox1999(红狐)  
  可由控制台发更新信号,

只传变化的

posted @ 2008-11-18 14:29 delphi2007 阅读(233) | 评论 (0)编辑 收藏

怎样在主窗体上单击一按钮时,调出的窗口显示在任务栏上?? VCL组件开发及应用
http://www.delphi2007.net/DelphiVCL/html/delphi_20061223094429170.html
如题:  
  我想在程序里调出一些特定的窗口时,让它们显示在主窗体以外的任务栏上,就像word里打开多个文档时,在任务栏上另开辟一个窗口一样,请高手指点,在线等.....

怎么没有人呀,说话呀

是不是要加个什么功能呀??

把特定的窗口单独编译成.exe   ;  
  再在主程序里winexec()调用它,这样怎么样

这样的话,就要有两个可执行文件了,最好在一个程序里

咦,没分,没分啊兄弟

posted @ 2008-11-18 14:29 delphi2007 阅读(307) | 评论 (0)编辑 收藏

调用application.messagebox()时出现的小问题! VCL组件开发及应用
http://www.delphi2007.net/DelphiVCL/html/delphi_20061223093818171.html
如题:  
  当保存成功时,保存按钮的事件最后一行为  
  application.message('保存成功!','提示信息',mb_iconinformation);  
  在程序运行到这时,有时候程序会失去活动状态,只有再单击任务栏上的主窗体时,才能看到提示信息,不知大家遇到过这种现象没有??  
  不知道是什么原因,请大侠指点,在线等...........  
 

请大家帮一下吧

用application.messagebox('保存成功!','提示信息',mb_iconinformation);试试,可能是焦点问题

是呀,刚才我少打了box我用的就是application.messagebox的

偶一般都用MessageBox(Handle,'dsa','fdsa',Mb_OK   +   Mb_IconInformation)  
  在有窗体的时候……

appliction.messagebox与messagebox()有什么区别吗?

会不会appliction.messagebox()有时会失去焦点呀??

不会的

posted @ 2008-11-18 14:29 delphi2007 阅读(276) | 评论 (0)编辑 收藏

初来乍道,问个比较菜的问题:如何把一文件中指定的内容提取出来? VCL组件开发及应用
http://www.delphi2007.net/DelphiVCL/html/delphi_20061223005343172.html
数据内容如下:  
  72800.000       38.91898908   -77.06621526         40.7516     1112188.776   -4842946.894     3985349.437     6.3756030408e-007     0.82         4.48       8       8     0.00000     0     0     0.000  
  172830.000       38.91898135   -77.06620653         41.6280     1112189.787   -4842947.914     3985349.320     6.4061365069e-007     1.05         4.51       8       8     0.00833     0     0   30.000  
  172860.000       38.91895879   -77.06620348         47.2173     1112191.370   -4842953.626     3985350.883     6.5588341696e-007     1.45         4.09       9       9     0.01667     0     1     0.000  
  172890.000       38.91895839   -77.06620595         47.4124     1112191.202   -4842953.850     3985350.971     6.5682624245e-007     1.46         4.11       9       9     0.02500     0     1   30.000  
  172920.000       38.91896101   -77.06620285         47.2516     1112191.395   -4842953.489     3985351.097     6.5675199614e-007     1.42         4.12       9       9     0.03333     0     2     0.000  
  172950.000       38.91896486   -77.06620350         46.7696     1112191.196   -4842952.875     3985351.126     6.5579189199e-007     1.32         4.14       9       9     0.04167     0     2   30.000  
  172980.000       38.91896559   -77.06620199         46.4309     1112191.253   -4842952.539     3985350.977     6.5487505133e-007     1.28         4.15       9       9     0.05000     0     3     0.000  
  173010.000       38.91896711   -77.06620177         45.8964     1112191.155   -4842952.026     3985350.772     6.5348139453e-007     1.25         4.17       9       9     0.05833     0     3   30.000  
  173040.000       38.91896774   -77.06619940         45.3632     1112191.252   -4842951.533     3985350.492     6.5210196616e-007     1.19         4.18       9       9     0.06667     0     4     0.000  
  173070.000       38.91896760   -77.06619931         45.6531     1112191.313   -4842951.761     3985350.662     6.5307188787e-007     1.23         4.19       9       9     0.07500     0     4   30.000  
  173100.000       38.91896831   -77.06619921         45.5575     1112191.294   -4842951.638     3985350.663     6.5291762658e-007     1.17         4.21       9       9     0.08333     0     5     0.000  
  用什么方法可以把每一行的第一个值那个用科学计数法表示的值给提取出来,最好能给出源码,谢谢了!

 
    用TStringList  
       
    可以很方便的取出每行数据  
   
    var  
        list1   :TStringList  
    begin  
        list1   ;=TStringList.create;  
        list1.loadFrom(filename);  
        ...  
   
 

 
      然后再取   第一个值    
   
 

TStringList

但怎么取值呢,能说的详细吗,谢谢。

你可以单行提取,然后用   '   '做结束标志,单个提取啊

StrToFloat   能够识别科学计数法。

我刚接触DELPHI不太清楚,看帮助里没有写关于Tstringlist有提取一行中某个数据是方法,  
  weixiaohua(我爱Delphi)   你说用''作结束标志,怎么操作呢,能写段代码最好,可以学习一下。  
   
 

function   GetValidStr3   (Str:   string;   var   Dest:   string;   const   Divider:   array   of   Char):   string;  
  const  
        BUF_SIZE   =   20480;   //$7FFF;  
  var  
  Buf:   array[0..BUF_SIZE]   of   char;  
        BufCount,   Count,   SrcLen,   I,   ArrCount:   Longint;  
        Ch:   char;  
  label  
  CATCH_DIV;  
  begin  
      Ch:=#0;//Jacky  
        try  
              SrcLen   :=   Length(Str);  
              BufCount   :=   0;  
              Count   :=   1;  
   
              if   SrcLen   >=   BUF_SIZE-1   then   begin  
                    Result   :=   '';  
                    Dest   :=   '';  
                    exit;  
              end;  
   
              if   Str   =   ''   then   begin  
                    Dest   :=   '';  
                    Result   :=   Str;  
                    exit;  
              end;  
              ArrCount   :=   sizeof(Divider)   div   sizeof(char);  
   
              while   TRUE   do   begin  
                    if   Count   <=   SrcLen   then   begin  
                          Ch   :=   Str[Count];  
                          for   I:=0   to   ArrCount-   1   do  
                                if   Ch   =   Divider[I]   then  
                                      goto   CATCH_DIV;  
                    end;  
                    if   (Count   >   SrcLen)   then   begin  
                          CATCH_DIV:  
                          if   (BufCount   >   0)   then   begin  
                                if   BufCount   <   BUF_SIZE-1   then   begin  
                                      Buf[BufCount]   :=   #0;  
                                      Dest   :=   string   (Buf);  
                                      Result   :=   Copy   (Str,   Count+1,   SrcLen-Count);  
                                end;  
                                break;  
                          end   else   begin  
                                if   (Count   >   SrcLen)   then   begin  
                                      Dest   :=   '';  
                                      Result   :=   Copy   (Str,   Count+2,   SrcLen-1);  
                                      break;  
                                end;  
                          end;  
                    end   else   begin  
                          if   BufCount   <   BUF_SIZE-1   then   begin  
                                Buf[BufCount]   :=   Ch;  
                                Inc   (BufCount);  
                          end;//   else  
                                //ShowMessage   ('BUF_SIZE   overflow   !');  
                    end;  
                    Inc   (Count);  
              end;  
        except  
              Dest   :=   '';  
              Result   :=   '';  
        end;  
  end;  
   
  上面这个函数功能就是你需要的.使用方法如下  
  tStr   :=   GetValidStr3(tStr,   s18,   ['   ',   #9]);  
  tStr   :=   GetValidStr3(tStr,   s1C,   ['   ',   #9]);  
  tStr   :=   GetValidStr3(tStr,   s20,   ['   ',   #9]);  
  提取出来在转换成数就行了.

weixiaohua(我爱Delphi)   谢谢你的回复,但这个函数对于初期的我来说有点难度,看不明白,不知有没有相对简单一点的方法,要是没有我就放分结贴了,。  
  第一次来这里就看到这么多热心的人,很感谢大家,也感谢CSDN。。

你不用管那个函数的具体实现.  
  假如你的数据在DataList中.  
  DataList   :=   TStringList.Create;  
  DataList.LoadFromFile('X:\XX.txt');  
  for   I   :=   DataList.count   -   1   do  
  begin  
      sLine   :=   DataList.Strings[I];  
      sLine   :=   GetValidStr3(sLine,   str1,   ['   ',   #9]);     //假如第一行   str1   :=   72800.000;  
      //sLine   :=   GetValidStr3(sLine,   str1,   ['   ',   #9]);   //在执行一次   str1   :=   38.91898908   你可以依此类推.  
      StrToFloat(str1);   //转换后就是你需要的数了.  
  end;  
 

up

weixiaohua(我爱Delphi)  谢谢了,分已送出请查收。。

posted @ 2008-11-18 14:29 delphi2007 阅读(136) | 评论 (0)编辑 收藏

窗体form失去焦点时(非激活状态),发生什么事件 VCL组件开发及应用
http://www.delphi2007.net/DelphiVCL/html/delphi_20061222233159173.html
由非激活状态变为激活状态是onActivate对吧  
  那么由激活状态变为非激活状态则对应哪个事件呢?onDeactivate么?我试了好像没用,鼠标点桌面或其他窗口,则form窗体变为非激活,应该触发啥事件?

FormDeactivate

FormDeactivate的触发时机:  
   
  when   the   form   transitions   from   being   the   active   form   to   another   form   in   the   same   application   becoming   the   active   form.    
   
  特别说明:  
  If   activation   goes   to   another   application,   this   event   is   not   triggered.  
   
  处理办法:  
   
  To   determine   if   another   application   has   become   active,   Use   the   TApplication   object's   OnDeactivate   event.  
   
  --------------------------------------------------  
   
  1、    
   
  procedure   OnLoseFocus(Sender:   TObject);  
  begin  
      Form1.Caption   :=   FormatDateTime('HH:MMMM:SS',   Now);  
  end;  
   
  procedure   TForm1.FormCreate(Sender:   TObject);  
  begin  
      ......  
      @Application.OnDeactivate   :=   @OnLoseFocus;  
      ......  
  end;  
   
  2、可以捕获WM_KillFocus来处理失去焦点的事件  
   
  procedure   TForm1.NewWindowProc(var   Message:   TMessage);  
  begin  
      if   Message.Msg   =   WM_KillFocus   then  
          Caption   :=   FormatDateTime('HH:MMMM:SS',   Now);  
      OldWindowProc(Message);  
  end;  
   
  procedure   TForm1.FormCreate(Sender:   TObject);  
  begin  
      ......  
      OldWindowProc   :=   sELF.WindowProc;  
      Self.WindowProc   :=   NewWindowProc;  
      ......  
  end;  
   
 

不好意思,上次给的事件必须是在进程内部的  
   
  按照你的意思  
  你可以添加   ApplicationEvents   控件  
  然后在OnDeactivate   事件添加即可

posted @ 2008-11-18 14:29 delphi2007 阅读(1904) | 评论 (0)编辑 收藏

仅列出标题
共34页: First 19 20 21 22 23 24 25 26 27 Last