iterating through PictureBoxes in visual c++ - visual-c++

I'm programming in visual c++, and I have about 60 pictures (indexed p0...p63). I want to make a loop that goes through all the pictures and change their ImageLocation under some conditions.
I figured the Tag property and one of my attempts was like this:
I tagged my pictures from 0 to 63 and then tried the following:
for(int i=0; i<64; i++)
{
PictureBox->Tag[i]->ImageLocation="possible-.gif";
}
It's not working... I get this error:
syntax error : missing ';' before '->' line: 1514
syntax error : missing ';' before '->' line: 1514
(twice, same line)
What's the right way of doing it?
Thank you!
edit:
OK now I have the pictures in an array. Is there a way to have a common rule for all of them? I want to make a click event for each and every one of the pictures. Is the only way setting a rule for each independently? Or can I set a rule for the array itself by saying something like:
if(Pictureboxes[i]_Clicked)
{
Pictureboxes[i].something = "something else";
}

I found the way to solve it. So I guess I'm gonna answer myself:
I made an array of PictureBoxes:
private: static array<System::Windows::Forms::PictureBox^>^ pictures=(gcnew array<System::Windows::Forms::PictureBox^>(64));
and filled it with the pictures:
pictures[0] = p0;
pictures[1] = p1;
pictures[2] = p2;
...
Then i clicked each of the pictures to create click_events.
In each event i typed this:
int place = (/*pic number*/);
IndexOf(pictures);
This code sends to a function named IndexOf the picture i clicked.
And here is IndexOf():
static System::Void IndexOf(int& place)
{
int flag = 0;
if(pictures[place]->ImageLocation == "possible-.bmp")
{
flag = 1;
/*DO CODE*/
}
if(flag)
/*OTHER CODE*/
}
Now i can do whatever code i want for pictures[i] at /do code/ above.

Related

How do I remove the last character from a string in a textBox?

I am trying to create a calculator program similar to what Windows has, and I am currently having trouble with making a backspace key. It should, when clicked, remove the last character from the textBox Text field.
Here what I was thinking would work:
private: System::Void button14_Click(System::Object^ sender, System::EventArgs^ e) {
textBox1->Text[textBox1->TextLength] = ""; }
The error list looks like this:
I have also seen suggestions to use pop_back(), remove() and erase() on the Internet, but I don't have an idea how to use them.
Strings are immutable... you can't technically change the string.
IDK how to write this in the weird CLI C++ syntax, but something close to:
String^ s = textBox1->Text;
s = s^.Substring(0, s.Length - 1); // original s preserved, but no longer used
textBox1->Text = s;
IDK if it would allow something like, but if it does, I'd prefer it:
auto s = textBox1->Text;
s = s^.Substring(0, s.Length - 1); // original s preserved, but no longer used
textBox1->Text = s;

What's the Easiest Way to Skip a Line in a Managed String^ VC++

