Change edit mfc control text from another - c++

Hi I have two dialog form on C++ MFC 2010 and I want change edit control on from1 by form2 .
How I can done it ?

With all due respect, you should NOT directly access controls of one form from another. This creates unneeded tight coupling between them, exposing internals of one form to another.
I suggest you implement a public setter that identifies the purpose rather than the control ID that might change without you knowing it.
In the target form:
public:
void SetUserName(const char* name)
{
SetDlgItemText(IDC_EDIT1, name);
}
And in the caller:
form1.SetUserName("new text");

You use SetDlgItemText.
form1.SetDlgItemText(IDC_EDIT1, "new text");

Related

Accessing document files from dialog class in mfc, sdi

I am new to mfc, so I don't know if I will explain my problem correctly but I'll try.
So I built a puzzle game in mfc, and I want to implement high score system. When the game is over, the dialog pops up, where you put your name, and name is written in the external txt file. So, I have Dialog class, where I implement stuff about putting in your name, and sending it to a txt file, but the problem is that I can't access the info about the score, which is stored in the ProjectDoc class, so I can't link the name of the player and the score.
So the question is how to access files from ProjectDoc class from dialog class.
The solution offered by IInspectable and thomiel works great if you have one (or a few) parameter.
Another extreme would be to pass a pointer to the Document and let the Dialog pull whatever it needs out of it, but that would violate "need to know" policy.
I would suggest to define an interface (abstract class) IHighScoreProvider with required accessors, for example:
class IHighScoreProvider
{
public:
virtual int GetGameScore() = 0;
virtual std::string GetPlayerName() = 0;
};
Then derive your Document from it and implement those methods. And pass that interface pointer to your dialog.
Submit the score as parameter in the constructor of you dialog class:
CHighscoreDlg::CHighscoreDlg(int score)
{
m_score = score; // store in private class member variable
}
...
...
void CPuzzleView::EndGame()
{
CHighscoreDlg hs(GetDocument()->m_gamescore);
hs.DoModal();
}

Clean OOP design when making a GUI

