Why the variable in statictext tool in mfc is undefined - c++

I create a static text in a mfc dialog, then I change variable of this static text into CString type and member name is a m_process.
Then, I will use this static text to show the time process, but the identifier not defined.
int64 tm1 = cv::getTickCount();
int64 tm2 = cv::getTickCount();
double sec = (tm2-tm1)/cv::getTickFrequency();
teks.Format(_T("%g"),sec);
m_process.SetWindowTextW(teks);
and this is the error
Error 9 error C2065: 'm_process' : undeclared identifier d:\kuliah\smt 8\bismillah ta\bismillah_dialog\bismillah_dialog\bismillah_dialogdlg.cpp 391 1 Bismillah_Dialog
Error 4 error C2228: left of '.SetWindowTextW' must have class/struct/union d:\kuliah\smt 8\bismillah ta\bismillah_dialog\bismillah_dialog\bismillah_dialogdlg.cpp 268 1 Bismillah_Dialog
this is the declaration of this static text.
in Dlg.cpp
CBismillah_DialogDlg::CBismillah_DialogDlg(CWnd* pParent /*=NULL*/)
: CDialogEx(CBismillah_DialogDlg::IDD, pParent)
{
m_hIcon = AfxGetApp()->LoadIcon(IDR_MAINFRAME);
modeTampil = 0;
openProcess = 0;
modeAuto = 0;
m_area = _T("");
m_process = _T("");
}
void CBismillah_DialogDlg::DoDataExchange(CDataExchange* pDX)
{
CDialogEx::DoDataExchange(pDX);
// DDX_Control(pDX, IDC_EDIT1, m_area);
// DDX_Control(pDX, IDC_EDIT2, m_process);
DDX_Control(pDX, IDC_BUTTON2, m_play);
DDX_Control(pDX, IDC_BUTTON1, m_open);
// DDX_Control(pDX, ID_STATIC, m_pic);
DDX_Control(pDX, ID_STATIC, m_pic);
DDX_Control(pDX, IDC_MFCEDITBROWSE1, m_name);
// DDX_Control(pDX, IDC_EDIT3, m_coba);
// DDX_Control(pDX, IDC_EDIT1, m_area);
DDX_Text(pDX, IDC_EDIT1, m_area);
DDX_Text(pDX, IDC_EDIT2, m_process);
}
and in the header file.
public:
CWinThread* thread;
afx_msg void OnEnChangeMfceditbrowse1();
int modeTampil;
int openProcess;
int modeAuto;
static DWORD ThreadPro(LPVOID *x);
afx_msg void threadProcess();
// CStatic m_area;
// CStatic m_process;
CButton m_play;
CButton m_open;
// CStatic m_pic;
CStatic m_pic;
afx_msg void OnBnClickedButton1();
CMFCEditBrowseCtrl m_name;
// CEdit m_coba;
// CStatic m_area;
CString m_area;
CString m_process;
};
The system already declared the static text, but it is not detect when I build this program.
I dont know how to solved it. I'm very confused, and newbie to this MFC. I'm very very need help. thank you :))

Given your code provided, the UI control is mapped to a CString and not to a CEdit.
Therefore, you can't use SetWindowTextW as CString is not a control object.
In your can just use:
m_process.Format(_T("%g"),sec);
UpdateData(FALSE);
I am not saying this is the most efficient way. But it works with your stated code. There are other ways to transfer control content to variables (for example: SetDlgItemText) but this is how I do it. No doubt there are even more methods.

Related

Moving data from a CDateTimeCtrl to a CTime object in VC++ 6

