Open another application's System Menu - c#

I have a WPF TaskBar like application that i am developing for fun and i want to be able to open the System Menu for the application (that is in my custom taskbar) that i right click on, preserving any custom menu that the app might create (i.e. Google Chrome). I have the following code that works for a borderless window app i made previously, but it doesn't seem to work and i am wondering why? And what do i need to do to get it to work?
public static void ShowContextMenu(IntPtr hWnd)
{
SetForegroundWindow(hWnd);
IntPtr wMenu = GetSystemMenu(hWnd, false);
// Display the menu
uint command = TrackPopupMenuEx(wMenu,
TPM.LEFTBUTTON | TPM.RETURNCMD, 0, 0, hWnd, IntPtr.Zero);
if (command == 0)
return;
PostMessage(hWnd, WM.SYSCOMMAND, new IntPtr(command), IntPtr.Zero);
}
Tip: It appears that TrackPopupMenuEx(...) returns immediately with the value of 0, instead of waiting for a response...

It appears there is an issue with giving TrackPopupMenuEx the owner window handle of the Menu... instead i used the handle of my wpf window and then when posting the message, i used the Menu's owner... seems a bit strange to me but it works!
public static void ShowContextMenu(IntPtr hAppWnd, Window taskBar, System.Windows.Point pt)
{
WindowInteropHelper helper = new WindowInteropHelper(taskBar);
IntPtr callingTaskBarWindow = helper.Handle;
IntPtr wMenu = GetSystemMenu(hAppWnd, false);
// Display the menu
uint command = TrackPopupMenuEx(wMenu,
TPM.LEFTBUTTON | TPM.RETURNCMD, (int) pt.X, (int) pt.Y, callingTaskBarWindow, IntPtr.Zero);
if (command == 0)
return;
PostMessage(hAppWnd, WM.SYSCOMMAND, new IntPtr(command), IntPtr.Zero);
}

Related

Find child window by class

I can't get the "Edit" field handle when selecting a photo in a third-party application.
Spy++ shows everything correctly, but FindWindow fails. I can get the handle of the window itself, the parent. I assume I need to look for child windows. I can get some handles with GetWindow but but it's not clear what they are. The window title is empty. FindWindowEx doesn't work at all, returns 0. I indicate it like this:
IntPtr hwndchild = (hwnd, IntPtr.Zero, null, "Edit")
Based on the screenshot you provided, and using just the FindWindow/Ex() functions, you can get the HWND of the Edit control like this:
IntPtr hwndDlg = FindWindow(null, "Choose an image");
IntPtr hwndCBEx = FindWindowEx(hwndDlg, IntPtr.Zero, "ComboBoxEx32", null);
IntPtr hwndCB = FindWindowEx(hwndCBEx, IntPtr.Zero, "ComboBox", null);
IntPtr hwndEdit = FindWindowEx(hwndCB, IntPtr.Zero, "Edit", null);
However, once you have the HWND to the ComboBoxEx control, the correct way to get the HWND of its Edit control is to use the CBEM_GETEDITCONTROL message:
const int CBEM_GETEDITCONTROL = 1031;
IntPtr hwndDlg = FindWindow(null, "Choose an image");
IntPtr hwndCBEx = FindWindowEx(hwndDlg, IntPtr.Zero, "ComboBoxEx32", null);
IntPtr hwndEdit = SendMessage(hwndCBEx, CBEM_GETEDITCONTROL, 0, 0);
Note, for a standard ComboBox control (which you can get from a ComboBoxEx control using the CBEM_GETCOMBOCONTROL message), you can use the CB_GETCOMBOBOXINFO message or the GetComboBoxInfo() function. The HWND of the Edit control is returned in the COMBOBOXINFO.hwndItem field.
If you are looking for a child window of a parent you should use EnumChildWindows. The following is C++ code but could be pinvoked easily: you can marshal delegates as function pointers for the callback.
std::vector<HWND> FindChildrenByClass(HWND parent, const std::string& target_class)
{
struct EnumWndParam {
std::vector<HWND> output;
std::string target;
} enum_param;
enum_param.target = target_class;
EnumChildWindows(
parent,
[](HWND wnd, LPARAM lparam) -> BOOL {
auto param = reinterpret_cast<EnumWndParam*>(lparam);
char class_name[512];
GetClassName(wnd, class_name, 512);
if (param->target == class_name)
param->output.push_back(wnd);
return TRUE;
},
reinterpret_cast<LPARAM>(&enum_param)
);
return enum_param.output;
}
int main()
{
auto windows = FindChildrenByClass( reinterpret_cast<HWND>(0x0061024A), "Edit");
for (auto wnd : windows) {
std::cout << std::hex << wnd << std::endl;
}
}
Note in the above that I do not recursively call FindChildrenByClass in the callback lambda. This is not a mistake. EnumChildWindows already performs this recursion. It runs over a parent window's children and grand children, etc., out of the box without you having to specify this behavior or implement it.
Like someone already assumed. Try the EnumChildWindow method.
Here is an complete sample already on stackoverflow

