How to implement #pragma pointers_to_members() for just one class? - c++

I want to use #pragma pointers_to_members() to just one class.
I have other class definitions in my header file but I want to apply the required pragma to only one class and other classes should not be affected. How can this be achieved? There are not many code examples for that.

I have resolved this issue. I used the # pragma directive just before the BEGIN_MESSAGE_MAP() in my .cpp file.
#pragma pointers_to_members(full_generality,virtual_inheritance)
BEGIN_MESSAGE_MAP(CMy4407Dlg, CDialogEx)
ON_WM_SYSCOMMAND()
ON_WM_PAINT()
ON_WM_QUERYDRAGICON()
ON_BN_CLICKED(IDC_BUTTON1, &CMy4407Dlg::OnBnClickedButton1)
END_MESSAGE_MAP()
This is my derived class CMy4407Dlg:
class CMy4407Dlg : public CDialogEx, public virtual ABCD
{
// Construction
public:
CMy4407Dlg(CWnd* pParent = NULL); // standard constructor
// Dialog Data
enum { IDD = IDD_MY4407_DIALOG };
protected:
virtual void DoDataExchange(CDataExchange* pDX); // DDX/DDV support
// Implementation
protected:
HICON m_hIcon;
// Generated message map functions
virtual BOOL OnInitDialog();
afx_msg void OnSysCommand(UINT nID, LPARAM lParam);
afx_msg void OnPaint();
afx_msg HCURSOR OnQueryDragIcon();
DECLARE_MESSAGE_MAP()
public:
afx_msg void OnBnClickedButton1();
};

Related

c++ Public member variable is inaccessible

There's an error message "member ... is inaccessible" in Visual Studio when I try to access the value of a member variable.
But, the member variable is declared public. It's a derived class, but it's not a member variable of the base class.
From the compiler, there's an error message "cannot access protected member".
The lines that cause the error:
CKaltestDlg dlg;
fprintf(debugout, "Reminders get input focus %s \n", dlg.m_ReminderInputFocus ? "true" : "false");
The header file. The member variable in question is near the end, under a public: heading.
// KaltestDlg.h : header file
//
#pragma once
// CKaltestDlg dialog
class CKaltestDlg : public CDialogEx
{
// Construction
public:
CKaltestDlg(CWnd* pParent = nullptr); // standard constructor
// Dialog Data
#ifdef AFX_DESIGN_TIME
enum { IDD = IDD_KALTEST_DIALOG };
#endif
protected:
virtual void DoDataExchange(CDataExchange* pDX); // DDX/DDV support
// Implementation
protected:
HICON m_hIcon;
// Generated message map functions
virtual BOOL OnInitDialog();
afx_msg void OnSysCommand(UINT nID, LPARAM lParam);
afx_msg void OnPaint();
afx_msg HCURSOR OnQueryDragIcon();
public:
DECLARE_MESSAGE_MAP()
afx_msg void OnBnClickedRemindersinputfocus();
CButton m_EnableDisableInputFocus;
BOOL m_ReminderInputFocus;
CButton m_EnableDisableRemindersOntop;
BOOL m_RemindersOnTop;
afx_msg void OnBnClickedRemindersalwaysontop();
CButton m_EnableDisableFlash;
BOOL m_FlashTaskbarButton;
afx_msg void OnBnClickedReminderflash();
};
From the documentation of the DECLARE_MESSAGE_MAP() macro
Note
If you declare any member after DECLARE_MESSAGE_MAP, you must specify a new access type (public, private, or protected) for them.
So the macro expansion may result in the visibility being changed. Either move the macro to the end of the class or add public: right after it. I'd recommend leaving a comment about this in your code to remind you of this fact if you modify the class in the future.

Calling a method from another class in message handler