Working with VS6 I noticed that some of my dialog boxes would crash when the date was changed in a CDateTimeCtrl object. Investigating this revealed that the call to DDX_DateTimeCtrl was moving 12 bytes of data onto a CTime object that is 4 bytes wide. Can anyone explain why this might be happening? Does anyone know how to correct it?
Header:
#if !defined(AFX_DATEDIALOG_H__B9373304_D774_4447_A4D1_BB4E1FB3404F__INCLUDED_)
#define AFX_DATEDIALOG_H__B9373304_D774_4447_A4D1_BB4E1FB3404F__INCLUDED_
#if _MSC_VER > 1000
#pragma once
#endif // _MSC_VER > 1000
// DateDialog.h : header file
//
/////////////////////////////////////////////////////////////////////////////
// CDateDialog dialog
class CDateDialog : public CDialog
{
// Construction
public:
CDateDialog(CWnd* pParent = NULL); // standard constructor
// Dialog Data
//{{AFX_DATA(CDateDialog)
enum { IDD = IDD_DIALOG_DATE };
CDateTimeCtrl m_StartDate;
CDateTimeCtrl m_EndDate;
CTime m_tmEndDate;
CTime m_tmStartDate;
//}}AFX_DATA
// Overrides
// ClassWizard generated virtual function overrides
//{{AFX_VIRTUAL(CDateDialog)
protected:
virtual void DoDataExchange(CDataExchange* pDX); // DDX/DDV support
//}}AFX_VIRTUAL
// Implementation
protected:
// Generated message map functions
//{{AFX_MSG(CDateDialog)
afx_msg void OnButtonBack();
afx_msg void OnDatetimechangeEndDate(NMHDR* pNMHDR, LRESULT* pResult);
afx_msg void OnDatetimechangeStartDate(NMHDR* pNMHDR, LRESULT* pResult);
afx_msg void OnCloseupStartDate(NMHDR* pNMHDR, LRESULT* pResult);
afx_msg void OnCloseupEndDate(NMHDR* pNMHDR, LRESULT* pResult);
//}}AFX_MSG
DECLARE_MESSAGE_MAP()
private:
// the range limits for the dates; these are set to the values found
// in m_tmStartDate and m_tmEndDate in OnInitDialog
CTime m_tmStart; // beginning of the range
CTime m_tmEnd; // end of the range
};
//{{AFX_INSERT_LOCATION}}
// Microsoft Visual C++ will insert additional declarations immediately before the previous line.
#endif // !defined(AFX_DATEDIALOG_H__B9373304_D774_4447_A4D1_BB4E1FB3404F__INCLUDED_)
Code:
// DateDialog.cpp : implementation file
//
#include "stdafx.h"
#include "CustomerSales.h"
#include "DateDialog.h"
#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif
/////////////////////////////////////////////////////////////////////////////
// CDateDialog dialog
CDateDialog::CDateDialog(CWnd* pParent /*=NULL*/)
: CDialog(CDateDialog::IDD, pParent)
{
//{{AFX_DATA_INIT(CDateDialog)
m_tmEndDate = 0;
m_tmStartDate = 0;
//}}AFX_DATA_INIT
}
void CDateDialog::DoDataExchange(CDataExchange* pDX)
{
CDialog::DoDataExchange(pDX);
//{{AFX_DATA_MAP(CDateDialog)
DDX_Control(pDX, IDC_START_DATE, m_StartDate);
DDX_Control(pDX, IDC_END_DATE, m_EndDate);
DDX_DateTimeCtrl(pDX, IDC_END_DATE, m_tmEndDate);
DDX_DateTimeCtrl(pDX, IDC_START_DATE, m_tmStartDate);
//}}AFX_DATA_MAP
}
BEGIN_MESSAGE_MAP(CDateDialog, CDialog)
//{{AFX_MSG_MAP(CDateDialog)
ON_BN_CLICKED(IDC_BUTTON_BACK, OnButtonBack)
ON_NOTIFY(DTN_DATETIMECHANGE, IDC_END_DATE, OnDatetimechangeEndDate)
ON_NOTIFY(DTN_DATETIMECHANGE, IDC_START_DATE, OnDatetimechangeStartDate)
ON_NOTIFY(DTN_CLOSEUP, IDC_START_DATE, OnCloseupStartDate)
ON_NOTIFY(DTN_CLOSEUP, IDC_END_DATE, OnCloseupEndDate)
//}}AFX_MSG_MAP
END_MESSAGE_MAP()
/////////////////////////////////////////////////////////////////////////////
// CDateDialog message handlers
void CDateDialog::OnButtonBack()
{
// exit with our buton ID
EndDialog(IDC_BUTTON_BACK);
}
void CDateDialog::OnDatetimechangeEndDate(NMHDR* pNMHDR, LRESULT* pResult)
{
if(m_EndDate.GetMonthCalCtrl() == NULL)
{
UpdateData();
if(m_tmStartDate > m_tmEndDate)
m_tmStartDate = m_tmEndDate;
UpdateData(FALSE);
}
*pResult = 0;
}
void CDateDialog::OnDatetimechangeStartDate(NMHDR* pNMHDR, LRESULT* pResult)
{
if(m_StartDate.GetMonthCalCtrl() == NULL)
{
UpdateData();
if(m_tmEndDate < m_tmStartDate)
m_tmEndDate = m_tmStartDate;
UpdateData(FALSE);
}
*pResult = 0;
}
void CDateDialog::OnCloseupStartDate(NMHDR* pNMHDR, LRESULT* pResult)
{
UpdateData();
if(m_tmEndDate < m_tmStartDate)
m_tmEndDate = m_tmStartDate;
UpdateData(FALSE);
*pResult = 0;
}
void CDateDialog::OnCloseupEndDate(NMHDR* pNMHDR, LRESULT* pResult)
{
UpdateData();
if(m_tmStartDate > m_tmEndDate)
m_tmStartDate = m_tmEndDate;
UpdateData(FALSE);
*pResult = 0;
}
I have observed the bug with the CDateTimeCtrl a long time ago. The GetTime method of the class would crash if used with the CTime variable. I remember that at that time I have found a reference in the Internet related to this problem. I cannot find it now. The proposed solution was to use COleDateTime.
It seems that the similar problem exists with the DDE/DDX exchanges, and it has not been fixed in the latest MFC.
The simplest workaround for me at that time was to use the COleDateTime variables.
The DDX_DateTimeCtrl works with CTime and COleDateTime, so the solution for you will be to use the COleDateTime for your m_tmEndDate and m_tmStartDate variables.

