|
No, it doesn't. You also cannot make just a single control click-through. It's the entire form, or nothing.
Dave Kreskowiak
Microsoft MVP - Visual Basic
|
|
|
|
|
Ok, I'll try to ask for another variant - more simple.
TRANSPARENT FOR MOUSE MOVES AND CLICKS - dont pay attention to this feature for now.
Just - opaque control
----------------------------
lalala, I'm from Ukraine
|
|
|
|
|
My current C#.NET project is MDI-based.
I am using a user control that has 10 textboxes. This user control is repeated 20 times on a screen. (that gives 200 textboxes on the screen)
When I refresh the screen, I can see every textbox being drawn to the screen from top to bottom. The desired behaviour is that the screen should appear in a flash without any rollover effect.
Currently, the screen gets refreshed at a rate of 35 milliseconds. We need to minimize this to 2-3 milliseconds.
I found that When one textbox of the usercontrol refreshes, internally Paint Event of that control is raised.
The textbox Paint Event internally raises its container's (user control's) paint event.
Subsequently, the user control raises paint event of all textboxes in it.
So I tried to suppress raising the Paint Event of usercontrol when the textbox is refreshed. (by Override OnPaint and Override OnPaintBackground event).
Also, double buffering is used.
But this has not helped much.
Is there a way we can accomplish a refresh rate of < 5 milliseconds?
|
|
|
|
|
SwEr wrote: Is there a way we can accomplish a refresh rate of < 5 milliseconds?
Don't try to do so much in the painting. 200 textboxes is excessive - do you really need that many on screen at one time? A user can only use 1 at a time, and only look at a couple at a time.
|
|
|
|
|
I think you'll find the problem is that the background is painting over the textboxes before the textboxes are re-drawn.
You should be able to override the PaintBackground event of whatever contains the text boxes, and draw the background yourself without painting over the text boxes.
|
|
|
|
|
SwEr wrote: Currently, the screen gets refreshed at a rate of 35 milliseconds. We need to minimize this to 2-3 milliseconds.
With that level of refresh this window must be display only window (read-only). If that is the case using all those controls is just a bad idea. You might look into just painting that data or something.
led mike
|
|
|
|
|
Each user control, represents a device. The text boxes in the user control would display the devices' dynamic properties. There would be as many user controls as the number of devices. Right now i am assuming only 20, but in reality could be much more. I cannot replace the user controls with a datagrid as the number of properties to be displayed would be different for each device. The user control as such is rendered by the device library. All these user controls are placed in a form container. The entire data received from devices needs to be displayed on one screen (no tabs,etc) as the user needs to continuously monitor it.
Is it possible to handle this at a lower level? (like drawing the data into an off screen version of the Form and then copying it on screen in one shot).
Any thoughts?
|
|
|
|
|
Is it for SCADA, DCS or instrumentation?
Most of these application doesn't use standard form and controls.
You can check out SL-GMS or Wonderware for these kind of instrumentation displaying. I am sure there are others.
|
|
|
|
|
Greetings!
I'm trying to connect to a database and read certain fields from it. I'm unable to read any fields from it and would appreciate your help debugging/fixing the problem.
Here is what I have:
1. A file that acts has the database interface code:
<br />
public class AppDatabaseInterface<br />
{<br />
<br />
private string m_cstrDefaultdbDir = "C:\\";<br />
<br />
private const string m_cstrDBFileName = "DefaultDatabase.mdb";<br />
<br />
private System.Data.OleDb.OleDbConnection m_dbConn;<br />
<br />
public AppDatabaseInterface()<br />
{<br />
System.Reflection.Assembly assm =<br />
System.Reflection.Assembly.GetAssembly(System.Type.GetType("AppDatabase.AppDatabaseInterface"));<br />
m_cstrDefaultdbDir = System.IO.Path.GetDirectoryName(assm.CodeBase.ToString());<br />
m_cstrDefaultdbDir = m_cstrDefaultdbDir.Remove(0, 6);
<br />
OpenDatabase();<br />
}<br />
<br />
<br />
private void OpenDatabase()<br />
{<br />
lock (this)<br />
{<br />
if (m_dbConn == null)<br />
{<br />
m_dbConn = new OleDbConnection();<br />
}<br />
else<br />
{<br />
if (m_dbConn.State != ConnectionState.Closed)<br />
{<br />
m_dbConn.Close();<br />
}<br />
}<br />
<br />
try<br />
{<br />
m_dbConn.ConnectionString = string.Format(<br />
@"Provider=Microsoft.Jet.OLEDB.4.0; Data Source={0}\{1};",<br />
m_cstrDefaultdbDir, m_cstrDBFileName);<br />
}<br />
catch<br />
{<br />
Console.WriteLine("Could not open database");<br />
}<br />
m_dbConn.Open();<br />
<br />
}<br />
}<br />
2. The "Makes" Method
Here's the "Makes" method in the AppDatabaseInterface.cs file
<br />
public string[] Makes<br />
{<br />
get<br />
{<br />
OleDbDataReader dbr = null;<br />
ArrayList Makes = new ArrayList();<br />
<br />
OleDbCommand cmd = new OleDbCommand(string.Format("SELECT * FROM {0};", "Speakers"), m_dbConn);<br />
dbr = cmd.ExecuteReader();<br />
<br />
while (dbr.Read())<br />
{<br />
for (int it = 0; it < dbr.FieldCount; it++)<br />
{<br />
string strField = dbr.GetName(it);<br />
if (strField == "MAKE")<br />
{<br />
string make = (string)dbr.GetValue(it);<br />
bool found = false;<br />
foreach (object o in Makes)<br />
{<br />
if ((string)o == make)<br />
{<br />
found = true;<br />
break;<br />
}<br />
}<br />
if (found)<br />
Makes.Add(make);<br />
break;<br />
}<br />
<br />
}<br />
<br />
}<br />
string[] strMakes = new string[Makes.Count];<br />
int i= 0;<br />
foreach (object o in Makes)<br />
{<br />
strMakes[i++] = (string)o;<br />
}<br />
return strMakes;<br />
}<br />
}<br />
3. The actual UI form
<br />
public partial class frmAppDatabase: Form<br />
{<br />
AppDatabaseInterface m_database;<br />
<br />
public frmSpeakerDatabase()<br />
{<br />
InitializeComponent();<br />
<br />
m_database = new AppDatabaseInterface();<br />
<br />
string[] strSpeakerMakes = m_database.Makes;<br />
<br />
for (int i = 0; i < strSpeakerMakes.Length; i++)<br />
{<br />
cbSpeakerMakes.Items.Add(strSpeakerMakes[i]);<br />
}<br />
}<br />
What I want this portion of the code to do is to fill in the combobox with the various items from the specified field in the database. However, I see nothing.
The Access file is in the \bin\debug directory of the project.
Could you please advice me as to what is wrong?
Thanks!
-- modified at 13:54 Friday 22nd September, 2006
|
|
|
|
|
Are you getting a run-time error or are you just not seeing anything displayed when you are trying to populate your combobox? I haven't analyzed your code thoroughly yet, but try putting a breakpoint in the for loop that populates "Makes" from the db table to see if you're actually getting data out of it. If you ARE getting the correct data out of the table, follow the debugger down until you lose it. Reply back with what you find. (I don't have .NET available right now so I can't plug your code into a project to debug it yourself. ....So help me help you......help me......help you lol)
|
|
|
|
|
Thanks for your reply!
There is no run-time error. The code compiles and runs just fine. The form comes up but the combo box has nothing in it.
I've stepped through the code to make sure that the database connection sees the Access file.
|
|
|
|
|
...I think your problem is that you are executing a query rather and not storing it in an OleDbReader object. (this is all off the top of my head, mind you) If you are in VS, use Intellisense to see what db.ExecuteReader() returns...I think it's an OleDbReader object. You need to store the results in one and read from it instead of your db connection. I don't believe that "db" as you have defined it will work the way you are wanting to to work. You need a companion class to hold the results of a query and read from it. I can help you out with that, but I don't have the files handy. I'll get them real quick and I'll be back.
|
|
|
|
|
Yup...I was right. You need to store your "db.ExecuteReader" results in an OleDbReader object. I referred to a project that I'm currently working on and I think I might be able to help you out a little bit. I've only included the relevant portions of my code, but I accomplished exactly what you are trying to do. I wanted to populate a combobox with the contents of my "category" table. I'm not finished copying (Having to write it down by hand and bring it over...my development computer is not "plugged in" to my network) I'm going to go back, get more code and place it here in an edit. I'll let you know at the end of this post what I'm going to be bringing back next post
...a little bit of explanation. I have 2 classes (clsDatabase & clsQueryResults) that provide a layer of abstraction away from ADO.NET. This allows me to separate my application logic from database management commands.
The form code:
private void form_Load(object sender, System.EventArgs e)
{
ArrayList mCategoriesToDisplay = Manager.getAllCategories();
foreach(clsManager.clsCategory cat in mCategoriesToDisplay)
{
this.cbCategory.Items.Add(cat.Title);
}
}
"clsManager" code ...I use "clsManager" as a mediator to perform network and assembly linkage. If I were developing a desktop app, this would not be needed...just thought it might be helpful to explain why this layer of abstraction is even present
clsCategoryList mCategoryList;
.
.
.
public ArrayList getAllCategories()
{
return mCategoryList.getAllCategories();
}
"clsCategoryList" is basically my own way of holding my category objects. getAllCategories returns an ArrayList of clsCategory objects
public ArrayList getAllCategories()
{
string sql = "Select * From Category";
clsQueryResults resultSet = new clsQueryResults();
resultSet.Open(mDatabase, sql);
while(!resultSet.EOF)
{
clsCategory category = new clsCategory();
category.RestoreStateFromQuery(resultSet);
Categories.Add(category);
resultSet.NextRecord();
}
return Categories
}
The code I will bring you in my next post will be what happens when we move closer to ADO.NET as well as what happens inside the actual "clsCategory" object. ...clsCategory is the only place along the "data chain" that can actually interface with a clsDatabase object and a clsDatabase object is the only thing that can actually communicate with Access.
inside "clsQueryResults"
public void Open(clsDatabase database, string sqlQuery)
{
mProvider = database.getProvider;
if(mProvider.Equals("OLEDB"))
{
if(database.State == System.Data.ConnectionState.Open)
{
mOleReader = database.ExecuteQuery(sqlQuery)
}
}
else if(mProvider.Equals("SQLSRVR"))
{
}
NextRecord();
}
public void NextRecord()
{
if(mProvider.Equals("OLEDB"))
{
mEOF = !mOleReader.Read();
}
}
public bool EOF
{
get
{
return mEOF;
}
}
"clsDatabase" stuff
private OleDbConnection mDatabase = null;
.
.
.
public clsDatabase(string connectionString, string provider)
{
databaseProvider = provider.ToUpper();
connection = connectionString.ToUpper();
if(databaseProvider.Equals("OLEDB"))
{
mDatabase = new OleDbConnection();
mDatabase.ConnectionString = connectionString;
}
}
public OleDbDataReader ExecuteQuery(string sqlQuery)
{
OleDbCommand OleCmd = null;
if(mDatabase.State == System.Data.ConnectionState.Open)
{
OleCmd = new OleDbCommand();
OleCmd.Connection = mDatabase;
OleCmd.CommandText = sqlQuery;
}
return OleCmd.ExecuteReader();
}
"clsCategory"
.
.
.
public void RestoreStateFromQuery(clsResultSet resultSet)
{
this.Title = resultSet.GetColumnValue("CategoryTitle");
}
I did not include clsResultSet's "GetColumnValue" method...I left a little bit for you to do for yourself. Look up OleDbDataReader on the MSDN to find out how you should define this method. You're going to be looking specifically for "GetOrdinal" and "GetValue". I hope this helped out a little bit....actually I hope it helped a lot.
-- modified at 17:18 Friday 22nd September, 2006
|
|
|
|
|
Wow... thanks, mate! You're a huge help... I really appreciate this!
I just figured out that making the following change in my AppDatabaseInterface.cs file did the trick for me:
<br />
if (!found)<br />
alMakes.Add(make);<br />
but your approach on the whole seems better and I'm going to look into it.
Thank you very much!
N.
|
|
|
|
|
You're not using an object oriented design are you? I assume from your variable names that you're doing something with sound equipment?? Typically, you would do something like the following
public class clsSpeaker
{
private string mMake;
private string mModel;
public Speaker()
{
mMake = "";
mModel = "";
}
public void RestoreStateFromQuery(clsResultSet rs)
{
this.mMake = rs.GetColumnValue("SpeakerMake");
this.mModel = rs.GetColumnValue("SpeakerModel");
}
public string Make
{
get
{
return mMake;
}
}
public string Model
{
get
{
return mModel;
}
}
}
...so now, you can just instantiate your clsSpeaker class inside your UI, Deserialize it from your database query, and then do the command that I included in my previous post labeled as "form code." It makes the code much more legible and bug tracing is a lot easier because your code is properly compartmentalized.
btw, put your code in "pre" tags instead of "code" tags...It's a lot easier to read. (Pre tags are what I used to post my code in this thread)
|
|
|
|
|
I want to make a service which can watch and log data send and recived when any internet connection activates. I will be thankful for any pointers and help.
|
|
|
|
|
|
how can we use list for string members
|
|
|
|
|
using System.Collections.Generic;
...
List<string> listOfStrings = new List<string>();
listOfStrings.Add("hello");
listOfStrings.Add("world");
|
|
|
|
|
List<string> strings = new List<string>();
strings.Add("Hello");
Something like this? Your question is not very precise.
regards
modified 12-Sep-18 21:01pm.
|
|
|
|
|
Hey, I'm making use of Iphlpapi.dll, particularily CreateIpForwardEntry(ref PMIB_IPFORWARDROW pRoute)
I'm a little unclear as to what format I need to be using for the MIB_IPFORWARDROW structure
This is my declaration (?) of the structure:
[StructLayout(LayoutKind.Sequential, CharSet = CharSet.Auto)]<br />
public struct PMIB_IPFORWARDROW<br />
{<br />
public UInt32 dwForwardDest;<br />
public UInt32 dwForwardMask;<br />
public UInt32 dwForwardPolicy;<br />
public UInt32 dwForwardNextHop;<br />
public UInt32 dwForwardIfIndex;<br />
public UInt32 dwForwardType;<br />
public UInt32 dwForwardProto;<br />
public UInt32 dwForwardAge;<br />
public UInt32 dwForwardNextHopAS;<br />
public UInt32 dwForwardMetric1;<br />
public UInt32 dwForwardMetric2;<br />
public UInt32 dwForwardMetric3;<br />
public UInt32 dwForwardMetric4;<br />
public UInt32 dwForwardMetric5;<br />
}
The ones I'm most confused about are dwForwardDest, dwForwardMask and dwForwardNextHop.
If I had a destination network of 10.11.0.0, mask 255.255.0.0 and the 'next hop' would be say... 10.11.7.3. The corresponding 'route add' command that I normally run from the command line is:
route add 10.11.0.0 mask 255.255.0.0 10.11.7.3
I get the feeling that I need to convert each octet to hex, but what do I do from there?
Any help would be greatly appreciated...
|
|
|
|
|
Converting each octet to hex doesn't get you any closer to a number. Instead you should convert each octet into a number, shift them and add them together.
For an example, the IP number 10.11.7.3 would add up as:
(10 << 24) + (11 << 16) + (7 << 8) + 3
---
b { font-weight: normal; }
|
|
|
|
|
I apologize, but I don't really understand what you're instructing me to do, what does (10 << 24) + ... mean?
Does anyone maybe have a bit of example code I could use as a guideline? I've found minimal assistance online so far..
|
|
|
|
|
The << operator shifts the first operand to the left the number of bits specificed by the second operand. As you have four bytes which should be positioned after each other in the uint, you shift the values to place the bytes at the correct position before adding them.
In binary it looks like this:
10 = 00001010
11 = 00001011
7 = 00000111
3 = 00000011
10 << 24 = 00001010000000000000000000000000
11 << 16 = 00000000000010110000000000000000
7 << 8 = 00000000000000000000011100000000
3 = 00000000000000000000000000000011
Adding them together gives the value:
00001010000010110000011100000011
Example code:
uint o1 = 10;
uint o2 = 11;
uint o3 = 7;
uint o4 = 3;
uint code = (o1 << 24) + (o2 << 16) + (o3 << 8) + o4;
---
b { font-weight: normal; }
|
|
|
|
|
OOOhhhhh that makes sense! Thanks a ton.
Should I be using uint instead of uint32? Not 100% sure what the difference is, will look it up a little later...
|
|
|
|