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

Returning focus to my application 1

Status
Not open for further replies.

StewartUK

Programmer
Feb 19, 2001
860
GB
I've implemented sonething where my application waits for the user to copy a url from somewhere. I set a variable to the _CLIPTEXT value and then run a DO loop until the _CLIPTEXT value changes.

Here's the code so far:
Code:
OriginalCliptext = _CLIPTEXT
MbResponse = MESSAGEBOX("Waiting for you to copy a web page url", Mb_OkCancel+Mb_InfoIcon, "Foundation")
DO WHILE OriginalCliptext = _CLIPTEXT AND MbResponse = MB_RTNOK
   WAIT WINDOW TIMEOUT 1 [] && so that there is a pause in processing allowing for the change in _CLIPTEXT to be detected
ENDDO

IF MbResponse = MB_RTNOK
   WITH THIS.Parent.edtDetail
      .Value = LEFT(.Value, .SelStart) + [<a href='] + _CLIPTEXT + ['>] + _CLIPTEXT + [</a>] + SUBSTR(.Value, IIF(.SelStart>0, .SelStart, 1))
   ENDWITH
*   ThisWindow = THISFORM.HWnd && _SCREEN.HWnd
*   ShowWindow(ThisWindow, 1)
*   BringWindowToTop(ThisWindow)
*   THISFORM.Show()
ENDIF

As you can see, I've been trying to get Windows to return control to my application once it detects that _CLIPTEXT has changed. However, none of my efforts have worked so far. I tried a messagebox after the IF..ELSE..ENDIF which also didn't work.

Does anyone have a suggestion?

Thanks,

Stewart
 
Stewart,

Let me get this right. In your application, you display the message box, and wait for the user to reply. If they hit OK, you then expect them to go to another application to alter the clipboard. Is that right?

Obviously, if they alter the clipboard before they hit OK, you'll never detect that. But as far as I can see, that's not the problem right now.

The issue seems to be that VFP will never have a chance to respond to Windows events, so it won't see the refreshed clipboard, even after the user has altered it.

One solution might be to remove the WAIT command, and to do a call to Sleep() instead. That will give VFP a chance to relinquish control, so that Windows has a chance to update the clipboard.

A better approach might be to use BINDEVENT() to trap the change in the clipboard. I can't give you any details about how to do that, but you should be able to figure it out.

Hope this helps.

Mike

__________________________________
Mike Lewis (Edinburgh, Scotland)

My Visual FoxPro site: www.ml-consult.co.uk
 
Mike,

Thanks for responding. I sometimes get the impression you're sitting there at your desk waiting for the next Tek-Tips question to arise!

Um, VFP is detecting the change and inserting the clipboard contents as I wanted.

The issue is that I can't get VFP to grab back control from IE (or do I mean I can't get it to get Windows to return control...).

I was always under the impression that Sleep sent Windows into sleep, stopping everything from working.

Stewart
 
I would think that these would work, but it may be because you have them in the wrong order of execution:
ShowWindow(ThisWindow, 1)
BringWindowToTop(ThisWindow)

Try it this way:
BringWindowToTop(ThisWindow)
ShowWindow(ThisWindow, 1)

And make sure you are getting the right window name.

On a side note, the API call of Sleep() only 'sleeps' the application that calls it.


-Dave Summers-
[cheers]
Even more Fox stuff at:
 
Stewart,

I sometimes get the impression you're sitting there at your desk waiting for the next Tek-Tips question to arise!

Naah. I only visit the forum on my tea breaks, when I want something relaxing to take my mind off work for a few minutes.

I was always under the impression that Sleep sent Windows into sleep, stopping everything from working.

No, it only suspends the program that calls it. The rest of the system will carry on working. The point is that other applications can then generate messages, which the sleeping application can later pick up.

I feel sure there must be a system message that tells you when the clipboard has changed, but I haven't a clue where to find out about it.

Mike

__________________________________
Mike Lewis (Edinburgh, Scotland)

My Visual FoxPro site: www.ml-consult.co.uk
 
Thanks for correcting me about sleep, that's helpful.

Dave - I tried the API calls again, switching them like you suggested, but that had no effect.

I tried them with the HWnd property of bith _SCREEN & the form. That is the correct property isn't it?

I hadn't thought about getting a system message about clipboard changes. I found a few web pages that might be helpful.

Stewart
 
Stewart,
Actually, you need to use the window handle of the application - as in what is shown in the task manager using FindWindow, GetWindow, GetWindowText, ... API calls.

The following is code I use to check for an instance of my app already running. I used examples from here on tek-tips, but I'm not certain which author or authors supplied the bulk of the code. (My apologies).

You may be able to adapt this code to set focus if the _CLIPTEXT changes. I wanted to be sure though, that you had the full code in order to find the proper window handle.

The app name specific parts are in blue:
Code:
PARAMETERS p1, p2, p3, p4, p5
LOCAL laApp, lnHandle, lnCount, lcTitle, lnI, lnHFox

STORE '' TO cParms
IF PCOUNT() > 0
   FOR zzz = 1 TO PCOUNT()
      STORE 'p' + ALLTRIM(STR(zzz)) TO cparmx
      cParms = cParms + "'" + EVALUATE(cparmx) + "' "
   NEXT
