C++ - save image from form to file - winforms

I'm new in programming Windows Form Application. I want to capture my Windows form (with the function CaptureScreen()) and save it to a file by clicking on a button using the SaveFileDialog. Here my code:
private: System::Void CaptureScreen()
{
Drawing::Graphics^ myGraphics = this->CreateGraphics();
memoryImage = gcnew Drawing::Bitmap(Size.Width, Size.Height, myGraphics);
Drawing::Graphics^ memoryGraphics = Drawing::Graphics::FromImage(memoryImage);
memoryGraphics->CopyFromScreen(this->Location.X, this->Location.Y, 0, 0, this->Size);
}
private: System::Void btnSave_Click(System::Object^ sender, System::EventArgs^ e)
{
SaveFileDialog^ saveDiag2 = gcnew SaveFileDialog();
saveDiag2->Filter = "Dateityp PNG (*.PNG)|*.PNG|All files (*.*)|*.*";
saveDiag2->FilterIndex = 1;
saveDiag2->RestoreDirectory = true;
if (saveDiag2->ShowDialog() == System::Windows::Forms::DialogResult::OK)
{
String^ savePath = saveDiag2->FileName;
if (saveDiag2->OpenFile() != nullptr)
{
try
{
CaptureScreen();
if (memoryImage != nullptr)
{
memoryImage->Save(savePath, Imaging::ImageFormat::Png);
}
}
catch (Exception^)
{
MessageBox::Show("There was a problem saving the file."
"Check the file permissions.");
}
}
}
}
I always get the Exception displayed. What am I doing wrong?

Hans Passant is right. You should dispose IDisposible objects. In C++ CLI you can do it with help of msclr::auto_handle smart pointer.
#include <msclr/auto_handle.h>
private: System::Void CaptureScreen()
{
msclr::auto_handle<Drawing::Graphics> myGraphics(this->CreateGraphics());
memoryImage = gcnew Drawing::Bitmap(Size.Width, Size.Height, myGraphics.get());
msclr::auto_handle<Drawing::Graphics> memoryGraphics(Drawing::Graphics::FromImage(memoryImage));
memoryGraphics->CopyFromScreen(this->Location.X, this->Location.Y, 0, 0, this->Size);
}
Also you can retrieve usefull information from Exception object:
catch (Exception^ exception)
{
MessageBox::Show("There was a problem saving the file: " + exception->ToString(),
"Check the file permissions.");
}

Related

MyForm2: undeclared identifier [closed]

Closed. This question needs debugging details. It is not currently accepting answers.
Edit the question to include desired behavior, a specific problem or error, and the shortest code necessary to reproduce the problem. This will help others answer the question.
Closed 2 years ago.
Improve this question
I've been strugling with this error for a while now.
I'm trying to implement a log in to an ATM system and I'm trying to connect it to a database as well. But when I try to run it, shows up 144 errors that are all the same:
'MyForm2': is not a member of 'jiji'
'MyForm2': undeclared identifier
Syntax error: missing ';' before identifier 'f2'
'f2':undeclared identifier
I honestly don't know why is this happening. I've tried to include MyForm2.h in the main code but nothing changes.
Here I leve the piece of code that is nearly the same for all my 7 forms ( except the 2nd that is the one that is giving the error I think)
MyForm.h:
private: System::Void button1_Click(System::Object^ sender, System::EventArgs^ e) {
try {
String^ User = textBox1->Text;
String^ Pwd = textBox2->Text;
int AN = Int32::Parse(textBox3->Text);
String^ constr = "Server=127.0.0.1;Uid=root;Pwd=;Database=visualcppdb";
MySqlConnection^ con = gcnew MySqlConnection(constr);
MySqlDataAdapter^ da = gcnew MySqlDataAdapter("Select AccountNum from Userinfo WHERE AccountNum = '" + AN + "'", con);
DataTable^ dt = gcnew DataTable();
da->Fill(dt);
if (dt->Rows->Count >= 1) {
MySqlCommand^ cmd = gcnew MySqlCommand("insert into Db values (" + AN + ") ", con);
con->Open();
MySqlDataReader^ dr = cmd->ExecuteReader();
con->Close();
try {
this->Hide();
jiji::MyForm2 f2;
f2.ShowDialog();
this->Show();
}
finally {
this->Close();
}
}
else {
MessageBox::Show("User does not exist, try again");
}
}
catch (Exception^ e) {
MessageBox::Show(e->Message);
}
}
By the way AN is the Account number.
The MyForm2.h code is the same over and over again except for the ending.
MyForm2.h:
//Extract money
private: System::Void button1_Click(System::Object^ sender, System::EventArgs^ e) {
try {
this->Hide();
jiji::MyForm3 f3;
f3.ShowDialog();
this->Show();
}
finally {
this->Close();
}
}
//Insert Money
private: System::Void button2_Click(System::Object^ sender, System::EventArgs^ e) {
try {
this->Hide();
jiji::MyForm4 f4;
f4.ShowDialog();
this->Show();
}
finally {
this->Close();
}
}
//Transfer
private: System::Void button3_Click(System::Object^ sender, System::EventArgs^ e) {
try {
this->Hide();
jiji::MyForm5 f5;
f5.ShowDialog();
this->Show();
}
finally {
this->Close();
}
}
//Check Amount
private: System::Void button4_Click(System::Object^ sender, System::EventArgs^ e) {
try {
this->Hide();
jiji::MyForm6 f6;
f6.ShowDialog();
this->Show();
}
finally {
this->Close();
}
}
//Reload phone
private: System::Void button5_Click(System::Object^ sender, System::EventArgs^ e) {
try {
this->Hide();
jiji::MyForm7 f7;
f7.ShowDialog();
this->Show();
}
finally {
this->Close();
}
}
//Exit
private: System::Void button6_Click(System::Object^ sender, System::EventArgs^ e) {
try {
String^ constr = "Server=127.0.0.1;Uid=root;Pwd=;Database=visualcppdb";
MySqlConnection^ con = gcnew MySqlConnection(constr);
MySqlCommand^ cmd = gcnew MySqlCommand("TRUNCATE Db ", con);
con->Open();
MySqlDataReader^ dr = cmd->ExecuteReader();
con->Close();
}
catch (Exception^ e) {
MessageBox::Show(e->Message);
}
finally {
this->Close();
}
}
Perhaps you aren't including MyForm2.h in a context MyForm.h can access?
Maybe look into how to declare a namespace and how to include headers, e.g. Creating a C++ namespace in header and source (cpp)
What happens if you inline the MyForm2 class definition into MyForm so you guarantee it is accessible?

