Application Foreground "Timeout"

G

Guest

I have a kiosk-type Pocket PC app which has a problem of moving to the
background after the device has been powered down with the power button. For
short durations of minutes to an hour or two, the app is in the foreground.
This only occurs after the device has been off for a relatively long time.
(e.g. powered off overnight).

I'm sure the app is still running because pressing a programmed HotKey
causes the top portion of my app to appear over the title bar. And then
tapping that exposed area of my app's screen restores the rest of the app to
full view.

I've tried using the BringToTop()/SetWindowPos()/ShowWindow() API commands
in the form's GotFocus event to no avail. (In VB6, this code keeps the
window on top no matter what; similar to a MsgBox with vbSystemModal.)

I suspect that it is not my app that goes to the background but rather
something in the OS that forces the Start screen to the foreground.

This application is used in scientific experiments. In a controlled lab,
this might not be such a problem. However, the app, being PDA-based, is also
used outside of a lab. Therefore it is imperative that the app never go to
the background. (To prevent subjects from running down the battery, and
inadvertent or intentional deletion of the app & its data; and to some
extent, give the appearance of a dedicated device which helps dissaude theft.)

Thanks in advance for any help!

shapij
 
G

Guest

Thanks Alex. The blog doesn't help since something would have to invoke my
app. But the timer idea just might work and may be the quick & dirty way out.

The inelegance of a timer doesn't have much appeal though. I'll bet there
is a better answer. And in the meantime, I'm still working on it.

Thanks again.
 
A

Alex Feinman [MVP]

Actually what I meant is you sending that message to yourself. This is the
best way that I know of to bring the app to the foreground
 
G

Guest

I understood that much. It's the timer that's inelegant, not the message.
Luckily, the screen in my app where this would be a problem doesn't do any
computations when it's idle, so a timer might work. (I haven't implemented a
timer yet.)

Anyway, I did another test of this phenomena that confirmed my suspicions.
I launched my app from the "Programs" screen and powered the device off.
Eighteen hours later, I pressed the power button and, in ***rapid***
sequence, I saw (1) my app, (2) the Programs screen, and then (3) the Home
screen came to the foreground. So, my conclusion is that my app doesn't go
to the background, but rather, the Home screen is forced to the foreground by
the OS. THIS is the behavior I'd like to change.

My guess is that there's either a registry setting that contains a timeout
value or one that points to the Home screen for a built-in (ROM based)
timeout.

This is very hard to troubleshoot since it takes hours of waiting to check
for one code change.

Thanks for your help.
 
G

Guest

Well, it's been a long hard slog and I believe I've formulated a solution to
this problem.

First, I tried sending a message using a timer and it had the partial effect
of doing what pressing one of my programmed HotKeys did. That is:

"I'm sure the app is still running because pressing a programmed HotKey
causes the top portion of my app to appear over the title bar. And then
tapping that exposed area of my app's screen restores the rest of the app to
full view." (Quoted from my initial post of this thread.)

However, this was exactly the same! as my desperation try of using
Me.BringToFront in my new timer routine. (Which was one line of code vs.
approximately 30 lines.)

Here's what DID work. I finally figured out that an API call using "user32"
wouldn't work. I needed to change that to "CoreDLL.dll".

FIRST THE CLASS
============================================
Public Class WinMgt
'Windows Positioning & Control Support.
'...API Declarations.
Private Declare Function ShowWindow Lib "CoreDll.dll" (ByVal hWnd As
Integer, ByVal nCmdShow As Integer) As Integer
Private Declare Function SetWindowPos Lib "CoreDll.dll" (ByVal hWnd
As Integer, ByVal hWndInsertAfter As Integer, ByVal x As Integer, ByVal y As
Integer, ByVal cx As Integer, ByVal cy As Integer, ByVal wFlags As Integer)
As Integer
Private Declare Function BringWindowToTop Lib "CoreDll.dll" (ByVal
hWnd As Integer) As Integer
Private Declare Function SetForegroundWindow Lib "CoreDll.dll"
(ByVal hWnd As Integer) As Boolean
'...Constant Declarations.
'ShowWindow
Public Enum WindowState
SW_SHOWNORMAL = 1
SW_SHOWMINIMIZED = 2
SW_SHOWMAXIMIZED = 3
End Enum
'SetWindowPos
Private Const SWP_NOSIZE As Int32 = &H1
Private Const SWP_NOMOVE As Int32 = &H2
Private Const SWP_HIDEWINDOW As Int32 = &H80
Private Const SWP_SHOWWINDOW As Int32 = &H40
Private Const SWP_NOACTIVATE As Int32 = &H10
Public Enum WindowPos
vbTopMost = -1&
vbNotTopMost = -2&
End Enum
Public Sub BringToTop(ByVal hWnd As Integer, Optional ByVal Position
As WindowPos = WindowPos.vbNotTopMost)
On Error Resume Next
SetWinPosition(hWnd, WindowPos.vbTopMost)
BringWindowToTop(hWnd)
SetWinPosition(hWnd, Position)
ShowWindow(hWnd, WindowState.SW_SHOWMAXIMIZED)
SetForegroundWindow(hWnd)
End Sub

Private Sub SetWinPosition(ByVal hWnd As Integer, ByVal Position As
WindowPos, Optional ByVal fHideWindow As Boolean = False)
Const wFlagsShow As Integer = SWP_NOMOVE Or SWP_NOSIZE Or
SWP_SHOWWINDOW Or SWP_NOACTIVATE
Const wFlagsHide As Integer = SWP_NOMOVE Or SWP_NOSIZE Or
SWP_HIDEWINDOW Or SWP_NOACTIVATE
If Position = WindowPos.vbTopMost Or Position =
WindowPos.vbNotTopMost Then
If fHideWindow Then
SetWindowPos(hWnd, Position, 0, 0, 0, 0, wFlagsHide)
Else
SetWindowPos(hWnd, Position, 0, 0, 0, 0, wFlagsShow)
End If
End If
End Sub

End Class 'WinMgt
====================================

NOW THE FORM CODE
====================================
Private win As New Corware.WinMgt
Private time As New Timer

Private Sub InitializeTimer()
AddHandler time.Tick, AddressOf TimeTick
time.Interval = 1
time.Enabled() = True
End Sub

Private Sub TimeTick(ByVal sender As Object, ByVal e As EventArgs)
win.BringToTop(Me.hWnd.ToInt32, Corware.WinMgt.WindowPos.vbTopMost)
End Sub

Private ReadOnly Property hWnd() As IntPtr
Get
Dim hwd As IntPtr
Capture = True
hwd = GetCapture()
Capture = False
Return hwd
End Get
End Property

Private Sub frmLogin_Load(ByVal sender As System.Object, ByVal e As
System.EventArgs) Handles MyBase.Load
' Take over the screen.
Me.WindowState = FormWindowState.Maximized ' Hide the Taskbar.
InitializeTimer()
End Sub
====================================

I had to remark out my HotKeys programming to get another -- native -- app
to the top and leave my app running. That's how I could tell that my
form/window was being forced to the top when the timer fired. Now it's time
to do the actual test of powering off the device overnight and see if the
power-on results in the Pocket PC's Start screen quickly (1 ms) disappearing
from view with my app on top. I'm definitely crossing my fingers!
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Similar Threads


Top