Setting Cedit Text - visual-c++

I have the following code in trying to set the text in a Cedit text box:
class CMetaDlg : public CDialogEx
{
public:
CMetaDlg();
// Dialog Data
enum { IDD = IDD_META };
protected:
virtual void DoDataExchange(CDataExchange* pDX); // DDX/DDV support
// Implementation
protected:
DECLARE_MESSAGE_MAP()
public:
CEdit m_author;
CEdit m_sources;
afx_msg void OnBnClickedOk();
};
CMetaDlg::CMetaDlg() : CDialogEx(CMetaDlg::IDD)
{
}
void CMetaDlg::DoDataExchange(CDataExchange* pDX)
{
CDialogEx::DoDataExchange(pDX);
DDX_Control(pDX, IDC_AUTHOR, m_author);
DDX_Control(pDX, IDC_SOURCES, m_sources);
}
BEGIN_MESSAGE_MAP(CMetaDlg, CDialogEx)
ON_BN_CLICKED(IDOK, &CMetaDlg::OnBnClickedOk)
END_MESSAGE_MAP()
void CEmergenceApp::OnFileMeta()
{
CMetaDlg md;
md.DoModal();
md.m_author.SetWindowTextW(CEmergenceView::GetDoc()->author);
md.m_sources.SetWindowTextW(CEmergenceView::GetDoc()->sources);
}
This gives me a debug assertion error. I am assuming the problem lies in the lines:
md.m_author.SetWindowTextW(CEmergenceView::GetDoc()->author);
md.m_sources.SetWindowTextW(CEmergenceView::GetDoc()->sources);
As commenting them out, everything works fine.

When you call DoModal the dialog is created, the edit controls are created and then when the user clicks OK or Cancel the edit controls and dialog window are destroyed. Then DoModal returns. I do not understand what you are trying to do by trying to set the edit control's text after the dialog box closes.

Related

How to capture windows message from the up/down button of a CDateTimeCtrl control?

I am using a CDateTimeCtrl, along with a callback field, in my dialog application. All works well as intended but I want to capture the windows message when the up-down button ( looks a lot like the spin control) of the CDateTimeCtrl is clicked without success. Spy++ reported the class of the up-down button to be msctls_updown32. Spy++ message log offer no clue either. How do I capture the mouse click messages from this up-down control ( looks like an OLE control to me)?
Edited: : I've tried handling the UDN_DELTAPOS message like so but still unable to capture the message from CMyTimeCtrl.
class CMyTimeCtrl : public CDateTimeCtrl
{
DECLARE_DYNAMIC(CMyTimeCtrl)
public:
CMyTimeCtrl();
virtual ~CMyTimeCtrl();
protected:
int m_msec;
DECLARE_MESSAGE_MAP()
public:
virtual void DoDataExchange(CDataExchange* pDX);
afx_msg void OnDtnFormat(NMHDR* pNMHDR, LRESULT* pResult);
afx_msg void OnDtnFormatquery(NMHDR* pNMHDR, LRESULT* pResult);
afx_msg void OnDtnWmkeydown(NMHDR* pNMHDR, LRESULT* pResult);
afx_msg void OnDeltaposSpin(NMHDR* pNMHDR, LRESULT* pResult);
};
BEGIN_MESSAGE_MAP(CMyTimeCtrl, CDateTimeCtrl)
ON_NOTIFY(WM_NOTIFY, UDN_DELTAPOS, &CMyTimeCtrl::OnDeltaposSpin)
ON_NOTIFY_REFLECT(DTN_FORMAT, &CMyTimeCtrl::OnDtnFormat)
ON_NOTIFY_REFLECT(DTN_FORMATQUERY, &CMyTimeCtrl::OnDtnFormatquery)
ON_NOTIFY_REFLECT(DTN_WMKEYDOWN, &CMyTimeCtrl::OnDtnWmkeydown)
END_MESSAGE_MAP()
Thanks, with the guidance from the comment section I manage to resolve my issue. In the message map I made an error, corrected as shown below. Now it's working fine. In my resource section, the IDC_STATIC value is 1000:
BEGIN_MESSAGE_MAP(CMyTimeCtrl, CDateTimeCtrl)
ON_NOTIFY(UDN_DELTAPOS, IDC_STATIC, &CMyTimeCtrl::OnDeltaposSpin)
ON_NOTIFY_REFLECT(DTN_FORMAT, &CMyTimeCtrl::OnDtnFormat)
ON_NOTIFY_REFLECT(DTN_FORMATQUERY, &CMyTimeCtrl::OnDtnFormatquery)
ON_NOTIFY_REFLECT(DTN_WMKEYDOWN, &CMyTimeCtrl::OnDtnWmkeydown)
END_MESSAGE_MAP()

