SetParent() resizing main form - c#

I am using SetParent() to embed my form on an existing window.
It works fine but when I move the existing window, my form gets resized to existing window's size. So for example if my form's size is 300x200 and the windows size is 800x800, once I move(drag) the window, my form gets resized to the window's size(800x800).
Is there a way to avoid that?
This is my code:
[DllImport("user32.dll", SetLastError = true)]
private static extern IntPtr SetParent(IntPtr hWndChild, IntPtr hWndNewParent);
[DllImport("user32.dll")]
public static extern int GetWindowLong(IntPtr hWnd, int nIndex);
[DllImport("user32.dll")]
public static extern int SetWindowLong(IntPtr hWnd, int nIndex, int dwNewLong);
public static int GWL_STYLE = -16;
public static int WS_CHILD = 0x40000000;
//my call of the methods
SetWindowLong(this.Handle, GWL_STYLE, GetWindowLong(this.Handle, GWL_STYLE) | WS_CHILD);
SetParent(this.Handle, GetHandle());

Related

Process frozen when I try to start it hooked to a panel

I need to launch an external .exe application within my windows forms app on a panel. If I start the process, without placing it on the panel, it's fine but if I place it on the panel the program freezes and does nothing.
I tried to google the problem but I did not find anything,can you help me?.
[DllImport("user32.dll")]
static extern IntPtr SetParent(IntPtr hWndChild, IntPtr hWndNewParent);
[DllImport("user32.dll")]
static extern int SetWindowLong(IntPtr hWnd, int nIndex, int dwNewLong);
[DllImport("user32.dll")]
static extern bool MoveWindow(IntPtr Handle, int x, int y, int w, int h, bool repaint);
[DllImport("USER32.DLL")]
public static extern int GetWindowLong(IntPtr hWnd, int nIndex);
private const int GWL_STYLE = (-16);
public static int WS_BORDER = 0x00800000;
public static int WS_CAPTION = WS_BORDER;
[DllImport("user32.dll")]
private static extern bool ShowWindowAsync(IntPtr hWnd, int nCmdShow);
private const int SW_SHOWMAXIMIZED = 3;
string projectDirectory = "C:\\Users\\anten\\OneDrive\\Desktop\\together\\VisualSharp7\\bin\\Debug";
Visual_Sharp7.StartInfo.WorkingDirectory = projectDirectory;
Visual_Sharp7.StartInfo.FileName = "VisualSharp7.exe";
if (Visual_Sharp7.Start())
{
IntPtr ptr = IntPtr.Zero;
while ((ptr = Visual_Sharp7.MainWindowHandle) == IntPtr.Zero) ;
int WS_VISIBLE = GetWindowLong(Visual_Sharp7.MainWindowHandle, GWL_STYLE);
SetWindowLong(Visual_Sharp7.MainWindowHandle, GWL_STYLE, (WS_VISIBLE & ~WS_CAPTION));
SetParent(Visual_Sharp7.MainWindowHandle, panelMain.Handle);
ShowWindow(Visual_Sharp7, SW_SHOWMAXIMIZED);
}

Set transparency to a control in windows form

I am new in programming. I can’t find a way to set transparency to a control. Please help. Something like, Form.transparency or some thing else.
The most simple way to make a form transparent is just to set the Form.Opacity property to a value.
Or, you can try, API calls for doing that,
[DllImport("user32.dll")]
static extern int SetWindowLong(IntPtr hWnd, int nIndex, int dwNewLong);
[DllImport("user32.dll", SetLastError = true)]
static extern int GetWindowLong(IntPtr hWnd, int nIndex);
[DllImport("user32.dll")]
static extern bool SetLayeredWindowAttributes(IntPtr hwnd, uint crKey, byte bAlpha, uint dwFlags);
public const int GWL_EXSTYLE = -20;
public const int WS_EX_LAYERED = 0x80000;
public const int LWA_ALPHA = 0x2;
public const int LWA_COLORKEY = 0x1;
For Calling,
SetWindowLong(Handle, GWL_EXSTYLE, GetWindowLong(Handle, GWL_EXSTYLE) ^ WS_EX_LAYERED);
SetLayeredWindowAttributes(Handle, 0, 128, LWA_ALPHA);

How to bring a form already shown up to the very foreground and focus it?

