Note, this is converted from C# with a converter program and some of my own hand coding, there is definitely a possibility that the compiler is right and something of the sort does not exist in C++, or its named diff.

I am having an issue with the long !System::Windows....line, getting the following compiling error:

1>UserFeedback.cpp(79): error C3083: 'Windows': the symbol to the left of a '::' must be a type
1>UserFeedback.cpp(79): error C3083: 'Forms': the symbol to the left of a '::' must be a type
1>UserFeedback.cpp(79): error C3083: 'Application': the symbol to the left of a '::' must be a type
1>UserFeedback.cpp(79): error C3083: 'ExecutablePath': the symbol to the left of a '::' must be a type
1>UserFeedback.cpp(79): error C2039: 'Equals' : is not a member of 'System'

internal:
			static void Close()
			{
				// Assumption:
				// If the console window title is equal to the executable path, exe was run by double
				// If it doesn't (eg. prefixed by c:\windows\system32\cmd.exe - c:\Progra...... )
				//  it was run from a console window (or batch file!) and shouldn't wait for a key.

				auto runningFromCommandPrompt = !System::Windows::Forms::Application::ExecutablePath::Equals(Console::Title, StringComparison::InvariantCultureIgnoreCase);
				if (runningFromCommandPrompt)
					return;
				Info("Press any key to quit");
				while (!Console::KeyAvailable)
				{
					System::Threading::Thread::Sleep(50);
				}
			}

If you want to convert C# to anything then convert it to CLR/C++ which is managed c++ and a very close cousin of C#. c++ itself knows nothing about System.

Edited 5 Years Ago by Ancient Dragon: n/a

I have been doing this, I have the Clr option fixed up, and have been using this, the compiler is not happy with this line of code though.

According to this, ExecutablePath is a property that returns String^ "The path and executable name for the executable file that started the application". So adding "::Equals" after it doesn't make any sense (line 9 of the code you posted).

Edited 5 Years Ago by Ancient Dragon: n/a

Ok, that makes sense, but what about the rest of it? According to what I read System doesnt have a Windows function, but then this says it does.

Yes, System::Windows. You need to start learning how to google for those things.

And what is that "= !" at the end of line 9???

I think what line 9 is trying to ask is if the console window title is the same as Current process name.

if( System::Windows::Forms::Application::ExecutablePath == Console::Title)

Edited 5 Years Ago by Ancient Dragon: n/a

Still getting the same error...I have been googling things all day, and I haven't gotten anywhere, which is why i then turn to the forums.

Okay, but there are a lot of bugs at the moment that I have not worked out and posted yet for help, was trying to take it one bug at a time.

AoE2Wide.h

#include <iostream>
#include <string>
#include <vector>
#using <mscorlib.dll>

using namespace System;
using namespace System::Collections;
using namespace System::Diagnostics;
using namespace System::IO;
using namespace System::Text;

namespace AoE2Wide
{
    private ref class Item
	{
	public:
		int Pos;
		int ReferenceValue;
		String ^Type;
		int Parameter;
		String ^Comments;
		String ^Asm;
		int OriginalPos;
	};

	private ref class Patch
	{
	public:
		String ^PatchFilepath;
		int FileSize;
		String ^Md5;
		String ^Version;
		int InterfaceDrsPosition;
		int InterfaceX1DrsPosition;
		IEnumerable<Item^> ^Items;
	};

	private ref class FatalError : Exception
	{
		public:
			FatalError(String ^msg) : Exception(msg)
			{
			}
	};
};

UserFeedback.cpp

// User Feedback information

#include "stdafx.h"
#include "AoE2Wide.h"
#include <iostream>
#using <mscorlib.dll>

using namespace System;

namespace AoE2Wide
{

