[AccessD] Hiding the Access Window WAS: access xp runtime

DWUTKA at marlow.com DWUTKA at marlow.com
Thu Dec 22 23:28:43 CST 2005


Yes, there is something new in my code.

Here's an example I setup for you:  http://www.marlow.com/HiddenAccess2k.zip
<http://www.marlow.com/HiddenAccess2k.zip> 

What's different in this setup, then what was out there before?  Well, in
Access 97, you could hide the Access window with normal API's, and all you
had to do was set the popup property of your forms to True (or yes) and they
would display on the desktop, with no problem.

In Access 2000 (and later), due to the change in how Access played with the
windows that 'host' the Access forms, you also had to set the Dialog
property to True (or yes).  That really goofed things up.  And that is
probably also the cause of what you are describing, where you had problems
giving focus to other forms.  (I bet the Dialog process was locking code on
the original form).

Anyhow, Susan and I co-wrote an article about putting an Access Form 'always
on top', so that the form stays above all other windows on your desktop.
Microsoft has code on the knowledge base to do this, but it uses the forms
timer to continuously put the form at the top of the ZOrder (That's the
placement order of the windows on your desktop.  Certain key values can do
different things.  There is one for 'Always On Top' (like the window
Taskmanager window)).  The reason that the Microsoft article used a timer,
is because Access forms are not true windows.  They are windows, in a sense,
but they are subclassed, and if you ever get into the window 'properties'
behind them, you'll wonder if the Access Development Team were smoking crack
at the time! ;)  Just kidding, most of what they did was to make life easier
in the VBA environment, and to deal with Accesses handy features like
'subforms'.  I may have lost you a bit on that, so let me give you a quick
explanation and example.  A window in Windows has an hWnd value, which is
the unique identifier for each window on your system.  You can do all sorts
of things to a window in Windows with API calls, but to do so, you need that
windows 'hWnd' value to tell Windows what window you want to mess with.
Along with an hWnd, windows also have other properties, such as dimensions,
ZOrder
, Text, children, class.  The window class is pretty important, because the
hWnd value is randomly assigned, so opening the same window two times in a
row is not going to give you the same hWnd.  However, the same window should
have the same class (unless you're manually creating a window with a
'random' window class).  An example of this is Access itself.  The main
Access window has a window class of 'oMain'.  I wrote a utility a long time
ago, which unhides all Access windows on your machine, it does this by
'showing' all windows with a class of 'oMain'.  (It was handy, because when
I was first messing with this kind of stuff in Access, every once in while I
would goof, and close all the forms, leaving a 'hidden' access session in
the background, and I'd have to use the taskmanager to kill it.  With my
utility, I could just unhide it.....of course, lessons learned also lead to
just putting 'cautionary' code into the app, so when all forms were closed,
the Access window was either shown, or Access was shutdown normally).  

