Tek-Tips is the largest IT community on the Internet today!

Members share and learn making Tek-Tips Forums the best source of peer-reviewed technical information on the Internet!

  • Congratulations TouchToneTommy on being selected by the Tek-Tips community for having the most helpful posts in the forums last week. Way to Go!

Show Desktop Windows Side by Side Programatically 2

Status
Not open for further replies.

mydocpro

Technical User
Mar 13, 2016
48
US
... i.e., without right-clicking the task-bar clock (of windows desktop).

All too oft: We'd like to arrange VFP-App side by side with Internet-Explorer or Windows-Explorer.

(Note: The VFP WebBrowser Class seemed ideal, but that is 'script'-limited for some URL-sites (like BCBS sites) and some Windows-Explorer manipulations as well ... so I cannot use the VFP WebBrowser Class)

Utmost thanks and blessings in advance (for any thoughts),
Philip
 
The web browser control is script limited? I think I know what you mean, but that only happens with local files, which are handled as coming from the Restricted Sites zone, which doesn't allow script execution.
The web browser control even supports popups, they just might appear behind the VFP screen/main form. Is that your problem?

As direct answer: Changing position and size of an automated IE window is as simple as with any form, because the OLE Server enables access to left,top,width, and height:
Code:
o = CREATEOBJECT("InternetExplorer.Application")
o.Top=0
o.Left=0
o.Width=SYSMETRIC(1)/2
o.Height=SYSMETRIC(2)
o.Visible = .t.

Bye, Olaf.
 
Yes sir, I'd prefer the WebBrowser control, but (as you well-validated), it 'hates' scripts from restricted web zones.
Also sir, the IE (Google Chrome) and Win-Explorer appear(s) behind the VFP app all too oft (hidden).

But your code seems MOST God-send ... if I can connect it with ShellExecute of:
(1) Windows Explorer and/or
(2) default web-browsers (like Google Chrome), i.e.:

(1) ShellExecute(0,"open","explorer",lDstDir,"",4) && lDstDir = some Windows Directory

and/or

(2) ShellExecute(0,"Open",Internet001,"","",1) && Internet001="
I will experiment and report. Again, utmost thanks and blessings,
Philip
 
Well, the issue with restricted zone urls remains. With such URLs you never get scripts run, but usually sites are not in that zone. Files (local files) are in that zone for some reasons, so I was thinking you did something like DownloadURLTOFile and then display that file or modified HTML to your needs and load that, which won't work, also not when automating IE.

In regard of positioning windows started with ShellExecute, that's less easy, you first have to find out which HWND belongs to the new process and you'd rather not use ShellExecute for that, but establish the API routine for CreateProcess to at least know the new process id as starter for any further access to this new processes Windows.

Take a read on this:
Bye, Olaf.
 
Hi Philip,

if the child app (google chrome, internet explorer, etc.) appears behind the parent app (VFP), thats a windows behavior.

Take a look at ForegroundLockTimeout: Link

ForegroundLockTimeout is a registry key under HKCU\Control Panel\Desktop.

Set ForegroundLockTimeout to 0 (manually or programmatically) to force the started app to appear in the foreground immediately.

Default value is 200000 milliseconds.

- suggestion: read the value before and restore the value after Your ShellExecute :)

Regards, Stefan
 
Thanks Stefan and Olaf (again),

It may be a work-around with Strahl's CreateProcess (and perhaps even ForegroundlockTimeout (which might have helped with ShellExcecute issues a couple months back).

As alway, I'll report if/when dots connect. I'll get to it.

Utmost blessings!
Philip
 
OK, peeling through Rick Strahl's Shell API and WebBrowser object 'onion layers'
( etc.)

... I discovered one line to append to Olaf's (and Strahl's) CreateObject("InternetExplorer.Application") code (above):

Code:
o.Navigate("[URL unfurl="true"]https://restricted-web-zone.org")[/URL]

