Buttons reaction on finger's touch in Windows 7 - winforms

I have Windows 7 with touchscreen attached.
My standard Windows Forms Application has several standard buttons.
My problem: buttons on form do not show reaction when I click on them using my finger.
My form shows that there has been a click on the button but button itself does not react.
If I use cursor - everything works fine.
If I use Windows XP - everything works fine.
Same thing with any standard application like calc.exe

I performed several experiments and now I believe problem with buttons reactions on touch is solved.
1) Using WndProc I noticed that WM_LBUTTONDOWN and WM_LBUTTONUP messages were comming to my window at one and the same time (on finger release).
2) I installed most recent driver, found setting Touch Mode and changed it to Mouse Emulation. This resolved the problem for my single touch screen. But problem remained the same for the multi touch screen.
3) I created class:
class TouchButton : Button
{
protected override void OnHandleCreated(EventArgs e)
{
base.OnHandleCreated(e);
RegisterTouchWindow(Handle, 0);
}
protected override void OnHandleDestroyed(EventArgs e)
{
UnregisterTouchWindow(Handle);
base.OnHandleDestroyed(e);
}
}
4) I replaced all the generic Buttons with the TouchButtons and problem has gone!

Related

WP7 - Splash Screen not working outside debugger session

When my MainPage loads in my Windows Phone 7 application, it triggers a popup splash screen that includes a progress bar and a graphic in a usercontrol. After displaying the spash screen I do some work in a BackgroundWorker thread to load some resources while the spash displays. When the loading is done I dismiss the popup. This technique is well documented on WindowsPhoneGeek.
I noticed today that while this is working flawlessly when running in debug under Visual Studio, if I run the same build directly without the debugger connected, the splash screen animation and progress bar never appear and the DoWork() thread takes at least twice as long to execute the same operations. I can see that the MainPage constructor gets called as well as OnNavigatedTo, but the popup still does't display and the default jpg splash image remains on the screen, until the worker thread completes. Then the popup displays for < 1 second and the mainpage displays. Again, this all works flawlessly when debugging through VS 2010.
This is all in the Emulator, I don't have a device yet. I just noticed this today, and coincidently(?) I just updated the environment to 7.1 last night.
// Constructor
public MainPage()
{
InitializeComponent();
IDictionary<string, object> state = Microsoft.Phone.Shell.PhoneApplicationService.Current.State;
if (!state.ContainsKey(STATE_WAS_LOADED))
{
state[STATE_WAS_LOADED] = "LOADED";
this.LayoutRoot.Visibility = System.Windows.Visibility.Collapsed;
_popup = new Popup();
_popup.Child = new NPGSplash();
System.Diagnostics.Debug.WriteLine("{0}: Displaying Splash Popup", DateTime.Now.ToString("ss.ffff"));
_popup.IsOpen = true;
// Asynchronously load the biggest dataset
StartLoadingData();
}
}
private void StartLoadingData()
{
_worker = new BackgroundWorker();
_worker.DoWork += new DoWorkEventHandler(_worker_DoWork);
_worker.RunWorkerCompleted += new RunWorkerCompletedEventHandler(_worker_RunWorkerCompleted);
_worker.RunWorkerAsync();
}
void _worker_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
{
this.Dispatcher.BeginInvoke(() =>
{
System.Diagnostics.Debug.WriteLine("{0}: Splash RunWorkerCompleted", DateTime.Now.ToString("ss.ffff"));
this.LayoutRoot.Visibility = System.Windows.Visibility.Visible;
this._popup.IsOpen = false;
});
}
EDIT:
I ended up buying a device on ebay this week to ensure that I don't release an app where I can't confirm that it works properly. I can confirm that whatever the problem is, it does NOT occur when running the application on the device. Good news. Still, I can't explain what appears to be an approximately 3-5 second pause in my application after the consrtuctor is called. I even changed my logic in the constructor to set a System.Windows.Threading.DispatcherTimer to fire in 100ms to kick off my logic. When this code executes, the constructor completes, but the timer doesn't tick for 3-5 seconds. Very odd, and only in the simulator when not attached to the debugger.
The problem here would appear to be that you are never attaching the Popup control to the visual tree. To be honest, I've got no idea why this would work with the debugger attached either, but I'm going off what I can interpret from your code.
What I think you need to do is to add the Popup control as an element in the XAML for MainPage so that it is attached to the visual tree.
One other thing I'd say is that it's perhaps worth moving all the data loading code out of the constructor and into either an override for OnNavigatedTo or a handler for the Loaded event. Generally speaking, it's best to keep constructors and short and simple as possible (and yes I appreciate that you're using a background worker to load the data).