How to hide a taskbar when AutoHideTaskbar option selected and a script (ahk script) trying to hide taskbar too?

My application is designed to launch in full screen, at any cost taskbar should not be visible to the user. For taskbar hiding below ahk scripts will be running in the background to perform the needed operations.
Regarding AHK scripting please select the below link for its description.
http://ahkscript.org/
The script doesn`t work if "Auto Hide taskbar" functionality of windows 7 is selected.
Hence I have taken the below C# code to solve the issue from the application side.
But in certain conditions like when the application launches for the first time after windows restart, showwindow function is not working properly especially when Auto Hide taskbar option selected.
Sample Code
[DllImport("user32.dll")]
public static extern int FindWindowEx(int parentHandle, int childAfter, string className, int windowTitle);
[DllImport("user32.dll")]
private static extern int GetDesktopWindow();
[DllImport("user32.dll")]
private static extern int ShowWindow(int hwnd, int command);
protected static int Handle
{
get
{
return (int)FindWindow("Shell_TrayWnd", "");
}
}
protected static int HandleOfStartButton
{
get
{
int handleOfDesktop = GetDesktopWindow();
int handleOfStartButton = FindWindowEx(handleOfDesktop, 0, "button", 0);
return handleOfStartButton;
}
}
public static void HideTaskbar()
{
int Taskbar = ShowWindow(Handle, SW_HIDE);
int StartButton = ShowWindow(HandleOfStartButton, SW_HIDE);
}
private void button1_Click(object sender, EventArgs e)
{
HideTaskbar();
}
Script
Below script hides the taskbar and disables the execution of some keys.(right window and left window button and ctrl+esc)
WinHide,ahk_class Shell_TrayWnd
LWin::Suspend
RWin::Suspend
^Esc::Suspend
other options I have tried out
[DllImport("user32.dll")]
public static extern bool SetWindowPos(
int hWnd, // handle to window
int hWndInsertAfter, // placement-order handle
short X, // horizontal position
short Y, // vertical position
short cx, // width
short cy, // height
uint uFlags // window-positioning options
);
private void button1_Click(object sender, EventArgs e)
{
int hwnd = FindWindow("Shell_TrayWnd", "");
SetWindowPos(hwnd, 0, 0, 0, 0, 0, SWP_HIDEWINDOW);
}
Above code alters the functionality. Not working properly.
Please suggest any ways to handle this scenario.
Here's an AutoHotkey solution to check OS Version and change the Hide Taskbar Setting:
If (A_OSVersion = WIN_7) {
; retrieve Registry Value of AutoHide Taskbar
RegRead, OutputVar, HKEY_CURRENT_USER\Software\Microsoft\Windows\CurrentVersion\Explorer\StuckRects2, Settings
; If AutoHide Taskbar is On
If (SubStr(OutputVar, 18, 1) == 3) {
ChangeSetting := RegExReplace(OutputVar, (03), "02",, 1, 16)
;ChangeSetting := StrReplace(OutputVar, "3", "2",,1)
RegWrite, REG_BINARY, HKEY_CURRENT_USER\Software\Microsoft\Windows\CurrentVersion\Explorer\StuckRects2, Settings, % ChangeSetting
; The Code below Automatically applies Registry settings (and on Win 8.1 Explorer.exe is also restarted immediatley
; Alternatively you could use Shutdown Command to Reboot the system but this is much faster...
Process, Close, explorer.exe
}
}
Here's some code if you just want to test it out:
Gui, Add, Button, x1 y1 w110 h30 gButton1, Change AutoHide
Gui, Show,, New GUI Window
Return
Button1:
RegRead, OutputVar, HKEY_CURRENT_USER\Software\Microsoft\Windows\CurrentVersion\Explorer\StuckRects2, Settings
ChangeSetting := ((SubStr(OutputVar, 18, 1) == 3)
? RegExReplace(OutputVar, (03), "02",, 1, 16)
: RegExReplace(OutputVar, (02), "03",, 1, 16))
RegWrite, REG_BINARY, HKEY_CURRENT_USER\Software\Microsoft\Windows\CurrentVersion\Explorer\StuckRects2, Settings, % ChangeSetting
Process, Close, explorer.exe
Return
GuiClose:
ExitApp
People will still be able to access the taskbar by pressing the Windows key on the keyboard or some other shortcut. All you're doing is hacking the computer's registry keys to mess with the user's customized shortcuts.
What you really want to do is create a fullscreen maximized window (similar to what you see when you maximize a youtube video).
Set the properties of your window such that:
1. FormBorderStyle = None,
2. On form load, get screen rects and resize your window to be of that size.

StartInfo.WindowStyle = ProcessWindowStyle.Hidden is still not working

ProcessStartInfo proc = new ProcessStartInfo();
proc.FileName = #"C:\\Windows\\System32\\RunDll32.exe";
proc.Arguments = "shell32.dll,Control_RunDLL inetcpl.cpl,Internet,4";//open Internet Properties window
proc.WindowStyle = ProcessWindowStyle.Hidden;
proc.UseShellExecute = false;
proc.CreateNoWindow = true;
Process.Start(proc);
SendKeys.Send("{TAB}{TAB}{TAB}{TAB}{ENTER}");// Open Lan Setting window
I've tried many way to hide/ close "Internet Properties window" and Lan Setting Window after it's called, but this code doesn't work.
Help me !
I think you should find another way to play with your proxy problem, but if you still want to use the trick which plays with showing and closing dialogs, I have a solution here which would help (I've tested) and you don't have to use SendKeys which I feel very unstable. Here is my code:
//You have to add these using first:
//using System.Runtime.InteropServices;
//using System.Threading;
//This is used to find a window
[DllImport("user32", CharSet=CharSet.Auto)]
private static extern IntPtr FindWindow(string className, string windowName);
//This is used to find Button in a window
[DllImport("user32")]
private static extern IntPtr FindWindowEx(IntPtr parent, IntPtr childAfter, string className, string windowName);
//This is to help you Click on a Button
[DllImport("user32")]
private static extern int SendMessage(IntPtr hwnd, int msg, IntPtr wParam, IntPtr lParam);
//---------------------------
//Here are our methods
//---------------------------
//This is used to Get handle of a Button of a Parent window by its Text
private IntPtr GetButton(IntPtr parent, string text)
{
return FindWindowEx(parent, IntPtr.Zero, "Button", text);
}
//This is used to Click on a Window (usually a Button) with its Handle passed in
private void ClickWindow(IntPtr hwnd)
{
SendMessage(hwnd, 0x201, IntPtr.Zero, IntPtr.Zero);
SendMessage(hwnd, 0x202, IntPtr.Zero, IntPtr.Zero);
}
//This is used to find the Local Area Network (LAN) Settings window
//This is called in a separate thread, because somehow the LAN settings window
//showing causes the main Form not-responding (we can't call anything in our main thread).
private void SearchForLanSettingsWindow()
{
int i = 0;
while (true)
{
Thread.Sleep(100);
IntPtr windowHandle = FindWindow(null,"Local Area Network (LAN) Settings");
if (windowHandle != IntPtr.Zero)
{
//Find the button OK, if you like, you can replace it with "Cancel",...
IntPtr button = GetButton(windowHandle, "OK");
//Click on that OK button to Close your Lan settings window
//You may want to research on the DestroyWindow or CloseWindow
//win32 api without having to click on a Button, but I think this should be better. It's up to you.
ClickWindow(button);
break;
}
i++;
if (i > 20)//timeout
{
break;
}
}
}
//And here is your code with my code appended
System.Diagnostics.ProcessStartInfo proc = new System.Diagnostics.ProcessStartInfo();
proc.FileName = #"C:\\Windows\\System32\\RunDll32.exe";
proc.Arguments = "shell32.dll,Control_RunDLL inetcpl.cpl,Internet,4";//open Internet Properties window
proc.UseShellExecute = false;
System.Diagnostics.Process.Start(proc);
Thread.Sleep(100);//Sleep to be sure the Window is really created
//Get the handle to the window "Internet Properties"
IntPtr mainHandle = FindWindow(null, "Internet Properties");
//Find the tab "Connections", this tab has class "#32770" and is a child window of the window "Internet Properties"
IntPtr child = FindWindowEx(mainHandle, IntPtr.Zero, "#32770", "Connections");
//Get the button "LAN settings"
IntPtr button = GetButton(child, "&LAN settings");
//Create new thread and start it to find the Lan settings window
//we have to do this now because for some reason, after the LAN settings window shows
//we can't call any code in our class.
new Thread(SearchForLanSettingsWindow).Start();
//Click on the LAN settings button to Show the LAN settings window
ClickWindow(button);
//Get the button OK on the window "Internet Properties"
button = GetButton(mainHandle, "OK");
//Click on that button to close the window "Internet Properties"
ClickWindow(button);
And that's all.
I've found that if the computer is installed with a non-English language, the Buttons OK, LAN settings may be different. So the better solution is to use GetDlgItem() to get the buttons from their IDs. To do so, you have to import the function GetDlgItem() first:
[DllImport("user32")]
private static extern IntPtr GetDlgItem(IntPtr dlgHandle, int itemID);
I used Spy++ to know what the control ids of OK and LAN settings are. The control ID of OK is 1 and the control ID of LAN settings is 0x62C. So to get the handles of those buttons you can use this code:
IntPtr button = GetDlgItem(parent, 1);//OK button
button = GetDlgItem(parent, 0x62C);//LAN settings, remember that the dialog containing LAN settings button is Connections not the Internet Properties.
Here is another solution using Process.Kill(), I'm not sure if killing the RunDll32.exe will be OK, but if it's OK this will be another solution which is even cleaner:
//You have to add these using first:
//using System.Runtime.InteropServices;
//using System.Diagnostics;
//using System.Threading;
//This is used to find a window
[DllImport("user32", CharSet=CharSet.Auto)]
private static extern IntPtr FindWindow(string className, string windowName);
[DllImport("user32")]
private static extern IntPtr FindWindowEx(IntPtr parent, IntPtr childAfter, string className, string windowName);
//This is to help you Click on a Button
[DllImport("user32")]
private static extern int SendMessage(IntPtr hwnd, int msg, IntPtr wParam, IntPtr lParam);
//This is used to get a Button (as an item) on a dialog
[DllImport("user32")]
private static extern IntPtr GetDlgItem(IntPtr dlgHandle, int itemID);
//---------------------------
//Here are our methods
//---------------------------
//This is used to Click on a Window (usually a Button) with its Handle passed in
private void ClickWindow(IntPtr hwnd)
{
SendMessage(hwnd, 0x201, IntPtr.Zero, IntPtr.Zero);
SendMessage(hwnd, 0x202, IntPtr.Zero, IntPtr.Zero);
}
//This is used to find the Local Area Network (LAN) Settings window
//This is called in a separate thread, because somehow the LAN settings window
//showing causes the main Form not-responding (we can't call anything in our main thread).
private void SearchForLanSettingsWindow()
{
int i = 0;
while (i < 20)
{
Thread.Sleep(100);
IntPtr windowHandle = FindWindow(null,"Local Area Network (LAN) Settings");
if (windowHandle != IntPtr.Zero)
{
if(runDll32 != null) runDll32.Kill();
break;
}
i++;
}
}
//the Process RunDll32
Process runDll32;
//And here is your code with my code appended
ProcessStartInfo proc = new ProcessStartInfo();
proc.FileName = #"C:\\Windows\\System32\\RunDll32.exe";
proc.Arguments = "shell32.dll,Control_RunDLL inetcpl.cpl,Internet,4";//open Internet Properties window
proc.UseShellExecute = false;
runDll32 = Process.Start(proc);
Thread.Sleep(100);//Sleep to be sure the Window is really created
//Get the handle to the window "Internet Properties"
IntPtr mainHandle = FindWindow(null, "Internet Properties");
//Find the tab "Connections", this tab has class "#32770" and is a child window of the window "Internet Properties"
IntPtr child = FindWindowEx(mainHandle, IntPtr.Zero, "#32770", "Connections");
//Get the button "LAN settings"
IntPtr button = GetDlgItem(child, 0x62C);
//Create new thread and start it to find the Lan settings window
//we have to do this now because for some reason, after the LAN settings window shows
//we can't call any code in our class.
new Thread(SearchForLanSettingsWindow).Start();
//Click on the LAN settings button to Show the LAN settings window
ClickWindow(button);
Again, I think, you should find another solution to do what you want originally. This kind of solution is just a trick. You may want to use MoveWindow win32 function to move all the dialogs out of the screen.
PS: này, em làm (hay vẫn đang học?) trong ngành tin thật à? Ở đâu vậy? How old? nice to meet you on stack over flow :)

C# WinAPI Clicking on menu items

I'm trying to click on a menu item inside a program called Media Subtitler and whatever I'm trying to do it's not working.
First, I tried to use the function GetMenu but it returned IntPtr.Zero.
Then, I tried using the ALT key + using the first letter of my menu (F stands for file) but it did nothing.
Then, I tried using a simple MOUSEDOWN and MOUSEUP messages but again, it did nothing (I also tried creating a loop that clicks on everything in that range but there was no click in that area).
What I clearly know is that I'm working on the correct window.
What am I doing wrong?
If someone wants to test it out you can download Media Subtitler for free and it doesn't weight that much.
Also, Here's the code I've been testing:
Process p = Process.Start(#"C:\Program Files\DivXLand\Media Subtitler\MediaSub.exe");
p.WaitForInputIdle(1500);
Thread.Sleep(3000);
SetForegroundWindow(p.MainWindowHandle);
ShowWindow(p.MainWindowHandle, SW_MAXIMIZE);
IntPtr handle = p.MainWindowHandle;
SendMessage(handle, WM_NCHITTEST, 0, MakeLParam(18, 29));
//for (int i = 0; i < 200; i++)
//{
// for (int x = 0; x < 200; x++)
// {
// SendMessage(p.MainWindowHandle, WM_LBUTTONDOWN, 0, MakeLParam(i, x));
// SendMessage(p.MainWindowHandle, WM_LBUTTONUP, 0, MakeLParam(i, x));
// }
//}
//IntPtr menuItems = GetMenu(p.MainWindowHandle);
return;
//SendMessage(p.MainWindowHandle, WM_COMMAND, 6, 0);
SendMessage(p.MainWindowHandle, WM_KEYDOWN, VK_MENU, 0);
SendMessage(p.MainWindowHandle, WM_KEYUP, VK_MENU, 0);
SendMessage(p.MainWindowHandle, WM_KEYDOWN, VK_F, 0);
SendMessage(p.MainWindowHandle, WM_KEYUP, VK_F, 0);
Thanks for any help!
By monitoring the messages sent to the main window of the application, I extracted the menu identifiers for the menu items. You can post WM_COMMAND message to the window, with the ID of the menu items as the wParam:
[DllImport("user32.dll")]
public static extern IntPtr PostMessage(IntPtr hWnd, Message msg, int wParam, int lParam);
PostMessage(handle, WM_COMMAND, 2, 0); // File->New subtitle
PostMessage(handle, WM_COMMAND, 3, 0); // File->New from clipboard
PostMessage(handle, WM_COMMAND, 5, 0); // File->Open text or subtitle
PostMessage(handle, WM_COMMAND, 6, 0); // File->Open video
...
I've tested the code with Media Subtitler, and it works like a charm! The only situation that this will not work, is when on windows Vista or Seven, your target program is running as Administrator and you C# program is not. Be aware of that!
The menu IDs can be easily examined by monitoring the WM_COMMAND message (using Spy++).
You can also use SendMessage instead of PostMessage, but then your program freezes until the user closes the window opened by the menu action.
You can use the same approach to send other command to other windows of the application. For example, clicking the 'Open' button of the 'Open video' window.
You can also do all of this using the System.Windows.Automation namespace: http://msdn.microsoft.com/en-us/library/ms590934.aspx
Using this namespace, you do not need to do any interop with the Win32 API. Here's an example of how to get a window by searching for a string that its name contains:
public static AutomationElement GetWindowByName(string name)
{
AutomationElement root = AutomationElement.RootElement;
foreach (AutomationElement window in root.FindAll(TreeScope.Children, new PropertyCondition(AutomationElement.ControlTypeProperty, ControlType.Window)))
{
if (window.Current.Name.Contains(name) && window.Current.IsKeyboardFocusable)
{
return window;
}
}
return null;
}
After you have the window as an AutomationElement object, you can search it for controls and perform operations on those controls, etc.
Hope this helps!
In Visual Studio there is a tool Spy++ with which you should be able to see handle of objects.
If you see it there, you should be able to get to it using user32.dll function
[DllImport("user32.dll", SetLastError = true)]
private static extern IntPtr FindWindowEx(IntPtr hwndParent, IntPtr hwndChildAfter, string className, string lpszWindow);
to get to them(handle will be different everytime you run your app)
If you get the right handle, you should be able to use SendMessage to send enter, or click.
Tried this only on one app, and I used it only to read and write text, so sorry if it wont work

Open Tab in IE8 using SendMessage() C#

In this below code, hWnd is the "URL Handle" in Spy++:
'WorkerW -> ReBarWindow32 -> Address Band Root -> Edit'
The URL is what I want to open.
I use the same method to open tabs in IE7 and send hWnd appropriately. I see that this works fine for IE7 and not for IE8. In IE8, it only opens 4 tabs and then IE8 stops honoring the SendMessage request; however, I can still press CTRL+T OR ALT+Enter to open new tabs in IE8 (so IE8 is still responsive).
/**
* Open URL in IE (open new tab when newTab is true)
* hWnd is found at runtime
**/
private void LaunchURLinIE(IntPtr hWnd, String url, bool newTab = false)
{
StringBuilder ob = new StringBuilder(url);
// Type text in the URL window
SendMessage(hWnd, WM_SETTEXT, 0, ob);
if (!newTab)
{ // Press Enter
SendMessage(hWnd, WM_KEYDOWN, VK_RETURN, 1);
}
else
{ // Press ALT Enter to open new tab
SendMessage(hWnd, WM_SYSKEYDOWN, VK_RETURN, 1 << 29);
}
}
My environment is: Windows XP Service Pack 3 [32-bit OS] , IE8 version 8.0.6001.18702
So, is it IE8 or something I am missing?
UPDATE - 1
I have updated comments on the code so that its clear what code does. The above code works perfectly fine for IE7 (tested upto 15 tabs) but with IE8 it only opens upto 4 tabs.
Update - 2
I was able to sove this by using PostMessage instead of SendMessage.
private void LaunchURLinIE(IntPtr hWnd, String url, bool newTab = false)
{
StringBuilder ob = new StringBuilder(url);
// Type text in the URL window
SendMessage(hWnd, WM_SETTEXT, 0, ob);
if (!newTab)
{ // Press Enter
PostMessage(hWnd, WM_KEYDOWN, VK_RETURN, 1);
}
else
{ // Press ALT Enter to open new tab
PostMessage(hWnd, WM_SYSKEYDOWN, VK_RETURN, 1
You might want to try using the COM exposed by the ShDocVw object which can be found as a .dll named Interop.ShDocVw.dll this contains an InternetExplorerClass interface which allows you to do most IE automation reliably.
I am a contributor to SWAT http://sourceforge.net/projects/ulti-swat/, if you would like some good examples feel free to use our source for IE automation located in SWAT.Core/InternetExplorer.cs
There are alot of problems with your code actually, window handles are hardcoded (why?) also you are only sending a key down, the application usually expects a keydown/keyup combo or sometimes a keydown/keypress/keyup sequence in order for it to be valid. Your application makes it seem as if you are holding down the keys you are sending. You may want to use the FindWindow windows API call which can help you find the window handle at runtime for the window you want to send the messages to.
Should you not send WM_KEYUP as well?
VK_RETURN? Not sure what it does. Would it be better to send CTRL+T keystrokes instead?
KEYDOWN CTRL
KEYDOWN T
KEYUP T
KEYUP CTRL
You can find key codes with KeyInterop.VirtualKeyFromKey.
I also think you need to use PostMessage:
[return: MarshalAs(UnmanagedType.Bool)]
[DllImport("user32.dll", SetLastError = true)]
private static extern bool PostMessage(IntPtr hWnd, uint Msg, int wParam, int lParam);
private const UInt32 WM_KEYDOWN = 0x0100;
private const UInt32 WM_KEYUP = 0x0101;
public static void IENewTab(IntPtr HWnd)
{
PostMessage(HWnd, WM_KEYDOWN, KeyInterop.VirtualKeyFromKey(System.Windows.Input.Key.LeftCtrl), 0);
PostMessage(HWnd, WM_KEYDOWN, KeyInterop.VirtualKeyFromKey(System.Windows.Input.Key.T), 0);
PostMessage(HWnd, WM_KEYUP, KeyInterop.VirtualKeyFromKey(System.Windows.Input.Key.T), 0);
PostMessage(HWnd, WM_KEYUP, KeyInterop.VirtualKeyFromKey(System.Windows.Input.Key.LeftCtrl), 0);
}

Categories

Resources