安装 Steam						
					
				
				
									登录
											 | 
						语言
						
																																															繁體中文(繁体中文)
																													日本語(日语)
																													한국어(韩语)
																													ไทย(泰语)
																													български(保加利亚语)
																													Čeština(捷克语)
																													Dansk(丹麦语)
																													Deutsch(德语)
																													English(英语)
																													Español-España(西班牙语 - 西班牙)
																													Español - Latinoamérica(西班牙语 - 拉丁美洲)
																													Ελληνικά(希腊语)
																													Français(法语)
																													Italiano(意大利语)
																													Bahasa Indonesia(印度尼西亚语)
																													Magyar(匈牙利语)
																													Nederlands(荷兰语)
																													Norsk(挪威语)
																													Polski(波兰语)
																													Português(葡萄牙语 - 葡萄牙)
																													Português-Brasil(葡萄牙语 - 巴西)
																													Română(罗马尼亚语)
																													Русский(俄语)
																													Suomi(芬兰语)
																													Svenska(瑞典语)
																													Türkçe(土耳其语)
																													Tiếng Việt(越南语)
																													Українська(乌克兰语)
																									报告翻译问题
							
						
 
											 
													
 
					 
 
 讨论规则及指引
 讨论规则及指引 6
 6							
 举报此帖
 举报此帖


