C# // SendKeys.SendWait works only when process'es window is minimzed - c#

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Collections;
using System.ComponentModel;
using System.Data;
using System.Runtime.InteropServices;
using System.Diagnostics;
using System.Threading;
using System.Windows.Forms;
using System.Drawing;
namespace TextSendKeys
{
class Program
{
[DllImport("user32.dll")]
static extern bool ShowWindow(IntPtr hWnd, int nCmdShow);
static void Main(string[] args)
{
Process[] processes = Process.GetProcessesByName("game");
Process game1 = processes[0];
IntPtr p = game1.MainWindowHandle;
ShowWindow(p,1);
SendKeys.SendWait("{DOWN}");
Thread.Sleep(1000);
SendKeys.SendWait("{DOWN}");
}
}
}
That program is suposed to send twice DOWN button in a game window. It only works, when my window is minimized (it's activating the window and doing it's job). If my window is activated (not minimized), nothin happens. How to solve that?
Thanks! :)

Try using the SetForegroundWindow Win32 API call, instead of ShowWindow, to activate the game window. (Signature from pinvoke.net.)
[DllImport("user32.dll")]
[return: MarshalAs(UnmanagedType.Bool)]
static extern bool SetForegroundWindow(IntPtr hWnd);
static void Main(string[] args)
{
Process[] processes = Process.GetProcessesByName("game");
Process game1 = processes[0];
IntPtr p = game1.MainWindowHandle;
SetForegroundWindow(p);
SendKeys.SendWait("{DOWN}");
Thread.Sleep(1000);
SendKeys.SendWait("{DOWN}");
}

Related

How do I set the background of a Windows form to be the same as the user's Desktop wallpaper?

I need to set the background of a Windows form to the user's current Desktop wallpaper. How do I do this in C#?
Thanks
You can try the following code. I've tested this code on windows 8 and it works for me:
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.IO;
using System.Linq;
using System.Runtime.InteropServices;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
namespace StringFormatting
{
public partial class WallpaperTest : Form
{
private const UInt32 SPI_GETDESKWALLPAPER = 0x73;
private const int MAX_PATH = 260;
[DllImport("user32.dll", CharSet = CharSet.Auto)]
public static extern int SystemParametersInfo(UInt32 uAction, int uParam, string lpvParam, int fuWinIni);
public WallpaperTest()
{
InitializeComponent();
this.BackgroundImage = GetCurrentDesktopWallpaper();
this.BackgroundImageLayout = ImageLayout.Stretch;
}
public Image GetCurrentDesktopWallpaper()
{
string currentWallpaper = new string('\0', MAX_PATH);
SystemParametersInfo(SPI_GETDESKWALLPAPER, currentWallpaper.Length, currentWallpaper, 0);
string imageAddress = currentWallpaper.Substring(0, currentWallpaper.IndexOf('\0'));
return Image.FromFile(imageAddress);
}
}
}

C# FindWindow can't find game (Settlers 4)

i'm writing a small "autosave" program for settlers 4.
The program should send "CTRL + S" every X seconds to make a quick-save ingame.
When i try the code below with notepad, everything works fine. But when i try it with the game (Settlers 4) it always opens the message box and tells me, that it can't find the game (game is running of course).
The game runs in fullscreen and doesn't need administrator rights, if that is important.
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.IO;
using System.Threading;
using System.Runtime.InteropServices;
using System.Diagnostics;
using System.Windows.Forms;
namespace Siedler4Autosave2
{
public partial class Form1 : Form
{
[DllImport("user32.dll", EntryPoint = "FindWindow")]
private static extern IntPtr FindWindow(string lp1, string lp2);
[DllImport("user32.dll", ExactSpelling = true, CharSet = CharSet.Auto)]
[return: MarshalAs(UnmanagedType.Bool)]
private static extern bool SetForegroundWindow(IntPtr hWnd);
public Form1()
{
InitializeComponent();
}
private void timer1_Tick(object sender, EventArgs e)
{
// Find Settlers 4
IntPtr handle = FindWindow("S4_Main", "Die Siedler IV");
if (!handle.Equals(IntPtr.Zero))
{
if (SetForegroundWindow(handle))
{
// send "CTRL + S"
SendKeys.Send("^(s)");
}
}
else
{
// Settlers 4 not found
MessageBox.Show("Siedler 4 nicht gefunden");
}
}
}
}

I am having trouble overlaying graphics on another window

