mcriscolo 47 Posting Whiz in Training

I want to make sure I'm not missing something here....

You have a class (Customer - perhaps implemented in "Customer.cs") that holds the data for a Customer/PrizeList. You want to be able to access this class in the event handler?

Can't you just declare a variable in the class (class global), then create a new instance of the class in the "Window_Loaded" event of the form (and do whatever you need to do to load the data)? You can then use this instance down in the event handler for "CellEndEdit"? Something like this:

public partial class MainWindow : Window
{
    private Customer c_oCust = null;

    public MainWindow()
    {
        InitializeComponent();
    }

    private void Window_Loaded(object sender, RoutedEventArgs e)
    {
        c_oCust = new Customer("Bob");
    }

    private void cmdOK_Click(object sender, RoutedEventArgs e)
    {
        if (c_oCust.TestCust(textBox1.Text))
        {
            MessageBox.Show("Yay!");
        }
        else
        {
            MessageBox.Show("The name in the object is: " + c_oCust.ToString());
        }
    }
}

That is, if the variable holding the instance of the "Customer" class is stored at the class level, any event handlers/methods should be able to see it.

Hopefully I'm not off the mark here and this helps.

mcriscolo 47 Posting Whiz in Training

Attached is some code that implements the base concept. Using the DLL, declare a new class, and have it implement the "IMsg" interface, and subclass the "BaseMsg" class, like so:

public class MyDataMsg : BaseMsg, IMsg

You then implement the "encode" and "decode" methods to put your object's specific data into the data stream. Finally, you use code like this:

byte[] baData = oMsg.encode();

to extract the data for your object as a byte array. You can push this over a socket, write it to a file, etc. When you want to decode it, you read the data into a binary array, then execute code like this:

MyDataMsg oNewMsg = new MyDataMsg();
oNewMsg.decode(byteArrayOfData);

Of course, there are always provisos. When you read the data from a socket, file, etc. - how do you know what type of object it was? The first 8 bytes of the data is the length and the "command id", respecitvely. Both are 4-byte integers, encoded onto the stream in Network (big-endian) format. When you read in the data, you extract the 2 ints, convert them to host format, then examine them to allocate a byte array large enough to hold all of the data, then use the "command id" to allocate the correct descendant of "BaseMsg". Finally, you can call the "decode" method to un-marshal the data and produce a new object with the data intact.

The sample program creates an object, writes it to a file, reads it back into …

mcriscolo 47 Posting Whiz in Training

They will always be there - IF - the corresponding version of the .NET Framework is installed on the target machine.

So, you would not include any of the individual DLLs with your application - you would check to see if the required version of the Framework is installed, and then use the Microsoft redistributable package to install it if needed.

Or, you can make it a prerequisite of your program, and impress upon the user to install the correct version before using your program.

mcriscolo 47 Posting Whiz in Training

Take a look at this post:

http://stackoverflow.com/questions/575977/choosing-between-immutable-objects-and-structs-for-value-objects

Be sure to read the comments under the second post - goes into a lot of detail concerning your question.

mcriscolo 47 Posting Whiz in Training

The main reason you see strings in all of these examples is that strings require the least amount of marshaling to push them across a connection. A string-based protocol is not necessarily a bad implementation; however, if you are in control of the client and server, then you can be a bit more elegant.

You may be able to use .NET object serialization. You declare your class then mark it as [Serializable]. You can then use the BinaryFormatter class to serialize and de-serialize your class to a stream. There are a lot of examples of .NET serialization on the web to examine.

Another approach is to create your own classes that wrap up the details of formatting your data into a byte array suitable for transmission over a socket. You can create a basic object – call it a "NetMsg" object that handles the basics of wrapping a message up into a byte array – for example, every message will probably have a distinct message type and a length. You can then derive a subclass from this class and add the details for the specifics of that type of message. You could have a "SaveDataNetMsg" object, for example. This message would override an “encode” method from the parent that would take the specifics of a “SaveData” message and encode them into a byte array (the base class would take care of encoding the length and the message type).

Once you have the object's data in a byte …

