WPF Window not following mouse when expanding - c#

On a new blank WPF app, I noticed that the resizing the window with mouse does not work properly.
When I'm shrinking the window, it works fine. But when I'm expanding it, the window does not follow the mouse until I leave the button, and then the window suddenly jumps to the new size.
It seems that if I move the cursor really slowly while expanding, the window follows the cursor; but a bit faster than that and it doesn't anymore.
You can see the issue in a video I recorded here.
I tried .NET versions 4.7.2, 4.7.1 and 4.6. All are having the same issue.
I've tried to look this up, but found nothing about this issue anywhere. Does anyone know what is causing this, and how can one fix it?
There's a possibility that this issue is somehow isolated to my machine, and therefore caused by something other than the framework itself. So another relevant question might be whether anyone else sees this behavior on a new WPF project or not.
Update: This is the behavior seen in a new blank WPF project, with no code changes at all. And the expected behavior is obviously for the window to follow the cursor while expanding, just like it already does when shrinking.
Update 2: As #gore85 mentioned, this might be an issue with Windows 10 version 1903. I was on 1903 insider preview builds when I posted this question (it's out now) and he's seeing the same thing after updating to 1903.

There is a fix for this issue now.
https://support.microsoft.com/en-us/help/4517211/windows-10-update-kb4517211
Addresses an issue with resizing Windows Presentation Foundation (WPF)
applications; they may not respond to being resized using the mouse
until you release the mouse button.
It seems to stem from a faulty tablet input support. Someone devised a workaround (without using the update):
public static void DisableWPFTabletSupport()
{
// Get a collection of the tablet devices for this window.
TabletDeviceCollection devices = System.Windows.Input.Tablet.TabletDevices;
if (devices.Count > 0)
{
// Get the Type of InputManager.
Type inputManagerType = typeof(System.Windows.Input.InputManager);
// Call the StylusLogic method on the InputManager.Current instance.
object stylusLogic = inputManagerType.InvokeMember("StylusLogic",
BindingFlags.GetProperty | BindingFlags.Instance |
BindingFlags.NonPublic,
null, InputManager.Current, null);
if (stylusLogic != null)
{
// Get the type of the stylusLogic returned
// from the call to StylusLogic.
Type stylusLogicType = stylusLogic.GetType();
// Loop until there are no more devices to remove.
while (devices.Count > 0)
{
// Remove the first tablet device in the devices collection.
stylusLogicType.InvokeMember("OnTabletRemoved",
BindingFlags.InvokeMethod |
BindingFlags.Instance | BindingFlags.NonPublic,
null, stylusLogic, new object[] { (uint)0 });
}
}
}
}

Related

Take screenshot of external OpenGL game C# with BitBlt (CopyFromScreen)

I am trying to create some kind of antycheat for counter strike (hl) game. Of course funcionality of making a screenshot in-game is built-in, but exploited (detected) by antyss applications, so every time screenshot is taken from the game, antyss is disabling the cheats (so that no cheats are visible on the screenshots)
For the last few days, I've read dozens of threads regarding this topic. Most of them are outdated and are using libraries, that are obsolete right now.
I've read about the approach with mirage driver (which is not working on windows 10), about injecting to the application (of course application/game is not part of my code) and using/incjeting some code with OPEN GL/D3D library (to read backbuffer). Probably this could be in the end the only solution.
But right now I have almost a working solution. I write "almost" because it is working but giving me only some kind of "cached" data. It is giving me a correct screenshot, but if I take another screenshot - still the same screenshot is taken as last time. If while being in-game I minimize the application (full-screen mode) and then get back to the game, the new screenshot taken will have up to date screenshot, but then again, the next screenshot would be exactly the same.
I don't know if it is "by design" or is it "some sort of bug" Nevertheless my question is: Can I force somehow this "reloading" without having to programmatically call some kind of "alt+tab" and then focusing on the application once again?
In this topic:
How to take screenshots of a game with OpenGL
#Andon M. Coleman wrote:
Are you on Windows? In fullscreen mode starting with Windows Vista, there is trouble with anything that tries to capture the front-buffer (including the built-in Alt + PrintScreen). The easiest solution is to change your buffer swap behavior to Copy Swap (PFD_SWAP_COPY, slower but guaranteed to work). Often if you Alt+TAB out and back in after making the fullscreen mode switch that will fix it too; though I have never been able to explain that ;) If you did not write the game in the question, then the second solution may be your only choice if you want to use that code.
This is exactly the problem I am facing. As he wrote: "Alt+Tab" is fixing the problem (although he did not know whether it is a feature or a bug) He proposed to change the buffer swap behavior to Copy Swap(PFD_SWAP_COPY) Any tips on how to change my code with that will also be most welcome (I can try this one) But if I understood correctly, this approach is the viable solution only if you can change this in the game (and this is not my case)
Here is my working code (which in topics about such scenarios was claiming that in this approach the screenshot is BLACK. But it is working for me)
private const int SW_RESTORE = 9;
public void TakeScreenShot()
{
var guid = Guid.NewGuid();
string procName = "hl";
Process proc;
try
{
proc = Process.GetProcessesByName(procName)[0];
}
catch (IndexOutOfRangeException e)
{
return;
}
// Focus on the application
SetForegroundWindow(proc.MainWindowHandle);
ShowWindow(proc.MainWindowHandle, SW_RESTORE);
Thread.Sleep(1000);
Rect rect = new Rect();
IntPtr error = GetWindowRect(proc.MainWindowHandle, ref rect);
while (error == (IntPtr)0)
{
error = GetWindowRect(proc.MainWindowHandle, ref rect);
}
int width = rect.right - rect.left;
int height = rect.bottom - rect.top;
using (Bitmap printscreen = new Bitmap(width, height, PixelFormat.Format32bppArgb))
{
using (var graphics = Graphics.FromImage(printscreen))
{
graphics.CopyFromScreen(rect.left,
rect.top,
0,
0,
new Size(width, height),
CopyPixelOperation.SourceCopy);
printscreen.Save($#"{Path.GetTempPath()}\{guid.ToString()}.jpg", ImageFormat.Jpeg);
}
}
}
I want this application to work on Windows7, Windows8, Windows 10. The best would be to cover full screen and windowed mode (but fullscreen is probably more important)
Any advice how to proceed (or why I am getting the "cached" data) would be nice :)
Of course if someone will say (with full authority), that what i want to achieve is impossible with CopyFromScreen (and there is no hack to fix that, apart from minimizing and maximazing the screen) i will consider option with injecting the code. But normally i would want to stay away from this one, as this could be treated as cheat and can lead to VAC ban.
====== UPDATE ======
You can try reproduce the process of taking screenshot by downloading the game (is small one, 260 MB):
https://cssetti.pl/Api/GameDownload.php?GameDownloadId=v43
Then you can copy-paste my code to Linqpad (or any other editor) and run the code. The application after launching will launch the HL process which is then use to try to grab the screenshot.
====== UPDATE 2 ======
In windows mode everything works correctly (the printscreens are ok)