Using OpenFileDialog with windows form not opening

I am making a GUI with a windows form and OpenFileDialog is not opening on button click.
I am using the following code and nothing happens when I click on my button designated as button1.
System::Void button1_Click(System::Object^ sender, System::EventArgs^ e)
{
Stream^ myStream;
OpenFileDialog^ openFileDialog1 = gcnew OpenFileDialog;
openFileDialog1->InitialDirectory = "c:\\";
openFileDialog1->Filter = "txt files (*.txt)|*.txt|All files (*.*)|*.*";
openFileDialog1->FilterIndex = 1;
openFileDialog1->RestoreDirectory = true;
if (openFileDialog1->ShowDialog() == System::Windows::Forms::DialogResult::OK)
{
if ((myStream = openFileDialog1->OpenFile()) != nullptr)
{
String^ strfilename = openFileDialog1->FileName;
String^ Readfile = File::ReadAllText(strfilename);
MessageBox::Show(Readfile); // This is a test line
//myStream->Close();
}
}
}

How do I prevent multiple instances of Process.start?

I have a button on my WinForm. Code works great until I observed my test users.
They don't wait for the PDF to launch. Instead they will click it several times (causing multiple instances of the Acrobat reader to launch
private void pictureBoxNewsLetter_Click(object sender, EventArgs e)
{
lockControls();
launchNewsLetter();
unlockControls();
}
private void launchNewsLetter()
{
// Newsletter
lockControls();
ProcessStartInfo psi = new ProcessStartInfo(#"Y:\Newsletter.pdf");
Process ps = new Process { StartInfo = psi };
ps.Start();
ps.WaitForExit();
Thread.Sleep(1000);
unlockControls();
}
--- Code to disable my controls.
private void lockControls()
{
dontRunHandler = false;
foreach (var pb in this.Controls.OfType<PictureBox>())
{
pb.Enabled = false;
}
}
private void unlockControls()
{
dontRunHandler = true;
foreach (var pb in this.Controls.OfType<PictureBox>())
{
pb.Enabled = true;
}
}

Cannot delete file because it is used by another process

I'm getting this exception
The process cannot access the file 'myfile.zip' because it is being used by another process.
When I try to delete a file. I understand the error, but I'm not sure what other process could be using the file.
I'm downloading the file via WebClient asynchronously, but I cancel the download before trying to delete it, which means that process should relinquish it, no?
Here are the relevant methods. It's a simple file-downloader:
private void textBox1_KeyUp(object sender, KeyEventArgs e)
{
string downloadFile = textBox1.Text.Trim();
if (e.Key == Key.Return && downloadFile != "")
{
var dlg = new SaveFileDialog();
dlg.FileName = Path.GetFileName(downloadFile);
dlg.DefaultExt = Path.GetExtension(downloadFile);
var result = dlg.ShowDialog();
if(result.Value)
{
textBox1.Text = "";
textBox1.Focus();
_saveFile = dlg.FileName;
progressBar1.Dispatcher.Invoke(DispatcherPriority.Normal, new Action(() => progressBar1.Foreground = new SolidColorBrush(Color.FromRgb(0, 255, 0))));
_webClient.DownloadFileAsync(new Uri(downloadFile), _saveFile);
}
}
}
private void Window_Closing(object sender, System.ComponentModel.CancelEventArgs e)
{
if (_webClient.IsBusy && _saveFile != null)
{
var result = MessageBox.Show("Download in progress. Are you sure you want to exit?", "Exit?", MessageBoxButton.YesNo, MessageBoxImage.Warning);
if (result == MessageBoxResult.Yes)
{
_webClient.CancelAsync();
File.Delete(_saveFile);
}
else
{
e.Cancel = true;
}
}
}
You need to wait when downloading realy canceled. When call _webClient.CancelAsync(); next operator executes immediatley before webClient canceled.
May be you need delete the file in callback of CancelAsync(...)

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) {
..
}

Resources