I have an application written in VB.net running on Windows 7 that opens a word document and inserts some values into it. This works fine, but on my client's machines(development works fine) Word is opening up behind my application. I've tried maximizing the document in code, but it's still opening behind my application on the client machines. Does anyone have any idea how I can fix this?
Things I've already tried:
maximizing word in my application
giving focus to word in my application
I've made sure the patches are up to date.
I've performed a repair on Office
Have you tried minimizing the application, as opposed to maximizing the document?
Me.WindowState = FormWindowState.Minimized will minimize the form that calls it (this is assuming that you are using a forms application).
You might need to bring Word to the forefront. This is a bit different from bringing a form in your app to the top.
You'll need to have a reference to two APIs, FindWindow and SetWindowPos - the first one can find the windows handle for another application that is running, and the second sends a message to the operating system to give an application focus (it uses the windows handle from FindWindow)
Here's some sample code.
Public Class Form1
<Runtime.InteropServices.DllImport("user32.dll", SetLastError:=True, CharSet:=Runtime.InteropServices.CharSet.Auto)> _
Private Shared Function FindWindow(ByVal lpClassName As String, _
ByVal lpWindowName As String) As IntPtr
End Function
<Runtime.InteropServices.DllImport("user32.dll", SetLastError:=True)> _
Private Shared Function SetWindowPos(ByVal hWnd As IntPtr, ByVal hWndInsertAfter As IntPtr, ByVal X As Integer, ByVal Y As Integer, ByVal cx As Integer, ByVal cy As Integer, ByVal uFlags As Integer) As Boolean
End Function
Private Shared ReadOnly HWND_TOPMOST As New IntPtr(-1)
Private Shared ReadOnly HWND_NOTOPMOST As New IntPtr(-2)
Private Const SWP_NOSIZE As Integer = &H1
Private Const SWP_NOMOVE As Integer = &H2
Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click
Shell("calc.exe")
End Sub
Private Sub Button2_Click(sender As Object, e As EventArgs) Handles Button2.Click
Dim myHandle As IntPtr = FindWindow(Nothing, "Calculator")
SetWindowPos(myHandle, HWND_TOPMOST, 0, 0, 0, 0, SWP_NOMOVE Or SWP_NOSIZE)
SetWindowPos(myHandle, HWND_NOTOPMOST, 0, 0, 0, 0, SWP_NOMOVE Or SWP_NOSIZE)
End Sub
End Class
Clicking the first button will instantiate a copy of Calculator, the second button will make it topmost, then set it back to normal... so it will still be the top form, but the user can activate other windows as well.
Related
I’m making an VB application which runs another process (windowed game). My app acts as a macro to that game.
I’m struggling to get mouse click working, although my code to send keys in the background works excellent (can provide if needed).
I mean the program to click into specific location within the process in the background, that means I could be browsing internet or playing another game when that mouse click takes action.
I'm getting an error message: Specified cast is not valid.
Error is on InputPressRightMouse Sub where:
PostMessage(Handle, WM_RBUTTONDOWN, 1, coord)
Private Const WM_RBUTTONDOWN As System.UInt32 = &H204
Private Const WM_RBUTTONUP As System.UInt32 = &H205
Dim coord = MakeDWord(-220, 85)
Private Function MakeDWord(ByVal LoWord As Integer, ByVal HiWord As Integer) As Long
MakeDWord = (HiWord * &H10000) Or (LoWord And &HFFFF&)
End Function
<System.Runtime.InteropServices.DllImport("user32.dll")>
Public Shared Function PostMessage(<System.Runtime.InteropServices.In()> ByVal hWnd As System.IntPtr, <System.Runtime.InteropServices.In()> ByVal Msg As System.UInt32, <System.Runtime.InteropServices.In()> ByVal wParam As System.IntPtr, <System.Runtime.InteropServices.In()> ByVal lParam As System.UIntPtr) As System.Boolean
End Function
Public Sub InputPressKey(ByVal Handle As System.IntPtr, ByVal Key As System.Windows.Forms.Keys)
PostMessage(Handle, WM_KEYDOWN, CType(Key, System.IntPtr), CType(WM_KEYDOWNLPARAM, System.UIntPtr))
End Sub
Public Sub InputReleaseKey(ByVal Handle As System.IntPtr, ByVal Key As System.Windows.Forms.Keys)
PostMessage(Handle, WM_KEYUP, CType(Key, System.IntPtr), CType(WM_KEYUPLPARAM, System.UIntPtr))
End Sub
Public Sub InputPressRightMouse(ByVal Handle As System.IntPtr, ByVal Mouse As System.Windows.Forms.MouseButtons)
PostMessage(Handle, WM_RBUTTONDOWN, 1, coord)
End Sub
And code to perform mouse click:
InputPressRightMouse(Process.MainWindowHandle, System.Windows.Forms.MouseButtons.Right)
Code to send key (which works)
InputPressKey(Process.MainWindowHandle, System.Windows.Forms.Keys.V)
Can somebody help with what I did wrong here?
I have made a custom task pane using a user control.
Every time I resize it I raise a method called SuspendDrawing the reason I do this is because the buttons on my custom task pane flicker when I resize it therefore I need to suspend it. I add these buttons using the designer
This works like a treat but then I need to call a method called ResumeDrawing when the user stops resizing however I don't know what event I should use to call the ResumeDrawing method as there is no ResizeEnd event for a user control.
Any suggestions would be appreciated as I'm out of ideas.
My code is as follows
Public Property Resizing As Boolean
<DllImport("user32.dll", EntryPoint:="SendMessageA", ExactSpelling:=True, CharSet:=CharSet.Ansi, SetLastError:=True)>
Private Shared Function SendMessage(ByVal hwnd As IntPtr, ByVal wMsg As Integer, ByVal wParam As Integer, ByVal lParam As Integer) As Integer
End Function
Public Shared Sub SuspendDrawing(ByVal target As Control)
SendMessage(target.Handle, WM_SETREDRAW, 0, 0)
End Sub
Public Shared Sub ResumeDrawing(ByVal target As Control)
ResumeDrawing(target, True)
End Sub
Public Shared Sub ResumeDrawing(ByVal target As Control, ByVal redraw As Boolean)
SendMessage(target.Handle, WM_SETREDRAW, 1, 0)
If redraw Then
target.Refresh()
End If
End Sub
Private Sub SideBarPowerPoint_Resize(sender As Object, e As EventArgs) Handles MyBase.Resize
SuspendDrawing(Me)
End Sub
My Custom Task Pane
Dim taskPaneView = New PowerPointCommon.SideBarPowerPoint
sideBarTaskPane = Globals.ThisAddIn.CustomTaskPanes.Add(taskPaneView, " ")
If sideBarTaskPane.Visible = True Then
sideBarTaskPane.Visible = False
End If
sideBarTaskPane.Visible = True
sideBarTaskPane.DockPosition = Microsoft.Office.Core.MsoCTPDockPosition.msoCTPDockPositionRight
sideBarTaskPane.Width = 100
I'm calling a vb.net exe from a program in java, and i want it to stay behind all of the already opened programs.
I read that you can kinda bring to front with TopMost set to true , but i find no way to put it in the back.
There's some workarounds, like setvisible=false the previous form and setting to true after that, but that isn't quite good with my application. Thank you!
Calling the form's SendToBack (Inherited from Control) method from the Shown event handler is the key.
Calling it from load for example, won't do anything since the window isn't "ready" yet anyway.
Private Sub Form1_Shown(sender As System.Object, e As System.EventArgs) Handles MyBase.Shown
SendToBack()
End Sub
Alternatively, use the SetWindowPos native function as defined in User32.dll.
Imports System.Runtime.InteropServices
...
'Signature source: http://pinvoke.net/default.aspx/user32/SetWindowPos.html
<DllImport("user32.dll", SetLastError:=True)>
Private Shared Function SetWindowPos(ByVal hWnd As IntPtr, ByVal hWndInsertAfter As IntPtr, ByVal X As Integer, ByVal Y As Integer, ByVal cx As Integer, ByVal cy As Integer, ByVal uFlags As Integer) As Boolean
End Function
...
Private Sub Form1_Shown(sender As System.Object, e As System.EventArgs) Handles MyBase.Shown
SetWindowPos(Handle, New IntPtr(1), Location.X, Location.Y, Width, Height, 0)
End Sub
The only thing I changed from the signature provided by PInvoke.net was that I changed the "uFlags" parameter type from "SetWindowPosFlags" (Also defined on the PInvoke.net) to an Integer.
I am trying to make an "overlay" application if you want to call it that. So you can see everything on the very top layer (above all applications) but you cannot interact with any of it so the mouse clicks are behind this window. I have managed to do it with the main Form with a TransparencyKey for the background color (white). But adding a PictureBox, the things that are not white on it are not transparent.
I found a solution in C# but not sure how to "translate" it or apply it to VB.net. Click through transparency for Visual C# Window Forms?
Things I have done and tried:
Create a Graphic of the image instead but I was not successful. As so:
Dim imageFile As Image = Image.FromFile("MyImage.jpg")
' Create graphics object for alteration.
Dim newGraphics As Graphics = Graphics.FromImage(imageFile)
' Alter image.
newGraphics.FillRectangle(New SolidBrush(Color.Black), _
100, 50, 100, 100)
' Draw image to screen.
newGraphics.Graphics.DrawImage(imageFile, New PointF(0.0F, 0.0F))
Found this on MSDN and tried to use it and various other examples I found on the internet but no luck.
So overall: Is there any way to make a whole application "transparent" to mouse clicks. What is a method of making each object (such as PictureBoxes) transparent to mouse clicks. - Thanks
Imports System.Runtime.InteropServices
Class Form1
Private InitialStyle As Integer
Dim PercentVisible As Decimal
Private Sub Form1_Load(sender As Object, e As RoutedEventArgs) Handles Form1.Load
InitialStyle = GetWindowLong(Me.Handle, -20)
PercentVisible = 0.8
SetWindowLong(Me.Handle, -20, InitialStyle Or &H80000 Or &H20)
SetLayeredWindowAttributes(Me.Handle, 0, 255 * PercentVisible, &H2)
Me.Topmost = True
End Sub
<DllImport("user32.dll", EntryPoint:="GetWindowLong")> Public Shared Function GetWindowLong(ByVal hWnd As IntPtr, ByVal nIndex As Integer) As Integer
End Function
<DllImport("user32.dll", EntryPoint:="SetWindowLong")> Public Shared Function SetWindowLong(ByVal hWnd As IntPtr, ByVal nIndex As Integer, ByVal dwNewLong As Integer) As Integer
End Function
<DllImport("user32.dll", EntryPoint:="SetLayeredWindowAttributes")> Public Shared Function SetLayeredWindowAttributes(ByVal hWnd As IntPtr, ByVal crKey As Integer, ByVal alpha As Byte, ByVal dwFlags As Integer) As Boolean
End Function
End Class
I have a window which should stay on top of Power point slide shows. So it should be on top of all the windows. I did this easily using VB 6 using Lib "user32", but it seems to be difficut with VB.net.
Me.TopMost = True
This does not seem to work as it works only within the program.
Private Declare Function BringWindowToTop Lib "user32" Alias "BringWindowToTop" (ByVal hwnd As Long) As Long
Private Sub frmTmr_Activated(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.Activated
BringWindowToTop(Me.Handle)
End Sub
This also gives a error!
Any help is greatly appreciated!
Thanks in advance,
Regards
Manjula
If you want a window in your application to always appear on top of a window of a different application, then the BringWindowToTop function is definitely not what you want. For starters, as you've noticed, you have to repeatedly call the function using a timer. That should be your first clue that it's the wrong API. Another problem is that it's only bringing your window to the top of the Z order for its process, not all of the other processes running on the system. As the documentation explains,
Calling this function is similar to calling the SetWindowPos function to change a window's position in the Z order. BringWindowToTop does not make a window a top-level window.
That last sentence should indicate that there is a better way. Windows has built-in support for top-level windows (i.e., those that should always appear on top of other windows): these are called top-most windows. This is exactly what you want. Top-most windows always appear above non-topmost windows.
Raymond Chen attempts to explain some of the confusion on his blog. Note that in this case, HWND_TOP is equivalent to BringWindowToTop. Instead, you want HWND_TOPMOST.
The simplest way of making a window top-most is to specify the WS_EX_TOPMOST flag when you create the window. The .NET Framework hides most of the window creation work behind the scenes, but you can customize the parameters when you need to by overriding the CreateParams property of your form class.
Here's some sample code to make a form always top-most:
Protected Overrides ReadOnly Property CreateParams() As CreateParams
Get
Const WS_EX_TOPMOST As Integer = &H00000008
Dim cp As CreateParams = MyBase.CreateParams
cp.ExStyle = cp.ExStyle Or WS_EX_TOPMOST
Return cp
End Get
End Property
This won't work if you want to toggle the top-most state of the window at run-time. To do that, you're going to have to P/Invoke the SetWindowPos function. P/Invoke is similar to what you used to do in VB6 with the Declare statement, but the semantics have changed slightly for the .NET world—that's why you can't use your old VB6 Declare statements in VB.NET.
Here's what that code might look like for VB.NET:
<DllImport("user32.dll", SetLastError:=True)> _
Private Shared Function SetWindowPos(ByVal hWnd As IntPtr, ByVal hWndInsertAfter As IntPtr, ByVal X As Integer, ByVal Y As Integer, ByVal cx As Integer, ByVal cy As Integer, ByVal uFlags As Integer) As Boolean
End Function
Private Const SWP_NOSIZE As Integer = &H1
Private Const SWP_NOMOVE As Integer = &H2
Private Shared ReadOnly HWND_TOPMOST As New IntPtr(-1)
Private Shared ReadOnly HWND_NOTOPMOST As New IntPtr(-2)
Public Function MakeTopMost()
SetWindowPos(Me.Handle(), HWND_TOPMOST, 0, 0, 0, 0, SWP_NOMOVE Or SWP_NOSIZE)
End Function
Public Function MakeNormal()
SetWindowPos(Me.Handle(), HWND_NOTOPMOST, 0, 0, 0, 0, SWP_NOMOVE Or SWP_NOSIZE)
End Function