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 IamaSherpa on being selected by the Tek-Tips community for having the most helpful posts in the forums last week. Way to Go!

Command Window vs. VFP screen focus issue 2

Status
Not open for further replies.

dmusicant

Programmer
Mar 29, 2005
253
US
I have written some code that puts data on the clipboard that I paste into a totally different (i.e. non-Foxpro) application on the computer. This works nicely in that I can Alt+Tab from VFP 9.0 to my other app, and do my pastes. I've been using one particular Windows (Win7) machine to do this, but right now that machine is down for repairs, etc. and I'm using another of my machines to run all this. This machine is running WinXP.

This works like so: I run the code from the Command Window, rerunning one of two routines (depending on what data I want on the clipboard) by clicking my cursor next to the command and pressing Enter. I then Alt+Tab back to the other app to paste. But on the WinXP machine I have to press Alt+Tab twice instead of once. It seems that this is because on this machine (and not the other, evidently), the Command Window has focus and I have to first give the VFP main screen focus before I can get back to the other app, therefore having to press Alt+Tab twice. Why is the behavior different for my two machines and is there a way I can eliminate having to press Alt+Tab twice to get back to my other app?
 
I am on my other machine, the Win7 one, and when in the Command Window, the main VFP screen does NOT have focus. But pressing Alt+Tab takes me to the last application, not the VFP main screen as happens with the WinXP machine. Is this an OS issue or is it a VFP configuration issue?
 
Yes, I can confirm this behaviour. I've never noticed it before - because it's never been an issue for me.

Is this operation something that you are doing yourself, on your own computer? If so, what is the problem with pressing Alt+TAB twice? It can only take a fraction of a second each time.

Or is it part of an application for end-users to operate? In that case, it would be better not to rely on Alt+TAB, but instead to set focus to the other application programmatically. That way, it would work the same on all machines, and it wouldn't depend on the applications being used in any particular order.

If you want to take that route, you can do it using Windows API calls, such as ShowWindow() and GetActiveWindow(). Let us know if you need an example of the code.

Mike

__________________________________
Mike Lewis (Edinburgh, Scotland)

Visual FoxPro articles, tips and downloads
 
The difference in behavior from one machine to another is most likely caused by the Dockable setting on the command window. Right click the CW's title bar and toggle the setting from the popup menu.
 
Dan's right. I've just tested it.

But I still think you should consider switching windows programmatically (if this process is part of a user applcation), as that will remove any dependency on the order of the windows or the dockability of the command window.

Mike

__________________________________
Mike Lewis (Edinburgh, Scotland)

Visual FoxPro articles, tips and downloads
 
Well, it shouldn't run in the IDE, unless it's a VFP IDE Add-On like several VFPX projects.
If it's just a tool you use there wouldn't be anything left to do, either change the dockable state of the command window or switch with double ALT+TAB.

Bye, Olaf.
 
Probably changing the dockable state is the easy answer. It's just me running this thing, but when I do this (once a week) I have to do it many times and I have a muscle-memory kind of activity going on. I do the Alt-Tab thing over 50 times at a sitting, possibly closer to 100 times, depending on the state of the data in the other application. I guess it's not a big deal because my Win7 laptop should be up in a day or so.

I'm curious about that Windows API code, could you paste in an example call? I've never done that. Maybe incorporating that into my routine will further automate the entire process, make it go faster and easier. This thing is something I've developed over the last few months, further refinement would nice, fun too! I first run a little PRG to open a table, set index and find the initial record. Then I run either of two PRGs from the Command Window to put appropriate text on my clipboard. I then Alt-Tab to the other app and paste (Control+V) into its data capture applet and Alt-Tab back to VFP and run either of the two PRGs (my choice at this point, it's not always the same) by clicking it in the Command Window and hitting <Enter>. If either of those PRGs could send me right to the other app, that would save me a lot of key strokes.
 
I'd double think, if full automation would help. Now you are verifying each paste of data into the foreign application, intended or not, because you visually see what you paste. That in itself wouldn't change, if the activation of applications is the only thing you automate, but it all seems half baked to me.

