question

JoSRM-1861 avatar image
0 Votes"
JoSRM-1861 asked SimpleSamples edited

SendKeys to Putty, MobaXterm etc... Without Hardcoding FindWindow(null, "Command Prompt");

C#
Visual Studio 2017
WINFORM

I hope you all are well!

I am developing an application that will send the contents of the Clipboard (string) to any terminal (Putty, MobaXterm, etc...). I found a partial solution. It works well if you hard code the windows you want to receive the text. e.g. I hard coded for the Command Prompt windows, and it works.

  IntPtr wordHandle = FindWindow(null, "Command Prompt");

What I am trying to figure out is how to do this without hard coding which windows gets the text because I do not know what app the user might use. Is there a way to get the last active windows because if I click on the button on the form the other windows loses its focus.

Credit to sending-key-strokes-to-another-application

Code used:

136438-code-used.jpg




Any suggestions is appreciated.
Sincerely and regards,

dotnet-csharp
code-used.jpg (73.4 KiB)
5 |1600 characters needed characters left characters exceeded

Up to 10 attachments (including images) can be used with a maximum of 3.0 MiB each and 30.0 MiB total.

SimpleSamples avatar image
1 Vote"
SimpleSamples answered SimpleSamples edited

It is not clear what you are asking; you are saying many things and I am not sure if any of the extra stuff is part of the question.

Try the following to get the last active window.

 IntPtr lastWindowHandle = GetWindow(Process.GetCurrentProcess().MainWindowHandle, (uint)GetWindow_Cmd.GW_HWNDNEXT);
 IntPtr hWndParent = GetParent(lastWindowHandle);
 while (!hWndParent.Equals(IntPtr.Zero))
 {
     lastWindowHandle = hWndParent;
     hWndParent = GetParent(lastWindowHandle);
 }


Then after the loop lastWindowHandle will have the handle of the top-level window of the last active application. You will also need the following.

 [DllImport("user32.dll", SetLastError = true)]
 static extern IntPtr GetWindow(IntPtr hWnd, uint uCmd);
 enum GetWindow_Cmd : uint
 {
     GW_HWNDFIRST = 0,
     GW_HWNDLAST = 1,
     GW_HWNDNEXT = 2,
     GW_HWNDPREV = 3,
     GW_OWNER = 4,
     GW_CHILD = 5,
     GW_ENABLEDPOPUP = 6
 }
 [DllImport("user32.dll", ExactSpelling = true, CharSet = CharSet.Auto)]
 public static extern IntPtr GetParent(IntPtr hWnd);


5 |1600 characters needed characters left characters exceeded

Up to 10 attachments (including images) can be used with a maximum of 3.0 MiB each and 30.0 MiB total.

TimonYang-MSFT avatar image
0 Votes"
TimonYang-MSFT answered

You can use GetForegroundWindow to get the active window.

 [DllImport("user32.dll", CharSet = CharSet.Auto, SetLastError = true)]
         static extern IntPtr GetForegroundWindow();
    
         [DllImport("user32.dll", CharSet = CharSet.Auto, SetLastError = true)]
         static extern int GetWindowText(IntPtr hWnd, StringBuilder text, int count);
    
         private static string GetCaptionOfActiveWindow()
         {
             var strTitle = string.Empty;
             var handle = GetForegroundWindow();
             // Obtain the length of the text   
             var intLength = 256;
             var stringBuilder = new StringBuilder(intLength);
             if (GetWindowText(handle, stringBuilder, intLength) > 0)
             {
                 strTitle = stringBuilder.ToString();
             }
             return strTitle;
         }

Combining these codes with Timer should meet your needs.

You can also consider using SetWinEventHook to monitor EVENT_SYSTEM_FOREGROUND to detect changes in the foreground window. This is an example. I haven't tested it yet, but it should be fine in theory.

asynchronously GetForegroundWindow via SendMessage or something?


If the response is helpful, please click "Accept Answer" and upvote it.
Note: Please follow the steps in our documentation to enable e-mail notifications if you want to receive the related email notification for this thread.

5 |1600 characters needed characters left characters exceeded

Up to 10 attachments (including images) can be used with a maximum of 3.0 MiB each and 30.0 MiB total.