-1

I try to code my first auto send key to a process which is already running.

I have a problem with list of processes: If 2 target open at same time which mean they have same MainWindowTitle then my app only sends to active windows.

Is there anyway for me to send key to that 2 target? Also the number I use in my code not working, only F1 to F12 are working.

http://pastie.org/9703763#58-59,103-112

mega.co.nz/#!O1Yx1YyR!XtDHsEHbqrj3_EzdIpC8xD0jeo_vkbmIoCnkVQbQiO0

This is my project

Filburt
  • 17,626
  • 12
  • 64
  • 115

1 Answers1

0

You should paste the relevant code into stackoverflow itself rather than referring to some external site.

That being said, your code is structured as follows:

  1. You make a list of all window titles:

        cb_procecss.Items.Clear();
        foreach (System.Diagnostics.Process p in System.Diagnostics.Process.GetProcesses())
        {
            if (p.MainWindowTitle!= "")
                cb_procecss.Items.Add(p.MainWindowTitle);
        }
    
  2. The user selects from the list, and you try to post a message to a window with that title:

        Send(key, cb_procecss.Text.ToString().Trim());
    
  3. You get confused trying to figure out which window was selected, having not remembered the process information:

    public void Send(int Key, string _FindWindow)
    {
        IntPtr Handle = FindWindow(null, _FindWindow);
        PostMessage(Handle, WM_KEYDOWN, Key, 0);
    }
    

An alternative strategy would be to remember the process itself, then later use its MainWindowHandle property directly, for instance in some lightweight class:

    public class ProcessWindowWrapper : IDisposable
    {
        Process process;

        public ProcessWindowWrapper(Process process)
        {
            this.process = process;
        }

        public Process Process { get { return process; } }

        public IntPtr MainWindowHandle
        {
            get
            {
                try
                {
                    return (process == null ? IntPtr.Zero : process.MainWindowHandle);
                }
                catch (InvalidOperationException)
                {
                    // Process exited
                    return IntPtr.Zero;
                }
            }
        }

        public override string ToString()
        {
            return (process == null ? string.Empty : process.MainWindowTitle);
        }

        #region IDisposable Members

        public void Dispose()
        {
            // Dispose of unmanaged resources.
            Dispose(true);
            // Suppress finalization.  Since this class actually has no finalizer, this does nothing.
            GC.SuppressFinalize(this);
        }

        void Dispose(bool disposing)
        {
            if (disposing)
            {
                var process = Interlocked.Exchange(ref this.process, null);
                if (process != null)
                    process.Dispose();
            }
        }

        #endregion
    }

Put this in the list instead of the main window title string, and your bookkeeping problems should be solved. By overriding ToString() you ensure the correct title is shown in the list.

Note that you eventually should dispose of your Process class instances, so this class should implement IDisposable, which I have done.

Community
  • 1
  • 1
dbc
  • 104,963
  • 20
  • 228
  • 340