Passing command line arguments to a windows form file in C++/CLI - winforms

I've been learning C++/CLI for a few months now, but no matter what I try, I can't seem to fix a problem I'm having.
I need to pass either a String^, Array^, or an ArrayList^ data type from main.cpp to Form1.h. I've attempted to make variables global in main.cpp and then call the variable using extern. However, this will not work for String, Array, and ArrayList data types.
How would I go about doing this? Thanks in advance. Here is a paraphrase of my code:
//main.cpp
bool LoadFileFromArgument = false; //A boolean can be declared global
String^ argument; //this will not pass from main.cpp to Form1.h
int main(array<System::String ^> ^args)
{
String ^ argument = args[1]
// Enabling Windows XP visual effects before any controls are created
Application::EnableVisualStyles();
Application::SetCompatibleTextRenderingDefault(false);
// Create the main window and run it
Application::Run(gcnew Form1());
return 0;
}
//Form1.h
public ref class Form1 : public System::Windows::Forms::Form
{
public:
Form1(void)
{
InitializeComponent();
//
//TODO: Add the constructor code here
//
extern bool LoadFileFromArgument; //is grabbed without error
extern String^ argument; //will not work
Here is the error:
error C3145: 'argument' : global or static variable may not
have managed type 'System::String ^'
may not declare a global or static variable,
or a member of a native type that refers to objects in the gc heap

Can you not create an overloaded constructor for the form. i.e.
public ref class Form1 : public System::Windows::Forms::Form
{
public:
Form1(String^ argument)
{
InitializeComponent();
//
//TODO: Add the constructor code here
//
// Use "argument" parameter as req'd.
}
Form1(void)
{
//....usual constructor here...
//..etc...
then from main
// Create the main window and run it
Application::Run(gcnew Form1(argument));

Related

How do I use my own function in a timer class?

The code is taken from here:
https://learn.microsoft.com/en-us/dotnet/api/system.windows.forms.timer?view=windowsdesktop-6.0
private:
static System::Windows::Forms::Timer^ myTimer = gcnew System::Windows::Forms::Timer;
static int alarmCounter = 1;
static bool exitFlag = false;
// This is the method to run when the timer is raised.
static void TimerEventProcessor( Object^ /*myObject*/, EventArgs^ /*myEventArgs*/ )
{
myTimer->Stop();
// Displays a message box asking whether to continue running the timer.
if ( MessageBox::Show( "Continue running?", String::Format( "Count is: {0}", alarmCounter ), MessageBoxButtons::YesNo ) == DialogResult::Yes )
{
// Restarts the timer and increments the counter.
alarmCounter += 1;
myTimer->Enabled = true;
}
else
{
// Stops the timer.
exitFlag = true;
}
}
For example, after the line myTimer->Stop(); I want to use my own method. How do I identify it? E0020 ID "draw 1" is not defined.
System:: Void Practform::MyForm::draw1() {
. . .
}
Please tell me, because I'm a little stalled, since I've never worked with this.
I have a feeling that what you are bumping up against is attempting to invoke an instance method from a static method. To do so, you would need to have an instance of the class which has the method, e.g:
ref struct Foo {
void InstanceMethod() {}
static void StaticMethod() {
auto instance = gcnew Foo();
instance->InstanceMethod();
}
}
called like so:
Foo::StaticMethod();
However, taking the example code, it could be easier (and more appropriate) to change the static methods to instance methods, like so:
using namespace System;
using namespace System::Windows::Forms;
ref struct MyForm : Form {
Timer ^myTimer = gcnew Timer();
MyForm(void) {
myTimer->Tick += gcnew EventHandler(this, &MyForm::TimerEventProcessor);
myTimer->Interval = 5000;
myTimer->Start();
}
void TimerEventProcessor(Object ^, EventArgs ^) {
myTimer->Stop();
draw1();
}
void draw1() {
MessageBox::Show("Done", "Timer is done", MessageBoxButtons::OK);
}
};
called like so:
auto form = gcnew MyForm();
form->Show();
Notes:
I'm assuming that you've added the code from the example into your own class, called MyForm
I've used struct throughout instead of class to make everything public - you should use the appropriate access modifiers to your use case
The most notable change is the use of the EventHandler constructor which takes an instance of the handler as its first argument, and the method to execute as its second.
The advantages of using instance methods and properties are that:
you will have access to this in the draw1() method (given the name of the method, is likely to want to draw using the form instance), and
the Timer instance will be garbage collected as appropriate,

Difference in the declaration beyween two syntaxes

Ref : Cannot reference "X" before supertype constructor has been called, where x is a final variable
class ArrayFunctions {
//public Integer[] arrayTemplate;
private static Scanner scanner = new Scanner(System.in);
ArrayFunctions(int k){
Integer[] arrayTemplate = new Integer[k] ;
}
.
.
.
public class ArrayFunctionsImplementation{
public static void main(String[] args) {
ArrayFunctions newArray = new ArrayFunctions(5);
newArray.getIntegers(newArray.arrayTemplate);
newArray.printIntegers(newArray.arrayTemplate);
newArray.sortArray(newArray.arrayTemplate);
newArray.printIntegers(newArray.arrayTemplate);
}
}
}
If I use the declaration //public Integer[] arrayTemplate; that is currently commented out , I am able to access the variable "arrayTemplate" in the public class.
But if I declare the variable by calling the constructor as per the code below, I am unable to access it anywhere. If I understand correctly, both the ways declare the variable and by the time I am trying to access it , the object is already created.
PS : I am using Integer class just for experimentation instead of using plain int
Cheers
Your current code declares a variable of the ArrayFunctions constructor and so, that variable is only accessible in your constructor.
Your commented code, declares a member of the ArrayFunctions class, which then can be accessed anywhere from the class (or elsewhere since you made it public).

Interlocked.Increment not working with my Get variable name

I have WPF application and my work method play my files in different threads
This is my Global variable that update my UI:
public static int _totalFilesSent;
Now because i am implement INotifyPropertyChanged in my model i have also this:
public static int TotalFilesSent
{
get { return _totalFilesSent; }
set
{
_totalFilesSent = value;
OnStaticlPropertyChanged("TotalFilesSent");
}
}
(i didn't add the event function because this is not relevant here).
So every time i am update my Global variable this way:
Interlocked.Increment(ref _totalFilesSent );
Now because i need to update my UI with my INotifyPropertyChanged event i need to use TotalFilesSent instead of _totalFilesSent but in this way i got this compilation error:
A property, indexer or dynamic member access may not be passed as an
out or ref parameter.
What does it mean and how can i solved it ?
You may easily raise the StaticPropertyChanged event after calling Interlocked.Increment:
private static int _totalFilesSent;
public static int TotalFilesSent
{
get { return _totalFilesSent; }
}
public static void IncrementTotalFilesSent()
{
Interlocked.Increment(ref _totalFilesSent);
OnStaticPropertyChanged("TotalFilesSent");
}

Silverlight 4 - Type.GetType() not working across assemblies

Basically the problem is that I'd like to invoke a method in an unreferenced assembly, but can't seem to find the right call for instantiating the class. I've tried things like a simple Type t = Type.GetType("MyApp.Helper") which returns null, and Assembly.LoadFrom("MyApp.Helper") which throws a security exception.
In the example below, two projects/assemblies (Helper.dll and Menu.dll) are compiled separately into a common 'libs' folder, but do not reference each other. Main.dll references both, and the references are set to 'Copy local' in VS. So when the app runs, the Main.xap should contain all three assemblies and they should be loaded into the same application domain. Or so goes my understanding. Is this an impossible quest? I see lots of comments regarding plug-ins but so far I haven't seen examples for this specific design. For example, I suppose I could do something like Jeff Prosise describes here, but I'd rather have everything in one package.
Here's a sketch of my code:
In one project/assembly, I have a worker class:
namespace MyApp.Helper {
public class Helper {
public void ShowHelp() {
Console.Write("Help!");
}
}
}
In another project/assembly, I have a menu class which tries to invoke the helper:
namespace MyApp.Menu {
public class Selector {
public void InvokeSelection(string className, string functionName) {
// fails: t will be null
Type t = Type.GetType(className);
// fails: t will be null
t = Type.GetType(string.Format("{0}.{1}, {0}, Version=1.0.0.0, Culture=\"\", PublicTokenKey=null", "MyApp.Helper", "Helper"));
// however, this works (reference to main assembly?)
t = Type.GetType(string.Format("{0}.{1}, {0}, Version=1.0.0.0, Culture=\"\", PublicTokenKey=null", "MyApp.Main", "Worker"));
// and, I'd like to do something like the following
// t.InvokeMember(functionName, ...);
}
}
}
Finally, I have the main app assembly:
namespace MyApp.Main {
public class Main {
public static void Main() {
MyApp.Menu.Selector sel = new Menu.Selector();
sel.InvokeSelection("MyApp.Help.Helper", "ShowHelp"); // fails
sel.InvokeSelection("MyApp.Main.Main", "Worker"); // works in some cases
}
public void Worker() {
Console.Write("Work!");
}
}
}
Thanks for any ideas!
-Chris.
You need to get the Assembly object, then call its GetType method.
However, I don't see why you're using Reflection at all.
You can call the method normally from your main project.
First, you should note that since it's SL, you can't invoke private/protected/internal members.
Second, try this:
public void InvokeSelection(string className, string functionName) {
var asm = Assembly.Load("MyApp.Helper, Version=1.0.0.0, Culture=\"\", PublicTokenKey=null"); // double check this is correct!
Type t = asm .GetType(className);
// and, I'd like to do something like the following
// t.InvokeMember(functionName, ...);
}

Where should I put initialization code so it would be executed in before VS initializes my control in design mode

I have a method Translate extension which searches for a translation. Normally translations are loaded in Window constructor (I tried in App.Setup too). No if i run the application all the translations are displayed correctly, but when opening a user control all translations are gone.
So the question is where do I put my initialization code so it would be executed before VS initializes design window
it should be default constructor
Either the class constructor (or code called from it) or some static member initialized by a static constructor.
Option 1:
public partial class MyUserControl : UserControl
{
int thisWillWork = 1;
int thisWillAlsoWork;
public MyUserControl()
{
thisWillAlsoWork = 1;
InitializeComponents();
}
Option 2:
public class SomeOtherClass
{
public static int YouCanUseThis = 1;
public static int AndThisAlso;
static SomeOtherClass()
{
AndThisAlso = 1;
}
}

Resources