C++\CLI Windows Forms - creating external class - forms

While making a simple windows forms application with VC++ I have a listview containing some files and their info. What I want to do is only show the filename in the list while storing the full filepath. I created an external class to do this:
class FileInfoContainer {
vector<string> filenames;
vector<int> uncompsize;
vector<int> compsize;
int getFileSize(string filepath);
public:
FileInfoContainer() {};
void AddItem(string filepath);
void AddItem(string filepath, int uncompsize, int compsize);
void AddItem(string filepath, int uncompsize);
string getItemFilename(int index);
int getItemCompsize(int index);
int getItemUncompsize(int index);
};
Now back to the automatic code generated by the VS template for this application, I tried to declare an instance of this class so that I can have the file information available anywhere within:
public ref class MainForm : public System::Windows::Forms::Form
{
public:
MainForm(void)
{
InitializeComponent();
}
protected:
~MainForm()
{
if (components)
{
delete components;
}
}
System::Windows::Forms::ListViewItem^ files; //my addition
FileInfoContainer compfiles; //my addition
private: System::Windows::Forms::OpenFileDialog^ openFileDialog1;
private: System::Windows::Forms::SaveFileDialog^ saveFileDialog1;
...........
}
This is generated code where I've only added those 2 lines, of which the first works normally while the second gives a member of managed class can't be non-managed class type error.
What can I do to go around this issue?

Related

Segmentation fault in header file

