views:

86

answers:

1

how to change the window style of a form outside your app?hard question?
i am actually trying to move a form witch is topmost and has no border.
i have the handle(hWnd) of the window.
i can write thousands of lines of code if guaranteed to work.

+1  A: 

Assuming that this window could be from any app produced from any kind of Win32-based runtime, it looks like you'll have to resort to p/invoke of the core Win32 apis for window operations.

For example, you could use SetWindowPos, which can be imported from user32.dll. It's signature is this:

BOOL SetWindowPos(HWND hWnd, 
  HWND hWndInsertAfter,
  int X,
  int Y,
  int cx,
  int cy,
  UINT uFlags
);

I'm not going to assume that you've done a p/invoke import before, so let's go from the top. Let's just bash out a windows forms app:

1) Create a windows forms app and then add these declarations to the Form1 class:

/* hWndInsertAfter constants.  Lifted from WinUser.h, 
 * lines 4189 onwards depending on Platform SDK version */
public static IntPtr HWND_TOP = (IntPtr)0;
public static IntPtr HWND_BOTTOM = (IntPtr)1;
public static IntPtr HWND_TOPMOST = (IntPtr)(-1);
public static IntPtr HWND_NOTOPMOST = (IntPtr)(-2);

/* uFlags constants.  Lifted again from WinUser.h, 
 * lines 4168 onwards depending on Platform SDK version */
/* these can be |'d together to combine behaviours */
public const int SWP_NOSIZE          = 0x0001;
public const int SWP_NOMOVE          = 0x0002;
public const int SWP_NOZORDER        = 0x0004;
public const int SWP_NOREDRAW        = 0x0008;
public const int SWP_NOACTIVATE      = 0x0010;
public const int SWP_FRAMECHANGED    = 0x0020;
public const int SWP_SHOWWINDOW      = 0x0040;
public const int SWP_HIDEWINDOW      = 0x0080;
public const int SWP_NOCOPYBITS      = 0x0100;
public const int SWP_NOOWNERZORDER   = 0x0200;  /* Don't do owner Z ordering */
public const int SWP_NOSENDCHANGING  = 0x0400;  /* Don't send WM_WINDOWPOSCHANGING */
public const int SWP_DRAWFRAME       = SWP_FRAMECHANGED;
public const int SWP_NOREPOSITION    = SWP_NOOWNERZORDER;
public const int SWP_DEFERERASE      = 0x2000;
public const int SWP_ASYNCWINDOWPOS  = 0x4000;

[DllImport("user32.dll", CharSet = CharSet.Auto)]
public static extern int SetWindowsPos(IntPtr hWnd,
  IntPtr hWndInsertAfter,
  int x,
  int y,
  int cx,
  int cy,
  UInt32 uFlags);

The annoying thing with p/invoke of Win32 windows methods is that you then have to start importing various numeric constants etc that Win32 uses - hence all the gumph beforehand.

Refer to the MSDN link for the SetWindowPos method for an explanation of what they do.

2) Add a button to the form called cmdMakeHidden and then write the handler as follows:

private void cmdMakeHidden_Click(object sender, EventArgs e)
{
  //also causes the icon in the start bar to disappear
  //SWP_HIDEWINDOW is the 'kill -9' of the windows world without actually killing!
  SetWindowPos(this.Handle, HWND_TOP, 0, 0, 0, 0, SWP_NOSIZE | SWP_NOMOVE | SWP_HIDEWINDOW);
}

Replace the 'this.Handle' with the window handle of your choice to hide that window.

This method is actually used to apply multiple changes at once, hence the need to use some of the SWP_NO* options. For example, you should specify SWP_NOSIZE otherwise passing 0 for cx and cy will cause the window to shrink to zero width and height at the same time.

To demonstrate moving a window, add another button your form called cmdMove and then write the click handler as follows:

private void cmdMove_Click(object sender, EventArgs e)
{
  SetWindowPos(this.Handle, HWND_TOP, 100, 100, 0, 0, SWP_NOSIZE | SWP_NOZORDER | SWP_NOREPOSITION);
}

This code moves your form to 100,100 whenever you hit the button.

Again, replace the this.Handle as you see fit. HWND_TOP here is completely optional, since reordering has been disabled with the SWP_NOZORDER and SWP_NOREPOSITION flags.

Hope this helps get you on the right track!

Andras Zoltan
It should be noted that you can this same method then to modify the actual window style of a window by using other Win32 methods. The SetWindowLong method (http://msdn.microsoft.com/en-us/library/ms633591(VS.85).aspx) is used to modify one or more window styles. Frequently you have to call SetWindowPos after modifying the style, largely if your style change causes a change in the window's frame it would appear.It's going to be ugly - but it will work!
Andras Zoltan
SetWindowsPos ==>SetWindowPos.thanks a lot.
Behrooz