I have created the following MFC program :
CMyClass is the class, it has one CString member called "m" and one method called "MyFunc". I would like to pass the current class as argument for my method.
In the header file:
public:
CString m;
void MyFunc(CMyClass CM)
In the cpp file:
//Button event
void CMyClass::OnBnClicked()
{
m = _T("");
MyFunc(this);
//MessageBox displaying the updated "m" member
MessageBox(m,_T(""),MB_ICONINFORMATION);
}
//Method updating the member m
void MyFunc(CMyClass CM)
{
CM.m = _T("TEST");
}
The button click function updates the member "m" of the class and display the new "m" value but it does not change.
I would like to know why the argument "this" has not been properly passed. Is something wrong with my code ?
Related
As you can see by my code, I'm trying to create a onClick event for a button that invoke a function from another class (I'm trying to make my custom button class instead of using win32 default ones for testing).
But even if this does not throw any error, it just doesn't invoke the given method.
This is the function signature inside Button.hpp
void onClick(POINT pt, void (ButtonsHandler::*clicked)(void));
This is the implementation inside Button.cpp (Using clicked() throws C++ expression preceding parentheses of apparent call must have pointer-to function type)
void Button::onClick(POINT pt, void (ButtonsHandler::*clicked)(void))
{
if (PtInRect(&textRect, pt) != 0)
{
clicked;
}
}
And this is where I actually call it
mainMenu.getPlay().onClick(pt, &ButtonsHandler::onPlay);
EDIT: solved thank you guys
I was just not creating a ButtonsHandler object to execute the non-static function
Here's the correct code I was missing.
void Button::onClick(POINT pt, void (ButtonsHandler::*clicked)(void)) {
if (PtInRect(&textRect, pt) != 0) {
ButtonsHandler bh;
(bh.*clicked)();
}
}
It just doesn't invoke the given method!
The passed pointer to member function has to be called to get in effect.
I assume that the Button is inherited from the ButtonsHandler. Then, for instance, you can call with the pointer to member function with this pointer as follows:
void Button::onClick(POINT pt, void (ButtonsHandler::*clicked)(void))
{
if (PtInRect(&textRect, pt) != 0) {
(this->*clicked)();
//^^^^^^^^^^^^^^^^^^
// or
// std::invoke(clicked, this) // need to include <functional> header(Since C++17)
}
}
If both classes are unrelated, you required an instance of ButtonsHandler to call the member function. For example:
ButtonsHandler obj;
(obj.*clicked)();
// or
// std::invoke(clicked, obj) // need to include <functional> header
Just wondering...how can I access the variable 'path' of ClassA function Open() from within another fucntion of class ClassB if both classes are declared 'friends'? I'm basically trying to populate a child window with info from the parent window when the child window is selected, although both windows have different classes.
ClassA.cpp:
void ClassA::Open()
{
// Open Program Properties window
ClassB dlg;
dlg.DoModal();
CString path;
path = m_DirTree.GetCurrentDir(); //Path specified by tree selection
}
ClassB.cpp:
void ClassB::Display(){
//HOW CAN I ACCESS 'path' HERE?
SetDlgItemText(IDC_PATH, path); //Populate the edit box
}
Thankyou for the replies...
You pass an A object by reference (or any other way to make the object visible to B::Display) and just excess it with '.' operator
void ClassB::Display(A &a){
SetDlgItemText(IDC_PATH, a.path);
}
although you might want to consider exposing public set and get functions for these kind of variables
With your current code you can't.
After the function void ClassA::Open() your CString path; will be destroyed.
You could save your CString path; as member variable.
Or you could add a variable of CString to your function void ClassB::Display(), which could result in this code:
void ClassA::Open(void)
{
// Open Program Properties window
ClassB dlg;
dlg.DoModal();
CString path;
path = m_DirTree.GetCurrentDir(); //Path specified by tree selection
m_classBMember.Display(path);
}
void ClassB::Display(CString &path)
{
SetDlgItemText(IDC_PATH, path); //Populate the edit box
}
In my first Gtkmm 3.0 program, I’m having trouble with the program structure and getting access to my class data from a DrawingArea class.
Based on a demo program from the gnome website (“Drawing thin lines”), I have a window class, a drawingArea class and a Board class with user data.
A drawingArea object is defined as a member variable in the windows class. In the window class constructor, I instantiate a Board object.
Now I want to access Board member variables in the on_draw routine in the drawingArea class. What's the best way to do this?
My board class has:
class Board {
public:
int sqPix;
My window class has:
Board &ExampleWindow::getBd() { return bdw; }
void ExampleWindow::setBd(Board b) {bdw = b; }
ExampleWindow::ExampleWindow(char * fn, vector<int>& t)
{
Board bd = Board(t);
setBd(bd);
My window class .h file has:
class ExampleWindow : public Gtk::Window
{
public:
ExampleWindow();
ExampleWindow(char * fn, std::vector<int>& t);
virtual ~ExampleWindow();
Board &getBd();
void setBd(Board b);
private:
Board bdw;
MyArea m_Area;
In my drawing area class, I want to do something like:
bool MyArea::on_draw(const Cairo::RefPtr<Cairo::Context>& cr)
{
Gtk::Allocation allocation = get_allocation();
=====> int sqPix = ExampleWindow::getBd().sqPix;
You should probably not couple your top level window to the drawing area, otherwise you can't reuse the drawing code in some other window of your application, for example, preferences to change an example board's appearance.
Instead, pass a Board reference or pointer to your DrawingArea in its constructor. Here is the window's constructor where the DrawingArea takes a Board reference. You can use a pointer and setBoard() instead if you think a DrawingArea won't always be associated with one Board:
ExampleWindow(const char * fn, const vector<int>& t) : bdw(t), m_Area(bdw) {
...
}
Add pointer to ExampleWindow to MyArea definition which you can later initialize in MyArea constructor. This way you will be able to access public interface of ExampleWindow. You can create public getters to allow external users (MyArea) to access fields.
I know this is a basic c++ question, but may I know how can I call a function/pass value (elementId) from one class to another in bada using the friend function?
In my form class, I have a listView and when the item in the listView has been clicked, I would like to pass the elementId to detailedForm to display info in the label (in detailedForm). In my form.h and .cpp I have included detailedForm.h, may I know how do I access the function in detailedForm to display the info? In form.h, I have also declared
friend class detailedForm;
and when I tried to use one of the function in detailedForm in my form class, namely displayInfo(); the form class has an error saying displayInfo() has not been declared.
form.h
...
public:
friend class ChartFormDetail;
Here is my code for form.cpp
#include "Form.h"
#include "ChartFormDetail.h"
...
void
Form::OnGroupedListViewItemStateChanged(Osp::Ui::Controls::GroupedListView &listView, int groupIndex, int itemIndex, int elementId, Osp::Ui::Controls::ListItemStatus state)
{
Frame* pFrame = Osp::App::Application::GetInstance()->GetAppFrame()->GetFrame();
FormMgr* pFormMgr = dynamic_cast<FormMgr*> (pFrame->GetControl("FormMgr"));
if(pFormMgr == null)
return;
pFormMgr->SendUserEvent(FormMgr::REQUEST_DETAILFORM, null);
//pFormMgr->SendUserEvent(elementId, null);
switch(elementId)
{
case ID_FORMAT_STRING_M12:
DisplayLabel();
break;
...
case ID_FORMAT_STRING_F19:
DisplayLabel();
break;
}
}
detailedForm.h
public:
...
void DisplayLabel(void);
code for detailedForm.cpp
void
ChartFormDetail::DisplayInfo(void)
{
pLabel->SetText("Text here");
RequestRedraw();
}
It looks like displayInfo is a member-function of CharFormDetail. That means you have to call it with an instance of ChartFormDetail.
To make it work, you need to do something like this:
ChartFormDetail & details = getDetails();
details.displayInfo();
This is just an example. I don't know how you would get an instance of ChartFormDetails, this depends very much on your architecture.
How are you trying to call displayInfo() in your class? You need an object of 'detailedForm' to access it. Also, if you need access the listView data in your friend class (detailedForm), you will need a reference to listView object.
If you're looking for an example to see how friend functions are used, you could check out: http://www.learncpp.com/cpp-tutorial/813-friend-functions-and-classes/
I have written a custom class which is available in QtScript through a Prototype. Also another global class is available which should be used to print the custom class generated in QtScript.
This is my custom class (very simple ;) ):
class Message
{
public:
int source;
int target;
};
This is the prototype I am using:
class MessagePrototype : public QObject, public QScriptable
{
Q_OBJECT
Q_PROPERTY(int source READ getSource WRITE setSource)
Q_PROPERTY(int target READ getTarget WRITE setTarget)
public:
void setSource(const int source);
int getSource() const;
void setTarget(const int target);
int getTarget() const;
};
The setter / getter are only changing / printing the corresponding Message object through a qscriptvalue_cast(QScriptable::thisObject());
Now my script looks like this:
var test = new Message;
test.source = 5;
print(test.source);
GlobalObject.sendMessage(test);
So, the script compiles fine and the print() command does what it should, it prints 5. But the problem is the sendMessage function of my GlobalObject:
void MessageAnalysis::sendMessage(Message msg)
{
qDebug() << "[Message]" << msg.source << msg.target;
}
This piece of code always prints: "[Message] 0 0".
MessageAnalysis is registered as "GlobalObject" for QtScript. Also I have registered Message and Message* as Metatypes and the constructor, prototype and everything else. This seems to work.
Does anyone knows why the values have been changed in QtScript but are not accessible from my C++ function? Or what I am doing wrong?
Ok. After several attempts I fixed it.
I changed the sendMessage function to accept a QScriptValue instead of a Message as parameter. Now I can get the properties out of it without problems.
Seems to work fine now :)