DDX_Control example for mfc

I am not able to get the DDX_Control working example.
When I create the dialog box, I am not able to create a reference for the control object.
Google doesn't have examples as well.
Thanks.
void CEditDialog::DoDataExchange(CDataExchange* pDX)
{
CDialog::DoDataExchange(pDX);
DDX_Control(pDX, IDC_COMBO1, m_cmbBox);
DDX_Text(pDX, IDC_EDIT1, m_Edit);
}
void CMFCApplicationDDEView::OnActionEdit2()
{
// TODO: Add your command handler code here
CEditDialog dlg;
CString str;
dlg.m_cmbBox.GetLBText(0, str);
if (dlg.DoModal() == IDOK)
{
MessageBox(dlg.cmbItemStr);
}
}
dlg.m_cmbBox is NULL. Why is it null and how can I reference it in my view
#barmak is correct in saying that you cannot access dialog box controls directly before the InitDialog() has executed.
However, you can set / retrieve the text of the edit portion of a combo box by using DDX_CBString, like:
// in .h file
CString m_cmbItemStr;
// in .cpp
void CEditDialog::DoDataExchange(CDataExchange* pDX)
{ CDialog::DoDataExchange(pDX);
DDX_CBString(pDX, IDC_COMBO1, m_cmbItemStr);
DDX_Text(pDX, IDC_EDIT1, m_Edit);
}
void CMFCApplicationDDEView::OnActionEdit2()
{ CEditDialog dlg;
CString str = TEXT("some value");
dlg.m_cmbItemStr = str;
if (dlg.DoModal() == IDOK)
MessageBox(dlg.m_cmbItemStr);
}
Your code for combo box and dialog box is correct but m_cmbBox.GetLBText() cannot be used before and after DoModal() because there is no window handle. Override like code below, then access combo_str instead of accessing windows
BEGIN_MESSAGE_MAP(CEditDialog, CDialog)
ON_COMMAND(IDOK, OnOK)
//...
END_MESSAGE_MAP()
BOOL CEditDialog::OnInitDialog()
{
BOOL res = CDialog::OnInitDialog();
//Dialog is created, window handles are available, set text here
return res;
}
void CEditDialog::OnOK()
{
//get text before dialog's window handles are destroyed
int sel = m_cmbBox.GetCurSel();
if (sel >= 0) m_cmbBox.GetLBText(sel, cmbItemStr);
CDialog::OnOK();
}