I have defined a Parent.h file, having Parent class with following data members:-
#pragma once
#include <string>
using namespace std;
class Person
{
private:
string id;
string name;
string email;
int contact_number;
string address;
public:
Person();
~Person();
void set_id(string);
void set_name(string);
void set_email(string);
void set_contact_number(int);
void set_address(string);
string get_id();
string get_name();
string get_email();
int get_contact_number();
string get_address();
};
Person::Person()
{
this->id = "";
this->name = "";
this->email = "";
this->contact_number = 0;
this->address = "";
}
void Person::set_id(string id)
{
this->id =id;
}
I have defined the rest of the functions(setters and getters) likewise in Parent.h file.
After that I am making a child class in Student.h header file, this Student class will publicly inherit the Parent class
#pragma once
#include"Courses.h" //course is aggregating to a student
#include"AcademicRecord.h"
#include "Person.h"
#include "Department.h"
#include<string>
#include<vector>
using namespace std;
class Student:public Person,public AcademicRecord,public Department
{
private:
string institute_email;
public:
Courses A;//A contains all information about the courses a student has opt for.
Student();
~Student();
//Using polymorphism between methods
void ShowStudentAcademicRecord(); //shows the academic record of current student
void ShowStudentCoursesInfo(); //getting the information for all courses of student
//setter
void set_institute_email(string email);
void setDepartmentID(string);
//getter
string get_institute_email();
};
After that I have a Display.h file having vector of Students as its Data member and using a member function in Display, I am asking user to input data members like ID,Name,Address,... for individual students.
#include "Student.h"
using namespace std;
class Display
{
public:
vector<Student> students;
Display();//default constructor
//setter
void setStudentData();
};
void Display::setStudentData()
{
int size;
cout<<"Enter the number of students: ";
cin>>size;
Student *current; //current Student
for (int i = 0; i < size; i++)
{
current = &students[i];
cout<<"For student "<<i+1<<"\nEnter the following: \n";//For general details
cout<<"ID Name Email Contact_Number Address Institute_Email\n";
string ID,Name,EMail,Address,insti_email;
int contact_number;
cin>>ID>>Name>>EMail>>contact_number>>Address>>insti_email;
current->set_id(ID);
current->set_name(Name);
current->set_email(EMail);
current->set_contact_number(contact_number);
current->set_address(Address);
current->set_institute_email(insti_email);
}
And when I try inserting value insides students by executing main.cpp file.
I get segmentation fault at run-time inside Person class at setter function, where the first setter I have declared inside the class is void set_id(string).
#include "Display.h"
#include<vector>
#include<string>
int main()
{
Display display;
display.setStudentData();
}
Error:-
I tried:-
1.Rechecking the setter function for any error
2.Bring all the classes inside the main.cpp file,instead of header files, but still the error continues.
I expected the program to take the desired input for various data members of student elments of vector students inside Display class.
Instead I got a seg-fault.
Please if anyone can tell me what I have done wrong, or do I have to do malloc somewhere, inside a function?
As Nate Eldredge, has said I should use push_back instead of accessing ith element of students vector in setStudentData() function, as initially during default declaration of a Display class, the students vector is empty. Hence trying to access students[i] in current = &students[i], I am getting segmentation fault.
The appropriate code for Display.h should be then
#include "Student.h"
using namespace std;
class Display
{
public:
vector<Student> students;
Display();//default constructor
//setter
void setStudentData();
};
void Display::setStudentData()
{
int size;
cout<<"Enter the number of students: ";
cin>>size;
total_students += size;
Student *temp =new Student(); //temp Student
for (int i = 0; i < size; i++)
{
cout<<"For student "<<i+1<<"\nEnter the following: \n";//For general details
cout<<"ID Name Email Contact_Number Address Faculty_Type Faculty_Description\n";
string ID,Name,EMail,Address,insti_email;
int contact_number;
cin>>ID>>Name>>EMail>>contact_number>>Address>>insti_email;
temp->set_id(ID);
temp->set_name(Name);
temp->set_email(EMail);
temp->set_contact_number(contact_number);
temp->set_address(Address);
temp->set_institute_email(insti_email);
cout<<"Enter the Course Details: \n";//For Course Details
int size_course;
cout<<"Enter the number of courses: ";
cin>>size_course;
cout<<"Enter the following for each course: \n";
cout<<"Course_Name Marks Attendance Percentage \n";
string name;
int marks;
float attendance;
for (int i = 0; i < size_course; i++)
{
cin>>name>>marks>>attendance;
temp->A.set_courses_enrolled(name);
temp->A.set_course_wise_marks(marks);
temp->A.set_coursewise_attendance_percentage(attendance);
}
cout<<"Enter the Academic Record Details: \n";//For Academic Record Details
string program_name; int admission_no, enroll_no, begin_year, end_year, credits; float CGPA;
cout<<"Enter Program_name, admission_no enroll_no begin_year end_year credits CGPA";
cin>>program_name>>admission_no>>enroll_no>>begin_year>>end_year>>credits>>CGPA;
setStudentAcademicRecord(temp,i,program_name,admission_no,enroll_no,begin_year,end_year,credits,CGPA); //passing temp pointer in this one
students.push_back(*temp); //adding a new student in students vector
}

c++/cli unmanaged library into managed code

I have the following code in c++/cli
`
public ref class Form1 : public System::Windows::Forms::Form
{
public:
Form1(void)
{
InitializeComponent();
//
//TODO: Konstruktorcode hier hinzufügen.
//
delegate int fooProc(UInt16);
}
...
public: void goTest(int x) { // declared in header
fooProc^ managed = gcnew fooProc(this, &Form1::foo);
IntPtr stubPointer = Marshal::GetFunctionPointerForDelegate(managed);
slave[x].module = static_cast<int(*)(unsigned short)>(stubPointer.ToPointer());
...
}
}
public: int foo(unsigned short test) {
Form1::label1->Text = "Hello success !";
...
return 1; // seems to not return to library function ( Run-Time Check Failure #0 - The value of ESP was not properly saved ...)
}
`
then in a static library with native code there is a function which calls the method 'foo' thru the pointer slave[x].module
as following:
int nativefoo(...) {
...
anyStruct[x].module(x); // struct defined in header
...
return 0;
}
The code crashes in method on return. Probably mismatch in calling conventions.
I have no idea how to solve this issue.
I only tried to alter and match the calling conventions. From __clrcall to __cdecl but no affect.

How to move a window between desktops using powershell/.net on windows 10 [duplicate]

I love that Windows 10 now has support for virtual desktops built in, but I have some features that I'd like to add/modify (e.g., force a window to appear on all desktops, launch the task view with a hotkey, have per-monitor desktops, etc.)
I have searched for applications and developer references to help me customize my desktops, but I have had no luck.
Where should I start? I am looking for Windows API functions (ideally, that are callable from a C# application) that will give me programmatic access to manipulate virtual desktops and the windows therein.
The Windows SDK Support Team Blog posted a C# demo to switch Desktops via IVirtualDesktopManager:
[ComImport, InterfaceType(ComInterfaceType.InterfaceIsIUnknown), Guid("a5cd92ff-29be-454c-8d04-d82879fb3f1b")]
[System.Security.SuppressUnmanagedCodeSecurity]
public interface IVirtualDesktopManager
{
[PreserveSig]
int IsWindowOnCurrentVirtualDesktop(
[In] IntPtr TopLevelWindow,
[Out] out int OnCurrentDesktop
);
[PreserveSig]
int GetWindowDesktopId(
[In] IntPtr TopLevelWindow,
[Out] out Guid CurrentDesktop
);
[PreserveSig]
int MoveWindowToDesktop(
[In] IntPtr TopLevelWindow,
[MarshalAs(UnmanagedType.LPStruct)]
[In]Guid CurrentDesktop
);
}
[ComImport, Guid("aa509086-5ca9-4c25-8f95-589d3c07b48a")]
public class CVirtualDesktopManager
{
}
public class VirtualDesktopManager
{
public VirtualDesktopManager()
{
cmanager = new CVirtualDesktopManager();
manager = (IVirtualDesktopManager)cmanager;
}
~VirtualDesktopManager()
{
manager = null;
cmanager = null;
}
private CVirtualDesktopManager cmanager = null;
private IVirtualDesktopManager manager;
public bool IsWindowOnCurrentVirtualDesktop(IntPtr TopLevelWindow)
{
int result;
int hr;
if ((hr = manager.IsWindowOnCurrentVirtualDesktop(TopLevelWindow, out result)) != 0)
{
Marshal.ThrowExceptionForHR(hr);
}
return result != 0;
}
public Guid GetWindowDesktopId(IntPtr TopLevelWindow)
{
Guid result;
int hr;
if ((hr = manager.GetWindowDesktopId(TopLevelWindow, out result)) != 0)
{
Marshal.ThrowExceptionForHR(hr);
}
return result;
}
public void MoveWindowToDesktop(IntPtr TopLevelWindow, Guid CurrentDesktop)
{
int hr;
if ((hr = manager.MoveWindowToDesktop(TopLevelWindow, CurrentDesktop)) != 0)
{
Marshal.ThrowExceptionForHR(hr);
}
}
}
it includes the API to detect on which desktop the Window is shown and it can switch and move a Windows the a Desktop.
Programmatic access to the virtual desktop feature is very limited, as Microsoft has only exposed the IVirtualDesktopManager COM interface. It does provide two key functions:
IVirtualDesktopManager::GetWindowDesktopId allows you to retrieve the ID of a virtual desktop, based on a window that is already assigned to that desktop.
IVirtualDesktopManager::MoveWindowToDesktop allows you to move a window to a specific virtual desktop.
Unfortunately, this is not nearly enough to accomplish anything useful. I've written some C# code based on the reverse-engineering work done by NickoTin. I can't read much of the Russian in his blog post, but his C++ code was pretty accurate.
I do need to emphasize that this code is not something you want to commit to in a product. Microsoft always feels free to change undocumented APIs whenever they feel like it. And there is a runtime risk as well: this code does not necessarily interact well when the user is tinkering with the virtual desktops. Always keep in mind that a virtual desktop can appear and disappear at any time, completely out of sync with your code.
To use the code, create a new C# class library project. I'll first post ComInterop.cs, it contains the COM interface declarations that match NickoTin's C++ declarations:
using System;
using System.Runtime.InteropServices;
namespace Windows10Interop {
internal static class Guids {
public static readonly Guid CLSID_ImmersiveShell =
new Guid(0xC2F03A33, 0x21F5, 0x47FA, 0xB4, 0xBB, 0x15, 0x63, 0x62, 0xA2, 0xF2, 0x39);
public static readonly Guid CLSID_VirtualDesktopManagerInternal =
new Guid(0xC5E0CDCA, 0x7B6E, 0x41B2, 0x9F, 0xC4, 0xD9, 0x39, 0x75, 0xCC, 0x46, 0x7B);
public static readonly Guid CLSID_VirtualDesktopManager =
new Guid("AA509086-5CA9-4C25-8F95-589D3C07B48A");
public static readonly Guid IID_IVirtualDesktopManagerInternal =
new Guid("AF8DA486-95BB-4460-B3B7-6E7A6B2962B5");
public static readonly Guid IID_IVirtualDesktop =
new Guid("FF72FFDD-BE7E-43FC-9C03-AD81681E88E4");
}
[ComImport]
[InterfaceType(ComInterfaceType.InterfaceIsIUnknown)]
[Guid("FF72FFDD-BE7E-43FC-9C03-AD81681E88E4")]
internal interface IVirtualDesktop {
void notimpl1(); // void IsViewVisible(IApplicationView view, out int visible);
Guid GetId();
}
[ComImport]
[InterfaceType(ComInterfaceType.InterfaceIsIUnknown)]
[Guid("AF8DA486-95BB-4460-B3B7-6E7A6B2962B5")]
internal interface IVirtualDesktopManagerInternal {
int GetCount();
void notimpl1(); // void MoveViewToDesktop(IApplicationView view, IVirtualDesktop desktop);
void notimpl2(); // void CanViewMoveDesktops(IApplicationView view, out int itcan);
IVirtualDesktop GetCurrentDesktop();
void GetDesktops(out IObjectArray desktops);
[PreserveSig]
int GetAdjacentDesktop(IVirtualDesktop from, int direction, out IVirtualDesktop desktop);
void SwitchDesktop(IVirtualDesktop desktop);
IVirtualDesktop CreateDesktop();
void RemoveDesktop(IVirtualDesktop desktop, IVirtualDesktop fallback);
IVirtualDesktop FindDesktop(ref Guid desktopid);
}
[ComImport]
[InterfaceType(ComInterfaceType.InterfaceIsIUnknown)]
[Guid("a5cd92ff-29be-454c-8d04-d82879fb3f1b")]
internal interface IVirtualDesktopManager {
int IsWindowOnCurrentVirtualDesktop(IntPtr topLevelWindow);
Guid GetWindowDesktopId(IntPtr topLevelWindow);
void MoveWindowToDesktop(IntPtr topLevelWindow, ref Guid desktopId);
}
[ComImport]
[InterfaceType(ComInterfaceType.InterfaceIsIUnknown)]
[Guid("92CA9DCD-5622-4bba-A805-5E9F541BD8C9")]
internal interface IObjectArray {
void GetCount(out int count);
void GetAt(int index, ref Guid iid, [MarshalAs(UnmanagedType.Interface)]out object obj);
}
[ComImport]
[InterfaceType(ComInterfaceType.InterfaceIsIUnknown)]
[Guid("6D5140C1-7436-11CE-8034-00AA006009FA")]
internal interface IServiceProvider10 {
[return: MarshalAs(UnmanagedType.IUnknown)]
object QueryService(ref Guid service, ref Guid riid);
}
}
Next is Desktop.cs. It contains the friendly C# classes that you can use in your code:
using System;
using System.Runtime.InteropServices;
namespace Windows10Interop
{
public class Desktop {
public static int Count {
// Returns the number of desktops
get { return DesktopManager.Manager.GetCount(); }
}
public static Desktop Current {
// Returns current desktop
get { return new Desktop(DesktopManager.Manager.GetCurrentDesktop()); }
}
public static Desktop FromIndex(int index) {
// Create desktop object from index 0..Count-1
return new Desktop(DesktopManager.GetDesktop(index));
}
public static Desktop FromWindow(IntPtr hWnd) {
// Creates desktop object on which window <hWnd> is displayed
Guid id = DesktopManager.WManager.GetWindowDesktopId(hWnd);
return new Desktop(DesktopManager.Manager.FindDesktop(ref id));
}
public static Desktop Create() {
// Create a new desktop
return new Desktop(DesktopManager.Manager.CreateDesktop());
}
public void Remove(Desktop fallback = null) {
// Destroy desktop and switch to <fallback>
var back = fallback == null ? DesktopManager.GetDesktop(0) : fallback.itf;
DesktopManager.Manager.RemoveDesktop(itf, back);
}
public bool IsVisible {
// Returns <true> if this desktop is the current displayed one
get { return object.ReferenceEquals(itf, DesktopManager.Manager.GetCurrentDesktop()); }
}
public void MakeVisible() {
// Make this desktop visible
DesktopManager.Manager.SwitchDesktop(itf);
}
public Desktop Left {
// Returns desktop at the left of this one, null if none
get {
IVirtualDesktop desktop;
int hr = DesktopManager.Manager.GetAdjacentDesktop(itf, 3, out desktop);
if (hr == 0) return new Desktop(desktop);
else return null;
}
}
public Desktop Right {
// Returns desktop at the right of this one, null if none
get {
IVirtualDesktop desktop;
int hr = DesktopManager.Manager.GetAdjacentDesktop(itf, 4, out desktop);
if (hr == 0) return new Desktop(desktop);
else return null;
}
}
public void MoveWindow(IntPtr handle) {
// Move window <handle> to this desktop
DesktopManager.WManager.MoveWindowToDesktop(handle, itf.GetId());
}
public bool HasWindow(IntPtr handle) {
// Returns true if window <handle> is on this desktop
return itf.GetId() == DesktopManager.WManager.GetWindowDesktopId(handle);
}
public override int GetHashCode() {
return itf.GetHashCode();
}
public override bool Equals(object obj) {
var desk = obj as Desktop;
return desk != null && object.ReferenceEquals(this.itf, desk.itf);
}
private IVirtualDesktop itf;
private Desktop(IVirtualDesktop itf) { this.itf = itf; }
}
internal static class DesktopManager {
static DesktopManager() {
var shell = (IServiceProvider10)Activator.CreateInstance(Type.GetTypeFromCLSID(Guids.CLSID_ImmersiveShell));
Manager = (IVirtualDesktopManagerInternal)shell.QueryService(Guids.CLSID_VirtualDesktopManagerInternal, Guids.IID_IVirtualDesktopManagerInternal);
WManager = (IVirtualDesktopManager)Activator.CreateInstance(Type.GetTypeFromCLSID(Guids.CLSID_VirtualDesktopManager));
}
internal static IVirtualDesktop GetDesktop(int index) {
int count = Manager.GetCount();
if (index < 0 || index >= count) throw new ArgumentOutOfRangeException("index");
IObjectArray desktops;
Manager.GetDesktops(out desktops);
object objdesk;
desktops.GetAt(index, Guids.IID_IVirtualDesktop, out objdesk);
Marshal.ReleaseComObject(desktops);
return (IVirtualDesktop)objdesk;
}
internal static IVirtualDesktopManagerInternal Manager;
internal static IVirtualDesktopManager WManager;
}
}
And finally a little test WinForms project that I used to test the code. Just drop 4 buttons on a form and name them buttonLeft/Right/Create/Destroy:
using Windows10Interop;
using System.Diagnostics;
...
public partial class Form1 : Form {
public Form1() {
InitializeComponent();
}
private void buttonRight_Click(object sender, EventArgs e) {
var curr = Desktop.FromWindow(this.Handle);
Debug.Assert(curr.Equals(Desktop.Current));
var right = curr.Right;
if (right == null) right = Desktop.FromIndex(0);
if (right != null) {
right.MoveWindow(this.Handle);
right.MakeVisible();
this.BringToFront();
Debug.Assert(right.IsVisible);
}
}
private void buttonLeft_Click(object sender, EventArgs e) {
var curr = Desktop.FromWindow(this.Handle);
Debug.Assert(curr.Equals(Desktop.Current));
var left = curr.Left;
if (left == null) left = Desktop.FromIndex(Desktop.Count - 1);
if (left != null) {
left.MoveWindow(this.Handle);
left.MakeVisible();
this.BringToFront();
Debug.Assert(left.IsVisible);
}
}
private void buttonCreate_Click(object sender, EventArgs e) {
var desk = Desktop.Create();
desk.MoveWindow(this.Handle);
desk.MakeVisible();
Debug.Assert(desk.IsVisible);
Debug.Assert(desk.Equals(Desktop.Current));
}
private void buttonDestroy_Click(object sender, EventArgs e) {
var curr = Desktop.FromWindow(this.Handle);
var next = curr.Left;
if (next == null) next = curr.Right;
if (next != null && next != curr) {
next.MoveWindow(this.Handle);
curr.Remove(next);
Debug.Assert(next.IsVisible);
}
}
}
The only real quirk I noticed while testing this is that moving a window from one desktop to another can move it to the bottom of the Z-order when you first switch the desktop, then move the window. No such problem if you do it the other way around.
There is this guy that made a application to map keyboard shorcut to move a window between virtual desktop.
https://github.com/Grabacr07/SylphyHorn
(I use it every day )
He has a blog where he explain what he did
http://grabacr.net/archives/5701 ( you can use google translate it is in japanese)
He in fact used the same api mantionned in the Alberto Tostado response.
http://www.cyberforum.ru/blogs/105416/blog3671.html
and the api can be found on his github https://github.com/Grabacr07/VirtualDesktop
The api is really simple to use BUT it seems impossible to move a window from another process.
public static bool MoveToDesktop(IntPtr hWnd, VirtualDesktop virtualDesktop)
{
ThrowIfNotSupported();
int processId;
NativeMethods.GetWindowThreadProcessId(hWnd, out processId);
if (Process.GetCurrentProcess().Id == processId) // THAT LINE
{
var guid = virtualDesktop.Id;
VirtualDesktop.ComManager.MoveWindowToDesktop(hWnd, ref guid);
return true;
}
return false;
}
To workaround this problem they made another implementation that they use alongside the one in the russian blog
if (VirtualDesktopHelper.MoveToDesktop(hWnd, right) //<- the one in the russian blog
|| this.helper.MoveWindowToDesktop(hWnd, right.Id)) <- the second implementation
The second implementation can be found here: https://github.com/tmyt/VDMHelper
This one can move a window from another process to another desktop. BUT it is buggy right now. For exemple when i try to move some window like google chrome it crash.
So this is the result of my research. I m rigth now trying to make a StickyWindow feature with these api.
I fear that all about "Virtual desktops" in Windows 10 is undocumented, but in a Russian page I've seen documented the interfaces. I don't speak Russian but seems that they have used reversed engineering. Anyway, the code is very clear (Thanks to them!).
Keep an eye here:
http://www.cyberforum.ru/blogs/105416/blog3671.html
I've been trying to see if the old API's CreateDesktop, OpenDesktop, etc... is linked to the new Virtual-Desktops, but no way...
The interfaces work with the final production release of Windows 10 (2015-05-08), but you shouldn't use them in a real wide distributed application until Microsoft documents them. Too much risk.
Regards.

Need help to get variable in mfc dialog class

please, I've spent all day trying to figure this out but can't. I have a class (artist1) created from a dialog box with some edit boxes. I want to get the data typed in the edit boxes and save them to variables i made public in the class. But don't know why it doesn't work. PS am new to mfc programming. Thanks
here is my artist class
void artist1::OnBnClickedButton1()
{
//artist1 AA=*art1;
CEdit* pEdit1 = (CEdit*)GetDlgItem(IDC_EDIT1);
pEdit1->GetWindowText(Name1);
nn=new CString;
*nn=Name1;
CEdit* pEdit2 = (CEdit*)GetDlgItem(IDC_EDIT2);
pEdit2->GetWindowText(Age1);
n2=new CString;
*n2=Age1;
CEdit* pEdit3 = (CEdit*)GetDlgItem(IDC_EDIT3);
pEdit3->GetWindowText(Nationality1);
n3=new CString;
*n3=Nationality1;
CEdit* pEdit4 = (CEdit*)GetDlgItem(IDC_EDIT4);
pEdit4->GetWindowText(Group1);
n4=new CString;
*n4=Group1;
CEdit* pEdit5 = (CEdit*)GetDlgItem(IDC_EDIT5);
pEdit5->GetWindowText(num_of_albums1);
n5=new CString;
*n5=num_of_albums1;
SH(Name1,Age1,Nationality1,Group1,num_of_albums1);
art1=this;
// memcpy(art1,this,sizeof(this));
//Name_box.SetWindowText(g);
//AfxMessageBox( Age );
//AfxMessageBox( Nationality );
// TODO: Add your control notification handler code here
}
/*bool artist1::SH()
{
if(NoShow==false)return true;
else return false;
}*/
void artist1::OnBnClickedButton2()
{
//Cooplab1View vm;
NoShow=false;
nvalidateRect(NULL,NULL);
EndDialog(IDD_FORMVIEW);
// TODO: Add your control notification handler code here
}
and here is the class artist header
class artist1 : public CDialogEx
{
//DECLARE_DYNAMIC(artist1)
public:
artist1(CWnd* pParent = NULL); // standard constructor
virtual ~artist1();
bool NoShow;
bool *address;
CString Albums[5];
void OnInsertArtist(artist1 &at);
// Dialog Data
enum { IDD = IDD_FORMVIEW };
private:
CString Nm;
CString Ag;
CString Nation;
CString group;
CString No_of_A;
CString *nnn;
public:
// artist1* GetTreeObj();
//virtual CString ShowDetails(CDC* pDC);
void SH(CString a,CString b,CString c,CString d,CString e)
{
Name=a;
Age=b;
Nationality=c;
Group=d;
num_of_albums=e;
}
protected:
CString Name,Age,Nationality,Group,num_of_albums;
virtual void DoDataExchange(CDataExchange* pDX); // DDX/DDV support
CString Name1,Age1,Nationality1,Group1,num_of_albums1;
DECLARE_MESSAGE_MAP()
public:
afx_msg void OnBnClickedButton1();
virtual CString ShowDetails(CDC* pDC,artist1 & at1);
afx_msg void OnBnClickedButton2();
};
and i call the class from the CView class cpp file
void Cooplab1View::OnDraw(CDC* pDC)
{
artist1 art;
artist1 A1;
Cooplab1Doc* pDoc = GetDocument();
//ASSERT_VALID(pDoc);
//if (!pDoc)
// return;
if (noShow)
{
art.OnInsertArtist(art);
//art.OnBnClickedButton1();
//art=&obj;
// art.GetTreeObj();
art.ShowDetails(pDC,art);
}
ASSERT_VALID(pDoc);
if (!pDoc)
return;
// TODO: add draw code for native data here
}
void Cooplab1View::OnInsertArtist1()
{
noShow=true;
InvalidateRect(NULL,NULL);
//UpdateWindow();
}
You should create variables (right click->Add variables in vs2010) matching your "edit boxes" and check their values.
Don't do "GetDlgItem" and not GetWindowText.
You should addUpdateData(TRUE) at the first line of OnBnClickedButton1
Good Luck !
Your class is quite messy, but if you just want to extract user entry text from the dialog items, it is actually quite simple.
void artist1::OnBnClickedButton1()
{
// Since variables Name,Age,Nationality,Group,num_of_albums are all CString items
// declare as member variables in the class,
// you can just retrieve user entry from the dialog directly into them
// without calling the "SH(Name1,Age1,Nationality1,Group1,num_of_albums1);"
GetDlgItemText(IDC_EDIT1, Name);
GetDlgItemText(IDC_EDIT2, Age);
GetDlgItemText(IDC_EDIT3, Nationality);
GetDlgItemText(IDC_EDIT4, Group);
GetDlgItemText(IDC_EDIT5, num_of_albums);
}
If you are entering a value to the edit control, you should call updatedata( FALSE ). If you want to store the value into a variable then call updatedata(TRUE). That's it.
I finally solved the problem. I declared some global variables, assigned the values inputted in the edit boxes to them in OnBnClickedButton1() using GetDlgItemText then in OnBnClickedButton2() i assigned the global variables to the variables in my class ie Name, Age etc.

unmanaged var as member of managed class c++

I'm novice in .net c++ and trying to create class looking like:
public ref class Klient
{
public:
Klient(){}
// zmienne
static DWORD klienty[41][2];
static int i = 1;
static DWORD* pid;
static HANDLE* handle;
//funkcje
};
but MSV says that:
error C4368: cannot define 'klienty' as a member of managed 'Klient': mixed types are not supported
What's wrong with this code?
You can have .NET basic data types as members of your managed class (static int i), or pointers to anything unmanaged (DWORD* pid, HANDLE* handle), but you're not allowed to have an unmanaged object directly, and the array of integers counts as an unmanaged object for this purpose.
Since the only item giving you a problem here is the unmanaged array, you could switch it to a managed array.
public ref class Klient
{
public:
Klient(){}
// zmienne
static array<DWORD,2>^ klienty = gcnew array<DWORD,2>(41,2);
static int i = 1;
static DWORD* pid;
static HANDLE* handle;
//funkcje
};
Or, you can declare a unmanaged class, put whatever you need to in there, and have a pointer to it from the managed class. (If you do this in a non-static context, don't forget to delete the unmanaged memory from your finalizer.)
public class HolderOfUnmanagedStuff
{
public:
DWORD klienty[41][2];
int i;
DWORD* pid;
HANDLE* handle;
HolderOfUnmanagedStuff()
{
i = 1;
}
};
public ref class Klient
{
public:
Klient(){}
// zmienne
static HolderOfUnmanagedStuff* unmanagedStuff = new HolderOfUnmanagedStuff();
//funkcje
};