Pascal Calculator - calculator

I am now developing a calculator in Pascal and I am getting this error that while the exponent is negative the result is always 0. Can someone help me with this?
Here is the piece of code for this function that I wrote so far:
5: Begin
clrscr;
Writeln('POWER');
Write('Base: ');
Readln(pot1);
Write('Exponent: ');
Readln(pot2);
res5 := 1;
if pot2 < 0 then
Begin
pot1 := 1 div pot1;
pot2 := -pot2;
res5 := 1 / res5;
End;
while pot2 > 0 do
Begin
res5 := res5 * pot1;
pot2 := pot2 - 1;
End;
Writeln('The result is: ', res5:0:4);
Readkey;
End;

Related

Addition menu using case of in Pascal

I am trying to add a menu using the case of in Pascal. I'm using pascal, what's wrong with this code statement to the case?
This is my program on pascal:
program InputNilai;
uses crt;
var
a,b,h : integer;
pilihan : char;
begin
clrscr;
write('1. Penjumlahan');
write('2. Perkalian');
write('Masukkan pilihan: '); readln(pilihan);
// menggunakan kondisi case of
case (pilihan) of
A : begin
write('Masukkan angka pertama: '); readln(a);
write('Masukkan angka kedua: '); readln(b);
h := a + b;
writeln('Result is: ',h);
end;
B : begin
write('Masukkan angka pertama: '); readln(a);
write('Masukkan angka kedua: '); readln(b);
h := a * b;
writeln('Result is ',h);
end;
else
writeln('Not valid');
end;
readln;
end.
program InputNilai;
uses crt;
var
a,b,h : integer;
pilihan : integer;
begin
clrscr;
writeln('1. Penjumlahan');
writeln('2. Perkalian');
writeln('Masukkan pilihan: ');
readln(pilihan);
// menggunakan kondisi case of
Case pilihan of
1:begin
writeln('Masukkan angka pertama: '); readln(a);
writeln('Masukkan angka kedua: '); readln(b);
h := a + b;
writeln('Result is: ',h);
end;
2:begin
writeln('Masukkan angka pertama: '); readln(a);
writeln('Masukkan angka kedua: '); readln(b);
h := a * b;
writeln('Result is ',h);
end;
else
writeln('Not valid');
end;
readln;
end.

Delphi 10.4. Fast Report 6. REST application. Print Failure

I have created a REST server in Delphi using WebBroker. My intention is to use it as a label printer. A client prepares and sends a JSON request detailing the printer name, Fast Report & variables. The server reads the JSON, creates a tFrxReport object loads the requisite report and populates the variables.
This all works admirably, except it will not print to a physical printer. If I select OneNote as my destination, the label is saved to the desktop. If I select a network attached printer, no label emerges.
I have tried PrintOptions.ShowDialog:=True The print dialog shows, indicating the correct printer, but it does not print.
If anyone has any experience, could you point me in the right direction please?
function processJson(itm : sat; jtr : tJsonTextReader): sat;
var
idx : integer;
//itm : sat; // simple array type [idx, 'val1', 'val2']
begin
setlength(itm,0);
idx:=0;
while jtr.Read do
begin
if jtr.TokenType = tJsonToken.PropertyName then
begin
setlength(itm, length(itm)+1);
itm[idx].st_idx := idx;
itm[idx].st_code := jtr.Value.ToString; // property name
jtr.Read;
itm[idx].st_desc := jtr.Value.AsString; // property value
inc(idx);
end;
end;
processJson := itm;
end;
function getPrinterInfo(pnam: string):printinfo_type;
var
ptr : printinfo_type;
idx : integer;
begin
ptr.idx := -1; //default printer
ptr.name := trim(pnam);
for idx := 0 to Printer.Printers.Count - 1 do
if AnsiContainsText(Printer.Printers[idx], ptr.name) then
ptr.idx := idx;
result := ptr;
end;
procedure Ttfdq.tfdqactLabelAction(Sender: TObject; Request: TWebRequest;
Response: TWebResponse; var Handled: Boolean);
var
post : simpleArray_type;
pdx, idx, iitm : integer;
jtr : tJsonTextReader;
sr : tStringReader;
pish : string;
fr : tFrxReport;
thePtr : printinfo_type;
itm : sat;
tstprt : boolean;
begin
d.myHost := 'http://' + Request.host + ':' + intToStr(Request.ServerPort);
d.hostIP := Request.host;
d.Request := Request;
d.Response := Response;
d.remAddr := Request.RemoteAddr;
post := explode(Request.Content);
tstprt := false;
pdx := isset(post, 'json');
pish:='';
if (pdx >=0) then
begin
sr := tStringReader.Create(post[pdx].st_desc);
jtr := tJsonTextReader.Create(sr);
while jtr.read do
begin
if jtr.TokenType = tJsonToken.StartObject then
itm := processJson(itm, jtr);
end;
if fileexists(itm[2].st_desc) then
begin
thePtr := getPrinterInfo(itm[1].st_desc);
fr := tFrxReport.Create(nil);
fr.LoadFromFile(itm[2].st_desc);
// pre load any vars so report does not fail
for idx := 0 to fr.Variables.Count-1 do
fr.Variables.Items[iitm].Value := frText('');
for idx := 4 to High(itm) do
begin
pish := pish + 'index of '+itm[idx].st_code+' = '+ intToStr (fr.Variables.IndexOf(itm[idx].st_code))+'<br>';
iitm := fr.Variables.IndexOf(itm[idx].st_code);
if iitm > -1 then
fr.Variables.Items[iitm].Value := frText(itm[idx].st_desc);
end;
if fr.PrepareReport then
begin
//fr.ShowPreparedReport;
fr.PrintOptions.Printer := thePtr.name;
fr.PrintOptions.PrnOutFileName := 'Trace Label';
fr.PrintOptions.ShowDialog := tstprt;
fr.ShowProgress := tstprt;
fr.Print;
end;
fr.Free;
end;
Response.Content := pish ;
end
else
begin
Response.Content := '<html>' +
'<head><title>Label List</title></head>' +
'<body>This is only used by print serve clients</p>'+
'</body>' +
'</html>';
end;
end;
The problem lies here:
fr.PrintOptions.PrnOutFileName := 'Trace Label';
I erroneously thought that would add a description in the print queue. What it actually did is send the report into limbo :)

