Link to home
Start Free TrialLog in
Avatar of MartinITllc
MartinITllcFlag for United States of America

asked on

File Download dialog


Hello,

The project that I am currently working on, requires to gather data from a website.  Once the data is found, the file associated with the data is downloaded to a directory.  Simple.

Here is the problem, once the data is found, there is a download button to click to get the file.  As you see in the code that I include, the first lines of the code the button is clicked and the file is starting to download.  This is where the problem starts.  The file download dialog appears and stops the automatic process.

The rest of the code that I have included, finds the file download dialog, and then locates the save button.  Once the button's handle is located, it will proceed to click on it.  Using Spy+, I can see that the message traffic is getting to the button, but there is no responding action.  

I have also tried to move the mouse cursor to the middle of the button and send a mouse click call to force the same action.  This hasn't accomplished the task either.

Now, there was an automatic download feature in IE, but that has been removed, in WIn7.  In XP, the feature is still there, but the same action of the file download dialog is present.

The question that I have, has anyone found a solution to this problem?  Could changing the mime type of the download file to be included in the safe downloads solve this?  

Thank you
Keith

 filedownload-problem.docx
Avatar of COBOLdinosaur
COBOLdinosaur
Flag of Canada image

I don't know if you can do it using IE as the browser... but can suppress the dialog in Firefox.

If they are all the same file type then in FF the first time you download you get the dialog, and you can set the option for it to not ask you for files of the same type in the future.  You will need to specify the folder where you want it to download to.  You will also want to turn off the display of the down load window in the download manager.
Avatar of MartinITllc

ASKER

Chrome and Firefox are identical in this option.  Twebbrowser uses the IE engine as a standard.
Twebbrowser uses the IE engine as a standard.


I don't follow.... What are you saying there?
Avatar of sYk0
sYk0

Why don't you use something like Synapse and completely forget about using TWebBrowser..?

In your application do users have to visually see the TWebBrowser component or are you hiding it and running through the HTML code until you find what you are looking for?

The reason I recommend Synapse is because it's NOT a visual component, you can parse HTML content in the background (the component could also save you time/bandwidth as it does NOT download any images, just plain vanilla HTML).

I used Synapse for a banking application (Synapse does support SSL if needed!) that I made, saved users having to manually download files as it logged in parsed the HTML and downloaded the files automatically.
Yes, I have used Synapse and also Chilkat Active X in different projects.  The interesting part of this project is that even though it is a web page, the actual page is JSP.  All that I have is a button in the web browser and no direct access to the file behind it.

The generated jsp code is just the front end to a database.  Where the presented data is in table format, and there is a button on the left side to download the tif/txt file that you requested.  Clicking on the button is the only access to get the file.
 Even in a JSP page, the button is normally HTML (it could be an embedded applet, in which case, it might not be worth the effort to try to figure out the mechanics).  Applets are not used extensively, in my experience, due to their large footprint.

  If it is HTML, you can either see where the click posts to or you can read the javascript of the page.  With either of those methods you should be able to duplicate the process without the browser control.  Then the only step left would be to duplicate what the button does... without the button.  I don't suppose you could provide us a link to test with?

Sorry but it is not the HTML button that I have the issue with.  In the HTML document format, I can navigate to the html button.  Have the application click on the button and start to download a file from a website.  The problem is not with the HTML but how IE takes care of the download.  When you start a download in IE displays the File Download dialog.

I am looking for a solution to have my application click or simulate clicking the "Save" button within the File Download Dialog.

My point about JSP is that I cannot directly call the file download by HTML GET.  the file is hidden within a JSP site that serves an Oracle Database.  Otherwise, a simple one call would get the file.
OK, thanks for the clarification.  Are you familiar with using FindWindow, GetWindowHandle and EnumChildWindows Windows API functions?  There are many examples on EE on how to use these API function within Delphi.  Using them you should be able to 1) watch for the Save dialog to be shown 2) enumerate the child controls (to find the save button) and 3) click the button (by sending messages to simulate mouse down and mouse up).  This link seems to show the basics of finding the window by title.  