	private ref class UserFeedback
	{
	public:
		static void Error(Exception^ e)
		{
			auto normalColor = Console::ForegroundColor;
			Console::ForegroundColor = ConsoleColor::Red;
			Console::WriteLine("An error occurred:");
			Console::WriteLine(e->Message);

			// Only for 'not our exception', dump details
			if (!(dynamic_cast<FatalError^>(e) != nullptr))
			{
				Console::ForegroundColor = ConsoleColor::DarkRed;
				Console::WriteLine("Exception Details:");
				Console::WriteLine(e->ToString());
			}
			Console::ForegroundColor = normalColor;

		}
		static void Info(String ^msg, Object ^param1)
		{
			Info(String::Format(msg, param1));
		}

		static void Info(String ^msg)
		{
			Console::WriteLine(msg);
		}

		static void Trace(String ^msg, Object ^param1)
		{
			Trace(String::Format(msg, param1));
		}

		static void Trace(String ^msg)
		{
			auto normalColor = Console::ForegroundColor;
			Console::ForegroundColor = ConsoleColor::DarkGray;
			Console::WriteLine(msg);
			Console::ForegroundColor = normalColor;
		}

		static void Warning(String ^msg, Object ^param1)
		{
			Warning(String::Format(msg, param1));
		}

		static void Warning(String ^msg)
		{
			auto normalColor = Console::ForegroundColor;
			Console::ForegroundColor = ConsoleColor::DarkYellow;
			Console::Write("Warning: ");
			Console::ForegroundColor = ConsoleColor::Yellow;
			Console::WriteLine(msg);
			Console::ForegroundColor = normalColor;
		}
		
		internal:
			static void Close()
			{
				// Assumption:
				// If the console window title is equal to the executable path, exe was run by double
				// If it doesn't (eg. prefixed by c:\windows\system32\cmd.exe - c:\Progra...... )
				//  it was run from a console window (or batch file!) and shouldn't wait for a key.

				if(System::Windows::Forms::Application::ExecutablePath == Console::Title);
					return;
				Info("Press any key to quit");
				while (!Console::KeyAvailable)
				{
					System::Threading::Thread::Sleep(50);
				}
			}
	};

};

SlpStreamer.cpp

#include "stdafx.h"
#include "AoE2Wide.h"

using namespace System;
using namespace System::Collections::Generic;
using namespace System::Diagnostics;
using namespace System::IO;