Say I have two main classes, Application and ApplicationGUI. Application does lots of things and can happily run without any knowledge that ApplicationGUI exists. ApplicationGUI is linked to Application in many ways, it has maybe 50 or 100 different knobs that can change Application's behavior.
ApplicationGUI is a hierarchical structure such that it has many instances of ControlGroup, each containing an arbitrary number of Buttons and Knobs, or even another ControlGroup.
Current design: Upon instantiation of the ApplicationGUI (Application was already running with some set of default parameters), I pass pointers of Application's parameters to various components of the GUI. For example:
my_gui.sound_controlgroup.knob.link_to_param(&(my_application.volume));
If I need to do something more complex, say call a member function of Application, my_application.update_something(), how is this done?
The easy answer is to pass a pointer to my_application to my_gui.sound_controlgroup.knob, but if I only ever need to call one of my_application's functions, it seems like I am giving my knob an option to change all kinds of things that it should even know about (my_application.update_something_unrelated(), for instance). What is the cleanest thing to do in this case?
Additionally, this either requires making all subcomponents of ApplicationGUI public or having a function at each stage of the hierarchy to forward that pointer to the bottom level. This leads to quite a lot of functions. Is this a necessary consequence of a UI with a lot of knobs?
Quick Short Answer
In order to implement interaction between your non GUI related Application object and your GUIApplication object I suggest apply the "Property and Method and Event Handler" paradigm.
Extended Complex Answer
G.U.I. development is one of the most practical implementation of the O.O.P. theory.
What is the "Property and Method and Event Handler" paradigm ?
That means build, both Non GUI Classes, and GUI Classes, should have:
Properties
Methods
Event handlers
"Events" (Handlers) are also called "Signals", and are implemented with functions pointers. Not sure, but, I think your "knob" (s) are like Event Handlers.
It's a technique to apply the my_application.update_something_unrelated(), you have in your question.
Since, C++, like Java, does not have property syntax, you may use "getter" and "setter" methods, or use a "property" template.
For example, if your application has a Close method, you may declare something like the following examples.
Note: They are not full programs, just an idea:
// Applications.hpp
public class BaseApplicationClass
{
// ...
};
public class BaseApplicationClientClass
{
// ...
};
typedef
void (BaseApplicationClientClass::*CloseFunctor)
(BaseApplicationClass App);
public class ApplicationClass: public BaseApplicationClass
{
// ...
public:
Vector<BaseApplicationClientClass::CloseFunctor>
BeforeCloseEventHandlers;
Vector<BaseApplicationClientClass::CloseFunctor>
AfterCloseEventHandlers;
protected:
void ConfirmedClose();
public:
virtual void Close();
} Application;
// Applications.cpp
void ApplicationClass::ConfirmedClose()
{
// do close app. without releasing from memory yet.
} // void ApplicationClass::ConfirmedClose()
void ApplicationClass::Close()
{
// Execute all handlers in "BeforeCloseEventaHandlers"
this.ConfirmedClose();
// Execute all handlers in "AfterCloseEventaHandlers"
} // void ApplicationClass::Close()
// AppShells.cpp
public class AppShell: public BaseApplicationClientClass
{
// ...
};
void AppShell::CloseHandler(ApplicationClass App)
{
// close GUI
} // void AppShell.CloseHandler(ApplicationClass App)
void AppShell::setApp(ApplicationClass App)
{
App->BeforeCloseEventHandlers->add(&this.CloseHandler);
} // void AppShell.setApp(ApplicationClass App)
void main (...)
{
ApplicationClass* AppKernel = new ApplicationClass();
ApplicationGUIClass* AppShell = new ApplicationGUIClass();
AppShell.setApp(App);
// this executes "App->Run();"
AppShell->Run();
free AppShell();
free AppKernel();
}
UPDATE: Fixed type declaration from global function pointer (a.k.a. "global functor") to object function pointer (a.k.a. "method functor").
Cheers.
Do you know about the model-view-controller (MVC) paradigm? Think of the Application class as the model, the entire hierarchy of GUI controls as the view, and the ApplicationGUI class as the controller. You don't want Application to know about the controls, and you don't want the controls to know about Application; they should both talk only to the controller, ApplicationGUI.
Using ApplicationGUI as the conduit for communication between controls and Application means that you can test either Application or controls by replacing the other with a mock object, for example. More importantly, you can change either the controls or Application without impacting the other. Individual controls don't need to know anything about Application -- they only need to know where to send their value when it changes. And Application shouldn't care whether an input comes from a knob or a slider or a text field. Keeping those two areas separate will simplify each of them.
Additionally, this either requires making all subcomponents of
ApplicationGUI public or having a function at each stage of the
hierarchy to forward that pointer to the bottom level. This leads to
quite a lot of functions. Is this a necessary consequence of a UI with
a lot of knobs?
A given control shouldn't care what value it manages. It doesn't need to know whether the value determines the number of alien invaders on the screen or the coolant level in a nuclear reactor. It does needs to know things like the minimum and maximum values, label to display, scale to use (linear, log, etc.), and other things that directly impact the way the control works. It also needs to know who to tell when something changes, and it might need some way to identify itself.
With that in mind, ApplicationGUI doesn't need to expose accessors for every possible parameter of Application. Instead, it should have a general method that lets controls send it updates. When a control changes, it should send a message to ApplicationGUI containing the new value(s) along with its identifier, and ApplicationGUI takes care of mapping that identifier to some particular parameter of Application. A control's identifier could be some identifying number that's given to it, or it could just be a pointer to the control.
Of course, sometimes communication has to go the other way, too... a GUI usually has both inputs and outputs, so you'll want some means for ApplicationGUI to get updates from Application and update the state of the GUI. For the same reasons described above, Application should send those updates to ApplicationGUI and let the latter find the actual UI components that need to be changed.

Qt C++; How to address a certain textfield, depending on user input

I'm having issues with formulating the question but this is what I want to do with my application.
A user can select one or multiple image-files (.ppm), and they are displayed in some sort of legend, with their filename underneath. The information of these images is stored in a structure. (This structure contains the image path, name, and other info).
Now I want to give the user the chance to change the name of the selected images, and uses this name in the rest of the application. So I would have to change the name in the structure.
I could do this by adding textfields in the legend, where users can type the desired name, but how can I get the input from this textfield if I don't know which one is alterred?
If the user selects 6 images, I need 6 new textfields in the legend, but how can I address the correct one?
struct[2].name = input2.getText();
I also thought about doing it with some sort of wizard, with 6 pages where the names can be changed, but I don't know how I can adress the correct textfield.
Any help would be welcome, thanks!!
If you want to allow users to rename multiple files at one time, you may want to create a wizard. In the wizard you could display each picture they selected (one at a time) and allow them to rename each picture (one at a time). Otherwise it will be confusing to the user and harder for you to manage.
When generating the wizard, I would use the information structure to associate the picture with the textfield.
Qt, signals and slots are your friend here.
When you setup the textfields for the name, assuming you use something like a QLineEdit object, connect to a relevant signal, such as editingFinished(). Make the connection to the slot of the Object that stores the structure. The receiving slot then updates the appropriate information.
So, assuming your struct is in an object derived from QObject, you can do something like this: -
struct DataStruct // the struct storing the underlying data
{
QString name;
QLineEdit* linkedEditWidget; // widget for user to change text
};
class MainObject : public QObject
{
Q_OBJECT // required for signals and slots
public slots:
void UpdateText();
private:
const int NUM_STRUCTS = 10; // initialisation in C++ 11
DataStruct myStructs[NUM_STRUCTS]; // a number of structs
};
When you initialize the array of structs and the LineEdit widgets, store a pointer to the matching LineEdit widget in each myStruct and connect the widgets' editingFinished signals to the MainObject updateText() slot. It would be a good idea to use weak smart pointers here, but I'll use a standard pointer, to keep things simple.
When you receive notification that the text has changed, you'll need to match up the caller with the LineEdit* in the struct. Note that QObject::sender() will return the pointer to the object that sent the message: -
void MainObject::UpdateText()
{
QObject* theSendingWidget = sender();
for(int i=0; i<NUM_STRUCTS; ++i) // assuming NUM_STRUCTS is already defined
{
if(myStructs[i].linkedEditWidget == theSendingWidget)
{
// update the name in the data struct
myStructs[i].name = (static_cast<QLineEdit*>(theSendingWidget))->text();
return; // our work is done.
}
}
}
Finally, you'd probably make life easier for yourself by storing the data in Qt model objects, rather than using a plain struct. I suggest reading up on Model / View programming and the MVC design pattern