I have .H file and .Cpp file for a dialog Print that contains two buttons Printer 1 and Printer 2 and I want to call a method in another class function when Printer 1 is pressed.
.H File
#pragma once
#ifndef PRINTCHOOSEDLG_H
#define PRINTCHOOSEDLG_H
class CPrintChooseDlg : public CTungstenDlg
{
public:
CPrintChooseDlg(CWnd* pParent = NULL);
enum { IDD = IDD_PRINTBOX };
protected:
virtual void DoDataExchange(CDataExchange* pDX);
protected:
afx_msg void OnPrinter1();
afx_msg void OnPrinter2();
//virtual void OnPrinter1();
//virtual void OnPrinter2();
DECLARE_MESSAGE_MAP()
};
#endif
.Cpp
#include "stdafx.h"
#include "Tungsten.h"
#include "PrintChooseDlg.h"
CPrintChooseDlg::CPrintChooseDlg(CWnd* pParent /*=NULL*/)
: CDialog(CPrintChooseDlg::IDD, pParent)
{
}
void CPrintChooseDlg::DoDataExchange(CDataExchange* pDX)
{
CDialog::DoDataExchange(pDX);
}
BEGIN_MESSAGE_MAP(CPrintChooseDlg, CDialog)
ON_BN_CLICKED(IDC_PRINTER1,OnPrinter1)
ON_BN_CLICKED(IDC_PRINTER2,OnPrinter2)
END_MESSAGE_MAP()
void CPrintChooseDlg::OnPrinter1()
{
CTungstenDlg aux;
aux.OnOK();
}
void CPrintChooseDlg::OnPrinter2()
{
CTungstenDlg aux;
aux.OnOK();
}
How can i call the method CTungsten::OnOK inside the function CPrintChooseDlg::OnPrinter1()
It gives me an error of course because it is not defined in the PrintChooseDlg.cpp
What i tried: is to include guards in header and use suggested solutions in comments
Thanks in Advance

IN MFC CLISTCTRL a column should have an EDIT feature?

I am a beginner to MFC and C++ I want to have an edit option in one column I tried to overload these functions in the Classes but the Edit Option is not working could any one help me on this what is the mistake I did ?
class CEditableListCtrl : public CListCtrl
{
public:
int GetRowFromPoint( CPoint &point, int *col ) const;
CEdit* EditSubLabel( int nItem, int nCol );
void OnHScroll(UINT nSBCode, UINT nPos, CScrollBar* pScrollBar);
void OnVScroll(UINT nSBCode, UINT nPos, CScrollBar* pScrollBar);
void OnEndLabelEdit(NMHDR* pNMHDR, LRESULT* pResult);
void OnLButtonDown(UINT nFlags, CPoint point);
};
class CInPlaceEdit : public CEdit
{
public:
CInPlaceEdit(int iItem, int iSubItem, CString sInitText);
// ClassWizard generated virtual function overrides
//{{AFX_VIRTUAL(CInPlaceEdit)
public: virtual BOOL PreTranslateMessage(MSG* pMsg);
//}}AFX_VIRTUAL
public: virtual ~CInPlaceEdit();
// Generated message map functions
protected:
//{{AFX_MSG(CInPlaceEdit)
afx_msg void OnKillFocus(CWnd* pNewWnd);
afx_msg void OnNcDestroy();
afx_msg void OnChar(UINT nChar, UINT nRepCnt, UINT nFlags);
afx_msg int OnCreate(LPCREATESTRUCT lpCreateStruct);
//}}AFX_MSG
DECLARE_MESSAGE_MAP()
private:
int m_iItem;
int m_iSubItem;
CString m_sInitText;
BOOL m_bESC;
};
If you only need one column to be editable, you don't need to do much: make sure your list has an LVS_EDITLABELS style. This will allow you to edit text in column 0. If you need to edit different column - change visible column order using CListCtrl::SetColumnOrderArray()

How to display a MFC dialog from a console application in C++?

I have a simple MFC dialog.
class CMessageBoxWithCustomTextDlg : public CDialogEx
{
// Construction
public:
CMessageBoxWithCustomTextDlg(CWnd* pParent = NULL); // standard constructor
__declspec(dllexport) void SetData(std::string& data);
// Dialog Data
enum { IDD = IDD_MESSAGEBOXWITHCUSTOMTEXT_DIALOG };
protected:
virtual void DoDataExchange(CDataExchange* pDX); // DDX/DDV support
// Implementation
protected:
HICON m_hIcon;
// Generated message map functions
virtual BOOL OnInitDialog();
afx_msg void OnPaint();
afx_msg HCURSOR OnQueryDragIcon();
DECLARE_MESSAGE_MAP()
public:
afx_msg void OnBnClickedShowMessagebox();
};
I would like to export it as dll and call it from a simple console application. Is it possible?
It is possible; here is how I did it:
For your console application have it be simply this:
#include <Windows.h>
typedef void (*EntryFunc)();
int main()
{
HMODULE hMod = LoadLibrary(L"MFCDll.dll");
EntryFunc func = (EntryFunc)GetProcAddress(hMod, "entrypoint");
func();
}
The name of the DLL is MFCDll.dll and there is an exported function called entrypoint in that DLL.
For the DLL I created a New MFC DLL project. And other than the dialog code and the dialog in the resources add this code:
extern "C" __declspec(dllexport) void entrypoint()
{
AFX_MANAGE_STATE(AfxGetStaticModuleState());
CMessageBoxWithCustomTextDlg dlg;
dlg.DoModal();
}
And the console program will load the DLL, call into the DLL and the dialog shows.