I'm trying to Skip a line in a Visual C++ managed String^ or String^ array but I haven't found any easy way to do so. In-fact, I've spent two days on something that would take less than 30 seconds in C#. There is a method .Skip() within C# Enumerable
https://learn.microsoft.com/en-us/dotnet/api/system.linq.enumerable.skip?view=netframework-4.7.2
and I'd like something similar for VC++ if possible.
Here's what I've tried:
auto a = gcnew cli::array<String ^>{ "Alpha", "Bravo", "Charlie", "Delta" };
auto xs = gcnew System::Collections::Generic::List<String^>(a);
System::Collections::Generic::IEnumerator<String^>^ e = xs->GetEnumerator();
e->MoveNext();
^^ that throws exception class System::EventArgs has no member "MoveNext"
EDIT: I know what's causing the exception System::EventArgs has no member "MoveNext" .. using ' e ' in Visual Studio causes the compiler to think I'm referring to the e for EventArgs as in e) click_method .. I switched to another name and it populates as this: System.Collections.Generic.List`1+Enumerator[System.String]
I also tried referencing System::Linq and then
System::Collections::Generic::List<String ^>^ _list = gcnew System::Collections::Generic::List<String ^>(System::IO::File::ReadAllLines(filename));
System::Collections::Generic::List<String ^>^ _list2 = _list->Skip(1);
which seems like it would work in C# but get the following exception
class System::Collections::Generic::List has no member skip
so the .NET library doesn't work in CLI / C++
Another thing I attempted was:
System::Collections::Generic::List<String ^>^ _list = gcnew System::Collections::Generic::List<String ^>(System::IO::File::ReadAllLines(filename));
System::Collections::Generic::List<String ^>^ _list2 = _list->RemoveAt(0);
but got exception:
a value of type "void" cannot be used to initialize an entity of type System::Collections::Generic::List^
I'm trying to do it without using marshal_string if possible, but I'm open for any suggestions, as I've been pulling my hair out on this, not sure what else to try =[
EDIT: this reads as an array not a String^ but I couldn't figure out how to do it with a String^ on it's own.
definitely not the quickest way but this skips x number of lines.
I am sick of CLI/C++/VC++ and can't wait to stop using it (I should have never used it in the first place and kick myself daily for not making this in C#).
//read the file to a CLI array (each line is a member)
auto a = System::IO::File::ReadAllLines("test66.txt");
//create a List from the array
auto xs = gcnew System::Collections::Generic::List<String^>(a);
//create a collection from the List
System::Collections::Generic::IEnumerator<String^>^ test66 = xs->GetEnumerator();
//the number of lines we want to skip
int x = 0;
//for loop stopping # x
for (int nxt; nxt <= x; nxt++)
{
test66->MoveNext();
}
//present selected array item to user or you could feed this into a String^
textBox11->Text = test66->Current;
feel free to give a better answer. I couldn't find much information since CLI/C++ is absolutely awful compared to C# and just about every other modern language. (IMO)

C++ Converting textbox content to a Float

Tried carefully code from this thread
Converting textbox string to float?
Tried to leavemy question in a comment, but yet not allowed to do so...
The summary of that goes like having two text boxes, taking data from first, doing something, and returning the result to the second.
String^ i1 = Textbox1->Text;
float rez = (float)(Convert::ToDouble(i1)*4);
Textbox2->Text = rez.ToString();
and it works pretty good unless Textbox1 got a float within itself (upd. it works ok with '65', but doesn't work with '65.5').
Trying to execute that code - crushes a program
> Calc.exe!Calc::Form1::Button0_Click(System::Object^ sender = 0x01b29c58, System::EventArgs^ e = 0x01b45e40) Line 123 + 0x30 byte C++
Convert::ToDouble
Using the ToDouble(String) method is equivalent to passing value to the Double.Parse(String) method. Value is interpreted by using the formatting conventions of the current thread culture.
So, you need
Catch possible exceptions
try {
float rez = (float)(Convert::ToDouble(i1)*4);
}
catch (FormatException) {
// handle format error exception here
}
catch (OverflowException) {
// handle overflow exception here
}
Use IFormatProvider

Evaluating the subscript operator in the watch window

I have a simple array wrapper class, which goes like this:
class MyArray
{
int * m_Data;
int m_Size;
public:
MyArray(int aSize) : m_Size(aSize), m_Data(new int[aSize])
{
}
int & operator [](int aIndex)
{
return m_Data[aIndex];
}
const int & operator [](int aIndex) const
{
return m_Data[aIndex];
}
};
MyArray a(10);
Whenever I try to evaluate a subscript operator in the debugger (quick watch, immediate window etc): e.g. a[0], I get a[0] no operator "[]" matches these operands error. I know I can dig through class fields to get to the content of the array. But it is so much easier to just copy a part of code line and evaluate it in the watch window.
I tried removing const and non-const [] operators. I also tried using () operator, it didn't work either, but it gave a different error message. I tried this in VS2012 and VS2013 Preview: same thing.
Is there any way to fix this?
If I replace the subscript operator with a member function:
int & Item(int aIndex)
{
return m_Data[aIndex];
}
Then watch window is able to show me the result. But I would prefer to use subscript operator.
I found a solution, which is not very convenient, but seems to work. If I use the expanded form of the operator call, then it works in VC++2012:
a.operator[](0)
It's not clear to me why these two forms are different to VC++ debugger. So I posted a new question here

some doubts in the following code

have a look at the code below once and help me out by clarifying my doubts.
I have commented my doubts on each lines where i have doubts. Moreover, its a part of code from a huge one. so please ignore the variable declarations and all.
The whole code is working perfect and no errors while compiled.
double Graph::Dijkstra( path_t& path )
{
int* paths = new int[_size];
double min = dijkstra(paths); // **is a function call or not? bcz i didn't found any function in the code**
if(min < 0) { delete[] paths; return -1;}
int i = _size - 1;
while(i>=0)
{
path.push(i); // **when will the program come out of this while loop, i'm wondering how does it breaks?**
i=paths[i];
}
path.push(0);
delete[] paths;
return min;
}
Full coding is available here.
double min = dijkstra(paths); // **is a function call or not? bcz i didn't found any function in the code**
It almost certainly is. However, it could be a free function, member function, function invoked by a macro, or something else. Without seeing the rest of the code, we can only guess.
while(i>=0)
{
path.push(i); // **when will the program come out of this while loop, i'm wondering how does it breaks?**
i=paths[i];
}
The program will come out of the loop as a soon as i is less than zero. If I had to guess, I'd say the each node in the path contains a link to the previous node's index with the last node in a path returning -1 or some other negative number.

Resources