Several parts of UI are not painted

We have a very strange behaviour of a WPF application. Sometimes (not very ofen), some parts of the user interface are simply not painted.
Just recently the save button and a text box on the configuration view didn't show up. Even more strange is that after a relogin, what results in a new view instance, the problem is still present.
Sometimes it helps to hover the mouse over the position where the missing controls usually are to get them visible. But switching the tab page and then back to the original one with the missing controls they are all missing again. Other controls won't show up by hoovering the mouse over them.
Another problem is that dialogs are sometimes screwed up. Parts of the dialog are displaced vertically. But when e.g. a text box inside the dialog gets the focus, it is painted correctly while the rest of the dialog stays displaced.
I don't have the slightest clue what causes this problem. Any idea is welcome.
[Edit 1] So far we have seen this always on Windows XP. Windows 7 seems to be Ok. Also switching to Software-Rendering seems to fix the problem on Windows XP but I'm not sure on this.
The problem was solved by switching the RenderMode to SoftwareOnly. It seems to be a .NET 4 issue when running on Windows XP:
public class MyWindow : Window
{
protected void SetSoftwareRendering()
{
System.Windows.Interop.HwndSource hwndSource = PresentationSource.FromVisual( this ) as System.Windows.Interop.HwndSource;
System.Windows.Interop.HwndTarget hwndTarget = hwndSource.CompositionTarget;
hwndTarget.RenderMode = System.Windows.Interop.RenderMode.SoftwareOnly;
}
}
Alternatively one can write
System.Windows.Media.RenderOptions.ProcessRenderMode = System.Windows.Interop.RenderMode.SoftwareOnly;
All windows are inherited from MyWindow and can decide wether or not they want the software rendering. Currently we don't use this flexibility and have it enabled on all instances.
If this happens in other WPF applications too it might be your hardware, driver, OS or .NET software.
If not, the only option is to try and reproduce in a minimal case and on several machines.
Are you able to make a minimal version that has the problem en post the code?

Silverlight MouseMove inconsistency for Chrome vs FF/IE

I've got a listbox with images. I'm capturing MouseMove. In FF (Win7 & OSX) & also in IE8, this fires whenever the mouse is moved over the images. In Chrome (on OSX), however, it only fires while the mouse button is pressed down. This Chrome behaviour would actually be quite useful, but only if I could control it, rather than have it just randomly happen on certain browsers. So does anyone know if there's some overall setting somewhere that's making it behave this way in Chrome, or is it just an inconsistency in SL implementations?
I suspect the latter, since I've never been able to find a way in SL of testing whether the mouse button is down.
Thanks for any help.
As far as I understand the problem is MouseMove, MouseEnter and MouseLeave events are not fired when mouse left button is down.
I had the same problem with TextBox. Actually it happened in IE too and my googling told me it is so by design. Further googling revealed the reason: the element is capturing mouse using CaptureMouse() method. So I have just derived from TextBox and overrode OnMouseMove(...) method:
protected override void OnMouseMove(MouseEventArgs e)
{
base.OnMouseMove(e);
ReleaseMouseCapture();
}
Note: I'm not sure, whether capturing mouse is the only thing the base implementation of this method does, so I added ReleaseMouseCapture() after calling it, but commenting it out also works, of course.

What causes a window to not appear in the taskbar until it's Alt-Tabbed to in Vista?

