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

📄 delsec07.txt

📁 《Delphi开发人员指南》配书原码
💻 TXT
📖 第 1 页 / 共 2 页
字号:


19) Q:  How do I make an Fixed Length ASCII text table from a table?

    A:  Like this:

	procedure TForm1.Button1Click(Sender: TObject);
	var
	  t1, t2: tTable;  {t1 = PW table; t2 = ASCII version}
	begin
	  t1 := tTable.create(self);
	  with t1 do
	  begin
	    DataBaseName := 'pw'; { Personal Alias for Paradox Directory }
	    tableName := 'customer.db'; { Source Table }
	    open;
	  end;	
	  t2 := tTable.create(self);
	  with t2 do
	  begin
	    DataBaseName := 'pw'; { Personal Alias for Paradox Directory }
	    tableName := 'asdf.txt';
	    TableType := ttASCII;

	    createTable; 
	    open;
	    edit;
	    BatchMove(t1, batCopy);
	    close;
	  end;
	  t1.close;
	end;


20) Q:  How do I set a format for a data field?

    A:  Select the table object, and double click.  Select the field that you 
	want to format.  Use the DisplayFormat and the EditFormat properties to 
	do what you want.  DisplayFormat works for when the field does not have 
	focus.  EditFormat works for when the field has focus.  Use the commands 
	as you would for the first parameter of the FormatFloat function, but 
	without the quotes.


21) Q:  How do I format a number to place commas as a thousanth's separator?

    A:  If you are not using Delphi, try this code:

	function FormatNumber(l: longint): string;
	var
	  len, count: integer;
	  s: string;
	begin
	  str(l, s);
	  len := length(s);
	  for count := ((len - 1) div 3) downto 1 do
	    begin
	      insert(',', s, len - (count * 3) + 1);
	      len := len + 1;
	    end;
	  FormatNumber := s;
	end;

        If you are using Delphi, there is, of course, the easy way:

	function FormatNumber(l: longint): string;

	begin
	  FormatNumber := FormatFloat('#,##0', StrToFloat(IntToStr(l)));
	end;


22) Q:  I have a CPU intensive function.  I want to be able to check to see if 
	the user wants to cancel.  How do I do that?

    A:  Call Application.ProcessMessages from time to time in your code.


23) Q:  How do you extract the high or low order byte from a word?  How do you 
	insert it?  

    A:  There are built in methods hi() and lo() for extracting, but for those 
	that want to know how to do it on their own, here it is in its most 
	efficient form (if I do say so myself <G>).  The functions for inserting
	bytes are not in Delphi.  

	Note:  Assembler functions return the contents of the AX register.

	function GetHiByte(w: word): byte; assembler;
	asm
	   mov ax, w
	   shr ax, 8
	end;

	function GetLoByte(w: word): byte; assembler;
	asm
	   mov ax, w
	end;

	function SetHiByte(b: byte; w: word): word; assembler;
	asm
	   xor ax, ax
	   mov ax, w
	   mov ah, b
	end;

	function SetLoByte(b: byte; w: word): word; assembler;
	asm
	   xor ax, ax
	   mov ax, w
	   mov al, b
	end;
   
	Another way of doing it (with an example of its use):  

	Type
	   TWord2Byte = record
                  Lo,Hi: Byte;
           end;

	var W: Word;
	     B: Byte;
	begin
	   W := $1234;
	   B := TWord2Byte(W).Hi;
	   writeln(TWord2Byte(W).Hi);
	   { going back }
	   TWord2Byte(W).Lo := $67;
	   TWord2Byte(W).Hi := $98; { no shl needed! }
	end.


24) Q:  I have an OBJ file that has several assembler routines compiled into it.
	I wouldn't want to have to rewrite them.  Is there a way to use them in
	a Delphi app?

    A:  You don't indicate if these return values or not (in Pascal this 
        matters.)

	If they don't, include the following near the front of your code:

	  Procedure TurnOn;  External;
	  Procedure TurnOff; External;

	If they return values, use:

	  Function TurnOn: Integer; External;
	  Function TurnOff: Integer; External;

	Replace Integer with whatever datatype they return.
	In either case follow that with:

	  {$L filename.obj}

	to link in the obj file.  See also the "linking external assembler code"
	in the on-line help.


25) Q:  Which memory model does Delphi use?

    A:  Delphi uses a mixed memory model, but it is very close to the "C" large model.  The defaults are:

	  - Methods are far
	  - Procedures in an interface section are far
	  - Procedures only used in an implementation section are near
	  - Heap data and all pointers in general (including class instances)
	    are far
	  - Global variables are near (DS based)
	  - Procedure parameters and local variables are near (SS based)
	  - Procedures declared FAR or EXPORT are far
	  - Virtual memory tables are far for the new class model and near for
	    the old

	This scheme has been used by Borland Pascal for a very long time. I find
	it flexible and efficient.

	Since all public procedures, methods and pointers are 32bit already, 
	Delphi32 won't have to change any of that.  It's likely that Delphi32 
	will switch to 32bit addressing for the data and stack segments too, 
	but that shouldn't affect any of your code either.  What will affect it
	is the change of Integer from 16 to 32 bit.


26) Q:  If a component doesn't handle the windows messages that I need it to 
	handle, do I have to write my own version that passes the messages that 
	I need, or is there way to tap (from a TForm or else where) into the 
	message loop, and grap what I need?

    A:  To respond to, say, the wm_size message, you would add:

	 procedure WMPaint(var Message: TWMPaint); message WM_PAINT;

	to your component.  Then you could have:

	 procedure TWhateverComponent.WMPaint(var Message: TWMPaint);
	 begin
	    {have your way with the component}
	 end;

	This will work for any windows message.  Most components respond to the 
	more popular messages already, and you can override their event handlers.


