Link to home
Start Free TrialLog in
Avatar of RetroRocker
RetroRocker

asked on

Terminate, minimize (or both) a .NET Compact Framework program ?

I know this is not a new issue and possibly even has a slightly contentious history but I'm pretty new to mobile device development, so ... what is considered the most acceptable/correct/appropriate way to 'close' a .NET CF program ?
OK, I know I can control minimize (X) and shutdown (Ok) behaviour with the main form's minimize property but is it good practice to perhaps offer a user the choice of minimizing or terminating their program ? Leading on from this could anyone offer suggestions as how best to achieve this ? presumably it woulld have to start with an 'exit' button in the program ...
Does anyone typically offer this sort of functionality or is it normally just left to the OS to determine whether it 'feels' it has too many minimized programs running and to start shutting them down ?

my thanks for your consideration

RR
Avatar of Mikal613
Mikal613
Flag of United States of America image

but is it good practice to perhaps offer a user the choice of minimizing or terminating their program ?

Usually people use some sort of task manager (i use htc) and there is an option if you want the clicking of the X to minimize or close.

I would like to see the option in the app. Even though most people close it to end it and not to minimize. But i would default to terminate.
Avatar of RetroRocker
RetroRocker

ASKER

Thanks Mikal for the opinion, the only one so far ... I too feel that the app. should offer the choice of either minimize or terminate. From research though it seems this debate has become the stuff of legend, what with the selection of (X) to minimize, (Ok) to terminate ... enough !
I have been looking into extending this topic by trying to find a way to programmatically mimic 'smart minimizing'. I know there are several articles around which have tried to cover this but it seems with limited success. I have tried 2 approaches based on these articles, both of which use "SetWindowPos" imported from coredll.dll and make the window 'sizeless' while sending it to the bottom of the Z order.
eg.
[DllImport("coredll.dll", EntryPoint = "SetWindowPos", SetLastError = true)]
private static extern bool SetWindowPos(IntPtr hWnd, IntPtr hWndInsertAfter, int X, int Y, int cx, int cy, uint uFlags);
private static readonly IntPtr HWND_TOPMOST = new IntPtr(-1);
private static readonly IntPtr HWND_NOTOPMOST = new IntPtr(-2);
private static readonly IntPtr HWND_TOP = new IntPtr(0);
private static readonly IntPtr HWND_BOTTOM = new IntPtr(1);
private const UInt32 SWP_NOSIZE = 0x0001;
private const UInt32 SWP_NOMOVE = 0x0002;
private const UInt32 SWP_NOZORDER = 0x0004;
private const UInt32 SWP_NOREDRAW = 0x0008;
private const UInt32 SWP_NOACTIVATE = 0x0010;
private const UInt32 SWP_FRAMECHANGED = 0x0020;
private const UInt32 SWP_SHOWWINDOW = 0x0040;
private const UInt32 SWP_HIDEWINDOW = 0x0080;
private const UInt32 SWP_NOCOPYBITS = 0x0100;
private const UInt32 SWP_NOOWNERZORDER = 0x0200;
private const UInt32 SWP_NOSENDCHANGING = 0x0400;

 a few unused constants here but I just copied/pasted the block :) Then call from inside a button click as follows ...

SetWindowPos(hWnd_mainform, HWND_BOTTOM, 0, 0, 0, 0, SWP_NOMOVE | SWP_NOSIZE | SWP_NOACTIVATE);

This is fine I think but the problem comes with retrieving the handle to the apps. main form for this function to use... I tried ...

[DllImport("coredll.dll", EntryPoint = "FindWindowW", SetLastError = true)]
private static extern IntPtr FindWindowW(string lpClassName, string lpWindowName);

IntPtr hWnd_mainform = FindWindowW("MainForm", null);

where "MainForm" obviously represents the main form's class name but this always returns zero ( as does calling FindWindow)

I also tried to get the mainform handle, using GetCapture/SetCapture which does get the handle, minimizes the window but leaves title bar of the form in situ waiting for a response. So nothing so far works correctly, just 'half successful'.

  It is fair to say that this whole exercise might be a bit academic but now I have come down this road it would be interesting to programmatically 'smart minimize'. Any further ideas please, anyone ?

thanks
Thanks again Mikal but unfortunately there was nothing new from that link in respect of 'smart minimize' behaviour. I have retested with ...

control.Capture = true;
IntPtr hwnd = Win32.GetCapture();
control.Capture = false;