MFC on form create event

I have simple FMC dialog form. Can't find how to manage event that should be called on form create moment. Something like onFormCreate like it is in VB or Delphi.
How to create such functionality?
My simple form header:
#pragma once
// CMFCApplicationUPTDlg dialog
class CMFCApplicationUPTDlg : public CDialog
{
// Construction
public:
CMFCApplicationUPTDlg(CWnd* pParent = NULL); // standard constructor
// Dialog Data
enum { IDD = IDD_MFCAPPLICATIONUPT_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 OnBnClickedOk();
afx_msg void OnBnClickedButton1();
};
You want to handle it in the OnInitDialog() member function. At the point that OnInitDialog() is called, the dialog and all of its child windows will have been created. However, the dialog will still be invisible to the user. After exiting OnInitDialog(), the dialog will be shown to the user.
So, it is the place where you would want to do initialization of your dialog.
You need to implement OnInitDialog in your own derived class.
BOOL CMFCApplicationUPTDlg::OnInitDialog()
{
// this will create the controls you defined in the resources.
BOOL retValue = __super::OnInitDialog();
// initialize (or add new controls to ) your dialog content here.
// ...
return retValue;
}

Set MFC dialog form caption

I need to set dialog form caption. I was trying to create CString variable that might be binded to caption with Class Wizard. But there is no main form control in selection menu. What is the way of doing that?
This is my dialog form:
#include "stdafx.h"
#include "MyDlg.h"
#include "afxdialogex.h"
// MyDlg dialog
IMPLEMENT_DYNAMIC(MyDlg, CDialog)
MyDlg::MyDlg(CWnd* pParent /*=NULL*/)
: CDialog(MyDlg::IDD, pParent)
, m_edit(_T(""))
{
}
MyDlg::~MyDlg()
{
}
void MyDlg::DoDataExchange(CDataExchange* pDX)
{
CDialog::DoDataExchange(pDX);
DDX_Text(pDX, IDC_EDIT1, m_edit);
}
BEGIN_MESSAGE_MAP(MyDlg, CDialog)
ON_BN_CLICKED(IDOK, &MyDlg::OnBnClickedOk)
END_MESSAGE_MAP()
// MyDlg message handlers
void MyDlg::OnBnClickedOk()
{
// TODO: Add your control notification handler code here
CDialog::OnOK();
txt=m_edit;
}
This is code that creates dialog:
BOOL CPreparationApp::InitInstance()
{
MyDlg Dlg;
//how to tell Dlg to have form caption "BLABLABLA"?
Dlg.DoModal();
return TRUE;
}
Hoping I've understood your question in the right way:
// MyDlg.h
class MyDlg
{
public: // private is fine too if you're OOP nazi but you have to provide a SetDlgCaption method then.
CString m_strDlgCaption;
};
// MyDlg.cpp
BOOL MyDlg::OnInitDialog( )
{
SetWindowText( m_strDlgCaption );
}
BOOL CPreparationApp::InitInstance()
{
MyDlg Dlg;
Dlg.m_strDlgCaption = _T("A fancy caption for your dialog");
Dlg.DoModal();
}
If you have not already done it you first need to add an override in the dialog class for OnInitDialog. This is the first place you can execute code after the dialog and its control windows exist. You can put SetWindowText(_T("BLABLABLA")) in OnInitDialog to set the dialog caption.

Crashing while executing GetParent(). Closing of a modeless dialog box

I am creating a modeless dialog box. The dialog box is called from the menu item of main frame window.
MainFrm.h
CModeless* modeless;
bool modelessDlgOpen;
MainFrm.cpp
void CMainFrame::OnDatabaseMLdlg()
{
// TODO: Add your command handler code here
if (modelessDlgOpen == TRUE)
return;
modelessDlgOpen = TRUE;
modeless = new CModeless(this);
//modeless->Create(IDD_MLDLG, GetDesktopWindow());
modeless->Create(IDD_MLDLG, this);
mbPoll->ShowWindow(SW_SHOW);
}
When menu item is clicked, OnDatabaseMLdlg() function is called and a modeless dialog box with resource ID IDD_MLDLG appears.
The issue is while closing the modeless dialog box.
I am not able to find out the correct method to have a clean closure / destroy of this modeless dialog box. Upon clicking the cross button in right-top corner, which message gets
generated?
My current code which I have tried is as follows. (producing code related only to the closure of the dialog box)
MLDLG.h
#pragma once
#define WM_MLDLG_CLOSED (WM_USER + 555)
// CModeless dialog
class CModeless : public CDialog
{
DECLARE_DYNAMIC(CModeless)
public:
CModeless(CWnd* pParent = NULL); // standard constructor
virtual ~CModeless();
// Dialog Data
enum { IDD = IDD_MLDLG };
protected:
virtual void DoDataExchange(CDataExchange* pDX); // DDX/DDV support
DECLARE_MESSAGE_MAP()
public:
virtual BOOL Create(UINT nIDTemplate, CWnd* pParentWnd = NULL);
afx_msg void OnNcDestroy();
virtual void PostNcDestroy();
CWnd* mParent;
afx_msg void OnBnClickedCancel();
};
MLDLG.cpp
void CModeless::OnNcDestroy()
{
CDialog::OnNcDestroy();
// TODO: Add your message handler code here
}
void CModeless::PostNcDestroy()
{
CDialog::PostNcDestroy();
GetParent()->PostMessage(WM_MLDLG_CLOSED,0,0); // **CRASHES HERE**
delete this;
}
void CModeless::OnBnClickedCancel()
{
// TODO: Add your control notification handler code here
//CDialog::OnCancel();
DestroyWindow();
}
Not able to understand what am I doing wrong or what am I missing?
I can provide additional details in case required.
Thanks in advance.
EDIT-20130612: Additional information:
My constructor is as follows:
CModeless::CModeless(CWnd* pParent /*=NULL*/)
: CDialog(CModeless::IDD, pParent)
{
mParent = pParent;
if (mParent == NULL)
{
MessageBox(L"mParent is NULL");
}
else
{
MessageBox(L"mParent is not NULL");
}
}
Here, I have verified that mParent is not NULL.
PostNCDestroy() is called VERY late and most of the useful state of the MFC window is not valid at that point. GetParent() is probably returning NULL, which will cause a crash the way you are using it.
Try moving the PostMessage call to OnDestroy() before calling the base class implementation there.
Another option is to cache the parent's hWnd and call ::PostMessage() on that hWnd;

Display a new view from within a custom control

I have a custom button which inherits from UIButton. I'm handling the TouchUpInside event and want to display a view on top of the current View. Is there such a thing as Dialogs like in Windows development? Or should I do this in another way?
[MonoTouch.Foundation.Register("HRPicker")]
public class HRPicker : UIButton
{
public HRPicker () : base()
{
SetUp();
}
public HRPicker(NSCoder coder) : base(coder)
{
SetUp();
}
public HRPicker(NSObjectFlag t) : base(t)
{
SetUp();
}
public HRPicker(IntPtr handle) : base(handle)
{
SetUp();
}
public HRPicker(RectangleF frame) : base(frame)
{
SetUp();
}
public void SetUp()
{
TouchUpInside += HandleTouchUpInside;
}
void HandleTouchUpInside (object sender, EventArgs e)
{
//I want to display a View here on top of the current one.
}
}
Thanks,
Yes, you have a couple options:
ModalViewController - is called from any UIViewController and overlays a ViewController in the foreground.
UIPopoverController - is a native control that takes a UIViewController and has hooks for presentation and dismissal
WEPopoverController - is a re-implementation of UIPopoverController and allows you to customize the layout, size, and color of the Popover container.
ModalViewController: http://developer.apple.com/library/ios/#documentation/uikit/reference/UIViewController_Class/Reference/Reference.html
UIPopoverController: http://developer.apple.com/library/ios/#documentation/uikit/reference/UIPopoverController_class/Reference/Reference.html
WEPopoverController: https://github.com/mono/monotouch-bindings/tree/master/WEPopover
Update: Regardless of which option you use you must call the presentation of the Popover / Modal view from the main thread:
using(var pool = new NSAutoReleasePool()) {
pool.BeginInvokeOnMainThread(()=>{
// Run your awesome code on the
// main thread here, dawg.
});
}
The equivalent of dialog in Cocoa is UIAlertView: http://developer.apple.com/library/ios/#documentation/uikit/reference/UIAlertView_Class/UIAlertView/UIAlertView.html
Check out this question for an example of how to use it: Showing an alert with Cocoa
The code should be pretty easy to translate to c# and MonoTouch. But here is a simple example: http://monotouchexamples.com/#19

Resources