When our app is started programatically (either through custom action in MSI installer or when starting a new instance) in Windows Vista (also happens in Windows 7 Beta) it won't appear in the taskbar and isn't focused. Alt-tabbing to it will make it appear in the taskbar properly and stay there.
What causes this? I've seen this in some other apps before as well, but not sure why. Out app is .NET WinForms app. Never see this happen in XP, only Vista and 7
Edit: Well, it seems like the only time this happens reproducibly is when it's run by the installer, I believe there's other times it occurs, but I might just be crazy. The launching code is a bit complex to post because we handle various command line launch parameters and it launches a signin form before actually launching the main app etc.
Has anyone had to deal with this scenario before and worked it out?
Try checking your main application form "Form Border" property.
If it's ToolWindow (Fixed or Sizable), try changing it to FixedDialog for example.
This solved the problem in my case.
The usual reason for this is that your main application window doesn't have the window styles that let Windows know it's a main application window (rather than a tool window or a dialog box). So Windows is having to guess based on how the app was started, etc.
Use Spy++ to complare the window styles (especially extended styles) if your window to that of some other window that doesn't have this problem. Are you missing the WS_EX_APPWINDOW style? Are any other styles/extended styles different from other top level windows?
G.So's answer made me find the solution for my problem, wich was caused by the fact that i had my form sizable from launch, but set to borderless in the load void.
If anyone is interested in how i managed to keep the switch to borderless and have it pop up as it should in the taskbar without any dirty hacks.. here it is..
Make a new event from the form on the form's "Shown" event, and put your line of code for switching to borderless in here. Problem solved :)
private void Form1_Shown(object sender, EventArgs e)
{
this.FormBorderStyle = System.Windows.Forms.FormBorderStyle.None;
}
and for the lazy ones ;) >>>>
this.Shown += new EventHandler(Form1_Shown);
Thanks again G.So for clearing up what could cause this in the first place.
I stuggled with this issue as well, and found like a previous commenter said, you cannot have anything in the form's Load() event that changes that FormBorderStyle property. Move anything that changes it to the Shown() event.
Well, one solution is to use a hack like this. That's really not what it's for.
Usually the decision of whether a window will be in the taskbar or not is based on the border styles it uses. The article I linked to provides a bit more detail. The article's comment about the window having an owner or not is quite possible highly relevant to your issue, since the window might somehow be getting a different owner when launched by the installer.
That article is in VB but it's all based around API calls so the info it provides is pretty language independent.
Never see this happen in XP, only Vista and 7
Maybe it's a bug in Vista...?
What happens if you call SetForegroundWindow() (or equivalent in .Net)?
Edit
I did of course mean "BringWindowToTop()".
Or do both.
We had this same problem and fixed it by setting the form property showintaskbar property to true.
Weird that all windows os's dont run apps in the same way!
In our situation, this was tracked down to the form's text property being changed within the Load event.
After putting this inside a BeginInvoke, this odd behaviour no longer happened.
Hope this helps anyone else.
Example
private void Form_Load(object sender, EventArgs e)
{
...
...
...
// this needs to be inside a BeginInvoke otherwise it messes with the taskbar visibility
this.BeginInvoke(new Action(() =>
{
this.Text = "Something new";
}));
...
...
...
}
We encountered the same issue, also in Windows 8. Sometimes the form was receiving correctly the focus, but say just ~30% of the time.
We tried different solutions, but actually the one that worked was the following:
private void OnFormShown(object sender, EventArgs e)
{
// Tell Windows that the Form is a main application window
this.FormBorderStyle = System.Windows.Forms.FormBorderStyle.FixedDialog;
// Even if true, enforce the fact that we will the application on the taskbar
this.ShowInTaskbar = true;
// Put the window to the front and than back
this.BringToFront();
this.TopMost = true;
this.TopMost = false;
// 'Steal' the focus.
this.Activate();
}
Moreover, we ensure also not to set the title of the form during the Load event.

how to set wpf MessageBox.Owner to desktop window because SplashScreen closes MessageBox