mcriscolo 47 Posting Whiz in Training

Implement each function in it's own class. But the structure of the program would change a bit.

First, create a new .cs file - you will put your function in this file (for example, call it "FirstClass.cs"):

public class FirstClass
{
    public FirstClass()
    {
        // default constructor
    }

    public void doFirstThing()
    {
        int x = 3;
        int y = 5;
        Console.Out.WriteLine("The total is: {0}", (x + y));
    }
}

Then, in your main, you would do this:

FirstClass oFC = new FirstClass();
oFC.doFirstThing();

You can create new .cs files for your other functions, and use the same convention as above to include them and call them in your code.

mcriscolo 47 Posting Whiz in Training

I'm not 100% sure I understand, but what I think you're trying to say is: you have 2 (or 3) programs (console apps), that do all of their stuff in "main()". You need to combine them into one program, so you can run it and it will do all 2 (or 3) things.

If that's the case, first, in each project, create a function and move all of the code from "main" into it. Then, from "main", all you're doing is calling the function that does all of your stuff. Example:

Old way:

class Program
{
    static void Main(string[] args)
    {
       int x = 3;
       int y = 5;
       Console.Out.WriteLine("The total is: {0}", (x + y));
    }
}

New way:

class Program
{
    public void doFirstThing()
    {
       int x = 3;
       int y = 5;
       Console.Out.WriteLine("The total is: {0}", (x + y));
    }

    static void Main(string[] args)
    {
        Program p = new Program();
        p.doFirstThing();
    }
}

Once you have that, you can create a new project that has all 2 (or 3) of your functions in it, then your "Main" looks like this:

static void Main(string[] args)
{
    Program p = new Program();
    p.doFirstThing();
    p.doSecondThing();
    p.doThirdThing();
}

Hope this helps!

mcriscolo 47 Posting Whiz in Training

I ran the program with your data, and lo and behold, I started to get the same results! After looking at it for some time, and monkeying around with the structure, and other things, I happened to look at the top of the program:

fstream inOutPlayer ( "player.txt", ios::in | ios::out );

You're reading and writing data via structs (i.e., binary mode)! So, try this:

fstream inOutPlayer ( "player.txt", ios::in | ios::out | ios::binary );

Your code should work much better.

mcriscolo 47 Posting Whiz in Training

Can't do it your way - the "CellType" property is read only.

If you are setting the columns in the designer, when you add a new column, you can specify the type from the drop-down.

In code, if you are adding the columns by hand, you can do it this way:

DataGridViewCheckBoxColumn c = new DataGridViewCheckBoxColumn();
c.HeaderText = "Column1";
dataGridView1.Columns.Add(c);

or, you can build a DataTable, and the types in the DataTable will set the appropriate column types in the DataGridView:

DataTable dt = new DataTable();
dt.Columns.Add("Column1", typeof(String)); // First col is a string
dt.Columns.Add("Column2", typeof(Boolean)); // Second col is a boolean

DataRow dr = dt.NewRow();
dr["Column1"] = "Data";
dr["Column2"] = true;
dt.Rows.Add(dr);
dataGridView1.DataSource = dt;
mcriscolo 47 Posting Whiz in Training

I ran the code in Visual Studio 2010 (full version, not Express), and I'm running Win 7/64-bit.

Here are the steps I went through with my setup:

1) In VS2010, from the "File" menu, select "New | Project"
2) In the box, click on "Visual C++", and in the right-hand side, select "Win32 Project".
3) Type a name for the project and press OK.
4) In the wizard, press "Next >".
5) Change the type to "Console application". Press "Finish".
6) Overlay the code in the main C++ code file (whatever you named the project), with the code from your post.

I just did it again (to write the above steps) and it works fine. I've attached my "players.txt" file - put it where your program can get it and see if you can read it with your version of the code.

mcriscolo 47 Posting Whiz in Training

Instead of separating the fields with spaces, use commas. Then rather than writing to the console, write to a file with a ".CSV" at the end. It's that simple. See this link: http://www.javapractices.com/topic/TopicAction.do?Id=42 for examples of writing to a file.

