SetParent not Working InvalidOperationException - c#

I recently tried to work on an old project I had an i am not able to get the setparent to work it keeps giving me the "InvalidOperationException" error, here is the code:
private void button1_Click(object sender, EventArgs e)
{
Process proc = Process.Start("calc.exe");
proc.WaitForInputIdle();
Thread.Sleep(500);
SetParent(proc.MainWindowHandle, this.Handle);
}
Its being called with a button and when it tries to set the parent it errors out. Everything i can find online say that my code is right.

This code below is working fine on my side (Please check the declaration of your Windows API function SetParent):
[DllImport("user32.dll", SetLastError = true)]
private static extern IntPtr SetParent(IntPtr hWndChild, IntPtr hWndNewParent);
private void button1_Click(object sender, EventArgs e)
{
Process proc = Process.Start("calc.exe");
proc.WaitForInputIdle();
Thread.Sleep(500);
SetParent(proc.MainWindowHandle, this.Handle);
}
Result:
Hope that helps :)

Related

Control one form that is opened multiple times

Let's say I have the same form opened multiple times but I want to control just one of them (one that f.e has "hello" as window title (text) <- to identify)
How do I manage to do that?
EDIT:
Here is an example of what I want to do (it's a bit complicated, im not good at explaining what I want)
private void openthesecformfirst_Click(object sender, EventArgs e)
{
Form2 sec = new Form2();
sec.Text = "Hi";
sec.Show();
//The second form is now opened
}
private void openthesecformsecond_Click(object sender, EventArgs e)
{
Form2 sec = new Form2();
sec.Text = "Hello";
sec.Show();
//the second form is now opened twice
}
private void changelabelinfirst_Click(object sender, EventArgs e)
{
//Identified by the title the first opened form2 is supposed to change a label text
//How do I get this one specifically?
}
private void changelabelinsecond_Click(object sender, EventArgs e)
{
//Identified by the title the second opened form2 is supposed to change a label text
//How do I get this one specifically?
}
For find window in OS Windows you can use FindWindowEx from the Win32 Api, for example:
Because this is original unsafe code you should import functions from user32.dll:
[DllImport("user32.dll", SetLastError = true)] static extern IntPtr
FindWindowEx(IntPtr hwndParent, IntPtr hwndChildAfter,
string lpszClass, string lpszWindow);
[DllImport("user32.dll", SetLastError = true)]
public static extern IntPtr FindWindowEx(IntPtr parentHandle, IntPtr
childAfter,
string className, string windowTitle);
After import you can use function like that:
var CaptionTextForLooking = "hello"; // or "Hi"
var foundWindowPtr =
FindWindowEx(IntPtr.Zero,IntPtr.Zero,CaptionTextForLooking
,IntPtr.Zero);
More you can find here
You can use the Application.OpenForms property.

Input the text from the text box in other program textbox

I need to take a text from textbox1 and putt it in other program text box .
How can I do that and with what?
so far i saw SendKey but that is sending the specify text and my text will change and will not send text to specify text box of another application
i finded something like this but I don't see where to putt secify application
using System;
using System.Runtime.InteropServices;
using System.Windows.Forms;
namespace WindowsFormsApplication1
{
public partial class Form1 : Form
{
const uint WM_SETTEXT = 0x000C;
[DllImport("user32.dll", CharSet = CharSet.Auto)]
static extern IntPtr SendMessage(IntPtr hWnd, unit Msg,
IntPtr wParam, string lParam);
public Form1()
{
InitializeComponent();
}
private void textBox1_TextChanged(object sender, EventArgs e)
{
MessageBox.Show(textBox1.Text);
}
private void button1_Click(object sender, EventArgs e)
{
SendMessage(textBox1.Handle, WM_SETTEXT, IntPtr.Zero,
textBox1.Text + ", " + textBox1.Text);
}
}
}
You need to implement interprocess communication, Please check this link What is the simplest method of inter-process communication between 2 C# processes
In this link you can find multiple options to implement interprocess communication such as:
Windows Communication Foundation
Windows Messages

Showing starting text of Mulitline TextBox when focus is changed

I am creating a form which has a Multiline TextBox to enter an URL. Expected URLs will be very long.
User will paste the URL and move to next box.
Right now, TextBox shows ending part of the URL when user moves to next TextBox. I want such that it will show starting of URL (Domain name) instead of trailing part.
Current:
Expected:
And this should happen when user leaves the TextBox.
I tried various methods of Selection in textBox_Leave() event but I guess, these methods won't work if focus is lost.
I am using .Net framework 3.5.
Update: Textbox I am using is Multiline. Answers suggested by #S.Akbari and #Szer are perfect if the Mutliline property is set to False. I realized it late that Multiline will play such a significant role. Hence updating the question!
Use SelectionStart in the Leave event should works:
private void textBox1_Leave(object sender, EventArgs e)
{
textBox1.SelectionStart = 0;
}
Before:
After leaving TextBox:
Tried it and it works. Proof
public Form1()
{
InitializeComponent();
textBox1.LostFocus += TextBox1_LostFocus;
}
private void TextBox1_LostFocus(object sender, EventArgs e)
{
textBox1.SelectionStart = 0;
textBox1.SelectionLength = 0;
}
I can see how it doesn't work with the Multiline property set to true.
A simple API call can make this work:
[DllImport("user32.dll", CharSet = CharSet.Auto)]
private static extern int SendMessage(IntPtr hWnd, int wMsg, IntPtr wParam, IntPtr lParam);
private const int WM_VSCROLL = 0x115;
private const int SB_TOP = 6;
void textBox1_Leave(object sender, EventArgs e) {
SendMessage(textBox1.Handle, WM_VSCROLL, (IntPtr)SB_TOP, IntPtr.Zero);
}

Windows forms - catch pressed key in main form

I have this:
[DllImport("user32.dll")]
static extern IntPtr SetParent(IntPtr hWndChild, IntPtr hWndNewParent);
private void Form1_Load(object sender, EventArgs e)
{
ProcessStartInfo info = new ProcessStartInfo();
info.FileName = "notepad";
info.UseShellExecute = true;
var process = Process.Start(info);
Thread.Sleep(2000);
SetParent(process.MainWindowHandle, this.Handle);
}
private void Form1_KeyPress(object sender, KeyPressEventArgs e)
{
MessageBox.Show("asd");
}
Now, whenever I press a key while Form1 has focus, it detects it just fine. But when I start typing text in notepad - Form1 doesn't see the keys I press. How can I make that Form1 can catch the keys I press?
What you need is a keylogger kind of software. It works even if the form is not focused. Check this link out. It should be able to help you.
http://null-byte.wonderhowto.com/how-to/create-simple-hidden-console-keylogger-c-sharp-0132757/

Winform and WPF form/window border

I have been dealing with this issue and i dont know how to proceed.
I have a project with both windows forms and WPF forms.
I want every form to be displayed like this (its a WPF one):
WPF = http://imageshack.us/photo/my-images/545/wpfk.png/
I achieved this windows style = none and canresize = yes. I dont actually want it to be resized. I just want that thin border arround the form. But if i put canresize = false i lose the border. I also want to be able to move the window in the screen, not to be static in that place.
I need all that for my winforms too.
Winforms:
WINFORM = http://imageshack.us/photo/my-images/836/winforms.png/
I hope you guys understand what i need. Graphically, it has to be like the first image.
I'm not sure if it helps, but you can create Forms collection for this. (a)
http://support.microsoft.com/kb/815707/en-us
Solution: Paste this code into your form or base form.
private const int WS_SYSMENU = 0x80000;
protected override CreateParams CreateParams
{
get
{
CreateParams cp = base.CreateParams;
cp.Style &= ~WS_SYSMENU;
return cp;
}
}
Thanks Killercam for the help!
Solution for WPF Window:
public MainWindow()
{
SourceInitialized += Window_SourceInitialized;
InitializeComponent();
}
private void button2_Click(object sender, RoutedEventArgs e)
{
this.Close();
}
private void button3_Click(object sender, RoutedEventArgs e)
{
this.WindowState = WindowState.Minimized;
}
private void Window_SourceInitialized(object sender, EventArgs e)
{
WindowInteropHelper wih = new WindowInteropHelper(this);
int style = GetWindowLong(wih.Handle, GWL_STYLE);
SetWindowLong(wih.Handle, GWL_STYLE, style & ~WS_SYSMENU);
}
private const int GWL_STYLE = -16;
private const int WS_SYSMENU = 0x00080000;
[DllImport("user32.dll")]
private extern static int SetWindowLong(IntPtr hwnd, int index, int value);
[DllImport("user32.dll")]
private extern static int GetWindowLong(IntPtr hwnd, int index);
You just need to set the WinForms FormBorderStyle property in the designer to Sizable, FixedDialog, Fixed3D etc. One of these is bound to give you the behaviour you require.

Categories