Delphi TWebBrowser error - ios

I am developing an iOS app using Delphi XE5 FireMonkey (with Update 1).
I download PDFs and store them locally and view them with a TWebBroswer. This always works the first time I download a document, or when viewing an already downloaded PDF. However, if I download and view a second PDF, the TWebBrowser does not load the file.
if FileExists(filename) then
begin
WebBrowser1.Navigate('about:blank'); //clear page
WebBrowser1.Navigate('file://' + filename);
//filename points to a PDF on the local device and the file
//definitly exists
//first run always works 100%, second run comes into this IF statement
//but the DidFailLoadWithError is fired
end;
I am trying to determine what the error is. Placing a try...except around the Navigate does not work, and the DidFailLoadWithError does not allow one to find the error.
See: http://qc.embarcadero.com/wc/qcmain.aspx?d=115652 for information on the DidFailLoadWithError 'bug'
procedure Tform1.WebBrowser1DidFailLoadWithError(ASender: TObject);
begin
//ASender is a TWebBrowser
//No parameter with Error info!
end;
Any suggestions as to how I can determine the error that is returned?

You'll need to make a copy of the FMX source directory, add that directory to your search path and make some tweaks to a couple of files.
When you next build your project it will recompile all those FMX units you copied/tweaked. You may be able to get away with copying just the one(s) you modify, and maybe a couple more via trial and error, which will make the initial build rather quicker.
In the FMX.WebBrowser.iOS procedure TiOSWebViewDelegate.webView() method, take the error parameter and do what is needed to get the error string from it, which basically amounts to calling the localizedDescription method, and pass it along to a call to NSLog. Documentation is here.
Then you can read the error message in the log, either in Console.app on OS X if using the iOS simulator, or in the Console section for your device in the Organizer window of Xcode if using an actual iOS device.

Related

Why does extracting file a file using TZipFile in iOS Simulator raise access violation?

I'm using TZipFile to extract a zip file and it's works ok in win32 but raise this exception in ios simulator. I dont know why , i've checked the location for the extraction is ok, passed the open file but when come to the extract it still raise that exception. Currently i'm not having any ios device for the real testing but please help on simulator, i'm frustrating with this.
ZipFile.Open(filePath, zmRead);//this line passed,
ZipFile.Extract(0,dirPath );//raise EAccess exception in this line
ZipFile.Close;
//the filePath and the dirPath is the location of file and location i want to extract, it's all correct.
Or use
Zipfile.ExtractZipFile(filePath,dirPath) //still that exception
Update:
OH i think i'm missing the information about my project, my working is to download a zip file which contain a .csv file from a server. I've downloaded it to the a folder(create at run time) in the ios simulator, the directory of folder i put in to variable dirPath = Tpath.GetHomePath() + SeparatorChar + 'csv' and the variable 'fileName' is the dirPath' + name of file zip i downloaded. And i about to extract it right in that folder. So i use TZipFile to extract it and it cause up the access violation error in ZipFile.Extract line. I putted my download and extract section code to a new project and it works perfectly. I dont know why but my main project is a large prj which contain many functions and come up before my download section.Thanks
Problem solved, in my Download.pas is a separated class and i use library System.Zip in there and i use another class to call it. So my work around is put uses System.Zip right in the Main form when project start and problem solved, there is no logical here and i think it's a bug from System.Zip. Thanks

Delphi: Play mp4 file using DSPack

I have been playing around with DSPack, it can play avi and wmv files, but it is not playing mp4 files. i have installed ffdshow codec but still it wont play any other format. I read somewhere that i need to use ffdshow filter, but there is very limited documentation on how to do so... Can someone help me out here?
Edit
Thats the error i get when playing any other format
raised exception class EDirectShowException with message 'C ($80040265).'. Process stopped. Use Step or Run to continue.
and thats the function which pops the exception
function CheckDSError(HR: HRESULT): HRESULT;
var Excep: EDirectShowException;
begin
Result := HR;
if Failed(HR) then
begin
Excep := EDirectShowException.Create(format(GetErrorString(HR)+' ($%x).',[HR]));
Excep.ErrorCode := HR;
raise Excep;
end;
end;
Edit
I installed the haali demultiplexer, it was a self installer after installation i still get the same error. and the gdcl demultiplexer, those are two dll files, any suggestions on how to use them?
PS: I have never worked with codecs and/or this kind of stuff, so sorry for being so thick, And i am using Windows 7 x64
I can successfully play *.mp4 files with the "DSVideoWinDowEx\PlayWin" demo application that ships with DSPack. Windows 7 includes the mp4 codec, so this should not be an issue. Make sure that you're not running your application in debug mode, because many codecs refuse to work if a debugger is active.
The Haalie Media Splitter is not used for my test *.mp4 files. But it uses the AC3Filter. So your problem could also be a missing audio codec.
If that doesn't fix the issue then the question might be: "Why does it not work on your PC?"
In order to further narrow down the issue try playing the video with GraphEdit or GraphStudio and see if that works. These tools will also show the filter graph that is used. You can also show the FilterGraph that is used in your DSPack application.
If you install a DirectShow filter (codec) on your system, it will be used automatically by DirectShow/DSPack. You could register a filter in the system manually by calling regsvr32 "path_to_codec.ax", but this is usually done by the installer. It is possible to manually use a filter in DirectShow, but most of the time this is not needed.
lavfilters provide everything you will need with source splitters and decoders. It's open source, actively developed and based on ffmpeg. If you can't playback the mp4 after installing lavfilters then I would say there is a problem with the mp4 itself. In this case use something like ffprobe to inspect the file or post a link to the file.

