2

I have Visual Studio 2022 on a Windows 10 platform, and although I've been using it to develop code in C for a while, I'm new to using it to develop a GUI using Win Forms. I've been looking at some online tutorials, and have some questions.

My application has three forms, a login form, an encode form and a decode form, which are LoginForm.h, EncodeForm.h and DecodeForm.h respectively. I have designed these forms using the design view for each of them, and that works OK. In following a tutorial, LoginForm.cpp contains the following code:

#include "LoginForm.h" using namespace myFirstSteganGUI; void main() { Application::EnableVisualStyles(); Application::SetCompatibleTextRenderingDefault(false); Application::Run(gcnew LoginForm()); } 

with EncodeForm.cpp and DecodeForm.cpp just including their respective header files with nothing else.

The login form contains several controls, the two that are relevant here are "Encode" (button 3) and "Decode" (button 4), such that when you click on one of them the application takes you to the encode or decode forms.

In the design view of LoginForm.h I double click on "Encode" and "Decode", and in both cases I include code in the generated functions near the end of the code for LoginForm.h. The code is as follows:

private: System::Void button3_Click(System::Object^ sender, System::EventArgs^ e) { EncodeForm obj; obj.ShowDialog(); } private: System::Void button4_Click(System::Object^ sender, System::EventArgs^ e) { DecodeForm obj; obj.ShowDialog(); } 

together with inserting #include "EncodeForm.h" and #include "DecodeForm.h" immediately after #pragma once. The applications compiles correctly, and opens the login form, then when I click on the "Encode" the encode form does indeed open, but the login form stays open and I want it to close. This is problem 1. If I close the encode form then I can click on "Decode" and the decode form opens, but as before the login button stays open.

I want to be able to switch from the encode or decode forms back to the login form, and have the button on both forms as "Back to Login". In "EncodeForm.h" design view I tried the same as I did for LoginForm.h, namely double click on "Back to Login", then insert the code in the generated function as follows:

private: System::Void button3_Click(System::Object^ sender, System::EventArgs^ e) { LoginForm obj; obj.ShowDialog(); } 

and inserted #include "LoginForm.h" below #pragma once. However, this did not compile and produced several errors which are difficult to understand. It's certain that the same problem would happen with the decode form, which I didn't try. This is problem 2.

As a test, I changed LoginForm.cpp before I tried the changes above, with the resultant code being:

#include "LoginForm.h" #include "EncodeForm.h" #include "DecodeForm.h" using namespace myFirstSteganGUI; void main() { Application::EnableVisualStyles(); Application::SetCompatibleTextRenderingDefault(false); Application::Run(gcnew LoginForm()); Application::Run(gcnew EncodeForm()); Application::Run(gcnew DecodeForm()); } 

The login form does indeed appear, then the encode form appears after I close the login form, then the decode form appears after I close the encode form. This is indeed as expected, and although is not what I want, this at least enables me to see how these forms are displayed.

My questions are:

1: From the login form I want the encode or decode form to appear and the login form to close. At the moment the login form does not close.

2: From either the encode or decode forms, I want the login form to reopen with its original state preserved, i.e with the login code, when "Back to Login" is clicked, and the encode or decode forms to close. They do not need to preserve their states.

What is the best way of doing this? I'm sure there must be a simple answer, I just do not know enough about Visual Studio using Win Forms for this.

1 Answer 1

0

Instead of the login form actually closing, would it be acceptable instead for the dialog to just not be shown? If so, then a relatively simple solution is to use the Login form's Hide() method before displaying the Encode or Decode forms. For example, there's

private: System::Void button3_Click(System::Object^ sender, System::EventArgs^ e) { EncodeForm obj; Hide(); obj.ShowDialog(); } 

Next, store a reference to the Login form somewhere accessible from the Encode and Decode forms, such as in a global variable, e.g., objLogin. This can be set in various ways, such as from the LoginForm constructor. Alternatively, to make it more flexible and easily extensible, you could do as suggested in Louis Go's comment, i.e., create an accessible callback to be used instead.

Then in the Encode/Decode form handlers for the "Back to Login" buttons, have the Login form's Show() method be called (e.g., objLogin.Show();) and then Close(); to close this form (or possibly the other way around if there's any issue with the Login form still being in its Click method showing the Encode/Decode form).

Sign up to request clarification or add additional context in comments.

14 Comments

I'll suggest create a callback that is accessible by every form and make the instance accessible to callback instead of holding it in other forms. What if you want 100 forms accessing single form? That would be tedious.
@LouisGo Thanks for the feedback. Your suggestion is a good one, so I've added it to my answer.
Many thanks for your tips. I got Hide() to work in both EncodeFirm.h and DecodeForm.h, but I can't get back to LoginForm.h. Unfortunately I know much less about classes in C++ compared to Java. In the LoginForm.h after InitializeComponent() I added Object objLogin,, then in EncodeForm I added objLogin; objLogin.Show(); Close(); for the button in question, as well as adding #include "LoginForm.h" at the top of the file. I just get a bunch of compilation error. For now I want to avoid callback functions and just do something as simple as possible.
@csharp You're welcome. I'm surprised the login form is not redisplayed when you use the Show() method with it. According to the Microsoft documentation about this, it should set the Visible property to true and, thus, redisplay the form. Perhaps the form then needs to have Activate called. As it says there, ...
@csharp (cont.) "Activating a form brings it to the front if this is the active application, or it flashes the window caption if this is not the active application. The form must be visible for this method to have any effect." Thus, you should make this call after first calling Show(). Regarding your compilation errors, one reason is with Object objLogin, unless you do a cast, the compiler will think it's just a generic Object, so there's no Show() method on it. Instead, you should have a global variable defined for it like LoginForm objLogin;. Please let me know about any other issues.
|

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.