4  Interesting QA from various newsgroups
unsorted, uncommented, simply copied from NG - mails (without written permission of the authors)


last updated: Sep30-1998    Index 1QA


Subject:      Re: MASM and Long Filenames
From:         sgvd@xs4all.nl (Simon van Dongen)
Date:         1998/07/02
Message-ID:   <6neom9$ejp$3@winter.news.erols.com>
Newsgroups:   comp.lang.asm.x86

On or about 1 Jul 1998 13:32:49 GMT, Ron McGregor wrote:

>As I recall, the long file name system used in NT is totally different to
>that used in Windows95. Windows95 long file name structures are actually
>compatible with DOS because the shortened  version of the file name (the
>one with the tilde character ~) is stored right after the long version.
>WindowsNT long file names do not follow this procedure. I think that
>WindowsNT file system is more similar to OS/2 than to Windows95. I suspect
>that this could be why int21/7160h doesn't work under WindowsNT.
>

Has anyone bothered to find out yet what happens if you rename a file
to a longer name? Do all the files further on in the directory get
moved?

BTW, you can find the extra bits of long filenames in MS DOS 5 with
plain, oldfashioned 4Eh/4Fh calls by setting CX (the attributes)
appropriately (CX=0Fh iirc). You do have to decode them yourself, of
course.

--
Simon van Dongen <sgvd@xs4all.nl> Rotterdam, The Netherlands

As he reclined there he sang ballads of ancient valour, from
time to time beating a hollow wooden duck in unison with his
voice, so that the charitable should have no excuse for
missing the entertainment.  -Bramah, Kai Lung's Golden Hours



   Subject:   Re: DLLs and PChars
      Date:   Wed, 1 Jul 1998 10:47:37 +0200
      From:   "Teddy" <orsystem@mnet.fr>
 Organization:Mnet InterNet News Access
 Newsgroups: cern.delphi, comp.lang.pascal.delphi.components.misc, comp.lang.pascal.delphi.misc

Hi,

Your variable S in local to your function (it is created within the stack),
so when you function exits, the memory for this var is freed an reused.
As i see you DLL is wrote using Delphi 1 (because or the export statement
and your string to PChar conversion). You're lucky, because stack of a 16
bits application is shared with his caller, but in 32 bits, Dll's have its
own stack...
Anyway, you cannot use stack to send back a data.

There is two solutions to your problem...
As you use a 16 bits Dll, you can make you S variable global (so its address
will be static) but i dont recommend this solution.
You should use a argumented PChar to send back data (it'll work both on 16
an 32 bits..)
Try :

function MakeKey(name, additional1, additional2, ANSWER: PChar): PChar;
export;
var s: String;
begin
    s := MakeVerySecretCode(StrPas(name));
    StrPCopy(ANSWER, s);
    Result := ANSWER;
end;

DO NOT FORGET TO ALLOCATE MEMORY FOR YOUR ANSWER PCHAR !!!

@+

Lorenz Graf a écrit dans le message
<6nbep9$s1h$5@freenet-b.fen.baynet.de>...
>Hello Delphi coders !
>My problem is:
>I want to build a DLL which contains a function that returns a pchar:
>  function MakeKey(name, additional1, additional2: PChar): PChar; export;
>Now I try to generate a result pchar e.g. by doing this:
>  function MakeKey(name, additional1, additional2: PChar): PChar; export;
>  var s: String;
>  begin
>       s := MakeVerySecretCode(StrPas(name));
>       s := s+#0;                { makes string null -terminated }
>       Result := @s[1];               { skip s[0], as it contains length }
>  end {MakeKey};
>However, all the time I call the function from my application, I get an
>access violation. So my questions are: How to avoid the Access Violation ?
>Where does the memory I allocate for the result get freed ? Does it get
>freed at all ??
>If you know about this, I would be very pleased to hear from you. If you
got
>a friend who is the DLL-Man, please give me his e-mail address.
>Greetings,
>Lorenz
>--
>please reply to LGraf@POBoxes.com
> and visit the HTMLtool homepage at
>http://www.poboxes.com/HTMLtool/
> rated 5 duckies at NoNags



   Subject:   Re: re-dimensioning arrays (Source)
      Date:   1 Jul 1998 10:08:29 GMT
      From:   Antivivisektion@t-online.de (Antivivisektion e.V.)
 Organization:http://Antivivisektion.base.org
 Newsgroups:  comp.lang.pascal.borland

Toby Cubitt wrote:
>
> What can you do in turbo pascal if you want to re-dimension an array
> based on user input.

{$A+,B-,D+,E-,F-,I-,L+,N-,O-,R-,S-,V-,T-}
{$DEFINE UNIT}
{$IFDEF UNIT}
Unit Plateau;

Interface
{$ENDIF}

Type
  IndexArray = Array[1..$3FFF] Of LongInt;
  SizeArray = Array[0..$3FFE] Of LongInt;
  PlatauObj = Object
         Base: Pointer;
   IndexTable: ^IndexArray;
    SizeTable: ^SizeArray;
          Dim: Word;

    Function Init (pDim,pSize: Word; Var pBound,pIndex): Boolean;
    Function GetAddr: Pointer;
    Procedure Help;
  End;

{$IFDEF UNIT}
Implementation
{$ENDIF}