namespace AoE2Wide
{
	private ref class SlpStrecher
	{
		public:
			static std::vector<char> Enlarge(UInt32 id, std::vector<char> data, int oldWidth, int oldHeight, int newWidth, int newHeight)
			{
				BinaryReader ^reader = gcnew BinaryReader(gcnew MemoryStream(data, false));
				// testing patch version
				auto version = reader->ReadUInt32();
				if (version != 0x4e302e32)
					return data;

				auto framecount = reader->ReadUInt32();
				if (framecount != 1)
					return data;

				auto comment = reader->ReadBytes(24);
				/*auto linesOffset = */reader->ReadUInt32();
				auto maskOffset = reader->ReadUInt32();
				auto paletteOffset = reader->ReadUInt32();
				auto properties = reader->ReadUInt32();

				auto width = reader->ReadInt32();
				if (width != oldWidth)
					return data;

				auto height = reader->ReadInt32();
				auto centerX = reader->ReadInt32();
				auto centerY = reader->ReadInt32();

				// if height - centerY doesnt equal oldHeight return data due to error
				if (height - centerY != oldHeight)
					return data;

				if (centerY != 0)
				{
					int higher = newHeight - oldHeight;
					centerY -= higher;
					newHeight = oldHeight = height;
				}

				auto newMaskSize = (UInt32) (newHeight*4);
				auto newLinesOffset = maskOffset + newMaskSize;
				auto newLinesSize = (UInt32) (newHeight*4);
				auto newLineDataStart = newLinesOffset + newLinesSize;

				MemoryStream ^outStream = gcnew MemoryStream();
				BinaryWriter ^writer = gcnew BinaryWriter(outStream);

				// Added by Master_G for testing purposes
				// UserFeedback.Info(string.Format("Resizing image #{0} for {1}x{2} to {3}x{4}",
				//    id, oldWidth, oldHeight, newWidth, newHeight));

				// writing the information provided above
				writer->Write(version);
				writer->Write(framecount);
				writer->Write(comment);
				writer->Write(newLinesOffset);
				writer->Write(maskOffset);
				writer->Write(paletteOffset);
				writer->Write(properties);
				writer->Write(newWidth);
				writer->Write(newHeight);
				writer->Write(centerX);
				writer->Write(centerY);

				//UserFeedback.Info(string.Format("Version: {0}, FrameCount: {1}, Comment: {2}, newLinesOffset: {3}",
				//    version, framecount, comment, newLinesOffset));
				//UserFeedback.Info(string.Format("MaskOffSet: {0}, PaletteOffset: {1}, Properties: {2}",
				//    maskOffset, paletteOffset, properties));
				//UserFeedback.Info(string.Format("NewWidth: {0}, NewHeight: {1}, CenterX {2}, CenterY {3}",
				//   newWidth, newHeight, centerX, centerY));
				
				auto osp = outStream->Position;
				Trace::Assert(osp == maskOffset);

				// read every line of pixels from file into orgLineMasks array
				array<UInt32> ^orgLineMasks = gcnew array<UInt32>(oldHeight);
				for (auto inLine = 0; inLine < oldHeight; inLine++)
					orgLineMasks[inLine] = reader->ReadUInt32();

				// read every original line start of old height into array
				array<UInt32> ^orgLineStarts = gcnew array<UInt32>(oldHeight + 1);
				for (auto inLine = 0; inLine < oldHeight; inLine++)
					orgLineStarts[inLine] = reader->ReadUInt32();
				orgLineStarts[oldHeight] = safe_cast<UInt32>(data->Length);

				// Subtract the next piece in orgLineStarts from the previous piece
				// and then store into a new autoiable called orgLines
				List<array<Byte>^> ^orgLines = gcnew List<array<Byte>^>(oldHeight);
				for (auto inLine = 0; inLine < oldHeight; inLine++)
				{

					auto orgLineSize = orgLineStarts[inLine + 1] - orgLineStarts[inLine];
					orgLines->Add(reader->ReadBytes(safe_cast<int>(orgLineSize)));
				}

				// initialize new lists
				array<UInt32> ^newLineMasks = gcnew array<UInt32>(newHeight);
				List<array<Byte>^> ^newLines = gcnew List<array<Byte>^>(newHeight);

				// difference in the lines from oldHeight compared to newHeight
				// e.g. 1200 - 1024 = 176

				auto extraLines = newHeight - oldHeight;

				// determine whether shrinking resolution or expanding it

				auto shrinking = extraLines < 0;

				auto expanding = extraLines > 0;

				// define middle of oldHeight
				// e.g. 1024/2 = 512

				auto centreLine = oldHeight / 2;

				// e.g. 512 + 176 = 688

				auto shrinkSkipStart = centreLine + extraLines;
				auto shrinkSkipEnd = centreLine;
				// duplication is the amount of times every duplicated line, is duplicated
				// e.g. duplication = 1 + (176 + 1)/(1024/2)
				// e.g. duplication = 1.34570

				auto duplication = 1 + (extraLines + 1)/(oldHeight/2);
				// the duplication block size is the block that is being duplicated
				// the last line of which MIGHT not be duplicated 'duplication' times
				//  eg if duplication is 2, extralines = 501, dbs = 251, the last of which is
				//  duped just once.

				auto duplicationBlockSize = (extraLines + duplication - 1)/duplication;


				auto dupStart = centreLine - duplicationBlockSize / 2;

				auto dupEnd = dupStart + duplicationBlockSize;

				int dupedLines = 0; //'UNIT'TEST
				for (auto inLine = 0; inLine < oldHeight; inLine++)
				{
					// If shrinking skip 'extralines' lines on the centerline and above
					if (shrinking && inLine >= shrinkSkipStart && inLine < shrinkSkipEnd)
					{
						dupedLines--;
						continue;
					}
					// newLineMasks has same ammount of positions as newHeight
					// e.g. 1200 => 1200
					// 
					newLineMasks[newLines->Count] = orgLineMasks[inLine];


					auto newLine = StretchLine(orgLines[inLine], oldWidth, newWidth);
					newLines->Add(newLine);

					// If expanding, duplicate the right amount of lines before centreLine
					if (!expanding || inLine < dupStart || inLine >= dupEnd)
						continue;

					for (auto rep = 0; rep < duplication && dupedLines < extraLines; rep++)
					{
						newLineMasks[newLines->Count] = orgLineMasks[inLine];
						newLines->Add(newLine);
						dupedLines++;
					}
				}
				Trace::Assert(newLines->Count == newHeight);
				Trace::Assert(dupedLines == extraLines);


				auto nextLineStart = newLineDataStart;


				for each (auto newLineMask in newLineMasks)
					writer->Write(newLineMask);

				osp = outStream::Position;
				Trace::Assert(newLinesOffset == osp);


				for each (auto newLine in newLines)
				{
					writer->Write(nextLineStart);
					nextLineStart += safe_cast<UInt32>(newLine->Length);
				}

				osp = outStream::Position;
				Trace::Assert(newLineDataStart == osp);


				for each (auto newLine in newLines)
					writer->Write(newLine);

				Trace::Assert(outStream->Position == nextLineStart);

				writer->Close();


				array<Object^> ^newSlp = outStream->ToArray();

				// For debugging:
				//File.WriteAllBytes(string.Format(@"slp\{0}org.slp", id), data);
				//File.WriteAllBytes(string.Format(@"slp\{0}new.slp", id), newSlp);

				return newSlp;
			}
	private:
		static array<Byte> ^BlitColor(int amount, Byte color)
				{
					if (amount <=0)
						return nullptr;


					//	using (auto outStream = new MemoryStream())
					MemoryStream ^outStream = gcnew MemoryStream();
					try
					{
						while (amount > 15)
						{
		
							auto count = Math::Min(amount, 255);
							outStream->WriteByte(7);
							outStream->WriteByte(safe_cast<Byte>(count));
							outStream->WriteByte(color);
							amount -= count;
						}
						while (amount > 0)
						{

							auto count = Math::Min(amount, 15);
							outStream->WriteByte(safe_cast<Byte>(7 | (count << 4)));
							outStream->WriteByte(color);
							amount -= count;
						}
						return outStream->ToArray();
					}
					finally
					{
						delete outStream;
					}
				}

				static array<Byte> ^StretchLine(array<Byte> ^orgLine, int oldWidth, int newWidth)
				{
					if (orgLine->Length == 1)
						return orgLine;

					// Take the last byte before the 0x0F eol as color (I suppose that's always a color :S )
					auto color = orgLine[orgLine->Length - 2];
					// e.g. 1900-1280 = 620, color is from 
					array<Byte> ^addendum = BlitColor(newWidth - oldWidth, color);
					if (addendum == nullptr || addendum->Length == 0)
						return orgLine;


					//	using (auto outStream = new MemoryStream(orgLine.Length + addendum.Length))
					MemoryStream ^outStream = gcnew MemoryStream(orgLine->Length + addendum->Length);
					try
					{
						outStream->Write(orgLine,0, orgLine->Length - 1);
						outStream->Write(addendum, 0, addendum->Length);
						outStream->WriteByte(orgLine[orgLine->Length - 1]);
						return outStream->ToArray();
					}
					finally
					{
						delete outStream;
					}
				}

	};
};