Do you paste into a web site form? You can automate any html form by browser automation.

AutoHotKey also is a recommendable tool in case of interop via simulated interaction, eg for activation of a certain window by title caption see:

Bye, Olaf.
 
Thanks, Olaf. Well, the app I'm pasting into isn't browser based. It runs on my PC, although the data, once pasted into and saved in the app it gets uploaded to a server somewhere. I know this because I can open the app on my other machines and it always has the latest data. The app doesn't like it when it's running on two machines simultaneously, well it at the very least gives a hiccup!

I'll see if I can incorporate code in my two little PRGs that switches to the other app so I don't have to continually do the Alt-Tab thing. It isn't that hard to do, I'm good at it, but saving that step would further refine the whole process very significantly.
 
Here's a bit of code that might do what you want. It will look at all the application windows that are open on the desktop, and switch to the one that you specify (if the application is open). You'll need to plug in the title of the target application (or part of it), as indicated in the code.

Code:
DECLARE INTEGER GetActiveWindow IN Win32API

DECLARE INTEGER GetWindow IN Win32API ;
  INTEGER HWND, INTEGER nType

DECLARE INTEGER GetWindowText IN Win32API ;
  INTEGER HWND, STRING @cText, INTEGER nType

DECLARE INTEGER SHOWWINDOW IN Win32API ;
  INTEGER HWND, INTEGER CmdShow

lcTitle = "My Application"
    && Set this to any text that you know will appear in the
    && title bar of the target window

hNext = GetActiveWindow()

* iterate through the windows on the desktop
DO WHILE hNext<>0
  cText = REPLICATE(CHR(0),80)
  GetWindowText(hNext,@cText,80)

  IF UPPER(lcTitle) $ UPPER(cText)
    SHOWWINDOW(hNext,1)  && 1 means show in normal window
    EXIT
  ENDIF

  hNext = GetWindow(hNext,2)
ENDDO

I have only tested it very quickly, so let me know if any problems.

Mike


__________________________________
Mike Lewis (Edinburgh, Scotland)

Visual FoxPro articles, tips and downloads
 
Why not use FindWindow? Besides a Window already in normal mode will not come to front without SetForeGroundWindow...

Code:
lcTitle = "My Application"
*#beautify keyword_nochange
DECLARE INTEGER FindWindow IN Win32API ;
  STRING @ClassName, STRING @Caption

DECLARE INTEGER ShowWindow IN Win32API ;
  INTEGER HWND, INTEGER CmdShow

DECLARE INTEGER SetForegroundWindow IN Win32API ;
  INTEGER HWND
*#beautify  
[s][/s]
lnHwnd = FindWindow(NULL,lcTitle)
If lnHwnd<>0
   ShowWindow(lnHwnd,1)
   SetForegroundWindow(lnHwnd)
Endif

Bye, Olaf.


 
Today this was a "life saver" for myself.

