Source file: /~heha/messtech/kreuzt.zip/GRILL/SMSP.PAS

unit smsp;
{Sammlung diverser allgemeiner Unterprogramme zum Thema
 * Zahlen-Konvertierung
 * Zahlen-String-Konvertierung
 * Meldungsbox mit String-ID
 * Mul und Div (eher Selbstzweck)
}
{$C PRELOAD FIXED}
interface
uses WinProcs,WinTypes,Strings,WinDos,SMSH,UMSTEP;

function GetReal(HWindow:HWnd; ID: Word; var Z:TReal):boolean;

function Real2S(Z:TReal; F:Integer; S:PChar):PChar;
function S2Real(S:PChar; var Z: TReal):boolean;

function Hinweis(Wnd:HWnd; ID:Word; var p):Integer;
function Hinweis1(Wnd:HWnd; ID:Word; S:PChar):Integer; {1 arg}
{Notfalls auch 2 Integer-Argumente mit PChar(MakeLong(Par2,Par1)) }

procedure ShortYield;

function LongMul(F1,F2:Integer):LongInt;
 inline($5A/$58/$F7/$EA);	{pop dx; pop ax; imul dx}
function ULongMul(F1,F2:Word):LongInt;
 inline($5A/$58/$F7/$E2);	{pop dx; pop ax; mul dx}
function LongDiv(Z:LongInt; N:Integer):Integer;
 inline($59/$58/$5A/$F7/$F9);	{pop cx; pop ax; pop dx; idiv cx}
function ULongDiv(Z:LongInt; N:Word):Word;
 inline($59/$58/$5A/$F7/$F1);	{pop cx; pop ax; pop dx; div cx}
function ULongMod(Z:LongInt; N:Word):Word;
 inline($59/$58/$5A/$F7/$F1/$87/$C2);
 {pop cx; pop ax; pop dx; div cx; xchg ax,dx}

function GetDlgItemHex(Wnd:HWnd; ID:Word; var W:Word):Boolean;

procedure MotorCallback;

const
 AMotor:TMotor=(
  Handle:	0;
  CFlags:	MC_Trapeze or MC_Table;
  RefW:		$0101;
  PortHWE:	$2C0;
  PortA:	$2C0;
  PortB:	$2C1;
  CallbackAddr:	@MotorCallback;
  CallbackDS:	Seg(HInstance);
  CallbackUser:	0;
  MaxSpeed:	48*65536;
  RefSpeed:	12*65536;
  MaxAccel:	48;
  Refpoint:	0;
  LeftBound:	-MaxLongInt;
  RightBound:	+MaxLongInt;
  EndW:		$0303;
  BrakeW:	$0000);

procedure SetMotorStruc;

function GetFileNamePtr(S:PChar):PChar;
const
 ARV_CantRemove = 1;
 ARV_CantAdd = 2;
 ARV_FailCreateTempFile = -2;
 ARV_FailOpenSystemIni = -3;
 ARV_FailReadWrite = -4;
 ARV_FailDelete = -5;
 ARV_FailRename = -6;
function AddRemoveVxD(AddPath,RemovVxD:PChar):Integer;

implementation

function GetReal(HWindow:HWnd; ID: Word; var Z:TReal):boolean;
 var
  S: TS31;
 begin
  GetDlgItemText(HWindow,ID,S,sizeof(S));
  GetReal:=S2Real(S,Z);
 end;

function Real2S(Z:TReal; F:Integer; S:PChar):PChar;
{Diese Funktion arbeitet wie Str(Z:F:F,S), jedoch werden unnötige
 Nachkommastellen (Nullen) abgeschnitten}
{STR erwartet String-Längenangabe; daher mit wildem Typecast ruhigstellen}
 begin
  Str(Z:F:F,TS255(Pointer(S)^));	{mittels Systemfunktion wandeln}
  Real2S:=S;		{Stringzeiger durchreichen}
  S:=StrScan(S,'.');	{Dezimalpunkt enthalten?}
  if S<>nil then begin
   S:=StrEnd(S);	{Auf die Null}
   repeat
    Dec(S);		{Zeiger aufs Stringende (vor die Null)}
    if S^='.' then begin {String besteht nur (noch) aus dem Dezimalpunkt?}
     S^:=#0;		{String kürzen und raus!}
     break;
    end;
    if S^='0' then S^:=#0	{Stringende ist die Null? - Kürzen und weiter}
    else break;		{sonst raus!}
   until false;
  end;
 end;

