Main form randomly dissappears after a reboot of CE device - c#

I have an app written in C#.Net which is running on a Motorola MC67 Windows Mobile device.
Through the "Startup" folder my app is automatically launched after a reboot which loads a "Logon" screen. It was reported that occasionally after a reboot the device is displaying a blank white screen.
At this stage, the software has not crashed as I am able to use some of the devices physical buttons to move to a new screen and then navigate back to the "Logon" screen which now displays correctly.
I am having trouble finding the route of the problem and would appreciate some assistance.
The problem seems to only occur while it is docked (it happens more in a 4 way dock compared to a single dock as the 4 way does more networking) and as it is after a reboot it is difficult to debug.
The white screen that is shown is a splash screen that is displayed while the app launches and just sits in the background so it appears that the "Logon" screen has somehow been hidden or disposed.
As a temp solution I have created a method called "Form_Deactivate()" that is called whenever the "Logon" screen loses focus and when it does I call "this.BringToFront()" which then displays the "Logon" screen correctly and no longer displays the white screen.
Although this probably is an acceptable fix I am still trying to find the cause of the problem.
If it helps, when the deactivate method is called I force an exception in order to log the stack trace but this hasn't really helped me.
at InSync.LogonForm.Form_Deactivate(Object sender, EventArgs e)
at System.Windows.Forms.Form.OnDeactivate(EventArgs e)
at System.Windows.Forms.Form.WnProc(WM wm, Int32 wParam, Int32 lParam)
at System.Windows.Forms.Control._InternalWnProc(WM wm, Int32 wParam, Int32 lParam)
at Microsoft.AGL.Forms.EVL.EnterMainLoop(IntPtr hwnMain)
at System.Windows.Forms.Application.Run(Form fm)
at InSync.ApplicationManager.Start()
at InSyncLauncher.Program.Main()
If anyone has any suggestions or things that I could try to get to the bottom of this issue I would be grateful, thanks.

First, the API functions your app and the Compact Framework uses may not be ready to be used when your app is started with a lnk in \Windows\Startup. There is a native function IsAPIReady to check for the different API sets.
Secondly, the OS system may load another window to foreground, for example the Home screen. So your app should use a timer to bring the login form to foreground periodically or use GetForGroundWindow periodically to check if the foreground window handle is the Login window (or your current active window).
If you want to write a kiosk mode app, there are many more situations you have to check periodically to prevent the user from getting outside the kiosk app.

Related

Remove Notification icon on WPF application on process exit

There should be a pretty straightforward answer to this question but I can´t seem to find a solution. I have seen similar questions on SO (like NotifyIcon remains in Tray even after application closing but disappears on Mouse Hover) but they don´t cover my case.
I have a WPF application with a Notification Icon that is set up inside the MainWindow method:
InitializeComponent();
myIcon = new System.Windows.Forms.NotifyIcon();
myIcon.Icon = someFancyIcon;
myIcon.Visible = true;
On the xaml I have defined the Window attribute Closing="Window_Closing" so that when the window is closed it calls:
private void Window_Closing(object sender, System.ComponentModel.CancelEventArgs e)
{
Log.Info("Closing application");
myIcon.Icon = null;
Environment.Exit(0);
}
If I ran the application and close it in the normal way, Window_Closing is called and the notification icon disappears as expected (and info is output to the log).
Problem is: this application is monitored by another process (out of my control), and that other process sometimes kills the WPF application process so that Window_Closing is never called and my application notification icon keeps on lingering on the notification area until you hover your mouse over it. Since the monitoring process can restart my application and close it again several times, the notification area is soon filled with copies of the notification icon.
How can I remove the notification icon so that even if my application is finished in some abnormal way the icon disappears?
In common case, you can't do that due how Windows Tray is designed. All the tray icons are driven by their apps: they're created by and removed by the corresponding app who owns that icon(s).
If the app is terminated abnormally the tray has no clue about that. The only case is to move mouse pointer over the orphaned icon and then it will be removed from tray as no corresponding app found alive.
What can we do then? Do not kill the app. Instead, send it a message causing it to close (so, all handlers would be called then and all resources are to be freed, including tray icons as well).

Launch a custom screensaver + lock machine

In my application I'd like to accomplish 2 things when a user wants to take a break and clicks a log out button.
Lock the machine
Launch a custom screen saver that would show the time the user is logged out.
I managed to do the lock easily by:
[DllImport("user32.dll")]
private static extern void LockWorkStation();
I found a tutorial on how to make a custom screen saver. I downloaded the sample code and it worked fine. But when I added the LockWorkStation(); line it killed the screen saver.
Can you help me with this or suggest a workaround?
EDIT
This screen saver from tutorial is just w WinForm. Should I somehow install it to the system? Is it possible form my application level?
The solution most likely is the following:
Lock the workstation
Show the screensaver
For the second step, the following is important:
You application is simply a program showing a window. As such any windows it tries to show are not shown to the user when the workstation is locked.
Your window will only be shown when you register your program as a real screensaver, set it as the current screensaver and than start it, for example using the SC_SCREENSAVE message.