InputQuery Formatting Issues

I'm having trouble with InputQuery/InputBox on Delphi XE2.
The input area is out of place (should be under text).
Is there a way to re-align it before making my own input form?
Thank you!
InputQuery() is not designed to be used in this manner. The prompt text is meant to be a short label displayed to the left of the text field (similar to TLabeledEdit). It is not designed to display instructions above the prompts, like you are attempting. This situation would be much better handled by simply creating your own custom Form using whatever controls and layouts you want. For instance, using TDateTimePicker for dates and times, TCheckBox or TRadioGroup to indicate repeats, etc.
However, that being said, InputQuery() is implemented using a custom VCL TForm, so it is technically possible to accomplish what you are trying to achieve. You can use the TScreen.OnActiveFormChange event to gain access to the Form object when it becomes visible, and then you can manipulate it however you want. For example:
procedure TMyForm.ActiveFormChanged(Sender: TObject);
var
Form: TCustomForm;
Prompt: TLabel;
Edit: TEdit;
Ctrl: TControl;
I, J, ButtonTop: Integer;
begin
Form := Screen.ActiveCustomForm;
if (Form = nil) or (Form.ClassName <> 'TInputQueryForm') then Exit;
for I := 0 to Form.ControlCount-1 do
begin
Ctrl := Form.Controls[i];
if Ctrl is TLabel then
begin
Prompt := TLabel(Ctrl);
end
else if Ctrl is TEdit then
begin
Edit := TEdit(Ctrl);
end;
end;
Edit.SetBounds(Prompt.Left, Prompt.Top + Prompt.Height + 5, Prompt.Width, Edit.Height);
Form.ClientWidth := (Edit.Left * 2) + Edit.Width;
ButtonTop := Edit.Top + Edit.Height + 15;
J := 0;
for I := 0 to Form.ControlCount-1 do
begin
Ctrl := Form.Controls[i];
if Ctrl is TButton then
begin
Ctrl.SetBounds(Form.ClientWidth - ((Ctrl.Width + 15) * (2-J)), ButtonTop, Ctrl.Width, Ctrl.Height);
Form.ClientHeight := Ctrl.Top + Ctrl.Height + 13;
Inc(J);
end;
end;
end;
procedure TMyForm.DoSomething;
var
value: string;
begin
Screen.OnActiveFormChange := ActiveFormChanged;
try
InputQuery('Enter New Schedule', 'Format: <Second> <Minute> <Hour> <Day_of_the_Month> <Month_of_the_Year> <Day_of_the_Week> <Year>.'#10'Use * for repeating cycles. ex: 0 0 7 * * * * (trigger at 7AM everyday)', value);
finally
Screen.OnActiveFormChange := nil;
end;
end;
Alternatively:
class procedure TScreenEvents.ActiveFormChanged(Sender: TObject);
var
Form: TCustomForm;
Instructions: TLabel;
Ctrl: TControl;
I, J, K, Offset: Integer;
begin
Form := Screen.ActiveCustomForm;
if (Form = nil) or (Form.ClassName <> 'TInputQueryForm') then Exit;
for I := 0 to Form.ControlCount-1 do
begin
Ctrl := Form.Controls[I];
if Ctrl is TLabel then
begin
Instructions := TLabel.Create(Form);
Instructions.Parent := Form;
Instructions.Caption := 'Format: <Second> <Minute> <Hour> <Day_of_the_Month> <Month_of_the_Year> <Day_of_the_Week> <Year>.'#10'Use * for repeating cycles. ex: 0 0 7 * * * * (trigger at 7AM everyday)';
Instructions.SetBounds(Ctrl.Left, Ctrl.Top, Instructions.Width, Instructions.Height);
Offset := Instructions.Top + Instructions.Height + 5;
Form.ClientWidth := Instructions.Width + (Instructions.Left * 2);
K := 0;
for J := 0 to Form.ControlCount-1 do
begin
Ctrl := Form.Controls[J];
if Ctrl <> Instructions then
begin
Ctrl.Top := Ctrl.Top + Offset;
if Ctrl is TEdit then
begin
Ctrl.Width := (Form.ClientWidth - Ctrl.Left - Instructions.Left);
end
else if Ctrl is TButton then
begin
Ctrl.Left := (Form.ClientWidth - (Ctrl.Width + 5) * (2-K));
Inc(K);
end;
end;
end;
Form.ClientHeight := Form.ClientHeight + Offset;
Break;
end;
end;
end;
procedure TMyForm.DoSomething;
var
value: string;
begin
Screen.OnActiveFormChange := ActiveFormChanged;
try
InputQuery('Enter New Schedule', 'Value', value);
finally
Screen.OnActiveFormChange := nil;
end;
end;

How to prevent forms moving of screen

I use the following helper for preventing forms moving of screen and it is most of the time working OK. But if I open a wsNormal form in a MDI app then the form might show up of the area where it is supposed to be. I can then just move it a bit and then the unit here takes over and moves it in place.
My question is now: how can I either prevent this from happening or send a message to the form saying it is moving so the unit her can do its job.
unit U_FormsMove;
interface
uses
Messages, Windows, Forms;
{$M+}
type
TForm = class(Forms.TForm)
private
protected
procedure WMMoving(var message : TWMMoving); message WM_MOVING;
published
public
end;
implementation
function GetMovementArea: TRect;
var
MovementRect: TRect;
begin
if Application.MainForm.FormStyle = fsMDIForm then
Windows.GetWindowRect(Application.MainForm.ClientHandle, MovementRect)
else
SystemParametersInfo(SPI_GETWORKAREA, 0, #MovementRect, 0);
if MovementRect.Top < 150 then
MovementRect.Top := 150;
MovementRect.Top := MovementRect.Top + 5;
MovementRect.Left := MovementRect.Left + 5;
MovementRect.Right := MovementRect.Right - 5;
MovementRect.Bottom := MovementRect.Bottom - 5;
Result := MovementRect;
end;
{ TFormHelper }
procedure TForm.WMMoving(var Message: TWMMoving);
var
rec: ^TRect;
wrk: TRect;
begin
wrk := GetMovementArea;
rec := Pointer(Message.DragRect);
if rec^.Left < wrk.Left then
begin
rec^.Right := rec^.Right - (rec^.Left - wrk.Left);
rec^.Left := wrk.Left;
end
else if rec^.Right > wrk.Right then
begin
rec^.Left := rec^.Left - (rec^.Right - wrk.Right);
rec^.Right := wrk.Right;
end;
if rec^.Top < wrk.Top then
begin
rec^.Bottom := rec^.Bottom - (rec^.Top - wrk.Top);
rec^.Top := wrk.Top;
end
else if rec^.Bottom > wrk.Bottom then
begin
rec^.Top := rec^.Top - (rec^.Bottom - wrk.Bottom);
rec^.Bottom := wrk.Bottom;
end;
end;
end.

Minimize the whole application when a child modal form is minimized

In another question near this, i get the answer to get modal forms to keep inside a workarea inside the mainform.
The way i can accomplish that (thanks to David again) is catching WMSizing, WMMoving, WMGetMaxMinInfo, and for my porpuose WMShowwindow messages.
I am not closed to messages handling and i think it is likely the way i manage messages the cause that i am not getting the result i needed.
All the forms in my application are modal. But you can open a lot in the same execution thread. (Mainform, form1, form2, form3... formN).
All form(1..N) move inside a workarea in my mainform. Maximize, restore, size, move... all between limits of that workarea.
But i cannot manage how to minimize the whole application from then click on active modal form minimize button, and from click on taskbar button.
The application will be used in XP and W7... i am developing in DelphiXE.
The project can be downloaded from here (Project files - Mainform, panel, button, SecondaryForm, unit, nothing more), just to see that i try all the suggestions i found before asking here.
This is the source code of the original unit that keeps the modal forms inside the workarea.
unit uFormularios;
interface
uses Classes, SysUtils, Windows, Messages, Forms, DBGrids, StdCtrls, Menus, Graphics, ComCtrls, Math;
type
TForm_en_ventana = class(TForm)
private
inicializada: boolean;
bCentrada : boolean;
bMaximizada : boolean;
ancho_original: integer;
alto_original : integer;
procedure WMShowWindow(var Message: TWMShowWindow); message WM_SHOWWINDOW;
procedure WMSizing(var msg: TMessage); message WM_SIZING;
procedure WMMoving(Var msg: TMessage); message WM_MOVING;
procedure WMGetMinMaxInfo(Var msg: TWMGetMinMaxInfo); message WM_GETMINMAXINFO;
public
constructor Create(AOwner: TComponent); override;
property centrada: boolean read bCentrada write bCentrada;
property maximizada: boolean read bMaximizada write bMaximizada;
end;
procedure MaximizarFormulario(var F; MaximaAltura: integer = 0; MaximoAncho: integer = 0; Centrado: boolean = TRUE);
procedure InicializarVentanaTrabajo(const izq, der, arr, aba: integer);
var
ESPACIO_DE_TRABAJO, VENTANA_DE_TRABAJO: TRect;
implementation
constructor TForm_en_ventana.Create(AOwner: TComponent);
begin
inherited;
centrada := TRUE;
maximizada := false;
inicializada := false;
end;
Procedure TForm_en_ventana.WMGetMinMaxInfo(Var msg: TWMGetMinMaxInfo);
begin
inherited;
with msg.MinMaxInfo^.ptMaxPosition do
begin
x := VENTANA_DE_TRABAJO.Left;
y := VENTANA_DE_TRABAJO.Top;
end;
with msg.MinMaxInfo^.ptMaxSize do
begin
x := VENTANA_DE_TRABAJO.Right - VENTANA_DE_TRABAJO.Left;
y := VENTANA_DE_TRABAJO.Bottom - VENTANA_DE_TRABAJO.Top;
end;
with msg.MinMaxInfo^.ptMaxTrackSize do
begin
x := VENTANA_DE_TRABAJO.Right - VENTANA_DE_TRABAJO.Left;
y := VENTANA_DE_TRABAJO.Bottom - VENTANA_DE_TRABAJO.Top;
end;
with msg.MinMaxInfo^.ptMinTrackSize do
begin
x := ancho_original;
y := alto_original;
end;
end;
procedure TForm_en_ventana.WMSizing(var msg: TMessage);
var
R: PRect;
begin
R := PRect(msg.LParam);
R.Left := Max(R.Left, VENTANA_DE_TRABAJO.Left);
R.Right := Min(R.Right, VENTANA_DE_TRABAJO.Right);
R.Top := Max(R.Top, VENTANA_DE_TRABAJO.Top);
R.Bottom := Min(R.Bottom, VENTANA_DE_TRABAJO.Bottom);
Caption := 'Ancho: ' + inttostr(ancho_original) + ' - Alto: ' + inttostr(alto_original);
end;
procedure TForm_en_ventana.WMMoving(var msg: TMessage);
var
R : PRect;
dx, dy: integer;
begin
R := PRect(msg.LParam);
dx := 0;
dy := 0;
if R.Left < VENTANA_DE_TRABAJO.Left then
dx := VENTANA_DE_TRABAJO.Left - R.Left;
if R.Right > VENTANA_DE_TRABAJO.Right then
dx := VENTANA_DE_TRABAJO.Right - R.Right;
if R.Top < VENTANA_DE_TRABAJO.Top then
dy := VENTANA_DE_TRABAJO.Top - R.Top;
if R.Bottom > VENTANA_DE_TRABAJO.Bottom then
dy := VENTANA_DE_TRABAJO.Bottom - R.Bottom;
OffsetRect(R^, dx, dy);
end;
procedure TForm_en_ventana.WMShowWindow(var Message: TWMShowWindow);
begin
if inicializada then
Exit;
inicializada := TRUE;
ancho_original := Width;
alto_original := Height;
Constraints.MinHeight := Height;
Constraints.MinWidth := Width;
if centrada then
begin
Left := (((VENTANA_DE_TRABAJO.Right - VENTANA_DE_TRABAJO.Left) - Width) div 2) + VENTANA_DE_TRABAJO.Left;
Top := (((VENTANA_DE_TRABAJO.Bottom - VENTANA_DE_TRABAJO.Top) - Height) div 2) + VENTANA_DE_TRABAJO.Top;
end;
if maximizada then
SendMessage(Handle, WM_SYSCOMMAND, SC_MAXIMIZE, 0);
end;
procedure InicializarVentanaTrabajo(const izq, der, arr, aba: integer);
begin
VENTANA_DE_TRABAJO.Left := izq;
VENTANA_DE_TRABAJO.Right := der;
VENTANA_DE_TRABAJO.Top := arr;
VENTANA_DE_TRABAJO.Bottom := aba;
end;
procedure MaximizarFormulario(var F; MaximaAltura: integer = 0; MaximoAncho: integer = 0; Centrado: boolean = TRUE);
begin
LockWindowUpdate(TForm(F).Handle);
TForm(F).Left := ESPACIO_DE_TRABAJO.Left;
if MaximoAncho = 0 then
TForm(F).Width := ESPACIO_DE_TRABAJO.Right
else
begin
if ESPACIO_DE_TRABAJO.Right < MaximoAncho then
TForm(F).Width := ESPACIO_DE_TRABAJO.Right
else
TForm(F).Width := MaximoAncho;
end;
TForm(F).Top := ESPACIO_DE_TRABAJO.Top;
if MaximaAltura = 0 then
TForm(F).Height := ESPACIO_DE_TRABAJO.Bottom
else
begin
if ESPACIO_DE_TRABAJO.Bottom < MaximaAltura then
TForm(F).Height := ESPACIO_DE_TRABAJO.Bottom
else
TForm(F).Height := MaximaAltura;
end;
if ((MaximoAncho <> 0) or (MaximaAltura <> 0)) and (Centrado) then
begin
TForm(F).Left := (ESPACIO_DE_TRABAJO.Right - TForm(F).Width) div 2;
TForm(F).Top := (ESPACIO_DE_TRABAJO.Bottom - TForm(F).Height) div 2;
end;
LockWindowUpdate(0);
end;
initialization
SystemParametersInfo(SPI_GETWORKAREA, 0, #ESPACIO_DE_TRABAJO, 0);
VENTANA_DE_TRABAJO := ESPACIO_DE_TRABAJO;
end.
Thanks to anybody who can help me!
I needed this too, and I tried the other answer but it's not working. Fortunately I managed to make it work, like this:
procedure TFoodsForm.WMSysCommand(var Msg: TWMSysCommand);
begin
if (fsModal in FormState) and (Msg.CmdType and $FFF0 = SC_MINIMIZE)
then Application.MainForm.WindowState:= wsMinimized
else inherited;
end;
Simply catch the Minimize and Restore messages in the Modal Form and do this ...
procedure TTheModalForm.WMSysCommand(var Msg: TWMSysCommand);
begin
if (fsModal in FormState) or not Application.MainForm.Visible then
begin
case Msg.CmdType of
SC_MINIMIZE:
begin
ShowWindow(Application.Handle, SW_SHOWMINNOACTIVE);
end;
SC_RESTORE:
begin
ShowWindow(Application.Handle, SW_SHOWNORMAL);
inherited;
end;
else
inherited;
end;
end
else
inherited;
end;
Thank you, JFGravel! This worked great for me, but I could never get the SC_RESTORE to get caught here, but restore works fine without, so here's my short version:
if (Message.CmdType and $FFF0) = SC_MINIMIZE then
ShowWindow(Application.Handle, SW_SHOWMINNOACTIVE)
else
inherited;