Resizing via SendMessage with transparent controls

G

gourmete

Hello!

I have a huge problem!

I have a custom-shaped form with no borders and some transparent
controls on it.
I implemented the resizing functionality via sendmessage:

private void resizeBorder_MouseDown(object sender, MouseEventArgs e)
{
ReleaseCapture();
SendMessage(Handle, WM_NCLBUTTONDOWN, 10, 0);
}

The problem occurs while resizing from right to left and from top to
bottom: The background of the transparent controls does not update.
If I use a form with borders and let windows do all the resizing work
everything is allright. Even resizing via sendMessage works correctly
in case of the form having a border.

I tried to invalidate the controls, refresh, force repaint and so on,
but nothing worked.

So my question is: What additional tricks does windows do on resizing a
form having borders???

I tracked the problem down to a very simple example:
Use Form1(false) to create a working form and Form1(true) to create the
problem form. Click on the left gray panel to resize.

------------------------------------------------------------------------
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Text;
using System.Windows.Forms;
using System.Runtime.InteropServices;

namespace WindowsApplication2
{
public class Form1 : Form
{
private Panel resizeBorder;
private Panel panel1;
private System.ComponentModel.IContainer components = null;

protected override void Dispose(bool disposing)
{
if (disposing && (components != null))
{
components.Dispose();
}
base.Dispose(disposing);
}

private void InitializeComponent()
{
this.resizeBorder = new System.Windows.Forms.Panel();
this.panel1 = new System.Windows.Forms.Panel();
this.SuspendLayout();
this.resizeBorder.BackColor =
System.Drawing.SystemColors.Control;
this.resizeBorder.Dock =
System.Windows.Forms.DockStyle.Left;
this.resizeBorder.Location = new System.Drawing.Point(0,
0);
this.resizeBorder.Name = "resizeBorder";
this.resizeBorder.Size = new System.Drawing.Size(12, 266);
this.resizeBorder.TabIndex = 0;
this.resizeBorder.MouseDown += new
System.Windows.Forms.MouseEventHandler(this.resizeBorder_MouseDown);
this.panel1.BackColor = System.Drawing.Color.Fuchsia;
this.panel1.Dock = System.Windows.Forms.DockStyle.Fill;
this.panel1.Location = new System.Drawing.Point(12, 0);
this.panel1.Name = "panel1";
this.panel1.Size = new System.Drawing.Size(280, 266);
this.panel1.TabIndex = 1;
this.AutoScaleDimensions = new System.Drawing.SizeF(6F,
13F);
this.AutoScaleMode =
System.Windows.Forms.AutoScaleMode.Font;
this.BackColor = System.Drawing.SystemColors.Control;
this.ClientSize = new System.Drawing.Size(292, 266);
this.Controls.Add(this.panel1);
this.Controls.Add(this.resizeBorder);
this.Name = "Form1";
this.Text = "Form1";
this.TransparencyKey = System.Drawing.Color.Fuchsia;
this.ResumeLayout(false);
}

public Form1(bool problem)
{
InitializeComponent();
if (problem)
this.FormBorderStyle = FormBorderStyle.None;
}

[DllImportAttribute("user32.dll")]
public static extern int SendMessage(IntPtr hWnd, int Msg, int
wParam, int lParam);

[DllImportAttribute("user32.dll")]
public static extern bool ReleaseCapture();

private const int WM_NCLBUTTONDOWN = 0xA1;

private void resizeBorder_MouseDown(object sender,
MouseEventArgs e)
{
ReleaseCapture();
SendMessage(Handle, WM_NCLBUTTONDOWN, 10, 0);
}
}
}
 
G

gourmete

I discoderd some strange behaviour:

It works if a part of the forms background is visible, i.e. it is not
completly coverd by controls.
Even one tiny visible pixel of the forms background makes my
transparent controls to be repainted correctly.
I think thats why it works with a border, cause the border belongs to
the form!?

If anyone knows another solution, please tell me.
 
G

gourmete

Hi!

Thanks for your answer!
I looked at your sample. I think it does not make a difference whether
to use WndProc or SendMessage. The problem with WndProc is that it gets
solely invoked in case of the mouse beeing over the form itself. If you
want to use controls as resize and or moving frame, the wndProc of the
form will not be invoked. I think thats why you used GDI to paint that
areas.
You can use SendMessage for Example in a controls onMouseDown event. As
long as you pass the handle of the parent window it will do what you
want.
 
O

Oliver Sturm

I'm sorry, you're right - I just had that sample around and I thought that
was a big difference, but the bigger one is that you're using a control
and I'm not.

Now, the problem is: I tried your example and I believe I can't reproduce
your problem. In other words, when I create your form class with true or
false as the ctor parameter, there seems to be no difference whatsoever in
the resize behaviour - the only difference is that in one case the form
has borders, in the other it doesn't. Based on your description, I was
expecting to see the background remaining white, or black, or grey or
something... but it's being redrawn just fine in both cases.

Maybe it makes a difference that I'm using Vista? I guess the composition
functionality could change some details of the redrawing behaviour in such
cases.


Oliver Sturm
 
G

gourmete

Hi!

Yes, it´s a real difference that you are using vista.
I did a lot work with transparency stuff the last few weeks and ran
into many trouble. But all this problems disapeared running the app
under vista.
Vista deals with transparency all over the place, so they had to
improve the mechanisms and did a real good job, I think.
Unfortunately most apps should also run on no-vista OS versions ;)

Thank you for spending your time on my problem!
 

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