mcriscolo 47 Posting Whiz in Training

On line 12, you read the first line of the file. When you go into your "while" loop at line 16, you read the file again, thereby destroying the first line you read from the file without processing it. Delete line 12.

Second, when you output your results, it's outside of the "while" loop. The "ResultStr" will have all of the matches for the entire file, with no CR/LFs in them.

1) If the term starting with "52=" is always the end of a "line", then you can add a CR/LF when you put the value into the "ResultStr";
2) Otherwise, move the "Console.WriteLine(ResultStr)" into the "while" loop, and after you print it, clear the contents of "ResultStr", so you are ready to process the next line.

mcriscolo 47 Posting Whiz in Training

I copied your code down and compiled it; it seems to work fine for me. I added 3 players, and I can run the code and display all three just fine. I stopped the program and ran it again, and all of my data was still intact.

I did have to make some changes to get your code to compile. It looks like a windows console app; but it was attempting to include "stdafx.h", as well as it had the "_tmain" entry point, and "_TCHAR* as the type for "argv"; I removed all of these, replacing them with "main" and "char *", and compiled it as a straight C++ console app.

I then created a new Win32 project, and in the wizard stated I wanted it to be a console app, and was able to get your code to compile straight from your submission.

In both cases, the program ran fine. I copied the data file from the first project to the second, and was able to successfully browse the data.

Structurally, the code appears to be fine. Couple of notes:

1) the program just quits if it can't load "players.txt". You could just create a new, empty file in that case, instead of making me do it ;)
2) I'm a baseball fan, but not a huge baseball *stats* fan, so, in the code when you ask when a player is a pitcher, catcher, etc. - are these mutually exclusive, or can a …

mcriscolo 47 Posting Whiz in Training

Can't say if one is better than the other - I suppose it just gives the developer the flexibility of choosing a method based on the data he/she has in-hand. Methods 1 & 2 are closely related to each other (build an object and hand it in via a single "Add" call), while 3 & 4 are closely related (use indexes/iterate the collection to insert at a given location).

Of course, there is also the ability to load an entire data set into a DGV in one shot:

private void AddMethod5()
{
    dataGridView1.Columns.Clear();  // Remove the defined columns from the DGV

    DataTable dt = new DataTable();
    DataRow dr = dt.NewRow();
    for (int i = 0; i < 3; i++)
    {
        dt.Columns.Add("Column" + i.ToString(), typeof(String));
        dr["Column" + i.ToString()] = "RowCell" + i.ToString();
    }
    dt.Rows.Add(dr);
    dataGridView1.DataSource = dt;
}

At this point, I'm not truly in the spirit of what you originally proposed:

...adding a row to a DataGridView consisting of textboxes.

This is using the DGV as a viewing mechanism on a separate data source. As the comment indicates, it removes any column definitions in the DGV. But, it *is* yet another way to get a DGV to display data. And, of course, there are a lot of different ways to construct data sets/tables - from a database, from code, etc...

A lot of ways to skin the proverbial cat.

mcriscolo 47 Posting Whiz in Training

OK, sorry, one more change you need to make. In Form2, change this line:

private Form m_InstanceRef;

to:

private Form1 m_InstanceRef;

That will allow you to "see" the "ToggleMenus" method in Form1.

mcriscolo 47 Posting Whiz in Training

Check out line 23 - what's that equal sign ("=") all about? Remove that and see what happens.

mcriscolo 47 Posting Whiz in Training

This appears to be an exact repost of this DaniWeb post...?

mcriscolo 47 Posting Whiz in Training

Try this (put at the very top of the "while" loop):

string::iterator it = s.begin();
while (*it == ' ')
{
        s.erase(it);
}
string::iterator itb = s.end() - 1;
while (*itb == ' ')
{
        s.erase(itb);
        itb--;
}
mcriscolo 47 Posting Whiz in Training

Take the period check out of your loop, and add this right after the "for" loop:

if (s[s.length() - 1] != '.')
{
    cout << "Missing period at end of line!" << endl;
}
mcriscolo 47 Posting Whiz in Training