... that I might experiment with ... to 'positionally' replace my ShellExecute(), Olaf's/Strahl's CreateProcess(), etc. ... I could find no positional commands for CreateProcess(), unfortunately. o.CreateObject"InternetExplorer.Application")+o.Navigate(" might allow positional placement of IE-apps + navigation. (More experimentation is needed)

Off topic: Albeit, Strahl ultimately embraces the WebBrowser object, (about 10 years ago) and its DOM (document object model) layers to "play with", iirc ... with generous (and lovely) WebBrowser-methods' examples to penetrate HTML files (though unrestricted web-zones methinks).

On topic:
Code:
Declare Long FindWindow In Win32API String, String
DECLARE integer SetWindowPos IN win32api integer hWnd,integer hWndInsertAfter,integer X,integer Y,integer cx,integer cy,integer uFlags
... and ...

Code:
local lnHwnd
WAIT WINDOW "" TIMEOUT 0.1  && slow the fox a bit else fails
lnHwnd = FindWindow( .null., cFileTitle)  && cFileTitle = header of Windows File Explorer
SetWindowPos( lnHwnd,[b]-2[/b],0,0,500,500, 0 )	&& -2-NonTopMost 0-NotOnTop, 1-Bottom, -1-AlwaysOnTop
_screen.Left = 500 && for VFP-app

This, indeed, seems to be working quite well for starters.
The problem, 'Programmatically Position Desktop Windows Side by Side', is resolved!

Utmost blessings all!
Philip
 
Well, you didn't get what this was all about:

CreateProcess allows you to know process information you don't know with ShellExecute. ShellExecute is just Shoot and go, it's less work, but Rick Strahls has put CreateProcess into a function that you can call with about the same parameterization, so all the extra work to build up a process info is already done for you. This is not giving anything to right away put in positional parameters, but you know the processID of the process you start and can do things with that.

FindWindow only is a solution, if you know the Window title, this can bite you, if a) there are many Windows Explorer Windows and b) if titles differ because of Windows Locale being something else but English.

No, the process handle is a better and more concrete handle on the process you want to control. I left out how exactly to get the hwnd you need for SetWindowPos, but FindWindow can also be used after ShellExecute, that's not the way I'd propose. You better go the harder way here to really be sure you get the right HWND, what you do is too loosely coupled.

Bye, Olaf.
 
I am sorry Olaf,

I researched CreateProcess() (Strahl, Microsoft, VFP sites, Google, etc.) and could not figure out positional commands nor other 'positional' APIs to use with that CreateProcess API. Strahl's excellent wrapper ( does demo "to write Standard output to a file" vs. the limited VFP RUN commmand.

Thus, I am unable. Indeed, I'd switch to CreateProcess as the purist solution for positional commands, were I able. I simply have been unable to find many online examples of its usage in VFP or other languages (which I am weak at) ... let alone for positional commands.

And you inspired my necessary workaround (which seems bulletproof for our 'unique' Window's titles (unique record strings)). Thank you for your patience.

Utmost blessings!
Philip
 
You're looking at he wrong place, you look for a direct solution of positional parameters.
The mere difference of ShellExecute and CreateProcess is, that you have the some data about the new process.
You have a unique identifier for the project in this line:

Code:
lhProcess = CHARTOBIN( SUBSTR(cProcessInfo,1,4) )

And there's more in cProcessInfo, you also get the ProcessID:
You can do like Hans in Luck and trade the ProcessID until you get the HWND you need for SetWindowPos(). The final solution still is SetWindowPos, but you get the handle on a more concrete identifier than the Window title.

Bye, Olaf.
 
Olaf, I am in a similar dilemma as "Anita":
Like her, I've failed when I made public Strahl's cProcessInfo and lhProcess, to try to obtain the correct HWND pass to SetWindowPos(HWND) ... i.e.,

Code:
SetWindowPos( pcProcess,-2,0,0,nWidth,nHeight, 0)
Code:
SetWindowPos( pProcessInfo ,-2,0,0,nWidth,nHeight, 0)

For Anita, You sympathetically and graphically highlighted a processID of "10620", iirc (correction 8-21-16: albeit mine is 4 digits) ... numbers similar to my own. Are these 5 digit numbers the final HWND or is it some hexadecimal 'thingy' that requires yet another API or wrapper? Finally, you mentioned "GetWindowThreadProcessId(hwnd,@dwPID)", "parent/child relationship Processes", "differing Process and Thread IDs", etc. ...
I think I am like Anita: hoping and praying, seeking for the real HWND and correct API manipulations of the processID. We are very inspired by you and Strahl but need to learn the tricky APIs better. I don't know.

Thank you exceedingly for your patience, time, and inspiration.
Utmost Blessings!
Philip
 
A process handle is not a hwnd.

You can do like Hans in Luck and trade the ProcessID until you get the HWND you need for SetWindowPos().

Please google and find out yourself how to do this, just one time.

Bye, Olaf.
 
There seem to be dWORDS and c++ structs with "Hans in Luck" ... getting the HWND from the ProcessID ... I'll study more, Lord willing.

CreateProcess() seems excellent and straightforward for files (notepad, excel, jpgs, docs, pdfs, etc), but
CreateProcess() is tricky for managing explorer-folders and URLs in VFP.

Three champions I've emulated (1) (2) Stahl (above), and, (3) Ed Rauh's CreateProcess() wrapper (Process.vcx) ... all seem unable to terminate explorer folders with CreateProcess(). I've tested successfully with files. Folders and Chrome 'instances' always fail to close.

I'll continue studying, Lord willing.

Utmost Blessings!
Philip
 
Status
Not open for further replies.

Part and Inventory Search

Sponsor

Back
Top