https://www.experts-exchange.com/questions/27187092/Delphi-Mouse-click-simulation-with-PostMessage-or-something-similar.html?sfQueryTermInfo=1+10+30+delphi+down+enumchildwindow+mous

I like to look by the window class.  This link shows how to get window class names of active windows (this will get you the class name to search for).
http://stackoverflow.com/questions/7096542/collect-all-active-window-class-names

Using FindWindow should easily allow you to find the window by name.
http://www.swissdelphicenter.ch/torry/showcode.php?id=327

Once you have the window handle, EnumChildWindows and look for the button.

Let me know if you need more.

Thank you for your help, but this is all done.  Once I have the html button clicked as so:

          WB.OleObject.document.Forms.item(5).elements.item(I).click;

Open in new window


The application starts a timer waiting for the "File Download dialog" to show.  The timer is due to the time lag between clicking of the button and the appearance of the dialog.  Here is the code to the timer:


procedure TForm5.FileDownloadTimerTimer(Sender: TObject);
Var
  WHandle, ButtonHandle: hWnd;
  ParentHandle: DWORD;
  P: Array [0 .. 256] Of Char;
  ProcessIdActif: DWORD;
Begin

  // get Thread process id from the current form
  ProcessIdActif := 0;
  GetWindowThreadProcessId(Handle, @ProcessIdActif);
  LogUpdate(datetimetostr(now) + ' [INFO] Waiting for File Download Dialog.');

  WHandle := FindWindow(Nil, Nil);
  While (WHandle <> 0) Do
    begin // While there are still windows
      P[0] := #0;
      GetWindowText(WHandle, P, 255);
      // blank caption not needed
      if P[0] <> #0 then
        begin
          // get Process Id of this window
          GetWindowThreadProcessId(WHandle, @ParentHandle);
          // get windows for the current process
          if ProcessIdActif = ParentHandle then
            begin
              if CompareText(P, 'File Download') = 0 then
                begin
                  LogUpdate(datetimetostr(now) + ' [INFO] File Download Dialog found.');
                  ButtonHandle := FindWindowEx(WHandle, 0, 'Button', '&Save');
                  if ButtonHandle > 0 then
                    begin
                      LogUpdate(datetimetostr(now) + ' [INFO] &Save Button Found....' + inttostr(ButtonHandle));
                      SendMessage(ButtonHandle, BM_CLICK, 0, 0);
                      FileDownloadTimer.Enabled := False;
                    end;
                end;
            end;
        end;
      WHandle := GetWindow(WHandle, GW_HWNDNEXT);
    End;
end;

Open in new window


If the file dialog doesn't appear in a defined amount of time, the timer is aborted and the HTML button is reclicked.  After another defined amount of clicking the HTML button an error is raised and logged.  Simple design.

Now using Spy+ and the ButtonHandle that I get from the FindWIndowEX, the handle is correct.  Watching message traffic to the button handle, I can see that there is a sending of BM_CLICK to it.  The Save button of the File Download Dialog just will not response.  Just to check my methods, I commented the BM_CLICK section out and replaced it with mouse commands.  I moved the mouse to the button's center, and passed a series of Mouse Left Button down and up commands.  The same response, or actually the lack of response was seen from the Button.

Thank you for your help

 Have you tried sending a WM_KEYDOWN WM_KEYUP combination to the handle of the button?

  If that does not work, the next thing I would do is to try focusing the button first WM_SETFOCUS.  If the button is a default button (normal for a dialog) then I would also try sending the enter key (down and up) to the parent of the button.  That should trigger the default action.
You could also try replacing IE (TWebBrowser) with Chromium Embedded (Note: the supporting libraries are large (28MB) if size is a factor for you), see http://code.google.com/p/delphichromiumembedded/.

I have used it for a few projects that require the rendering of Web pages but should also work for your purposes.
As far as I can remember, you can handle downloads with Chromium Embedded via one of its properties (see GetDownloadHandler).

If you insist on using TWebBrowser I'm sure I can a solution for you, let me know.
ASKER CERTIFIED SOLUTION
Avatar of MartinITllc
MartinITllc
Flag of United States of America image

Link to home
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Start Free Trial
it was the one that worked.  All of the others, would probably work, but the project requirements would not allow it.