I'm updating an existing application that scans barcodes and is written in VB.net running on windows compact framework 3.5. The scanner is a POCKETPC running windows mobile handheld 6.5. I have a combobox DropDownStyle='DropDown'. I want to programmatically drop down the box.
I have coded the following:
<DllImport("coredll.dll", SetLastError:=True)> _
Public Shared Function SendMessage(ByVal hWnd As IntPtr, _
ByVal Msg As Integer, _
ByVal wParam As Integer, _
ByVal lParam As Integer) As IntPtr
End Function
Const CB_SHOWDROPDOWN As Int32 = &H14F
SendMessage(cmbVisitoringUnit.Handle, CB_SHOWDROPDOWN, 1, 0)
The return code is 1 but no dropdown takes place. What am I missing?
Based on a lot more testing I have done, let me answer my own question. In order for the dropdown message to the combobox to work the combobox must have focus, so the code must first set focus to the control and then send the message to dropdown. There is another quirk with the combobox. If it is dropped down and it losses focus for any reason the control cancels the dropdown and then destroys the event. This leads to an impression that the program is not responding and the user needs to repeat the action again. The only fix I could come up with is to always cancel the dropdown where possible.
Related
I'm back for more help please.
I'm still on the same project as my question a few weeks ago but stuck on another bit.
I have a multiscreen (win 7) set up and am trying to write an application that will start a number of applications and move/resize them in to the correct positions. I'm doing this as a console app in vb.net.
Following the help I received with my last question I can now start up , move , resize, close all the apps I need bar a couple.
Unfortunately I need to run two applications through Citrix.
One is an Excel sheet.
I can find the windows handle for these windows and select them and or close them but MoveWin() or SetWindowPos() doesn't seem to do anything though the title bar of the window I want to move turns blue so I know it is selecting it..
Any assistance would be greatly appreciated.
A section of the code is pasted below. I'm testing this in excel at the moment and I'll port it across to my console app once working...
Thanks...
Public Declare Function SetWindowPos Lib "user32.dll" (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
Public Const SWP_FRAMECHANGED = &H20 'Fully redraw the window in its new position.
Sub MoveWin()
Dim retval As Long
Dim hwnd As Long
Dim RetWhnd As Long
hwnd = '123456'
retval = SetWindowPos(hwnd, RetWhnd, 0, 0, 600, 400, SWP_FRAMECHANGED) ' Application.hwnd
End Sub
I am not at my home machine, so I cannot confirm this, but I am fairly certain that VB 6 has a tab on the compile dialog (last one perhaps) that has a citrix-related option checkbox. If it's not there, it might be in the project properties.
Just in case this helps someone else. I've contacted the Citrix people and they basically don't know the answer. I at least wanted to know if it was possible. Anyway as far as I can ascertain, the move command doesn't seem to be possible across the Citrix divide. The solution I've come up with is to leave the actual move part of the code in the remotely run app. That is build code in to the apps run through Citrix to look at an ini file on the local machine and receive instructions from it.
This now works great but will only work for apps that either have ability to run a container language or can be wrapped up somehow..
I need to know how we can minimize an already open Internet Explorer browser using vb.net. Everywhere i can only find code to minimize the form and not for the web browser. Any help will be appreciated. Thanks in advance.
Here is how to. But remember this is WindowsAPI. You should read, and learn more before doing any serious stuff.
Imports System.Runtime.InteropServices
Public Class Form1
<DllImport("user32.dll", SetLastError:=True, CharSet:=CharSet.Auto)>
Private Shared Function ShowWindow(ByVal hwnd As IntPtr, ByVal nCmdShow As ShowWindowCommands) As Boolean
End Function
Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click
Dim hWnd As Long = Process.GetProcessesByName("iexplore").First().MainWindowHandle
ShowWindow(hWnd, ShowWindowCommands.ForceMinimize)
End Sub
Enum ShowWindowCommands As Integer
Hide = 0
Normal = 1
ShowMinimized = 2
Maximize = 3
ShowMaximized = 3
ShowNoActivate = 4
Show = 5
Minimize = 6
ShowMinNoActive = 7
ShowNA = 8
Restore = 9
ShowDefault = 10
ForceMinimize = 11
End Enum
End Class
I'll explain.
The import in the first line is needed to use DllImport, which will be used subsequently. The lines of code beginning with <DllImport... imports a function from user32.dll. Since we are going to work with an external application, we take support from WindowsAPI, a set of services provided by windows, to manage that.
The function we're using has the ability to Minimize, Maximize, Hide or Restore an external window. The possible alternatives are listed in the Enum which is at the end of the code. pinvoke.net nicely lists down what they do, if you need a peek.
This code simply assigns a button click do all the work, but of course, this is an example, you should change this as you wish.
We then get the process we need, here it is iexplore, for internet explorer. You can find it in the task manager or tasklist command in Command Prompt. But use it without the .exe part. When we are getting the process, we receive a list: of course, multiple instances of iexplore might be running! I extracted the first one. (Be careful, though, if no iexplore is running, it'll throw an error - handle that.)
And then, get the handle of the main window! What is a handle, btw?
Use ShowWindow(hWnd, ShowWindowCommands.ForceMinimize) to minimize Internet Explorer with the API. (I had to force. It didn't work with Minimize = 6 value.)
Read more here on pinvoke and here on MSDN
EDIT:
OMG! Internet explorer is multi-process!
Instead of minimizing the first, minimize them all!
Change code inside Button1_Click to:
For Each p In Process.GetProcessesByName("iexplore")
' Since Internet Explorer always has its name in the title bar,
If p.MainWindowTitle.Contains("Internet Explorer") Then
Dim hWnd As Long = p.MainWindowHandle
ShowWindow(hWnd, ShowWindowCommands.ForceMinimize)
End If
Next
I recently made an app in VB 2010 and in order to make it individual from the .Net Framework, I begun remaking the app in VB 6.0.
I have a button that is supposed to open the Default Email Client and populate the body with the text from a textbox.
In VB 2010 it works like this :
Process.Start("mailto:test#email.com?subject= &body=" & System.Uri.EscapeDataString(Textbox1.Text))
Can you help me find a way to do what the above does in VB 6.0 ?
To do this, use the ShellExecute API:
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 myButton_Click()
ShellExecute Me.hWnd, "open", "mailto:test#email.com?subject= &body=" & Textbox1.Text, _
vbNullString, vbNullString, 1
End Sub
If you want escape your TextBox1.Text, check this question.
VB6 specific
Shell Function
Runs an executable program and returns a Variant (Double) representing the program's task ID if successful, otherwise it returns zero.
Syntax
Shell(pathname[,windowstyle])
The Shell function syntax has these named arguments:
Part Description
pathname Required; Variant (String). Name of the program to execute and any required arguments or command-line switches; may include directory or folder and drive.
windowstyle Optional. Variant (Integer) corresponding to the style of the window in which the program is to be run. If windowstyle is omitted, the program is started minimized with focus.
The windowstyle named argument has these values:
Constant Value Description
vbHide 0 Window is hidden and focus is passed to the hidden window.
vbNormalFocus 1 Window has focus and is restored to its original size and position.
vbMinimizedFocus 2 Window is displayed as an icon with focus.
vbMaximizedFocus 3 Window is maximized with focus.
vbNormalNoFocus 4 Window is restored to its most recent size and position. The currently active window remains active.
vbMinimizedNoFocus 6 Window is displayed as an icon. The currently active window remains active.
Remarks
If the Shell function successfully executes the named file, it returns the task ID of the started program. The task ID is a unique number that identifies the running program. If the Shell function can't start the named program, an error occurs.
Note By default, the Shell function runs other programs asynchronously. This means that a program started with Shell might not finish executing before the statements following the Shell function are executed.
Is there any option to close the currently opened MsgBox using any code in VBA access form application?
Check out Randy Birch's response on this thread in microsoft.public.vb.general.discussion
He recommends creating a function in a .bas file called MsgBox. Doing so will cause VB to call your function rather than the built in one.
You'd then create your own MsgBox form and build in a timer to close your form after a set period of time. He provides links showing how to do this.
He also discusses a way to explicitly call the built in MsgBox function in case you need to do this.
Note: I've never done this but I've found that Randy Birch is a knowledgeable resource.
MsgBoxes are not intended to be programmatically closed, that's why it's difficult to do so. If you find yourself in a design where you must force close a MsgBox, you should probably re-evaluate your design.
I may be wrong but MsgBox is a blocking call creating a modal form so I don't think there is an easy way such as an option to do that. Do you have a specific use case for this ?
As MarkJ points out, could this could be a dialog generated by Access (rather than a VBA.MsgBox called in your own code)?
For example, when using table's 'dataview' in the Access UI to add a row you get a message, "You are about to append 1 record..." (or similar). Is this the kind of message you mean? If so, there are indeed ways to suppress them...
I used to have an easy answer to this: use the Windows Scripting Shell object, which has a 'Popup' function - a Message Box, just like the VBA MsgBox() function, with a 'SecondsToWait' parameter that provides exactly the timeout you wanted.
With CreateObject("Scripting.WsShell")
.Popup "Watch me disappear in 5 seconds", 5, Application.Name & ": test", vbInformation + vbOkCancel
End With
If you include a 'Cancel' button, it might still work: the available parameters are vbOkCancel, vbYesNoCancel, and vbRetryCancel.
If you're trying to close a dialog box you didn't initiate with your own msgBox() function call, that's unhelpful: and, as I've hinted above, the 'SecondsToWait' parameter doesn't really work these days - someone in Redmond really does't like the idea of one thread closing another thread's helpful warnings and important interruptions to the user's workflow.
However, you can launch a delayed Message Box 'Close' command using the API Timer() function - not quite 'close the currently opened MsgBox', as this requires advance warning that you intended to open it - but it's the closest thing I have, it fits into a self-contained VBA module, and I posted the code in an answer to a very similar StackOverflow question to yours.
I should warn you that the answer in question is using a sledgehammer to crack a nut, with a side order of lengthy explanation.
Rather than writing an alternative to the Access MsgBox from scratch, you might consider using (or at least studying) Arvin Meyer's Custom MessageBox Creator (downloadable on this page).
Message Boxes are meant to depict some information to the user. Hence programmatically closing is not a good design, unless you are not automating some process.
You can use sendkeys or win APIs.
I have had a similar problem; theoretically you can use the "SendKeys" function (see http://msdn.microsoft.com/en-us/library/8c6yea83%28VS.85%29.aspx). However, the MsgBox blocks the running so you cannot use the command. If you know when it going to pop up, you may run (from the script) external whshell that wait some time and then use the SendKeys. But if you know how to do that, tell me (here). Other similar possibility is to open different thread/process for it that will not be block, but I don't know if it is possible in VBA.
An easy to use Win32 based answer to actually be useful calling it. Using the below code you can easily do a timer-based PopUpBox. I like 1/2 second timer control so 2 = 1 second. Found this answer looking for the answer to this thread. Above answers don't seem to work. I want to use this when I want to show a quick message or quick answer default is normally right can be used for more.
Function Code usually in a Module:
Declare Function MessageBoxTimeout Lib "user32.dll" Alias "MessageBoxTimeoutA" ( _
ByVal hwnd As Long, _
ByVal lpText As String, _
ByVal lpCaption As String, _
ByVal uType As Long, _
ByVal wLanguageID As Long, _
ByVal lngMilliseconds As Long) As Long
Private Declare Function FindWindow Lib "user32" Alias "FindWindowA" ( _
ByVal lpClassName As String, _
ByVal lpWindowName As String) As Long
Public Function PopUpBox(Optional stMessage As String _
= "Yes or No? leaving this window for 1 min is the same as clicking Yes.", _
Optional stTitle As String = "PopUp Window", _
Optional HalfSecTimer As Long = 120, Optional lgVBmsgType As Long = vbYesNo) As Long
Dim RetVal As Long
HalfSecTimer = HalfSecTimer * 500
RetVal = MessageBoxTimeout(FindWindow(vbNullString, Title), stMessage, stTitle, lgVBmsgType, _
0, HalfSecTimer)
PopUpBox = RetVal
End Function
Call Function Code
Examples: Actual code from my database
PopUpBox "Re-Linking and Closing dB", "Closing dB", 3, vbOKOnly
intAnswer = PopUpBox("Software Lock Down Active?", "Security", 10, vbYesNo)
I know this is an old post, put it seems there is a new a easy way to do this:
Sub MessageBoxTimer()
Dim AckTime As Integer, InfoBox As Object
Set InfoBox = CreateObject("WScript.Shell")
'Set the message box to close after 10 seconds
AckTime = 10
Select Case InfoBox.Popup("Click OK (this window closes automatically after 10 seconds).", _
AckTime, "This is your Message Box", 0)
Case 1, -1
Exit Sub
End Select
End Sub
Sample code provided by: Tom Urtis
https://learn.microsoft.com/en-us/office/vba/excel/concepts/controls-dialogboxes-forms/automatically-dismiss-a-message-box
I am working with a Custom Ribbon in Power Point, I need to iterate through all tabs and get the ID of them.
The Ribbon contains Tabs added from different projects (C++, C#) as addins and I don't know their IDs.
I am using VBA to handle the events fired from the Ribbon.
How do I do to get the ID from all tabs in the Ribbon using VBA?
Thanks in advance.
The Ribbon is accessed using CommandBars("Ribbon") which returns an IAccessible object. You access tabs by using
AccessibleChildren _
Lib "oleacc.dll" _
(ByVal paccContainer As Object, _
ByVal iChildStart As Long, _
ByVal cChildren As Long, _
rgvarChildren As Variant, _
pcObtained As Long) _
As Long
This will fill an array with a list of all child elements (tabs) which are also IAccessible objects. The ID's you get are strings, and you can iterate through the children of each one to get submenu items and so on.
It's quite complicated, so the best way to get this done would be to work from an example. Lucky for you there is a gleaming example here: http://www.wordarticles.com/Shorts/RibbonVBA/RibbonVBADemo.htm
Pore through the code on that one.