Announcement

Collapse
No announcement yet.

Dialog Not Getting Back Focus

Collapse
X
 
  • Filter
  • Time
  • Show
Clear All
new posts

  • Dialog Not Getting Back Focus

    I commonly use the following code to disable to the current program and dialog while calling another program to look something up and return a value to the calling program.

    Problem is that most computers will dutifully cause the calling program to receive full focus while others do not whether or not some other program is running on the desktop.

    Not shown is the attempt to use SetForeGroundWindow api function with the handle of the dialog. I've also tried SetFocus hdlg where hdlg is the window handle of the dialog that needs to be fully focused. The taskbar item seems to actually have the focus even though the program is the only one on the screen.

    Any help with forcing the program I want to always have the foreground focus would be helpful.

    Code:
    '
    'Call party lookup program
    '
      LSET C.INQ = "": SPARE$ = CPROGID$: LSET C.SPARE = SPARE$: C.LSPARE = LEN(SPARE$)': @pC = C
      PU_PROG$ = CPROGID$: LSET C.PU_PROG = PU_PROG$: @pC = C
      IF FNSP(CUST_DIR$) THEN
        SHELLPROG$ = "PUPARTY.EXE "
      ELSE
        SHELLPROG$ = $STDEXE + "PUPARTY.EXE "
      END IF
      DIALOG DISABLE hdlg
      Yinstance& = SHELL(SHELLPROG$ + COMMONLINK$)
      SLEEP 1000
      Zprocessid& = OpenProcess(%PROCESS_QUERY_INFORMATION + %PROCESS_TERMINATE,%False,Yinstance&)
      DO
        DIALOG DOEVENTS
        I& = GetExitCodeProcess(BYVAL Zprocessid&,lpExitCode&)
      LOOP WHILE lpExitCode& = %STILL_ACTIVE
      DIALOG ENABLE hdlg
      DIALOG SHOW STATE hdlg,%SW_SHOWNORMAL
      stat = GetCommon(C)
      INQPARTY$ = RTRIM$(INQ$)
      VKEY = 0
    RETURN
    BOB MECHLER

  • #2
    Try SetFocus() to one of the controls on the dialog. (a button or text box)

    Or 'CONTROL SET FOCUS', I guess, if you are DDT guy.
    Michael Mattias
    Tal Systems (retired)
    Port Washington WI USA
    [email protected]
    http://www.talsystems.com

    Comment


    • #3
      Along with 'SetForeGroundWindow', you might also try 'SetActiveWindow'.

      Comment


      • #4
        Will try both. Thanks.

        What is odd is that when control comes back to the program the dialog is enabled, the program actually takes the info returned, fills in one field, looks up a description on another file, fills that in on the dialog in question and then it loses focus (on some machines). Really weird.

        Bob Mechler

        Comment


        • #5
          Neither works.
          Putting a msgbox just before the system activates the next control does work. I'm trying a sleep statement.

          The program is shelling to another program for lookup which itself may shell to another program to do an Add of a code.

          When it comes back from adding it returns to the lookup program and immediately returns to the first calling program. It's probably a timing issue but only occurs on 20% of the machines we are testing with.

          The taskbar item for the dialog flashes at the bottom when it returns and nothing on the desktop has focus. The taskbar might be what has the focus.

          Bob Mechler

          Comment


          • #6
            Another API call to possibly try is BringWindowToTop...

            Possibly SetFocus, then that one...
            Adam Drake
            PowerBASIC

            Comment


            • #7
              Nothing works so far on these 3 machines. You have to click on the dialog even though the program just filled in two fields and created a new field where it seems the focus is (the insertion bar is blinking there).


              Bob Mechler

              Comment


              • #8
                Show enough failing code for others to compile and try.

                I don't "do DDT" but I know SetFocus() works perfectly for this using SDK-Style coding.

                Also with DIALOG SHOW STATE in there, include compiler version. IIRC that had some issues in prior versions of compiler.
                Michael Mattias
                Tal Systems (retired)
                Port Washington WI USA
                [email protected]
                http://www.talsystems.com

                Comment


                • #9
                  Michael, what you are suggesting would be the next step if the code involved wasn't over 6,000 lines. If I can't figure it out this evening, I'll have to write something a lot smaller that has the same problem, and if I can't figure it out, that is what I will do.

                  Right now it's back to SetWindowText and sleep every few lines of code. Can't use msgbox's cause when I do, the dialog properly gets focus.

                  Bob Mechler

                  Comment


                  • #10
                    Problem solved to my satisfaction.

                    DIALOG SHOW STATE hdlg,%SW_HIDE
                    SLEEP 500
                    DIALOG SHOW STATE hdlg,%SW_SHOW

                    The SLEEP 500 may not have to be that long. I'm still working with it. The machine was a Windows 2000 which may have had something to do with it.

                    BOB MECHLER

                    Comment


                    • #11
                      Well. as long as you have that solved... you may as well replace this:
                      Code:
                      Yinstance& = SHELL(SHELLPROG$ + COMMONLINK$)
                        SLEEP 1000
                        Zprocessid& = OpenProcess(%PROCESS_QUERY_INFORMATION + %PROCESS_TERMINATE,%False,Yinstance&)
                        DO
                          DIALOG DOEVENTS
                          I& = GetExitCodeProcess(BYVAL Zprocessid&,lpExitCode&)
                        LOOP WHILE lpExitCode& = %STILL_ACTIVE
                      ... with this function ...
                      Win 32: Monitor Process with ShellExecuteEx June 22, 2001

                      .. which waits for completion.

                      If you have a dialog you need to be responsive at this time, run the function in its own thread of execution. You can go right from this demo:
                      GUI + Worker Thread + Abort Demo 11-24-07

                      MCM
                      Michael Mattias
                      Tal Systems (retired)
                      Port Washington WI USA
                      [email protected]
                      http://www.talsystems.com

                      Comment


                      • #12
                        Thanks, needed more Thread examples.

                        Dialog Redraw also worked on the original problem. The Zorder being messed with by Yahoo IM I think was related somehow. Probably used SetWindowPos to grab the TopMost position. The tester of the program is always getting IM's from different people in the office.

                        Bob Mechler

                        Comment


                        • #13
                          Glad you got it working.
                          Here is another shell replacement using WaitForSingleObject.
                          It has worked in situations where environment space was a problem.

                          Code:
                          FUNCTION WaitShell(BYVAL CmdLine AS STRING, TimeOutInMilliseconds AS LONG) AS LONG
                          'Shells to another process with optional wait. Use %INFINITE to wait until done
                            LOCAL Si AS STARTUPINFO
                            LOCAL Pi AS PROCESS_INFORMATION
                            LOCAL Pid AS DWORD
                            Si.cb = SIZEOF(Si)
                            Si.dwFlags = %STARTF_USESHOWWINDOW
                            Si.wShowWindow = %SW_SHOWNORMAL
                            Pid = CreateProcess("", _
                              BYVAL STRPTR(CmdLine), _
                              BYVAL %NULL, _
                              BYVAL %NULL, _
                              0, _
                              %NORMAL_PRIORITY_CLASS, _
                              BYVAL %NULL, _
                              BYVAL %NULL, _
                              Si, _
                              Pi)
                            IF Pid THEN
                              'Call WaitForInputIdle(pi.hProcess, %IGNORE) 'not needed
                              FUNCTION = WaitForSingleObject(pi.hProcess, TimeOutInMilliseconds)
                              CALL CloseHandle(pi.hProcess)
                              CALL CloseHandle(pi.hThread)
                              ELSE
                              ? "Unable to CreateProcess, error" + STR$(GetLastError)
                            END IF
                          END FUNCTION
                          The world is full of apathy, but who cares?

                          Comment

                          Working...
                          X