I'm not really sure why the code you have is not producing that. Further, perhaps if I knew what the program was trying to accomplish, I might be able to give more directed insight. So far, I've been trying to address the specifics of what you say is not working.

Is this for an assignment? Is this just an example but not part of your actual program?

Sometimes, trial and error is the best way. You muddle through things, gaining understanding of how the library functions work and how to construct the code to do what you want. What may not be fun is when you have to do all of that on a tight schedule.

mcriscolo 47 Posting Whiz in Training
mcriscolo 47 Posting Whiz in Training

Try this:

// Convert &lt; &gt; etc. to HTML
String sResult = HttpUtility.HtmlDecode(sData);
// Remove HTML tags delimited by <>
String result = Regex.Replace(sResult, @"<[^>]*>", String.Empty);

If you are using a .NET Forms app, you will have to specifically reference "System.web" in order to get your hands on "HttpUtility". "Regex" is in "System.Text.RegularExpressions".

mcriscolo 47 Posting Whiz in Training

I put this line of code right below the "while" but before the "for" loop:

cout << endl << "First char of line: '" << s[0] << "'" << endl;

I get this:

First char of line: 'a'
a dog
First char of line: 'a'
a cat
First char of line: ''

(The last one is since I have a blank line in my file at the end).

About your other issue. The code:

if(s.length()!=' ')
   cout << "ERROR"

won't work, because "s.length()" returns an integer, and you're comparing it to a space (or two spaces, which is really a string, and not a character). You can inject some simple code in your "for" loop to check for spaces - but you have to count them. Declare an int called "iSpaceCount", initialize it to zero, and then put this in your "for" loop:

if (s[i] == ' ')
{
    iSpaceCount++;
}
else
{
    iSpaceCount = 0;
}
if (iSpaceCount > 1)
{
    cout << "Too many spaces!!!" << endl;
}

See if that gets you a bit further.

mcriscolo 47 Posting Whiz in Training

First, when you post code, use the "CODE" tags....

In Form1.cs, put the following code:

public void ToggleMenus()
{
    menuStrip2.Enabled = !menuStrip2.Enabled;
    menuStrip1.Enabled = !menuStrip1.Enabled;
    menuStrip1.Visible = !menuStrip1.Visible;
    menuStrip2.Visible = !menuStrip2.Visible;
}

In Form1_Load, put this code:

menuStrip1.Enabled = true;
menuStrip2.Enabled = false;
menuStrip2.Visible = false;

In Form2's listView1_Click method, put this:

m_InstanceRef.ToggleMenus();

See how that works for you.

mcriscolo 47 Posting Whiz in Training

In the message, your excerpt from your "sample.log" file seems messed up. What are the field separators? Are they commas, or tabs, or something else?

Assuming they are commas or tabs, you need to split the string that you read in on that delimiter. See this post on how to do that.

Once you have them in an array of strings, you can select the ones you want.

mcriscolo 47 Posting Whiz in Training

If you want to use 2 windows, then you should develop a Windows app, and after the main window is created, create a 2nd window. You can't really do a console app and Windows app at the same time (OK, perhaps you CAN, but I think it would be a lot more trouble than just using 2 windows).

If you want your second window to be like a "console", then create it and use a black background and fixed-width fonts to simulate a "console" look.

mcriscolo 47 Posting Whiz in Training

Hmm... seems to work fine for me (Mac OS X 10.6/g++)

Random stuff... you mean a lot of 'a' characters? When I ran your program as-is, here was the output (my input file has 2 lines - "a dog" and "a cat"):

aa adaoagaaa acaaata

Of course, that's because each trip through the loop, you emit the "s[0]". To break up the lines, add:

cout << endl;

after your "for" loop, and each line in your file will wind up on it's own line in the output.

Are you seeing other characters, other than 'a's? What platform are you developing on?

mcriscolo 47 Posting Whiz in Training

Because the "else" condition for your invalid character check is only on the "if (fare == 'C' || fare == 'c')" statement. If the user enters an "s" or "S", it does everything you want, but then falls to the "if" statement for "C", and, failing that, it shows the error message.

