How to call 2 windows forms in each other in C++? - winforms

I've been trying to convert a C# program with multiple forms to C++, but turned out that if I just include them in each other, the code would not compile.
I have tried to use forward declarations, but it only gave me issues with object creation.
I also tried to use #indef, but the program still doesn't compile and gives the same errors (c2065, c2061, and c2227 as result when I try to Show() a newly created form).
And I couldn't properly work with ParentForm due to the lack of brains (sadly, but true).
Here is a small part of the code that causes issues for me:
NewPasswordInput.h
#pragma once
#include "Encrypt.h" //class with functions
#include "AccessGranted.h"
namespace PassEncryptPlus {
//...
public ref class NewPassInput : public System::Windows::Forms::Form
{
private: String^ key;
public:
NewPassInput(String^ key)
{
InitializeComponent();
this->key = key;
}
//...
private: Encrypt *encrypt = new Encrypt();
private: System::Void button1_Click(System::Object^ sender, System::EventArgs^ e) {
//...
String^ newpass1 = textBox1->Text;
String^ str = encrypt->WritePass(newpass1); //generating a new key
int i = Application::OpenForms->Count;
AccessGranted^ accessGranted = new AccessGranted(str) //passing the key
accessGranted->Show();
Hide();
}
}
AccessGranted.h
#pragma once
#include "AccessGranted.h"
namespace PassEncryptPlus {
//...
public ref class AccessGranted : public System::Windows::Forms::Form
{
private: String^ key;
public:
AccessGranted(String^ key)
{
InitializeComponent();
this->key = key;
richTextBox1->Text = key;
}
//...
private: System::Void linkLabel1_LinkClicked(System::Object^ sender, System::Windows::Forms::LinkLabelLinkClickedEventArgs^ e) {
NewPassInput^ newPassInput = gcnew NewPassInput(str);
newPassInput->Show();
Hide();
}
}
Thank you in advance!
PS: AccessGranted appears first called by the form I didn't list here, if the order is important.

Related

Defining eventhandlers outside MainWindow?

I am trying to define some event handlers inside auser class but im not sure how. The MainWindow needs the handler definitions.
public abstract partial class MainWindow: Window {
public User user = new User();
}
public class User {
internal void ExampleMouseEventDown(object sender, MouseEventArgs e) {
// Does stuff;
}
}
Isnt there a way to somehow make this work? Such as:
mainWindow.AddHandleDefinition += ExampleMouseEventDown();
Also tried this:
public partial class MainWindow : Window {
public MainWindow() {
User user = new User(this);
}
}
public class User
{
internal User(MainWindow w)
{
w.AddObserverButton.MouseUp += ExampleMouseEventDown;
}
internal void ExampleMouseEventDown(object sender, MouseEventArgs e)
{
// Does stuff;
}
}

Updating TextBox in a windows form from a public method outside the form

I have a windows form (Form1.h) with a Button and a TextBox. The TextBox is empty when the form is initialized. On button click, a method outside the form is called and it should update the TextBox. How would I make an update of the TextBox from a non-form class? Below is my sample code:
// Form1.h
private: System::Void findResultButton_Click(System::Object^ sender, System::EventArgs^ e) {
FirstResults* firstResults = new FirstResults();
firstResults->findResult();
}
// FirstResults.cpp
void FirstResults::findResult() {
// do some calculations here and find result.
// write the result value to a .txt file.
// Update TextBox in Form1.h with result value.
}
First you need to create a static instance of the form.
Then in any .cpp file you want to access the TextBox1 or TextArea you just
public ref class Form1 : public System::Windows::Forms::Form
{
public:
static Form1^ myForm1;
Form1(void)
{
InitializeComponent();
myForm1 = this;
//
//TODO: Add the constructor code here
//
}
}
Then in .cpp #include "form1.h"
and
Form1^ myform1 = gcnew Form1();
Form1::myForm1->textBox1->Text = L" FROM the main.cpp ";
Or if you need
System::Windows::Forms::myform1->textBox1->Text = L" FROM the main.cpp ";

How to set an event handler of a lower class radiobutton in an upper class?

I create a user control group sub-class. There are two radiobuttons. I need to create event handlers for them. I have two directions to go. One is to create event handlers in the sub class and let the event handler to change a constant in the subclass. I will use a function to check the sub class constant in the upper class. The other one is to create event handlers in the upper class for the sub-class radio buttons. The following is my code for method 1.Note I have commented out two lines (they are the event handler creation) because they are wrong because they create errors please help
using namespace System;
using namespace System::ComponentModel;
using namespace System::Collections;
using namespace System::Windows::Forms;
using namespace System::Data;
using namespace System::Drawing;
using namespace System::Collections;
using namespace System::Collections::Generic;
#include <stdio.h>
#include <stdlib.h>
#using <mscorlib.dll>
public ref class temp_groupbox: public GroupBox
{
public: temp_groupbox(int a, int b, String ^groupboxname){
// Create and initialize a GroupBox and two RadioButton controls.
//GroupBox^ groupBox1 = gcnew GroupBox;
RadioButton^ radioButton1 = gcnew RadioButton;
RadioButton^ radioButton2 = gcnew RadioButton;
// Add the RadioButtons to the GroupBox.
this->Controls->Add( radioButton1 );
this->Controls->Add( radioButton2 );
this->Location = System::Drawing::Point(a, b);
this->Size = System::Drawing::Size(500, 100);
this->TabIndex = 0;
this->TabStop = false;
radioButton1->Name = L"radioButton1";
radioButton2->Name = L"radioButton2";
radioButton1->Size = System::Drawing::Size(85, 17);
radioButton2->Size = System::Drawing::Size(85, 17);
radioButton1->Location = System::Drawing::Point(30, 40);
radioButton2->Location = System::Drawing::Point(30, 90);
radioButton1->TabIndex = 0;
radioButton1->TabStop = true;
radioButton2->TabIndex = 1;
radioButton2->TabStop = true;
radioButton1->UseVisualStyleBackColor = true;
radioButton1->CheckedChanged += gcnew System::EventHandler(this, radioButton1_CheckedChanged);
radioButton2->UseVisualStyleBackColor = true;
radioButton2->CheckedChanged += gcnew System::EventHandler(this, radioButton2_CheckedChanged);
this->SuspendLayout();
this->ResumeLayout(false);
this->PerformLayout();
}
public: RadioButton^ radioButton1;
public: RadioButton^ radioButton2;
public: int anss;
void radioButton1_CheckedChanged(Object^ sender, EventArgs^ e)
{
anss = 1;
}
void radioButton2_CheckedChanged(Object^ sender, EventArgs^ e)
{
anss = 2;
}
};// end ref class
Do you have methods radioButton1_CheckedChanged and radioButton2_CheckedChanged defined?
void radioButton1_CheckedChanged(Object^ sender, EventArgs^ e)
{
}
void radioButton2_CheckedChanged(Object^ sender, EventArgs^ e)
{
}
If these methods already exist, please list the error message you're getting. It's hard to figure out how to fix something if we don't know what's wrong.
You need to specify the full class name of the method you're creating a delegate for, and use the & to take the address of it.
gcnew System::EventHandler(this, &temp_groupbox::radioButton1_CheckedChanged)

How to create an array of objects in VC++2010?

I need to build an array to contain objects. However, it does not work and I could not find out the error myself. Please help
# include "CRegistration.h" //My object class
SKIP MANY LINES
public:
Form1(void)
{
InitializeComponent();
//
//TODO: Add the constructor code here
//
array<CRegistration^> ^CregArray = gcnew array<CRegistration^>(100);
record_number = 0;
}
private: System::Void MyAdd_Click(System::Object^ sender, System::EventArgs^ e) {
Form2^ myForm2 = gcnew Form2();
if (myForm2->ShowDialog()==System::Windows::Forms::DialogResult::OK) {
record_number = record_number + 1;
CRegistration^ Creg = gcnew CRegistration(System::Convert::ToString(record_number),myForm2->TempReg[0],myForm2->TempReg[1],myForm2->TempReg[2],myForm2->TempReg[3]);
CregArray[record_number-1] = Creg;
}
}
};
change line
array<CRegistration^> ^CregArray = gcnew array<CRegistration^>(100);
to
CregArray = gcnew array<CRegistration^>(100);
add field declaration:
Form1(void)
{
..
}
array<CRegistration^> ^CregArray;
private: System::Void MyAdd_Click(System::Object^ sender, System::EventArgs^ e) {
..
}

Proper way to call AnimateWindow with a .NET WinForms Form?

i'm trying to call AnimateWindow to animate the show and hide of a WinForms window.
Here's a copy of the win32 translation:
private static class NativeMethods
{
public const int AW_ACTIVATE = 0x20000;
public const int AW_HIDE = 0x10000;
public const int AW_BLEND = 0x80000;
public const int AW_CENTER = 0x00000010;
public const int AW_SLIDE = 0X40000;
public const int AW_HOR_POSITIVE = 0x1;
public const int AW_HOR_NEGATIVE = 0X2;
[DllImport("user32.dll", CharSet = CharSet.Auto)]
public static extern int AnimateWindow(IntPtr hwand, int dwTime, int dwFlags);
}
But the problem is how to fit a call to AnimateWindow into the) WinForms scheme. One person suggests OnLoad:
protected override void OnLoad(EventArgs e)
{
base.OnLoad(e);
AnimateWindow(this.Handle, 200, AW_ACTIVATE | AW_HOR_NEGATIVE | AW_SLIDE);
}
and OnClosing:
protected override void OnClosing(System.ComponentModel.CancelEventArgs e)
{
base.OnClosing(e);
if (e.Cancel == false)
{
AnimateWindow(this.Handle, 200, AW_HIDE | AW_HOR_POSITIVE | AW_SLIDE);
}
}
Except that it doesn't work.
the form doesn't use any animation while appearing
during hide the form animates its horizontal slide off the screen, then reappears, before hiding the normal way
What is the correct way to mix AnimateWindow with WinForms?
See also
.NET AnimateWindow: this guy asked the same question. But since it was trying to achieve something else, people solved his problem rather than answering his question.
C# WinForms AnimateWindow issue: This guy was interested in using AnimateWindow with child controls, rather than a top-level window.
Bonus Chatter
i was perusing through the Form -> Show -> Visible -> SetVisibleCore, when i discovered this bug:
protected virtual void SetVisibleCore(bool value)
{
try
{
HandleCollector.SuspendCollect();
//...snip...
}
finally
{
HandleCollector.ResumeCollect();
}
}
Nice to know that everyone can introduce these subtle errors.
I think AnimateWindow has it's limitations to work properly. For example, it doesn't play well with Aero, so to animate a sliding form, you would need to set the BorderStyle to None. Also, make sure the StartPosition is set to Manual.
Simple example:
public partial class Form1 : Form {
public const int AW_ACTIVATE = 0x20000;
public const int AW_HIDE = 0x10000;
public const int AW_BLEND = 0x80000;
public const int AW_CENTER = 0x00000010;
public const int AW_SLIDE = 0X40000;
public const int AW_HOR_POSITIVE = 0x1;
public const int AW_HOR_NEGATIVE = 0X2;
[DllImport("user32.dll", CharSet = CharSet.Auto)]
public static extern int AnimateWindow(IntPtr hwand, int dwTime, int dwFlags);
public Form1() {
InitializeComponent();
}
private void button1_Click(object sender, EventArgs e) {
Form toastForm = new Form();
toastForm.ShowInTaskbar = false;
toastForm.StartPosition = FormStartPosition.Manual;
toastForm.FormBorderStyle = FormBorderStyle.None;
toastForm.Size = new Size(256, 64);
toastForm.Location = new Point(Screen.PrimaryScreen.WorkingArea.Right - toastForm.Width,
Screen.PrimaryScreen.WorkingArea.Bottom - toastForm.Height);
Button closeButton = new Button();
closeButton.Text = "Close";
toastForm.Controls.Add(closeButton);
closeButton.Click += delegate { toastForm.Close(); };
AnimateWindow(toastForm.Handle, 200, AW_ACTIVATE | AW_HOR_NEGATIVE | AW_SLIDE);
toastForm.Show();
}
}
I'm not sure what your AnimateWindow call does, but when you need to change underlying native 'stuff' to do with windows forms, I've always used the CreateParams() override. You may
find a similar function for what you are trying to achieve.
Here's an example of a transparent tool window, that doesn't activate when it is shown.
Protected Overrides ReadOnly Property CreateParams() As System.Windows.Forms.CreateParams
Get
Dim baseParams As Windows.Forms.CreateParams = MyBase.CreateParams
baseParams.ExStyle = baseParams.ExStyle Or NativeMethods.ExtendedWindowsStyles.WS_EX_LAYERED Or NativeMethods.ExtendedWindowsStyles.WS_EX_TRANSPARENT Or NativeMethods.ExtendedWindowsStyles.WS_EX_NOACTIVATE Or NativeMethods.ExtendedWindowsStyles.WS_EX_TOOLWINDOW
Return baseParams
End Get
End Property

Resources