Function Ptr2Long(p: Pointer): LongInt; Assembler;
Asm
   mov ax,word ptr [p+2]
   mov dx,ax
   shr dx,12
   shl ax,4
   add ax,word ptr [p]
   adc ax,0
End;

Function Long2Ptr(l: LongInt): Pointer; Assembler;
Asm
   mov ax,word ptr [l]
   mov dx,word ptr [l+2]
   mov bx,ax
   and ax,0Fh
   shr bx,4
   shl dx,12
   add dx,bx
End;

Function SubPtr(p: Pointer; d: LongInt): Pointer;
Begin
  SubPtr := Long2Ptr(Ptr2Long(p)-d);
End;

Function AddPtr(p: Pointer; d: LongInt): Pointer;
Begin
  AddPtr := Long2Ptr(Ptr2Long(p)+d);
End;

Function PlatauObj.Init (pDim, pSize: Word; Var pBound, pIndex):
Boolean;
Var Loop: Word; Disp: LongInt; Bound: Array[1..$1FFF,1..2] Of LongInt
Absolute pBound;
Begin
  {$IFOPT D+} FillChar (Self,SizeOf(Self),0); {$ENDIF}
  IndexTable := @pIndex;
  Dim := pDim;
  GetMem (SizeTable,SizeOf(LongInt)*Succ(pDim));
  SizeTable^ [pDim] := pSize;

  Disp := 0;
  For Loop := pDim DownTo 1 Do
  Begin
    Inc(Disp,SizeTable^[Loop]*Bound[Loop,1]);
    SizeTable^[Pred(Loop)] :=
SizeTable^[Loop]*Succ(Bound[Loop,2]-Bound[Loop,1]);
  End;

  If (MaxAvail < SizeTable^[0])
     Then Init := False
     Else
       Begin
         Init := True;
         Base := SubPtr(HeapPtr,Disp);
         HeapPtr := AddPtr(HeapPtr,SizeTable^[0]);
       End;
End;

Function PlatauObj.GetAddr: Pointer;
Var Loop: Word; Disp: LongInt;
Begin
  Disp := 0;
  For Loop := 1 To Dim Do
    Inc(Disp,SizeTable^[Loop] * IndexTable^[Loop]);
  GetAddr := AddPtr (Base,Disp);
End;