MFC- receiving Button-Click-Message failed

I've created a new dialog in my MFC dialog based application. the new dialog contains 5 control buttons.
the following happens and I don't understand why?
click on buttonX. (result ok, OnBnClicked message is sent)
click on on any place of the application, but not on the dialog.(removing focus from dialog)
click again on buttonX (FAILED, OnBnClicked message is NOT sent). but if instead I click on any other button in the dialog (result ok, OnBnClicked message is sent).
and when I do:
...
...
click on the dialog area just to set focus on the dialog again
click again on buttonX. (result ok, OnBnClicked message is sent)
**I need to do step 3 only if I want to click again on the buttonX! why??
I think it related to SetFocus() but I m not sure how.
the buttons IDC are:
IDC_BACK_MEDIA_PRESS_BUTTON 1180
IDC_TOOLS_LEFT_RIGHT 1024
IDC_MEDIA_FOREWARD_BUTTON 1103
IDC_MEDIA_BACKWARD_BUTTON 1104
IDC_TOOLS_HOOD_BUTTON 2346
the dialog properties is:
IDD_TOOLS_DIALOG DIALOGEX 0, 0, 51, 218
STYLE DS_SETFONT | DS_MODALFRAME | DS_FIXEDSYS | WS_POPUP | WS_VISIBLE | WS_CAPTION | WS_SYSMENU
CAPTION "Tools"
FONT 8, "MS Shell Dlg", 400, 0, 0x1
BEGIN
PUSHBUTTON "Media &Foreward",IDC_MEDIA_FOREWARD_BUTTON,7,79,37,36,BS_MULTILINE
PUSHBUTTON "&Media &BackWard",IDC_MEDIA_BACKWARD_BUTTON,7,43,37,36,BS_MULTILINE
PUSHBUTTON "Back Media Press",IDC_BACK_MEDIA_PRESS_BUTTON,7,127,37,36,BS_MULTILINE | NOT WS_VISIBLE
PUSHBUTTON "Hood",IDC_TOOLS_HOOD_BUTTON,7,7,37,36
PUSHBUTTON "Left Right",IDC_TOOLS_LEFT_RIGHT,7,175,37,36
END
I've tried different style like, tool windows, overlapped, popup. it happens in all the cases.
Thanks for the help.
.h
class CToolsDlg : public CBDialog
{
DECLARE_DYNAMIC(CToolsDlg)
public:
CToolsDlg(CWnd* pParent = NULL); // standard constructor
virtual ~CToolsDlg();
CToolTipCtrl m_ToolsTips;
// Dialog Data
enum { IDD = IDD_TOOLS_DIALOG };
protected:
virtual void OnCancel();
virtual void DoDataExchange(CDataExchange* pDX); // DDX/DDV support
DECLARE_MESSAGE_MAP()
public:
CMFCButton m_HoodButton;
CMFCButton m_MediaForewardButton;
CMFCButton m_MediaBackwardButton;
CMFCButton m_LeftRightButton;
virtual BOOL OnInitDialog();
virtual BOOL PreTranslateMessage(MSG* pMsg);
afx_msg void OnTimer(UINT_PTR nIDEvent);
afx_msg void OnBnClickedCancel();
afx_msg void OnBnClickedToolsHoodButton();
afx_msg void OnBnClickedMediaForewardButton();
afx_msg void OnBnClickedMediaBackwardButton();
afx_msg void OnBnClickedLeftRightButton();
afx_msg void OnBnClickedBackMediaPressButton();
};
.cpp
IMPLEMENT_DYNAMIC(CToolsDlg, CBDialog)
CToolsDlg::CToolsDlg(CWnd* pParent /*=NULL*/)
: CBDialog(CToolsDlg::IDD, pParent)
{
}
CToolsDlg::~CToolsDlg()
{
}
void CToolsDlg::DoDataExchange(CDataExchange* pDX)
{
CBDialog::DoDataExchange(pDX);
DDX_Control(pDX, IDC_TOOLS_HOOD_BUTTON, m_HoodButton);
DDX_Control(pDX, IDC_MEDIA_FOREWARD_BUTTON, m_MediaForewardButton);
DDX_Control(pDX, IDC_MEDIA_BACKWARD_BUTTON, m_MediaBackwardButton);
DDX_Control(pDX, IDC_TOOLS_LEFT_RIGHT, m_LeftRightButton);
}
BEGIN_MESSAGE_MAP(CToolsDlg, CBDialog)
ON_WM_CLOSE()
ON_WM_DESTROY()
ON_WM_TIMER()
ON_BN_CLICKED(IDC_TOOLS_HOOD_BUTTON, &CToolsDlg::OnBnClickedToolsHoodButton)
ON_BN_CLICKED(IDC_MEDIA_FOREWARD_BUTTON, &CToolsDlg::OnBnClickedMediaForewardButton)
ON_BN_CLICKED(IDC_MEDIA_BACKWARD_BUTTON, &CToolsDlg::OnBnClickedMediaBackwardButton)
ON_BN_CLICKED(IDC_TOOLS_LEFT_RIGHT, &CToolsDlg::OnBnClickedLeftRightButton)
ON_BN_CLICKED(IDC_BACK_MEDIA_PRESS_BUTTON, &CToolsDlg::OnBnClickedBackMediaPressButton)
END_MESSAGE_MAP()
// CToolsDlg message handlers
BOOL CToolsDlg::OnInitDialog()
{
CBDialog::OnInitDialog();
// Window position
//////////////////////////////////////////////////////////////////////////
CMainFrame* mf = (CMainFrame*)AfxGetMainWnd();
RECT MFwinRect;
RECT ThiswinRect;
CWnd* fv = mf->m_wndSplitter.GetView( mf->m_wndSplitter.GetCurrentViewIndex(0,0) );
fv->GetWindowRect(&MFwinRect);
GetWindowRect(&ThiswinRect);
MoveWindow(
MFwinRect.right - (ThiswinRect.right - ThiswinRect.left) - 14, // X
MFwinRect.top + 14, // Y
(ThiswinRect.right - ThiswinRect.left), // nWidth
(ThiswinRect.bottom - ThiswinRect.top) ); // nHeight
// Set controls state
//////////////////////////////////////////////////////////////////////////
m_ToolsTips.Create(this);
m_ToolsTips.AddTool(&m_HoodButton, TOOLTIP_HOOD_BUTTON);
m_ToolsTips.AddTool(&m_MediaForewardButton, TOOLTIP_MEDIA_FOREWARD_BUTTON);
m_ToolsTips.AddTool(&m_MediaBackwardButton, TOOLTIP_MEDIA_BACKWARD_BUTTON);
m_ToolsTips.AddTool(&m_LeftRightButton, TOOLTIP_LEFT_RIGHT_BUTTON);
m_ToolsTips.SetDelayTime(1000);
m_ToolsTips.Activate(BARAK_PREFS->m_Params.m_bShowToolTips);
// Main timer loop (no need for now)
// SetTimer( 1, 1000, NULL );
return TRUE;
}
BOOL CToolsDlg::PreTranslateMessage(MSG* pMsg)
{
m_ToolsTips.RelayEvent(pMsg);
return CBDialog::PreTranslateMessage(pMsg);
}
void CToolsDlg::OnCancel()
{
// When closing the window, destroy it and not only hide (its a floating window).
DestroyWindow();
}
void CToolsDlg::OnTimer(UINT_PTR nIDEvent)
{
CBDialog::OnTimer(nIDEvent);
}
void CToolsDlg::OnBnClickedToolsHoodButton()
{
...
}
void CToolsDlg::OnBnClickedMediaForewardButton()
{
...
}
void CToolsDlg::OnBnClickedMediaBackwardButton()
{
...
}
void CToolsDlg::OnBnClickedLeftRightButton()
{
...
}
void CToolsDlg::OnBnClickedBackMediaPressButton()
{
...
}
I see that you are filling view with dialog content. Have you put focusing to your dialog? I think this mystic behavior happening only on first mouse click in your dialog (then dialog gets the focus). I'm just guessing :)