Wait for third party application window to load

I'm trying to create a C#.NET 2.0 script to automate a workflow in a third party application written in Java.
I’m using the user32.dll functions to be able to interact with the Java app windows.
My problem is that the Java app windows are slow to completely load and my action sent through IntPtr SendMessage(IntPtr hWnd, UInt32 Msg, UInt32 wParam, IntPtr lParam) sometimes are lost. Example: during the load of the main window, if I try to open a menu (at this moment I actually have a handle on the main window), my message just is lost and the menu never opens.
I found some answers on Stack Overflow telling that we could use the Process.WaitForInputIdle() method for that purpose but I discovered that this only works if the app is mono threaded which is not the case of my Java app. ( C# SendKeys Wait for Program to Load before sending )
I'm looking for something working the same idea but that supports multithread or any other idea you could have?!: )
Following the Mari9' idea I finally used the System.Diagnostic.PerformanceCounter() to watch the third party app process activity. Then it commes to 0, it means the process has done what it had to do and is able to execute the message I send it.
PerformanceCounter PC = new PerformanceCounter();
PC.CategoryName = "Process";
PC.CounterName = "% Processor Time";
PC.InstanceName = "<process name>";
Console.WriteLine(PC.NextValue().ToString());
I assume you have a way of detecting when the window you want to send input to is shown on screen, but sending input immediately does not work since the window is busy.
You could have a predefined/hardcoded wait interval (possibly customized for each Java window) - this is not very reliable, but may work well in a controlled environment (for instance if the app is used only on your computer).
If the appearance of the window changes reliably when loading is complete, you might capture a screenshot of the window and test to see if the right pixels are there, and repeat this until true before sending the message.
Another option is using Spy++ to see if any particular message is generated for a window when the loading is complete (eg. could be a repaint with certain parameters) and install a hook to detect those messages.
If the Java application uses native window controls (SWT), you could try to detect changes in the window texts/structure indicating that the load is complete.
If the window loading process is resource intensive you might also monitor the CPU usage of the java app, and wait for the end of the 'peak' before sending your message.

child controls disappear when running already running app

bit of a strange one... when my app is running I add a custom control to a StackPanel on the click of a button like so...
void btnAddPlayer_Click(object sender, EventArgs e)
{
PlayerControl sbItem = new PlayerControl();
ctlPanel.Children.Add(sbItem);
}
(ctlPanel is a StackPanel PlayerControl is a standard Control inherited from UserControl)
So I add one or two, not a problem... if I multi-task on the phone to a different app, then multi-task back to my app, not a problem... however, if I multi-task away (or hit the windows phone button) and then instead of multi-tasking back, I just click on the icon (as if Im running the app again) it reloads my app but without any PlayerControl's in the StackPanel ... and while debugging, it doesnt hit the InitializeComponents() method in the pages constructor (of course this could be because it might not debug it when you run it straight from the menu)
Anyone know if theres a way to only allow an app to be run once (and dont restart it if the user runs the app again)????
It does not work that way. You can save the "state" of your app and load that when you start the application. Look at "Tombstoning" for windows phones. Example, you can save in the local storage the current screen id and any other necessary data and when you launch the app, if you have something in local storage you load that screen, else you start with your homepage.

Stick application to the Desktop on Vista

I have an application that I want to stick to the desktop. Stick to the desktop means that every time that someone click windows+D or the show desktop icon the desktop will appear with the application on it.
The user can locate the application on the desktop and change the location at any time but it always remains on the desktop.
We manage to do it on XP by setting the application’s parent to be the desktop using the winAPI methods SetParent (this .Handle, FindWindow ( "Progman " , null ));.
On Vista we manage to stick it to the desktop, whenever the desktop gets focus, it draws a gray background around we window. this background doesn't disappear when my window is moved, leaving ugly squares on the desktop. when I click Windows+D they all vanish.
Note that this doesn't happen on XP at all.
The client is based on .NET 3.0 and WPF .
Any idea why it happens and how to solve it?
use the following code and pass the window handle to the function while form load hope fully this resolves your problem
public void SetFormOnDesktop(IntPtr hwnd) {
IntPtr hwndf = hwnd;
IntPtr hwndParent = FindWindow("ProgMan", null);
SetParent(hwndf, hwndParent);
}

Categories

Resources