Procedure PlatauObj.Help;
Begin
  WriteLn;
  WriteLn ('Unit Plateau V1.2 - (C) by Antivivisektion@t-online.de,
Update: 3. Feb 1992');
  WriteLn ('Fields of dynamic dimensions and borders with size > 64 K');
  WriteLn;
  WriteLn ('1. Static version');
  WriteLn ('   Var Field: Array[-3..30,-4..40,-5..50] Of Real;');
  WriteLn ('   Begin');
  WriteLn ('     Field[-2,-3,-4] := PI;');
  WriteLn ('   End.');
  WriteLn;
  WriteLn ('2. Dynamic version');
  WriteLn ('   Uses Plateau;');
  WriteLn ('   Const DIM = 3;');
  WriteLn ('   Const Bound: Array[1..DIM,1..2] Of LongInt =
((-3,30),(-4,40),(-5,50));');
  WriteLn ('   Var Index: Array[1..DIM] Of LongInt; Field: PlatauObj;');
  WriteLn ('   Begin');
  WriteLn ('     If Not Field.Init (DIM,SizeOf(Real),Bound,Index) Then
RunError(203);');
  WriteLn ('     Index[1] := -2; Index[2] := -3; Index[3] := -4;');
  WriteLn ('     Real(Field.GetAddr^) := PI;');
  WriteLn ('   End.');
  WriteLn;
End;

{$IFNDEF UNIT}
Const DIM = 3;
Const Bound: Array[1..DIM,1..2] Of LongInt = ((-3,30),(-4,40),(-5,50));
Var Index: Array[1..DIM] Of LongInt; Field: PlatauObj; i: LongInt;
Begin
  If Not Field.Init (DIM,SizeOf(Real),Bound,Index) Then RunError(203);
  Index[1] := -2; Index[2] := -3; Index[3] := -4;
  Real(Field.GetAddr^) := PI;
{$ENDIF}
End.
A.E.Neumann für die Antivivisektion e.V., PO-Box 201, D-53569 Unkel
mailto:Antivivisektion@t-online.de http://Antivivisektion.base.org/



   Subject:   Re: Delphi and MS Word
      Date:   Wed, 1 Jul 1998 20:34:32 GMT
      From:   Alan MacArthur <spam-me-not---alan.s.macarthur@boeing.com>
 Organization:The Boeing Company
        To:   Lee Davis <peebles@bigfoot.com>
 Newsgroups:
          alt.comp.lang.borland-delphi, alt.lang.delphi, borland.public.delphi.oleautomation,
          borland.public.delphi.reporting-charting, comp.lang.pascal.delphi, comp.lang.pascal.delphi.misc

Hope this helps, it's not commented very well:

procedure TForm1.Button1Click(Sender: TObject);
var
  I:                         Integer;
  FileHandle:                Integer;

  V:                         Variant;

begin
  V:=CreateOleObject('Word.Basic');
  For I:=1 to 3 do begin
    FileHandle:=V.FileNew('d:\Alan\delphi projects\testole\TextB.dot');

    V.EditGoTo('Title');
    V.Insert('MyTitleIsHere-'+IntToStr(I)+'-');

V.FileSaveAs(Name:='d:\Alan\TestOLE-'+IntToStr(I)+'.doc',Format:=0,AddToMRU:=0);
    V.FileClose(FileHandle);
  end;

  ShowMessage('All done.');
end;
=======

Lee Davis wrote:
>
> Hi,
>
> I am trying to start Word, load a template and fill in fields in the Word
> document with fields from my database including a graphic, but having no
> success.
>
> Can someone please paste me code showing exactly how to do this please?
>
> Many thanks
> Lee



   Subject:   Re: Intersection of 2 lines
      Date:   19 Jul 1998 17:54:25 GMT
      From:   waynechem@aol.com (WayneChem)
 Organization:AOL http://www.aol.com
 Newsgroups:  comp.lang.pascal.borland
 

The following is a farily simple routine to determine if 2 line segments
intersect.  The only exception is if the 2 lines are co-linear.  I'll leave
this check for you to figure out.  I hope this will help you out.

Wayne

{----------------}
Type
  point =
     record
        x,y : integer;
     end;
   lne =
      record
        p1,p2 : point;
     end;

function intersect(L1,L2 : lne) : boolean;
  {checks to see if 2 points lie on the same side of a line or
    on opposite sides...if on opposite side, then intersection occurs and
returns true}

  var
    tb : boolean;
    s1,s2,dx,dy,dx1,dx2,dy1,dy2 : longint;

               {-----------------------------------------------}
               function same(l : lne;p1,p2 : point) : longint;
                 begin
                   dx  := l.p2.x - l.p1.x;
                   dy  := l.p2.y - l.p1.y;
                   dx1 := p1.x - l.p1.x;
                   dy1 := p1.y - l.p1.y;
                   dx2 := p2.x - l.p2.x;
                   dy2 := p2.y - l.p2.y;
                   same := (dx*dy1-dy*dx1)*(dx*dy2-dy*dx2);
                 end;
               {-----------------------------------------------}
  begin
    s1 := same(l1,l2.p1,l2.p2);
    s2 := same(l2,l1.p1,l1.p2);
    tb := (s1<=0) and (s2<=0);
    intersect := tb;
  end;{intersect}
{--------------}

In article <35B12503.3D29@virgin.Net>, Kenn <kenn.p@virgin.Net> writes:

>Hello.
>
>Ive written a routine to calculate the intersection of 2 lines, but
>as its not very fast I thought I pose the problem here rather than
>work on it any more myself ;)
>
>line 1 is defined as x1 y1 x2 y2 (all integer)
>line 2 is defined as sx sy a (start position and angle (0-2047 degrees)
>and of infinate length, and once again all integers.
>
>I dont really want to post the code itself here (its a bit of a mess
>having gone from pascal to asm in many separate stages and then after
>a _lot_ of optimising) but i will if anyone is interested.
>
>Basically the method I've used is to rotate line1 by -a.
>
>I also do a few checks to see if it is impossible for the lines to cross
>(ie impossible if (x2<sx) or (x1>sx) or ((y1>sy) and (y2>sy))
>and checked to see if line1's back is facing (x1>x2)

[snip]



Betreff: Display a bitmap in a MDI frame...
  Datum: Thu, 20 Aug 1998 13:05:50 +0200
    Von: Thomas <senikies@amj-groupe.com>
  Foren: borland.public.delphi.graphics

I'd like to display a bitmap in the main MDI frame (the workspace where
the MDI childs are). Some kind of a logo...
I know this is possible with some WinAPI fonction, something low level
and which draws inside the very form.
I don't wanna use any component, for when you do this, it may not stay
at the middle of the MDI frame and I don't wanna bother with redrawing.
Does anybody have an idea ?
---------------------------
   Betreff: Re: Display a bitmap in a MDI frame...
     Datum: Thu, 20 Aug 1998 13:12:22 GMT
       Von: xavier@xapware.com (Xavier Pacheco (TeamB))
     Foren: borland.public.delphi.graphics

The following unit illustrates how to do this:

--- x

{Copyright © 1998 by Delphi 4 Developer's Guide - Xavier Pacheco and
Steve Teixeira

www.xapware.com/ddg}

unit MainFrm;

interface

uses Windows, SysUtils, Classes, Graphics, Forms, Controls, Menus,
  StdCtrls, Dialogs, Buttons, Messages, ExtCtrls;

type
  TMainForm = class(TForm)
    mmMain: TMainMenu;
    mmiFile: TMenuItem;
    mmiNew: TMenuItem;
    mmiClose: TMenuItem;
    N1: TMenuItem;
    mmiExit: TMenuItem;
    mmiImage: TMenuItem;
    mmiTile: TMenuItem;
    mmiCenter: TMenuItem;
    mmiStretch: TMenuItem;
    imgMain: TImage;
    procedure mmiNewClick(Sender: TObject);
    procedure mmiCloseClick(Sender: TObject);
    procedure mmiExitClick(Sender: TObject);
    procedure mmiTileClick(Sender: TObject);
  private
    FOldClientProc,
    FNewClientProc: TFarProc;
    FDrawDC: hDC;
    procedure CreateMDIChild(const Name: string);
    procedure ClientWndProc(var Message: TMessage);
    procedure DrawStretched;
    procedure DrawCentered;
    procedure DrawTiled;
  protected
    procedure CreateWnd; override;
  end;

var
  MainForm: TMainForm;

implementation

uses MdiChildFrm;

{$R *.DFM}

procedure TMainForm.CreateWnd;
begin
  inherited CreateWnd;
  // Turn the ClientWndProc method into a valid window procedure
  FNewClientProc := MakeObjectInstance(ClientWndProc);
  // Get a pointer to the original window procedure
  FOldClientProc := Pointer(GetWindowLong(ClientHandle, GWL_WNDPROC));
  // Set ClientWndProc as the new window procedure
  SetWindowLong(ClientHandle, GWL_WNDPROC, LongInt(FNewClientProc));
end;

procedure TMainForm.DrawCentered;
{ This procedure centers the image on the form's client area }
var
  CR: TRect;
begin
  GetWindowRect(ClientHandle, CR);
   with imgMain do
     BitBlt(FDrawDC, ((CR.Right - CR.Left) - Picture.Width) div 2,
            ((CR.Bottom - CR.Top) - Picture.Height) div 2,
            Picture.Graphic.Width, Picture.Graphic.Height,
            Picture.Bitmap.Canvas.Handle, 0, 0, SRCCOPY);
end;

procedure TMainForm.DrawStretched;
{ This procedure stretches the image on the form's client area }
var
  CR: TRect;
begin
  GetWindowRect(ClientHandle, CR);
  StretchBlt(FDrawDC, 0, 0, CR.Right, CR.Bottom,
             imgMain.Picture.Bitmap.Canvas.Handle, 0, 0,
             imgMain.Picture.Width, imgMain.Picture.Height, SRCCOPY);
end;

procedure TMainForm.DrawTiled;
{ This procedure tiles the image on the form's client area }
var
  Row, Col: Integer;
  CR, IR: TRect;
  NumRows, NumCols: Integer;
begin
  GetWindowRect(ClientHandle, CR);
  IR := imgMain.ClientRect;
  NumRows := CR.Bottom div IR.Bottom;
  NumCols := CR.Right div IR.Right;
  with imgMain do
    for Row := 0 to NumRows+1 do
      for Col := 0 to NumCols+1  do
        BitBlt(FDrawDC, Col * Picture.Width, Row * Picture.Height,
               Picture.Width, Picture.Height,
Picture.Bitmap.Canvas.Handle,
               0, 0, SRCCOPY);
end;

procedure TMainForm.ClientWndProc(var Message: TMessage);
begin
  case Message.Msg of
    // Capture the WM_ERASEBKGND messages and perform the client area
drawing
    WM_ERASEBKGND:
      begin
        CallWindowProc(FOldClientProc, ClientHandle, Message.Msg,
Message.wParam,
          Message.lParam);
        FDrawDC := TWMEraseBkGnd(Message).DC;
        if mmiStretch.Checked then
          DrawStretched
        else if mmiCenter.Checked then
          DrawCentered
        else DrawTiled;
        Message.Result := 1;
      end;
    { Capture the scrolling messages and ensure the the client area
      is redrawn by calling InvalidateRect }
    WM_VSCROLL, WM_HSCROLL:
      begin
        Message.Result := CallWindowProc(FOldClientProc, ClientHandle,
Message.Msg,
          Message.wParam, Message.lParam);
        InvalidateRect(ClientHandle, nil, True);
      end;
    else
    // By Default, call the original window procedure
      Message.Result := CallWindowProc(FOldClientProc, ClientHandle,
Message.Msg,
        Message.wParam, Message.lParam);
  end; { case }
end;

procedure TMainForm.CreateMDIChild(const Name: string);
var
  MdiChild: TMDIChildForm;
begin
  MdiChild := TMDIChildForm.Create(Application);
  MdiChild.Caption := Name;
end;

procedure TMainForm.mmiNewClick(Sender: TObject);
begin
  CreateMDIChild('NONAME' + IntToStr(MDIChildCount + 1));
end;

procedure TMainForm.mmiCloseClick(Sender: TObject);
begin
  if ActiveMDIChild <> nil then
    ActiveMDIChild.Close;
end;

procedure TMainForm.mmiExitClick(Sender: TObject);
begin
  Close;
end;

procedure TMainForm.mmiTileClick(Sender: TObject);
begin
  mmiTile.Checked := false;
  mmiCenter.Checked := False;
  mmiStretch.Checked := False;
  { Set the Checked property for the menu item which invoked }
  { this event handler to Checked                            }
  if Sender is TMenuItem then
    TMenuItem(Sender).Checked := not TMenuItem(Sender).Checked;
  { Recraw the client area of the form }
  InvalidateRect(ClientHandle, nil, True);
end;

end.

==============================
Xavier Pacheco (TeamB)
xavier@xapware.com

Sorry but TeamB cannot answer support
questions received via email.



Betreff: Drucken vom BMP´s unter TPW printing BMP with TPW
  Datum: Tue, 15 Sep 1998 10:06:49 +-200
    Von: Karsten Krieger <kusedv@evolution.org>
     An: <office@meg-glaser.biz>

Hallo Herr Glaser,

Nach dem Studium der mitgelieferten Beispiele in BPW7.0 habe ich das Problem nun
anscheinend lösen können; alle Blt-Operationen mit dem Handle der Bitmap funktionieren
anscheinend nur mit dem Bildschirm-DC?! Wenn ich jedoch die Funktion die mir das
Handle zum Drucken vergewaltige (mit SetDIBitsToDevice(Hunderttausendparameter)
funktioniert das. SetDIBitsToDevice muß den (Drucker)treiber des DC verwenden, so daß
die ganze Sache auch auf´s Papier kommt. Dankschreiben an Herrn Gates, für mich gehört
in die API eine Funktion DrawBitmap(DC:HDC; FileName:PChar; XPos, YPos, Vieleicht noch
Streck und Stauch und meinetwegen Farbpalette).

Ich hoffe Ihnen damit geholfen zu haben.:->

Karsten Krieger
KUSEDV@Evolution.org

----------------------------
function LoadBitmapFile(FileName: PChar; DC:HDC): HBitmap;

var
  F: Integer;                   { File Handle for Windows file functions }
  H: THandle;                   { Handle to memory for bitmap }
  Size, N: Longint;             { Size of bitmap, Size of color spec }
  P: PBitmapInfo;               { Windows bitmap format info header }
  Header: TBitmapFileHeader;    { Bitmap file header }

begin
  LoadBitmapFile := 0;
  F := _LOpen(FileName, of_Read);
  if F = -1 then Exit;

  { read in the Bitmap file header }
  if (_LRead(F, @Header, SizeOf(Header)) <> SizeOf(Header)) or
    (Header.bfType <> BMType) then
  begin
    _LClose(F);
    Exit;
  end;

  { read the rest of the file }
  Size := _LFileSize(F) - SizeOf(TBitmapFileHeader);
  H := GlobalAlloc(gmem_Moveable, Size);        { Allocate the memory }
  if H = 0 then
  begin
    _LClose(F);
    Exit;
  end;

  P := GlobalLock(H);                           { Lock it down }

  if (HugeIO(_LRead, F, P, Size) <> 0) and
    (P^.bmiHeader.biSize = SizeOf(TBitmapInfoHeader)) then
  begin
    { Compute the offset from the beginning of P^ }
    { where the actual image begins }
    N := Header.bfOffBits - SizeOf(TBitmapFileHeader);

    { actually create the Bitmap }
    LoadBitmapFile := CreateDIBitmap(DC, P^.bmiHeader,
      cbm_Init, Ptr(PtrRec(P).Hi,N),P^, dib_RGB_Colors);
  end;

  {------------------------------> Print Bitmap to DC <------------------------------------}

  SetDIBitsToDevice(DC,
    10, 10, P^.bmiHeader.biWidth, P^.bmiHeader.biHeight, 0, 0, 0, 100,
    Ptr(PtrRec(P).Hi,N), P^, DIB_RGB_Colors);

  {------------------------------> Print Bitmap to DC <------------------------------------}

  GlobalUnlock(H);
  GlobalFree(H);
  _LClose(F);
end;


   Betreff:Re: turbo pascal vers. 3.0 execute instruction
     Datum:21 Sep 1998 18:03:31 -0500
       Von:joefish@iglou.com (Joe Fischer)
     Firma:IgLou Internet Services, Inc.
     Foren:comp.lang.pascal.borland
 

david_echavarria@my-dejanews.com wrote:
: I need to know how to program the execute instruction in
: turbo pascal version 3.0.

        This is what I use, haven't had any trouble.

Joe Fischer

{.F-}
{
Executes any DOS or external command from within Turbo Pascal.
Call as EXECUTE CommandString
CommandString may be any DOS INTERNAL, Batch, COM or EXE command
  and may include command line arguments.
Note that the PATH is automatically searched
  for any external program files.

IMPORTANT: Compile with min heap = $200/ max heap = $200.

The procedure execute_string may be incorporated into any Turbo program.
it is the responsibility of the host program to deallocate sufficient
memory above itself for the external command to execute.

************************WARNING*******************************
*    this technique uses undocumented features of MSDOS.     *
*    It appears to work on all versions of MSDOS (2.X-3.1),  *
*    but since it is undocumented it may not always work.    *
**************************************************************

written by Russ Nelson, Potsdam, NY.
small modifications and uploaded by Kim Kokkonen, 72457,2131.

Other Mods Kerry Kirsch 70176,576 - Shut off Interrupts when messing with
the stack aviod potential big crash. Also ***WARNING*** It appears that this
procedure will close all files open with File Handles, (not files opened
with file control blocks). Also, nested calls of the procedure results in
free memory getting gobbled up. i.e. - Execut c:\Execut dir.
}
{.F+}

PROGRAM Execute;
TYPE
  str255 = STRING[255];
VAR
  commandline : str255 ABSOLUTE CSeg : $80;

  PROCEDURE execute_string(s : str255);
    { execute_string -- execute a command line }
  VAR
    save_ax : Integer;
  CONST
    save_ss : Integer = 0;
    save_sp : Integer = 0;
  BEGIN
    s[Length(s)+1] := ^M;
    INLINE(
      $1E/                    {   push    ds                   }
      $55/                    {   push    bp                   }
      $2E/$8C/$16/save_ss/    {   mov     cs:[save_ss],ss      }
      $2E/$89/$26/save_sp/    {   mov     cs:[save_sp],sp      }
      $8C/$D0/                {   mov     ax,ss                }
      $8E/$D8/                {   mov     ds,ax                }
      $8D/$76/<s/             {   lea     si,s[bp]             }
      $CD/$2E/                {   int     2eh                  }
      $FA/                    {   cli                          }
      $2E/$8E/$16/save_ss/    {   mov     ss,cs:[save_ss]      }
      $2E/$8B/$26/save_sp/    {   mov     sp,cs:[save_sp]      }
      $FB/                    {   sti                          }
      $5D/                    {   pop     bp                   }
      $1F/                    {   pop     ds                   }
      $89/$46/<save_ax        {   mov     save_ax[bp],ax       }
      );
    IF save_ax <> 0 THEN WriteLn('Exit code = ', save_ax);
  END;

BEGIN
  IF Length(commandline) > 0
  THEN execute_string(commandline)
  ELSE execute_string('dir/w');
END.



Betreff:How to set NumLock: The solutions
  Datum:22 Sep 1998 15:26:11 GMT
    Von:"Olivier Avenel" <avenel@spec.saclay.cea.fr>
  Firma:CEA Commissariat a l'Energie Atomique, France.
  Foren:comp.lang.pascal.borland

Thanks to various inputs from Franz Glaser, JKe7306087 and Ulli Conrad
(Coder's Base), I solved my problem of setting NumLock, CapsLock and
ScrollLock on all 3 platforms:

Real mode:
  Mem[$0040:$17]:=Mem[$0040:$17] or $20;         {NumLock ON}
  Mem[$0040:$17]:=Mem[$0040:$17] and (not $20);  {NumLock OFF}
    {NumLock: $20, ScrollLock: $10, CapsLock: $40}

Protected mode:
  Mem[Seg0040:$17]:=Mem[Seg0040:$17] or $20;

Windows:
  uses WinProcs, WinTypes;  {also Win31 for VK_SCROLL}
  var KeyState: TKeyboardState;
  begin
    GetKeyboardState(KeyState);
    KeyState[VK_NUMLOCK]:=#1;           {#0: OFF, #1: ON}
    SetKeyboardState(KeyState);
  end.
    {VK_CAPITAL for CapsLock, VK_SCROLL for ScrollLock}

Took me some time to find out that VK_SCROLL also needs the Win31 unit !!

Thanks again.
___________
Olivier Avenel  SPEC / CEA-Saclay   91191 Gif-sur-Yvette Cedex  France
avenel@spec.saclay.cea.fr



   Betreff:Re: Filemode in TP3
     Datum:Wed, 23 Sep 1998 21:40:05 GMT
       Von:rdonais@leading.net (R.E.Donais)
     Firma:Southeast Network Services, Inc.
     Foren:comp.lang.pascal.borland

"Stephane Landry" <landrys@grics.qc.ca> wrote:

>Hi,
>
>I use in my program in Turbo pascal version 6 the variable "FILEMODE" to
>open files in ReadOnly mode,
>
>I search How I can do the same in the Turbo Pascal version 3.  I know that
>the variable "FILEMODE" does not exist but if you know a way to do the same
>help me please....

I love a challenge.  In this case it helps to have reversed
engineered a copy of Turbo 3.01a as an exercise for learning
x86 assembly. ;-)

You'll have to zap the library's openfile mov AX,3D02h
instruction used for opening typed and untyped files.  That's
the technical side.

The not so technical instructions are to compile and run the
following ditty.  If it beeps "Eureka!", then you can define
VAR FileMode: Byte absolute CSEG:$24FC;  Otherwise let me know
the three hex digits it prints and we'll try again.

    ...red

TYPE Str2 = String[2];
VAR x: Array[0..2] of byte absolute Cseg:$24FB;

Function Hex(x: Byte): Str2;
CONST H: Array[0..15] of Char = '0123456789ABCEDF';
Begin
    Hex := h[x shr 4] + h[x and $F];
End;

BEGIN
    If (x[0] = $B8) and (x[1] = $02) and (x[2] = $3D) Then
       Writeln('Eureka!'#7)
    Else Writeln(Hex(x[0]), ' ', Hex(x[1]), ' ',Hex(x[2]))
END.
 
 

   Betreff: Re: TurboPascal 6 fonction Not in TP3
     Datum: Fri, 25 Sep 1998 03:11:26 GMT
       Von: rdonais@leading.net (R.E.Donais)
      Firma:Southeast Network Services, Inc.
      Foren:comp.lang.pascal.borland
 

Stephane and I resolved the problem through email.  I was working
with a PC-DOS 3.01A version of TP and she had an earlier PC-DOS
3.00B version.  The 3-byte instruction in the earlier version is
located at $248C so filemode for the two versions can be defined
as:

{VERSION 3.00B} VAR FileMode: Byte absolute CSEG:$248D;
{VERSION 3.01A} VAR FileMode: Byte absolute CSEG:$24FC;

    ...red


   Betreff: Re: Source code for the Procedure FormatStr in DRIVERS.TPU ???
     Datum: 25 Sep 1998 16:33:26 GMT
       Von: ldeboer@ibm.net
      Firma:IBM.NET
      Foren:comp.lang.pascal.borland
 

In <35f975a4.0@d2o206.telia.com>, "AGH" <arnt.gustav.haagensen@nt.telia.no> writes:
>The DRIVERS.TPU "unit"  is included on TP disks.
>
>I am looking for the  source code for ...
>  Procedure FormatStr(String, String, Pointer);
>
>Does any one have the source code for the DRIVERS.TPU file or
>the FormatStr procedure ???
>
>Best  Regards
>AGH
>arnt.gustav.haagensen@nt.telia.no
>

This is from our Free Vision project

{---------------------------------------------------------------------------}
{  FormatStr -> Platforms DOS/DPMI/WIN/NT/OS2 - Updated 13Aug98 LdB         }
{---------------------------------------------------------------------------}
PROCEDURE FormatStr (Var Result: String; CONST Format: String; Var Params);
TYPE TLongArray = Array[0..0] Of LongInt;
VAR ResultLength, FormatIndex, Justify, Wth: Byte; Fill: Char; S: String;

   FUNCTION LongToStr (L: Longint; Radix: Byte): String;
   CONST HexChars: Array[0..15] Of Char =
    ('0', '1', '2', '3', '4', '5', '6', '7',
     '8', '9', 'A', 'B', 'C', 'D', 'E', 'F');
   VAR I: LongInt; S: String; Sign: String[1];
   BEGIN
     LongToStr := '';                                 { Preset empty return }
     If (L < 0) Then Begin                            { If L is negative }
       Sign := '-';                                   { Sign is negative }
       L := Abs(L);                                   { Convert to positive }
     End Else Sign := '';                             { Sign is empty }
     S := '';                                         { Preset empty string }
     Repeat
       I := L MOD Radix;                              { Radix mod of value }
       S := HexChars[I] + S;                          { Add char to string }
       L := L DIV Radix;                              { Divid by radix }
     Until (L = 0);                                   { Until no remainder }
     LongToStr := Sign + S;                           { Return result }
   END;

   PROCEDURE HandleParameter (I : LongInt);
   BEGIN
     While (FormatIndex <= Length(Format)) Do Begin   { While length valid }
       While (Format[FormatIndex] <> '%') AND         { Param char not found }
       (FormatIndex <= Length(Format)) Do Begin       { Length still valid }
         Result[ResultLength+1] := Format[FormatIndex]; { Transfer character }
         Inc(ResultLength);                           { One character added }
         Inc(FormatIndex);                            { Next param char }
       End;
       If (FormatIndex < Length(Format)) AND          { Not last char and }
       (Format[FormatIndex] = '%') Then Begin         { '%' char found }
         Fill := ' ';                                 { Default fill char }
         Justify := 0;                                { Default justify }
         Wth := 0;                                    { Default 0=no width }
         Inc(FormatIndex);                            { Next character }
         If (Format[FormatIndex] = '0') Then
           Fill := '0';                               { Fill char to zero }
         If (Format[FormatIndex] = '-') Then Begin    { Optional just char }
           Justify := 1;                              { Right justify }
           Inc(FormatIndex);                          { Next character }
         End;
         While ((FormatIndex <= Length(Format)) AND   { Length still valid }
         (Format[FormatIndex] >= '0') AND
         (Format[FormatIndex] <= '9')) Do Begin       { Numeric character }
           Wth := Wth * 10;                           { Multiply x10 }
           Wth := Wth + Ord(Format[FormatIndex])-$30; { Add numeric value }
           Inc(FormatIndex);                          { Next character }
         End;
         If ((FormatIndex <= Length(Format)) AND      { Length still valid }
         (Format[FormatIndex] = '#')) Then Begin      { Parameter marker }
           Inc(FormatIndex);                          { Next character }
           HandleParameter(Wth);                      { Width is param idx }
         End;
         If (FormatIndex <= Length(Format)) Then Begin{ Length still valid }
           Case Format[FormatIndex] Of
             'c': S := Char(TLongArray(Params)[I]);  { Character parameter }
             'd': S := LongToStr(TLongArray(Params)[I],
               10);                                   { Decimal parameter }
             's': S := PString(TLongArray(Params)[I])^;{ String parameter }
             'x': S := LongToStr(TLongArray(Params)[I],
               16);                                   { Hex parameter }
           End;
           Inc(FormatIndex);                          { Next character }
           If (Wth > 0) Then Begin                    { Width control active }
             If (Length(S) > Wth) Then Begin          { We must shorten S }
               If (Justify=1) Then                    { Check right justify }
                 S := Copy(S, Length(S)-Wth+1, Wth)   { Take right side data }
                 Else S := Copy(S, 1, Wth);           { Take left side data }
             End Else Begin                           { We must pad out S }
               If (Justify=1) Then                    { Right justify }
                 While (Length(S) < Wth) Do
                   S := S+Fill Else                   { Right justify fill }
                 While (Length(S) < Wth) Do
                   S := Fill + S;                     { Left justify fill }
             End;
           End;
           Move(S[1], Result[ResultLength+1],
             Length(S));                              { Move data to result }
           ResultLength := ResultLength + Length(S);  { Adj result length }
         End;
       End;
     End;
   END;

BEGIN
   ResultLength := 0;                                 { Zero result length }
   FormatIndex := 1;                                  { Format index to 1 }
   HandleParameter(0);                                { Handle parameter }
   Result[0] := Chr(ResultLength);                    { Set string length }
END;



   Betreff: Re: Novel Netware 3.12    GetNovellUserName:=GetUserName;
     Datum: Wed, 30 Sep 1998 17:39:04 +0200
       Von: "Paul" <paul.backus@writeme.com>
      Foren:comp.lang.pascal.borland

Allen,

Take a look at this

Function GetNovellUserName : TStrg;

Type ObjectStr = String[47];
     Str15     = string[15];

     DayOfTheWeek     = (Sunday,Monday,Tuesday,Wednesday,Thursday,
                         Friday,Saturday);

     NovDateType      = record
                         Year,                     {80=1980}
                         Month,
                         Day,
                         Hour,
                         Minute,
                         Second     : Byte;
                         WeekDay    : DayOfTheWeek;
                         Filler     : Byte;
                        end;
 

     ConnInfoType     = record
                          ObjectID   : LongInt;     {the logged in object's
ID}
                          ObjectType : Word;        {the logged object's
type}
                          ObjectName : String[48];  {the name of the object}
                          LoginDate  : NovDateType; {the time/date the
object}
                                                 {logged on to connection}
                        end;
 
 

function NetWareLoaded(var LoggedOn : Boolean) : Boolean;
{-Returns TRUE if NetWare shell is loaded}
var
  NovRegs : Registers;

  Request : record
              Len    : Word;
              SubF   : Byte;
            end;

  Reply   : record
              Len    : Word;
              Access : Byte;
              ID     : LongInt;
            end;

begin
  FillChar(Reply,SizeOf(Reply),0);
  Reply.Len := 5;

  with Request do begin
    Len := 1;
    SubF := $46;
  end;

  with NovRegs do begin
    AH := $E3;
    DS := Seg(Request);  {DS:SI points to request}
    SI := Ofs(Request);
    ES := Seg(Reply);    {ES:DI points to reply}
    DI := Ofs(Reply);
    MsDos(NovRegs);      {MsDos = Intr $21}
    with Reply do begin
      NetWareLoaded := (AL=0) and (ID <> 0);
      LoggedOn      := (AL=0) and ((ID <> 0) and (ID <> -1));
    end;
  end;
end;
 
 
 

function GetConnNo : Byte;
{ returns connection number of requesting WS (1..MaxConnections) }

var
  NovRegs          : Registers; { register type for DOS/Novell calls }

begin
  {Novell function DCh subfunc 0}
  with NovRegs do
    AX := $DC00;
  MsDos(NovRegs);    {MsDos = Intr $21}
  GetConnNo := NovRegs.AL   {connection number from AL}
end;
 

function AsciiZ2Str(var Buffer; Max : Byte) : String;

const
  AsciiZMAX        = 255;

type
  AsciiZBuffer     = Array[1..AsciiZMAX] of Char;

var
  A                : AsciiZBuffer absolute Buffer;
  I                : Word;
  S                : String;

begin
  I := 1;
  { search for terminating #0, stop if max string length exceeded}
  while (A[I] <> #0) and (I < Max) do begin
    S[I] := A[I];
    Inc(I);
  end;
  S[0] := Char(I-1);
  AsciiZ2Str := S  {return the string}
end;
 
 

Function NetwareSwapLongPB (Li : Longint) : Longint;

Var Result : Record
       AW : Word;
       BW : Word;
    End;

Begin
  Move(Mem[Seg(Li):Ofs(li)],Result.Aw,2);
  Move(Mem[Seg(Li):Ofs(li)+2],Result.Bw,2);

  {Of Move (Li,Result,4);}

  With Result Do
    Begin
      Aw:=Swap(Aw); {Swap Lo,Hi part of word}
      Bw:=Swap(Bw);
    End;

  {Letop hier wordt ook nog gewisseld}

  Move(Result.Bw,Mem[Seg(Li):Ofs(li)],2);
  Move(Result.Aw,Mem[Seg(Li):Ofs(li)+2],2);

  NetwareSwapLongPB:=Li;
End;
 
 

procedure GetConnInfo(ConnNo : Byte; var ConnInfo : ConnInfoType);
{Get information about the object logged on to a given connection. The
 information returned includes the object's ID, the object type, the
object's
 name, and the time and date it logged on to the connection.
}

var
  NovRegs          : Registers;
  Request          : record
                       Len     : Word;
                       SubF    : Byte;
                       Conn    : Byte;
                     end;

  Reply            : record
                       Len     : Word;
                       ID      : LongInt;
                       ObjType : Word;
                       ObjName : Array[1..48] of Char;
                       Time    : NovDateType;
                     end;
 

begin
  Reply.Len := SizeOf(Reply) - 2;      {!!.03}
  with Request do begin
    Len  := 2;
    SubF := $16;
    Conn := ConnNo;
  end;
  with NovRegs do begin
    AH := $E3;
    DS := Seg(Request);  {DS:SI points to request}
    SI := Ofs(Request);
    ES := Seg(Reply);    {ES:DI points to reply}
    DI := Ofs(Reply);
    MsDos(NovRegs);      {MsDos = Intr $21}
  end;

  with ConnInfo do begin
    ObjectID   := NetWareSwapLongPB(Reply.ID);
    ObjectType := Swap(Reply.ObjType);
    ObjectName := AsciiZ2Str(Reply.ObjName,48);
    LoginDate  := Reply.Time;
  end;
end;

function GetUserName : ObjectStr;

var
    ConnInfo : ConnInfoType;
    LoggedIn : boolean;

begin
  if NetwareLoaded(LoggedIn) and LoggedIn then
    begin
      GetConnInfo(GetConnNo, ConnInfo);
      GetUserName := ConnInfo.ObjectName
    end
  else GetUserName := ''
end;  { GetUserName }
 

Begin
  GetNovellUserName:=GetUserName;
End;







tpqa index    tpqa_3 back    tpqa_5 forward

Get your own FREE HOMEPAGE