Faster way of searching for Top Level Windows in WPF CodedUI

I have several parts of my application that are supposed to close a window.
Checking that these windows have been closed using Coded-UI is incredibly slow. Right now my code looks like this:
Assert.IsFalse(UIMap.SomeWindow.TryFind(),
"X Window found when should be closed");
The problem is, this takes around 30s to search, and there are around 5 times this is used, and I have around 10 similar windows all being tested. I'd like to trim this time if possible, as it's making my tests slow.
I have also tried a dynamic solution (which is basically identical to the UIMap implementation):
var window = new WpfWindow();
window.SearchProperties.Add(UITestControl.PropertyNames.Name, "Window Title");
Assert.IsFalse(window.TryFind());
This is just as slow. It would be nice to use ApplicationUnderTest as a search parent, but as the window is Top Level, it doesn't seem to work.
Surely it shouldn't be too hard just to look at the open windows on my system (5), and check their titles against the search parameter?
Edit: Using SearchConfiguration.VisibleOnly doesn't seem to help either.
Found my answer, surprisingly on LinkedIn.
Now using:
Playback.PlaybackSettings.SearchTimeout = 1000; //in ms
Playback.PlaybackSettings.ShouldSearchFailFast = true;
Source: https://www.linkedin.com/grp/post/3828241-5843659258196959234
(C&P):
//Search Settings
// Value is in milliseconds. Default search timeout is 2 minutes.
// The search engine will continue making passes until the timeout has expired
// or the window has been found.
settings.SearchTimeout = 10000;
// Default search will make 3 attempts.
// If true the default 3 attempts is applied. If false then only one attempt should take place.
settings.ShouldSearchFailFast = true;
I think there might be a better answer. If set a global configuration like that and have to deal with a WPF Table and find a specific cell you might not find it working.
Using Window name generally isn't a great idea if there is any dynamic titles, Control Name is a good constant. It sounds to me like you are passing bad SearchProperties. You can use DrawHighlight() to see if CUI is actually finding your controls. First pass in the main parent window to your close window method, then use it as a try.
public static WinWindow _mainParent(string MainParentCtlName)
{
var _mainForm = new WinWindow();
_mainForm.SearchProperties.Add("ControlName", MainParentCtlName);
return _mainForm;
}
public static void CloseWindow(string MainWinCtlName)
{
var close = new WinButton(_mainParent(MainWinCtlName));
close.SearchProperties.Add("Name", "Close");
Mouse.Click(close);
}
try
{CloseWindow("MainWindowForm")}
catch{}

Order of WindowHandles

