Positioning the cursor/mouse tip using VBA - vba

I am using Visual Basic for Applications, and in my program, I am opening Inventor parts and capturing thumbnails. I get undesirable results if the mouse tip is left hovering over the parts. I would like to be able to re-position the cursor such that it is well out of the way.
Any VBA code that accomplishes this along with the required references would be much appreciated.

You can use the SetCursorPos API for this, although the UX might be horrible if you don't put it back where you found it:
Private Declare Sub SetCursorPos Lib "user32.dll" (x As Long, y As Long)
Sub Example()
SetCursorPos 0, 0
End Sub
If you do want to restore the original location, just grab it with GetCursorPos first.

Related

Copy/Paste in PowerPoint VBA causing errors

So, I've been banging my head against this one for a few days now, and figured it couldn't hurt to see if someone else has a solution.
I'm programming a macro in VBA for PowerPoint. Amongst other things, it needs to copy and paste multiple shapes (approximately 40 every time it's run). However, it randomly stops with an error:
This happens at random points during execution, not at the same point every time; sometimes it will instead paste the previous shape, causing other issues; and sometimes it will fully execute with no problems. I have tried numerous suggested fixes that I've found here and on other sites, and nothing seems to be working.
Right now, this is the relevant bit of code:
ClearClipboard
newPriorityShape.Copy
DoEvents
Set pastedShp = curSlide.Shapes.PasteSpecial(ppPasteDefault)
ClearClipboard
And for ClearClipboard I have:
Private Declare PtrSafe Function OpenClipboard Lib "user32" (ByVal hwnd As Long) As Long
Private Declare PtrSafe Function EmptyClipboard Lib "user32" () As Long
Private Declare PtrSafe Function CloseClipboard Lib "user32" () As Long
Public Function ClearClipboard()
OpenClipboard (0&)
EmptyClipboard
CloseClipboard
End Function
If anyone has any other suggestions, I'd be most grateful.
A little bit too late but I ran into the same issue recently. The implementation of the clipboard history on Windows conflicts with this, so in order to avoid those random errors you need to disable it.

Experiencing problems with copy/paste excel objects/shapes with VBA

I have some complex code which takes some user inputs (names of shapes to copy) then copies said shapes from one sheet to another multiple times. The items are grouped shapes drawn in Excel and all named correctly and uniquely.
I receive copy and paste errors intermittently "Method 'Paste' of object _Worksheet' failed" and "Method 'copy' Of Object '_worksheet' Failed. Through researching the problem we understand that it is fairly common and has something to do with programmes which conflict with Excel when they are accessing the clipboard.
So far, my colleague and I have deduced that 2 programmes in particular interfere the most with the copy/paste operations - Adobe Reader and Autodesk Powershape. (Autodesk and Adobe both have Reference Libraries available within VBA, not sure if this is a coincidence?)
The problem used to occur very frequently whilst we had the programmes open, so we wrote the following macros/functions to try and stablise the code:-
Public Sub CopyShape(ItemName, CopyDestination)
Call ClearClipboard Sheets(CopyDestination).Shapes(ItemName).Copy
Do Until IsClipboardEmpty = False DoEvents Loop
End Sub
Where "ClearClipboard" is:-
Public Function ClearClipboard()
OpenClipboard (0&)
EmptyClipboard
CloseClipboard
End Function
and the function IsClipboardEmpty is:-
Function IsClipboardEmpty() As Boolean
IsClipboardEmpty = (CountClipboardFormats() = 0)
End Function
with the following public declarations:-
Declare Function OpenClipboard Lib "user32" (ByVal hwnd As Long) As Long
Declare Function EmptyClipboard Lib "user32" () As Long
Declare Function CloseClipboard Lib "user32" () As Long
Public Declare Function CountClipboardFormats Lib "user32" () As Long
This code works quite a lot of the time (far better than trying to use "DoEvents" after the copy operation which just failed miserably) as it forces the code to check if the copied item is in the clipboard before trying to paste it, but it doesn't always work - something in the background still messes up the code.
Is there any way of either:-
locking and unlocking the clipboard using VBA or APIs?
using a completely different method of copying and pasting the shapes?
Any and all solutions welcome and of course happy to answers any questions.
Thanks

Winmove() not working with citrix app

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..

RFID Programming With VB.NET

I'm trying to use RFID Contactless Smart Card (T8/D8 Series) for my final project.
But i have problem acessing the dcrf32.dll file in my form.
There are 3 things included in RFID Package, (therefore : 12 smartcards, an usb port, and a driver CD)
In the driver CD, there are so many sample project in some programming language, except VB.NET, i tried them one by one, and that's work.
There is a folder named "win32-dll", it have 3 files inside (dcrf32.dll, dcrf32.h, dcrf32.lib). I have to copy them all in every sample program that i want to use.
They also have example in VB.6, when i try to run it, no problems at all. It works.
(i also put those 3 dcrf files in the %windows%\System32 folder).
But, when i try to build my own project with Visual Studio 2010 and using VB.NET programming language, i have a problem calling the dcrf32.dll file.
I migrate the VB6 source code to VB.NET, it has error when giving parameters to dc_init function.
Can anybody help me? Where is my fault?
Here are the links that important to solve my problems :
Here
I just need help with my first button, and you don't have to help me with the other button like in VB 6 example program.
I just wanna know how to connect the dcrf32 files, and why in VB.NET it has error but in VB 6 it works properly.
I wonder it.
The problem that you are having is dealing with your Declare Functions and the fact there are changes to the size of integers and longs etc. in VB.Net. Look at this Link and this Code Project Article on using PInvoke.
i.e. An Integer in VB6 is a Short in VB.Net, A Long in VB6 is an Integer in VB.Net. The % in your Declares is a VB6 Integer and will become a short.
Declare Auto Function dc_init Lib "dcrf32.dll" (ByVal port as Short, ByVal baud As Integer) As Integer
Declare Auto Function dc_exit Lib "dcrf32.dll" (ByVal icdev As Integer) As Short
Declare Auto Function dc_request Lib "dcrf32.dll" (ByVal icdev As Integer, ByVal mode as Short, tagtype As Integer) As Short
Declare Auto Function dc_anticoll Lib "dcrf32.dll" (ByVal icdev As Integer, ByVal bcnt as Short, snr As Integer) As Short
...

How do I close a currently opened MsgBox using VBA?

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