1>UserFeedback.cpp(79): error C3083: 'Windows': the symbol to the left of a '::' must be a type
1>UserFeedback.cpp(79): error C3083: 'Forms': the symbol to the left of a '::' must be a type
1>UserFeedback.cpp(79): error C3083: 'Application': the symbol to the left of a '::' must be a type
1>UserFeedback.cpp(79): error C2039: 'ExecutablePath' : is not a member of 'System'
1>UserFeedback.cpp(79): error C2065: 'ExecutablePath' : undeclared identifier
1>UserFeedback.cpp(80): warning C4390: ';' : empty controlled statement found; is this the intent?

This is the first set.

So what alternative do I have? This code worked 100% fine in C#, so i am confused on how I would convert it by still using a console project. I really appreciate the information though, i am learning a lot today about C++ as a language.

This is the original code in C#

internal static void Close()
        {
            // Assumption:
            // If the console window title is equal to the executable path, exe was run by double
            // If it doesn't (eg. prefixed by c:\windows\system32\cmd.exe - c:\Progra...... )
            //  it was run from a console window (or batch file!) and shouldn't wait for a key.
            var runningFromCommandPrompt =
                !System.Windows.Forms.Application.ExecutablePath.Equals(Console.Title,
                                                                        StringComparison.InvariantCultureIgnoreCase);
            if (runningFromCommandPrompt)
                return;

            Info(@"Press any key to quit");
            while (!Console.KeyAvailable)
            {
                System.Threading.Thread.Sleep(50);
            }
        }

Edited 5 Years Ago by MasterGberry: n/a

Line 79 of your first listing you have a semicolon after the if statement.

Also, remember than in C++/CLI the . operator of C# can translate to a namespace or a member function. (so either a :: or a -> or even a . for a non-pointer)

But, AD is right in that you need to find the equivalent for a console application (I'm not sure if selecting CLR console will allow you to access the System::Windows::Forms members, but there should be an alternative).

Edited 5 Years Ago by jonsca: n/a

Got it, I think :) No error at the moment, so I assume I got it right. Ty for the help :) Now time for a new thread with help xD

static void Close()
			{
				// Assumption:
				// If the console window title is equal to the executable path, exe was run by double
				// If it doesn't (eg. prefixed by c:\windows\system32\cmd.exe - c:\Progra...... )
				//  it was run from a console window (or batch file!) and shouldn't wait for a key.

				Assembly^ assem = Assembly::GetExecutingAssembly();

				if(assem->CodeBase == Console::Title)
					return;
				Info("Press any key to quit");
				while (!Console::KeyAvailable)
				{
					System::Threading::Thread::Sleep(50);
				}
			}

CodeBase seems to return the path in a file:///C:\etc\etc format, so you may need to do some string operations on it. I'm not sure why you are comparing the filename to the one on the console, as they are probably derived from the same source.

I am pretty sure all I am trying to do in that piece of code is just make sure there isnt another instance of the same program already running. Like I said i didn't make this code, i am just trying to convert it over.

This question has already been answered. Start a new discussion instead.