|
To do a custom textbox is alot of work, perhaps the RichTextBox can serve u better. Also inheriting from a TextBox wont work, TextBox relies on too much PInvoked code, hence much stuff cant be overriden in the usual fashion.
leppie::AllocCPArticle("Zee blog"); Seen on my Campus BBS: Linux is free...coz no-one wants to pay for it.
|
|
|
|
|
I'm not really afraid of putting a lot of work into it. And i'm mostly a Win32 API programmer, so PInvoke doesn't really bother me. I'm just new to C#. What I want to be able to do is to draw ontop of the text (i.e. circle a word with the mouse) and I was hoping to develop a custom control to allow this to happen. Do you have any suggestions as to how I could do this? Additionally, have you any idea how the VS .Net IDE does the coloring of keywords. Should I just develop my own control entirely from scratch? Any Ideas are welcome.
|
|
|
|
|
Most controls in the .NET Frameworks base class library wrap their equivalent Windows common controls. If you've handled common control messages before, you should have no problem handling this. Just extend the control in question, override WndProc and be sure to call the base implementation (base.WndProc ) to let the derived class handle the rest of the work.
There are plenty of examples that do syntax highlighting and there are many ways to do it. A good implementation with open source is SharpDevelop[^], a free C#/VB.NET/HTML IDE with designer support. Take a look at the source for syntax highlighting if you're interested.
Microsoft MVP, Visual C#
My Articles
|
|
|
|
|
That is what I had done. I was attempting to extend the TextBox; however, the textbox does some drawing outside of the paint message, and I don't know what that message is. I understand the grand concept, I just can't figure out what message is doing the redrawing (I mean aside from WM_PAINT).
Regardless, the source code to SharpDevelop is definatly going to help me out a lot. I've looked at the source code for the TextEditor control for it and that should be enough to get me pretty far along. Thanks alot for that link.
|
|
|
|
|
Hi,
We have a smartclient application in C#. We don't know the clients resolution or dpi.
I know it is possible to detect this.
But then we want to adapt or forms and fonts to that type of screen.
Do we have to create a piece of code for each combination (resolution/dpi) to adapt font and controls (hight/width)?
Or is there something automatically that can do this for us.
Ex. we wrote all forms and they are very nice on a screen with a dpi=96 and pixels 1024/768. But when we run the app. on a screen with other setting it is like hell.
So, I would before showing a form that we detect the settings and then adapt our whole app. forms for this screen settings.
Maybe build one form that consits of a panel. Call it mainpanel.cs.
And then all forms hire of that mainpanel. ....
I don't know where to start with this problem.
Tks,
|
|
|
|
|
SystemInformation.VirtualScreen ?
Mazy
"Improvisation is the touchstone of wit." - Molière
|
|
|
|
|
Subclassing is not the way to solve this. You'll end up with more problems than solutions because of an overly-complex architecture.
You could simply get - as part of a static call (it really only needs to be obtained once) - the dpi of the screen (or any graphical output device for that matter) and either initially size your controls accordingly (hence not relying on the designers to do the dirty work and re-arrange your code for optimal execution) or call Scale or ScaleCore (inherited from Control , and the last is virtual so you can override its behavior).
To get the dpi (logical pixels), you'll need to P/Invoke GetDeviceCaps since .NET doesn't expose these properties in the base class library:
[DllImport("gdi32.dll")]
private static extern int GetDeviceCaps(IntPtr hdc, int index);
private const int LOGPIXELSX = 88;
private const int LOGPIXELSY = 90; Once you have the dpi (should normally be the same for the X and Y axis) you can do the appropriate calculations and scale your controls accordingly.
Microsoft MVP, Visual C#
My Articles
|
|
|
|
|
Hi there
i have an mdi app that has a notifyicon.
i want my app to minimize to the tray when it is minimized
but when i minimize the app it minimizes to the bottom of my desktop!
i have set the property
ShowInTaskbar = false
of the main form
Can anyone help me??
VisionTec
|
|
|
|
|
Use Hide(); and Show(); methods of Form.
The smaller the mind the greater the conceit.
Aesop
|
|
|
|
|
The Show() Hide() methods work fine if i use buttons or menus.
But i want to use the minimize box that the form has.
Can anyone plz help?
VisionTec
|
|
|
|
|
protected override void OnDeactivate(EventArgs e) {
Hide();
}
try this, hope it helps.
The smaller the mind the greater the conceit.
Aesop
|
|
|
|
|
Hi,
I'm expecting to get an extra column named 'state' displayed in the datagrid but it doesnt add one.
Can you please help me find out the problem with the source code.
SqlConnection myConnection = new SqlConnection(
"server=(local);database=demo;Integrated Security=SSPI");
SqlDataAdapter myCommand = new SqlDataAdapter ("select * from demo", myConnection);
/* myCommand.SelectCommand.Parameters.Add(new SqlParameter("@State", SqlDbType.NVarChar, 2));
myCommand.SelectCommand.Parameters["@State"].Value = MySelect.Value
*/
try
{
myCommand.SelectCommand.Parameters.Add(new SqlParameter("@State",SqlDbType.NVarChar,2));
myCommand.SelectCommand.Parameters["@State"].Value = "aa";
}
catch(Exception ex)
{
Response.Write(ex.Message);
}
DataSet ds = new DataSet();
myCommand.Fill(ds, "mytable");
DataGrid1.BorderColor=Color.Black;
DataGrid1.BorderWidth=1;
DataGrid1.GridLines=GridLines.Both;
DataGrid1.CellPadding=3;
DataGrid1.CellSpacing=0;
DataGrid1.HeaderStyle.BackColor=Color.FromArgb(0xaaaadd);
DataGrid1.DataSource=ds.Tables["mytable"].DefaultView;
DataGrid1.DataBind();
Yours sincerely
Andla
|
|
|
|
|
Does your demo table have a field entry for state? If not you will need to modify the SQL statement to include this as well.
- Nick Parker My Blog
|
|
|
|
|
I'm doing some statistical analysis work. I have a binary file that contains around 10 million integers. This is my test method:
<br />
Hashtable myNumber = new Hashtable();<br />
Random r = new Random(13214);<br />
for(int j = 0; j < 10000; j++)<br />
{<br />
int c = r.Next(9999999);<br />
if(!myNumber.ContainsKey(c))<br />
myNumber.Add(c, null);<br />
}<br />
<br />
int p = 0;<br />
FileStream fs = new FileStream(Directory.GetCurrentDirectory() + "\\test.txt", FileMode.Open, FileAccess.Read);<br />
BinaryReader bw = new BinaryReader(fs);<br />
Hashtable h = new Hashtable();<br />
DateTime s = DateTime.Now;<br />
int foundnumbers = 0;<br />
for(int i = 0; i < 10000000; i++)<br />
{<br />
int current = bw.ReadInt32();<br />
if (myNumber.ContainsKey(current))<br />
foundnumbers++;<br />
}<br />
bw.Close();<br />
Is there anyway to improve the performance? What I need is to see if a set of numbers is contained in the file.
|
|
|
|
|
Consider I have a lot of Points, each of which are drawn on a PictureBox surface within its Paint event handler if needed.
Now, to you, what is the best approach to add zooming functionality to a paint like application? I mean, do you handle all the stuff yourself, or there are some useful methods within the GDI+ classes which can help us...
Don't forget, that's Persian Gulf not Arabian gulf!
|
|
|
|
|
See the Graphics class, there's plenty of ways to do this, including Graphics.DrawImage and Graphics.ScaleTransform .
Microsoft MVP, Visual C#
My Articles
|
|
|
|
|
I am getting the classic "Object reference not set to an instance of an object." error inside a System.Windows.Forms.UnsafeNativeMethods.DispatchMessageW(MSG& msg) call.
Before you tell me the canned response about null references, here is the trace:
System.Windows.Forms.UnsafeNativeMethods.DispatchMessageW(MSG& msg)
at System.Windows.Forms.ComponentManager.System.Windows.Forms.UnsafeNativeMethods+IMsoComponentManager.FPushMessageLoop(Int32 dwComponentID, Int32 reason, Int32 pvLoopData)
at System.Windows.Forms.ThreadContext.RunMessageLoopInner(Int32 reason, ApplicationContext context)
at System.Windows.Forms.ThreadContext.RunMessageLoop(Int32 reason, ApplicationContext context)
at System.Windows.Forms.Application.Run(Form mainForm)
at eCandidus.Master.Main() in C:\Enterprise Candidus\eCandidus\eCandidus\Master.cs:line 104
The error happens randomly while scrolling a dropdown list combo box, and happens in different combo boxes in different forms. Note that is being caught in a last resort try/catch at the very outmost call posible.
Anyone run into this one before?
|
|
|
|
|
Hi,
my question is.. im using winforms..where one form needs a connection to a SQL Server 7.0 database..can anyone tell me what are the classes involved is it :
System.Data; and System.Data.SqlClient; ??
and also how do i code the connection part...some example would shed some light...i've searched online and got many examples but they're very confusing.
forgive me if im asking for too much...im still new to C#..
plus where can i get the .Net SDK documentation.
Arvinder Gill
ArvinderGill
|
|
|
|
|
You can get the .NET Framework SDK both online and for downloading from http://msdn.microsoft.com/netframework[^].
There are MANY examples - both simple and advanced - dealing with ADO.NET in there. Rather than typing out a lot of code and explaining it as many other articles have done and what the .NET Framework SDK covers in the ADO.NET sections, I'll just let you read it.
Microsoft MVP, Visual C#
My Articles
|
|
|
|
|
I'm creating a tool that queries game servers on the internet.
Though I seem to be having a weird problem when it comes to threading.
I managed to get round the problem of not being able to create threads and pass parameters to those methods.
There is a public variable called queryThread. For example it is: 64. The following code loops 64 times creating threads called queryServerRange. Each with the name of its thread number. (I use this number later on for the thread to figure out which servers it will query).
int i = 0;
while (i < queryThread)
{
i++;
Thread queryRangeThread = new Thread( new ThreadStart( queryServerRange ) );
queryRangeThread.Name = i.ToString();
queryRangeThread.Start();
Random R = new Random();
Thread.Sleep(R.Next(200));
}
Now the following code then first of all figures out which thread number it is,
how many servers there are to be queried in total (from the hashtable servers.Count).
In knowing its thread number, I do some maths to figure out the range this thread will handle.
i.e. server number 0 to 128.
I did it in this way also in an attempt to minimize deadlock/shared variable problems.
However my problem is this: intermittently the whole program will freeze in what I can only see as deadlock,
as yet I can't seem to find a solution.
There are occasions when the problem will not occur, but I can only see this
as being a fluke and down to servers responding in time, etc.
An earlier problem I had was in adding items to the listview below (some items were not appearing),
but I solved this problem with a monitor (Monitor.Enter(servers);).
I looked at doing the same whilst assigning myServer and calling .Refresh() however this slowed the program
right down and made it no faster than querying the servers one by one.
Another strange thing I've noticed, is that the lockups only seem to occur inside the Visual Studio IDE,
when I run the program completely outside of the IDE it doesn't appear to lock up ever.
Does anyone have any smart ideas of how I can stop my code locking up?
Thanks,
Peter.
Here's the code...
private void queryServerRange()
{
int remainder;
int number = Math.DivRem(int.Parse(servers.Count.ToString()), queryThread, out remainder);
int threadNumber = int.Parse(Thread.CurrentThread.Name);
int startPoint;
if (threadNumber == 1)
startPoint = number * (threadNumber - 1);
else
startPoint = number * (threadNumber - 1) + 1;
int endPoint;
if (threadNumber.Equals(queryThread) && !remainder.Equals(0))
endPoint = (number * threadNumber) + remainder;
else
endPoint = number * threadNumber;
//MessageBox.Show("start: " + startPoint.ToString() + " end: " + endPoint.ToString());
try
{
while (startPoint < endPoint)
{
if (status.pressedCancel)
{
Thread.CurrentThread.Abort();
}
Random R = new Random();
Thread.Sleep(R.Next(50));
int listViewIndex = -1;
object obj1 = servers[(long)startPoint];
GameServer myServer = new GameServer();
myServer = (GameServer) obj1;
// Set the servers' time until it gives up trying to contact it.
myServer.Timeout = timeout;
myServer.Refresh();
Monitor.Enter(servers);
// If the server is not in listViewServers and the server has the same filter,
// then add this server into the listView
if (listViewIndex == -1 && (filter.Equals(myServer.Filter.ToString()) || filter.Equals("") ))
{
if (! myServer.HostName.Equals("Timed Out"))
{
//Create a listItem so that the server can be added in one go to the listViewServer control
System.Windows.Forms.ListViewItem theServer = new System.Windows.Forms.ListViewItem(myServer.HostName.ToString());
//Add the servers' host name.
System.Windows.Forms.ListViewItem.ListViewSubItem item1 = new System.Windows.Forms.ListViewItem.ListViewSubItem (theServer, myServer.Ip.ToString() + ":" + myServer.Port.ToString());
//Add the servers' ip address and port number.
System.Windows.Forms.ListViewItem.ListViewSubItem item2 = new System.Windows.Forms.ListViewItem.ListViewSubItem (theServer, myServer.MapName.ToString());
//Add the number of players and total number of players allowed.
System.Windows.Forms.ListViewItem.ListViewSubItem item3 = new System.Windows.Forms.ListViewItem.ListViewSubItem (theServer, myServer.NumPlayers.ToString() +"/" + myServer.MaxPlayers.ToString());
//Add the servers' ping time.
System.Windows.Forms.ListViewItem.ListViewSubItem item4 = new System.Windows.Forms.ListViewItem.ListViewSubItem (theServer, myServer.Ping.ToString()+ "ms");
//Add if the server is a favourite.
System.Windows.Forms.ListViewItem.ListViewSubItem item5 = new System.Windows.Forms.ListViewItem.ListViewSubItem (theServer, "");
//Add the SubItems to the item.
theServer.SubItems.Add(item1);
theServer.SubItems.Add(item2);
theServer.SubItems.Add(item3);
theServer.SubItems.Add(item4);
theServer.SubItems.Add(item5);
theServer.Tag = myServer.serverID.ToString();
//Add the item to the listView.
listViewServers.Items.Add(theServer);
}
}
Monitor.Exit(servers);
status.labelRefresh.Text = "Refreshing Servers (" + (status.progressBarDownloading.Value) +"/" + status.progressBarDownloading.Maximum.ToString() + ")...";
status.progressBarDownloading.Value = status.progressBarDownloading.Value + 1;
startPoint++;
}
Thread.CurrentThread.Abort();
}
catch (Exception ex)
{
MessageBox.Show(ex.ToString());
}
}
}
|
|
|
|
|
You can use the lock keyword against an instance of an object (use a static object like the Type - using typeof(YourClass) - for static objects, and an instance member for instance resources). This uses the Monitor when it compiles, but it does so in a better way than what you've done (which doesn't take exceptions into account). For example, the following block:
lock(typeof(MyClass))
{
} translates to
Monitor.Enter(typeof(MyClass));
try
{
}
finally
{
Monitor.Exit(typeof(MyClass));
} This way, if an exception occurs where the comment is, the handle is unlocked. There are many other locking mechanisms you should read about in the System.Threading namespace class documentation in the .NET Framework SDK.
Note also that any implementation of ICollection must implement a SyncRoot (a property that returns an object that can be locked) that you can use to synchronize access to a collection or list. Other classes have such support, too, and some even can generate a synchronized instance for you (see Hashtable.Synchronized , for example).
Microsoft MVP, Visual C#
My Articles
|
|
|
|
|
I'm trying to use WNetEnumResource() in C#. I've imported the functions from the system DLL's, allocated buffer memory etc but there's one little step that's got me beat. My code looks approximately like this (extraneous guff removed).
[StructLayout(LayoutKind.Sequential)]
private struct NETRESOURCE
{
public uint dwScope;
public uint dwType;
public uint dwDisplayType;
public uint dwUsage;
public string lpLocalName;
public string lpRemoteName;
public string lpComment;
public string lpProvider;
};
<p>
[DllImport("Mpr.dll", EntryPoint="WNetEnumResourceW",
SetLastError=true, CallingConvention=CallingConvention.Winapi)]
<p>
unsafe private static extern ErrorCodes WNetEnumResource(
IntPtr hEnum, ref uint lpcCount, byte *buffer, ref uint lpBufferSize);
<p>
private unsafe void EnumerateServers()
{
uint bufferSize = 16384;
byte *buffer = (byte *) Marshal.AllocHGlobal((int) bufferSize);
IntPtr handle = (IntPtr) 0;
ErrorCodes result;
uint cEntries = 1;
<p>
result = WNetOpenEnum(ResourceScope.RESOURCE_GLOBALNET, ResourceType.RESOURCETYPE_ANY, 0, 0, out handle);
<p>
if (result == ErrorCodes.NO_ERROR)
{
aData.Add("WNetOpenEnum succeeded");
<p>
do
{
result = WNetEnumResource(handle, ref cEntries, buffer, ref bufferSize);
<p>
if (result == ErrorCodes.NO_ERROR)
{
NETRESOURCE *p = (NETRESOURCE *) buffer;
}
else if (result != ErrorCodes.ERROR_NO_MORE_ITEMS)
break;
} while (result != ErrorCodes.ERROR_NO_MORE_ITEMS);
}
else
aData.Add("WNetOpenEnum failed");
<p>
Marshal.FreeHGlobal((IntPtr) buffer);
}
As you can see, I've declared the 3rd parameter (the buffer) in the call to WNetEnumResource() function as a byte pointer and used the Marshal.AllocHGlobal to allocate a buffer. Single stepping through the code shows that the initial WNetOpenEnum() succeeds as does the WNetEnumResource() call.
What I can't seem to do (no matter what I try) is to cast the buffer to a pointer to a NETRESOURCE structure. The compiler informs me that I can't take the address or the size of a managed type.
I've probably missed something blindingly obvious but any hints or help would be appreciated.
Rob Manderson
Paul Watson wrote:What sense would you most dislike loosing?
Ian Darling replied.
Telepathy
Then I'd no longer be able to find out everyones dirty little secrets The Lounge, December 4 2003
|
|
|
|
|
And, of course, after posting this I got to thinking and realised I'm bringing a c++ approach to the problem. A bit of spelunking around in System.Runtime.InteropServices revealed the Marshal.PtrToStructure() function which, after changing the NETRESOURCE into a class rather than a struct solves the problem nicely.
Is there a better approach?
Rob Manderson
Paul Watson wrote:What sense would you most dislike loosing?
Ian Darling replied.
Telepathy
Then I'd no longer be able to find out everyones dirty little secrets The Lounge, December 4 2003
|
|
|
|
|
You don't need to use an unsafe context. Instead of using byte* just use ref byte ; ref and out should typically be used for pointers to value types, while they shouldn't be used for reference types - since they're already references - exception when a pointer to a pointer is needed.
Instead of declaring your param as an IntPtr for your struct or enum, you can typically use the ref keyword as well. Take, for example, the typical declaration of SendMessage :
[DllImport("user32.dll")]
private static extern IntPtr SendMessage(IntPtr hWnd, int handle,
IntPtr wParam, IntPtr lParam); This means that if you want to pass a pointer to a struct (say, for a window message to a common control) that you have to use the method Marshal.StructureToPtr and then pass it. Instead, a much easier - and perfectly ligitimate - alternative would be like so:
[DllImport("user32.dll")]
IntPtr SendMessage(IntPtr hWnd, int msg,
ref MyStruct wParam, IntPtr lParam); All this is done without requiring an unsafe context, which is typically only useful for when you have to perform address references or allocate memory for native calls without using CoTaskMemAlloc or GlobalAlloc (which are available from the Marshal as managed calls).
Keep these things in mind, remember that enums are value types too, and you should find a better, easier alternative.
Microsoft MVP, Visual C#
My Articles
|
|
|
|
|
You're absolutely right. I iterated my way to a working solution using the unsafe keyword and then, following your advice here, removed it and it still compiles and works.
I kinda feel much like I did 15 or so years ago when I was learning how many *'s to bung in front of a pointer to dereference it Heh I'm still in the early stages of learning C#
My final solution looks like this:
[DllImport("Mpr.dll", EntryPoint="WNetEnumResourceA",
CallingConvention=CallingConvention.Winapi)]
<p>
private static extern ErrorCodes WNetEnumResource(
IntPtr hEnum, ref uint lpcCount, IntPtr buffer,
ref uint lpBufferSize);
I guess I have a little way to go in unlearning the pointer way. Nonetheless, I still had problems with trying to handle the IntPtr buffer parameter. I could see that I was getting back the correct values but could see no way to convert the buffer into a struct (in the sense of being able to use struct members to refer to the various fields).
I changed the struct to a class (thanks to Inside C# by Tom Archer) and wrote this line...
Marshal.PtrToStructure(buffer, p);
where p is a NETRESOURCE instance and now I can reference each value using p. syntax. You can see that I was thinking in c++ terms and trying to cast a pointer to a different type.
Hmmm this works but I can't see how to call the WNetEnumResource function in such a way as to return more than 1 instance of the NETRESOURCE structure. The Marshal.PrtToStructure method gives me no way to step down the buffer to the second instance, or the third, of the NETRESOURCE structure within the buffer given that I cannot take a sizeof or the address of a managed object. I can see why the compiler forbids me this
On the other hand, I can't see how to do it in c++ either This is a port of some code I wrote in c++ and, single stepping through the c++ code, I see that each time (whatever value I set as the count of entries to be returned) it returns 1 entry. This makes sense actually - the MSDN entry for the WNetEnumResource API says that the buffer must be large enough to contain not only the NETRESOURCE structure itself but also the strings it points to (which is why I allocated a very large buffer). I'm guessing that the API fills in the structure values and copies the strings immediately afterward - and if it does that then one can't use standard c++ pointer arithmetic to step down the buffer.
Rob Manderson
Paul Watson wrote:What sense would you most dislike loosing?
Ian Darling replied.
Telepathy
Then I'd no longer be able to find out everyones dirty little secrets The Lounge, December 4 2003
|
|
|
|
|