|
Thanks a lot, seems to work!
I'm still not quite sure if it's running ok, because i don't get the bytes out of the file correct. How do i have to assign the bytes to the datetime ?
Thanks,
Dennis
|
|
|
|
|
You don't read the bytes directly, unless you want to take all the Types into account. Use a BinaryReader and call ReadInt64 to get the ticks or ReadInt32 to get the milliseconds. Next, read the struct documentation for DateTime in the .NET Framework SDK. There are several constructor overloads, some of which accept either the ticks or milliseconds.
Microsoft MVP, Visual C#
My Articles
|
|
|
|
|
Hi.
How can i prevent a user from changing tabpage without removing tabpages and without the flicker that occurs if i in the selectedIndexChanged event set it back to the original tabpage?
It seems that all events a raised AFTER the tabpage changed.... even the various mouse events...
|
|
|
|
|
Yes, of course it's called after. It is SelectedIndexChanged afterall.
In order to prevent this, you're going to have to derive from TabControl and override WndProc and handle the TCN_SELCHANGING (-552). Return true to prevent the change:
private const int TCN_SELCHANGING = -552;
protected override void WndProc(ref Message m)
{
base.WndProc(ref m);
if (m.Msg == TCN_SELCHANGING)
{
if (!allowChange) m.Result = new IntPtr(1);
}
}
Microsoft MVP, Visual C#
My Articles
|
|
|
|
|
Forgive me, but I'm a little confused.
Heath Stewart wrote:
private const int TCN_SELCHANGING = -552;
I'm assuming that's from CommCtrl.h :
#define TCN_FIRST (0U-550U) // tab control
...
#define TCN_SELCHANGING (TCN_FIRST - 2)
But the MSDN library has the following definition for WindowProc:
LRESULT CALLBACK WindowProc( HWND hwnd,
UINT uMsg,
WPARAM wParam,
LPARAM lParam
);
Which leads me to believe that uMsg will never be -552.
To test it, I derived a control from TabControl and overrode WndProc as such:
protected override void WndProc(ref Message m) {
Console.WriteLine(m.Msg);
base.WndProc (ref m);
}
I added my tab control to a form, gave it a few tabpages and ran it. Sure enough, every value printed as I clicked and poked and prodded was a positive integer.
I started programming with .NET, so I don't have any prior experience with windows messages and I'm obviously missing something, but I can't figure it out. I've been searching the documentation for the last hour trying to make sense of it, with no luck.
|
|
|
|
|
The fact that the number looks negative to you doesn't mean it's negative to a CPU. The runtime doesn't really care, either, except when it comes time to compare or display the value. The Type of the value type will determine if it can be negative or not.
A 32-bit signed integer such as -552 is the same as the 32-bit unsigned integer 0xfffffdd8. When taking into account unsigned equivalents, this is 4294966744.
Unfortunately, this only would've applied if the const was defined as a UInt32 (uint keyword). Sorry about the confusion. Instead, define your constant int as the hex value given above and it should work.
Microsoft MVP, Visual C#
My Articles
|
|
|
|
|
Please forgive me if I'm being exceptionally dense, but it's still not clear to me.
Heath Stewart wrote:
A 32-bit signed integer such as -552 is the same as the 32-bit unsigned integer 0xfffffdd8. When taking into account unsigned equivalents, this is 4294966744.
Thank you for explaining this. This part makes perfect sense to me, that's not the problem.
The range for TabControl messages, according to CommCtrl.h is -550 to -580. None of the value I get from my tab control is even close to this range. Switching back and forth between pages, selecting controls on the pages, hiding and showing the form... all of them return message IDs of 0-675
Heath Stewart wrote:
define your constant int as the hex value given above and it should work.
I can't do this because 0xffffdd8 is beyond the valid range of values for an int . Using a long or unit would be pointless because the Msg poperty of Message is of type int .
const int TCN_SELCHANGING = -552;
protected override void WndProc(ref Message m) {
Debug.Assert(m.Msg != TCN_SELCHANGING);
base.WndProc (ref m);
}
|
|
|
|
|
It wouldn't be pointless to define a uint because you can always cast it to an int upon comparing, but I wouldn't recommend it since this method should be fast (it has to process potentially a lot of messages, after all) and the extra instruction to cast (and possibly two more to store and retrieve depending on the code) is too expensive.
Fortunately, I re-read the documentation for TCN_SELCHANGING and noticed that this message is sent in the form of a WM_NOTIFY message to the parent of the TabControl . This little example works:
using System;
using System.Runtime.InteropServices;
using System.Windows.Forms;
public class Test : Form
{
public static void Main()
{
Application.Run(new Test());
}
public Test()
{
TabControl tab = new TabControl();
this.SuspendLayout();
this.Text = "Test";
this.Controls.Add(tab);
tab.TabPages.Add(new TabPage("Page 1"));
tab.TabPages.Add(new TabPage("Page 2"));
tab.Dock = DockStyle.Fill;
this.ResumeLayout();
}
private const int WM_NOTIFY = 0x004e;
private const int TCN_SELCHANGING = -552;
private struct NMHDR
{
public IntPtr hwndFrom;
public int idFrom;
public int code;
}
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));
Console.WriteLine(hdr.code);
if (hdr.code == TCN_SELCHANGING)
m.Result = new IntPtr(1);
}
}
} Sorry for the mess. Most messages I deal with are sent directly and aren't WM_NOTIFY style messages. This gets a little quirky. You'll notice I marshal the LPARAM parameter to an NMHDR struct, which I then check the code. Getting to know the notification messages helps, I just feel dumb that I didn't fully read it before.
Also note that I'm calling base.WndProc first. If you don't, Windows is likely to change the Message.Result field to 0 (or reset it to 0). You could also just not call it and return in this case if you get the WM_NOTIFY message with the NMHDR.code set to TCN_SELCHANGING .
Microsoft MVP, Visual C#
My Articles
|
|
|
|
|
That is a beautiful thing.
I started programming with .NET and have always been somewhat uncomfortable when it comes to anything outside the framework, although I am reasonably adept at programming within it.
Thank you, Heath, for your help. It's a small thing, I know, but it helped me tremendously.
|
|
|
|
|
Hi.
I just tried this and it works just fine. Great
However, it is still possible to change the tab by pressing the default shortcutkey (ctrl + tab).
I want to be able to control this too. My guess is that all I have to do is add a check do compare to a different messagenumber. Is this correct? If so, Do you have a link to som docs where I can find this number?
I would also like to know if it is possible to detect which tabpage he pressed. for example:
If the user is on tabpage1, he can go to tabpage 2 but NOT to tabpage 3.
To be able to do this, I need to know which tabpage he clicked
Thanks so far.
|
|
|
|
|
As with all Windows Common Controls, you can find these in the Platform SDK on MSDN Library Online[^]. For the common controls, see http://msdn.microsoft.com/library/en-us/shellcc/platform/commctls/wincontrols.asp[^]. Under "Individual Controls" you'll find documentation on the control messages you want. You should take a look at the rest of the stuff, too.
You can try overriding OnKeyDown , although IIRC Ctrl+Tab is handled a little differently. You can find more information about handling the notification messages in the application pump (using an IMessageFilter perhaps) if this is the case in the .NET Framework SDK (find the interface in the help index I mentioned) and in the Platform SDK.
In order to determine which tab he clicked on, you're going to have to do a lot of this yourself. You can override the OnMouseDown event which gives you coordinates relative to the client (TabControl ). Then enumerate your TabPage s and call TabControl.GetTabRect with each one (or rather, their index) and use Rectangle.Contains to see which they clicked on. Other ways most likely won't work because you stopped the tabs from changing, so the other messages that fire events in .NET won't be sent and received.
In cases when you derive a control, you should override the OnEvent method, calling base.OnEvent before or after your code (depending on the circumstances). Handle these events from outside the class. This improves performance slightly and makes for a better polymorphic design.
Microsoft MVP, Visual C#
My Articles
|
|
|
|
|
How can I in my winform display picture or icons in one of the columns in my datagrid?
|
|
|
|
|
By writing your own DataGridColumnStyle class. There are many examples out there that describe hosting a ComboBox in a DataGridColumnStyle , and these wouldn't be hard to adapt and use a PictureBox instead. If you want, you wouldn't even have to worry about the editing if you want this image to be read-only (the editing is the most difficult part). Just make sure your query returns a BLOB (which you can read into a Stream , like a MemoryStream ) or a path to an image.
For a good example of hosting a ComboBox in a DataGridColumnStyle , see http://msdn.microsoft.com/msdnmag/issues/03/08/DataGrids/[^]. It includes examples and sample source.
Microsoft MVP, Visual C#
My Articles
|
|
|
|
|
hi,
table containing fileds code,name. in the name field i need query to retrive repeated datas and code is not same. any one help to me. thanks in advance.
Have A Nice Day!
Murali.M
|
|
|
|
|
|
<br />
private void btnAddP_Click(object sender, System.EventArgs e)<br />
{<br />
<br />
try<br />
{<br />
createSqlConnection();<br />
<br />
if ( txtName.Text != "" && txtHPNO.Text != "")<br />
{<br />
myCommand = new SqlCommand("INSERT INTO Patient(Acct ID, Name, Age, Height, Weight, Address, IcNo, HomeNo, HpNo, EName, EPhoneNo, ERelation, Date, Status, Remarks) VALUES('"+@txtAcctId.Text+"','"+@txtName.Text+"','"+@txtAge.Text+"','"+@txtHeight.Text+"','"+@txtWeight.Text+"','"+@txtAdd.Text="','"+@txtICNO.Text+"','"+@txtHomeNo.Text+"','"+@txtHPNO.Text+"','"+@txtEName.Text+"','"+@txtEPhoneNo.Text+"','"+@txtERelation.Text+"','"+@dTimeDate.Text+"','"+@txtStatus.Text+"','"+@txtRemarks.Text+"')",myConnection);<br />
<br />
MessageBox.Show("Creating New Patient Record.....", "Information");<br />
<br />
myCommand.ExecuteNonQuery();<br />
<br />
MessageBox.Show("New Patient Record Created","Information");<br />
<br />
myConnection.Close();<br />
}<br />
<br />
else<br />
{<br />
MessageBox.Show("All Text Boxes Should be Filled with Information","Reminder");<br />
}<br />
}<br />
<br />
catch (Exception error1)<br />
{<br />
MessageBox.Show(error1.ToString());<br />
}<br />
when i compile the .cs file i get an error..can anyone tell me whats wrong
D:\ASGill\D E G R E E\D. Final Year Project (7)\SOFTWARE\C.I.System\CLINICINFORMATIONSYSTEM\AddPatient.cs(534): The left-hand side of an assignment must be a variable, property or indexer
what does it mean?...
thx
Arvinder Gill
|
|
|
|
|
|
Didn't I tell you before that you shouldn't use string concatenation for SQL queries? What in the hell do you think the OleDbParameter and SqlParameter are for? ADO.NET introduces parameterized expressions which take ALL of the encoding work out of your application. Got a quote in one of your variables? With your way, you have to parse your values and make sure they quotes are escaped or encoded. With parameterized queries, you don't have to worry about it. Besides, massive string concatenation like you're doing is a drastic performance decrease, resulting in (m-1)O(2n) times where m is the number of strings and n is the characters in each string.
See the OleDbParameter[^] class documentation in the .NET Framework SDK for more information and an example. Most likely, not escaping or encoding your string values is what's causing that error since the string is generated and sent to the database engine AS IS.
Also, don't prompt the user before executing the query! First of all, it's annoying. Second of all, if you open the connection before prompting and they don't respond for a while (why would they think they need to answer such a stupid dialog - no other program does it; they just work). The connection gets closed and your call to ExecuteNonQuery throws an exception. Also, put your connection.Close in the finally block to make sure it gets closed on success or failure (exception). Microsoft has recommended this time and time again if you actually read the .NET Framework SDK. The finally block will always run regardless of whether or not an exception was thrown (always except for when Environment.Exit is called, which unloads the CLR - and your application - immediately).
Microsoft MVP, Visual C#
My Articles
|
|
|
|
|
Hi,
I've created a custom control that inherits from ListBox, it has custom draw enabled so i can make it look almost exactly like the Outlook 2003 Inbox Listbox.
Currently i add my "Objects" to the list using the standard "Add" function in the "ListBox.ObjectCollection", however this forces me to do a type check when drawing as anything can still be added to the collection.
Ideally i would like to override the "Add" function described above to force only my "Objects" to be added, but i can't find any documentation on how to go about this.
Any example or pointer would be great to finish my control off.
Thanks in advance
|
|
|
|
|
You have to hide that member by using the new operator, which only makes it valid when the variable type is your custom ListBox derivative class:
public class MyListBox : ListBox
{
private MyListBox.MyObjectCollection items;
public new MyListBox.MyObjectCollection Items
{
if (items == null)
items = new MyListBox.MyObjectCollection();
return items;
}
private class MyObjectCollection : CollectionBase
{
}
}
Microsoft MVP, Visual C#
My Articles
|
|
|
|
|
Hi.
I just found the wonderfull SuspendLayout Method on the WinForm class.
I was wondering if there is a similar feature to susoend the layout for the whole Application in multible forms, without doing it on every single form?
Something like Application.SuspendLayout();;)
Any ideas or suggestions?
|
|
|
|
|
No, and why would there be? The whole idea of object-oriented programming is that objects are responsible for themselves (encapsulation, data hiding, etc.). Each form initializes it's surface so you just need to suspend and resume the layout in each. An Application in Windows Forms really just represents the message pump that keeps the main window (Form ) alive and dispatches window messages to their respective windows.
Microsoft MVP, Visual C#
My Articles
|
|
|
|
|
I have a Form containing a Panel that contains buttons.
The size of the panel will sometimes change, and I whant the bounds of the buttons to change acordenly to the panel.
Is there a method for this, or must I recalculate the bounds of all the buttons each time?
(Maybe something like setting the panel as the buttons parent)
Thanks
Thomas
|
|
|
|
|
The controls can automatically be resized, but they can't move in relation to an adjacent control's size automatically. For information on what is possible, see the Control.Anchor and Control.Dock property documentation in the .NET Framework SDK. These are exposed in the Visual Studio .NET designer as well.
Microsoft MVP, Visual C#
My Articles
|
|
|
|
|
Heath:
This is the second time someone asks a question like this. Simply point them to the code I posted (see post below this one).
This is a typical question from programmers that used a third party VB control, and that I believe is not available for .NET.
FYI: I know that the code posted does not work nicely with text boxes (for which I have a private solution), but it should give them a starting point to work from.
|
|
|
|
|