For whatever reason (Windows 8 perhaps) the foxpro screen docked spanning my three monitors and beyond that (the upper right control box with the buttons to set the window to normal or minimze wasn't displayed, it must have become off screen or better off screens). What's more important: The inner editor window was visible in display 1, but I couldn't activate/focus it and my last changes would have been lost without resetting the window to normal size mode via ShowWindow(lnHwnd,1).

I could open a second VFP session, set it's caption to something else than "Microsoft Visual FoxPro" and then save the somehwat strangely overmaximised first VFP IDE session by finding and "normalizing" that "Microsoft Visual FoxPro" window.

Bye, Olaf.
 
MikeLewis,

When I run the code you specified as a PRG, substituting part of the title of the other app for My Application (while that application is running in Windows), I get the following error at this point:

DECLARE INTEGER SHOWWINDOW IN Win32API ;
INTEGER HWND, INTEGER CmdShow

The error is:

Cannot find entry point SHOWWINDOW in the DLL.
 
***********************************************
Cannot find entry point SHOWWINDOW in the DLL.
***********************************************
Because SHOWWINDOW is case sensitive use --> ShowWindow

DECLARE INTEGER ShowWindow IN Win32API ;
INTEGER HWND, INTEGER CmdShow
 
This is because function names in the Windows API are case-senstive. If you change SHOWWINDOW to ShowWindow, it should work.

This is my fault. I used Beautify to clean up the code before I posted it. I have Beuatify configured to capitalise VFP function names, and, of course SHOWINDOW() happens to be a VFP function. Olaf spotted that, and inserted [tt]*#beautify keyword_nochange[/tt] in his version of the code.

Mike

__________________________________
Mike Lewis (Edinburgh, Scotland)

Visual FoxPro articles, tips and downloads
 
Mike is correct. API functions are case sensitive, so Windows API knows ShowWindow(), but not SHOWWINDOW(). This only ever is a problem, if beautfy modifies the case of keywords and ShowWindow is one, that VFP also knows. In VFP it's a form class property, which name is derived from that API call for sure.

It's safe to put all declarations between *#beautify keyword_nochange and *#beautify to let keywords stay unmodified, even though there is just a small overlap of function names and VFP keywords and if you use CamelCase beautification the risc is even lower.

[URL unfurl="true"]http://fox.wikis.com/wc.dll?vfp~BeautifyDirectivekeywordnochange[/url]

Bye, Olaf.
 
Thank you, folks. Yes, I understand the issue, or think I do. Well, I've changed the ShowWindow() call to accommodate the necessary case sensitivity, and the code doesn't error, but when I run the PRG from the command window when the other app is also running I get no reaction. It's as though the entire function were RETURN. Possibly it's because of the nature of the app? The app is ThinkorSwim, the trading platform from TDAmeritrade. It's probably built on C++, is my thinking and doesn't look particularly like a WinAPI type of application.

Now, I tried this with one of my other apps, my email client (Forte Agent 1.932), and it does work... sort of. I run Agent full screen. My Switch.prg function brings up Agent non-full screen. If I then switch back to VFP (Alt-Tab), and run Switch again, nothing happens. If I have in the meantime changed Agent to Full Screen, VFP will bring it up again non-full screen.

Well, maybe ThinkorSwim can't be switched to using this Win API call strategy?
 
Well, both code alternatives use ShowWindow(hWnd,1), which means the window will be put to normal mode, no matter if it was in maximised or minimized or nomral mode before. You can use other parameter values instead of 1, see the definition of ShowWindow.

Aside of that some apps may not create Winforms, I don't know whether WPF application windows also react to ShowWindow. And the caption must fit exact, also case sensitive. Some applications show some side info in the caption, eg a mail client mail window caption may be showing a mail subject. If the caption is not constant you won't find the window unless you change code all the time, and that may become more cimbersome than hitting ALT+TAB twice.

By now I think you're really wasting your time. You'l surely find something more beneficial than thinking about how to save some seconds here. I know you said "muscle memory" and I know what you mean, but with a little less speed and a bit more concentration this'll work out much easier. If it's all about trading I'd rather look out for something you can automate fully via some SDK or developer API than with copy&paste.

Bye, Olaf.



 
Yea, Alt-Tab isn't a biggie. Actually, what bothered me was just that with one machine I only had to do it once, from the other twice. You guys explained how I can eliminate the extra one, so now I can have both machines do a single. I was only using the other machine because this one was down for repairs. Those are done, I believe, and will stick with using this machine for that functionality. I do like the functionality as it is, it doesn't bother me, so I don't much care if I can't get the ShowWindow() thing to work. I just thought "that would be cool." But it's no biggie. The info I am injecting into ThinkorSwim is provided by a company I'm subscribed with. I have thought about calling them and asking if they can provide me the data in some form other than a newspaper (that's where I'm getting the data, I'm actually typing it into FoxPro from the print newspaper!). They have an online presence, I'm sure they have the data digitally, of course, that's the way even print newspapers work these days. Besides, they have an online version of the newspaper... It's Investor's Business Daily. However, they aren't very geeky, is my sense of it, they are apt to tell me they can't accommodate me in terms of sending me a spreadsheet or some such thing. No biggie, I don't mind typing all the stuff in.
 
Status
Not open for further replies.

Part and Inventory Search

Sponsor

Back
Top