I have a somewhat strange issue in WPF, where I have created a custom window type (comes with a notification icon and custom chrome, mainly). Under normal circumstances it works fine (e.g. resizing using handles etc). However, when trying to make the window automatically size to content, I've ended up with a situation where it can resize smaller without redrawing the windows behind it.
When the window is moved (via DragMove()), it correctly repaints everything behind it, but until it either moves or is hidden, nothing happens.
Can anyone tell me what messages DragMove() is generating that cause the area that was previously hidden by the window client area to invalidate and repaint correctly? I've tried WM_PAINT pointed at my custom window, but either it does nothing (e.g. windows doesn't expect a WM_PAINT message from me) or it only repaints the current client area, not the previous one.
Whilst I was not able to identify why the issue was occurring, and this isn't an answer to the question I posed, I was able to resolve the problem by taking a different approach. Previously, I had been binding on MaxHeight and MinHeight; what eventually worked was using SizeToContent instead (which doesn't suffer from the same inability to render restore background as binding to MaxHeight and MinHeight did in my approach), and then removed the ability to resize my control.
This isn't the answer (if anyone does know how force windows to redraw the area that a window used to occupy, I'd still be interested), but it does solve the problem.
Related
I have a WinForms Application. I need it to run also in Mono.
I have a problem with form repainting. There are many controls in the form. When I resize the form or when I try to update it (it needs to be updated on timer tick), the repainting does not work . Sometimes the controls are placed right, but it flickers, sometimes the the controls do not move or resize at all, some of the controls (buttons) seem to be disabled, some of them even disappear or are displayed twice.
In .NET I had similar problems, but enabling double-buffering on form solved them. But it seems that it does not work in Mono at all and I really don't know what to do.
On resize I need to move and resize the controls and redraw pictures in PictureBoxes.
I also have a problem with the above mentioned timer - the tick event fires only once and then almost everything on the form stops working, but I think it may be connected with the repainting problem.
If someone had an advice on how to correctly repaint a WinForms form in Mono, I would appreciate it.
I have an application whose UI is custom rendered with a theme. I also want to add new non-default-cursors (like the resize cursors when the user intends to resize the window) to match that theme.
With the WinAPI function SetCursor I am only able to change the default pointer for the application, but this is not enough, so I looked up SetSystemCursor which works just fine. Problem is: The latter version changes the cursors system-wide permanently, but I only want them to be changed for my application only.
I thought about copying the previous cursors before I do the SetSystemCursor and re-set them at application exit, but even when I implement a terminate handler it may not be called if the process e.g. just crashes. Also the cursors would still be changed system-wide as long as the application is running.
Specifically for the resize-cursors, I could just drop the window style, make a borderless window, and render/implement the resizing grips and logic myself (then I could just hook the mouse-over events), but that is really just my last resort - I'd rather like to know if it is possible achieve my goal before I do this cumbersome task...
For anyone who is interested: The UI is rendered with WPF, but WPF doesn't provide this functionality either (again, they have it, but just for the default pointer). It's no concern for me to use the WinAPI or other "low-level" calls if I have to, but at the moment it seems there are none that are fitting my needs :(
So if anybody knows how to change the other system cursors (not the default pointer) in WPF or WinAPI just for my application without having to implement custom cursor-logic to my window just for that, you would make my day.
I don't know how to implement this in WPF, but if you want to set the cursor to something other than default, then your window procedure should handle the WM_SETCURSOR message.
http://msdn.microsoft.com/en-us/library/windows/desktop/ms648382(v=vs.85).aspx
I have a splittercontainer (vertical) placed on form. In the right panel, I placed another splittercontainer (horizontal).
When I run the application, the topmost splittercontainer works fine, no issues. The problem is with the embedded splittercontainer.
The size of the embedded splittercontainer when resized is fine, however the panels show up as a smaller size. I did not even thing that was possible. I cannot seem to get the embedded panel to consistently show the proper dimensions.
I did a search, and turned up this article.
http://support.microsoft.com/kb/953934
I tried out the recommended solution, and quite usual for any Microsoft post, it does not work.
In fact, things worked better without the suggested solution. At least after the application showed, I was able to get the panels to size properly, just by adjusting the splitter container of either control.
Thoughts?
Thanks in advance,
Sarah
After suffering for quite some time, it seems that posting my question got my head to think of a solution.
The outer splittercontainer must be set for docking type fill. Embed the second splitter container directly inside Panel 2 and have that set to docking type fill.
In the resize event, do not add any Controls.Add() for the splitter container, as that is done in the designer. You should add a Controls.Add() for any forms that you want to show.
Do not size the splittercontainers. Allow Windows to do that. Do resize the forms. Make sure to set the TopLevel to false first and show the form after adding to the control of the panel.
I tried the docking type none and several other things. It was either setting to none or setting the manually setting the sizing or whatever that caused the problem.
I hope this post helps someone.
OK, anyone can explain how Jing take screen shots with that overlay form? It appears that it take a full screen shot and records all visible window handles and let you select within the form a specific hwnd. could be true? if is, what are the big steps to achieve this? could be a simple picturebox or without a custom control i don't have a chance to freeze the screen while taking a screen shot?
Thank you!
I'm not familiar enough with Jing to know exactly what it uses. But there are two basic techniques. One is as you mention, capture the screen and display it in a topmost borderless form. The Vista/Win7 Snipping tool works that way. You'll find the code you need to get this started it in my answer in this thread.
The other, perhaps more likely to be used by Jing, is similar to what Spy++ does, allowing the user to move the mouse and draw a selection rectangle around the window. Its advantage is that it can deal with windows resizing or disappearing while you've got the tool running. You implement it by using a topmost form the size of the screen that has its TransparencyKey property set to the value of the BackColor. Fuchsia is a popular choice. You can draw on this form with the OnPaint() method, the drawing appears on top of all the windows. You'd need some P/Invoke (GetWindow) to iterate the underlying windows in their Z-order to know which window the user is pointing at. GetWindowRect() to get the window rectangle. Plus some hassle to deal with Aero lying about the border size.
You can find sample code to get you started on that technique in my answer in this thread.
I would like to remove the resizing border from my WPF custom window.
I already found that I have to handle the WM_NCCALCSIZE message and return 0.
That removes the border and aligns the window to the top left corner of the window.
The problem is that by doing so, the client area increases and the WPF root control doesn't.
That creates black edges on the left and bottom sides of the window that I would like to get rid of.
I'm using VS2010 C# Windows XP and would like this to work under both Windows XP and Windows 7.
Thanks in Advance.
EDIT:
I found out what is causing the black edges, they are the window behind.
Now it seems that the problem is with the root element of the window not occupying the whole window. When I set its margin to negative values it draws over the black area. Apparently the layout pass is ok and the desired size is the same as the window but the render size is different.
I also found out that the whole problem could be solved by removing WS_THICKFRAME from the window style. The problem with that is the resizing functionality that is enabled only when WS_THICKFRAME is used. I'm using WM_NCHITTEST to do the resizing and if the window knows it doesn't have a resizing border, it will shutdown its resizing functionality.
I would like to make the root element occupy the whole window to eliminate the black window background or alternatively enable the native resizing functionality without the thick frame.
Thanks.
I found the reason for that black area.
It appears that the code I was using that someone else made was causing the black area by somehow messing with the layout pass of the framework and therefore the correct size of the root element.
I handled the WM_NCCALCSIZE in another project and it worked like a charm.
After all of that, although I found the idle way to create a custom window with all of the original window functionality, I decided to use the standard window the Microsoft has to offer so that my program will have future compatibility with windows.
If someone would like the code or help with WPF window customization they can comment here and I will help so that at least all of my research won't go in vain.
Thanks for reading.