Jump to content

Question/Discussion loading local files


Recommended Posts

For much of our SMS software we will be using it not only online but also on a desktop where it runs inside a embedded chromium host application. This works really well for us as it allows us to merge the HTML5 software with our win32 software and the kids don't notice that there is something fundamentally different between the two types of applications.

The challenge is when we need to load a text or JSON file from the res folder. It doesn't work. I am looking for alternatives.

I remember Jon using images as a file system but I cannot find that post/article.

How else could I store data (questions for the students etc) locally and still be able to access it?

 

edit: currently looking at using an indyserver (idTCPserver) on my delphi host application and have SMS application talk to it

 

 

 

Link to post
Share on other sites

I have implemented a simple server using TIdHTTPServer in Delphi 10.0

in SMS I have the following. This setup works if I use the internal browser. But it fails if I use Firefox or Chrome. I have opened the firewall so the port 8091 is not blocked.

I cannot figure out why it works with the internal browser but it fails when using external browser.

  W3Memo1.clear;
  FHttp := TW3HttpRequest.Create;
  FHttp.OnDataReady := HandleDataReady;
  FHttp.OnError := HandleError;

  fHTTP.Get('http://localhost:8091?file=QPool1.json')

The OnError does fire but I can't get any details out of it apart from Error 0.

 

Here is the Delphi code using indy TIdHTTPServer and a memo. The server is bound to 127.0.0.1 port 8091 and it is active

unit tcpserver;

interface

uses
  Winapi.Windows, Winapi.Messages, System.SysUtils, System.Variants, System.Classes, Vcl.Graphics,
  Vcl.Controls, Vcl.Forms, Vcl.Dialogs, IdContext, IdBaseComponent, IdComponent, IDSync, IdURI,
  IdCustomTCPServer, IdTCPServer, Vcl.StdCtrls, IdCustomHTTPServer, IdHTTPServer;

type
  TForm4 = class(TForm)
    Memo1: TMemo;
    IdHTTPServer1: TIdHTTPServer;
    Button1: TButton;
    procedure IdHTTPServer1CommandGet(AContext: TIdContext;
      ARequestInfo: TIdHTTPRequestInfo; AResponseInfo: TIdHTTPResponseInfo);
    procedure FormCloseQuery(Sender: TObject; var CanClose: Boolean);
    procedure IdHTTPServer1Connect(AContext: TIdContext);
    procedure IdHTTPServer1Disconnect(AContext: TIdContext);
    procedure Button1Click(Sender: TObject);
  private

    { Private declarations }
  public
    { Public declarations }
  end;



var
  Form4: TForm4;

implementation

{$R *.dfm}


procedure TForm4.Button1Click(Sender: TObject);
begin
memo1.Clear;
end;

procedure TForm4.FormCloseQuery(Sender: TObject; var CanClose: Boolean);
begin
IdHTTPServer1.Active := false;
end;

procedure TForm4.IdHTTPServer1CommandGet(AContext: TIdContext;
  ARequestInfo: TIdHTTPRequestInfo; AResponseInfo: TIdHTTPResponseInfo);
var
  name, value: string;
  I: integer;
  f : Tstringlist;
begin
  memo1.Lines.Add('ok'+ ARequestInfo.Params.Text);
  for i := 0 to ARequestInfo.Params.Count-1 do
  begin
    Name := ARequestInfo.Params.Names[i];
    Value := ARequestInfo.Params.ValueFromIndex[i];

    AResponseInfo.ResponseNo := 200;
    AResponseInfo.ContentType := 'application/json';

    if (Name = 'file') and (fileexists('c:\temp\'+value)) then
    begin
      f := Tstringlist.Create;
      try
       f.LoadFromFile('c:\temp\'+value);
       AResponseInfo.ContentText := f.text;
       memo1.Lines.Add('AResponseInfo.ContentText set');
      finally
       f.Free;
      end;
    end;
  end;
end;

procedure TForm4.IdHTTPServer1Connect(AContext: TIdContext);
begin
 memo1.Lines.Add('connected');
end;

procedure TForm4.IdHTTPServer1Disconnect(AContext: TIdContext);
begin

 memo1.Lines.Add('disconnected');
end;

end.

 

Here is the SMS application which simply has a button and a memo on the form

unit Form1;

interface

uses 
  System.Types,
  System.Types.Convert,
  System.Objects,
  System.Time,
  SmartCL.System,
  SmartCL.Time,
  SmartCL.Graphics,
  SmartCL.Components,
  SmartCL.FileUtils,
  SmartCL.Forms,
  SmartCL.Fonts,     smartcl.net.http,
  SmartCL.Theme,
  SmartCL.Borders,
  SmartCL.Application, SmartCL.Controls.Button, SmartCL.Controls.Memo;

type
  TForm1 = class(TW3Form)
    fHTTP : TW3HttpRequest;
    procedure W3Button1Click(Sender: TObject);
  private
    {$I 'Form1:intf'}
    procedure HandleDataReady(Sender: TW3HttpRequest);
    procedure HandleError(Sender: TW3HttpRequest);
    function  HandleTimeOut : TNotifyEvent;
  protected
    procedure InitializeForm; override;
    procedure InitializeObject; override;
    procedure Resize; override;
  end;

implementation

{ TForm1 }

procedure TForm1.W3Button1Click(Sender: TObject);
begin
  W3Memo1.clear;
  FHttp := TW3HttpRequest.Create;
  FHttp.OnDataReady := HandleDataReady;
  FHttp.OnError := HandleError;
  //FHttp.OnTimeout := HandleTimeOut;

  writeln('GET http://localhost:8091?file=QPool1.json');
  fHTTP.Get('http://localhost:8091?file=QPool1.json')
end;

procedure TForm1.HandleError(Sender: TW3HttpRequest);
begin
  W3Memo1.add('ERROR: ' + fhttp.Status.ToString + ' ' + fhttp.StatusText + 'With Response: ' + fhttp.ResponseText);
end;

function TForm1.HandleTimeOut : TNotifyEvent;
begin
end;
procedure TForm1.HandleDataReady(Sender: TW3HttpRequest);
begin
  W3Memo1.add('HandleDataReady > '#13);
  W3Memo1.add(Sender.ResponseText);

//  fHTTP.free;
end;

procedure TForm1.InitializeForm;
begin
  inherited;
  // this is a good place to initialize components
end;

procedure TForm1.InitializeObject;
begin
  inherited;
  {$I 'Form1:impl'}
end;
 
procedure TForm1.Resize;
begin
  inherited;
end;
 
initialization
  Forms.RegisterForm({$I %FILE%}, TForm1);
end.

 

 

 

Link to post
Share on other sites
  • Moderators

Don't know what os you're using. There are lots of comments on the internet of having problems accessing localhost after win10 creators update.

Seems to relate to not getting the correct dns from the hosts file

Did you try 127.0.0.1 ?

Other than that, I can't see a problem with your code at first glance.

I usually use POST rather than GET, but ...

  FHttp := TW3HttpRequest.Create;
  FHttp.OnDataReady := RetrieveSQLSelect;
  FHttp.open("POST",url);
  FHttp.setRequestHeader("Content-type","application/x-www-form-urlencoded");
  asm @encodedstr = encodeURIComponent('SELECT * , DATEDIFF( current_date, Datum ) as period FROM jobs where not (status = 6) order by datum, job'); end;

  sql_statement := "sql_statement="+encodedstr;
  FHttp.send(sql_statement);

requestheader in your case is correctly application/json

Link to post
Share on other sites

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.

Guest
Reply to this topic...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

×
×
  • Create New...