Access 2010 Hiding the Access Window - window

I want to permanently hide the access window. I have a auto exe macro that hides the window initially but if the user ever clicks my database's icon on the task bar if appears behind my forms and is just rather annoying. I was wondering if there was a way to keep it down without having to copy past a hide window macro every where

The following will work on older versions of access (source: http://www.vbaexpress.com/kb/getarticle.php?kb_id=74):
Option Compare Database
Option Explicit
Global Const SW_HIDE = 0
Global Const SW_SHOWNORMAL = 1
Global Const SW_SHOWMINIMIZED = 2
Global Const SW_SHOWMAXIMIZED = 3
Private Declare Function apiShowWindow Lib "user32" _
Alias "ShowWindow" (ByVal hWnd As Long, _
ByVal nCmdShow As Long) As Long
Function fSetAccessWindow(nCmdShow As Long)
Dim loX As Long
Dim loForm As Form
On Error Resume Next
Set loForm = Screen.ActiveForm
If Err <> 0 Then
loX = apiShowWindow(hWndAccessApp, nCmdShow)
Err.Clear
End If
If nCmdShow = SW_SHOWMINIMIZED And loForm.Modal = True Then
MsgBox "Cannot minimize Access with " _
& (loForm.Caption + " ") _
& "form on screen"
ElseIf nCmdShow = SW_HIDE And loForm.PopUp <> True Then
MsgBox "Cannot hide Access with " _
& (loForm.Caption + " ") _
& "form on screen"
Else
loX = apiShowWindow(hWndAccessApp, nCmdShow)
End If
fSetAccessWindow = (loX <> 0)
End Function
Just call fSetAccessWindow(0) to hide and fSetAccessWindow(1) to show. Alternatively, you could use fSetAccessWindow(2) and fSetAccessWindow(3) to show minimized/maximized. The application will be hidden from the taskbar too, preventing users from clicking it.
If it doesn't work with Access 2010, you could also try this: http://www.tek-tips.com/faqs.cfm?fid=2562

Related

How to bring the application to the front?

Currently copied and modifying a portion of a coding within the same program to create a button that when clicked will bring the Vision application to the front of the GUI.
Created a button called "btVisionCam_Click()"
Declared "Private lVideo As Long"
CEIVidCap is the Vision application that is running behind of the GUI when the GUI is opened
Private Sub btVisionCam_Click()
If btVisionCam.Value = 1 Then
lVideo = FindWindow(vbNullString, "CEIVidCap")
If lVideo = 0 Then
lVideo = Shell("C:\machine\appls\CEIVidCap.exe", vbNormalFocus)
End If
End If
End Sub
When the button is clicked, it does not bring the Vision application to the front of the GUI. Please help, thanks!
Create a module and copy the following declarations:
Declare Function FindWindow Lib "user32" Alias "FindWindowA" (ByVal lpClassName As String, ByVal lpWindowName As String) As Long
Declare Function ShowWindow Lib "user32" (ByVal hwnd As Long, ByVal nCmdShow As Long) As Long
Then in your button, as you are already doing, use FindWindow to get the window handle and use ShowWindow to bring it up:
Dim lnghWnd As Long
lnghWnd = FindWindow(vbNullString, "CEIVidCap")
ShowWindow lnghWnd, 1
Supported values for nCmdShow parameter of ShowWindow:
SW_HIDE = 0
Hide the window.
SW_MAXIMIZE = 3
Maximize the window.
SW_MINIMIZE = 6
Minimize the window.
SW_RESTORE = 9
Restore the window (not maximized nor minimized).
SW_SHOW = 5
Show the window.
SW_SHOWMAXIMIZED = 3
Show the window maximized.
SW_SHOWMINIMIZED = 2
Show the window minimized.
SW_SHOWMINNOACTIVE = 7
Show the window minimized but do not activate it.
SW_SHOWNA = 8
Show the window in its current state but do not activate it.
SW_SHOWNOACTIVATE = 4
Show the window in its most recent size and position but do not activate it.
SW_SHOWNORMAL = 1
Show the window and activate it (as usual).
Try setting it as the foreground window.
Add this to your other API calls:
Declare Function Win32_SetForegroundWindow Lib "user32" _
Alias "SetForegroundWindow" ( _
ByVal hWnd As Long) _
As Long
Then add:
Dim Ret As Long
Ret = Win32_SetForegroundWindow(lnghWnd)
If Ret Then
' Your window should be foreground
End If

Form type "file" default folder

I have a webform displayed in a WebBrowser control in a Visual Basic application to allow users to upload files to my webserver. Unusually for this type of thing, I know in advance the folder they need to browse to (I want them to upload a file which the VB application has generated) and I would like the Browse dialog box to default to that folder but it seems to default to whichever folder was last used by any application for File / Open.
I've tried using ChDir in VB to set the current folder but that doesn't work.
Is there any way I can persuade the Browse box to default to my desired folder?
First of all, I ought to state that there is no reliable way of doing this. The reason why it is so hard is for security reasons. There is a defaultValue and value property for the INPUT TYPE=FILE element, but if programmers had access to this, this could be used to suck files from the client machine - definitely not a good idea.
In Internet Explorer, the browse file dialogue is actually implemented by a Windows Common Dialog component. However, you have no direct access to this component.
There is no reliable browser-independent way of doing this. And I certainly don't recommend you reverse-engineer the "Last Recently Used" file list for the Common Dialog control (see jac's link). Doing that is very dangerous, since it is an internal-algorithm likely to change. And worse, you are hacking global state to solve a local problem (see Old New Thing blog, ad nauseam).
A solution that doesn't violate global state, but still hacky is to take advantage of the fact we know what the text is on the file upload dialogue. After your document has loaded, you can use a Timer to wait for the dialogue to appear, and at that point, paste the correct directory into the dialogue.
In my sample, I have code where the web browser control sits, and the BrowserHack.bas module.
Form code:
Option Explicit
Private Sub cmdLoadPage_Click()
' Store the default path into the .Tag property.
tmrWaitForDialogue.Tag = "C:\Windows\System32"
' Load URL.
wbMain.Navigate "<URL>"
End Sub
Private Sub Form_Load()
tmrWaitForDialogue.Enabled = False
tmrWaitForDialogue.Interval = 100 ' 10th of a second delay.
End Sub
Private Sub tmrWaitForDialogue_Timer()
If BrowserHack.IsBrowserFileDialogueVisible Then
' We don't want the Timer to fire again.
tmrWaitForDialogue.Enabled = False
' Copy the directory onto the clipboard.
Clipboard.Clear
Clipboard.SetText tmrWaitForDialogue.Tag
' The focus will be on the file path text box in the Open dialogue.
' Use CTL-V to paste the text, and then followed by an Enter character to
' dismiss the dropdown, and another to Open the folder.
SendKeys "^V"
SendKeys "{ENTER}"
SendKeys "{ENTER}"
End If
End Sub
Private Sub wbMain_DocumentComplete(ByVal pDisp As Object, URL As Variant)
tmrWaitForDialogue.Enabled = True
End Sub
BrowserHack:
' Purpose: Code to look for the WebBrowser (Internet Explorer) dialogue which appears when a File Upload control is clicked.
' Notes: Internet Explorer version dependent.
Option Explicit
Private Declare Function EnumThreadWindows Lib "User32.dll" ( _
ByVal dwThreadId As Long, _
ByVal lpfn As Long, _
ByVal lParam As Long _
) As Long
Private Declare Function GetClassName Lib "User32.dll" Alias "GetClassNameW" (ByVal hWnd As Long, ByVal lpClassName As Long, ByVal nMaxCount As Long) As Long
Private Declare Function GetWindowText Lib "User32.dll" Alias "GetWindowTextW" (ByVal hWnd As Long, ByVal lpString As Long, ByVal nMaxCount As Long) As Long
Private Declare Function IsWindowVisible Lib "User32.dll" (ByVal hWnd As Long) As Long
Private Const APITRUE As Long = 1 ' Win32 API TRUE value
Private Const APIFALSE As Long = 0 ' Win32 API FALSE value
' This dialogue class is pretty universal.
Private Const m_ksDialogueClass As String = "#32770"
Private Const m_knDialogueClassLen As Long = 6
' This text may well change every time the browser is updated.
Private Const m_ksDialogueText As String = "Choose File to Upload"
Private Const m_knDialogueTextLen As Long = 21
' Buffers to be used for these strings.
Private m_sClassNameBuffer As String
Private m_sWindowNameBuffer As String
' Callback from the EnumThreadWindow() function.
Private Function EnumThreadWndProc( _
ByVal hWnd As Long, _
ByVal lParam As Long _
) As Long
Dim nRet As Long
' Filter out hidden windows.
If IsWindowVisible(hWnd) = APITRUE Then
' Retrieve the class name of the window.
' Note that this function requires you to allocate a buffer *including* the terminating null character.
' Since VB strings *always* are null terminated, we can add one to the string length.
nRet = GetClassName(hWnd, StrPtr(m_sClassNameBuffer), (m_knDialogueClassLen + 1))
' If the classes match, then try for a match on the window's text.
If m_sClassNameBuffer = m_ksDialogueClass Then
' Ditto GetClassName().
nRet = GetWindowText(hWnd, StrPtr(m_sWindowNameBuffer), (m_knDialogueTextLen + 1))
If m_sWindowNameBuffer = m_ksDialogueText Then
' This return value says "stop the enumeration".
' In this case EnumThreadWindow() with also return APIFALSE.
EnumThreadWndProc = APIFALSE
Exit Function
End If
End If
End If
EnumThreadWndProc = APITRUE
End Function
' Purpose: If the browser window is detected
Public Function IsBrowserFileDialogueVisible() As Boolean
' If this is the first time this function has been called, the buffers will not be allocated.
' Do this now.
If LenB(m_sClassNameBuffer) = 0 Then
m_sClassNameBuffer = Space$(m_knDialogueClassLen)
m_sWindowNameBuffer = Space$(m_knDialogueTextLen)
End If
' Enumerate through all windows on this thread. VB apps are single-threaded, and all GUI elements are forced to be on this thread, so this is ok.
If EnumThreadWindows(App.ThreadID, AddressOf EnumThreadWndProc, 0&) = APIFALSE Then
IsBrowserFileDialogueVisible = True
Else
IsBrowserFileDialogueVisible = False
End If
End Function