Program.cs:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace Test {
class Program {
static void Main(string[] args) {
for (int i = 0; i < 1000000000; i++) {
WindowHandler.testOverlay();
}
}
}
}
WindowHandler.cs:
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Drawing;
using System.Linq;
using System.Runtime.InteropServices;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
namespace Test {
static class WindowHandler {
private const String WINDOW_TITLE = "Minesweeper";
private static IntPtr windowHandle = IntPtr.Zero;
public static void testOverlay() {
if (windowHandle == IntPtr.Zero) {
windowHandle = getWindowHandle();
}
Graphics g = Graphics.FromHwnd(windowHandle);
g.FillRectangle(new SolidBrush(Color.White), 0, 0, 10000, 10000);
}
private static IntPtr getWindowHandle() {
foreach (Process proc in Process.GetProcesses()) {
if (proc.MainWindowTitle == WINDOW_TITLE) {
return proc.MainWindowHandle;
}
}
MessageBox.Show("Error: Unable to find window.");
return IntPtr.Zero;
}
}
}
I am not sure what I am doing wrong. I am writing a Minesweeper Solver and I am trying to overlay graphics on the Minesweeper window to provide debugging information. Unfortunately, it doesn't seem to work at all as I do not see any change on my screen. I am looping 1000000000 times in Program.cs just in case it erases my overlay on every frame refresh. I prefer to not try to hook DirectX.

How to use [DllImport("")] in C#?

I found a lot of questions about it, but no one explains how I can use this.
I have this:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Runtime.InteropServices;
using System.Windows.Forms;
using Microsoft.FSharp.Linq.RuntimeHelpers;
using System.Diagnostics;
using System.Runtime.InteropServices;
using System.IO;
public class WindowHandling
{
public void ActivateTargetApplication(string processName, List<string> barcodesList)
{
[DllImport("User32.dll")]
public static extern int SetForegroundWindow(IntPtr point);
Process p = Process.Start("notepad++.exe");
p.WaitForInputIdle();
IntPtr h = p.MainWindowHandle;
SetForegroundWindow(h);
SendKeys.SendWait("k");
IntPtr processFoundWindow = p.MainWindowHandle;
}
}
Can someone help me to understand why it gives me an error on the DllImport line and on the public static line?
Does anyone have an idea, what can I do?
Thank you.
You can't declare an extern local method inside of a method, or any other method with an attribute. Move your DLL import into the class:
using System.Runtime.InteropServices;
public class WindowHandling
{
[DllImport("User32.dll")]
public static extern int SetForegroundWindow(IntPtr point);
public void ActivateTargetApplication(string processName, List<string> barcodesList)
{
Process p = Process.Start("notepad++.exe");
p.WaitForInputIdle();
IntPtr h = p.MainWindowHandle;
SetForegroundWindow(h);
SendKeys.SendWait("k");
IntPtr processFoundWindow = p.MainWindowHandle;
}
}
Starting with C# 9, your syntax would be valid if you remove the public keyword from the SetForegroundWindow deceleration:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Runtime.InteropServices;
using System.Windows.Forms;
using Microsoft.FSharp.Linq.RuntimeHelpers;
using System.Diagnostics;
using System.Runtime.InteropServices;
using System.IO;
public class WindowHandling
{
public void ActivateTargetApplication(string processName, List<string> barcodesList)
{
[DllImport("User32.dll")]
static extern int SetForegroundWindow(IntPtr point);
Process p = Process.Start("notepad++.exe");
p.WaitForInputIdle();
IntPtr h = p.MainWindowHandle;
SetForegroundWindow(h);
SendKeys.SendWait("k");
IntPtr processFoundWindow = p.MainWindowHandle;
}
}
In C# 9 local functions can have attributes, see here

How do I capture the Screensaver Event?

I'm trying to capture a Screensaver event, however when I run my application it throws the following exception;
Unable to find an entry point named 'SystemParametersinfo' in DLL 'user32.dll'.
this is my code so far, any and all help would be greatly appreciated =D
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using NLog;
using Topshelf;
using OsWatch;
using Microsoft.Win32;
using System.Runtime.InteropServices;
namespace NotifyIcon
{
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
SystemEvents.SessionSwitch += SystemEvents_SessionSwitch;
}
[DllImport("user32.dll", CharSet = CharSet.Auto)]
public static extern int SystemParametersinfo(int uAction, int uParam, ref int ipvParam, int fuWinini);
const int SPI_GETSCREENSAVERRUNNING = 114;
static int screenSaverRunning = -1;
int ok = SystemParametersinfo(SPI_GETSCREENSAVERRUNNING, 0, ref screenSaverRunning, 0);
private void ScreenSaver()
{
if (ok == 0)
{
Logger.Trace("SCREENSAVER OFF");
}
if (screenSaverRunning != 0)
{
Logger.Trace("SCREENSAVER ON");
}
}

Categories

Resources