|
Thanks for ur response Dan,
Actually I was giving the full quialified name for the file but the problem was somewhere else. and It got sorted out when i used the
'MSXML2::'
before the ambiguious names. It was addressed on the Microsoft website, surrently I dont have the URL with me. but I have sorted it out thankfully
Rocky
You can't climb up a ladder with your hands in your pockets.
|
|
|
|
|
Ahhhh there was an ambiguity between some function/object, so you may have had msxml2::DoSomething() and std::DoSomething and it didnt know which to choose so fully qualifying the function/object sorts it.
Any ways glad you sorted it.
Dan
|
|
|
|
|
Hello,
I wrote a managed C++ wrapper to integrate an unmanaged DLL into my C# application. From within this wrapper I have to pass a list of structures to C#:
struct structTwo{
int signal_value;
char text_info[PARSER_MAXSTRLEN];
};
struct structOne
{
int num_of_logical_values;
structTwo* logical_value; //<-- This is the list of the above structure
int num_of_physical_ranges;
int num_of_bcd_ranges;
int num_of_ascii_ranges;
};
So with one call to C# I would like to pass the whole structOne including the list of structTwos. Ok?
Passing a list of strings or INTs works fine using an ArrayList as parameter type:
ArrayList* stringList= new ArrayList();
for (int i=0; i<sporadic_frame_entries->num_of_frame_entries; i++)
{
stringList->Add(new String(theString));
}
Can I do this with the structure too? I tried several things but somehow I can't figure out.
Can someone suggest an appropriate solution?
thx
Steffen
|
|
|
|
|
IMHO there is no point in making C# code deal with a native structure when the memory must be marshaled anyway. Design a manged OO API and let the C++/CLI code deal with marshaling the memory from the native structures to the managed classes.
|
|
|
|
|
Thanks, that seems reasonable to me. I'll give it a try....
|
|
|
|
|
I'm writing managed c++ / CLI dll that calls unmanaged dlls. Up till here everything is splendid.
The unmanaged dll itself fails using its own resources.
The unmanaged dll's dllMain is called and hence CDynLinkLibrary, but when calling the unmanaged dll's exported functions, I get ASSERTS;
For example in dlgcore.cpp when trying to CDialog::create
if (!_AfxCheckDialogTemplate(lpszTemplateName, FALSE))<br />
{<br />
ASSERT(FALSE);<br />
....<br />
Just to be clear - I'm not trying to use the unmanaged resources, rather the unmanaged dll itself tries to access them and asserts.
Any buyers?
|
|
|
|
|
Hi, I am using Visual Studio 2005 C++/CLI. What is it that is responsible for painting a DataGridView control on the screen? I am using a DataGridView Control to represent a silicon wafer with 12,000 die on it. If I make the height and width of each cell very small I can represent the wafer on my display, it just takes ten seconds to paint the screen (and then another 10 seconds before the controls that I have progamatically added become active). I have turned the DataGridView's "Causes Validation" property to false and have remarked out any Paint routines in my application. Then I instantiate a gcnew dataGridViewForm and use dataGridViewForm->ShowDialog() which slowly then displays the DataGridView control. Since it does not take 10 seconds to paint the screen I think that something is causing a repaint for each cell in the DataGridView control which would be 12,000 repaints total (which may or may not take a while, I don't know). Is this what might be happening? And if so is there a way to disable the painting until the grid has completed drawing itself (internally)?
Thanks
Buck
|
|
|
|
|
Hi Buck,
still drawing wafers?
all Controls get painted by the Paint event; when you make a Form visible, it will show
(hence paint) all the items in its Controls property (unless they are flagged invisible);
furthermore it will execute an OnPaint method if available, and it will invoke whatever
you may have added to the Paint event (with Paint+=gcnew PaintEventHandler(...)).
if you modify the DGV once it is painted, it will be repainted; hence you should not
just add items to it, that would become very slow unless you do it while invisible,
or you turn it off temporarily (I guess with SuspendLayout or maybe BeginUpdate).
How many Controls does your form have? Normal forms have no more than say 50 Controls;
exceeding this number will make things slow.
are you sure you need one big DGV? is it just for painting? if so, consider the
light-weight approach: have a single Panel, and write the code to draw your 12000 chips
in one (or two) big for loops inside a single Paint handler. That would take a fraction
of a second. If later on you need to process say mouse events per chip, let the same
Panel catch the mouse event and convert the Panel-relative coordinates to a chip position...
Hope this helps.
Luc Pattyn [Forum Guidelines] [My Articles]
this weeks tips:
- make Visual display line numbers: Tools/Options/TextEditor/...
- show exceptions with ToString() to see all information
- before you ask a question here, search CodeProject, then Google
|
|
|
|
|
Hi Luc,
Your second paragraph looks like the approach I need to take. My rational for using one big DGV is why I am still drawing wafers, but they're different problems. The initial drawing of a wafer was to read a file of failed die at x-y coordinates and represent them graphically. In order to let the application know which [x, y] array elements are valid die (vs. invalid) and inked die I have to look at the wafer under the microscope and count the number of rows and columns in each row. Then reproduce this in a Word document. Then sit down and manually select rectanglar areas of the wafer that will be defined as possible passing die and also die that will always be inked. The definition looks something like BIN0(X1, Y1, X2, Y2) and there can be a hundred of these in order to define the entire wafer (don't blame me, this is the way the definitions were setup long before I got here). What I am able to do with a DGV is be able to use the mouse to click on the die (DGV cell) for the upper left corner of the rectangular area and then click on the die (DGV cell) for the lower right corner of the rectangular area and then write this information to the configuration file that I currently define with a text editor. This new method (even if I can't make it faster in displaying) will be far less time consuming than doing it manually. SIDE NOTE: I remarked out all Paint() and OnPaint() methods in my application, so the DGV is causing an operating system Paint() to occur.
Thanks,
Buck
|
|
|
|
|
I don't know. I think the way the DataGridView control is painted is a function of the control. Once I display the Form (that takes 10 seconds to paint the DGV control) I can click on another running app at the bottom of the screen and when I click back on the Form that contains the DGV control the painting of the control is not all at once it is still done by painting row 0 col 1, row 0 col 2, row 0 col 3, etc. I was hoping that by setting the CausesValidation property to false that no painting would be done until an Invalidate() was issued, but that is not the case. I'm sure that some Windows guru might know how to do this but as an old UNIX guy I try not to get into the intricacies of the Windows message pump. I'm going to spend the day researching the DGV control and the GDI+, but I have a feeling I'm trying to use this control in a way that the original designers were not thinking of.
Buck
|
|
|
|
|
Hi Luc,
The documentation that I have been reading states that cells paint themselves. I have at least been able to speed things up a bit. By using the RowPrePaint event I can then set the e->PaintParts = DataGridViewPaintParts::Background | DataGridViewPaintParts::SelectionBackground; This at least paints the screen in a couple of seconds instead of 10. I have been trying to figure out how to paint the whole row. There is a sentence in the documentation that says "A row or column performs no painting". If you ask me, painting everything at the cell level is stupid.
Buck
|
|
|
|
|
Hi Buck,
I am unfamiliar with the DGV control, but I performed some experiments with a Panel
and drawing/dispatching events myself. This is the C# code involved:
using System;
using System.Drawing;
using System.Windows.Forms;
namespace wafer {
class Chip {
public Rectangle rect;
public bool inked;
public string name;
public void Paint(Graphics g) {
if(inked) g.FillRectangle(Brushes.Red, rect);
g.DrawRectangle(Pens.Black, rect);
}
}
class WaferPanel : Panel {
private int hor;
private int vert;
private Chip[,] chips;
private Random rand=new Random();
private static Font font=new Font("Courier New", 7);
public WaferPanel(int hor, int vert, bool doubleBuffered) {
if(doubleBuffered) {
SetStyle(ControlStyles.AllPaintingInWmPaint|
ControlStyles.OptimizedDoubleBuffer|
ControlStyles.UserPaint, true);
}
log("WaferPanel.ctor");
this.hor=hor;
this.vert=vert;
chips=new Chip[hor,vert];
for(int i=0; i< hor; i++) {
for(int j=0; j< vert; j++) {
Chip c=new Chip();
chips[i, j]=c;
c.inked=rand.Next(10)==0;
c.name=i.ToString()+","+j.ToString();
}
}
BackColor=Color.White;
}
private void log(string s) { Console.WriteLine(s); }
protected override void OnResize(EventArgs e) {
int W=Width;
int H=Height;
log("WaferPanel.OnResize: W="+W+" H="+H);
int w=(W-100)/hor;
int h=(H-100)/vert;
if(w<4) w=4;
if(h<4) h=4;
log("WaferPanel.OnResize: w="+w+" h="+h);
int x0=(W-w*hor)/2;
int y0=(H-h*vert)/2;
log("WaferPanel.OnResize: x0="+x0+" y0="+y0);
for(int i=0; i< hor; i++) {
for(int j=0; j< vert; j++) {
Chip c=chips[i, j];
c.rect=new Rectangle(x0+i*w, y0+j*h, w-3, h-3);
}
}
}
protected override void OnPaint(PaintEventArgs e) {
log("WaferPanel.OnPaint");
Graphics g=e.Graphics;
for(int i=0; i< hor; i++) {
Chip c=chips[i, 0];
g.DrawString(i.ToString(), font, Brushes.Black, c.rect.X, 10);
}
for(int j=0; j< vert; j++) {
Chip c=chips[0, j];
g.DrawString(j.ToString(), font, Brushes.Black, 10, c.rect.Y);
}
for(int i=0; i< hor; i++) {
for(int j=0; j< vert; j++) {
Chip c=chips[i, j];
c.Paint(g);
}
}
}
protected override void OnMouseClick(MouseEventArgs e) {
Point pt=new Point(e.X,e.Y);
Chip hit=null;
foreach(Chip c in chips) {
if(c.rect.Contains(pt)) hit=c;
}
if(hit==null) {
Console.Beep();
} else {
log("WaferPanel.OnMouseClick hit "+hit.name);
hit.inked=!hit.inked;
Invalidate(hit.rect);
}
}
}
}
Hope this helps.
-- modified at 13:52 Wednesday 26th September, 2007 (HTML repairs)
Luc Pattyn [Forum Guidelines] [My Articles]
this weeks tips:
- make Visual display line numbers: Tools/Options/TextEditor/...
- show exceptions with ToString() to see all information
- before you ask a question here, search CodeProject, then Google
|
|
|
|
|
Hi Buck,
I also tried to mail you a small ZIP file at toko but got an automatic reply "User quota exceeded"...
Luc Pattyn [Forum Guidelines] [My Articles]
this weeks tips:
- make Visual display line numbers: Tools/Options/TextEditor/...
- show exceptions with ToString() to see all information
- before you ask a question here, search CodeProject, then Google
|
|
|
|
|
BuckBrown wrote: I am using a DataGridView Control to represent a silicon wafer with 12,000 die on it
That might be considered abuse of that control. A grid control, any of them, is going to draw each cell to the screen. I don't know what your requirements are but the opposite of that approach is to draw the entire wafer in memory and then paint it to the screen. The difference in performance between those two approaches would be significant.
|
|
|
|
|
Hi Mike,
Yes, the idea of drawing the entire wafer in memory and then painting it to the screen is exactly what I want to do but with no Paint() or OnPaint() method in my application the DGV still paints. I think Luc, in his response, has the right idea. In my response to him you can read about why it is I am doing this.
Thanks
Buck
|
|
|
|
|
I don't know. I think the way the DataGridView control is painted is a function of the control. Once I display the Form (that takes 10 seconds to paint the DGV control) I can click on another running app at the bottom of the screen and when I click back on the Form that contains the DGV control the painting of the control is not all at once it is still done by painting row 0 col 1, row 0 col 2, row 0 col 3, etc. I was hoping that by setting the CausesValidation property to false that no painting would be done until an Invalidate() was issued, but that is not the case. I'm sure that some Windows guru might know how to do this but as an old UNIX guy I try not to get into the intricacies of the Windows message pump. I'm going to spend the day researching the DGV control and the GDI+, but I have a feeling I'm trying to use this control in a way that the original designers were not thinking of.
Buck
|
|
|
|
|
It is (as other mentioned) an abuse if the controls. You better think about writing a own controls: ownerdrawn and a data structure which fullfills your needs as change of status and selections. Then you will better control YOUR Paint function and can optimize it. (Memory DC and only draw changes)
This sounds like a bunch of work but the result will be worth it.
Greetings from Germany
|
|
|
|
|
I'm trying to mimic the pipe capability of a unix command line in windows(2003 Ent. Ed).
My unix shell script executes the following:
~~~~~~~~~~~~~~~~~~start~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
mknod exp_pipe_dmp p
exp user/passwd@SID parfile=mydb.par &
gzip < exp_pipe_dmp > exp_sid.dmp.gz
~~~~~~~~~~~~~~~~~~~end~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Exp is an oracle command-line utility to create a database dump file(binary).
We execute the exp command in the background then immediately redirect "<"
the contents of the 'pipe' file to gzip and gzip then creates it's own
file, exp_sid.dmp.gz.
The importance of solving this problem:
On unix, Solaris, Linux the exp and the gzip execute simultaneously!
I have not been able to do this using Dave Roths Win32 perl packages, the Win32::API
or IPC::Run. I have turned to C, C++ or even C# to try to accomplish this but have not been able to reproduce this.
I can create a named pipe with the OVERLAPPED struct. I can open the pipe using a simple client as provided by the MSDN but I cannot write to the pipe and also read from it simultaneously - the exp process executes first THEN the gzip processes the pipe contents. I tried to create a stream file instead and the same exact thing occurs.
My goal is to save time. Any direction torward solving would be a great help. I document all code with references from ALL sources and would identify contributors to this effort.
Thanks,
Tracy
|
|
|
|
|
higgsbo wrote: to create a database dump file
what does that mean? Are you putting an image of the database into the zip file, like a backup or something?
|
|
|
|
|
Check the parameter for creating the pipe, there some values for bidirectional use. Or create 2 pipes one for "read" and onr for "write" pipe: 1=>2 and 2=>1
Greetings from Germany
|
|
|
|
|
Hi,
Please consider the following code fragment in C++/CLI (I am quoting from memory )...
Assembly^ a = Assembly::LoadFile("MyTypes.dll");<br />
Type^ myType = a->GetType("MyNamespace.MyClass");<br />
Object^ obj = Activator::CreateInstance(myType);<br />
<br />
IMyInterface^ itf = (IMyInterface^)obj;
The last line throws an invalid cast exception even if MyClass implements IMyInterface. Any idea whats going on and how to solve this problem?
SDX2000
|
|
|
|
|
Where is "IMyInterface" located? Is it in "MyTypes.dll"? If not, is the assembly containing "IMyInterface" common to the current code and the loaded assembly? Are you using a "using namespace MyTypes;" somewhere in your code?
"We make a living by what we get, we make a life by what we give." --Winston Churchill
|
|
|
|
|
Hi George,
Thanks for responding. IMyInterface is located in the same assembly (say MyLoader) which is trying to load MyTypes.dll, in other words its not located in MyTypes.dll.
A reference to MyLoader has been added while compiling MyTypes.dll.
I am not using "using namespace MyTypes;" anywhere. Actually I don't want to. Doing so will defeat the purpose of interface based programming.
You could think of this as a plugin based application where the main application has been written in C++/CLI and the plugins can be written in any language. Its not possible for me to add the references to all present and future plugins while compiling MyLoader.
Regards,
SDX.
SDX2000
|
|
|
|
|
Please note that two identical interfaces created in two different assemblies are not the same type. Thus, you will get casting errors.
Using namespaces does not defeat the purpose of interface programming. The .NET Framework is an example of that.
"We make a living by what we get, we make a life by what we give." --Winston Churchill
|
|
|
|
|
George, I think I was bit hasty in describing my problem. I agree with you "Using namespaces does not defeat the purpose of interface programming." but that is not what I meant.
Thanks for your help anyway. I have found the reason why I was getting an Invalid cast exception. An invalid cast exception may be generated due to missing assemblies! (consider Assembly1::Class1 extends Assembly2::Interface1). (Note:Assemblies can be in the same folder and still be missing!) refer suzzane cooks blog http://blogs.msdn.com/suzcook/archive/2004/06/02/debugging-an-invalidcastexception.aspx
The best way to accelerate a Macintosh is at 9.8m/sec-sec.
- Marcus Dolengo
|
|
|
|