Background: So I've created an application that is basically a large preference dialog where the user can configure a number of pages, each with a bunch of different settings. These settings are in the form of dropdowns and text boxes. I want to store all of the variables into one massive "Parameters.h" file so that I can access them from anywhere in my application. Each sub-page has it's own source and header file.
I'm having trouble with the pointers though. I'm not sure how to reference the Parameters class. Basically, my application has two main components: a main dialog and a bunch of sub, child pages. The main dialog is where the sub-pages are shown and hidden, based on what page the user chooses in a listbox on the left of the main dialog.
I'm just working with one sub-page right now, and have the following, but when I debug, I'm getting <BadPtr> all over the place. I have greatly simplified the code, but it should be enough to figure out what I'm doing wrong.
Question: So how do I point to this Parameters class in each sub-dialog so that I can store and use all of these variables?
SAPrefsDialog.cpp: Main dialog that houses the sub-pages
BOOL CSAPrefsDialog::OnInitDialog()
{
CDialog::OnInitDialog();
FSC_Main fscMain;
fscMain.SetParametersPointer(&m_pParams);
// [ ... ]
}
SAPrefsDialog.h: Main dialog header file
#include "Parameters.h"
public:
CSAPrefsDialog(CWnd* pParent = NULL); // standard constructor
~CSAPrefsDialog();
Parameters m_pParams;
FSC_Main.h: Sub-page header file
#include "Parameters.h"
class FSC_Main : public CSAPrefsSubDlg
{
// Construction
public:
FSC_Main(CWnd* pParent = NULL); // standard constructor
// Dialog Data
//{{AFX_DATA(FSC_Main)
enum { IDD = IDD_FS_CONFIG_MAIN };
//}}AFX_DATA
public:
void SetParametersPointer(Parameters* pParameters)
{ m_Params = pParameters; }
private:
Parameters *m_Params;
};
Parameters.h
#include "stdafx.h"
#include "prefs.h"
#pragma once
class Parameters
{
public:
Parameters(); // standard constructor
public:
~Parameters(void);
protected:
virtual void DoDataExchange(CDataExchange* pDX); // DDX/DDV support
public:
//*****************************************************************************
//
// FSC_Main.cpp Variables
//
//*****************************************************************************
CString m_strVehiclesMainNumVehicles;
CString m_strVehiclesMainMaxSensorCount;
CString m_strVehiclesMainTaskProcessingInterval;
CString m_strVehiclesMain
// [ ... ]
Parameters.cpp
#include "stdafx.h"
#include "prefs.h"
#include "pages.h"
#include "Parameters.h"
//*****************************************************************************
//
// Parameters::Parameters
//
//*****************************************************************************
Parameters::Parameters():
m_strVehiclesMainNumVehicles("")
, m_strVehiclesMainMaxSensorCount("")
, m_strVehiclesMainTaskProcessingInterval("")
// [ ... ]
{
}
The problem is that you're making the pages as local variables in CSAPrefsDialog::OnInitDialog, and those variables are destroyed as soon as you leave the function. You should make them as member variables of your CSAPrefsDialog class. Everything else you're doing looks fine.
Related
everybody.
I am working on a gtkmm app and need some help getting a "Close" button to work. As suggested by the gtkmm documentation, I derived a class for the main window object, created some members, and left the main() function mostly for reading the glade UI file, instantiating the form and starting the main loop.
There are 3 files, named conveniently for explanation: Declarations.h, Declarations.cpp, Program.cpp
In "Declarations.h" I have the class inherited from the Gtk Window:
#include <gtkmm.h>
class MainWindowClass : public Gtk::ApplicationWindow
{
protected:
Gtk::Button *button_close;
// other buttons here
protected:
void on_button_close_clicked();
// other callback functions here
public:
MainWindowClass(BaseObjectType *cobject, const Glib::RefPtr<Gtk::Builder> &refGlade); // Constructor
// Destructor, other public members
};
In "Declarations.cpp" I have the implementations:
#include "Declarations.h"
using namespace Gtk;
// Implementing the constructor
MainWindowClass::MainWindowClass(BaseObjectType *cobject, const Glib::RefPtr<Gtk::Builder> &refGlade) :
Gtk::Window(cobject), builder(refGlade)
{
builder->get_widget("button_close", button_close);
// Getting other widgets from the glade file
button_close->signal_clicked().connect(sigc::mem_fun(*this, &MainWindowClass::on_button_close_clicked));
// Connecting other callback functions here
}
// Implementing the callback for the "Close" button, ** PROBLEM IS HERE **
void MainWindowClass::on_button_close_clicked()
{
//gtk_main_quit(); Apparently GTK+/C only, compiler doesn't complain but causes a segfault when clicking the button
//Gtk::Application::quit(); Won't compile
}
The Program.cpp reads the UI from a file and starts the main program loop:
#include <gtkmm.h>
#include "Declarations.h"
int main(int argc, char *argv[])
{
auto app = Gtk::Application::create(argc, argv, "Damn this close button");
Glib::RefPtr<Gtk::Builder> builder = Gtk::Builder::create_from_file("Program_UI.glade");
MainWindowClass our_main_window;
return app->run(our_main_window);
}
I am omitting some non-relevant code (of other objects and callbacks) because they work, it is the close procedure that is causing me trouble, though closing the app with "X" works.
I have also thought about trying to call a quit() or destroy() function (if they exist) of "app", but then the callback function doesn't know "app" exists.
What do you guys suggest?
Thanks a lot.
** Edit: fixed this using FormMain::hide(), which is inherited from GtkWindow.
I thought the static procedure Gtk::Main::hide() would do it, but the compiler says that hide() is not a member of Gtk::Main...
Well, moving forward one step at a time.
Used FormMain::hide() (inherited from GtkWindow). The static procedure Gtk::Main::hide() was not being recognized by the compiler.
I am really hoping that you all can help me with this problem. I am both new to the site and new to C++ (only been learning for about a month). My compiler is VS2012. I am working on a set of menus for a program. The menus use simple switch statements for each of their classes. Each menu is derived from a base menu class. Since I do not seem to be having any issues with the menu classes themselves, I am not including them at the moment since they are all in separate .cpp files with their own .h header files. I am including the base menu .cpp and .h files since I believe they are part of my issue. I am also including my main .cpp file.
BaseMenu.h
#ifndef BaseMenu_M
#define BaseMenu_M
#include<string>
#include<iostream>
using std::cout;
class BaseMenu
{
public:
BaseMenu() { m_MenuText = "This is where the menu text choices will appear"; }// Constructor providing menu text to each derived menu
virtual ~BaseMenu() { } // virtual destructor
virtual BaseMenu getNextMenu(int iChoice, bool& iIsQuitOptionSelected); // used to set up the framework
virtual void printText() // member function to display the menu text
{
cout << m_MenuText << std::endl;
}
protected:
std::string m_MenuText; // string will be shared by all derived classes
};
#endif
BaseMenu.cpp
#include "stdafx.h"
#include "BaseMenu.h"
#include<iostream>
BaseMenu::BaseMenu(void)
{
}
BaseMenu::~BaseMenu(void)
{
}
Main .cpp file
#include "stdafx.h"
#include "BaseMenu.h"
#include "TicketSalesMenu.h"
#include "MainMenu.h"
#include "ListMenu.h"
#include "AdministrativeTasksMenu.h"
#include "basemenu.h"
#include <iostream>
#include <string>
using std::cin;
int tmain (int argc, _TCHAR* argv[])
{
BaseMenu* aCurrentMenu = new MainMenu; // Pointer to the current working menu
bool isQuitOptionSelected = false;
while (!isQuitOptionSelected) // set to keep menus running until the quit option is selected
{
aCurrentMenu->printText(); // call and print the menu text for the currently active menu
int choice = 0; // Initializing choice variable and setting it to 0
cin >> choice;
BaseMenu* aNewMenuPointer = aCurrentMenu->getNextMenu(choice, isQuitOptionSelected); // This will return a new object, of the type of the new menu we want. Also checks if quit was selected //**This is the line that the error is reported**//
if (aNewMenuPointer)
{
delete aCurrentMenu; // clean up the old menu
aCurrentMenu = aNewMenuPointer; // updating the 'current menu' with the new menu
}
}
return true;
}
For some reason I can not figure out, I am receiving a
error C2440: 'initializing' : cannot convert from 'BaseMenu' to 'BaseMenu*'. This error is in the main .cpp file on line 35, which is
"BaseMenu* aNewMenuPointer = aCurrentMenu->getNextMenu(choice, isQuitOptionSelected);"
I have looked at multiple similar questions from this site and others. One of the solutions I tried, resulted in multiple link errors for all my menu classes. It has taken me 3 days to get the errors reduced to just this one remaining error and I am at a loss.
The compiler is telling you the problem. getNextMenu returns an actual BaseMenu object, but you are trying to assign it to a pointer to a BaseMenu object.
I'm trying to create a game in C++.
It has a "Session" class that kind of manages everything. It contains things like a GraphicsManager, a SoundManager, and the current world. It also contains a static pointer to an instance of itself. This way, I want the world to be available for the GraphicsManager so it can be rendered, for example.
Here is a simplified version of my code:
main.ccp
#pragma once
#include "Session.h"
int main() {
Session::getSession()->run(); //Starts a new session and runs it
return 0;
}
Session.h
#pragma once
#include "GraphicsManager.h"
#include "World.h"
class Session; //Forward declaration so it can have a pointer to itself
class Session {
private:
Session();
static Session* s;
World* w; //Pointer because no world is loaded at the beginning of the program
GraphicsManager gm; //Required right away
public:
~Session();
void run(); //Actually launches the game after preparation; not further declared in this example
World* getWorld(); //Returns the pointer to the current world
static Session* getSession();
}
Session.cpp
#include "Session.h"
Session::Session(): gm(GraphicsManager()) {}
Session* Session::getSession() { //Return an instance of Session. If no instance exist yet, create one.
if(s == NULL) s = new Session();
return s;
}
World* Session::getWorld() {return w;} //Returns a pointer to the current world
GraphicsManager.h
#pragma once;
class GraphicsManager {
private:
void render();
public:
void run(); //Calls the render method repeatedly; no further declaration in this example
}
GraphicsManager.cpp
#include "GraphicsManager.h"
void GraphicsManger::render() {
World* w = Session::getSession()->getWorld(); //Get pointer to current world so it can be rendered
}
The render method is where I'm stuck. If I put #include "Session.h" into the GraphicsManager.h file, it gives me an error because apparently two header files cannot include each other. If I put a forward declaration at the beginning of GraphicsManager.h or GraphicsManager.cpp, Visual Studio tells me that incomplete types are not permitted.
This has been giving me a headache for weeks. I've made games in Java before and there this pattern was accepted. So how can I do this? If this structure is not possible in C++, do you have other suggestions for it?
In GraphicsManager.cpp, the compiler needs to know about the Session, so you have to #include "Session.h" which by the way includes GraphicsManager as well as World.
A forward definition will not be sufficient, as the compiler would not be able to check types of getSession()->getWorld() expression.
Apparently your GraphicsManager.h doesn't rely itself on the other definitions, so there should'nt be an issue here.
Try to include Session.h to GraphicsManager.cpp:
#include "Session.h"
void GraphicsManger::render() {
World* w = Session::getSession()->getWorld(); //Get pointer to current world so it can be rendered
}
This way Session class defenition will be visible for compiler in GraphicsManager.cpp, so it will not generate incomplite type error. On the other hand, Session.h is not included to GraphicsManager header, so there will no problem that both headers include each other.
I have created a Windows Form Project in VC++ 2010 Express version. So, in that project I created a Form, which had only 1 button and 1 textbox. The name of this form was Form1.
This button called a function FD written in a .cpp file in the same project. However, while running the code, I need to update the textbox with some text. I want to access the textbox through the .cpp file.
I have tried the following:
I included #include "Form1.h" and then wrote textBox1->Text="XYZ". However, while building it says that it cannot find any member called textBox1.
How do I access the textbox from the .cpp file?
EDIT:
FD.cpp
#include<stdafx.h>
#include "Form1.h"
... //other includes
void abc()
{
//Some code
textBox1->Text="String to be displayed."
//Some code
}
Form1.h
This is simple GUI form, where a button called button1 and a textbox called textBox1 is added.
#include<FD.h>
//code generated by the GUI
void button1_click()
{
abc();
}
// FD.cpp
void abc(Form1^ f)
{
// Assuming that textBox1 is public. If not, make it public or make
// public get property
f->textBox1->Text="String to be displayed."
//Some code
}
// Form1.h
void button1_click()
{
abc(this);
}
Or:
// FD.cpp
void abc(TextBox^ t)
{
t->Text="String to be displayed."
//Some code
}
// Form1.h
void button1_click()
{
abc(textBox1);
}
Another way: make abc method return type String^ and set its return value in Form1 to textBox1. Advantage: abc doesn't know anything about UI level. Yet another way: events http://msdn.microsoft.com/en-us/library/58cwt3zh.aspx
The reason you're getting this error is because you haven't specified whose textBox that is. It is not enough to #include the header file, you need to find a way to communicate with your Form1 object. You can do this in several ways.
Using a global pointer to the instance of your main Form1 that can be accessed from anywhere,
Using a local pointer to the instance of your main Form1 that is passed around and can be called upon,
Providing a friend function that can manipulate the data in the class (not recommended),
I would choose 2.
I am learning MFC programming. In the part of dialog design, I entered a problem.
The resource is IDD_PEN_WIDTH, which is the ID of the dialog. And there is a piece of automatically generated code related to this:
class PenWidthDlg : public CDialogEx
{
DECLARE_DYNAMIC(PenWidthDlg)
public:
PenWidthDlg(CWnd* pParent = NULL); // standard constructor
virtual ~PenWidthDlg();
// Dialog Data
enum { IDD = IDD_PEN_WIDTH };
protected:
virtual void DoDataExchange(CDataExchange* pDX); // DDX/DDV support
DECLARE_MESSAGE_MAP()
public:
int m_nPenWidth;
};
Before I run my program, the IDD_PEN_WIDTH shows "#define IDD_PEN_WIDTH 301" while hovering mouse on IDD_PEN_WIDTH in the code. But when I run it, there is one error says IDD_PEN_WIDTH is an undefined identifier. Then I hover mouse on "IDD_PEN_WIDTH", it also says it's undefined.
I am usually confused in MFC studying, and I will appreciate very much for your detailed explanations. Thanks.
It has to be defined in every cpp file that uses it. Add #include "Resource.h" in those cpp files. Do that #include before the #include of the dialog .h file.