OnSelectionChanged not getting called

Header:
#pragma once
class AlarmsList : public CVSListBox
{
DECLARE_DYNAMIC(AlarmsList)
public:
AlarmsList();
virtual ~AlarmsList();
void OnAfterAddItem(int index);
void OnSelectionChanged(NMHDR *pNMHDR, LRESULT *pResult);
protected:
DECLARE_MESSAGE_MAP()
public:
afx_msg void OnDtnDatetimechangeDatetimepicker1(NMHDR *pNMHDR, LRESULT *pResult);
};
void AlarmsList::OnAfterAddItem(int index)
{
GetParent()->GetDlgItem(IDC_TIMEPICK)->EnableWindow(true);
LOGIC->addAlarm();
LOGIC->changeSelection(index);
}
void AlarmsList::OnSelectionChanged(NMHDR *pNMHDR, LRESULT *pResult)
{
}
OnAfterAddItem gets called when i add a new item but OnSelectionChanged NEVER gets called how much i even try.
Linking it trough a message map neither dosnt work:
IMPLEMENT_DYNAMIC(AlarmsList, CVSListBox)
BEGIN_MESSAGE_MAP(AlarmsList, CVSListBox)
ON_NOTIFY(LVN_ITEMCHANGED, IDC_LIST, OnSelectionChanged)
END_MESSAGE_MAP()
I create the AlarmsList object using the create function.
Source code and project: http://www.filedropper.com/clockmaster
Generally, I think the LVN_ITEMCHANGED notification is sent to the parent window. Put the handler and the message map entry int your dialog/window that is the parent of the list box.
Didnt help :/.
Tried both parent property page and that property pages dialog.
Overloading dosnt work either :/, it does for OnAfterAddItem tough.
And yes I'm then using the same parameters as the virtual function.
You can try overriding the functions in the CVSListBoxBase class.In this class, the signature of OnSelectionChanged function requires no arguments.
You can find the declaration of the CVSListBoxBase class in afxvslistbox.h.
Just had a look at some of my own MFC code that uses list boxes, and the following works;
CMyListBox : public CListBox
{
}
class CMyDialog : public CDialog
{
// Construction
public:
CMyDialog(CFeatureDoc* pFeatureDoc,BOOL SheetLayout = FALSE,CWnd* pParent = NULL); // standard constructor
//{{AFX_DATA(CMyDialog)
enum { IDD = IDD_MY_DIALOG };
CMyListBox m_MyListBox;
//}}AFX_DATA
// Overrides
// ClassWizard generated virtual function overrides
//{{AFX_VIRTUAL(CMyDialog)
protected:
virtual void DoDataExchange(CDataExchange* pDX); // DDX/DDV support
//}}AFX_VIRTUAL
// Implementation
protected:
// Generated message map functions
//{{AFX_MSG(CMyDialog)
afx_msg void OnSelChangeListBox();
//}}AFX_MSG
DECLARE_MESSAGE_MAP()
};
void CMyDialog::DoDataExchange(CDataExchange* pDX)
{
CDialog::DoDataExchange(pDX);
//{{AFX_DATA_MAP(CMyDialog)
DDX_Control(pDX, IDC_MY_LIST_BOX, m_MyListBox);
//}}AFX_DATA_MAP
}
BEGIN_MESSAGE_MAP(CMyDialog, CDialog)
//{{AFX_MSG_MAP(CMyDialog)
ON_LBN_SELCHANGE(IDC_MY_LIST_BOX, OnSelChangeListBox)
//}}AFX_MSG_MAP
END_MESSAGE_MAP()
/////////////////////////////////////////////////////////////////////////////
// CMyDialog message handlers
void CMyDialog::OnSelChangeListBox()
{
}
If you want to have your own control process messages from a dialog, you may want to subclass it. See this related question What's the correct way to create a subclass of a MFC control?