Is there a way alter the window of a 3rd party application? Resize, Minimizie, Make Transparent... any of those, or all of the above?
Printable View
Is there a way alter the window of a 3rd party application? Resize, Minimizie, Make Transparent... any of those, or all of the above?
To Minimize an external application, you simply need to use the ShowWindow API. Have a look at this example :
So, all you'd need to do is to replace Notepad with the EXE name of your external application.Code:Imports System.Runtime.InteropServices 'used with APIs
Public Class Form1
Private Const SW_SHOWMINIMIZED As Int32 = 2 'Minimize constant
<DllImport("user32.dll", EntryPoint:="ShowWindow", CharSet:=CharSet.Auto)> _
Private Shared Function ShowWindow(ByVal hwnd As Int32, ByVal nCmdShow As Int32) As Int32
End Function 'ShowWindow API
Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click
Dim NoteProc() As Process = Process.GetProcessesByName("notepad") 'Get Notepad's handle
If NoteProc.Length > 0 Then ShowWindow(NoteProc(0).MainWindowHandle, SW_SHOWMINIMIZED) 'Minimize
End Sub
End Class
To Maximize an external window, you can follow the exact same method as outlined above; obviously, you'd need to use the SW_SHOWMAXIMIZED constant, and optionally, you could use the SetForegroundWindow API to bring the external application to the front.
Try this part first, then, we can look at resizing external windows :)
I hope my post was useful :)
I converted a vb6 example, that makes most external windows transparent.
It would be nice to add this example to the "VB.NET API FAQ's" section. :)
All you need is a button, and a trackbar.
EDIT: max is 255 not 256Code:Public Class Form1
Const LWA_COLORKEY As Int32 = 1
Const LWA_ALPHA As Int32 = 2
Const GWL_EXSTYLE As Int32 = (-20)
Const WS_EX_LAYERED As Int32 = 524288
Private Declare Function apiGetWindowLong Lib "user32" Alias "GetWindowLongA" (ByVal hWnd As Int32, ByVal nIndex As Int32) As Int32
Private Declare Function apiSetWindowLong Lib "user32" Alias "SetWindowLongA" (ByVal hWnd As Int32, ByVal nIndex As Int32, ByVal dwNewLong As Int32) As Int32
Private Declare Function apiSetLayeredWindowAttributes Lib "user32" Alias "SetLayeredWindowAttributes" (ByVal hWnd As Int32, ByVal crKey As Int32, ByVal bAlpha As Byte, ByVal dwFlags As Int32) As Int32
Dim nhwnd As Int32
Private Sub Form1_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
Dim p As New System.Diagnostics.Process
p = Process.Start("notepad")
p.WaitForInputIdle()
nhwnd = p.MainWindowHandle.ToInt32
TrackBar1.Maximum = 255
TrackBar1.Value = 100
End Sub
Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click
Transparency(nhwnd, 100) 'Set transparency to 100, or anywhere between 0-255. Use a trackbar if you want.
End Sub
Private Sub Transparency(ByVal hwnd As Int32, ByVal sOpacity As Int32)
Dim Ret As Int32 = apiGetWindowLong(hwnd, GWL_EXSTYLE) 'Set the window style to 'Layered'
Ret = Ret Or WS_EX_LAYERED
apiSetWindowLong(hwnd, GWL_EXSTYLE, Ret)
apiSetLayeredWindowAttributes(hwnd, 0, sOpacity, LWA_ALPHA) 'Set the opacity of the layered window
End Sub
Private Sub TrackBar1_Scroll(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles TrackBar1.Scroll
Transparency(nhwnd, TrackBar1.Value)
End Sub
End Class
HanneSThEGreaT That works great, is resizing that easy?
That transparency thing is awesome!
How do we go about doing that to an app that is already running and not launched from the program?
I'm wondering the same thing about resizing actually.
I usually use the API MoveWindow, but I don't really move it anywhere.
Then I just use the height and width params to crop.
However, this is not the same way, that you normally would resize a form with the mouse. So I'm all ears Hannes!
fallnwrld,
You can use the API FindWindow to get the handle of the external application. Just plug the integer handle into the Transparency sub.
I think this API might work too:
UpdateLayeredWindow
And it also resizes I think, but I haven't had a crack at it yet.
I was able to get FindWindow to work thanks. Is there a way to get the hwnd by the executable name, instead of the title of the app like we do in FindWindow?
I'll try that resize code, i'm interested on how you crop as well that may fit my needs.
Learning tons so far, thanks guys.
_
If you need to deal with more than one process with the same name, you can also do this:
Hannes should be back online soon, so lets see what he has to say about resizing.Code:For Each p As Process In Process.GetProcessesByName("notepad")
If p.MainWindowHandle <> 0 Then
MessageBox.Show(p.MainWindowHandle)
End If
Next
I think he had something in mind, but if not I'll show you how to use MoveWindow with a couple extra steps.
Here's a page with GDI Translate/Transform. Also, rotate, transpose, etc.
http://www.vbdotnetheaven.com/Upload...nsGDIplus.aspx
TT(n), great mind think alike :p
Well, there are actually 3 ways to approach this :
1) MoveWindow - which is basically the easiest, and which I'll show :)
2) SendMessage - use the WM_SIZE constant
3) SetWindowsPos - where you could supply starting X and Y values, as well as Width and Height, and some flags to make the window un - resizable, or always on top etc.
Here is an example ( which works ) using MoveWindow :
Easy as pie, isn't it ¿ :)Code:'Import the System.Runtime.InterOpServices Namespace
<DllImport("user32.dll", EntryPoint:="MoveWindow", CharSet:=CharSet.Auto)> _
Public Shared Function MoveWindow(ByVal hWnd As IntPtr, _
ByVal X As Int32, _
ByVal Y As Int32, _
ByVal nWidth As Int32, _
ByVal nHeight As Int32, _
ByVal bRepaint As Boolean _
) As Boolean
End Function
Private Sub Button2_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button2.Click
Dim NoteProc() As Process = Process.GetProcessesByName("notepad") 'Get Notepad's handle
MoveWindow(NoteProc(0).MainWindowHandle, 10, 10, 200, 300, True) 'Resize
End Sub
Hey that's a cool link man.
I love that stuff.
I was just working on something similar, to try and get the blur effect that Vista has. I've found a few ways to make only certain areas transparent, like Vista, so within no time I should have a decent aero example for XP users. Although right now my ATI tv tuner doesn't agree with it.
I think I'm cramping it's style. lol
Until then...
Well I'm no ninja. lolQuote:
TT(n), great mind think alike
Ofcourse SendMessage, and SetWindowPos. duh.
I should have thought of that.
Now with MoveWindow, you've moved it though.
The extra steps would be to find out where it currently is, and then use that x,y instead of 10. Essentially resizing it in place.
I thought it might only crop it, but I guess not.
If a window is maximized, I know that it does only crop it, or if the window isn't resizable. Maybe that's why I thought that.
Don't worry, after about a 100 reruns of Karate Kid, I'd say I still am no ninja either :)
When a window is maximized, best would be to restore it using ShowWindow, then resize.
To get the Position of the external window, you could use the getWindowPos API, as shown here :
http://ih4x.wordpress.com/2008/05/21...-getwindowpos/
Thanks for all the help guys, got this working pretty well. Before I close he got me thinking with that cropping the window idea. That can actually end up being useful for me. See this executable has an advertisement on the left hand side. If I can crop that out, that would be pretty darn cool.
first of all im sorry for bringing up an old topicCode:Public Class Form1
Const LWA_COLORKEY As Int32 = 1
Const LWA_ALPHA As Int32 = 2
Const GWL_EXSTYLE As Int32 = (-20)
Const WS_EX_LAYERED As Int32 = 524288
Private Declare Function apiGetWindowLong Lib "user32" Alias "GetWindowLongA" (ByVal hWnd As Int32, ByVal nIndex As Int32) As Int32
Private Declare Function apiSetWindowLong Lib "user32" Alias "SetWindowLongA" (ByVal hWnd As Int32, ByVal nIndex As Int32, ByVal dwNewLong As Int32) As Int32
Private Declare Function apiSetLayeredWindowAttributes Lib "user32" Alias "SetLayeredWindowAttributes" (ByVal hWnd As Int32, ByVal crKey As Int32, ByVal bAlpha As Byte, ByVal dwFlags As Int32) As Int32
Dim nhwnd As Int32
Private Sub Form1_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
Dim p As New System.Diagnostics.Process
p = Process.Start("notepad")
p.WaitForInputIdle()
nhwnd = p.MainWindowHandle.ToInt32
TrackBar1.Maximum = 255
TrackBar1.Value = 100
End Sub
Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click
Transparency(nhwnd, 100) 'Set transparency to 100, or anywhere between 0-255. Use a trackbar if you want.
End Sub
Private Sub Transparency(ByVal hwnd As Int32, ByVal sOpacity As Int32)
Dim Ret As Int32 = apiGetWindowLong(hwnd, GWL_EXSTYLE) 'Set the window style to 'Layered'
Ret = Ret Or WS_EX_LAYERED
apiSetWindowLong(hwnd, GWL_EXSTYLE, Ret)
apiSetLayeredWindowAttributes(hwnd, 0, sOpacity, LWA_ALPHA) 'Set the opacity of the layered window
End Sub
Private Sub TrackBar1_Scroll(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles TrackBar1.Scroll
Transparency(nhwnd, TrackBar1.Value)
End Sub
End Class
im new at vb and rly dont know how to do this with an already started application
could somebody rewrite it to make it work with and already started application?
Code:Public Class Form1
Const LWA_COLORKEY As Int32 = 1
Const LWA_ALPHA As Int32 = 2
Const GWL_EXSTYLE As Int32 = (-20)
Const WS_EX_LAYERED As Int32 = 524288
Private Declare Function apiGetWindowLong Lib "user32" Alias "GetWindowLongA" (ByVal hWnd As Int32, ByVal nIndex As Int32) As Int32
Private Declare Function apiSetWindowLong Lib "user32" Alias "SetWindowLongA" (ByVal hWnd As Int32, ByVal nIndex As Int32, ByVal dwNewLong As Int32) As Int32
Private Declare Function apiSetLayeredWindowAttributes Lib "user32" Alias "SetLayeredWindowAttributes" (ByVal hWnd As Int32, ByVal crKey As Int32, ByVal bAlpha As Byte, ByVal dwFlags As Int32) As Int32
Private Declare Function apiFindWindow Lib "user32" Alias "FindWindowA" (ByVal lpClassName As String, ByVal lpWindowName As String) As Int32
Dim nhwnd As Int32 = 0 'Handle of window
Private Sub Form1_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
TrackBar1.Maximum = 255
TrackBar1.Value = 100
nhwnd = Me.Handle.ToInt32 'Set handle to this application
'Or uncomment, and insert any application title below
'nhwnd = apiFindWindow(Nothing, "Application Title Here")
End Sub
Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click
Transparency(nhwnd, 100) 'Set transparency to 100, or anywhere between 0-255. Use a trackbar if you want.
End Sub
Private Sub Transparency(ByVal hwnd As Int32, ByVal sOpacity As Int32)
Dim Ret As Int32 = apiGetWindowLong(hwnd, GWL_EXSTYLE) 'Set the window style to 'Layered'
Ret = Ret Or WS_EX_LAYERED
apiSetWindowLong(hwnd, GWL_EXSTYLE, Ret)
apiSetLayeredWindowAttributes(hwnd, 0, sOpacity, LWA_ALPHA) 'Set the opacity of the layered window
End Sub
Private Sub TrackBar1_Scroll(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles TrackBar1.Scroll
Transparency(nhwnd, TrackBar1.Value)
End Sub
End Class
Thanks!
1 more question
can i pick the window by process name instead of form name?
Code:Private Sub Form1_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
nhwnd = HandleFromProcessName("Running process name here")
TrackBar1.Maximum = 255
TrackBar1.Value = 100
End Sub
Private Function HandleFromProcessName(ByVal pName As String) As Int32
For Each p As Process In Process.GetProcesses
If p.ProcessName = pName Then HandleFromProcessName = p.MainWindowHandle.ToInt32
Next
End Function
hehe tyvm again
and is there any other way to make it trasparent but without using apis?
I don't think so.
If there is a way in .NET, then it's not very well known.
There is no way IMHO, that there is a non - API solution to making a third party window transparant.
as i tought, anyway thanks for helping me out
P.S. doesnt work with every application
I'm sure it doesn't.Quote:
P.S. doesnt work with every application
However, there are several possible reasons.
A. The application is doing a custom paint operation, or it's non regular window form.
Not much you can do about that without going way overboard.
B. The process loop is not obtaining the correct main window handle(or common zero .net bug).
In which case you have to use a bunch more API for getting the process information.
It would be more reliable, but still not failsafe.
However, you would get almost all windows covered.
I use API for this usually.
C. You've simply used it wrong, and the handle is zero.
D. Your reply may have meant, that not all applications(processes) with the same name become transparent.
If so, you can extend that so that all processes with the same name get the transparency applied.
E. Other
_
DirectX draws directly into memory on the GPU, not the screen buffer area. It gets to the screen buffer automagically. You can't intercept that