|
Use something similar to my last reply[^] to your similar question, only handle the HDN_ITEMCHANGING (-300 or -320 for *A and *W defs respectively) message and set Message.Result to new IntPtr(0) (FALSE ) to deny the change, or new IntPtr(1) (TRUE ) to allow the change.
Microsoft MVP, Visual C#
My Articles
|
|
|
|
|
Thank you again! I will try it.
La realidad no es más que impulsos eléctricos del cerebro - Morpheus
|
|
|
|
|
ok, it was not much simple for me.
Would you write to me a more especif sample code of your sugestion? Where and how to handle the HDN_ITEMCHANGING message and set Message.Result to new IntPtr(0)or new IntPtr(1) When I need?
I add your last code to my class and add and implement the DataListView_ColumnHeaderChanged.
Thank you!
La realidad no es más que impulsos eléctricos del cerebro - Morpheus
|
|
|
|
|
It really isn't hard and I think you'd learn best by figuring out why I did what I did. Note that the changes are very minor.
Also, in the future, you'd do best to reply to me instead of yourself, otherwise I won't receive a reply notification and may not see your message. It just so happened I did this time, but only because I noticed the old thread was longer than it should be as I happened to glance at it.
Microsoft MVP, Visual C#
My Articles
|
|
|
|
|
ok, thank you. I will try it more, but this - interop with windows messages is new for me and its difulcult to me understand how works with this a n use its constants at this moment
I think I need to modify the WndProc because is there where i found m.result and HDN_ITEMCHANGEDW. I think I need to use the same message WM_NOTIFY and hdr.code == HDN_ITEMCHANGEDA || hdr.code == HDN_ITEMCHANGEDW becouse your last tip.
I do this to try but it does nothing. The colums change the width.
protected override void WndProc(ref Message m)<br />
{<br />
base.WndProc(ref m);<br />
if (m.Msg == WM_NOTIFY)<br />
{<br />
NMHDR hdr = (NMHDR)Marshal.PtrToStructure(m.LParam, typeof(NMHDR));<br />
if (hdr.hwndFrom == hWndHeader &&<br />
(hdr.code == HDN_ITEMCHANGEDA || hdr.code == HDN_ITEMCHANGEDW))<br />
{<br />
m.Result = new IntPtr(0);
<br />
NMHEADER header = (NMHEADER)<br />
Marshal.PtrToStructure(m.LParam, typeof(NMHEADER));<br />
<br />
int index = header.iItem;<br />
if (index >= 0 && index < Columns.Count)<br />
{<br />
ColumnHeader col = Columns[index];<br />
OnColumnHeaderChanged(new ColumnHeaderChangedEventArgs(col));<br />
}<br />
}<br />
}<br />
}
La realidad no es más que impulsos eléctricos del cerebro - Morpheus
|
|
|
|
|
The biggest change is that you must call base.WndProc after setting Message.Result to either TRUE (to allow resizing) or FALSE (to deny resizing). You do this by setting Result to new IntPtr(0) for FALSE , and new IntPtr(1) for TRUE (or define these as read-only fields, whatever you prefer). If you call base.WndProc first, the message is processed and the resizing is allowed. Besides the messages being defined to different values, the original code I posted is pretty much the same.
Microsoft MVP, Visual C#
My Articles
|
|
|
|
|
I put m.Result = new IntPtr(0); firs before base.WndProc but still changin the width.
<br />
protected override void WndProc(ref Message m)<br />
{<br />
m.Result = new IntPtr(0);<br />
base.WndProc(ref m);<br />
if (m.Msg == WM_NOTIFY)<br />
{<br />
Thak you for your help!
La realidad no es más que impulsos eléctricos del cerebro - Morpheus
|
|
|
|
|
DO NOT set Message.Result to FALSE like that! You could screw-up anything. You only set it when the message in which you're interested comes through the message handler. There are potentionally hundreds of messages flying through your message handler while initializing, with many more passing through while the code is executing or even idle in some cases.
See my sample code that I posted which does work. I also mentioned that I mis-read the documentation - you actually pass TRUE (new IntPtr(1) ) to deny changing the column header width.
Microsoft MVP, Visual C#
My Articles
|
|
|
|
|
Actually, I have that backward: return TRUE to deny changes or FALSE to allow them. My bad. Also, something in base.WndProc is resetting the Message.Result back to 0, so you will have to call it first. Since I made a mistake, I'll post my modified source here:
using System;
using System.Drawing;
using System.Reflection;
using System.Runtime.InteropServices;
using System.Windows.Forms;
[assembly: AssemblyVersion("1.0.*")]
[assembly: AssemblyKeyFile(@"C:\Proplanner.NET\KeyFile.snk")]
public class Test : Form
{
static void Main(string[] args)
{
bool b = true;
if (args.Length > 0)
{
try
{
b = bool.Parse(args[0]);
}
catch {}
}
Application.Run(new Test(b));
}
public Test(bool allowResizing)
{
SuspendLayout();
Text = "MyListView Test";
MyListView lv = new MyListView();
Controls.Add(lv);
lv.Dock = DockStyle.Fill;
lv.View = View.Details;
lv.AllowResizing = allowResizing;
lv.ColumnHeaderChanged += new ColumnHeaderChangedEventHandler(
lv_ColumnHeaderChanged);
ColumnHeader col1 = new ColumnHeader();
col1.Text = "One";
ColumnHeader col2 = new ColumnHeader();
col2.Text = "Two";
lv.Columns.Add(col1);
lv.Columns.Add(col2);
ResumeLayout();
}
private void lv_ColumnHeaderChanged(object sender,
ColumnHeaderChangedEventArgs e)
{
Console.WriteLine("Column {0} changed: new width = {1}",
e.ColumnHeader.Text, e.ColumnHeader.Width);
}
}
public class MyListView : ListView
{
private IntPtr hWndHeader;
private bool allowResizing = true;
public bool AllowResizing
{
get { return allowResizing; }
set { allowResizing = value; }
}
protected override void OnHandleCreated(EventArgs e)
{
base.OnHandleCreated(e);
hWndHeader = SendMessage(Handle, LVM_GETHEADER, 0, 0);
}
protected override void WndProc(ref Message m)
{
base.WndProc(ref m);
if (m.Msg == WM_NOTIFY)
{
NMHDR hdr = (NMHDR)Marshal.PtrToStructure(m.LParam, typeof(NMHDR));
if (hdr.hwndFrom == hWndHeader)
{
if (hdr.code == HDN_ITEMCHANGINGA ||
hdr.code == HDN_ITEMCHANGINGW)
{
if (allowResizing) m.Result = FALSE;
else m.Result = TRUE;
}
else if (hdr.code == HDN_ITEMCHANGEDA ||
hdr.code == HDN_ITEMCHANGEDW)
{
NMHEADER header = (NMHEADER)
Marshal.PtrToStructure(m.LParam, typeof(NMHEADER));
int index = header.iItem;
if (index >= 0 && index < Columns.Count)
{
ColumnHeader col = Columns[index];
OnColumnHeaderChanged(
new ColumnHeaderChangedEventArgs(col));
}
}
}
}
}
public event ColumnHeaderChangedEventHandler ColumnHeaderChanged;
protected virtual void OnColumnHeaderChanged(ColumnHeaderChangedEventArgs e)
{
if (ColumnHeaderChanged != null)
ColumnHeaderChanged(this, e);
}
private const int WM_NOTIFY = 78;
private const int HDN_ITEMCHANGINGA = -300;
private const int HDN_ITEMCHANGINGW = -320;
private const int HDN_ITEMCHANGEDA = -301;
private const int HDN_ITEMCHANGEDW = -321;
private const int LVM_GETHEADER = 4127;
private static readonly IntPtr FALSE = new IntPtr(0);
private static readonly IntPtr TRUE = new IntPtr(1);
[StructLayout(LayoutKind.Sequential)]
public class NMHDR
{
public IntPtr hwndFrom;
[MarshalAs(UnmanagedType.U4)] public int idFrom;
[MarshalAs(UnmanagedType.U4)] public int code;
}
[StructLayout(LayoutKind.Sequential)]
public class NMHEADER
{
public IntPtr hwndFrom;
[MarshalAs(UnmanagedType.U4)] public int idFrom;
[MarshalAs(UnmanagedType.U4)] public int code;
public int iItem;
public int iButton;
public IntPtr pitem;
}
[DllImport("user32.dll")]
private static extern IntPtr SendMessage(IntPtr hWnd, int msg,
int wParam, int lParam);
}
public delegate void ColumnHeaderChangedEventHandler(object sender,
ColumnHeaderChangedEventArgs e);
public class ColumnHeaderChangedEventArgs : EventArgs
{
private ColumnHeader columnHeader;
public ColumnHeaderChangedEventArgs(ColumnHeader header)
{
columnHeader = header;
}
public ColumnHeader ColumnHeader
{
get { return columnHeader; }
}
} To test this, copy it and compile it then run the application. As you can see you can resize the column headers. Now execute the program passing "false" as a command-line parameter and you'll see that you can't resize the column headers.
Microsoft MVP, Visual C#
My Articles
|
|
|
|
|
I am working on the roosvelt ID3 algorithm and I want to know how to let the target node accept string and boolean attributes instead of only boolean attributes
Thanks
Cherif
P.S
an attached code will be very appreciated
|
|
|
|
|
Then declare it as an object property and validate that it is either a string or bool in the set accessor:
private object value;
public object Value
{
get { return this.value; }
set
{
if (value is string) this.value = value;
else
try
{
bool b = Convert.ToBoolean(value);
this.value = b;
}
catch
{
throw new ArgumentException("Invalid type.");
}
}
}
} If you want only boolean values (thus accepting values like "True" and "False" as strings), then declare the field (value in the example) as a bool but keep the property as an object . You can use Convert.ToBoolean or Boolean.Parse to convert a string to a boolean. If the string does not represent a boolean, then an exception is thrown (which you see I take advantage of in the example).
Microsoft MVP, Visual C#
My Articles
|
|
|
|
|
is there a way of changing the updatetext property of the update button in the editcommandcolumn in a datagrid at run time?
Thanks
|
|
|
|
|
Yes, but you may want to ask in the correct forum[^], or look at the EditCommandColumn.UpdateText property documentation in the .NET Framework SDK.
Microsoft MVP, Visual C#
My Articles
|
|
|
|
|
Obviously I am a newbie to programming. I need help with a windows form. I have created objects on the form and they are all working fine, but I would like to capture the return key and make it act like they clicked the OK button.
Thanks for the help,
Daniel
|
|
|
|
|
On your form in the designer, set it's AcceptButton property to the button your using for OK.
RageInTheMachine9532
|
|
|
|
|
In addition, you can set the DialogResult for that button to OK if you want it to return DialogResult.OK if you used ShowDialog on your Form . This also sets the Form.DialogResult property if you want to determine which button was clicked that closed the form (since setting the Form.DialogResult property also closes the Form ).
Microsoft MVP, Visual C#
My Articles
|
|
|
|
|
|
For .NET development - if you don't plan on supporting clients using other technologies - you may want to look at .NET Remoting instead. It is a much more powerful, more flexible technology and takes care of the communications automatically. The simplest designer just uses a shared assembly which defines interfaces that the server implements and that the clients user to communicate with the server through a proxy. When using the TcpChannel provided by the .NET Framework Class Library (FCL), you can even have events so that when a client sends a message to the server an event is raised and other clients can get the message immediately. If you're writing your own socket-based chat, you have to handle all this yourself.
In such a case, you need to keep track of connected clients (which .NET Remoting can also do for you pretty easily, though you could use something similar to...) by storing them in a list or something and associate them to each other were appropriate.
If you're having problems with the applications you've found on this site, then you should be specific about what those problems are and you should post questions on the articles' message boards since they're specific to that article.
Microsoft MVP, Visual C#
My Articles
|
|
|
|
|
Thank you Heart! Im gonna try the Remoting thing then
- Up The Irons, Morten Kristensen
|
|
|
|
|
Hi,
I'm writing a program based on an Access Database.
I need to create this database while installing the Application Installer.
While reading Visual Studio documentation, I saw I have to use the SQL Keyword CREATE DATABASE. This is ok for Sql Server, but not for Access.
How can I do ?
Any idea is welcome.
Thanks.
|
|
|
|
|
You either need to use DDL to create a database for Access, or just embed an empty .mdb (Jet Database) as an embedded resource in your assembly that contains the installer and just extract it (if you mean the Installer class). If you're using an installation package like Windows Installer (for which VS.NET contains a couple different projects for creating them), then you could just deploy an empty .mdb that way and put it wherever you need to.
Microsoft MVP, Visual C#
My Articles
|
|
|
|
|
Your right, the Jet engine doesn't know what to do with CREATE DATABASE...
Wouldn't it be alot easier to include a blank copy of your (database).MDB file with your installer?
RageInTheMachine9532
|
|
|
|
|
I have run into an issue in C# / .Net where the control box will not close the form when the user clicks on it.
When my app initially runs, it works fine, but after a while it does nothing when clicked on. I have multiple apps that act in this manner.
Has anyone else run into this? Is there a fix for it?
dpb
Darryl Borden
Principal IT Analyst
darryl.borden@elpaso.com
|
|
|
|
|
This commonly happens when a multi-threaded app has different threads setting properties on the controls that were created in a different thread, or when unhandled exceptions occur during instantiation of the main application form (the form used in the call to Application.Run ). First go through and make sure that you're handling all exceptions that could occur during instantiation of your child controls and that no worker threads are setting properties (and many times even getting properties) or calling methods on the controls from those threads (see Control.InvokeRequired and Control.Invoke in the .NET Framework SDK for more information).
A work-around is to use Application.Quit for your File->Exit (or whatever) menu instead of just calling Close on your form.
Microsoft MVP, Visual C#
My Articles
|
|
|
|
|
Hallo, my name is Axel. I´m in process of learning C#. and I want to realize the following problem:
- On a moblile computer runs a client, on my workstation a server application. I want to send simple commands from client to server. Depending on the received command the server application should do something (for example: open a picture, start internet explorer...)
- I want the server application to start once
so that the the client is (as often as necessary) able to connect/disconnect with the server to send data
- I've just tried a solution like the following, but it is not so good:
private void timer1_Tick(object sender, System.EventArgs e)
{
string[] Antwort = {"answer 1","answer 2","answer 3","answer 4"};
byte[] b = new byte[1];
Socket s = new Socket(AddressFamily.InterNetwork,SocketType.Stream,ProtocolType.Tcp);
Socket sa;
try
{
s.Bind(new IPEndPoint(IPAddress.Any,65000));
s.Listen(1);
sa = s.Accept();
do
{
sa.Receive(b);
if (b[0] > 0)
{
this.statusBarServer.Text = "Server open";
if(b[0] <6)
{
this.statusBarServer.Text = "send back: "+ answer[b[0]-1];
sa.Send(Encoding.ASCII.GetBytes(answer[b[0]-1]));
}
else
sa.Send(Encoding.ASCII.GetBytes("wrong question"));
}
else
{
sa.Send(Encoding.ASCII.GetBytes("CU"));
}
}
while (b[0] >0);
sa.Close();
s.Close();
this.statusBarServer.Text = "Server close";
}
catch(SocketException ex)
{
this.statusBarServer.Text = ex.Message;
}
}
I don't like using a timer for this particular problem. Can someone give me any help?
Thanks,
Axel
|
|
|
|