Back to why Access forms are goofy.  Let's take an input box, one created by
the InputBox() command.  That is a normal window. If you 'peek' at the
window and it's children, you'll find that the main window text is the
'caption' of the window.  The 'dialog' is a label class window, and it's
text is the message displayed (what you put into the prompt argument).  The
Ok and Cancel buttons are also 'windows', their text being 'Ok' and 'Cancel'
respectively.  The textbox you are entering data into is also a window, and
when you capture it's text, it'll be the data you are entering into it.  So
you could programmatically, just using API's, capture that window.  I wrote
a program (which we use at work), which does just that.  We have a computer
called WolfWeb, that runs a multithreaded VB application.  Our Intranet
webserver (MINet) has a few webpages which allow our external users to view
reports in some of our larger 'report heavy' databases.  Those reports use
dialog boxes (I didn't write them, the original developers used expressions
like [Enter PO Number of * for all]), which pause any code opening the
reports tied to those queries.  What the program on the WolfWeb computer
does, is when someone requests a report from the Intranet machine, that
machine tells the WolfWeb what report to run (through named pipes).  The
WolfWeb then starts two threads.  One thread runs the report, the other
thread watches for dialog windows in that Access application. (because as
soon as the first thread hits a dialog box, it's paused).  When a dialog box
appears, that second thread 'records' all of the information about it (and
it's children (buttons, labels, etc)) and sends that information back to the
Intranet (through the named pipes), which then recreate that window in HTML
for the user to interact with it.  In essence, it's a terminal server.  The
difference is, that since it is specifically designed for that application,
it's a FAST terminal server.  (Kind of like Remote Desktop, which displays
some things faster then others, because it 'cheats' by sending text, instead
of images of text....text is faster).  Anyhow, I built that years ago, and
was actually planning on selling it as a 'remote Access' application, but I
ran into one heck of a snag.  Dialog windows worked great, and it didn't
even have to be an Expression, it also worked with ODBC logon boxes and
message boxes.  But Access forms don't work the same way.  When you look at
an Access form, you have the main window (which is pretty much accurate to
the forms main window properties), but then there are a set number of child
windows (something like 3 or 4).  No matter how many controls are on that
form.  What Access does, is one of those child windows is the control that
has the focus.  NONE of the other controls are windows (and thus are
'invisible' to window APIs).  The only way I could get around that would be
to capture the form through automation, which I just never got around to
doing, I had other things on my plate at the time.

Microsoft's 'solution' to putting a form 'always on top' just plain sucks,
who wants a timer firing all the time, just to keep a window on top.  Our
article stemmed from a post Susan wrote, asking about doing this, because
she wanted an easier way to copy and paste information from the web, without
having to switch between windows all the time.  I took it up as a challenge,
and discovered a few more 'undocumented' things about how Access forms are
subclassed windows.  You can't set their ZOrder to be always on top, but you
CAN set Access's ZOrder to always be on top.  But that doesn't wouldn't do a
lot of good.  In Susan's dilemma, she would have had to resize the Access
window, so that it was the size of the form she needed.  But, with how the
forms are subclassed, they inherit the always on top 'property', and so if
you hide the Access window, you now have an Access form, on the desktop, and
it's 'Always On Top'.

In working with this, I ran into the old 'Access 2k needs the Dialog
property set' problem, and I took a WAG and tried something new.  I left
that property off, and instead, had the form call the ShowWindow API on
itself.  That worked.  Access was hidden, and the form was now on the
desktop...though it was 'empty' (nothing within the border).  A simply
Repaint method was all that was needed to fix that.

So, in the sample database I posted, you will see that there are three
forms. FrmMain, frmOne and frmTwo.  FrmMain will start with the database,
and has two buttons (to open frmOne and frmTwo).  The code to hide the
Access window is behind frmMain.  There is identical code behind frmOne and
frmTwo (two lines, in the form's OnLoad event). (Also, there is a module in
that database, which contains the API declarations (two of them), and two
public constants).  That's it, it's pretty simple.  Like I mentioned in the
early post, the only 'trick' with hiding the Access window is previewing
reports.  If you need to preview a report, you have to show the Access
window.

Drew




	-----Original Message-----
	From:	William Hindman [SMTP:wdhindman at bellsouth.net]
	Sent:	Thursday, December 22, 2005 10:31 PM
	To:	Access Developers discussion and problem solving
	Subject:	Re: [AccessD] access xp runtime

	...unless there is something new in your code Drew, you can open
another 
	form but you can't give it focus ...i.e. you can't click between
forms ...if 
	that's not true with your code I'll take another look because I'd
certainly 
	love to use it ...but I sure wasted a lot of effort with this
approach once 
	before ...its why I was experimenting using subforms on a single
main form 
	in order to beat the always-on-top problem.

	William

	----- Original Message ----- 
	From: <DWUTKA at marlow.com>
	To: <accessd at databaseadvisors.com>
	Sent: Thursday, December 22, 2005 10:55 PM
	Subject: Re: [AccessD] access xp runtime


	> What are you talking about?  With the Access window hidden, you
can open 
	> as
	> many forms as you want, just set their popup property to Yes.  (My
code 
	> gets
	> around having to set the dialog property to yes in A2k and up
too....).
	>
	> The only drawback, from what I remember (because honestly, I don't
use 
	> this
	> in Access anymore, if I want a 'desktop' app, I just use VB), is
that
	> reports won't preview, so you have to unhide the Access Window to
preview
	> reports.
	>
	> Drew
	>
	> -----Original Message-----
	> From: William Hindman [SMTP:wdhindman at bellsouth.net]
	> Sent: Thursday, December 22, 2005 9:44 PM
	> To: Access Developers discussion and problem solving
	> Subject: Re: [AccessD] access xp runtime
	>
	> ...the problem with that API is that it only works for forms on
top
	> ...you
	> can't open another form ...pop up a calendar for instance ...I got
	> heavy
	> into an experimental app with this approach before abandoning it
	> ...too many
	> compromises.
	>
	> William
	>
	> ----- Original Message ----- 
	> From: <DWUTKA at marlow.com>
	> To: <accessd at databaseadvisors.com>
	> Sent: Thursday, December 22, 2005 8:53 PM
	> Subject: Re: [AccessD] access xp runtime
	>
	>
	> > This is code I put on an 'Always On Top' form which also hides
the
	> Access
	> > window:
	> >
	> > Option Compare Database
	> > Option Explicit
	> > Private Declare Function SetWindowPos Lib "user32" (ByVal hwnd
As
	> Long, _
	> > ByVal hWndInsertAfter As Long, ByVal x As Long, ByVal y As Long,
	> ByVal _
	> > cx As Long, ByVal cy As Long, ByVal wFlags As Long) As Long
	> > Private Declare Function IsWindowVisible Lib "user32" (ByVal
hwnd
	> As Long)
	> > As Long
	> > Private Declare Function ShowWindow Lib "user32" (ByVal hwnd As
	> Long, _
	> > ByVal nCmdShow As Long) As Long
	> > Const SW_HIDE = 0
	> > Private Const SW_SHOW = 5
	> > Private Const SWP_NOMOVE = &H2
	> > Private Const SWP_NOSIZE = &H1
	> > Private Const HWND_TOPMOST = -1
	> > Private Const HWND_NOTOPMOST = -2
	> >
	> > Private Sub cmdAlwaysOnTop_Click()
	> > If IsWindowVisible(Application.hWndAccessApp) Then
	> >    ShowWindow Application.hWndAccessApp, SW_HIDE
	> >    SetWindowPos Application.hWndAccessApp, HWND_TOPMOST, 0, 0,
0,
	> 0, _
	> >    SWP_NOMOVE Or SWP_NOSIZE
	> >    ShowWindow Me.hwnd, SW_SHOW
	> >    Me.Repaint
	> > Else
	> >    ShowWindow Application.hWndAccessApp, SW_SHOW
	> >    SetWindowPos Application.hWndAccessApp, HWND_NOTOPMOST, 0, 0,
	> 0, 0, _
	> >    SWP_NOMOVE Or SWP_NOSIZE
	> > End If
	> > End Sub
	> > Private Sub Form_Unload(Cancel As Integer)
	> > If IsWindowVisible(Application.hWndAccessApp) = False Then
	> >    ShowWindow Application.hWndAccessApp, SW_SHOW
	> >    SetWindowPos Application.hWndAccessApp, HWND_NOTOPMOST, 0, 0,
	> 0, 0, _
	> >    SWP_NOMOVE Or SWP_NOSIZE
	> > End If
	> > End Sub
	> >
	> > -----Original Message-----
	> > From: Michael Maddison [mailto:michael at ddisolutions.com.au]
	> > Sent: Thursday, December 22, 2005 7:11 PM
	> > To: Access Developers discussion and problem solving
	> > Subject: Re: [AccessD] access xp runtime
	> >
	> >
	> > Hi David,
	> >
	> > I'm (almost) sure I saw some API code a couple of years ago that
	> > completely hid the Access parent container window.
	> > I can't find it on my pc but its out there somewhere ;-)
	> >
	> > cheers
	> >
	> > Michael Maddison
	> >
	> > DDI Solutions Pty Ltd
	> > michael at ddisolutions.com.au
	> > Bus: 0260400620
	> > Mob: 0412620497
	> > www.ddisolutions.com.au
	> >
	> > -----Original Message-----
	> > From: accessd-bounces at databaseadvisors.com
	> > [mailto:accessd-bounces at databaseadvisors.com] On Behalf Of David
&
	> > Joanne Gould
	> > Sent: Friday, 23 December 2005 11:23 AM
	> > To: Access Developers discussion and problem solving
	> > Subject: Re: [AccessD] access xp runtime
	> >
	> > My only plan for it is to hide the database window, put a
	> different icon
	> > on the titlebar. My client doesn't require menu bar or toolbars
	> (thank
	> > goodness). I'm hoping this will look like any other software in
a
	> box.
	> >
	> > David
	> >
	> > At 10:58 AM 23/12/2005, you wrote:
	> >>"wants his database to not look like an access database (no
	> problem)"
	> >>D&J
	> >>
	> >>...lol ...runtime is one thing ...I run them on several client
	> systems
	> >>...but I'd really, really like to know how you make an Access db
	> not
	> >>look like an Access db ...the only way you can hide the Access
	> window,
	> >>afaik, is using popups which severely limits your gui
	> ...alternatively
	> >>you can fill the window with your main form and call subforms to
	> do
	> >>most of your work, an appoach I quickly abandoned ...and even