Delphi XE5 open pdf for mobile

I am using XE5 to create a mobile app and one thing I need to do is be able to download a PDF as a byte stream via a datasnap server, store it on the local device and then open it.
I have manage to download and store a PDF on the local device (not using datasnap server yet, but simply using an Indy HTTP control. This works okay for now and the document is definitely stored on the local device.
Now I am trying to open it and am struggling to figure out how to.
This filename points to the correct file:
filename := TPath.Combine(TPath.GetDocumentsPath, 'Test.pdf');
This points to
/Users/versodev/Library/Application Support/iPhone Simulator/7.0.3/Applications/96674DE6-7997-48F9-9892-1383EBCE473B/Documents/Test.pdf
I have tried using the Apple.Utils class in the samples folder and using SharedApplication.OpenURL but this does not work (even if I convert the filename to a NSUrl).
Interestingly though, the canOpenURL returns true.
Any ideas on how I can simply open a PDF document that is stored in the Documents folder of the app on the local device? I don't mind using a default app (eg Safari), or creating a control in my app to view it.
(I have tried using the UIDocumentInteractionController but am not totally sure how it works)

How can I close an app without a modal dialog box being shown?

I have an app that can optionally open PDF's after it creates them. If two reports are generated in succession with the same name, the second attempt fails if the first copy of acrobat still has the PDF open, so before I write the PDF I check (with FindWindow) for a window with the document name. If one is found I issue a SendMessage WM_Close.
This works OK, but I was doing some other tests and was using Word to "edit" the PDF, to hold it open so I could test the app's behaviour when it can't write the PDF file. Now, when my app tries to close the window, Word pops up a "do you want to save" dialog. If I click cancel, Word remains open, my app carries on and I can test that it behaves sensibly when it encounters a file that it can't write to.
All good, but it has alerted me to the fact that using SendMessage WM_CLOSE to close another app will snag my app if the other app pops up a modal dialog. Is there any way around this - i.e a more forceful (but not too forceful) way of closing the other app? Or a "Close and click on cancel if necessary". Or should I use asynchronous messages?
Do not force any application to close, there may be other documents open the user is viewing etc... You can use SendMessageTimeout to wait the return of WM_CLOSE a sensible amount of time, and then proceed with either failure or success..
var
Word: HWND;
msgResult: DWORD;
begin
...
SendMessageTimeout(Word, WM_CLOSE, 0, 0, SMTO_NORMAL, 5000, msgResult);
if IsWindow(Word) then begin
// bummer! Application is open...
 
I would not close the other application at all. I think it's better to delete the current file before generating the report. If it fails (DeleteFile), show a message to the user that the file cannot be overwritten (because it is opened by another program) and do not generate the report at all. This is much safer, because you leave the option to the user. Also this saves you from major headaches, what if the program is opened by another program that does not show the title in the window caption?
If you want to go one step further than WM_CLOSE you can only terminate the application. Everything else would be like lottery.
That said I am against both. What if your PDF opens in a MDI application already showing other documents? Forcing the application to close would make the user lose all changes to the other open documents. And sending a close message to this application would be annoying since the user still needs the other documents opened.
You cannot predict the behavior of every application. And you certainly don't know every application. If the report has the same name then you can tell the user to close the other one with the same name. Otherwise he won't get a new report. Think what would happen if Windows started closing your applications as soon as you try to overwrite a file which is currently in use.

Installing applications OTA

I have a system set up to download jad files on users' Blackberries, but it only works intermittently, and seemingly randomly. If the user clicks on the link within their BlackBerry browser, 95% of the time on the first try an error message will pop up saying there was an HTTP 500 error (which our server never returns).
Viewing the details of this message within the blackberry browser, it says nothing but java.lang.nullpointerexception which, again, could not have come from our server (running apache/php).
However, if the user clicks on the link a few more times, or navigates away and goes back to that page, it suddenly works. No change on the server, it just shows the application install screen. Unfortunately, this doesn't always work; sometimes the error 500 just keeps showing up.
The link is rather long (containing an sha hash as a token as part of the URL), but I would think that a long URL would either always be broken or always work, not work intermittently.
The link uses a php script to download the jad and cod files. Linking to the files directly rather than using the script seems to work more often (I haven't determined if that also ever has an error 500 or not), but I can't find any issues with the headers. The content type is set correctly and, like I said, if the headers were an issue, I'd think it would either always work or always break.
Any clues?
You may be able to shed some light on the problem by looking at the event logs, which you can get using JavaLoader:
javaloader -u eventlog > event.log
Search for NullPointerException within those logs and you'll be able to see what's causing it.
I can't explain the intermittent behaviour, but I had a similar situation where I was getting the java.lang.NullPointerException in the browser details. Unfortunately, the Event Log (as dumped by javaloader.exe) or by viewing on-device using Alt-L-G-L-G didn't show the exception.
(I'm using bb-ant-tools and JDE 4.6.1.) When the signature tool ran, I noticed that there were two .cod files being signed and I can see both of them inside the .jar file the compiler creates. But the output written was a single .cod file of size 92306 bytes that was not a .zip of smaller .cod files. The compiler somehow was not able to create a .cod that contained siblings. For comparison, compiling the project with JDE 5.0.0 created sibling .cod files that were able to be loaded over OTA.
My project included an .mp3 file of 53542 bytes which I happened to not require. After removing it, the 4.6.1 compiler outputted a single .cod and I was able to successfully download it via OTA.

Resources