Alt + Tab is not showing the forms when Form.Owner is set - vb.net

I have an application (VB.NET) with the name MainForm and other child forms without using MDI Container. The child forms are based on assign to the MainForm with Me.Owner = MainForm
When I press Alt + Tab, for switching between these form, the Windows is showing the MainForm only unless I remove Me.Owner = Nothing it's working as expected again.
I tried Call SetWindowLong on Onload function but not luck. I am still looking for the solution.
EDIT
Actually it's easy for reproduced, I created very simple project.
Simple Application
Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click
Dim Form2 As New Form2
Form2.Owner = Me ' Alt+Tab only Show Form1, not showing Form2.
Form2.Show()
End Sub
Disable Owner property is working fine again.
Please check my teamview recording. Actually it's original form without change anything.
#Royce Your solution still not working, it's throw Win32Exception from my side.

Try to change the ShowInTaskbar Property to True.

Ran your example on my machine (Windows 10) and both windows showed up in my Alt-Tab menu (screenshot).
In your original program, make sure that the FormBorderStyle property of either window is not set to one of the two ToolWindow options and that ShowInTaskbar is True.
Otherwise, you might try changing the CreateParams of your second form to exclude WS_EX_TOOLWINDOW extended style bit by doing something similar to this:
Protected Overrides ReadOnly Property CreateParams() As CreateParams
Get
Dim cp As CreateParams = MyBase.CreateParams
cp.ExStyle = cp.ExStyle And (Not &H80)
Return cp
End Get
End Property

Related

how to set transparent opacity to panel