Put an "else" on the front of the "if" statement for couples and it should work better.

mcriscolo 47 Posting Whiz in Training

Take the "ios::app" option out of your open statement. It's forcing all the writes to go to the end of the file (for adds that's OK, but when you delete or modify a record, it's actually writing them to the end of the stream). Once you do that, it should work a lot better.

mcriscolo 47 Posting Whiz in Training

Just make a new instance of the "Service1SoapClient", like this:

Service1SoapClient myWS = new Service1SoapClient();

Then, you should see your methods on the "myWS" variable:

string sResult = myWS.CelsiusToFahrenheit("25");

You may have to include the namespace, if you did not put it in the "using" section:

ServiceReference1.Service1SoapClient myWS = new ServiceReference1.Service1SoapClient();

However, after you have instantiated the class, you can call the methods on it.

mcriscolo 47 Posting Whiz in Training

Your seekg positioning is off. When you add records, you use:

fio.write((char*)(&t1), sizeof(t1));
    fio.write((char*)(&active), sizeof(active));

but when you look for records in your modify and delete, you use:

fio.seekg((number + 1) * sizeof(t1));

all well and good, but you are not accounting for the 1 byte boolean (active) that you write at the end of each record. Your seek code should look like:

fio.seekg((number + 1) * (sizeof(t1) + sizeof(active)));

You might consider moving the "active" flag inside your tool class - then your calculations work.

Some other things - the "tool" instance you pass into your getInput method is useless (other than to calculate the size of the tool object) - also the calculation is incorrect here, as well. You can use "sizeof(tool) + sizeof(boolean)".

Your "getInput" method - when you add a new record (when "modify" is false) - what happens when I add 2 records, and I type in a record number of "1" for both? It appears that I will overwrite the first record with the second. An add operation should seek to EOF and add there.

That should be enough to get you going.

mcriscolo 47 Posting Whiz in Training

Really? I ran this and I got 0x01. Here's the code (Eclipse Helios on Windows 7):

public class ArrayRefTest 
{
	public ArrayRefTest()
	{
		//Default Constructor
	}
	
	public static void main(String[] args)
	{
		ArrayRefTest a = new ArrayRefTest();
		a.foo();
	}
	
	public void ChangePrimitiveArray(byte bytes[])
	{
	    bytes[0] = 1;
	}

	public void foo()
	{
	    byte bytes[] = new byte[2];
	    bytes[0] = 4;
	    ChangePrimitiveArray(bytes);

	    System.out.printf("bytes[0]=0x%02x\n", bytes[0]);
	}
}

Check this out:

http://www.javacoffeebreak.com/faq/faq0066.html

VernonDozier commented: Thanks. +13
mcriscolo 47 Posting Whiz in Training
mcriscolo 47 Posting Whiz in Training

Perhaps this:

try
{
    FileSystem.CopyFile(fSource, fTarget, UIOption.AllDialogs, UICancelOption.ThrowException);  // Throw exception if user cancels
    foreach (ListViewItem checkItem in listView_left.Items)
    {
        if (checkItem.Text == lItem.Text)
        {
            listView_left.Items.Remove(checkItem);
        }
    }
    listView_left.Items.Add((ListViewItem)lItem.Clone());
    reload(lItem, fSource);
}
catch (OperationCanceledException ocex)
{
    // The user canceled
}
mcriscolo 47 Posting Whiz in Training

Suggestion - put each of your data gathering activities into its own method (you've already done that for one or two of them. Use a method signature like this:

bool SelectFromMenu(string[] menu, ref int iCat)

and call it like:

if (!SelectFromMenu(cat_menu, ref catPizza)))
{
    continue;
}

You pass an initialized version of "catPizza" into your method (say, -1). If the method returns false, the user entered "restart" - hence the "continue" statement - it will take you to the top of your "while" loop. Otherwise, the method will have set "catPizza" to the value the user selected, and you continue processing.

Set your other methods up similarly, and you have a mechanism to escape if the user wants to start over.