I am using the SplashScreen feature in WPF by setting a bitmap's Build Action to Splashscreen. Behind the splash screen, licensing information is being check, and if it fails I show a MessageBox.
According to this Feedback, it is because the MessageBox.Owner is the splash screen and as soon as another window is open even if it is a MessageBox the splash screen window is closed which then in turn closes the MessageBox, so the user never sees the MessageBox.
So the workaround would be to set the MessageBox.Owner to another window, but that would mean that I have to instantiate another window which might not even be needed.
Would it be possible to set the MessageBox.Owner to the desktop window? And how, because the only other function that comes to mind is the GetDesktopWindow() api function, but that returns a window handle and MessageBox.Owner is a WPF Window.
Since using the desktop window as the parent for your modal dialogs is not a good idea, as #Nir pointed out in his answer, here are three other workarounds:
1) Use a hidden window. Create a tiny, non-modal window to act as the parent for your MessageBox or other modal dialog. This approach is described here:
http://social.msdn.microsoft.com/Forums/en-US/wpf/thread/116bcd83-93bf-42f3-9bfe-da9e7de37546/
2) Create non-modal message windows. Change your startup mode to explicit shutdown and use a non-modal window to display your message. This approach is described in the answer to this StackOverflow question:
MessageBox with exception details immediately disappears if use splash screen in WPF 4.0
3) Call MessageBox twice. Apparently, the problem only affects the first modal dialog shown. So you could simply call your modal dialog twice, if you didn't mind the flash of the first one opening and closing.
https://connect.microsoft.com/VisualStudio/feedback/details/600197/wpf-splash-screen-dismisses-dialog-box
Personally, I don't like any of these workarounds. The only other option is to avoid the built-in SplashScreen functionality and to roll your own from scratch. Here's a link if you want to investigate that route further:
http://social.msdn.microsoft.com/Forums/en-US/wpf/thread/8dd49fd0-9cc9-43c6-b285-6f119ab8a32e/
Finally, if you're as annoyed by this issue as I am, you can vote for Microsoft to fix this bug here:
http://connect.microsoft.com/VisualStudio/feedback/details/600197/wpf-splash-screen-dismisses-dialog-box
I came up with this solution myself, so maybe there's something wrong with it, but it seems to work perfectly:
Window temp = new Window() { Visibility=Visibility.Hidden };
temp.Show();
MessageBox.Show(temp, "An error occurred before the application could start.\n\nTechnical Details: " + ex.Message, "Fatal Error", MessageBoxButton.OK, MessageBoxImage.Stop);
App.Current.Shutdown(1);
I found the problem. I am also using the build-in splash screen which causes this: WPF SplashScreen closes MessageBox
Can you post some code? I just tried adding this to the App.xaml.cs file in a new WPF application:
protected override void OnStartup(StartupEventArgs e)
{
if (MessageBox.Show("Start app?", "Confirm Start",
MessageBoxButton.YesNo) == MessageBoxResult.No)
{
this.Shutdown();
return;
}
this.StartupUri = new Uri("Window1.xaml", UriKind.Relative);
base.OnStartup(e);
}
... and it works as expected (the "Confirm Start" prompt stays open until I've responded, and if I click "No" the app shuts down).
The desktop window is never the correct parent, read this to know why:
http://blogs.msdn.com/oldnewthing/archive/2004/02/24/79212.aspx
Now the problem described in this post doesn't happen so much because MS worked around it, in this post you can see how:
http://blogs.msdn.com/oldnewthing/archive/2006/11/02/931674.aspx
This issue is still an issue, I faced it recently. For me, the solution was to close immediately the splash screen in case of any issues:
SplashScreen splash = new(Assembly.GetAssembly(typeof(GuiApp))!, "Resources/img_my.png");
splash.Show(false);
using ServiceProvider? services = initializeApp();
if (services == null)
{
splash.Close(TimeSpan.Zero);
return -3;
}
After that MessageBox displayed normally.
this has helped me a lot .....
Given me new idea
but the example code that i have seen here has some modification required
here is an simple example in wpf with modification
now it is working
on button click
paste this code
if (System.Windows.Forms.MessageBox.Show("are u sure", "delete", System.Windows.Forms.MessageBoxButtons.YesNo, System.Windows.Forms.MessageBoxIcon.Question) == System.Windows.Forms.DialogResult.Yes)
{
this.Close();
}
else
{
MessageBox.Show("why not to delete");
}
This is not directly related to the OP's situation, but might be useful for others who are having problems with MessageBox being hidden behind other windows in certain special situations.
As #dthrasher mentions, one solution is to use a hidden dummy window. But sometimes even that is not enough. I had a situation where the solution was to not only use a hidden dummy window, but to turn on its TopMost property whenever I used it with MessageBox.
_formKludge.TopMost = true;
MessageBox.Show(_formKludge, "Nice informative message.", "Super-duper Program",
MessageBoxButtons.OK, MessageBoxIcon.Error);
_formKludge.TopMost = false;

Resources