function S2Real(S:PChar; var Z: TReal):boolean;
{wie Val(), jedoch vorher Komma zu Punkt wandeln}
{Weißraum (TAB & SPC) am Anfang wird übergangen, Weißraum (#0..' ')
 am Ende auch, beim Abhacken wird das Zeichen zwischendurch gemerkt.
 Achtung: Bei Fehler wird eine 0.0 in die Variable Z geschrieben!}
 var
  I:Integer;
  SP: PChar;
  MemChr: Char;
 begin
  while (S^=' ') or (S^=#9) do Inc(S);	{Weißraum am Anfang übergehen}
  SP:=StrScan(S,',');
  if SP<>nil then SP^:='.';	{Komma zum Punkt machen}
  SP:=S;
  while SP^>' ' do Inc(SP);	{Ende des Strings suchen}
  MemChr:=SP^; SP^:=#0;		{Zeichen merken, String abhacken}
  Val(S,Z,I);
  SP^:=MemChr;			{Zeichen zurückschreiben}
  S2Real:= (I=0);		{false wenn Fehler in Real-Zahl}
 end;

function Hinweis(Wnd:HWnd; ID:Word; var p):Integer;
{HINWEIS lädt einen String aus der Resource mit der entsprechenden ID und
zeigt ihn in einer Messagebox an. Da Resourcenstrings ein Längenbyte haben,
dient ein eventuelles #0-Zeichen im String als Trenner zwischen Text und Titel}
 var
  S,S2: TS255;			{2 Puffer; leider so erforderlich}
  SPT,SPH: PChar;		{Zeiger auf Text und Titel}
  I,K: Integer;
  TextType:Word;
 begin
  TextType:=MB_OK or MB_IconExclamation;
  I:=LoadString(HInstance,ID,S,sizeof(S)); {I=Anzahl der Zeichen insgesamt}
  SPT:=S;
  if S[0]='$' then begin
   Val(S,TextType,K);
   SPT:=StrEnd(S)+1;
  end;
  SPH:=StrEnd(SPT)+1;
  if SPH-S>I then SPH:=AppName;
  MessageBeep(TextType);
  wvsprintf(S2,SPT,P);
  Hinweis:=MessageBox(Wnd,S2,SPH,TextType);
 end;

function Hinweis1(Wnd:HWnd; ID:Word; S:PChar):Integer;
 begin
  Hinweis1:=Hinweis(Wnd,ID,S);
 end;

procedure ShortYield;
 var
  Msg: TMsg;
 begin
  if PeekMessage(Msg,0,0,0,PM_Remove) then begin
   TranslateMessage(Msg);
   DispatchMessage(Msg);
  end;
 end;

procedure MotorCallback; assembler;
 asm
	push	dx	{Window}
	push	cx	{Message}
	push	ax	{wParam=Flags und Handle}
	push	di
	push	si	{lParam=Position}
	call	PostMessage
 end;

procedure SetMotorStruc;
 var
  Freq: TReal;
  Swap: LongInt absolute Freq;
 begin
  Freq:=SMGetIntFreq;
  with MotorR do begin
   AMotor.MaxSpeed:=Round(Abs(MaxSpeed*256*65536*StepsPerUnit/Freq));
   AMotor.RefSpeed:=Round(RefSpeed*256*65536*StepsPerUnit/Freq);
   AMotor.MaxAccel:=Round(Abs(MaxAccel*256*65536*StepsPerUnit/sqr(Freq)));
   AMotor.Refpoint:=Round(RefPoint*256*StepsPerUnit);
   AMotor.LeftBound:=Round(LeftBound*256*StepsPerUnit);
   AMotor.RightBound:=Round(RightBound*256*StepsPerUnit);
  end;
  if AMotor.LeftBound>AMotor.RightBound then begin
   Swap:=AMotor.LeftBound;
   AMotor.LeftBound:=AMotor.RightBound;
   AMotor.RightBound:=Swap;	{Tauschen der Ränder}
  end;
 end;

function GetDlgItemHex(Wnd:HWnd; ID:Word; var W:Word):Boolean;
 var
  S: TS31;
  HW: Word;
  EC: Integer;
 begin
  GetDlgItemHex:=false;
  GetDlgItemText(Wnd,ID,S+1,sizeof(S)-1);
  S[0]:='$';
  Val(S,HW,EC);
  if EC=0 then begin
   W:=HW;
   GetDlgItemHex:=true;
  end;
 end;

function GetFileNamePtr(S:PChar):PChar; assembler;
{** OK für DLL **}
{liefert Zeiger hinter das letzte Auftreten von /\: oder Stringanfang}
 asm	les	si,[S]
	cld
@@ME:	mov	dx,si	{Mögliches Ende merken}
@@l:	seges	lodsb
	cmp	al,'\'
	jz	@@ME
	cmp	al,'/'
	jz	@@ME
	cmp	al,':'
	jz	@@ME
	or	al,al
	jnz	@@l
	mov	ax,es
	xchg	dx,ax
 end;

function AddRemoveVxD(AddPath,RemovVxD:PChar):Integer;
{** OK für DLL **}
 const
  devkey: array[0..7]of Char='device=';
 var
  f1,f2: Text;	{zum SYSTEM.INI parsen}
  S,Line: array[0..255]of Char;
  PS,PL: PChar;
  InsideSection,CopyLine: Boolean;
  W: Word;
 begin
  WritePrivateProfileString(nil,nil,nil,'SYSTEM.INI');	{Cache leeren}
  W:=GetWindowsDirectory(S,sizeof(S));
  if S[W-1]<>'\' then begin S[W]:='\'; S[W+1]:=#0; end;	{Backslash anhängen}
  PS:=S+lStrLen(S);		{auf die Null}
  lStrCpy(PS,'SYSTEM.IN$');	{Tempname anhängen}
  Assign(f2,S); ReWrite(f2);	{zum Schreiben öffnen}
  if IOResult<>0 then begin
   AddRemoveVxD:=ARV_FailCreateTempFile;
   exit;
  end;
  lStrCpy(PS,'SYSTEM.INI');	{Richtigen Namen anhängen}
  Assign(f1,S); Reset(f1);	{zum Lesen öffnen}
  if IOResult<>0 then begin
   AddRemoveVxD:=ARV_FailOpenSystemIni;
   exit;
  end;
  InsideSection:=false;
  while not eof(f1) do begin
   ReadLn(f1,Line); CopyLine:=true;
   if Line[0]='[' then begin
    InsideSection:=(StrLIComp(Line,'[386Enh]',8)=0);
    if InsideSection and (AddPath<>nil) then begin
     WriteLn(f2,Line);			{Sektionsbeginn beibehalten}
     WriteLn(f2,devkey,AddPath);	{Neue Zeile hinzufügen}
     AddPath:=nil;			{Einmal hinzufügen genügt}
     CopyLine:=false;			{nichts weiter...}
    end;
   end else begin
    if InsideSection
    and (RemovVxD<>nil)
    and (StrLIComp(Line,devkey,7)=0)
    and (lStrCmpi(GetFileNamePtr(Line+7),RemovVxD)=0) then begin
     CopyLine:=false;
     RemovVxD:=nil;			{erledigt}
    end;
   end;
   if CopyLine then WriteLn(f2,Line);
  end;
  Close(f1); Close(f2);
  if IOResult<>0 then begin
   AddRemoveVxD:=ARV_FailReadWrite;
   exit;	{Problem! Quelle nicht löschen!}
  end;
  Erase(f1);			{Quelle löschen}
  if IOResult<>0 then begin
   AddRemoveVxD:=ARV_FailDelete;
   exit;
  end;
  ReName(f2,S);			{Ziel umbenennen}
  if IOResult<>0 then begin
   AddRemoveVxD:=ARV_FailRename;
   exit;
  end;
  AddRemoveVxD:=0;
  if RemovVxD<>nil then AddRemoveVxD:=ARV_CantRemove;
  if AddPath<>nil then AddRemoveVxD:=ARV_CantAdd;
 end;


end.
Detected encoding: OEM (CP437)1
Wrong umlauts? - Assume file is ANSI (CP1252) encoded