i have a treeview in winforms . When i double click on treenode ,its childnode gets disappear .Again when i click on that very node its child nodes gets expand. Any body please help me out.
If you want to disable double click alltogether you will have handle directly the WM_LBUTTONDBLCLK (0x0203). To do that create a MyTreeView control inheriting from System.Windows.Forms.TreeView and override the WndProc(ref Message m) method.
public class MyTreeView : TreeView
{
protected override void WndProc(ref Message m)
{
if (m.Msg == 0x203) { m.Result = IntPtr.Zero; } //Makes the control ignore double licks`
else base.WndProc(ref m);
}
};
This solution will disable completely double clicks on all the TreeView control. If you can live with that, this solution will do.
Related
I have a class based on the NativeWindow class and I want to be able to perform some action when the user clicks inside of it. Here is what I tried:
Code removed
However it doesn't work. Debugging suggests for some reason the message is never 0x0201 which is supposedly a left mouse button click. What's wrong with it?
I'm not sure tooltips can receive a WM_LBUTTONDOWN. You could try using the TTM_RELAYEVENT message that's meant for passing a mouse message to a tooltip control for processing, something like this:
protected override void WndProc(ref System.Windows.Forms.Message m)
{
const int TTM_RELAYEVENT = 0x407;
if (m.Msg == TTM_RELAYEVENT)
{
Message relayed = (Message)Marshal.PtrToStructure(m.LParam, typeof(Message));
if (related.Msg == WM_LBUTTONDOWN)
{
// Do something
}
}
base.WndProc(ref m);
}
I have a simple windows form with no border and several label controls (nothing that needs to be clicked). I needed to be able to allow the user to move the form by clicking anywhere on it, so I found this question, and used the following code found there.
private const int WM_NCHITTEST = 0x84;
private const int HTCLIENT = 0x1;
private const int HTCAPTION = 0x2;
protected override void WndProc(ref Message m)
{
switch (m.Msg) {
case WM_NCHITTEST:
base.WndProc(ref m);
if ((int)m.Result == HTCLIENT) {
m.Result = (IntPtr)HTCAPTION;
return;
} else {
return;
}
break;
}
base.WndProc(ref m);
}
This works well...to a point. If I click anywhere on the form itself (the background), WM_NCHITTEST is HTCLIENT, so I can move my form as expected. However, if I click on a label control itself, the message is something different, and I can't tell what it is.
I found this article about the various possible values for WM_NCHITTEST but none of them seem to be what I need.
I realize I could disable all my label controls and that would allow me to click "on" them as if it was the form itself, but I'm wondering if there's a better/different way to do this.
Thanks for the help!
You are overriding the WndProc for the form, but when the cursor is over a label the WM_NCHITTEST message is sent to the label.
You could create your own label control derived from Label and override its WndProc. This should always return HTTRANSPARENT in response to WM_NCHITTEST. Something like:
private const int HTTRANSPARENT = -1;
protected override void WndProc(ref Message m)
{
switch (m.Msg)
{
case WM_NCHITTEST:
m.Result = (IntPtr)HTTRANSPARENT;
return;
}
base.WndProc(ref m);
}
Also note that there's a small bug in your WndProc. If the message is WM_NCHITTEST but the region isn't HTCLIENT then you call the base class twice.
Is it possible to create a MouseEnter-Event also for the border of the window? I mean also for the minimize and maximize-buttons. Because if I set the Event for my Form1, it works only when i'm inside the Form, but not on the border and the Buttons.
You can override WndProc in you form and you can detect mousemove
protected override void WndProc(ref Message m)
{
base.WndProc(ref m);
// mouse in window or in Border and max, close & min buttons
if (m.Msg == 0xa0 || m.Msg == 0x200)
{
//Do some thing
}
}
I saw the code posted on this forum for moving the WinForm without borders but my dialog (C#) has a panel covering the whole area. I know I have to use WndProc to do this. I don't know what to do at this point. My window doesn't move unless I expose some of it by shrinking the size of the panel. Thank you.
The code I have:
protected override void WndPro(ref Message m)
{
switch(m.Msg)
{
case 0x84:m.Result = new intPtr(0x2);
return
}
base.wndProc(ref m);
}
You'll need to give the panel the same kind of treatment, except that you return HTTRANSPARENT. That makes it transparent to hit tests and the form will get the message. Now it works. Add a class to your project and paste the code shown below. Compile. Replace your existing panel with this one.
using System;
using System.Windows.Forms;
class BackPanel : Panel {
protected override void WndProc(ref Message m) {
if (m.Msg == 0x84) m.Result = (IntPtr)(-1);
else base.WndProc(ref m);
}
}
I'd like a context menu on the caption bar right click
any tips/samples pref in c# ?
UPDATE - for various reasons, right click on the form won't work because the form is not empty and the form is composited dynamically so....
You can do this by trapping the WM_NCRBUTTONDOWN notification that Windows sends when the user right-clicks the title bar. The control class does not have an event for it, you'll need to override WndProc(). Here's an example form, you'll need to add a ContextMenuStrip:
public partial class Form1 : Form {
public Form1() {
InitializeComponent();
}
protected void OnTitlebarClick(Point pos) {
contextMenuStrip1.Show(pos);
}
protected override void WndProc(ref Message m) {
const int WM_NCRBUTTONDOWN = 0xa4;
if (m.Msg == WM_NCRBUTTONDOWN) {
var pos = new Point(m.LParam.ToInt32());
OnTitlebarClick(pos);
return;
}
base.WndProc(ref m);
}
}
MSDN explains how to handle right-clicks on Windows Forms controls. Controls, including Forms, inherit the MouseClick event.
MouseEventArgs will tell you what button was clicked through the Button property. Have a look at the MouseButtons Enumeration.
if you handle the form mouse-click, you can then use the following code:
private void Dialog_MouseClick(object sender, MouseEventArgs e)
{
if (e.Button == MouseButtons.Right)
{
this.Text = "new caption text";
}
}
But you'll have to make sure that you generate this event for the top-level control on a form. For instance if you have a group box on the form, it will receive the mouse-click events rather than the form itself, for the areas of the form that are under the group box.
There is already a menu managed by Windows when you right-click the titlebar.
Do you want to replace it completely?
If you want to add to it you will have to use the Win32 API and interop and you will have to subclass the form.
See the AppendMenu() function.
Basically you need to use p-invoke to do this. There is a really great example at Here
You can see from the example you will need to manually mimic the event handlers, but this is pretty straight forward.
You can override WndProc of the form and capture the WM_NCRBUTTONDOWN message:
protected override void WndProc(ref Message m)
{
const int WM_NCRBUTTONDOWN = 0xA4;
if (m.Msg == WM_NCRBUTTONDOWN)
{
MessageBox.Show("Caption right clicked!");
}
else
{
base.WndProc(ref m);
}
}
This code will suppress the window's context menu, however. You may not wish this. The WM_NCRBUTTONDOWN message will also be sent if you right click the window borders as well. You may not desire this either.