I'm encountering an issue where WebDriver seems to change the order of WindowHandles. This causes us to close the wrong one intermittently after getting them in some cases.
What seems to happen is the previously established first window handle is returned as a subsequent handle, which causes my logic to of course, close the wrong one.
Is WebDriver supposed to return the window handles in the same order every time (order of first opened window to last?). This is what I initially expected, but now I'm not so sure.
I should also mention the problem seems to only occur in IE right now, but I'm not certain if this is a more generic issue.
Here is how I'm closing the active window and switching back to the root window.
public void Close()
{
//switch to latest window
string windowName = string.Empty;
if (_driver.WindowHandles.Count > 1)
{
//get 'root' window in list
windowName = _driver.WindowHandles[0];
_driver.Close();
_driver.SwitchTo().Window(windowName);
}
else
{
_driver.Close();
}
}
We're on WebDriver 2.45 (C# bindings, 32-bit IEDriver). If there is a method to close the active window in the C# bindings that would most likely solve this issue as well.
This pop up window handler is entirely unordered as per my understanding. I remember having same conversation on SO and luckily JimEvans(one of the contributors of Selenium) chimed in and clarify few factors. I read about the PopupWindowFinder of Selenium .NET bindings and found that class can make your life lot easier. API is here. However, the whole order issue is entirely complex and painful to deal with. See this thread. Just don't want to reinvent the wheel.

Why I can't detect touch screen?

I'm using this C#(wpf) code to detect touch screen on
return Tablet.TabletDevices.OfType<TabletDevice>().Any(dev => dev.Type == TabletDeviceType.Touch)
But it is not working. Tablet.TabletDevices Count is always 0.
I'm using extension touch monitor(use USB connect PC for touch detect)
Is there any better way to check if current PC has touch screen or not?
Thanks.
Update1:
I don't know why but even when I remove the touch screen USB and monitor,
GetSystemMetrics(SM_MAXIMUMTOUCHES) still returns 1.
Update2:
looks like that is not working, I mean use :
return GetSystemMetrics(SM_MAXIMUMTOUCHES) > 0
Because it's always returning 1, even when I restart computer(win7 OS,
laptop computer)
I use a bit different approach, and it works for variety of touchscreens. It works from Win7 and up (as defined here, in section about SM_DIGITIZER setting).
bool touchDevicePresent()
{
return GetSystemMetrics(SM_DIGITIZER) & NID_READY;
}

WebBrowser control memory leak

I have problem with memory leak in webBrowser control.
I have found this thread:
How to get around the memory leak in the .NET Webbrowser control?
and this:
//dispose to clear most of the references
this.webbrowser.Dispose();
BindingOperations.ClearAllBindings(this.webbrowser);
//using reflection to remove one reference that was not removed with the dispose
var field = typeof(System.Windows.Window).GetField("_swh", System.Reflection.BindingFlags.NonPublic | System.Reflection.BindingFlags.Instance);
var valueSwh = field.GetValue(mainwindow);
var valueSourceWindow = valueSwh.GetType().GetField("_sourceWindow", System.Reflection.BindingFlags.Instance | System.Reflection.BindingFlags.NonPublic).GetValue(valueSwh);
var valuekeyboardInput = valueSourceWindow.GetType().GetField("_keyboardInputSinkChildren", System.Reflection.BindingFlags.Instance | System.Reflection.BindingFlags.NonPublic).GetValue(valueSourceWindow);
System.Collections.IList ilist = valuekeyboardInput as System.Collections.IList;
lock(ilist)
{
for (int i = ilist.Count-1; i >= 0; i--)
{
var entry = ilist[i];
var sinkObject = entry.GetType().GetField("_sink", System.Reflection.BindingFlags.NonPublic | System.Reflection.BindingFlags.Instance);
if (object.ReferenceEquals(sinkObject.GetValue(entry), this.webbrowser.webBrowser))
{
ilist.Remove(entry);
}
}
}
But I'm using Windows.Forms no WPF window and i have problem with converting this code to my needs. Can somebody help me?
We have used Chromium in a couple of applications. This allowed us to run HTML 5 in WinXP. Since the webBrowser control uses the installed IE of the OS you can't use most of the better HTML/Javascript. Microsoft doesn't support WinXP's IE so the application only can access older versions of IE.
If you use the CEFSharp version of Chromium you can even compile in further mods and aids for your navigation which gives you improved embedded communication that isn't supported by IE.
The code is really simple and there are several examples but just look:
InitializeComponent();
Text = "CefSharp";
web_view = new WebView("https://github.com/perlun/CefSharp", new BrowserSettings());
web_view.Dock = DockStyle.Fill;
toolStripContainer.ContentPanel.Controls.Add(web_view);
//even setup the console to log to a Textbox for debugging by setting up a Handler.
web_view.ConsoleMessage += new CefSharp.ConsoleMessageEventHandler(ConsoleMessageHandler);
We faced that problem some time ago... to no avail.
To work around the problem and keep our application's memory consumption at a reasonable level we decided to split our application in two kind of processes, one for the main window and N child processes to host the WebBrowserControl. Then, design a pipe protocol (or RMI/RPC-like) to communicate events from the main window to the child processes and vice versa.
Doing that, you can design a recycle strategy using a pool of browser processes and a background kill-and-spawn policy to get the memory consumption at a controlled level.
Have you considered using other web browser controls? There are a lot out there! I feel like chromium is a good bet, check out this question for alternatives.

Categories

Resources