In iOS how do I change the text of a button, from a class other than viewController?

I would like to change the text of my UIBarButtonItem from another class (objective-C++) that I use in my project.
I have an IBOutlet myButton setup in myViewController and I can successfully do something like:
[ myButton setTitle:#"newTitle" ];
in myViewController.mm
Now I would like to do the same but from myCppClass that I use in my project.
Is there a way for myCppClass to access myViewController's myButton?
Shall I use some type of delegation mechanism?
I am pretty new to Ios and objective-C.
Thanks,
Baba
Create a method within your myViewController class to change the button title, then call that method from myCppClass by following the instructions described in this answer:
How to call method from one class in another (iOS)
https://stackoverflow.com/a/9731162/2274694
The short answer is, don't. You should treat a view controller's views as private. Instead, add a method to your VC like changeButtonTitle. Then call that method from from your other class.
The answers above are correct, but from your comments I suspect you aren't yet happy.
If you are super lazy, and you don't mind the string being the same in all instances of the VC (which in practice is usually the case) you could simply write a getter and setter for the string name as a class variable in the destination class. That way you don't even need access to the actual instance of the class, just its name. Tacky but super easy.
As others have pointed out, don't try and modify the buttons on a different VC directly. Pass a message and have the owning VC do it when it loads.
Well, passing messages forwards (to a new VC) is very easy. At the bottom of every VC class code there is #pragma navigation section commented out which gives you a handle to the destination VC. Cast it to the proper type and you set properties in the destination VC instance. In your case, create a public property NSString which holds the button text in your destination VC, and set it in your navigation section. This could be any class, or even a delegate, but a simple string should work.
Passing messages backwards (to previous VCs) can work the same way but it starts to get messy. You can programatically step back through the stack of VCs to find a particular (instance of) a VC. One of the answers to Get to UIViewController from UIView? gives sample code for stepping back through view controllers.
But if its simply forward communication, passing messages or information through
(void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender
at the bottom of the VC code and the commented out lines below is very easy and safe.

How to implement UserControl in WinRT

I have created a simple UserControl consisting solely of a Grid and an embraced Image.
Now I want to apply events such as "ManipulationDeltaEvent", etc. for touch-control. When I assign an event-handler like
pic->ActionToken = pic->ManipulationDelta +=
ref new ManipulationDeltaEventHandler(this, &MainPage::SwipeImageEventHandler);
pic->CompletedToken = pic->ManipulationCompleted +=
ref new ManipulationCompletedEventHandler(this, &MainPage::ImageManipulationCompletedEventHandler);
I receive valid EventRegistrationTokens, but when I want to swipe over the control, simply nothing happens (I debugged).
I read about overriding the OnManipulationDelta-method from Windows::UI::Xaml::Controls::Control, but I here I am stuck:
protected:
void OnManipulationDelta
(Windows::UI::Xaml::Input::ManipulationDeltaRoutedEventArgs^ e) override {
}
Although only barely related, for C++\CLI it states on MSDN:
The OnManipulationDelta method has no default implementation. Override OnManipulationDelta in a derived class to handle the ManipulationDelta event. Be sure to call the OnManipulationDelta method of the base class so that base classes receive the event.
Please give me a hint, thank you.
EDIT
The overriding is unnecessary
You need to specify ManipulationMode on the control and the control needs a non-null Background or Fill, e.g. Background="Transparent".