ENDIF

DIMENSION laApp[1]
lnHFox=0

#DEFINE SW_HIDE             0
#DEFINE SW_SHOWNORMAL       1
#DEFINE SW_NORMAL           1
#DEFINE SW_SHOWMINIMIZED    2
#DEFINE SW_SHOWMAXIMIZED    3
#DEFINE SW_MAXIMIZE         3
#DEFINE SW_SHOWNOACTIVATE   4
#DEFINE SW_SHOW             5
#DEFINE SW_MINIMIZE         6
#DEFINE SW_SHOWMINNOACTIVE  7
#DEFINE SW_SHOWNA           8
#DEFINE SW_RESTORE          9
#DEFINE SW_SHOWDEFAULT      10
#DEFINE SW_FORCEMINIMIZE    11
#DEFINE SW_MAX              11

DECLARE INTEGER FindWindow ;
   IN win32api ;
   INTEGER nullpointer, ;
   STRING cwindow_name

DECLARE INTEGER GetWindow ;
   IN win32api ;
   INTEGER ncurr_window_handle, ;
   INTEGER ndirection

DECLARE INTEGER GetWindowText ;
   IN win32api ;
   INTEGER n_win_handle, ;
   STRING @ cwindow_title, ;
   INTEGER ntitle_length

DECLARE LONG BringWindowToTop IN Win32API LONG

DECLARE INTEGER GetCurrentThreadId;
   IN kernel32

DECLARE INTEGER GetWindowThreadProcessId IN user32;
   INTEGER   HWND,;
   INTEGER @ lpdwProcId

DECLARE INTEGER GetCurrentThreadId;
   IN kernel32

DECLARE INTEGER AttachThreadInput IN user32 ;
   INTEGER idAttach, ;
   INTEGER idAttachTo, ;
   INTEGER fAttach

DECLARE INTEGER GetForegroundWindow IN user32

DECLARE Long ShowWindow In Win32API Long, Long

DECLARE INTEGER ShellExecute IN shell32.DLL ;
   INTEGER hndWin, ;
   STRING cAction, ;
   STRING cFileName, ;
   STRING cParams, ;
   STRING cDir, ;
   INTEGER nShowWin

STORE .F. TO lFoundIt
lnHFox = FindWindow(0,_SCREEN.CAPTION)
lnHandle = lnHFox && GetWindow(lnHFox,0)
lnCount = 0

DO WHILE lnHandle > 0
   lcTitle=SPACE(255)
   lnI=GetWindowText(lnHandle, @lcTitle,LEN(lcTitle))
   IF lnI>0
      lcTitle=STRTRAN(TRIM(lcTitle),CHR(0),"")
   ELSE
      lcTitle=""
   ENDIF
   IF lnHandle > 0 .AND.  !EMPTY(lcTitle)
[COLOR=blue]      &&...  As shown in the 'Applications' tab of Task Manager
      IF 'YourAppName' $ lcTitle  [/color]
         STORE lnHandle TO nAppHandle
         lFoundIt = .T.
      ENDIF
   ENDIF
   lnHandle = GetWindow(lnHandle,2)
ENDDO
[COLOR=blue]IF lFoundIt 
   &&... Force window to foreground
   =ForceForegroundWindow(nAppHandle)[/color]
ELSE
[COLOR=blue]   &&...  otherwise, start a new instance
   DO YourAppMainPrg WITH p1, p2, p3, p4, p5[/color]
ENDIF

RETURN

FUNCTION ForceForegroundWindow(lnHWND)

   LOCAL nForeThread, nAppThread

   nForeThread = GetWindowThreadProcessId(GetForegroundWindow(), 0)
   nAppThread = GetCurrentThreadId()

   IF nForeThread != nAppThread
      AttachThreadInput(nForeThread, nAppThread, .T.)
      BringWindowToTop(lnHWND)
      SHOWWINDOW(lnHWND, SW_SHOWNORMAL)
      AttachThreadInput(nForeThread, nAppThread, .F.)
   ELSE
      BringWindowToTop(lnHWND)
      SHOWWINDOW(lnHWND, SW_SHOWNORMAL)
   ENDIF

ENDFUNC





-Dave Summers-
[cheers]
Even more Fox stuff at:
 
Thanks for all that Dave. Off for the weekend now, get back Monday.

Have a good one!

Stewart
 
OK, so it took more than the weekend...

Brilliant Dave [2thumbsup], thanks so much. Works perfectly.

Stewart
 
Dave,

How about an FAQ of this? I'm sure others would find it very useful.

Stewart
 
Well, thanks for the flattery. I'm glad you got it working. [smile]

I was considering writing an FAQ, but I think most of the grunt work has already been taken care of by Craig here:
Force Window to Front (not blink in taskbar)
faq184-4262

and danceman here:
Having only one instance of App, bring window to top
faq184-1998

I forget exactly, but I'm sure that's where I got my inspiration - to both of which I'll tip my hat [thumbsup]


-Dave Summers-
[cheers]
Even more Fox stuff at:
 
Status
Not open for further replies.

Part and Inventory Search

Sponsor

Back
Top