Keeping a mdi child maximized

I

Ivan Weiss

Hey guys, quick question. I am trying to create a form that is always
maximized and is an MDI Child. When another form opens I want it to
open (windowed) on top of this form which is still maximized. Is this
possible?

-Ivan
 
H

Herfried K. Wagner [MVP]

* Ivan Weiss said:
Hey guys, quick question. I am trying to create a form that is always
maximized and is an MDI Child. When another form opens I want it to
open (windowed) on top of this form which is still maximized. Is this
possible?

Why do you use an MDI environment? Maybe that's not the best choice for
your purpose.
 
I

Ivan Weiss

I am still working on a workaround to a problem I had before. I want to
use a background image I have for my MDI Container and since there is no
way to do that I was thinking of filling a form with a picturebox and
just keeping it maximized which would make it appear like a background
image in all functionality.

-Ivan
 
I

Ivan Weiss

As a further response I think an MDI environment is preferred because it
just gives a much more professional feel to an app and makes it look
like a familiar program (providing ease of use for my users)

-Ivan
 
S

Stephany Young

Au contraire!!!!!!!!

I don't know who you have been talking but displaying a background image on
the MDI parent client area can certainly be done.

Try googling for 'mdi background image'.
 
I

Ivan Weiss

I have found one example in c++ but the problem is that it uses pointers
so trying to convert it to VB.Net would be very difficult. It seems to
be a widely asked topic but difficult to answer on how to apply and
stretch a background image. Do you know of any examples or code
snippets to help?

-Ivan
 
S

Stephany Young

Here we go!!!!!!!

As you have found out, the BackgroundImage and BackColor properties of a
form appear to be redundant when dealing with a form where the
IsMdiContainer property is set. When the IsMdiContainer property is set, the
form displays a sunken client area with a raised border. This area is
actually a control of type 'MdiClient' with a default BackColour of
SystemColors.AppWorkspace and it covers all of the normal client area of the
form that is not occupied by other controls. I cannot emphasise enough, that
you MUST differentiate between this MdiClient control and the client area of
the form. If you fail to do so you will find yourself in deep brown stuff.

The following assumes that the BackColor property of the form is set to the
desired colour, the BackgroundImage property of the form is set to the
desired image and that the IsMdiClient property of the form is set.

You will need 3 variables with module scope:
Private m_MDIClient As MdiClient
Private m_OriginalBackgroundImage As Image
Private m_IgnoreSetBackgroundImage As Boolean

The first thing you need to do is obtain a reference to the MdiClient
control of the form and store it the appropriate variable. You can use your
favourite algorithm for doing this. The form will have only one such
control. Once you have it, you need to set its BackColor property to that of
the form. This MUST be done in the forms constructor.

In the forms Load event handler, code:
Me.SetStyle(ControlStyles.UserPaint, True)
Me.SetStyle(ControlStyles.ResizeRedraw, True)
Me.SetStyle(ControlStyles.DoubleBuffer, True)
Me.SetStyle(ControlStyles.AllPaintingInWmPaint, True)

The next thing you need is a procedure to do the work:
Private Sub UpdateBackGround()

Dim g As Graphics

If Not (m_OriginalBackgroundImage Is Nothing) Then
If m_MDIClient.Width > 0 And m_MDIClient.Height > 0 Then
Dim b As BitMap = New BitMap(m_MDIClient.Width,
m_MDIClient.Height)
Dim g As Graphics = Me.CreateGraphics.FromImage(b)
g.Clear(Me.BackColor)
g.DrawImage(m_OriginalBackgroundImage, New
Point((m_MDIClient.Width - m_OriginalBackgroundImage.Width) / 2,
(m_MDIClient.Height - m_OriginalBackgroundImage.Height) / 2))
m_IgnoreSetBackgroundImage = True
Me.BackgroundImage = b
m_IgnoreSetBackgroundImage = false
End If
End If

End Sub

In the forms BackgroundImageChanged event handler, code:
If Not m_IgnoreSetBackgroundImage Then
m_OriginalBackgroundImage = me.BackgroundImage
UpdateBackGround()
End If

In the forms Resize event handler, code:
If Not (m_MDIClient Is Nothing) then UpdateBackGround()
 
I

Ivan Weiss

Stephany,

You are my hero if this works. I cannot tell you how long I have been
trying to paint the client area. However, I am not sure I understand
this part of your instructions:

The first thing you need to do is obtain a reference to the MdiClient
control of the form and store it the appropriate variable. You can use
your
favourite algorithm for doing this. The form will have only one such
control. Once you have it, you need to set its BackColor property to
that of
the form. This MUST be done in the forms constructor.

I am very new to this level of programming and it is kind of above my
skill but I want to learn so if you do not mind please just bare with
me. There seems to be no good book or resource to teach this stuff...

How do I get a reference to the MDIClient?
Than you are saying to set its backcolor to the backcolor of the form?
Both of these must be done in the constructor?

-Ivan
 
I

Ivan Weiss

Stephany,

I think I figured out how to do what you said. I put the following code
in the constructor:

Dim ctl As Control

For Each ctl In Controls
If TypeOf ctl Is MdiClient Then
m_MDIClient = ctl
m_MDIClient.BackColor = Me.BackColor
End If
Next

However, in form load I am getting an error saying:

An unhandled exception of type 'System.NullReferenceException' occurred
in Elite Corporate Toolbox.exe

Additional information: Object reference not set to an instance of an
object.

for the line:

If m_MDIClient.Width > 0 And m_MDIClient.Height > 0 Then

any ideas?

-Ivan
 
S

Stephany Young

The line where the error is thrown should not be in the forms Load event
handler.

If you read the instructions again, you will see that that block of code
should be in a Private Sub named UpdateBackground.

Taking into account your comments in your previous post, I'm going to assume
that you need to be taught how to suck eggs, so:

The constructor for the form is the Sub New procedure that can be found in
the generated block which is collapsed by default. You will see a comment
about where to place additional code.

Because there is only 1 MdiClient control for a form with IsMdiContainer
set, you can exit the For ... Next loop immediately you have dealt with it.
This saves iterating for the rest of the controls on the form. none of which
we are interested in. Place an Exit For directly preceding the End If.

I assume that you have set the IsMdiContainer property at design time. If
that is not set then there will be no MdiClient control.

If you coded it exactly as I described then it will run.
 
I

Ivan Weiss

I did all of that as you showed and the line that is throwing that error
is not in the forms load event but in the updatebackground procedure
that we created.

I declared the 3 variables at the top of the form as shown here:

Public Class mdiMain
Inherits System.Windows.Forms.Form

Private m_MDIClient As MdiClient
Private m_OriginalBackgroundImage As Image
Private m_IgnoreSetBackgroundImage As Boolean

#Region " Windows Form Designer generated code "

Public Sub New()
MyBase.New()

'This call is required by the Windows Form Designer.
InitializeComponent()

'Add any initialization after the InitializeComponent() call

Dim myAppName As String
Dim myAppVersion As String
Dim ctl As Control

myAppName = Application.ProductName()
myAppVersion = Application.ProductVersion
Me.Text = myAppName + " " + myAppVersion

For Each ctl In Controls
If TypeOf ctl Is MdiClient Then
m_MDIClient = ctl
m_MDIClient.BackColor = Me.BackColor
Exit For
End If
Next

End Sub

Yet it is still throwing that exception as I showed before saying I dont
have an instantiated reference...

-Ivan
 
S

Stephany Young

Can you post your forms Load event handler and a stack trace at the error
point please.
 
D

Dursun

Did anybody had an answer to this question. Because I am
having the same problem without the dll part.

Thanks,
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Top