when you make the statement:
new foo()
is equivalent to saying in english: "Hey program allocate for me a new object/memory area of type foo"
MainF frm = new MainF(); is an assignment operation.
Try doing this:
//Application.Run(new MainF());
MainF frm = new MainF();
frm.SetLabel("Hello World");
Applicaiton.Run(frm);
MainF frm = new MainF();
frm.SetLabel1"Hello World");
Application.Run(frm);
But this one doesn't show . I want to be able to set the label text after the form shows
MainF frm = new MainF();
Application.Run(frm);
frm.SetLabel1("Hello World");
OH and it is related to CNC i was going to attempt to change my Pascal Meg Extractor to C#
Once i get how you do a few things LOL
Ok I have have tried this
Application.Run(frm);
frm.SetLabel1("Hello World");
frm.label1.Text = "Hello There";
frm.label1.Invalidate();
frm.label1.Update();
frm.label1.Visible=false;
and it has no effect on the label at all
I don't know why you want to change things in your form from the Main() function, but, it just doesn't work that way. Put any initialisation code either in the form's constructor, under the "InitializeComponent()" line, or make a "Load" or "Shown" event, and put it in there.
To make a "Load" event, go to the UI editor and double click the form background and it'll make the listener and the function. For other events, make sure you have the form selected (and not one of the controls), and in the form's properties (if you can't find it, press alt+enter) go to the events tab (with the lightning bolt) and find the right event you want the form to make a function for.
Note, if you make a function to handle an event, and decide not to use it later and delete it, you will need to manually open "MainF.Designer.cs" and also delete the line in there that linked a listener to that function. That file contains all the code generated by the visual editor. This is mainly the variables of the UI controls, and the InitializeComponent() function that applies all their initialisation and positioning.
OH! now it starts to make sense.. i didn't try the debugger till later and i didn't set a break point there in the Main()
Yeah i gave up on the using Main() to set the labels
I did get the labels to work i added a button
then added this to my Form
private void button1_Click(object sender, EventArgs e)
{
Test ts = new Test();
string name = "";
SetLabel1(ts.Split(out name));
label2.Text = name;
}
then on a new class page
public class Test
{
public void SplitPath(string path, out string dir, out string name)
{
int i = path.Length;
while (i > 0)
{
char ch = path;
if (ch == '\\' || ch == '/' || ch == ':')
{
break;
}
i--;
}
dir = path.Substring(0, i);
name = path.Substring(i);
}
public string Split(out string named)
{
string dir, name;
SplitPath(@"c:\Windows\System\hello.txt", out dir, out name);
named = name;
return dir;
// Console.WriteLine(dir);
// Console.WriteLine(name);
}
}
}
By the way, "String" class has a perfectly usable Split() function already. You can even give it multiple characters to split by, and tell it whether or not to keep empty values in the resulting array.
And the static "Path" tool-class already has a bunch of toolsets to split filenames, folder names and extensions. It's one of the things I really like about the .net framework, in fact; it has an enormous amount of standard tools already built in.
well i have managed to get the steam path to cncremastered\data\ from the registry, i put this in Main()
if (ch == '/')
{
ch = (char)92;
}
s = s + ch;
i++;
}
// add the rest of the path
Globals.STPath = s + @"/steamApps/common/CnCRemastered/Data/";
// replace all of the / with \
Globals.STPath=Globals.STPath.Replace('/','\\');[/code]
Humm its adding my code end block to the end of my code, well two code end blocks didn't solve it.
and i put this in globals
as well i changed the splitpath function to use split()
if (i == count-2) s = s + str;
}
dir = s;
name = str[count-1];
}[/code]
Ok im going to try to get a file list of whats in the data directory next and display it in a listbox
eg : Foos foo = new Foos();
but some other place i need access to the class Foos again , but don't want to create a new copy of it
I got the file names into a list box no problem , now i'm trying to decide how i want to access the meg file
This stuff is vitally important when it comes to stuff like closing file streams after reading data from them, since opening a stream tends to lock the file for other applications.
This is from the code I use to find the Steam game library containing the game:
You can copy that whole class from my project if you want; it's open source for a reason.
https://github.com/Nyerguds/CnCTDRAMapEditor/blob/master/CnCTDRAMapEditor/Utility/SteamAssist.cs
Called here:
https://github.com/Nyerguds/CnCTDRAMapEditor/blob/master/CnCTDRAMapEditor/Program.cs#L75
Copy? If the class is either inside your project, or accessible from the project references, but it is not in the same namespace as the current class, you have to specifically tell the current class that it should reference it. This is done by adding a "using" statement for it at the top of the file. This is not necessary for classes in the same namespace. (Note, don't confuse this with the "using" blocks I mentioned before; that's a completely different thing.)
On most new classes you make, you'll at least see something like:
https://i.imgur.com/EoWacxg.png
(this is the flood fill code from the map editor
You can also reference it by full namespace name (the third option in the list there; to change the current text to "Utility.BlobDetection"), but that's generally more tedious than a global import with a "using" statement that works for the whole file.
I see on Megafile.cs they have "using " but i cant figure out what class they are referring to.
EG: using (var magicNumberReader = new BinaryReader(megafileMap.CreateViewStream(readOffset, 4, MemoryMappedFileAccess.Read)))
Ok i have on my form a listbox with all of the Meg files (LBFiles)
when i click on one of the Items it Loads up the Meg file ( i just used MegaFile.cs and changed the stringtable to public) and that fills in the LBItems (listbox for the items in the stringtable of the Meg file )
Now when i do this Megafile Mega = new Megafile(MegPath); I assume it creates a totally new Class Instance right ?
So it brings me to the question of how do i get rid of the previous instance ? Or does it dispose of its self .
So i tried it this way , but the commented out section gave me errors ,the idea was if there is an existing class then i dispose of that and create a new one
OH i kinda see now so i should be saying something like using(Megafile Mega = new Megafile(MegPath)) because the MegaFile is IDisposable
Your code there fails because you're comparing a class type (MegaFile) with null. A type can't be compared with null; it's not a real object. It's just the "template" which the real objects are created from.
If you define a new meg file with the code "Megafile Mega = new Megafile(MegPath);" then your object variable is "Mega", so if you want to dispose the object, you need to call Dispose() on that "Mega" variable. The class itself will not contain that; any function that can be called on the bare class name is a static function that acts independently from any objects.
Note, c# naming convention is normally to give class names and function names CamelCase, and variables lowerCamelCase. So a variable like your Megafile object there would normally be called "mega", not "Mega". This convention also makes it easier to distinguish variables from class names.
Yep! With the brackets block behind it, otherwise it's only valid for a single line of code. And it means you don't have to worry about closing any file streams it has open internally; "Dispose()" (or "using") is a promise to the user that all such stuff will be cleaned up afterwards.
Ha naming convention I'm used to Pascal where the case doesn't matter . I am trying now though with the names .
Though i do like pascals use of classes a lot more .
EG : var Mc : MyClass; , Mc := MyClass.Create; Then i can use Mc all over my application until i need to dispose of it then it is as simple as Mc.Free;
Unlike in C# where it seems like i have to keep creating new copies of the class like
using (Megafile mega = new Megafile(MegPath))
{
}
I am making progress, It now fills in the Meg file listbox when the form shows.
I added an Extract One , and ExtractAll buttons , and they even work :)
I added a progress bar to the Extract All function and update a label with the file it saved , In the proper directories even.
It also will display the XML files .
But i ran into a snag when i tried to put a Tga image into a picture box seems like it does not like that lol. So now i guess ill have to use the TGASharp Library.
Though in that case, in general, the class itself should inherit IDisposable and you should make sure that its own Dispose function handles the cleanup when the object is disposed.
For forms, this already exists; the Dispose function is in the .designer.cs file.
On a related note, many people seem to ignore it, but the fact forms are IDisposable also means that any sub-dialogs shown for opening stuff like a little settings window should generally also be done with a "using" block.
Yea, that's what the editor does, too.
Thanks for the info so far .
Bizarrely, running normally without debugging doesn't have the issue. I also don't have the problem on my old Win7 PC.
Well i now have the zips displaying the Tga's and i can play the Wav files, plus that it even saves the forms size in the app.config and sets that to be its starting size