How to programmatically (assuming we've got a reference to it as a variable) bring a form already shown up to the very foreground and focus it in a C# WinForms application?
You can use SetForegroundWindow. Good example here: C# Force Form Focus.
[DllImport("User32")]
private static extern int SetForegroundWindow(IntPtr hwnd);
Usage:
SetForegroundWindow(form.Handle);
You should use the BringToFront() method
The answers here didn't quite do it for me. Using BringToFront wouldn't actually bring it to the front if the form was not focused and using Form.Activate just makes the form flash if it doesn't have focus. I wrote this little helper and it works flawlessly (I can't take total credit, found this somewhere on the web for WPF and converted it):
public static class FormHelper
{
const UInt32 SWP_NOSIZE = 0x0001;
const UInt32 SWP_NOMOVE = 0x0002;
const UInt32 SWP_SHOWWINDOW = 0x0040;
[DllImport("user32.dll")]
private static extern IntPtr GetForegroundWindow();
[DllImport("user32.dll")]
public static extern bool SetWindowPos(IntPtr hWnd, IntPtr hWndInsertAfter, int X, int Y, int cx, int cy, uint uFlags);
[DllImport("User32")]
private static extern int SetForegroundWindow(IntPtr hwnd);
[DllImport("user32.dll")]
private static extern uint GetWindowThreadProcessId(IntPtr hWnd, IntPtr ProcessId);
[DllImport("user32.dll")]
private static extern bool AttachThreadInput(uint idAttach, uint idAttachTo, bool fAttach);
public static void BringToFront(Form form)
{
var currentForegroundWindow = GetForegroundWindow();
var thisWindowThreadId = GetWindowThreadProcessId(form.Handle, IntPtr.Zero);
var currentForegroundWindowThreadId = GetWindowThreadProcessId(currentForegroundWindow, IntPtr.Zero);
AttachThreadInput(currentForegroundWindowThreadId, thisWindowThreadId, true);
SetWindowPos(form.Handle, new IntPtr(0), 0, 0, 0, 0, SWP_NOSIZE | SWP_NOMOVE | SWP_SHOWWINDOW);
AttachThreadInput(currentForegroundWindowThreadId, thisWindowThreadId, false);
form.Show();
form.Activate();
}
}
All you have to do is call FormHelper.BringToFront passing in the form you want to be shown.
Form.Show();
or
Form.ShowDialog();
What's different? First show new form but all other will be activity. Second solution make that only this new form will be activity.
Have you tried Form.Show() and/or Form.BringToFront() ?

Modify the windows style of another application using winAPI

My application starts up another application. whereby, i want to remove the title bar of the application which is started using c#.
How can i do this, starting up with the piece of code below ?
//Get current style
lCurStyle = GetWindowLong(hwnd, GWL_STYLE)
//remove titlebar elements
lCurStyle = lCurStyle And Not WS_CAPTION
lCurStyle = lCurStyle And Not WS_SYSMENU
lCurStyle = lCurStyle And Not WS_THICKFRAME
lCurStyle = lCurStyle And Not WS_MINIMIZE
lCurStyle = lCurStyle And Not WS_MAXIMIZEBOX
//apply new style
SetWindowLong hwnd, GWL_STYLE, lCurStyle
//reapply a 3d border
lCurStyle = GetWindowLong(hwnd, GWL_EXSTYLE)
SetWindowLong hwnd, GWL_EXSTYLE, lCurStyle Or WS_EX_DLGMODALFRAME
//redraw
SetWindowPos hwnd, 0, 0, 0, 0, 0, SWP_NOMOVE Or SWP_NOSIZE Or SWP_FRAMECHANGED
#region Constants
//Finds a window by class name
[DllImport("USER32.DLL")]
public static extern IntPtr FindWindow(string lpClassName, string lpWindowName);
//Sets a window to be a child window of another window
[DllImport("USER32.DLL")]
public static extern IntPtr SetParent(IntPtr hWndChild, IntPtr hWndNewParent);
//Sets window attributes
[DllImport("USER32.DLL")]
public static extern int SetWindowLong(IntPtr hWnd, int nIndex, int dwNewLong);
//Gets window attributes
[DllImport("USER32.DLL")]
public static extern int GetWindowLong(IntPtr hWnd, int nIndex);
[DllImport("user32.dll", EntryPoint = "FindWindow", SetLastError = true)]
static extern IntPtr FindWindowByCaption(IntPtr ZeroOnly, string lpWindowName);
[DllImport("user32.dll")]
static extern IntPtr GetMenu(IntPtr hWnd);
[DllImport("user32.dll")]
static extern int GetMenuItemCount(IntPtr hMenu);
[DllImport("user32.dll")]
static extern bool DrawMenuBar(IntPtr hWnd);
[DllImport("user32.dll")]
static extern bool RemoveMenu(IntPtr hMenu, uint uPosition, uint uFlags);
//assorted constants needed
public static uint MF_BYPOSITION = 0x400;
public static uint MF_REMOVE = 0x1000;
public static int GWL_STYLE = -16;
public static int WS_CHILD = 0x40000000; //child window
public static int WS_BORDER = 0x00800000; //window with border
public static int WS_DLGFRAME = 0x00400000; //window with double border but no title
public static int WS_CAPTION = WS_BORDER | WS_DLGFRAME; //window with a title bar
public static int WS_SYSMENU = 0x00080000; //window menu
#endregion
public static void WindowsReStyle()
{
Process[] Procs = Process.GetProcesses();
foreach (Process proc in Procs)
{
if (proc.ProcessName.StartsWith("notepad"))
{
IntPtr pFoundWindow = proc.MainWindowHandle;
int style = GetWindowLong(pFoundWindow, GWL_STYLE);
//get menu
IntPtr HMENU = GetMenu(proc.MainWindowHandle);
//get item count
int count = GetMenuItemCount(HMENU);
//loop & remove
for (int i = 0; i < count; i++)
RemoveMenu(HMENU, 0, (MF_BYPOSITION | MF_REMOVE));
//force a redraw
DrawMenuBar(proc.MainWindowHandle);
SetWindowLong(pFoundWindow, GWL_STYLE, (style & ~WS_SYSMENU));
SetWindowLong(pFoundWindow, GWL_STYLE, (style & ~WS_CAPTION));
}
}
}

