Resizing Custom / Transparent Windows (Again!)
August 23rd, 2008 | View Comments
In my previous post, I described how you can resize transparent windows by using the ResizeGrip control. That approach, while simple, has several problems. The ResizeGrip only allows resizing diagonally (NW-SE). Styling your ResizeGrip, while not impossible, isn’t the easiest of tasks. Finally, it breaks consistency. A resizable window should be resizable on all corners and sides.
In this post, let’s look at my preferred way for resizing your transparent window by going below WPF and working with the low-level window messages responsible for resizing directly. The following is a screenshot of my transparent window application that allows you to resize on all four sides and corners:
You can download the Visual Studio 2008 / Expression Blend 2 source files by clicking on the below link:
| Download Resizing Transparent Window Source |
Once you have downloaded and extracted the files, open Window1.xaml.cs in Visual Studio. The main lines to look at are the following:
- private const int WM_SYSCOMMAND = 0×112;
- private HwndSource hwndSource;
- public Window1()
- {
- this.InitializeComponent();
- // Insert code required on object creation below this point.
- this.SourceInitialized += new EventHandler(InitializeWindowSource);
- }
- private void InitializeWindowSource(object sender, EventArgs e)
- {
- hwndSource = PresentationSource.FromVisual((Visual)sender) as HwndSource;
- }
- public enum ResizeDirection
- {
- Left = 1,
- Right = 2,
- Top = 3,
- TopLeft = 4,
- TopRight = 5,
- Bottom = 6,
- BottomLeft = 7,
- BottomRight = 8,
- }
- [DllImport("user32.dll", CharSet = CharSet.Auto)]
- private static extern IntPtr SendMessage(IntPtr hWnd, uint Msg, IntPtr wParam, IntPtr lParam);
- private void ResizeWindow(ResizeDirection direction)
- {
- SendMessage(hwndSource.Handle, WM_SYSCOMMAND, (IntPtr) (61440 + direction), IntPtr.Zero);
- }
Before describing the code, let me give you a bird’s eye view of what is going on. Everything you do to a window such as hovering over it, clicking it, resizing it, moving it around, etc. generates many messages. These messages are in the form of numbers that, internally, map to a particular action. By sending your own actions, you have the ability to control what your window does…such as resizing your window even though no resize handles seem to be visible. If you’ve never done classic Windows API programming, this is probably bizarre to you – especially in the context of a WPF app!
The reason I can do this is because WPF windows do not replace the old Win32/GDI windows that Windows has had for many years. Instead, WPF layers itself above the Win32 window and provides you with a nice wrapper where most of the scary details are hidden from your view. What you type in C# might be something neat such as "this.Width = 300". What actually happens behind the scenes is a series of window messages are sent translating what you want into the language your native window understands.
Because WPF already translates window-related changes to low-level messages, you may be wondering why I can’t just adjust the Top, Left, Width, and Height properties for each window to do the resizing. The reason is that while Width and Height can be adjusted easily, there are some issues in WPF in how it handles Top and Left alterations. If you were to try it, you will find that your window unnecessarily flickers and jumps. Hopefully this will be addressed in the future, so in the meantime, that brings us to passing in low-level Windows messages.
hWnd, P/Invoke, and Other Stuff
In the Windows API, central to passing around messages is your hWnd. hWnd stands for the window handle, and you can think of it as your main window that you listen and send messages to. You can retrieve it easily in WPF by accessing it via the SourceInitialized event handler:
- private const int WM_SYSCOMMAND = 0×112;
- private HwndSource hwndSource;
- public Window1()
- {
- this.InitializeComponent();
- // Insert code required on object creation below this point.
- this.SourceInitialized += new EventHandler(InitializeWindowSource);
- }
- private void InitializeWindowSource(object sender, EventArgs e)
- {
- hwndSource = PresentationSource.FromVisual((Visual)sender) as HwndSource;
- }
Once you have the hWnd from your WPF window, you are almost set to pass messages to it. What you need is a dash of P/Invoke which I talked about a while ago. P/Invoke is a way for you to communicate with Win32, and for this example, I need a way to communicate with Win32′s SendMessage function. To invoke SendMessage, the following lines of code are used:
- [DllImport("user32.dll", CharSet = CharSet.Auto)]
- private static extern IntPtr SendMessage(IntPtr hWnd, uint Msg, IntPtr wParam, IntPtr lParam);
- private void ResizeWindow(ResizeDirection direction)
- {
- SendMessage(hwndSource.Handle, WM_SYSCOMMAND, (IntPtr) (61440 + direction), IntPtr.Zero);
- }
The first two lines define my P/Invoke signature for SendMessage that resides in user32.dll. The ResizeWindow method contains my actual call to SendMessage, and notice that I am passing in my hWnd, a system command command, a message indicating resize, and a zero value. Of these arguments, the most important one is the third argument where I tell my window the direction my resize will be: "61440 + direction". The eight values that correspond to the ResizeDirection are:
- public enum ResizeDirection
- {
- Left = 1,
- Right = 2,
- Top = 3,
- TopLeft = 4,
- TopRight = 5,
- Bottom = 6,
- BottomLeft = 7,
- BottomRight = 8,
- }
If your window receives a 61442, it means a Right-resize needs to happen. If a 61448 is received, your window knows to handle it as a bottom-right resize. Your window takes care of everything else such as the mouse drag functionality, etc. If you look at the rest of the code, almost all of it is there for the sole purpose of displaying the appropriate mouse cursor! That’s all there is to it.
Going Forward
In my next post, I will explain how I was able to figure this out. While this may look complicated, it really isn’t. It is just a matter of observing which window messages correspond to which particular action and just sending those messages yourself.
Cheers!
Kirupa