27) Q:  Borland decided that accessing environment variables from Windows 
	Programs is a Bad Thing.  Why do they force you to use the "obsolete" 
	WinDos unit?

    A:  Use the GetDOSEnvironment() call from the API.


28) Q:  How would I write a basic screen saver (like, blank the screen) 
	using Delphi?

    A:  An easy implementation would be something like this:

	var
	  f: tForm;

	begin
	  f := tForm.create(self);
	  f.WindowState := wsMaximized;
	  f.color := black;
	  f.borderStyle := bsNone;
	  f.show;
	end;

	There is more to do, of course.  You must have a way back from there.  
	Perhaps an actual form that has a mouse click event programmed to 
	f.close it.  Also, you want to hide the mouse.  Etc, etc.  But, this 
	answers the question.


29) Q:  How can I determine the Length in pixels of a string after a specific 
	font has been aplied to it?

    A:  The two methods, TextHeigh and TextWidth, can be used to determine 
	both the text height and width of a string in pixels.  These methods 
	can only be accessed through components that have a Canvas property 
	such as TForm.  The TPanel component does not have access to its Canvas 
	property by default because it is protected.

	If a component doesn't have a Canvas property then The following 
	function will return the text width based on the font passed.

	  function GetTextWidth(CanvasOWner: TForm; Text : String;
     	                        TextFont :  TFont): Integer;
	  var
	     OldFont : TFont;
	  begin	
	    OldFont := TFont.Create;
	    try
	      OldFont.Assign( CanvasOWner.Font );
	      CanvasOWner.Font.Assign( TextFont );
	      Result := CanvasOWner.Canvas.TextWidth(Text);
	      CanvasOWner.Font.Assign( OldFont );
	    finally
	      OldFont.Free;
	    end;
	  end;


30) Q:  Where is the best place to open a splash screen on program start up?

    A:  The best place to open a splash screen is in the project source file 
	after the first FormCreate and before the Run  This is  accomplished 
	by creating a form on the fly and then displaying it before the app is 
	actual opened.

	 program Project1;

	 uses Forms,  Unit1 in 'UNIT1.PAS' {Form1}, Splash;

	 {$R *.RES}
	 var
	   SplashScreen : TSplashScreen;  {in the Splash unit}

	 begin
	   Application.CreateForm(TForm1, Form1);
	   SplashScreen := TSplashScreen.Create(Application);
	   try
	     SplashScreen.Show;
	     {
	      do other CreatForms or any other processing 
	      before the app is to be opened
	     }
	     SplashScreen.Close;
	   finally  {Make sure the splash screen gets released}
	     SplashScreen.Free; 
	   end;   
	   Application.Run;
	 end.


31) Q:  How do I call a function from a DLL?

    A:  In order to call a function you must know it's exact syntax. and setup
	a function type.  For example to call the CallMe function, which accepts
	two integers and returns a string, from MyTest.Dll when a button is 
	pushed, you could use the following code:

	procedure TForm1.Button1Click(Sender: TObject);

	type
	  TCallMeDll = function(a,b: Integer): string;

	var
	  CallMeDll: TCallMeDll;
	  FuncPtr: TFarProc;
	  hDll: THandle;
	  result: string;

	begin
	  hDll:=LoadLibrary('Mytestdll.dll');
	  FuncPtr:=GetProcAddress(hDLL,'CallMe');
	  @CallMeDll:=FuncPtr;
	  if @CallMeDll <> nil then
	    result:=CallMeDll(4,5);
	  FuncPtr:=nil;
	  FreeLibrary(hDll);
	end;

	Note that w must first load the dll into memory, then we can obtain a 
	pointer to the function, and assign that to the contents of CallMeDll.
	At this point I am checking to see if the ProcAdderss is Nil, this would 
	indicate that the call to GetProcAddress failed.

	It is important to note that sometimes you might want to load the 
	library, and get the procedure address once at the begenning of your 
	program, and free the library once at the end.
	  

32) Q:  What is a Callback function, and how do I create one?

    A:  A call back function is a function which you write, but is called by 
	some other program or module, such as windows.  To create a callback function, you
	must first declare a function type, the funciton itself, and implement 
	the function.  In the interface section:

	{ In main program interface }

	type
	  TCallBackFunction = function(s: string): integer;
	  CallMe(s: string): integer;

	And in the Implementation section:

	{ In main program implementation }

	procedure TestCallBack(CallBackFunction: TCallBackFunction); far; external 'Other';
		{ Note that 'other' is a Dll containing the procedure TestCallBack }

	function CallMe(s: PChar): integer;
	begin
	  { what ever you need to do }
	  CallMe := 1; { What ever you need to return }
	end;

	procedure TForm1.Button1Click(Sender: TObject);
	begin
	  TestCallBack(CallMe);
	end;

	Note that in 'Other' you would also declare a function type, and use it
	like this:

	{ in library Other interface }

	type
	  TMainFunction = function(s: string): integer;
	  TestCallBack(MainFunc: TMainFunction);

	{ in library Other implementation }

	TestCallBack(MainFunc: TMainFunction);
	var
	  result: integer;
	begin
	  result:=MainFunc('test');
	end;

⌨️ 快捷键说明

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