Docwiki
https://docwiki.embarcadero.com/RADStudio/Athens/en/WebStencils
Marco Cantu Blog
This method creates a temporary file called temp post request.html, puts parameters in it, and calls it using a web browser.
procedure OpenBrowserWithPostRequest;
var
HTMLFileName, HTMLContent: string;
HTMLFile: TextFile;
begin
// temp HTML file
HTMLFileName := ExtractFilePath( ParamStr(0)) + 'temp_post_request.html';
// HTML file write
HTMLContent :=
'<html>' +
'<body onload="document.forms[0].submit()">' +
'<form action="http://127.0.0.1/exam1" method="POST">' +
'<input type="hidden" name="param1" value="exam">' +
'<input type="hidden" name="param2" value="1">' +
'<input type="hidden" name="param3" value="3">' +
'</form>' +
'</body>' +
'</html>';
AssignFile( HTMLFile, HTMLFileName );
Rewrite( HTMLFile );
Write( HTMLFile, HTMLContent );
CloseFile( HTMLFile );
ShellExecute(0, 'open', PChar( HTMLFileName ), nil, nil, SW_SHOWNORMAL);
end;
When converting a 2-tier project to 3-tier, you often have to move the SQL queries used in the 2-tier app to the 3-tier middleware server, which increases the workload and makes the project on the server huge.
In this case, there is a way to send the SQL statement itself as a String parameter without moving the query statement used in the second-tier project to the server.
In this case, the middleware server receives the sql string, processes it, and makes the result visible to the client app.
Depending on the SQL query statement, the column names retrieved from the database or the field names replaced with AS in the SQL query statement are all different, so you can output the field names like below.
for i := 0 to FDQueryI.FieldCount - 1 do
JsubObj.AddPair( FDQueryI.Fields[ i ].FullName, FDQueryI.Fields[ i ].AsString );
In some cases, you may know the field names of the queried results in the database, but FireDAC can show the field names of the queried results in the same way as the sample source, so you can use it.
The sample source outputs the result as Json, so you can utilize Rad server or Datasnap Rest method.
function TRTestResource1.QueryText_sql( sqlText : string ) : String;
var
JTopObj, JsubObj : TJSONObject;
JArr : TJSONArray;
JPair : TJSONPair;
i : integer;
begin
JTopObj := TJSONObject.Create;
try
FDConnection1.Open;
try
FDQueryI.Close;
FDQueryI.SQL.Clear;
FDQueryI.SQL.Add( sqlText );
FDQueryI.Open;
FDQueryI.First;
JArr := TJSONArray.Create;
while Not FDQueryI.EOF do
begin
JsubObj := TJSONObject.Create;
for i := 0 to FDQueryI.FieldCount - 1 do
JsubObj.AddPair( FDQueryI.Fields[ i ].FullName, FDQueryI.Fields[ i ].AsString ); // 조회 결과값의 필드명과 데이터를 같이 출력 하는 방법
JArr.AddElement( JsubObj );
FDQueryI.Next;
end;
JPair := TJSONPair.Create( 'Items', JArr );
JTopObj.AddPair( 'Count', TJSONNumber.Create( FDQueryI.RecordCount ) );
JTopObj.AddPair( JPair );
except
on e: Exception do begin
result := 'Error';
Exit;
end;
end;
finally
FDConnection1.Close;
result := JTopObj.ToString; // 결과값 전달.
JTopObj.Free;
end;
end;
This video is created by connecting two planets orbiting the sun with different orbital periods with a line.
You can visually see the distance between two destination lines by the length of the line.
The length between the two points was calculated in the following way.
procedure TMForm.Draw_Line2P( x1,y1, x2,y2 : single; setColor : cardinal );
var
d, xtemp, ytemp, rAngle : single;
drawLine : TLine;
begin
if x1 > x2 then
begin
xtemp := x1; ytemp := y1;
x1 := x2; y1 := y2;
x2 := xtemp; y2 := ytemp;
end;
d := SQRT( Power( x2-x1, 2 ) + Power( y2-y1, 2 ) ); // Uses System.Math
rAngle := RadToDeg( ArcSin( (y2-y1)/d ));
drawLine := TLine.Create( BLayout );
drawLine.Parent := BLayout;
drawLine.LineLocation := TLineLocation.Inner;
drawLine.LineType := TLineType.Bottom;
drawLine.RotationCenter.X := 0;
drawLine.RotationCenter.Y := 0;
drawLine.Stroke.Thickness := 1;
drawLine.Stroke.Color := setColor;
drawLine.Height := 1;
drawLine.Width := d;
drawLine.Position.X := x1;
drawLine.Position.Y := y1;
drawLine.RotationAngle := rAngle;
end;
A colorful graphic show made with Delphi Firemonkey.
// ChatGPT Personal Key : https://beta.openai.com/account/api-keys
unit MainCGPT;
interface
uses
System.SysUtils, System.Types, System.UITypes, System.Classes, System.Variants, System.JSON,
FMX.Types, FMX.Controls, FMX.Forms, FMX.Graphics, FMX.Dialogs, FMX.Memo.Types, FMX.StdCtrls, FMX.Controls.Presentation, FMX.ScrollBox,
FMX.Memo, System.Net.URLClient, System.Net.HttpClient, System.Net.HttpClientComponent, FMX.Layouts;
type
TMForm = class(TForm)
Memo_Ans: TMemo;
Memo_HanQ: TMemo;
BT_Question: TButton;
NetHTTPClient1: TNetHTTPClient;
NetHTTPRequest1: TNetHTTPRequest;
Label1: TLabel;
Label3: TLabel;
Layout1: TLayout;
Layout3: TLayout;
SpeedButton1: TSpeedButton;
procedure BT_QuestionClick(Sender: TObject);
procedure NetHTTPClient1RequestCompleted(const Sender: TObject; const AResponse: IHTTPResponse);
procedure Memo_HanQDblClick(Sender: TObject);
private
{ Private declarations }
public
{ Public declarations }
end;
var
MForm: TMForm;
// ChatGPT key : https://beta.openai.com/account/api-keys
Const MyGPTKey = 'mykey_1234abcd'; // Input your key
implementation
{$R *.fmx}
procedure TMForm.Memo_HanQDblClick(Sender: TObject);
begin
Memo_HanQ.Lines.Clear;
end;
// Question *********************************************
procedure TMForm.BT_QuestionClick(Sender: TObject);
var
LPostdata: string;
LPostDataStream: TStringStream;
begin
LPostData := '{' +
'"model": "text-davinci-003",'+
'"prompt": "' + Memo_HanQ.Text + '",'+
'"max_tokens": 2048,'+
'"temperature": 0'+
'}';
LPostDataStream := TStringStream.Create( LPostData, TEncoding.UTF8);
NetHTTPClient1.CustomHeaders['Authorization'] := 'Bearer ' + MyGPTKey;
NetHTTPClient1.CustomHeaders['Content-Type'] := 'application/json';
LPostDataStream.Position := 0;
NetHTTPClient1.Post('https://api.openai.com/v1/completions', LPostDataStream );
end;
// Answer ********************************************************************************
procedure TMForm.NetHTTPClient1RequestCompleted(const Sender: TObject; const AResponse: IHTTPResponse);
var
LString, ansStr : string;
LJson: TJsonObject;
begin
if AResponse.StatusCode = 200 then
begin
LString := AResponse.ContentAsString;
LJson := TJSONObject.ParseJSONValue(LString) as TJSONObject;
try
ansStr := LJson.GetValue('choices').A[0].FindValue('text').Value;
finally
LJson.Free;
end;
end
else
ansStr := 'HTTP response code: ' + AResponse.StatusCode.ToString;
Memo_Ans.Lines.Clear;
Memo_Ans.Lines.Add( ansStr );
end;
end.
unit PMUnit;
interface
uses
System.SysUtils, System.Types, System.UITypes, System.Classes, System.Variants, System.Permissions,
FMX.Types, FMX.Controls, FMX.Forms, FMX.Graphics, FMX.Dialogs, FMX.Controls.Presentation, FMX.StdCtrls;
type
TForm1 = class(TForm)
Button1: TButton;
Button2: TButton;
Button3: TButton;
procedure Button1Click(Sender: TObject);
procedure Button2Click(Sender: TObject);
procedure Button3Click(Sender: TObject);
procedure FormCreate(Sender: TObject);
private
procedure DisplayRationale(Sender: TObject; const APermissions: TClassicStringDynArray; const APostRationaleProc: TProc);
procedure Loacation_PermissionRequestResult(Sender: TObject; const APermissions: TClassicStringDynArray;
const AGrantResults: TClassicPermissionStatusDynArray);
procedure Call_PermissionRequestResult(Sender: TObject; const APermissions: TClassicStringDynArray;
const AGrantResults: TClassicPermissionStatusDynArray);
procedure Camera_PermissionRequestResult(Sender: TObject; const APermissions: TClassicStringDynArray;
const AGrantResults: TClassicPermissionStatusDynArray);
{ Private declarations }
public
{ Public declarations }
FPermissionLoacation, FPermissionCall, FPermissionCamera : string;
end;
var
Form1: TForm1;
implementation
uses
{$IFDEF ANDROID}
Androidapi.JNI.Os,
Androidapi.Helpers,
AndroidApi.Jni.JavaTypes,
FMX.DialogService;
{$ENDIF}
{$R *.fmx}
procedure TForm1.FormCreate(Sender: TObject);
begin
FPermissionLoacation := JStringToString(TJManifest_permission.JavaClass.ACCESS_FINE_LOCATION );
FPermissionCall := JStringToString(TJManifest_permission.JavaClass.CALL_PHONE );
FPermissionCamera := JStringToString(TJManifest_permission.JavaClass.CAMERA );
end;
procedure TForm1.Button1Click(Sender: TObject);
begin
PermissionsService.RequestPermissions([FPermissionLoacation], Loacation_PermissionRequestResult, DisplayRationale);
end;
procedure TForm1.Button2Click(Sender: TObject);
begin
PermissionsService.RequestPermissions([FPermissionCall], Call_PermissionRequestResult, DisplayRationale);
end;
procedure TForm1.Button3Click(Sender: TObject);
begin
PermissionsService.RequestPermissions([FPermissionCamera], Camera_PermissionRequestResult, DisplayRationale);
end;
procedure TForm1.DisplayRationale(Sender: TObject; const APermissions: TClassicStringDynArray; const APostRationaleProc: TProc);
var
I: Integer;
RationaleMsg: string;
begin
for I := 0 to High(APermissions) do
begin
if APermissions[I] = FPermissionLoacation then
RationaleMsg := RationaleMsg + 'The app needs to access the Permission Location' + SLineBreak + SLineBreak
else if APermissions[I] = FPermissionCall then
RationaleMsg := RationaleMsg + 'The app needs to access the Permission Call' + SLineBreak + SLineBreak
else if APermissions[I] = FPermissionCamera then
RationaleMsg := RationaleMsg + 'The app needs to access the Permission Camera';
end;
// Show an explanation to the user *asynchronously* - don't block this thread waiting for the user's response!
// After the user sees the explanation, invoke the post-rationale routine to request the permissions
TDialogService.ShowMessage(RationaleMsg,
procedure(const AResult: TModalResult)
begin
APostRationaleProc;
end)
end;
procedure TForm1.Loacation_PermissionRequestResult(Sender: TObject; const APermissions: TClassicStringDynArray; const AGrantResults: TClassicPermissionStatusDynArray);
begin
// 3 permissions involved: CAMERA, READ_EXTERNAL_STORAGE, WRITE_EXTERNAL_STORAGE
// if (Length(AGrantResults) = 3) and
// (AGrantResults[0] = TPermissionStatus.Granted) and
// (AGrantResults[1] = TPermissionStatus.Granted) and
// (AGrantResults[2] = TPermissionStatus.Granted) then
if ( Length(AGrantResults) = 1) and
(AGrantResults[0] = TPermissionStatus.Granted) then
TDialogService.ShowMessage('Location permissions OK ' )
else
TDialogService.ShowMessage('The required permissions are not granted');
end;
procedure TForm1.Call_PermissionRequestResult(Sender: TObject; const APermissions: TClassicStringDynArray; const AGrantResults: TClassicPermissionStatusDynArray);
begin
if ( Length(AGrantResults) = 1) and
(AGrantResults[0] = TPermissionStatus.Granted) then
TDialogService.ShowMessage('Call permissions OK ' )
else
TDialogService.ShowMessage('The required permissions are not granted');
end;
procedure TForm1.Camera_PermissionRequestResult(Sender: TObject; const APermissions: TClassicStringDynArray; const AGrantResults: TClassicPermissionStatusDynArray);
begin
if ( Length(AGrantResults) = 1) and
(AGrantResults[0] = TPermissionStatus.Granted) then
TDialogService.ShowMessage('Camera permissions OK ' )
else
TDialogService.ShowMessage('The required permissions are not granted');
end;
end.
Uses
Androidapi.Helpers,
Androidapi.JNIBridge,
Androidapi.JNI.Media,
AndroidApi.Jni.JavaTypes,
AndroidApi.Jni.App;
procedure BeepSound();
{$IFDEF ANDROID}
var
AudioObj: JObject;
Audio: JAudioManager;
{$ENDIF}
begin
{$IFDEF ANDROID}
AudioObj:= TAndroidHelper.Activity.getSystemService( TJActivity.JavaClass.AUDIO_SERVICE);
Audio := TJAudioManager.Wrap((AudioObj as ILocalObject).GetObjectID);
Audio.loadSoundEffects;
Audio.playSoundEffect( 8 ); // 0 ~ 9
{$ENDIF}
end;