System tray problem using a custom shell instead of windows explorer

Collapse
This topic is closed.
X
X
 
  • Time
  • Show
Clear All
new posts
  • none@comcast.net

    System tray problem using a custom shell instead of windows explorer

    Hello all, I wrote a shell program a few years ago in VB6 that needs
    to be modified. The problem I have is this:

    The SysAdmin uses this shell in place of Explorer, so there is no
    taskbar. When his users run PC Anywhere from the shell, and minimize
    it, it minimizes to the system tray. With no task bar, there is no
    system tray, so there is no way to restore the PC Anywhere window.

    The shell starts PC Anywhere using ShellExecute. I have found a lot
    of info on Shell_NotifyIco n but this doesn't seem to do what I need.
    All I need to do is restore the PC Anywhere window.

    One more thing, the shell installs with no installation program (one
    of the requirements for the project), and is on about 50 machines, so
    I don't want to have to add and register another dll, or ocx if
    possible. I found an example on how to see if the app was running,
    but uses a dll that would have to be registered on every machine to
    work.

    Any help would be greatly appreciated
  • J French

    #2
    Re: System tray problem using a custom shell instead of windows explorer

    On Sat, 31 Jul 2004 01:54:11 -0400, none@comcast.ne t wrote:
    [color=blue]
    >Hello all, I wrote a shell program a few years ago in VB6 that needs
    >to be modified. The problem I have is this:
    >
    >The SysAdmin uses this shell in place of Explorer, so there is no
    >taskbar. When his users run PC Anywhere from the shell, and minimize
    >it, it minimizes to the system tray. With no task bar, there is no
    >system tray, so there is no way to restore the PC Anywhere window.
    >
    >The shell starts PC Anywhere using ShellExecute. I have found a lot
    >of info on Shell_NotifyIco n but this doesn't seem to do what I need.
    >All I need to do is restore the PC Anywhere window.
    >
    >One more thing, the shell installs with no installation program (one
    >of the requirements for the project), and is on about 50 machines, so
    >I don't want to have to add and register another dll, or ocx if
    >possible. I found an example on how to see if the app was running,
    >but uses a dll that would have to be registered on every machine to
    >work.
    >
    >Any help would be greatly appreciated[/color]

    Your Shell sounds really interesting.
    I wonder where PC Anywhere is getting minimized to if there simply is
    no system tray

    However, if it works consistently, then I doubt if that matters much.

    Since you start PC Anywhere, you can easily find its main window
    handle and can SendMessage commands to bring it back up again.

    HTH

    Comment

    • none@comcast.net

      #3
      Re: System tray problem using a custom shell instead of windows explorer

      I think I'll try openeing it with CreateProcess instead of
      ShellExecute. ShellExecute doesn't return the handle to the window
      (bummer), so from what I understand, I would have to use the
      FindWindow API to get the handle. I am not sure what the window
      caption will be, and from what I can tell, there is no way to wait for
      the app to start to get the caption using ShellExecute. I am afraid
      if the user opens PC Anywhere, then opens another program right away,
      I would get the wrong handle if I used somthing like GetForgoundWind ow
      to retrieve the handle. I'll let you know what I come up with.

      If you want a copy of the shell, there is a trial version you can
      download from my site:



      Just scroll down to "Window Replacement Shell"


      On Sat, 31 Jul 2004 07:44:54 +0000 (UTC), erewhon@nowhere .com (J
      French) wrote:
      [color=blue]
      >On Sat, 31 Jul 2004 01:54:11 -0400, none@comcast.ne t wrote:
      >[color=green]
      >>Hello all, I wrote a shell program a few years ago in VB6 that needs
      >>to be modified. The problem I have is this:
      >>
      >>The SysAdmin uses this shell in place of Explorer, so there is no
      >>taskbar. When his users run PC Anywhere from the shell, and minimize
      >>it, it minimizes to the system tray. With no task bar, there is no
      >>system tray, so there is no way to restore the PC Anywhere window.
      >>
      >>The shell starts PC Anywhere using ShellExecute. I have found a lot
      >>of info on Shell_NotifyIco n but this doesn't seem to do what I need.
      >>All I need to do is restore the PC Anywhere window.
      >>
      >>One more thing, the shell installs with no installation program (one
      >>of the requirements for the project), and is on about 50 machines, so
      >>I don't want to have to add and register another dll, or ocx if
      >>possible. I found an example on how to see if the app was running,
      >>but uses a dll that would have to be registered on every machine to
      >>work.
      >>
      >>Any help would be greatly appreciated[/color]
      >
      >Your Shell sounds really interesting.
      >I wonder where PC Anywhere is getting minimized to if there simply is
      >no system tray
      >
      >However, if it works consistently, then I doubt if that matters much.
      >
      >Since you start PC Anywhere, you can easily find its main window
      >handle and can SendMessage commands to bring it back up again.
      >
      >HTH[/color]

      Comment

      • none@comcast.net

        #4
        Re: System tray problem using a custom shell instead of windows explorer

        OK, feel free to call me a complete dumb ass... I have tried start
        an app using CreateProcess, but this does not give the handle to the
        application. It does, however, give the dwProcessID, dwThreadId,
        hThread, and hProcess. I tried to use the dwProcessID and OpenProcess
        API to get the handle from the PIDL, but this didn't work.

        So, I launch PC Anywhere using ShellExecute, then enable a timer I
        have on the main form. After 1 second, it gets the handle of the top
        most window (should be PC Anywhere) using the GetForgroundWin dow API.
        The handle is stored in a global variable (hdlPCAnywhere) , so if the
        user presses the button again for PC Anywhere, the sub routine sees
        this variable's value is not 0 and calls the ShowWindow(hldP CAnywhere,
        9) API.

        This works, but I think there is a better way - any ideas? I thought
        there was a way to launch an app from VB and get the apps handle as a
        return value of the call.
        [color=blue]
        >
        >Your Shell sounds really interesting.
        >I wonder where PC Anywhere is getting minimized to if there simply is
        >no system tray
        >
        >However, if it works consistently, then I doubt if that matters much.
        >
        >Since you start PC Anywhere, you can easily find its main window
        >handle and can SendMessage commands to bring it back up again.
        >
        >HTH[/color]

        Comment

        • J French

          #5
          Re: System tray problem using a custom shell instead of windows explorer

          On Sat, 31 Jul 2004 20:23:41 -0400, none@comcast.ne t wrote:
          [color=blue]
          >OK, feel free to call me a complete dumb ass... I have tried start
          >an app using CreateProcess, but this does not give the handle to the
          >application. It does, however, give the dwProcessID, dwThreadId,
          >hThread, and hProcess. I tried to use the dwProcessID and OpenProcess
          >API to get the handle from the PIDL, but this didn't work.
          >
          >So, I launch PC Anywhere using ShellExecute, then enable a timer I
          >have on the main form. After 1 second, it gets the handle of the top
          >most window (should be PC Anywhere) using the GetForgroundWin dow API.
          >The handle is stored in a global variable (hdlPCAnywhere) , so if the
          >user presses the button again for PC Anywhere, the sub routine sees
          >this variable's value is not 0 and calls the ShowWindow(hldP CAnywhere,
          >9) API.
          >
          >This works, but I think there is a better way - any ideas? I thought
          >there was a way to launch an app from VB and get the apps handle as a
          >return value of the call.[/color]

          There is. You will find all you need in here:

          Option Explicit

          ' J French - 27th Nov 2003 / 1st Aug 2004
          ' Shell and Re-Parent
          ' hacked from MS and KPD
          ' Add Two Command Buttons

          Private Declare Function MoveWindow _
          Lib "user32" _
          (ByVal hwnd As Long, _
          ByVal x As Long, _
          ByVal y As Long, _
          ByVal nWidth As Long, _
          ByVal nHeight As Long, _
          ByVal bRepaint As Long) As Long

          Private Declare Function FindWindow _
          Lib "user32" _
          Alias "FindWindow A" _
          (ByVal lpClassName As Long, _
          ByVal lpWindowName As Long) As Long

          Private Declare Function GetWindow _
          Lib "user32.dll " _
          (ByVal hwnd As Long, _
          ByVal wCmd As Long) As Long

          Private Declare Function GetParent _
          Lib "user32" (ByVal hwnd As Long) As Long

          Private Declare Function SetParent _
          Lib "user32" _
          (ByVal hWndChild As Long, _
          ByVal hWndNewParent As Long) As Long

          Private Declare Function GetWindowThread ProcessId _
          Lib "user32" _
          (ByVal hwnd As Long, _
          lpdwProcessId As Long) As Long

          Private Declare Function LockWindowUpdat e _
          Lib "user32" _
          (ByVal hwndLock As Long) As Long

          Private Declare Function GetDesktopWindo w _
          Lib "user32" () As Long

          Private Declare Function Putfocus _
          Lib "user32" _
          Alias "SetFocus" _
          (ByVal hwnd As Long) As Long

          Private Declare Function SendMessage _
          Lib "user32" _
          Alias "SendMessag eA" _
          (ByVal hwnd As Long, _
          ByVal wMsg As Long, _
          ByVal wParam As Long, _
          ByVal lParam As Any) As Long

          Private Declare Function WaitForInputIdl e _
          Lib "user32.dll " _
          (ByVal hProcess As Long, _
          ByVal dwMilliseconds As Long) As Long



          Private Const STARTF_FORCEONF EEDBACK As Long = &H40

          Private Const GW_HWNDFIRST As Long = 0
          Private Const GW_HWNDNEXT = 2
          'Private Const WM_QUIT As Long = &H12
          Private Const WM_CLOSE = &H10
          Private Const WM_SYSCOMMAND As Long = &H112
          Private Const SC_CLOSE As Long = &HF060&

          Private Type STARTUPINFO
          cb As Long
          lpReserved As String
          lpDesktop As String
          lpTitle As String
          dwX As Long
          dwY As Long
          dwXSize As Long
          dwYSize As Long
          dwXCountChars As Long
          dwYCountChars As Long
          dwFillAttribute As Long
          dwFlags As Long
          wShowWindow As Integer
          cbReserved2 As Integer
          lpReserved2 As Long
          hStdInput As Long
          hStdOutput As Long
          hStdError As Long
          End Type

          Private Type PROCESS_INFORMA TION
          hProcess As Long
          hThread As Long
          dwProcessID As Long
          dwThreadID As Long
          End Type


          Private Declare Function CreateProcessA _
          Lib "kernel32" _
          (ByVal lpApplicationNa me As String, _
          ByVal lpCommandLine As String, _
          ByVal lpProcessAttrib utes As Long, _
          ByVal lpThreadAttribu tes As Long, _
          ByVal bInheritHandles As Long, _
          ByVal dwCreationFlags As Long, _
          ByVal lpEnvironment As Long, _
          ByVal lpCurrentDirect ory As String, _
          lpStartupInfo As STARTUPINFO, _
          lpProcessInform ation As PROCESS_INFORMA TION) As Long

          Private Declare Function WaitForSingleOb ject _
          Lib "kernel32" _
          (ByVal hHandle As Long, _
          ByVal dwMilliseconds As Long) As Long

          Private Declare Function CloseHandle Lib "kernel32" _
          (ByVal hObject As Long) As Long

          Private Const NORMAL_PRIORITY _CLASS = &H20&


          Dim mWnd As Long

          Function InstanceToWnd(B yVal target_pid As Long) As Long
          Dim test_hwnd As Long, _
          test_pid As Long, _
          test_thread_id As Long

          'Find the first window top level window
          test_hwnd = FindWindow(ByVa l 0&, ByVal 0&)
          test_hwnd = GetWindow(test_ hwnd, GW_HWNDFIRST)

          Do While test_hwnd <> 0
          'Check if the window isn't a child (??)
          If GetParent(test_ hwnd) = 0 Then
          'Get the window's thread
          test_thread_id = GetWindowThread ProcessId(test_ hwnd, _
          test_pid)
          If test_pid = target_pid Then
          InstanceToWnd = test_hwnd
          Exit Do
          End If
          End If
          'retrieve the next window
          test_hwnd = GetWindow(test_ hwnd, GW_HWNDNEXT)
          Loop
          End Function

          Public Function ExecCmd(cmdline $) As Long
          Dim proc As PROCESS_INFORMA TION
          Dim start As STARTUPINFO
          Dim Ret&

          ' Initialize the STARTUPINFO structure:
          start.cb = Len(start)
          start.dwFlags = STARTF_FORCEONF EEDBACK

          ' Start the shelled application:
          Ret& = CreateProcessA( vbNullString, cmdline$, _
          0&, 0&, 1&, _
          NORMAL_PRIORITY _CLASS, _
          0&, vbNullString, _
          start, proc)
          ' --- let it start - this seems important
          Call WaitForInputIdl e(proc.hProcess , 500)
          ' we should check the result of this

          If Ret Then
          ExecCmd = InstanceToWnd(p roc.dwProcessID )
          Me.Print Ret, ExecCmd
          Call CloseHandle(pro c.hThread)
          Call CloseHandle(pro c.hProcess)
          End If

          End Function


          Private Sub Command1_Click( )
          'KPD-Team 1999
          'URL: http://www.allapi.net/
          'E-Mail: KPDTeam@Allapi. net
          ' ---
          Me.AutoRedraw = True

          'Lock the window update
          LockWindowUpdat e GetDesktopWindo w

          'Execute notepad.Exe
          mWnd = ExecCmd("notepa d.exe")
          'If mWnd = 0 Then MsgBox "Error starting the app"

          Me.Print Str$(mWnd)
          ' Set the notepad's parent
          If mWnd Then
          SetParent mWnd, Me.hwnd
          ' -
          Me.ScaleMode = vbPixels
          Call MoveWindow(mWnd , 0, 0, _
          Me.ScaleWidth, _
          Me.ScaleHeight, 1)
          ' Put the focus on notepad
          Putfocus mWnd
          End If

          ' Unlock window update
          LockWindowUpdat e False
          End Sub


          Private Sub Command2_Click( )
          Call SendMessage(mWn d, WM_CLOSE, 0, ByVal 0&)
          'Call SendMessage(mWn d, WM_SYSCOMMAND, SC_CLOSE, ByVal 0&)

          End Sub

          Private Sub Form_Load()
          Command1.Captio n = "Start Notepad"
          Command2.Captio n = "Close Notepad"
          End Sub



          Comment

          • Eddie B

            #6
            Re: System tray problem using a custom shell instead of windows explorer


            I think that will do it! Thanks man, I really appreciate it!

            On Sun, 1 Aug 2004 09:09:53 +0000 (UTC), erewhon@nowhere .com (J
            French) wrote:
            [color=blue]
            >Option Explicit
            >
            >' J French - 27th Nov 2003 / 1st Aug 2004
            >' Shell and Re-Parent
            >' hacked from MS and KPD
            >' Add Two Command Buttons
            >
            >Private Declare Function MoveWindow _
            > Lib "user32" _
            > (ByVal hwnd As Long, _
            > ByVal x As Long, _
            > ByVal y As Long, _
            > ByVal nWidth As Long, _
            > ByVal nHeight As Long, _
            > ByVal bRepaint As Long) As Long
            >
            >Private Declare Function FindWindow _
            > Lib "user32" _
            > Alias "FindWindow A" _
            > (ByVal lpClassName As Long, _
            > ByVal lpWindowName As Long) As Long
            >
            >Private Declare Function GetWindow _
            > Lib "user32.dll " _
            > (ByVal hwnd As Long, _
            > ByVal wCmd As Long) As Long
            >
            >Private Declare Function GetParent _
            > Lib "user32" (ByVal hwnd As Long) As Long
            >
            >Private Declare Function SetParent _
            > Lib "user32" _
            > (ByVal hWndChild As Long, _
            > ByVal hWndNewParent As Long) As Long
            >
            >Private Declare Function GetWindowThread ProcessId _
            > Lib "user32" _
            > (ByVal hwnd As Long, _
            > lpdwProcessId As Long) As Long
            >
            >Private Declare Function LockWindowUpdat e _
            > Lib "user32" _
            > (ByVal hwndLock As Long) As Long
            >
            >Private Declare Function GetDesktopWindo w _
            > Lib "user32" () As Long
            >
            >Private Declare Function Putfocus _
            > Lib "user32" _
            > Alias "SetFocus" _
            > (ByVal hwnd As Long) As Long
            >
            >Private Declare Function SendMessage _
            > Lib "user32" _
            > Alias "SendMessag eA" _
            > (ByVal hwnd As Long, _
            > ByVal wMsg As Long, _
            > ByVal wParam As Long, _
            > ByVal lParam As Any) As Long
            >
            >Private Declare Function WaitForInputIdl e _
            > Lib "user32.dll " _
            > (ByVal hProcess As Long, _
            > ByVal dwMilliseconds As Long) As Long
            >
            >
            >
            >Private Const STARTF_FORCEONF EEDBACK As Long = &H40
            >
            >Private Const GW_HWNDFIRST As Long = 0
            >Private Const GW_HWNDNEXT = 2
            >'Private Const WM_QUIT As Long = &H12
            >Private Const WM_CLOSE = &H10
            >Private Const WM_SYSCOMMAND As Long = &H112
            >Private Const SC_CLOSE As Long = &HF060&
            >
            >Private Type STARTUPINFO
            > cb As Long
            > lpReserved As String
            > lpDesktop As String
            > lpTitle As String
            > dwX As Long
            > dwY As Long
            > dwXSize As Long
            > dwYSize As Long
            > dwXCountChars As Long
            > dwYCountChars As Long
            > dwFillAttribute As Long
            > dwFlags As Long
            > wShowWindow As Integer
            > cbReserved2 As Integer
            > lpReserved2 As Long
            > hStdInput As Long
            > hStdOutput As Long
            > hStdError As Long
            >End Type
            >
            >Private Type PROCESS_INFORMA TION
            > hProcess As Long
            > hThread As Long
            > dwProcessID As Long
            > dwThreadID As Long
            >End Type
            >
            >
            >Private Declare Function CreateProcessA _
            > Lib "kernel32" _
            > (ByVal lpApplicationNa me As String, _
            > ByVal lpCommandLine As String, _
            > ByVal lpProcessAttrib utes As Long, _
            > ByVal lpThreadAttribu tes As Long, _
            > ByVal bInheritHandles As Long, _
            > ByVal dwCreationFlags As Long, _
            > ByVal lpEnvironment As Long, _
            > ByVal lpCurrentDirect ory As String, _
            > lpStartupInfo As STARTUPINFO, _
            > lpProcessInform ation As PROCESS_INFORMA TION) As Long
            >
            >Private Declare Function WaitForSingleOb ject _
            > Lib "kernel32" _
            > (ByVal hHandle As Long, _
            > ByVal dwMilliseconds As Long) As Long
            >
            >Private Declare Function CloseHandle Lib "kernel32" _
            > (ByVal hObject As Long) As Long
            >
            >Private Const NORMAL_PRIORITY _CLASS = &H20&
            >
            >
            >Dim mWnd As Long
            >
            >Function InstanceToWnd(B yVal target_pid As Long) As Long
            > Dim test_hwnd As Long, _
            > test_pid As Long, _
            > test_thread_id As Long
            >
            > 'Find the first window top level window
            > test_hwnd = FindWindow(ByVa l 0&, ByVal 0&)
            > test_hwnd = GetWindow(test_ hwnd, GW_HWNDFIRST)
            >
            > Do While test_hwnd <> 0
            > 'Check if the window isn't a child (??)
            > If GetParent(test_ hwnd) = 0 Then
            > 'Get the window's thread
            > test_thread_id = GetWindowThread ProcessId(test_ hwnd, _
            > test_pid)
            > If test_pid = target_pid Then
            > InstanceToWnd = test_hwnd
            > Exit Do
            > End If
            > End If
            > 'retrieve the next window
            > test_hwnd = GetWindow(test_ hwnd, GW_HWNDNEXT)
            > Loop
            >End Function
            >
            >Public Function ExecCmd(cmdline $) As Long
            > Dim proc As PROCESS_INFORMA TION
            > Dim start As STARTUPINFO
            > Dim Ret&
            >
            > ' Initialize the STARTUPINFO structure:
            > start.cb = Len(start)
            > start.dwFlags = STARTF_FORCEONF EEDBACK
            >
            > ' Start the shelled application:
            > Ret& = CreateProcessA( vbNullString, cmdline$, _
            > 0&, 0&, 1&, _
            > NORMAL_PRIORITY _CLASS, _
            > 0&, vbNullString, _
            > start, proc)
            > ' --- let it start - this seems important
            > Call WaitForInputIdl e(proc.hProcess , 500)
            > ' we should check the result of this
            >
            > If Ret Then
            > ExecCmd = InstanceToWnd(p roc.dwProcessID )
            > Me.Print Ret, ExecCmd
            > Call CloseHandle(pro c.hThread)
            > Call CloseHandle(pro c.hProcess)
            > End If
            >
            >End Function[/color]

            Comment

            • J French

              #7
              Re: System tray problem using a custom shell instead of windows explorer

              On Sun, 01 Aug 2004 14:56:36 -0400, Eddie B <> wrote:
              [color=blue]
              >
              >I think that will do it! Thanks man, I really appreciate it![/color]

              You are welcome

              You might find that you need to wait a bit longer to find the main
              PCAnyWhere Window, some Apps put up a top level window while loading,
              then kill it

              You can also use WaitForSingleOb ject to see whether a process has
              terminated
              - you might find that useful

              Comment

              • Eddie B

                #8
                Re: System tray problem using a custom shell instead of windows explorer

                OK, I have a twist, and another problem. The guy I am doing this for
                lives in Louisianna, I live in Georgia. I sent him the updated
                program, and he said it didn't work. I have come to find out that he
                is running PC Anywhere as a service that starts with Windows and
                minimizes to the system tray - he forgot to tell me this :( I was
                under the impression that the user started PC Anywhere.

                The shell I made has a task bar, similar to windows task bar. When
                you click the Start button (the only button on the task bar), the
                shell gets a list of running applications (using the GetWindow API)
                to display a list to the user (using the GetWindowText API). This
                way, if they had started a program, and minimized it, their program
                will show up in this list. PC Anywhere is not showing up in the list
                - it is running as a service.

                Any suggestions on how to restore the window on a service that is not
                started by my shell?


                On Mon, 2 Aug 2004 08:29:51 +0000 (UTC), erewhon@nowhere .com (J
                French) wrote:
                [color=blue]
                >On Sun, 01 Aug 2004 14:56:36 -0400, Eddie B <> wrote:
                >[color=green]
                >>
                >>I think that will do it! Thanks man, I really appreciate it![/color]
                >
                >You are welcome
                >
                >You might find that you need to wait a bit longer to find the main
                >PCAnyWhere Window, some Apps put up a top level window while loading,
                >then kill it
                >
                >You can also use WaitForSingleOb ject to see whether a process has
                >terminated
                >- you might find that useful[/color]

                Comment

                • J French

                  #9
                  Re: System tray problem using a custom shell instead of windows explorer

                  On Mon, 02 Aug 2004 19:20:47 -0400, Eddie B <> wrote:
                  [color=blue]
                  >OK, I have a twist, and another problem. The guy I am doing this for
                  >lives in Louisianna, I live in Georgia. I sent him the updated
                  >program, and he said it didn't work. I have come to find out that he
                  >is running PC Anywhere as a service that starts with Windows and
                  >minimizes to the system tray - he forgot to tell me this :( I was
                  >under the impression that the user started PC Anywhere.
                  >
                  >The shell I made has a task bar, similar to windows task bar. When
                  >you click the Start button (the only button on the task bar), the
                  >shell gets a list of running applications (using the GetWindow API)
                  >to display a list to the user (using the GetWindowText API). This
                  >way, if they had started a program, and minimized it, their program
                  >will show up in this list. PC Anywhere is not showing up in the list
                  >- it is running as a service.
                  >
                  >Any suggestions on how to restore the window on a service that is not
                  >started by my shell?[/color]

                  I think the easiest way is to side step the problem

                  Start PCAnyWhere yourself, perhaps transparently

                  Out of curiousity, what OS is he using

                  I've had very little experience with services, but my understanding is
                  that the user communicates with them via a 'real' App that then uses
                  SendMessage or TCP/IP to talk to the 'hidden' Service


                  Comment

                  • Eddie B

                    #10
                    Re: System tray problem using a custom shell instead of windows explorer

                    He is unning under 98, 2000, and xp. If I find a way to restore the
                    service's window, I'll let you know. Thanks for all the help!

                    On Tue, 3 Aug 2004 06:26:49 +0000 (UTC), erewhon@nowhere .com (J
                    French) wrote:
                    [color=blue]
                    >On Mon, 02 Aug 2004 19:20:47 -0400, Eddie B <> wrote:
                    >[color=green]
                    >>OK, I have a twist, and another problem. The guy I am doing this for
                    >>lives in Louisianna, I live in Georgia. I sent him the updated
                    >>program, and he said it didn't work. I have come to find out that he
                    >>is running PC Anywhere as a service that starts with Windows and
                    >>minimizes to the system tray - he forgot to tell me this :( I was
                    >>under the impression that the user started PC Anywhere.
                    >>
                    >>The shell I made has a task bar, similar to windows task bar. When
                    >>you click the Start button (the only button on the task bar), the
                    >>shell gets a list of running applications (using the GetWindow API)
                    >>to display a list to the user (using the GetWindowText API). This
                    >>way, if they had started a program, and minimized it, their program
                    >>will show up in this list. PC Anywhere is not showing up in the list
                    >>- it is running as a service.
                    >>
                    >>Any suggestions on how to restore the window on a service that is not
                    >>started by my shell?[/color]
                    >
                    >I think the easiest way is to side step the problem
                    >
                    >Start PCAnyWhere yourself, perhaps transparently
                    >
                    >Out of curiousity, what OS is he using
                    >
                    >I've had very little experience with services, but my understanding is
                    >that the user communicates with them via a 'real' App that then uses
                    >SendMessage or TCP/IP to talk to the 'hidden' Service
                    >[/color]

                    Comment

                    Working...