how do i set panel transparent like opacity to 0. i set the panel by program and it was on top of video player. the code is like this
Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click ', AxVLCPlugin21.Click
Dim panelx As New Panel
panelx.Visible = True
panelx.Size = New Size(AxVLCPlugin21.Width, CInt(AxVLCPlugin21.Height / 2))
panelx.BackColor = System.Drawing.Color.Transparent
AxVLCPlugin21.Controls.Add(panelx)
panelx.BringToFront()
'AddHandler panelx.DoubleClick, AddressOf panelx_click
End Sub
the result is like this
then i try to play the video it only show the half
the reason i use panel is to pause the video (set panel on top of video by transparent), when i click the panel since the video doesn't support click event
update
i put the code in usercontrol1
still got me an error, although i have insert the code in designer. too clarify i put the code designer after below the main designer code. i have tried to put only inherit panel code in main designer code but it only take one inherit only.
The best way to do this is to create a custom control that inherits the panel class and overrides CreateParams and OnPaintBackground with this bit of code:
(Props to Zohar Peled for his post here)
Replace the code behind with:
Public Class TransparentPanel
Inherits System.Windows.Forms.Panel
Protected Overrides ReadOnly Property CreateParams() As CreateParams
Get
' Make background transparent
Dim cp As CreateParams = MyBase.CreateParams
cp.ExStyle = cp.ExStyle Or &H20
Return cp
End Get
End Property
Protected Overrides Sub OnPaintBackground(e As PaintEventArgs)
' call MyBase.OnPaintBackground(e) only if the backColor is not Color.Transparent
If Me.BackColor <> Color.Transparent Then
MyBase.OnPaintBackground(e)
End If
End Sub
End Class
And replace the designer code with:
<Global.Microsoft.VisualBasic.CompilerServices.DesignerGenerated()>
Partial Class TransparentPanel
Inherits System.Windows.Forms.Panel
'Control overrides dispose to clean up the component list.
<System.Diagnostics.DebuggerNonUserCode()>
Protected Overrides Sub Dispose(ByVal disposing As Boolean)
Try
If disposing AndAlso components IsNot Nothing Then
components.Dispose()
End If
Finally
MyBase.Dispose(disposing)
End Try
End Sub
'Required by the Control Designer
Private components As System.ComponentModel.IContainer
' NOTE: The following procedure is required by the Component Designer
' It can be modified using the Component Designer. Do not modify it
' using the code editor.
<System.Diagnostics.DebuggerStepThrough()>
Private Sub InitializeComponent()
components = New System.ComponentModel.Container()
End Sub
End Class
The code you're replacing may look different initially, but using this code will ensure everything works.
NOTE: This code will make the panel transparent if the backcolor is set to Transparent or Control (which depending on the control is normally actually the same as transparent.)
I tried to find an updated resource for creating and implementing a custom control, but I wasn't able to find a maintained resource. So here are some step by step instructions on how to create a custom control.
To create custom control usable in the designer:
(I'm using Visual Studio 2015 for the examples below, it may appear different in other versions.)
1. Create new Windows Forms Control Library
2. Then right click and rename your control to "TransparentPanel" (or
whatever name you like)
3. Paste the code above into the code behind and the designer code respectively (changing the class name if you didn't use "TransparentPanel")
4. Build the project (this will create the .dll you will need to reference in your main project)
5. This one is optional, but it is good to store your DLLs somewhere consistent, other than the project bin folder, so, optionally, navigate to the control library bin folder and copy the created DLL to another location you want to store your custom DLLs.
6. Go to the project you want to use the control in, and right click in the toolbox and click "Choose Items..."
7. Make sure you are on the the ".NET Framework Component" tap and select "Browse".
8. Navigate to the bin folder of the control library (or where ever you stored the DLL), select the control and click "Open".
9. You will see the TransparentControl selected now in the "Choose Toolbox Items" form. Click "OK"
10. Then you should be able to find the control under "General" section.
11. Drag and drop the control onto your form.
NOTE:
The control may not look transparent in the designer, but on runtime it should do what you are looking for.
I hope this works for you!

Close panel if clicked outside

I'm making a custom ComboBox, and I'm struggling to make it's dropdown (a Panel) close when the user clicks outside. As everyone probably knows, using LostFocus event is not enough because when the user clicks on eg.: a scroolbar or the form itself, the control doesn't lose focus. I tried using IMessageFilter, but I don't think I understood how it works. I also tried using the Capture property, forcing the dropdown to capture the mouse, but that also forces the mouse click to happen on the dropdown (Panel) itself, meaning that if the user had clicked on an item on the dropdown, the click won't work.
Let me clarify:
I'm making a custom control, a UserControl, which is compiled to a .DLL, and can be dragged'n dropped from the Toolbox onto forms, just like any other Winforms control.
The control is a Combobox.
I want to make the Combobox's dropdown (which is a panel, created at runtime) close when the user clicks outside of it, just like a normal ComboBox.
And what is the problem? Detecting clicks outside of the panel and then closing it.
-> Using LostFocus event: Not enough. If the user clicks on a blank space on the form, LostFocus is not fired. I know I can place a LostFocus event on my form and set the ActiveContrl to Nothing, but that would require that users (devs) of my custom ComboBox place the same code on every form they use the control.
-> Using Capture property: Has given the best results so far. There are still some problems though. When Capture is set to True, the mouse is indeed captured by the control which has that property set to True. Therefore, no mouse activity is sensed by any other control on the app, but only the control which has the mouse captured. It'll only release the mouse when the user performs a click. This leads to some problems:
If the user clicks on an item (a Button) on the dropdown, and the dropdown (a Panel) has its Capture property set to true, the click will be "ignored", as it'll be handled by the dropdown, and not by the Buttonon which the user actually wanted to click.
If the user clicks on the dropdown's scroolbar, the click will also be "ignored", just like explained above.
When user moves the mouse above the Buttons inside the dropdown (the ComboBox's items), they are not highlighted, because no MouseEnter is fired for them, as the mouse is Captured by the dropdown.
There is a way to solve the first issue: You can find on which button is the mouse pointing using Control.MousePosition, and then force a click on it.
I haven't been able to find a way to solve the 2nd and 3rd issue though. One possible solution I thought of was setting the dropdown's Capture property to False when the mouse enters on it. So, this is how it would work:
User clicks on the Combobox. Dropdown opens, captures the mouse;
User then moves the mouse inside Combobox's dropdown. Capture is set to false, thus making it possible for the user to click on any button inside the dropdown or on the dropdown's scroolbar, and so forth. Buttons inside the dropdown are also properly highlighted as user moves the mouse above them;
User moves the mouse outside Combobox's dropdown, Capture is again set to true, and now any click the user perform outside of it will be "ignored", and the dropdown will be closed. Just like a normal Combobox.
But when I tried to do this, another issue arrived: when a control has its Capture property set to True, it'll constantly fire MouseEnter events. MouseEnter event doesn't use the real mouse pointer location. Even if the mouse pointer is actually outside a Control, that Control will think the mouse is actually inside of it if its Capture property is set to True.
Edit2: here is the code for handling some different types of events (should work for all cases now).
Public Class Form1
Private Shared mouseNotify() As Int32 = {&H201, &H204, &H207} ' WM_LBUTTONDOWN, WM_RBUTTONDOWN, WM_MBUTTONDOWN
Private Shared scrollNotify() As Int32 = {&H114, &H115} ' WM_HSCROLL, WM_VSCROLL
Private Shared scrollCommands() As Int32 = {0, 1, 2, 3, 4, 5} ' SB_LINEUP, SB_LINEDOWN, SB_PAGEUP, SB_PAGEDOWN, SB_THUMBTRACK, SB_THUMBPOSITION
Private Sub baseLoad(ByVal sender As Object, ByVal e As EventArgs) Handles MyBase.Load
AutoScroll = True
Controls.Add(myPanel)
Controls.Add(myTextBox4)
myPanel.myTextBox1.Focus()
End Sub
Private myTextBox4 As New customTextBox(300)
Private myPanel As New customPanel
Protected Overrides Sub OnScroll(ByVal se As ScrollEventArgs)
MyBase.OnScroll(se)
ActiveControl = Nothing
End Sub
Protected Overrides Sub OnMouseWheel(ByVal e As MouseEventArgs)
MyBase.OnMouseWheel(e)
ActiveControl = Nothing
End Sub
Protected Overrides Sub OnResize(ByVal e As System.EventArgs)
MyBase.OnResize(e)
ActiveControl = Nothing
End Sub
Protected Overrides Sub OnMove(ByVal e As System.EventArgs)
MyBase.OnMove(e)
ActiveControl = Nothing
End Sub
Friend Shared Function isOverControl(ByRef theControl As Control) As Boolean
Return theControl.ClientRectangle.Contains(theControl.PointToClient(Cursor.Position))
End Function
Protected Overrides Sub WndProc(ByRef m As Message)
If mouseNotify.Contains(CInt(m.Msg)) Then
If Not isOverControl(myPanel) Then
ActiveControl = Nothing
Else
myPanel.myTextBox1.Focus()
End If
End If
MyBase.WndProc(m)
End Sub
Friend Class customPanel : Inherits Panel
Friend myTextBox1 As New customTextBox(20)
Private myTextBox2 As New customTextBox(60)
Private myTextBox3 As New customTextBox(200)
Friend Sub New()
AutoScroll = True
Location = New Point(0, 100)
Size = New Size(200, 100)
Controls.Add(myTextBox1)
Controls.Add(myTextBox2)
Controls.Add(myTextBox3)
End Sub
Protected Overrides Sub OnLeave(ByVal e As EventArgs)
MyBase.OnLeave(e)
myTextBox1.Text = "false"
myTextBox2.Text = "false"
BackColor = Color.Green
End Sub
Protected Overrides Sub OnEnter(ByVal e As EventArgs)
myTextBox1.Text = "true"
myTextBox2.Text = "true"
BackColor = Color.Gold
MyBase.OnEnter(e)
End Sub
Protected Overrides Sub WndProc(ByRef m As Message)
If mouseNotify.Contains(CInt(m.Msg)) Then
If isOverControl(Me) Then Form1.WndProc(m)
End If
MyBase.WndProc(m)
End Sub
End Class
Friend Class customTextBox : Inherits TextBox
Friend Sub New(ByVal y As Integer)
Location = New Point(10, y)
Size = New Size(100, 30)
End Sub
Protected Overrides Sub OnLeave(ByVal e As EventArgs)
MyBase.OnLeave(e)
BackColor = Color.Blue
End Sub
Protected Overrides Sub OnEnter(ByVal e As EventArgs)
BackColor = Color.Red
MyBase.OnEnter(e)
End Sub
End Class
End Class
If it doesn't work in all cases, you may have to attach events to all the controls on your form that can't/won't receive focus on mouse events.
also, this works slightly differently depending on the type of control. richtextbox use OnHScroll and OnVscroll for example, instead of OnScroll. you can also get the thumb position with CInt(m.WParam.ToInt32 >> 16), only valid for SB_THUMBTRACK, SB_THUMBPOSITION.
also, here are some interesting techniques: Handling a click event anywhere inside a panel in C#
this was actually taken from the MSDN page for WndProc: http://msdn.microsoft.com/en-us/library/system.windows.forms.control.wndproc%28v=vs.110%29.aspx
and the page for NativeWindow Class: http://msdn.microsoft.com/en-us/library/system.windows.forms.nativewindow.aspx

How to make custom properties in Properties Window to refresh upon change via code?

Here is some code:
ReadOnly Property X() As Integer
Get
Return PointerX
End Get
End Property
ReadOnly Property Y() As Integer
Get
Return PointerY
End Get
End Property
Private Sub Proj_MouseMove(ByVal sender As Object, ByVal e As System.Windows.Forms.MouseEventArgs) Handles Me.MouseMove
PointerX = e.X
PointerY = e.Y
End Sub
I want to make the Properties Window to update the properties for X and Y at each MouseMove, so they become immediately visible for the user. I know it is stupid, but it is my assignment.
Can somebody help me?
I would highly recommend pursuing this project in WPF using the OnPropertyChanged event to notify all listeners when a property is changed. Then, make the PropertyGrid listen to all such events on the object which it represents, updating the appropriate property. WPF is great for this stuff...
That's not a Windows Form project.
You created a Windows Control Library which includes a default UserControl and when you "run", you are seeing your UserControl being hosted, which is why you are seeing a PropertyGrid control.
You need to create or add a new project to your solution that is a Windows Form Application, and set it as the "Starup Project" (right mouse click the Form project and select "Set as Startup Project").
After you rebuild your solution, your UserControl "Proj" will be available from the ToolBox, which you can place on your form.

Select the content of textbox when it receives focus

I have found a similar question to mine in Making a WinForms TextBox behave like your browser's address bar
Now i am trying to modify or make it some more different by making it general. I want to apply same action to all the textboxes in form without write code for each one... how many i dun know. As soon as i add a textbox in my form it should behave with similar action of selecting.
So wondering how to do it?
The following code inherits from TextBox and implements the code you mentioned in Making a WinForms TextBox behave like your browser's address bar.
Once you've added the MyTextBox class to your project you can do a global search for System.Windows.Forms.Text and replace with MyTextBox.
The advantage of using this class is you can't forget to wire all the events for every textbox. Also if you decide on another tweak for all textboxes you have one place to add the feature.
Imports System
Imports System.Windows.Forms
Public Class MyTextBox
Inherits TextBox
Private alreadyFocused As Boolean
Protected Overrides Sub OnLeave(ByVal e As EventArgs)
MyBase.OnLeave(e)
Me.alreadyFocused = False
End Sub
Protected Overrides Sub OnGotFocus(ByVal e As EventArgs)
MyBase.OnGotFocus(e)
' Select all text only if the mouse isn't down.
' This makes tabbing to the textbox give focus.
If MouseButtons = MouseButtons.None Then
Me.SelectAll()
Me.alreadyFocused = True
End If
End Sub
Protected Overrides Sub OnMouseUp(ByVal mevent As MouseEventArgs)
MyBase.OnMouseUp(mevent)
' Web browsers like Google Chrome select the text on mouse up.
' They only do it if the textbox isn't already focused,
' and if the user hasn't selected all text.
If Not Me.alreadyFocused AndAlso Me.SelectionLength = 0 Then
Me.alreadyFocused = True
Me.SelectAll()
End If
End Sub
End Class
Assuming you're going to use the accepted solution from the question you link to, all you'd need to do would be that whenever you create a new textbox, you use AddHandler to add the same 3 eventhandlers to each new textbox.
Then you need to change the event handlers to instead of referencing the textbox as this.textBox1 they'll reference it as CType(sender, TextBox) which means that they'll use the textbox that generated the event.
Edit: I'll add that line of code here as well since it's easier to read then
Private Sub TextBox_GotFocus (ByVal sender As System.Object, ByVal e As System.EventArgs) Handles TextBox1.GotFocus, TextBox2.GotFocus, TextBox3.GotFocus
We use this custom textbox control:
Public Class TextBoxX
Inherits System.Windows.Forms.TextBox
Private Sub TextBoxX_MouseUp(sender As Object, e As MouseEventArgs) Handles Me.MouseUp
SelectAll()
End Sub
end class
You can see the full project of our TextBox (on steroids) on GitHub https://github.com/logico-dev/TextBoxX

Visually remove/disable close button from title bar .NET

I have been asked to remove or disable the close button from our VB .NET 2005 MDI application. There are no native properties on a form that allow you to grey out the close button so the user cannot close it, and I do not remember seeing anything in the form class that will allow me to do this.
Is there perhaps an API call or some magical property to set or function to call in .NET 2005 or later to do this?
~~~~~~~~~~~~~~~~~~~~~~~~~~~~
More information:
I need to maintain the minimize/maximize functionality
I need to maintain the original title bar because the form's drawing methods are already very complex.
Based on the latest information you added to your question, skip to the end of my answer.
This is what you need to set to false: Form.ControlBox Property
BUT, you will lose the minimize and maximize buttons as well as the application menu (top left).
As an alternative, override OnClose and set Cancel to true (C# example):
protected override void OnFormClosing(FormClosingEventArgs e)
{
if (e.CloseReason != CloseReason.WindowsShutDown && e.CloseReason != CloseReason.ApplicationExitCall)
{
e.Cancel = true;
}
base.OnFormClosing(e);
}
If neither of these solutions are acceptable, and you must disable just the close button, you can go the pinvoke/createparams route:
How to disable close button from window form using .NET application
This is the VB version of jdm's code:
Private Const CP_NOCLOSE_BUTTON As Integer = &H200
Protected Overloads Overrides ReadOnly Property CreateParams() As CreateParams
Get
Dim myCp As CreateParams = MyBase.CreateParams
myCp.ClassStyle = myCp.ClassStyle Or CP_NOCLOSE_BUTTON
Return myCp
End Get
End Property
You can disable the close button and the close menu item in the system menu by changing the "class style" of the window. Add the following code to your form:
const int CS_NOCLOSE = 0x200;
protected override CreateParams CreateParams {
get {
CreateParams cp = base.CreateParams;
cp.ClassStyle |= CS_NOCLOSE;
return cp;
}
}
This will not just stop the window from getting closed, but it will actually grey out the button. It is C# but I think it should be easy to translate it to VB.
Here is a simple way to remove the close button:
1. Select the Form
2. Now go to Properties.
3. Find ControlBox and change the value to False.
This will remove all the Control Buttons (e.g. Minimize, Maximize, Exit) and also the icon also that is in the to left corner before the title.
You should be able to override the OnClose event of the form. This is common when an application minimizes to the System Tray when "closed".
When you press the X box on the form.
The Form1_Closing is done first, then the Form1_Closed is done.
The e.Cancel = True in the Form1_Closing - prevents Form1_Closed from being called therefore, leaving your form still active.
Prevent to close the form, but hide it:
Private Sub Form1_Closing(ByVal sender As System.Object, ByVal e As System.ComponentModel.CancelEventArgs) Handles MyBase.Closing
Me.WindowState = FormWindowState.Minimized
Me.Visible=false
e.Cancel = True
End Sub
You can set the ControlBox property to False, but the whole title bar will be gone but the title itself...
What jmweb said here is OK as well. The X close button won't go if you cancel the event on form closing. But doing so, you need to release the processes the form needs and then closing the form.
Me.Dispose()
Me.Close()
This worked for me using Menu Strip.
Select (or click) the form itself
Click on events in the property window (the little lightning bolt icon).
Look for Form.Closing and double click it.
Then type: e.cancel=true
Making a Form without a Titlebar in Visual Basic.
Go to Form Properties and set both ControlBox and ShowIcon to false.
Then, clear all the text from the form's text property.
go to properties and select from bored style as none
Just select the required form and in the properties section, set controlBox = false
That just worked for me :)
Private Sub Form1_Closing(ByVal sender As System.Object, ByVal e As System.ComponentModel.CancelEventArgs) Handles MyBase.Closing
Beep()
e.Cancel = True
End Sub