Process monitor / dispatcher in VB6

I need to write a little application in VB6 to run instances of another VB6 application and keep an eye on the running processes, but I don't have any idea how to get process information in VB6. I can see some of what I need with the tasklist utility but I don't really know how create processes (specifying the process or application name if possible) and fetching information about processes from the operating system.
This application is to run on a Windows XP machine.
Does anyone know of a get-you-started tutorial or helpful web page for this sort of thing?
There are numerous Windows API functions you can use to do this. I'd start with looking at EnumProcesses (VB6 example and declaration here) which can be used to gather information about all running processes. You can also use OpenProcess
to start interrogating Windows about a particular process (another VB6 example).
There is also a fairly nice example on MSDN.
And of course, there is CreateProcess (AllApi link) or ShellExecute (AllApi) for spawning processes - the former gives you more control over the creation of the process, while the latter is a much simpler call.
There was another question posted about this a while back with some example code.
Another possible approach would be to use WMI (some useful snippets to adapt).
Finally, here are some tutorials that show you how to do it (I'd recommend trying it yourself first though :):
Getting Process Information using PSAPI
Another EnumProcesses/OpenProcess implementation
WMI-based demonstration
Here are some related questions although you probably already saw them when you searched this site before posting:
Monitoring processes to see if they've crashed in vb6
How can I execute a .bat file but wait until its done running before moving on?
How To Enumerate Processes From VB 6 on Win 2003?
Since you say the other application is ** also VB6**, it would be easier to make the other application into an ActiveX exe. Then you can get references to objects in the other application direct from your first application. COM solves it all for you.
Here's Microsoft's tutorial on the subject - you can download the code too.
Or here's another answer where I've written about this
You don't need to go spelunking for processes just to get a handle to child processes that you spawn. The VB6 Shell() function returns a Process ID you can use to call OpenProcess with. CreateProcess gives you the handle directly.
Ok, here is a super-stripped-down example of a program in VB6 to spawn and monitor programs. The example is coded to start and repeatedly restart 3 copies of the command shell (trivial sample child program). It is also written to kill any running children when it is terminated, and there are better alternatives to use in most cases. See A Safer Alternative to TerminateProcess().
This demo also reports back the exit code of each process that quits. You could enter exit 1234 or somesuch to see this in action.
To create the demo open a new VB6 Project with a Form. Add a multiline TextBox Text1 and a Timer Timer1 (which is used to poll the children for completion). Paste this code into the Form:
Option Explicit
Private Const SYNCHRONIZE = &H100000
Private Const PROCESS_QUERY_INFORMATION = &H400&
Private Const PROCESS_TERMINATE = &H1&
Private Const WAIT_OBJECT_0 = 0
Private Const INVALID_HANDLE = -1
Private Const DEAD_HANDLE = -2
Private Declare Function CloseHandle Lib "kernel32" ( _
ByVal hObject As Long) As Long
Private Declare Function GetExitCodeProcess Lib "kernel32" ( _
ByVal hProcess As Long, _
ByRef lpExitCode As Long) As Long
Private Declare Function OpenProcess Lib "kernel32" ( _
ByVal dwDesiredAccess As Long, _
ByVal bInheritHandle As Long, _
ByVal dwProcessId As Long) As Long
Private Declare Function TerminateProcess Lib "kernel32" ( _
ByVal hProcess As Long, _
ByVal uExitCode As Long) As Long
Private Declare Function WaitForSingleObject Lib "kernel32" ( _
ByVal hHandle As Long, _
ByVal dwMilliseconds As Long) As Long
Private Tasks() As String
Private Handles() As Long
Private Sub Form_Load()
Dim I As Integer
'We'll run 3 copies of the command shell as an example.
ReDim Tasks(2)
ReDim Handles(2)
For I = 0 To 2
Tasks(I) = Environ$("COMSPEC") & " /k ""#ECHO I am #" & CStr(I) & """"
Handles(I) = INVALID_HANDLE
Next
Timer1.Interval = 100
Timer1.Enabled = True
End Sub
Private Sub Form_QueryUnload(Cancel As Integer, UnloadMode As Integer)
Dim I As Integer
Timer1.Enabled = False
DoEvents
For I = 0 To UBound(Tasks)
If Handles(I) <> INVALID_HANDLE And Handles(I) <> DEAD_HANDLE Then
TerminateProcess Handles(I), 666
CloseHandle Handles(I)
Handles(I) = DEAD_HANDLE
End If
Next
End Sub
Private Sub Timer1_Timer()
Dim I As Integer
Dim ExitCode As Long
Dim Pid As Long
Timer1.Enabled = False
For I = 0 To UBound(Tasks)
If Handles(I) <> INVALID_HANDLE Then
If WaitForSingleObject(Handles(I), 0) = WAIT_OBJECT_0 Then
If GetExitCodeProcess(Handles(I), ExitCode) <> 0 Then
Text1.SelText = "Task " & CStr(I) & " terminated, " _
& "exit code: " & CStr(ExitCode) _
& ", restarting task." _
& vbNewLine
Else
Text1.SelText = "Task " & CStr(I) & " terminated, " _
& "failed to retrieve exit code, error " _
& CStr(Err.LastDllError) _
& ", restarting task." _
& vbNewLine
End If
CloseHandle Handles(I)
Handles(I) = INVALID_HANDLE
End If
End If
If Handles(I) = INVALID_HANDLE Then
Pid = Shell(Tasks(I), vbNormalFocus)
If Pid <> 0 Then
Handles(I) = OpenProcess(SYNCHRONIZE _
Or PROCESS_QUERY_INFORMATION _
Or PROCESS_TERMINATE, 0, Pid)
If Handles(I) <> 0 Then
Text1.SelText = "Task " & CStr(I) & " started." _
& vbNewLine
Else
Text1.SelText = "Task " & CStr(I) _
& ", failed to open child process." _
& vbNewLine
Handles(I) = DEAD_HANDLE
End If
Else
Text1.SelText = "Task " & CStr(I) _
& ", failed to Shell child process." _
& vbNewLine
Handles(I) = DEAD_HANDLE
End If
End If
Next
Timer1.Enabled = True
End Sub
Hopefully this helps answer the question.
something more simple will use sockets.
Launch you app server and on your client implements the communication against your server. With that you will provide intercommunication.
well i say. because i dont be what you try do
Sorry it only apply if your clients are done in house i you have the option of added changes

How can I show a message box with two buttons?

How can I show a message box with two buttons (For example: "on", "off")?
You probably want to do something like this:
result = MsgBox ("Yes or No?", vbYesNo, "Yes No Example")
Select Case result
Case vbYes
MsgBox("You chose Yes")
Case vbNo
MsgBox("You chose No")
End Select
To add an icon:
result = MsgBox ("Yes or No?", vbYesNo + vbQuestion, "Yes No Example")
Other icon options:
vbCritical or vbExclamation
The VBScript Messagebox is fairly limited as to the labels you can apply to the buttons, your choices are pretty much limited to:
OK
Cancel
Retry
Abort
Ignore
Yes
No
So you are going to have to build your own form if you want "ON"/"OFF"
Better yet, why not rephrase the prompt in the box so one of the above options works.
For example:
Do you want the light on?
[Yes] [No]
And for God's sake don't do one of these UI monstrosities!
Switch setting? (Click "yes" for ON and "No" for Off)
[Yes] [No]
Remember - if you set the buttons to vbOkOnly - it will always return 1.
So you can't decide if a user clicked on the close or the OK button. You just have to add a vbOk option.
Cannot be done. MsgBox buttons can only have specific values.
You'll have to roll your own form for this.
To create a MsgBox with two options (Yes/No):
MsgBox("Some Text", vbYesNo)
It can be done, I found it elsewhere on the web...this is no way my work ! :)
Option Explicit
' Import
Private Declare Function GetCurrentThreadId Lib "kernel32" () As Long
Private Declare Function SetDlgItemText Lib "user32" _
Alias "SetDlgItemTextA" _
(ByVal hDlg As Long, _
ByVal nIDDlgItem As Long, _
ByVal lpString As String) As Long
Private Declare Function SetWindowsHookEx Lib "user32" _
Alias "SetWindowsHookExA" _
(ByVal idHook As Long, _
ByVal lpfn As Long, _
ByVal hmod As Long, _
ByVal dwThreadId As Long) As Long
Private Declare Function UnhookWindowsHookEx Lib "user32" _
(ByVal hHook As Long) As Long
' Handle to the Hook procedure
Private hHook As Long
' Hook type
Private Const WH_CBT = 5
Private Const HCBT_ACTIVATE = 5
' Constants
Public Const IDOK = 1
Public Const IDCANCEL = 2
Public Const IDABORT = 3
Public Const IDRETRY = 4
Public Const IDIGNORE = 5
Public Const IDYES = 6
Public Const IDNO = 7
Public Sub MsgBoxSmile()
' Set Hook
hHook = SetWindowsHookEx(WH_CBT, _
AddressOf MsgBoxHookProc, _
0, _
GetCurrentThreadId)
' Run MessageBox
MsgBox "Smiling Message Box", vbYesNo, "Message Box Hooking"
End Sub
Private Function MsgBoxHookProc(ByVal lMsg As Long, _
ByVal wParam As Long, _
ByVal lParam As Long) As Long
If lMsg = HCBT_ACTIVATE Then
SetDlgItemText wParam, IDYES, "Yes :-)"
SetDlgItemText wParam, IDNO, "No :-("
' Release the Hook
UnhookWindowsHookEx hHook
End If
MsgBoxHookProc = False
End Function
msgbox ("Message goes here",0+16,"Title goes here")
if the user is supposed to make a decision the variable can be added like this.
variable=msgbox ("Message goes here",0+16,"Title goes here")
The numbers in the middle vary what the message box looks like.
Here is the list
0 - ok button only
1 - ok and cancel
2 - abort, retry and ignore
3 - yes no and cancel
4 - yes and no
5 - retry and cancel
TO CHANGE THE SYMBOL (RIGHT NUMBER)
16 - critical message icon
32 - warning icon
48 - warning message
64 - info message
DEFAULT BUTTON
0 = vbDefaultButton1 - First button is default
256 = vbDefaultButton2 - Second button is default
512 = vbDefaultButton3 - Third button is default
768 = vbDefaultButton4 - Fourth button is default
SYSTEM MODAL
4096 = System modal, alert will be on top of all applications
Note: There are some extra numbers. You just have to add them to the numbers already there like
msgbox("Hello World", 0+16+0+4096)
from https://www.instructables.com/id/The-Ultimate-VBS-Tutorial/
I did
msgbox "TEXT HERE",3,"TITLE HERE"
If Yes=true then
(result)
else
msgbox "Closing..."
It is possible to make Custom Dialog boxes in 2021 that are just as easy as Msgboxes! Note this is for VB, not VB script.
First make a new form using the dialog box template. It includes two boxes already of which you can change the names/text:
Then back in your main code put this, where "Dialog1" is the name of your new dialog. This allows you to treat this form as a msgbox with just one line of code:
Dim dialogInstance As New Dialog1
Dim result As dialogResult = dialogInstance.ShowDialog()
The variable "result" will behave like a traditional OK/Cancel msgbox exactly like the options above, but will display your custom text on the buttons. From here you can add custom pictures to your msgbox and more!

Elevated Credentials for VB6

I need to get elevated credentials (to start a service) in a VB6 application, but only if the user needs to restart the service (I.e. I don't want to get elevated credentials whenever the application is started, only when the user selects restart). How can I do this in VB6?
Fairly easy, but the preferred way involves a new elevated process. This example uses itself run with a switch to know to perform the Service Start instead of normal operations:
VERSION 5.00
Begin VB.Form Form1
BorderStyle = 1 'Fixed Single
Caption = "Form1"
ClientHeight = 3060
ClientLeft = 45
ClientTop = 345
ClientWidth = 4560
LinkTopic = "Form1"
MaxButton = 0 'False
MinButton = 0 'False
ScaleHeight = 3060
ScaleWidth = 4560
StartUpPosition = 3 'Windows Default
Begin VB.CommandButton Command1
Caption = "Start Service"
Height = 495
Left = 1448
TabIndex = 0
Top = 1283
Width = 1665
End
End
Attribute VB_Name = "Form1"
Attribute VB_GlobalNameSpace = False
Attribute VB_Creatable = False
Attribute VB_PredeclaredId = True
Attribute VB_Exposed = False
Option Explicit
Private Const BCM_SETSHIELD As Long = &H160C&
Private Declare Function SendMessage Lib "user32" _
Alias "SendMessageA" ( _
ByVal hWnd As Long, _
ByVal wMsg As Long, _
ByVal wParam As Long, _
lParam As Any) As Long
Private Declare Function ShellExecute Lib "shell32.dll" _
Alias "ShellExecuteA" ( _
ByVal hWnd As Long, _
ByVal lpOperation As String, _
ByVal lpFile As String, _
ByVal lpParameters As String, _
ByVal lpDirectory As String, _
ByVal nShowCmd As Long) As Long
Private Sub Command1_Click()
ShellExecute hWnd, "runas", App.EXEName & ".exe", "-start", CurDir$(), vbNormalFocus
End Sub
Private Sub Form_Load()
If UCase$(Trim$(Command$())) = "-START" Then
Caption = "Starting Service"
Command1.Visible = False
'Service starting functionality goes here.
Else
Caption = "Service Starter"
'For Shield to work you must have a Common Controls v. 6
'manifest and call InitCommonControls before loading
'this form (i.e. preferably from Sub Main).
SendMessage Command1.hWnd, BCM_SETSHIELD, 0&, 1&
Command1.Visible = True
End If
End Sub
One solution is to use the COM elevation moniker http://msdn.microsoft.com/en-us/library/ms679687(VS.85).aspx.
This link should be useful if your target is VB6 http://www.vbforums.com/showthread.php?t=459643.
You'll need to call into the WinAPI - CoImpersonateClient, or LogonUser.
Just remember to lower your privileges afterwards, and be DARN careful what you do when elevated (e.g. don't do ANYthing with user input).
Another option, which I believe is preferable (if available), is to use a COM+ configured object. You can have the COM+ subsystem manage credentials, and just limit access to call the object as necessary. This has the benefit of creating and ACTUAL trust boundary between low-privileged code and high-privileged code.

Resources