but as stated before, this does minimize the window but leaves the title bar. (See penultimate paragraph of my previous post). It certainly does return the handle to the form but the minimizing behaviour is not acceptable, so I'm wondering whether this can actually be achieved.

RR
Its just one setting

 if you set the minimizeBox to false it will convert the "x" to a "ok", and when the ok is pressed the program really closes.

else its the oppposite
Ah yes, we've known this from the very beginning (see my opening post) but this is not what we are after.
  The question has been extended (as I said previously) to try and find a way to programmatically 'smart minimize'. As stated in my previous post, using GetCapture() to provide a handle to the form which can then be supplied to SetWindowPos works but only partially in that the title bar of the form remains. The objective is to try a sort out this 'partial minimizing'.
RR
If SWP_NOACTIVATE doesnt work then im also stuck
Unfortunately the last posted link is almost the same as for the code I posted earlier for "SetWindowPos". The 'persistent' title bar still remains. I'll leave this thread open a while longer in case any other ideas surface but it is starting to look like an effective 'smart minimize' using code is not possible.
thanks RR.
ASKER CERTIFIED SOLUTION
Avatar of Mikal613
Mikal613
Flag of United States of America image

Link to home
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Start Free Trial
Mikal : Yes, me too :)
I have spent far too many hours on this one but I hate being beaten. At the moment I'm thinking about P/Invoke PostMessage to perhaps send a WM_PAINT to the topmost window to wipe out the persistent title bar. I can't make it work though, perhaps it's a silly idea !  Any ideas genuinely appreciated.

thanks again RR
and frm.refresh?
I tried using this.Refresh(); after the call to SetWindowPos but this and Update() will not remove this stubborn title bar. SetWindowPos is perfectly effective at minimizing the CLIENT area of the form but I just can find no way of 'smart minimizing' the WHOLE form. I'm really stuck with this :( and still open to any ideas.

thanks again RR
I am still stuck with this 'persistent' title bar when attempting to 'smart minimize' in code. The client area of my form minimizes correctly but not the title bar. The title bar of my form only minimizes on tapping it, or on the newly exposed form at the top of the Z order. I am still genuinely interested in determining why this is so and how to deal with it ... anyone please ?

thanks
RR
Further to my previous comment, I have found an exceedingly half-baked solution to this issue. It takes the form of faking a screen tap (mouse_event). It is taken from the blog of Chris Tacke at OpenNETCF.org and he has to receive the credit (although I don't think he would want it !) for this quote "Mother of all kludges" ... agreed ! ... but desperate situations require desperate measures, don't they ? or please someone, help me to understand how it has got to be better than this !
CT's code for faking a tap, in the total absence of elegance, does of course work very well but of course if you hit anything on the form below ...
Comments, better suggestions anyone - please ...
RR
BTW, the link for Chris Tacke's blog as mentioned in the previous post is ...

http://blog.opennetcf.org/ctacke/CategoryView,category,.NET Compact Framework.aspx
I am totally into that idea. I have attempted that "hack" at somehing else where i wanted to open the start menu from one of my soft keys on Mobile 5.0 so i sent a mouse down to coordinates 0,0 (upper left cprner). In you situation  you will have to take effect if the screen has been rotated. 0,240 if its regular and 0,320 else
OK but as I said earlier, I'm pretty new to .NET CF and I didn't realise that the title bar has a different handle to the client area of the form. It would be a lot more elegant to get the title bar handle (HHTaskBar) and minimize it in the same way as the form client area using 'SetWindowPos' but this has failed. The taskbar seems to be a separate entity in .NET CF whereas I have been regarding it as a simple form title bar. The element of 'fixture' or permanence of the taskbar makes me think that it cannot be treated like a form client area and the 'kludge' is the only way to go. If no one else has anything to offer, I guess we will have to leave it there. What do you think ?
thanks RR
so whats wrong with sending the mouse_click to the X?
Well nothing really, except there isn't going to be an X because it's an Ok. The point of the minimize with code was to give the user the option of Ok (to shutdown program) or a button to 'smart' minimize using code. I know X is the traditional (and Microsoft) way to go with the OS shutting down apps if it needs to but hey ... who wants to be eternally traditional :)
I guess there is going to be no actual conclusion to this. 'Smart minimizing' in code doesn't appear to be an option ... it was just interesting to see if anyone knew how to achieve it (completely). I'm closing down this thread - Mikal613 you get the points for sheer effort, thanks.
RR