Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

GetWindowLong / SetWindowLong vs overriding CreateParams?

Tags:

c#

winforms

Previously when I wanted to create a click-through form, I was tempted to use platform invokes to set the extended window styles (GetWindowLong / SetWindowLong in user32.dll).

Just now I wanted to make it invisible to Alt+Tab window list, and I've found an example overriding CreateParams to set the extended window style instead of using GetWindowLong / SetWindowong.

Now I have this:

protected override CreateParams CreateParams
{
    get
    {
        CreateParams cp = base.CreateParams;
        cp.ExStyle |= 0x80000 /* WS_EX_LAYERED */ | 0x20 /* WS_EX_TRANSPARENT */ | 0x80/* WS_EX_TOOLWINDOW */;
        return cp;
    }
}

Now the apparent changes is not needing any platform invoke.

So my few questions:

  1. Will there be any functional differences on Windows? (Just to say I don't even have an XP machine to try now.)
  2. Now I don't have the platform invoke, will my program run on Mono on Linux/Mac? (If I could try now I wouldn't be asking you here.)
  3. Control.CreateParams appears on msdn and has an example of manipulating window styles. Then why some online "examples" and answers on StackOverflow tell people to use GetWindowLong / SetWindowLong?
like image 937
Alvin Wong Avatar asked Dec 21 '12 08:12

Alvin Wong


1 Answers

Will there be any functional differences on Windows?

Yes, very much so. Overriding CreateParams ensures that the style flags have the desired value when the window is created with the CreateWindowEx() call. Pinvoking SetWindowLong() does it late, it requires the window to be created first since you need the Handle property. Using it with GWL_STYLE and GWL_EXSTYLE is risky, older Windows versions were cranky about that. So much so that Winforms does not do this, it actually recreates the window so it can pass new style flags to CreateWindowEx(). Note the RecreateHandle() method, it is used when a property is changed that is a style flag under the hood. Winforms did have the burden to also have to support Windows 98.

will my program run on Mono on Linux/Mac?

Not sure, you actually do have to try. But clearly you have a good "maybe", you have zero odds when you'd rely on pinvoke.

on StackOverflow tell people to use GetWindowLong / SetWindowLong?

Inertia, I think. SetWindowsLong() has been around for over 25 years, CreateParams is 10 years old and still is pretty obscure.

Pre-empting the next question: no, I've never seen a comprehensive list of what style flags can be change safely for which predefined window class at what exact time in the window life cycle by each Windows version. Pretty sure such a list doesn't exist, or could be trusted, trial and error is required. Do note that a call to SetWindowsPos() with SWP_FRAMECHANGED may be required to make the style changes effective.

like image 146
Hans Passant Avatar answered Sep 18 '22 11:09

Hans Passant