mcriscolo 47 Posting Whiz in Training

Does the "ref" value for the variable "SessionNumber" that gets returned to your calling program get set to "ERROR", or does the whole thing blow? If so, you may want to trap the exception to see what its giving you.

try
{
    System.Diagnostics.Process.Start(target);
    SessionNumber = "SUCCESS";
}
catch (Exception ex)
{
    Console.WriteLine("Exception {0}", ex.Message);
    SessionNumber = "ERROR";
}
mcriscolo 47 Posting Whiz in Training

Is there a reason why you have to set up the methods to take a type of "Object"? Will your "main" program accept DLLs that pass structs/classes of many types? Even if that's the case, your main project will still have to know about them in order to cast the inbound class/structs to the correct type (assuming you weren't getting that error).

Can you set up the main program so that when it loads the DLL, the methods pass structs/classes via method signatures that are known to both the DLL and main?

I know I'm generalizing, but other than your statement, I don't know the overall design goal of your program & libraries.

mcriscolo 47 Posting Whiz in Training
mcriscolo 47 Posting Whiz in Training

Are you checking the contents of the output file while the program is still running? Normally, when the file is closed (either explicitly, or when the object is disposed and the GC cleans it up), the buffers will be flushed.

If you want to check the status of your output file while the program is still running (e.g., you have a long-running process that's, say, writing a log file), then you will want to call "Flush" on the stream to push the data onto the disk.

A lot of things can affect when the data from a stream is actually written to the file (how long the process runs, how much data you are writing, etc.)

Does one program write more data than the other? A stream has a buffer, that, when it fills up, will be flushed to the disk. If one program is not writing a lot of stuff and you check it while still running, your file may be empty.

kvprajapati commented: Good point. +11
mcriscolo 47 Posting Whiz in Training

Well, a couple of things:

1) After you've selected from the first choices, you go into the "checksize" function. Here, you state that you can enter 'restart' to restart the ordering process. Your function is expecting a number (diameter of the pizza) - but if the user enters 'restart', they just get to keep trying on entering a diameter.

2) On line 84, you execute a 'Console.ReadLine()" but you aren't capturing the line the user entered. If they did indeed enter 'restart', you will never know it.

You're most of the way there, just a bit of cleanup and you should be good.

mcriscolo 47 Posting Whiz in Training

You really want to try to develop a query for your data. Searching serially through a database defeats the purpose of using a database in the first place.

See this post:

http://vbcity.com/forums/t/112704.aspx

to see how to set up C# code to query an Access database. You can either use a "SELECT" statement in your code, or you can set up an Access Query and call that from the C# code.

Good luck!

mcriscolo 47 Posting Whiz in Training

Depending on the complexity of the task, I can think of 2 ways off the top of my head:

1) Write a C# process that does your check and updates the required tables (most likely a Windows Console application). Set it up to run on your server as a Windows Scheduled Task, in the interval you need to check.

2) Develop a database procedure (e.g., in SQL Server, a stored procedure) that does your check and update. Set up a scheduled database job that runs your procedure.

Hope this helps!

mcriscolo 47 Posting Whiz in Training

You can search through the items in a ListView, by iterating through the "Items" collection. Further, each item has a SubItems collection. So, with code like this, you can look for an item in a ListView and do something with it. In this case, I have a ListView called "lvBatters" and I am try to locate a batter (value in txtBatter) and replace the item in column 2 of the ListView with the batting average (stored in sAvg - converted to a string earlier):

bool bFound = false;
    foreach (ListViewItem item in lvBatters.Items)
    {
        if (item.Text == txtBatter.Text)
        {
            item.SubItems[1].Text = sAvg;  // Set the batting average
            bFound = true;
            break;   // break out of the loop
        }
    }

    // If I don't find the batter in the list, add it!
    if (!bFound)
    {
        ListViewItem i = new ListViewItem(txtBatter.Text);
        i.SubItems.Add(sAvg);
        lvBatters.Items.Add(i);
    }

Keep in mind, "items.SubItems[0].Text" is the value in the first column!