August 28th, 2008 at 7:39 am
should work and in WinForms, right?
August 28th, 2008 at 2:00 pm
found another solution.
on mousedown
isresize = true
on mouse move
UIElementObj.CaptureMouse();
to get events of mousemove even after its left the UIElementObj
on mouse up
UIElementObj.ReleaseMouseCapture()
isresize = false
August 28th, 2008 at 8:47 pm
Cornel – yes it should work in WinForms as well, though I can’t guarantee that the syntax will be the same.
Leblanc – I’ll try that. In the past, when I captured the mouse in WPF, that tended to override the mouse capture needed for the resize.
August 29th, 2008 at 6:39 pm
[...] my previous post, I described how to resize your window by sending resize messages directly to the native window [...]
September 27th, 2008 at 7:26 pm
Thanks for the great post! This came in very handy. The only problem I have is that resizing a window from the left/top can cause some flashy artifacts because the window isn’t rendering fast enough (at least on mine), but hey at least it works.
September 27th, 2008 at 7:50 pm
chai – I noticed that when resizing custom/transparent windowed applications like Outlook 2007 also for example.
I wonder if this has something to do with how Windows handles (or doesn’t handle) resizing of custom windows.
December 15th, 2008 at 10:18 pm
you really impressed me , great great work
you helped me a lot thank you
Keep going wonderful man
May 7th, 2009 at 3:05 pm
Thanks Kirupa!
I’m trying to seperate the extra window logic into it’s own class called ResizableWindow since I would like to reuse the code across many windows in my App. How would I go about doing so?
May 8th, 2009 at 9:40 am
One bug I have found though. Only the top left corner mouse cursor correctly display the proper arrow while dragging. The other three corners change after leaving the initial area which the respective corner grip was at.
June 14th, 2009 at 5:48 pm
Great post. Thank you very much
October 22nd, 2009 at 5:40 pm
Thunderbird 3: I love Firefox but it loads pages slowly. ,
March 11th, 2010 at 11:57 am
Really nice but for some reason i can’t get this to work…
I’m using VB.NET and WPF. When i click&drag on one of the rectangles i go down to the SendMessage call, but then nothing happens.
SendMessage(hwndSource.Handle, WM_SYSCOMMAND, New IntPtr(61440 + direction), IntPtr.Zero)
The handle contains the handle of the window, WM_SYSCOMMAND contains 112, direction contains the direction as set in the enum(1 for left, 2 for right,…)…
My import of the SendMessage also seems good :
_
Private Shared Function SendMessage(ByVal hWnd As IntPtr, ByVal Msg As UInteger, ByVal wParam As IntPtr, ByVal lParam As IntPtr) As IntPtr
End Function
Any idea on what could cause the problem?
Thanks
Wo
March 11th, 2010 at 12:00 pm
Sorry, the dllimport part in the declaration of SendMessage didnt display in my last comment but its there in the code :
DllImport(“user32.dll”, SetLastError:=True, CharSet:=CharSet.Auto)
March 11th, 2010 at 12:13 pm
Never mind my question…. in WM_SYSCOMMAND I used 112 as integer but in your code it is in hex. So i switched it for 274(decimal) and all is working perfectly.
Thanks for the really good post.
April 16th, 2010 at 11:20 am
This is awesome, thanks for posting it. This post saved me a ton of time.
July 14th, 2010 at 4:35 pm
There’re good news:
July 20th, 2010 at 10:03 am
this is just GREAT!
July 24th, 2010 at 2:09 pm
Thanks for posting this code. For some reason had to change
WM_SYSCOMMAND = 0×112
to
WM_SYSCOMMAND = 0×0112
Works beautifully :^)
September 12th, 2010 at 10:59 am
[...] the Titlebar control, as well as the Resize Grips, the implementation of Resize Grips is based on Kirupa’s code, which uses some [...]
November 6th, 2010 at 8:17 am
Intimately, the post is in reality the best on this noteworthy topic. I fit in with your conclusions and will eagerly look forward to your forthcoming updates. Saying thanks will not just be enough, for the exceptional clarity in your writing. I will at once grab your rss feed to stay privy of any updates. Good work and much success in your business endeavors!
November 8th, 2010 at 8:23 am
Hi Kirupa!
Thank you for all your tutorials, always very precise and so helpful!
In 2008 you wrote that there is no other way to resize a WPF custom window.
Is it still true? I found some other examples which don’t work as well as yours, but kind of work.
What would you advice?
Thank you very much
Antoine from Switzerland
February 9th, 2011 at 12:33 pm
Absolutely brilliant, and it was easy to refactor the resizing logic into its own class to avoid having to rewrite again and again.
Thanks very much!
February 24th, 2011 at 9:09 am
[...] have to P/Invoke your way to victory. Kirupa Chinnathambi provides an excellent example of how to accomplish borderless window resizing which I took and refactored into some reusable classes that are hopefully fairly simple to [...]
March 8th, 2011 at 10:25 am
I used to be wondering what is up with that weird gravatar??? I know 5am is early and I am not wanting my best at that hour, however I hope I don’t look like this! I might nonetheless make that face if I’m requested to do a hundred pushups. lol Anyway, i
March 9th, 2011 at 3:09 am
I was wondering should you can be fascinated about changing into a guest poster on my weblog? and in trade you could possibly put a link the submit? Please let me know once you get a chance and I will send you my contact particulars – thanks. Anyway, in my language, there should not a lot good source like this.
March 9th, 2011 at 4:42 am
I was wondering what’s up with that bizarre gravatar??? I know 5am is early and I am not looking my best at that hour, but I hope I do not appear to be this! I’d however make that face if I am asked to do a hundred pushups. lol Anyway, in my language, there will not be much good source like this.
March 31st, 2011 at 5:48 pm
I appeared to be very pleased to search out this web-site.I want to appreciate it for your time for the wonderful read!! I certainly enjoying every little bit of this and I’ve you saved to look at new thing you blog post.
May 3rd, 2011 at 6:47 am
Howdy, i read text links your blog often and that i own a similar one and i was just wondering if you happen to get a number of spam feedback? If that’s the case how do text links you stop it, any plugin or something you can advise?text links I get so much lately it is driving me mad so any assistance could be very text links a lot appreciated. Anyway, in my language, text links there should not a lot good source like this.
May 20th, 2011 at 1:52 pm
Thank you!!!
You saved me a world of headaches.
June 28th, 2011 at 4:54 pm
liquid ecstasy energy drink herbal highs australia most powerful legal hallucinogenic shrooms cost in charlotte buy spice in cartersville buying marijuana in arizona spice diamond shop potent legal drug order hawaiian baby woodrose europe changa dmt smoke aphrodisiac like ecstasy pill buy ecstasy in netherlands buy ecstasy in utah smoking herbal meth jwh bayou blaster smileys herbal high best herbal incense to smoke dmaa legal in australia buy salvia leaves los angeles legal highs limerick list of mdma alternatives party pill mind candy legal recreational drugs us psychoactive seeds sale hawaiian baby woodrose liquid extract
July 6th, 2011 at 12:34 pm
I love that you place superlative content out that is articulate and good-written.
July 17th, 2011 at 10:00 am
What about windows 7 integration? Will it work like Zune client, when moving window to the edge of a screen? Does it support “undocking” of maximized window?
July 30th, 2011 at 12:14 pm
Looks like a good method. Silly question tho, what are the lines that set the coloured borders and how do I make the rectangles transparent?
August 10th, 2011 at 9:56 am
grt
September 29th, 2011 at 8:59 am
[...] currently no built-in methods in VS to accomplish this task. However, a suitable solution has been posted online. This code must be repeated for every window. I decided to develop the necessary piece of codes [...]
November 10th, 2011 at 5:18 pm
Can I simply say what a relief to find someone who truly knows what they’re talking about on the internet.
November 15th, 2011 at 2:24 am
Can you please tell us how we can make our window float..i.e. it should stick on the screen even if we navigate to some other window..even if team viewer is on..the window should appear floating