Using Window Handle to disable Mouse clicks and Keyboard Inputs using P/Invoke

I need to disable the Mouse Clicks, Mouse movement and Keyboard Inputs for a specific windows for a Kiosk application. Is it feasible using .NET ?
I have removed the menu bar and title bar of a specific window, will that be a starting point to achieve the above requirement ?
The code for removing the menu bar and title bar using window handle :
#region Constants
//Finds a window by class name
[DllImport("USER32.DLL")]
public static extern IntPtr FindWindow(string lpClassName, string lpWindowName);
//Sets a window to be a child window of another window
[DllImport("USER32.DLL")]
public static extern IntPtr SetParent(IntPtr hWndChild, IntPtr hWndNewParent);
//Sets window attributes
[DllImport("USER32.DLL")]
public static extern int SetWindowLong(IntPtr hWnd, int nIndex, int dwNewLong);
//Gets window attributes
[DllImport("USER32.DLL")]
public static extern int GetWindowLong(IntPtr hWnd, int nIndex);
[DllImport("user32.dll", EntryPoint = "FindWindow", SetLastError = true)]
static extern IntPtr FindWindowByCaption(IntPtr ZeroOnly, string lpWindowName);
[DllImport("user32.dll")]
static extern IntPtr GetMenu(IntPtr hWnd);
[DllImport("user32.dll")]
static extern int GetMenuItemCount(IntPtr hMenu);
[DllImport("user32.dll")]
static extern bool DrawMenuBar(IntPtr hWnd);
[DllImport("user32.dll")]
static extern bool RemoveMenu(IntPtr hMenu, uint uPosition, uint uFlags);
//assorted constants needed
public static uint MF_BYPOSITION = 0x400;
public static uint MF_REMOVE = 0x1000;
public static int GWL_STYLE = -16;
public static int WS_CHILD = 0x40000000; //child window
public static int WS_BORDER = 0x00800000; //window with border
public static int WS_DLGFRAME = 0x00400000; //window with double border but no title
public static int WS_CAPTION = WS_BORDER | WS_DLGFRAME; //window with a title bar
public static int WS_SYSMENU = 0x00080000; //window menu
#endregion
public static void WindowsReStyle()
{
Process[] Procs = Process.GetProcesses();
foreach (Process proc in Procs)
{
if (proc.ProcessName.StartsWith("notepad"))
{
IntPtr pFoundWindow = proc.MainWindowHandle;
int style = GetWindowLong(pFoundWindow, GWL_STYLE);
//get menu
IntPtr HMENU = GetMenu(proc.MainWindowHandle);
//get item count
int count = GetMenuItemCount(HMENU);
//loop & remove
for (int i = 0; i < count; i++)
RemoveMenu(HMENU, 0, (MF_BYPOSITION | MF_REMOVE));
//force a redraw
DrawMenuBar(proc.MainWindowHandle);
SetWindowLong(pFoundWindow, GWL_STYLE, (style & ~WS_SYSMENU));
SetWindowLong(pFoundWindow, GWL_STYLE, (style & ~WS_CAPTION));
}
}
}
Use the EnableWindow API call to do this. I haven't used this in many years but I don't believe there are any cross process issues with this.

Categories