Try that, and see what happens.

mcriscolo 47 Posting Whiz in Training

Your problem seems to be twofold, but related to the same thing:

Both solutions are named the same thing. When I pulled them down, it renamed the folder for one of them (the DLL project) to "PermutationGenerator.1". However, when I looked in the "References" item for the main project, you were referencing the .EXE in the current project, not the DLL from the DLL project. Even when I corrected the reference and pointed to the DLL in the other project, since the assembly names were the same (but the Public Key tokens are different), it wouldn't load the DLL.

I would recommend (this worked on my system with your code) to create a new "main" project (I called mine "PermTest"), and move your form code into it. Add a reference to the DLL in the other project, and the DLL should load.

However, in the final part of your DLL call (line 70 of Class1.cs), it hung there when I ran it - so you need to look at that. I used the wod "Test" as my input string.

Good luck!

mcriscolo 47 Posting Whiz in Training

First, that semicolon on line 8 (between the end of your method implementation and the curly brace) is going to be a problem....

"blabla.date" is "const char *". So, one of 2 things: either cast the return value as (char *), so it will match the method prototype:

return (char *)blabla.date;

or, change the method prototype to return a type of "const char *":

class Bla{
private:
   char date[9];
public:
   const char* ReturnDate(const Bla& blabla);
};

const char* Bla::ReturnDate(const Bla& blabla){
   return blabla.date;
}
mcriscolo 47 Posting Whiz in Training

Knowing nothing more about your code that what you wrote, an extremely high-level solution could look like:

1) Convert your main() function to C# in a new C# Console Application project.
2) Create a new C++ "Class Library" project.
3) Copy all of your C++ code, minus the main() function, into the new project.
4) Attempt to build the C++ library.
5) In your C# project, set a reference to the new C++ Class Library.
6) Run the C# program and see what happens.

Again, that's extremely high-level, and discounts any possible non-portable constructs that may be in the C++ code that will have to be modified/rewritten to work with the CLI. It also assumes that the main() function in your current C++ program is relatively straightforward and can be converted to C# easily.

That's the way I'd start out, at least.

Good luck!

jonsca commented: Good suggestions. +6
pseudorandom21 commented: Helpful, and interesting post. +0
mcriscolo 47 Posting Whiz in Training

Scott,

Well, it depends what you want to do with the file after you're done.... however, once you write a PNG file to the back of a TXT file, it's really not a TXT file anymore. You could write out your data as binary, then tack the PNG onto the back...

In the end, with that kind of a file, you will need some form of interpreter/decoder to separate the text part of your data from the image part. Now, if you wrote out a PDF directly from your code, you could then combine the text and the image data into a single document, and that doc would be instantly viewable (since, of course, its a PDF).

There are some libraries for Java that allow you to monkey with PDFs (PDFBox, iText). Here is a link for some libraries that provide PDF manipulation capability:

http://java-source.net/open-source/pdf-libraries

Hopefully this is somewhat helpful.

mcriscolo 47 Posting Whiz in Training

Here is a link that describes a situation similar to yours:

http://www.dotnet4all.com/dotnet-code/2004/12/serialization-headaches.html

The poster suggests that perhaps you develop a separate assembly (DLL) that does all of the serialization/de-serialization. Then call that from your CreateData and ReadData programs.

If you examine the contents of "DataFile.dat" in an editor capable of viewing hex, you can see that the "CreateData" assembly is tagged to the data in file. When your ReadData program comes along and attempts to read the data, you get the error.

One assembly that reads and writes the data would alleviate that issue.

Hope this helps.

mcriscolo 47 Posting Whiz in Training

The ListView supports the "DragLeave" event. Would this help? Once the event fires, you can check to see what's being dragged and if its an item from the ListView, you can remove it.

mcriscolo 47 Posting Whiz in Training

When you call "displayPlayerInfo", you are not referencing the array "players" that was created in main. You reference "pInfo", a new and uninitialized array of PlayerInfo structures.

Pass the "players" array into the "displayPlayerInfo" and change the loop to use that, and you should be all set.