MFC input form not accept less than 5 symbols

I have MFC dialog form with Text Edit control that allows to enter not more than 5 symbols. But how to make system not accept string less than 5 symbols?
Dialog form:
IMPLEMENT_DYNAMIC(InputDialog, CDialogEx)
InputDialog::InputDialog(CWnd* pParent /*=NULL*/)
: CDialogEx(InputDialog::IDD, pParent)
, m_edit(_T(""))
{
}
InputDialog::~InputDialog()
{
}
void InputDialog::DoDataExchange(CDataExchange* pDX)
{
CDialogEx::DoDataExchange(pDX);
DDX_Text(pDX, IDC_EDIT_INPUT, m_edit);
DDV_MaxChars(pDX, m_edit, 5);
}
BEGIN_MESSAGE_MAP(InputDialog, CDialogEx)
ON_BN_CLICKED(IDOK, &InputDialog::OnBnClickedOk)
END_MESSAGE_MAP()
Microsoft provides the source to MFC so you can see how they implemented DDV_MaxChars. Simply copy it and change the condition.
void AFXAPI DDV_MinChars(CDataExchange* pDX, CString const& value, int nChars)
{
// ...
if (pDX->m_bSaveAndValidate && value.GetLength() < nChars)
{
// ...
Handle the Kill Focus event for the text field. In the handler for the event get the length of the string that was entered. If it's less than 5, optionally pop up a message, and, set the focus back to the field.

change the background color of a dialog box mfc

I'm trying to change the background color of a dialog box (win 7, vs2010,c++).
I tried to catch WM_CTLCOLOR ,WM_ERASEBKGND and change the color.
I manged to change in this way the backgroung color, but when the window is finish to upload itself, the color is back to default but I noticed that the frame is in the right color.
I think that I'm changing the window and not the dialog box or something like that.
I'm doing this with WTL (not AFX).
What should I do?
Try this:
/////////////////////////////////////////////////////////////////////////////
// CAboutDlg dialog used for App About
class CAboutDlg : public CDialog
{
public:
CAboutDlg();
// Dialog Data
//{{AFX_DATA(CAboutDlg)
enum { IDD = IDD_ABOUTBOX };
//}}AFX_DATA
// ClassWizard generated virtual function overrides
//{{AFX_VIRTUAL(CAboutDlg)
protected:
virtual void DoDataExchange(CDataExchange* pDX); // DDX/DDV support
//}}AFX_VIRTUAL
// Implementation
protected:
//{{AFX_MSG(CAboutDlg)
//}}AFX_MSG
afx_msg BOOL OnEraseBkgnd(CDC* pDC);
DECLARE_MESSAGE_MAP()
};
CAboutDlg::CAboutDlg() : CDialog(CAboutDlg::IDD)
{
//{{AFX_DATA_INIT(CAboutDlg)
//}}AFX_DATA_INIT
}
void CAboutDlg::DoDataExchange(CDataExchange* pDX)
{
CDialog::DoDataExchange(pDX);
//{{AFX_DATA_MAP(CAboutDlg)
//}}AFX_DATA_MAP
}
BEGIN_MESSAGE_MAP(CAboutDlg, CDialog)
//{{AFX_MSG_MAP(CAboutDlg)
ON_WM_ERASEBKGND()
//}}AFX_MSG_MAP
END_MESSAGE_MAP()
BOOL CAboutDlg::OnEraseBkgnd(CDC* pDC)
{
CRect rect;
GetClientRect(&rect);
CBrush myBrush(RGB(255, 255, 255)); // dialog background color
CBrush *pOld = pDC->SelectObject(&myBrush);
BOOL bRes = pDC->PatBlt(0, 0, rect.Width(), rect.Height(), PATCOPY);
pDC->SelectObject(pOld); // restore old brush
return bRes; // CDialog::OnEraseBkgnd(pDC);
}
And have a look here
The better way will be to override WM_CTLCOLOR, background of controls such as STATIC will be fill with your color too.
BEGIN_MESSAGE_MAP(YourDlg, CDialogEx)
ON_WM_CTLCOLOR()
END_MESSAGE_MAP()
...
HBRUSH YourDlg::OnCtlColor(CDC* pDC, CWnd* pWnd, UINT nCtlColor)
{
return (HBRUSH)GetStockObject(WHITE_BRUSH);
}
The above answer will work only if you don't have a tab inside dialog box it will color background of dialog box other the tab portion. For the tab portion you have to create a new derived class with base class CTabCtrl.