在本课的这一部分中,我将捕获工作进程的所有窗口:
private static bool EnumWindowsCallback(IntPtr hWnd, IntPtr lParam)
{
bool specialCapturing = false;
if (hWnd == IntPtr.Zero) return false;
if (!IsWindowVisible(hWnd)) return true;
if (!countMinimizedWindows)
{
if (IsIconic(hWnd)) return true;
}
else if (IsIconic(hWnd) && useSpecialCapturing) specialCapturing = true;
if (GetWindowText(hWnd) == PROGRAMMANAGER) return true;
if (GetWindowText(hWnd).Contains("Test"))
windowSnaps.Add(new WindowSnap(hWnd, specialCapturing));
return true;
}
/// <summary>
/// Get the collection of WindowSnap instances fro all available windows
/// </summary>
/// <param name="minimized">Capture a window even it's Minimized</param>
/// <param name="specialCapturring">use special capturing method to capture minmized windows</param>
/// <returns>return collections of WindowSnap instances</returns>
public static WindowSnapCollection GetAllWindows(bool minimized, bool specialCapturring)
{
windowSnaps = new WindowSnapCollection();
countMinimizedWindows = minimized;//set minimized flag capture
useSpecialCapturing = specialCapturring;//set specialcapturing flag
EnumWindowsCallbackHandler callback = new EnumWindowsCallbackHandler(EnumWindowsCallback);
EnumWindows(callback, IntPtr.Zero);
return new WindowSnapCollection(windowSnaps.ToArray(), true);
}
最后,我在windowSnap中有两个示例,两个窗口的应用程序名称分别为Test。
在Form1中:
private void buttonSnap_Click(object sender, EventArgs e)
{
this.listBoxSnap.Items.Clear();
this.pictureBoxSnap.Image = null;
this.listBoxSnap.Items.AddRange
(
WindowSnap.GetAllWindows(this.checkBoxMinimized.Checked, this.checkBoxSpecialMode.Checked).ToArray()
);
}
现在在listBox(listBoxSnap)中,当我选择一个项目(例如,索引0中的项目)时,我想这样做是自动将击键发送给此应用程序的。例如,将击键ctrl + s发送到此特定的应用程序窗口,但不将应用程序窗口置于最前面或将其聚焦。
更新我的尝试:
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Runtime.InteropServices;
using System.Text;
using System.Windows.Forms;
namespace MinimizeCapture
{
public partial class Form1 : Form
{
[DllImport("user32.dll")]
static extern int SendMessage(IntPtr hWnd, int msg, int wParam, int lParam);
[DllImport("user32.dll")]
static extern bool SetForegroundWindow(IntPtr hWnd);
// windows messages
const int WM_KEYDOWN = 0x100;
const int WM_KEYUP = 0x101;
// "Ctrl key" virtual key-code
const int VK_CONTROL = 0x11;
public Form1()
{
InitializeComponent();
}
private void buttonSnap_Click(object sender, EventArgs e)
{
this.listBoxSnap.Items.Clear();
this.pictureBoxSnap.Image = null;
this.listBoxSnap.Items.AddRange
(
WindowSnap.GetAllWindows(this.checkBoxMinimized.Checked, this.checkBoxSpecialMode.Checked).ToArray()
);
}
private void listBoxSnap_SelectedIndexChanged(object sender, EventArgs e)
{
WindowSnap snap = this.listBoxSnap.SelectedItem as WindowSnap;
this.pictureBoxSnap.Image = snap.Image;
SetForegroundWindow(snap.Handle);
// hWnd is a handle of a window which should receive Ctrl+S
SendMessage(snap.Handle, WM_KEYDOWN, VK_CONTROL, 0);
SendMessage(snap.Handle, WM_KEYDOWN, (int)'s', 0);
SendMessage(snap.Handle, WM_KEYUP, (int)'s', 0);
SendMessage(snap.Handle, WM_KEYUP, VK_CONTROL, 0);
}
该行:
SetForegroundWindow(snap.Handle);
将选定的窗口置于最前面,但ctrl +似乎根本不会影响该窗口。
答案 0 :(得分:0)
据我从您的评论中可以看到,您需要向另一个窗口发送Ctrl+S
击键。如果是这样,则需要将SendMessage WinAPI与WM_KEYDOWN和WM_KEYUP消息一起使用。
我假设您已经知道如何获取窗口句柄,因此请检查以下代码:
[DllImport("user32.dll")]
static extern int SendMessage(IntPtr hWnd, int msg, int wParam, int lParam);
// windows messages
const int WM_KEYDOWN = 0x100;
const int WM_KEYUP = 0x101;
// "Ctrl key" virtual key-code
const int VK_CONTROL = 0x11;
// hWnd is a handle of a window which should receive Ctrl+S
SendMessage(hWnd, WM_KEYDOWN, VK_CONTROL, 0);
SendMessage(hWnd, WM_KEYDOWN, (int)'s', 0);
SendMessage(hWnd, WM_KEYUP, (int)'s', 0);
SendMessage(hWnd, WM_KEYUP, VK_CONTROL, 0);
请注意:应该收到此消息的窗口必须突出显示!