then
	> the
	> >>user can still expose the Access window in a number of ways you
	> can't
	> > control.
	> >>
	> >>...building innovative guis is one thing ...but making it not
look
	> like
	> >
	> >>an Access db? ...I'm all ears?
	> >>
	> >>...btw, if you have the option I highly recommend upgrading your
	> >>development system to A2K3 and buying the VSTO.
	> >>
	> >>William
	> >>
	> >>----- Original Message -----
	> >>From: "David & Joanne Gould" <dajomigo at tpg.com.au>
	> >>To: <AccessD at databaseadvisors.com>
	> >>Sent: Thursday, December 22, 2005 4:28 PM
	> >>Subject: [AccessD] access xp runtime
	> >>
	> >>
	> >> >I have a client that wants his database to not look like an
	> access
	> >> >database  (no problem) and be usable by people who don't have
	> access
	> >> >on their  computers. My understanding is that this is possible
	> if the
	> >
	> >> >database is a  runtime version. Is there any way to do this
	> without
	> >> >buying office  developer XP. We are using access xp for the
	> database.
	> >> >
	> >> > David
	> >> >
	> >> >
	> >> > --
	> >> > AccessD mailing list
	> >> > AccessD at databaseadvisors.com
	> >> > http://databaseadvisors.com/mailman/listinfo/accessd
	> >> > Website: http://www.databaseadvisors.com
	> >> >
	> >>
	> >>
	> >>--
	> >>AccessD mailing list
	> >>AccessD at databaseadvisors.com
	> >>http://databaseadvisors.com/mailman/listinfo/accessd
	> >>Website: http://www.databaseadvisors.com
	> >
	> >
	> > --
	> > AccessD mailing list
	> > AccessD at databaseadvisors.com
	> > http://databaseadvisors.com/mailman/listinfo/accessd
	> > Website: http://www.databaseadvisors.com
	> > -- 
	> > AccessD mailing list
	> > AccessD at databaseadvisors.com
	> > http://databaseadvisors.com/mailman/listinfo/accessd
	> > Website: http://www.databaseadvisors.com
	> > -- 
	> > AccessD mailing list
	> > AccessD at databaseadvisors.com
	> > http://databaseadvisors.com/mailman/listinfo/accessd
	> > Website: http://www.databaseadvisors.com
	> >
	>
	>
	> -- 
	> AccessD mailing list
	> AccessD at databaseadvisors.com
	> http://databaseadvisors.com/mailman/listinfo/accessd
	> Website: http://www.databaseadvisors.com
	> -- 
	> AccessD mailing list
	> AccessD at databaseadvisors.com
	> http://databaseadvisors.com/mailman/listinfo/accessd
	> Website: http://www.databaseadvisors.com
	> 


	-- 
	AccessD mailing list
	AccessD at databaseadvisors.com
	http://databaseadvisors.com/mailman/listinfo/accessd
	Website: http://www.databaseadvisors.com



More information about the AccessD mailing list