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

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.

Related

How to avoid flickering while the CScrollView is moving?

I was trying to make the CScrollView move
Although it moved successfully, but I found a problem...
The CScrollView flickered randomly while it is moving.
Below is the whole code of my project:
#include <afxwin.h>
#include <afxext.h>
#include "resource.h"
class MyView : public CScrollView
{
public:
void OnDraw(CDC *aDC){
CRect rc;
GetClientRect(&rc);
aDC->FillSolidRect(&rc, RGB(0,0,255));
}
BOOL PreCreateWindow(CREATESTRUCT& cs)
{
cs.style &= ~WS_BORDER;
return CScrollView::PreCreateWindow(cs);
}
afx_msg int OnCreate(LPCREATESTRUCT lpCreateStruct)
{
if(CScrollView::OnCreate(lpCreateStruct) == -1)
return -1;
CSize DCSize(200, 800);
SetScrollSizes(MM_TEXT, DCSize);
return 0;
}
DECLARE_DYNCREATE(MyView)
DECLARE_MESSAGE_MAP()
};
IMPLEMENT_DYNCREATE(MyView, CScrollView)
BEGIN_MESSAGE_MAP(MyView, CScrollView)
ON_WM_CREATE()
END_MESSAGE_MAP()
class CMainDlg : public CDialog
{
public:
CMainDlg(CWnd* pParent = NULL);
enum { IDD = IDD_MAIN_DIALOG };
CWnd* pFrameWnd;
CCreateContext context;
MyView* pView;
int time;
virtual BOOL OnInitDialog();
afx_msg void OnTimer(UINT_PTR timer);
void OnPaint(){
CPaintDC dc(this);
CRect rc;
GetClientRect(&rc);
dc.FillSolidRect(&rc,RGB(255,187,187));
}
DECLARE_MESSAGE_MAP()
};
BEGIN_MESSAGE_MAP(CMainDlg, CDialog)
ON_WM_TIMER()
ON_WM_PAINT()
END_MESSAGE_MAP()
CMainDlg::CMainDlg(CWnd* pParent /*=NULL*/)
: CDialog(CMainDlg::IDD, pParent)
{
}
BOOL CMainDlg::OnInitDialog()
{
CDialog::OnInitDialog();
pFrameWnd = this;
context.m_pCurrentDoc = NULL;
context.m_pNewViewClass = RUNTIME_CLASS(MyView);
pView = (MyView*)((CFrameWnd*)pFrameWnd)->CreateView(&context);
pView->ShowWindow(SW_SHOW);
time = 0;
SetTimer(1, 1, 0);
return TRUE;
}
void CMainDlg::OnTimer(UINT_PTR timer)
{
if(timer == 1){
if(time > 300){
KillTimer(1);
return;
}
pView->MoveWindow(CRect(time,10,time+300,200),FALSE);
}
time+=1;
Invalidate(FALSE);
}
class MyApp : public CWinApp
{
public:
BOOL InitInstance()
{
CWinApp::InitInstance();
CMainDlg Frame;
Frame.DoModal();
return true;
}
} a_app;
I don't know why the CScrollView flickered while it is moving. Can anyone solve this problem?
It is flickering because you're invalidating the entire window. This causes a WM_ERASE, which blanks the window, then a WM_PAINT, which redraws the entire thing. You're passing FALSE as the bRepaint (last) parameter to MoveWindow, so that it won't repaint any necessary window area after the window has been moved.
Normally when a window moves the content moves with it, and the only parts that need to be redrawn are bits that were offscreen or under another window. Passing TRUE as the last parameter will cause only these areas of the window to be redrawn, which will avoid the flicker.

VC++ Trasforming a sample application into a DLL

I have a project where I received an sample code that is an exe, that basically loads to a dialog two activeX controls.
I need to make an DLL to use the functions of that controls.
What's the best strategy to do this?
I think my DLL need's to make an instance of the window.
and when the window is build get pointers to the activeX controls to make stuff happen.
What is the best strategy to do this? or if it is even possible?
The App Code:
StartUp.h
#pragma once
#ifndef __AFXWIN_H__
#error "include 'stdafx.h' before including this file for PCH"
#endif
#include "resource.h" // main symbols
// CStartUpApp:
// See StartUp.cpp for the implementation of this class
//
class CStartUpApp : public CWinApp
{
public:
CStartUpApp();
// Overrides
public:
virtual BOOL InitInstance();
// Implementation
DECLARE_MESSAGE_MAP()
};
extern CStartUpApp theApp;
StartUpDlg.h
#pragma once
#include "xnssdkdevicectrl.h"
#include "xnssdkwindowctrl.h"
// CStartUpDlg dialog
class CStartUpDlg : public CDialog
{
// Construction
public:
CStartUpDlg(CWnd* pParent = NULL); // standard constructor
// Dialog Data
enum { IDD = IDD_STARTUP_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()
private:
// [ XNS ACTIVEX HELP ]
// -----------------------------------------------------------------------
// XNS Device control and Window control variables
// -----------------------------------------------------------------------
CXnssdkwindowctrl m_ctrlXnsWindow; // XnsWindow control
CXnssdkdevicectrl m_ctrlXnsDevice; // XnsDevice control
public:
afx_msg void OnBnClickedOk();
};
StartUp.cpp
#include "stdafx.h"
#include "StartUp.h"
#include "StartUpDlg.h"
#ifdef _DEBUG
#define new DEBUG_NEW
#endif
// CStartUpApp
BEGIN_MESSAGE_MAP(CStartUpApp, CWinApp)
ON_COMMAND(ID_HELP, &CWinApp::OnHelp)
END_MESSAGE_MAP()
// CStartUpApp construction
CStartUpApp::CStartUpApp()
{
// TODO: add construction code here,
// Place all significant initialization in InitInstance
}
// The one and only CStartUpApp object
CStartUpApp theApp;
// CStartUpApp initialization
BOOL CStartUpApp::InitInstance()
{
// InitCommonControlsEx() is required on Windows XP if an application
// manifest specifies use of ComCtl32.dll version 6 or later to enable
// visual styles. Otherwise, any window creation will fail.
INITCOMMONCONTROLSEX InitCtrls;
InitCtrls.dwSize = sizeof(InitCtrls);
// Set this to include all the common control classes you want to use
// in your application.
InitCtrls.dwICC = ICC_WIN95_CLASSES;
InitCommonControlsEx(&InitCtrls);
CWinApp::InitInstance();
AfxEnableControlContainer();
// Standard initialization
// If you are not using these features and wish to reduce the size
// of your final executable, you should remove from the following
// the specific initialization routines you do not need
// Change the registry key under which our settings are stored
// TODO: You should modify this string to be something appropriate
// such as the name of your company or organization
SetRegistryKey(_T("Local AppWizard-Generated Applications"));
CStartUpDlg dlg;
m_pMainWnd = &dlg;
INT_PTR nResponse = dlg.DoModal();
if (nResponse == IDOK)
{
// TODO: Place code here to handle when the dialog is
// dismissed with OK
}
else if (nResponse == IDCANCEL)
{
// TODO: Place code here to handle when the dialog is
// dismissed with Cancel
}
// Since the dialog has been closed, return FALSE so that we exit the
// application, rather than start the application's message pump.
return FALSE;
}
StartUpDlg.cpp
#include "stdafx.h"
#include "StartUp.h"
#include "StartUpDlg.h"
// [ XNS ACTIVEX HELP ]
// -----------------------------------------------------------------------
// This files are installed in {$SDK path}\sample_code\include
// You should include this files
// -----------------------------------------------------------------------
#include "XnsCommon.h"
#include "XnsDeviceInterface.h"
#ifdef _DEBUG
#define new DEBUG_NEW
#endif
// Macro for OutputDebugString()
#define DBG_LOG(...) do{\
CString strMessage = _T("");\
strMessage.AppendFormat(_T("(%S:%d)"), __FUNCTION__, __LINE__); \
strMessage.AppendFormat(__VA_ARGS__);\
OutputDebugString(strMessage);\
}while(0);
// Macro for AfxMessageBox()
#define ERROR_BOX(...) do{\
CString strMessage = _T("");\
strMessage.Format(__VA_ARGS__);\
AfxMessageBox(strMessage);\
}while(0);
// CAboutDlg dialog used for App About
class CAboutDlg : public CDialog
{
public:
CAboutDlg();
// Dialog Data
enum { IDD = IDD_ABOUTBOX };
protected:
virtual void DoDataExchange(CDataExchange* pDX); // DDX/DDV support
// Implementation
protected:
DECLARE_MESSAGE_MAP()
};
CAboutDlg::CAboutDlg() : CDialog(CAboutDlg::IDD)
{
}
void CAboutDlg::DoDataExchange(CDataExchange* pDX)
{
CDialog::DoDataExchange(pDX);
}
BEGIN_MESSAGE_MAP(CAboutDlg, CDialog)
END_MESSAGE_MAP()
// CStartUpDlg dialog
CStartUpDlg::CStartUpDlg(CWnd* pParent /*=NULL*/)
: CDialog(CStartUpDlg::IDD, pParent)
{
m_hIcon = AfxGetApp()->LoadIcon(IDR_MAINFRAME);
}
void CStartUpDlg::DoDataExchange(CDataExchange* pDX)
{
CDialog::DoDataExchange(pDX);
DDX_Control(pDX, IDC_XNSSDKDEVICECTRL, m_ctrlXnsDevice);
DDX_Control(pDX, IDC_XNSSDKWINDOWCTRL, m_ctrlXnsWindow);
}
BEGIN_MESSAGE_MAP(CStartUpDlg, CDialog)
ON_WM_SYSCOMMAND()
ON_WM_PAINT()
ON_WM_QUERYDRAGICON()
//}}AFX_MSG_MAP
ON_BN_CLICKED(IDOK, &CStartUpDlg::OnBnClickedOk)
END_MESSAGE_MAP()
// CStartUpDlg message handlers
BOOL CStartUpDlg::OnInitDialog()
{
CDialog::OnInitDialog();
// Add "About..." menu item to system menu.
// IDM_ABOUTBOX must be in the system command range.
ASSERT((IDM_ABOUTBOX & 0xFFF0) == IDM_ABOUTBOX);
ASSERT(IDM_ABOUTBOX < 0xF000);
CMenu* pSysMenu = GetSystemMenu(FALSE);
if (pSysMenu != NULL)
{
CString strAboutMenu;
strAboutMenu.LoadString(IDS_ABOUTBOX);
if (!strAboutMenu.IsEmpty())
{
pSysMenu->AppendMenu(MF_SEPARATOR);
pSysMenu->AppendMenu(MF_STRING, IDM_ABOUTBOX, strAboutMenu);
}
}
// Set the icon for this dialog. The framework does this automatically
// when the application's main window is not a dialog
SetIcon(m_hIcon, TRUE); // Set big icon
SetIcon(m_hIcon, FALSE); // Set small icon
// TODO: Add extra initialization here
// [ XNS ACTIVEX HELP ]
// -----------------------------------------------------------------------
// Initializes the DLL files.
// For this, XnsActiveX library requires config.xml, device.xml,
// and xns.xml files and the DLL file list should be mentioned
// in Xns.xml file. The path of the DLL file can not exceed 512 bytes
// in length. The XnsActiveX library searches for xns.xml using
// XnsSDKDevice.ocx installed in "{$SDK path}\Config" folder.
// -----------------------------------------------------------------------
long nRet = m_ctrlXnsDevice.Initialize();
if (nRet != ERR_SUCCESS)
{
DBG_LOG(_T("XnsSdkDevice:: Initialize() fail: errno=[%d]\n"), nRet);
}
// [ XNS ACTIVEX HELP ]
// -----------------------------------------------------------------------
// Initializes the XnsSdkWindow control.
// Namely, this will specify the window handle in order to display
// images on the screen.
// -----------------------------------------------------------------------
nRet = m_ctrlXnsWindow.Initialize(NULL, NULL);
DBG_LOG(_T("XnsSdkWindow:: Initialize() return=[%d](%s)\n"),
nRet, m_ctrlXnsDevice.GetErrorString(nRet));
return TRUE; // return TRUE unless you set the focus to a control
}
void CStartUpDlg::OnSysCommand(UINT nID, LPARAM lParam)
{
if ((nID & 0xFFF0) == IDM_ABOUTBOX)
{
CAboutDlg dlgAbout;
dlgAbout.DoModal();
}
else
{
CDialog::OnSysCommand(nID, lParam);
}
}
// If you add a minimize button to your dialog, you will need the code below
// to draw the icon. For MFC applications using the document/view model,
// this is automatically done for you by the framework.
void CStartUpDlg::OnPaint()
{
if (IsIconic())
{
CPaintDC dc(this); // device context for painting
SendMessage(WM_ICONERASEBKGND, reinterpret_cast<WPARAM>(dc.GetSafeHdc()), 0);
// Center icon in client rectangle
int cxIcon = GetSystemMetrics(SM_CXICON);
int cyIcon = GetSystemMetrics(SM_CYICON);
CRect rect;
GetClientRect(&rect);
int x = (rect.Width() - cxIcon + 1) / 2;
int y = (rect.Height() - cyIcon + 1) / 2;
// Draw the icon
dc.DrawIcon(x, y, m_hIcon);
}
else
{
CDialog::OnPaint();
}
}
// The system calls this function to obtain the cursor to display while the user drags
// the minimized window.
HCURSOR CStartUpDlg::OnQueryDragIcon()
{
return static_cast<HCURSOR>(m_hIcon);
}
void CStartUpDlg::OnBnClickedOk()
{
// TODO: Add your control notification handler code here
OnOK();
}
my dll header
__declspec(dllexport) long init();//initilize app with activeX controls in window
__declspec(dllexport) long getDlgInstance();//get dlg handle to be able to call activeX
__declspec(dllexport) long connect(long handle);//do stuff
Shouldn't be that hard...
Without having seen your code (how could I?), I assume you defined functions to return the pointers of the activeX controls to the caller.
Judging by the questions you asked earlier you know how to make a DLL. Get all the code you need in a new DLL project, export only the functions you want to access from the host application and you're done
Your DLL code would look something like
__declspec (dllexport) CStartUpDlg *ShowStartUpDlg()
{ AFX_MANAGE_STATE(AfxGetStaticModuleState()); // in case the dialog is in the DLL's .rc file
// alternate to the above line: AfxSetResourceHandle(hInstance); // hInstance is what you get in the DLL's InitInstance()
CStartUpDlg *pDlg = new CStartUpDlg();
if (pDlg == NULL)
return NULL;
if (!pDlg->Create(IDD_STARTUP_DLG))
return NULL;
pDlg->ShowWindow(SW_SHOW);
return pDlg; // make sure you close the dialog and delete pDlg at the end of your program
}

Get timer event in parent class

I have MFC form InputYesNoDlg that is derived from CDialogExInput. In CDialogExInput I have added timer. Unfortunatly I can't get timer event when I create InputYesNoDlg form. Why?
Code CDialogExInput
h:
#define ID_INPUT_TIMER 101
...
afx_msg void OnTimer(UINT uTime);
...
cpp:
BEGIN_MESSAGE_MAP(CDialogExInput, CDialogEx)
ON_WM_TIMER()
END_MESSAGE_MAP()
void CDialogExInput::OnTimer(UINT uTime)
{
timeElapsedSec--;
}
BOOL CDialogExInput::OnInitDialog()
{
SetTimer(ID_INPUT_TIMER,1000,NULL);
return true;
}
Code InputYesNoDlg
cpp:
IMPLEMENT_DYNAMIC(InputYesNoDlg, CDialogExInput)
...
BOOL InputYesNoDlg::OnInitDialog()
{
return CDialogExInput::OnInitDialog();
}
...

C++ MFC MDI View rendering

in my application, i currently have 2 document types. The one i will be focusing on, will be the second. My application is a 3d engine editor, which is build in MFC MDI. The first document is the render window, which works perfect, because it's simple to extract the hwnd of it, and then send it to my graphics class. But my second window, which is scripting, is supposed (for now) just to have a rich edit. But for some reason, it doesn't render(actually it does, but only once :/).
CEditorScriptView.h
#pragma once
#include "CEditorDoc.h"
class CCEditorCntrItem;
class CCEditorScriptView : public CView
{
public: // create from serialization only
CCEditorScriptView();
DECLARE_DYNCREATE(CCEditorScriptView)
// Attributes
public:
CCEditorDoc* GetDocument() const;
static CCEditorScriptView * GetView();
// m_pSelection holds the selection to the current CCEditorCntrItem.
// For many applications, such a member variable isn't adequate to
// represent a selection, such as a multiple selection or a selection
// of objects that are not CCEditorCntrItem objects. This selection
// mechanism is provided just to help you get started
// TODO: replace this selection mechanism with one appropriate to your app
CCEditorCntrItem* m_pSelection;
CRichEditCtrl* m_rEdit;
int TYPE;
// Operations
public:
// Overrides
public:
virtual void OnDraw(CDC* pDC); // overridden to draw this view
virtual BOOL PreCreateWindow(CREATESTRUCT& cs);
protected:
virtual void OnInitialUpdate(); // called first time after construct
virtual BOOL IsSelected(const CObject* pDocItem) const;// Container support
// Implementation
public:
virtual ~CCEditorScriptView();
#ifdef _DEBUG
virtual void AssertValid() const;
virtual void Dump(CDumpContext& dc) const;
#endif
protected:
// Generated message map functions
protected:
afx_msg void OnDestroy();
afx_msg void OnSetFocus(CWnd* pOldWnd);
afx_msg void OnSize(UINT nType, int cx, int cy);
afx_msg void OnInsertObject();
afx_msg void OnCancelEditCntr();
afx_msg void OnFilePrint();
afx_msg void OnFilePrintPreview();
afx_msg void OnRButtonUp(UINT nFlags, CPoint point);
afx_msg void OnContextMenu(CWnd* pWnd, CPoint point);
DECLARE_MESSAGE_MAP()
};
#ifndef _DEBUG // debug version in CEditorView.cpp
inline CCEditorDoc* CCEditorScriptView::GetDocument() const
{ return reinterpret_cast<CCEditorDoc*>(m_pDocument); }
#endif
CEditorScriptView.cpp:
#include "stdafx.h"
// SHARED_HANDLERS can be defined in an ATL project implementing preview, thumbnail
// and search filter handlers and allows sharing of document code with that project.
#ifndef SHARED_HANDLERS
#include "CEditor.h"
#endif
#include "CEditorDoc.h"
#include "CntrItem.h"
#include "resource.h"
#ifdef _DEBUG
#define new DEBUG_NEW
#endif
// CCEditorView
#pragma region CCEditorScriptView
IMPLEMENT_DYNCREATE(CCEditorScriptView, CView)
BEGIN_MESSAGE_MAP(CCEditorScriptView, CView)
ON_WM_DESTROY()
ON_WM_SETFOCUS()
ON_WM_SIZE()
ON_COMMAND(ID_OLE_INSERT_NEW, &CCEditorScriptView::OnInsertObject)
ON_COMMAND(ID_CANCEL_EDIT_CNTR, &CCEditorScriptView::OnCancelEditCntr)
ON_COMMAND(ID_FILE_PRINT, &CCEditorScriptView::OnFilePrint)
ON_WM_CONTEXTMENU()
ON_WM_RBUTTONUP()
END_MESSAGE_MAP()
// CCEditorView construction/destruction
CCEditorScriptView::CCEditorScriptView()
{
EnableActiveAccessibility();
m_pSelection = NULL;
// TODO: add construction code here
m_rEdit->Create(WS_CHILD|WS_VISIBLE|WS_BORDER|ES_MULTILINE,
CRect(10,10,500,500), this, 1);
//m_rEdit->SetFocus();
TYPE = ID_CEDITOR_VIEW_SCRIPT;
}
CCEditorScriptView::~CCEditorScriptView()
{
}
BOOL CCEditorScriptView::PreCreateWindow(CREATESTRUCT& cs)
{
// TODO: Modify the Window class or styles here by modifying
// the CREATESTRUCT cs
return CView::PreCreateWindow(cs);
}
// CCEditorView drawing
void CCEditorScriptView::OnDraw(CDC* pDC)
{
if (!pDC)
return;
CCEditorDoc* pDoc = GetDocument();
ASSERT_VALID(pDoc);
if (!pDoc)
return;
// TODO: add draw code for native data here
// TODO: also draw all OLE items in the document
// Draw the selection at an arbitrary position. This code should be
// removed once your real drawing code is implemented. This position
// corresponds exactly to the rectangle returned by CCEditorCntrItem,
// to give the effect of in-place editing.
// TODO: remove this code when final draw code is complete.
m_rEdit->UpdateWindow();
if (m_pSelection != NULL)
{
CSize size;
CRect rect(10, 10, 210, 210);
if (m_pSelection->GetExtent(&size, m_pSelection->m_nDrawAspect))
{
pDC->HIMETRICtoLP(&size);
rect.right = size.cx + 10;
rect.bottom = size.cy + 10;
}
m_pSelection->Draw(pDC, rect);
}
}
// MDI view implementation file
CCEditorScriptView * CCEditorScriptView::GetView()
{
CMDIChildWnd * pChild =
((CMDIFrameWnd*)(AfxGetApp()->m_pMainWnd))->MDIGetActive();
if ( !pChild )
return NULL;
CView * pView = pChild->GetActiveView();
if ( !pView )
return NULL;
// Fail if view is of wrong kind
/*if ( ! pView->IsKindOf( RUNTIME_CLASS(CCEditorRenderView) ) )
return NULL;*/
return (CCEditorScriptView *) pView;
}
void CCEditorScriptView::OnInitialUpdate()
{
CView::OnInitialUpdate();
// TODO: remove this code when final selection model code is written
m_pSelection = NULL; // initialize selection
}
void CCEditorScriptView::OnDestroy()
{
// Deactivate the item on destruction; this is important
// when a splitter view is being used
COleClientItem* pActiveItem = GetDocument()->GetInPlaceActiveItem(this);
if (pActiveItem != NULL && pActiveItem->GetActiveView() == this)
{
pActiveItem->Deactivate();
ASSERT(GetDocument()->GetInPlaceActiveItem(this) == NULL);
}
CView::OnDestroy();
}
// OLE Client support and commands
BOOL CCEditorScriptView::IsSelected(const CObject* pDocItem) const
{
// The implementation below is adequate if your selection consists of
// only CCEditorCntrItem objects. To handle different selection
// mechanisms, the implementation here should be replaced
// TODO: implement this function that tests for a selected OLE client item
return pDocItem == m_pSelection;
}
void CCEditorScriptView::OnInsertObject()
{
// Invoke the standard Insert Object dialog box to obtain information
// for new CCEditorCntrItem object
COleInsertDialog dlg;
if (dlg.DoModal() != IDOK)
return;
BeginWaitCursor();
CCEditorCntrItem* pItem = NULL;
TRY
{
// Create new item connected to this document
CCEditorDoc* pDoc = GetDocument();
ASSERT_VALID(pDoc);
pItem = new CCEditorCntrItem(pDoc);
ASSERT_VALID(pItem);
// Initialize the item from the dialog data
if (!dlg.CreateItem(pItem))
AfxThrowMemoryException(); // any exception will do
ASSERT_VALID(pItem);
if (dlg.GetSelectionType() == COleInsertDialog::createNewItem)
pItem->DoVerb(OLEIVERB_SHOW, this);
ASSERT_VALID(pItem);
// As an arbitrary user interface design, this sets the selection
// to the last item inserted
// TODO: reimplement selection as appropriate for your application
m_pSelection = pItem; // set selection to last inserted item
pDoc->UpdateAllViews(NULL);
}
CATCH(CException, e)
{
if (pItem != NULL)
{
ASSERT_VALID(pItem);
pItem->Delete();
}
AfxMessageBox(IDP_FAILED_TO_CREATE);
}
END_CATCH
EndWaitCursor();
}
// The following command handler provides the standard keyboard
// user interface to cancel an in-place editing session. Here,
// the container (not the server) causes the deactivation
void CCEditorScriptView::OnCancelEditCntr()
{
// Close any in-place active item on this view.
COleClientItem* pActiveItem = GetDocument()->GetInPlaceActiveItem(this);
if (pActiveItem != NULL)
{
pActiveItem->Close();
}
ASSERT(GetDocument()->GetInPlaceActiveItem(this) == NULL);
}
// Special handling of OnSetFocus and OnSize are required for a container
// when an object is being edited in-place
void CCEditorScriptView::OnSetFocus(CWnd* pOldWnd)
{
COleClientItem* pActiveItem = GetDocument()->GetInPlaceActiveItem(this);
if (pActiveItem != NULL &&
pActiveItem->GetItemState() == COleClientItem::activeUIState)
{
// need to set focus to this item if it is in the same view
CWnd* pWnd = pActiveItem->GetInPlaceWindow();
if (pWnd != NULL)
{
pWnd->SetFocus(); // don't call the base class
return;
}
}
CView::OnSetFocus(pOldWnd);
}
void CCEditorScriptView::OnSize(UINT nType, int cx, int cy)
{
CView::OnSize(nType, cx, cy);
COleClientItem* pActiveItem = GetDocument()->GetInPlaceActiveItem(this);
if (pActiveItem != NULL)
pActiveItem->SetItemRects();
}
void CCEditorScriptView::OnFilePrint()
{
//By default, we ask the Active document to print itself
//using IOleCommandTarget. If you don't want this behavior
//remove the call to COleDocObjectItem::DoDefaultPrinting.
//If the call fails for some reason, we will try printing
//the docobject using the IPrint interface.
CPrintInfo printInfo;
ASSERT(printInfo.m_pPD != NULL);
if (S_OK == COleDocObjectItem::DoDefaultPrinting(this, &printInfo))
return;
CView::OnFilePrint();
}
void CCEditorScriptView::OnRButtonUp(UINT /* nFlags */, CPoint point)
{
ClientToScreen(&point);
OnContextMenu(this, point);
}
void CCEditorScriptView::OnContextMenu(CWnd* /* pWnd */, CPoint point)
{
#ifndef SHARED_HANDLERS
theApp.GetContextMenuManager()->ShowPopupMenu(IDR_POPUP_EDIT, point.x, point.y, this, TRUE);
#endif
}
// CCEditorView diagnostics
#ifdef _DEBUG
void CCEditorScriptView::AssertValid() const
{
CView::AssertValid();
}
void CCEditorScriptView::Dump(CDumpContext& dc) const
{
CView::Dump(dc);
}
CCEditorDoc* CCEditorScriptView::GetDocument() const // non-debug version is inline
{
ASSERT(m_pDocument->IsKindOf(RUNTIME_CLASS(CCEditorDoc)));
return (CCEditorDoc*)m_pDocument;
}
#pragma endregion
#endif //_DEBUG
// CCEditorView message handlers
And this is currently what it outputs:
Now is seems ok, but it only renders it once, meaning if I would click on it(richEdit) nothing would happen, or if I tried to type in the richEdit, nothing would happen as well. So I'm wondering, why? Why doesn't it continue rendering, or updating the view?
Thank You
PS. If you wan't me to post anything, like code, please comment.
So, it seems that I've solved my problem, here's the solution:
I looked at the console and noticed that the window had failed to create. And i came to the solution that the m_rEdit was the fault(by testing). So i figured out that i had to initialize the pointer in the constructor, and use the m_rEdit->Create in the OnInitialUpdate(). And that fixed it.
Anyways, thank you for anyone who tried to solve this mystery.

Where I can define a global variable in an MFC application?

I want to declare a global variable inside an MFC application, so that every action inside the application can see this variable and manipulate it, but I don't know where exactly I can declare that variable. in this code i have many button actions, i need to declare a string variable that's shared among this actions.
// CalculatorDlg.cpp : implementation file
//
#include "stdafx.h"
#include "Calculator.h"
#include "CalculatorDlg.h"
#ifdef _DEBUG
#define new DEBUG_NEW
#endif
// CAboutDlg dialog used for App About
class CAboutDlg : public CDialog
{
public:
CAboutDlg();
// Dialog Data
enum { IDD = IDD_ABOUTBOX };
public:
static CString myValue;
protected:
virtual void DoDataExchange(CDataExchange* pDX); // DDX/DDV support
// Implementation
protected:
DECLARE_MESSAGE_MAP()
};
CAboutDlg::CAboutDlg() : CDialog(CAboutDlg::IDD) {}
void CAboutDlg::DoDataExchange(CDataExchange* pDX){
CDialog::DoDataExchange(pDX);
}
BEGIN_MESSAGE_MAP(CAboutDlg, CDialog)
END_MESSAGE_MAP()
// CCalculatorDlg dialog
CCalculatorDlg::CCalculatorDlg(CWnd* pParent /*=NULL*/)
: CDialog(CCalculatorDlg::IDD, pParent)
{
m_hIcon = AfxGetApp()->LoadIcon(IDR_MAINFRAME);
}
void CCalculatorDlg::DoDataExchange(CDataExchange* pDX)
{
CDialog::DoDataExchange(pDX);
}
BEGIN_MESSAGE_MAP(CCalculatorDlg, CDialog)
ON_WM_SYSCOMMAND()
ON_WM_PAINT()
ON_WM_QUERYDRAGICON()
//}}AFX_MSG_MAP
ON_BN_CLICKED(IDC_BUTTON1, &CCalculatorDlg::OnBnClickedButton1)
ON_BN_CLICKED(IDC_BUTTON3, &CCalculatorDlg::OnBnClickedButton3)
ON_BN_CLICKED(IDC_BUTTON2, &CCalculatorDlg::OnBnClickedButton2)
ON_BN_CLICKED(IDC_BUTTON6, &CCalculatorDlg::OnBnClickedButton6)
ON_BN_CLICKED(IDC_BUTTON5, &CCalculatorDlg::OnBnClickedButton5)
ON_BN_CLICKED(IDC_BUTTON4, &CCalculatorDlg::OnBnClickedButton4)
ON_BN_CLICKED(IDC_BUTTON9, &CCalculatorDlg::OnBnClickedButton9)
ON_BN_CLICKED(IDC_BUTTON8, &CCalculatorDlg::OnBnClickedButton8)
ON_BN_CLICKED(IDC_BUTTON7, &CCalculatorDlg::OnBnClickedButton7)
END_MESSAGE_MAP()
// CCalculatorDlg message handlers
BOOL CCalculatorDlg::OnInitDialog()
{
CDialog::OnInitDialog();
// Add "About..." menu item to system menu.
// IDM_ABOUTBOX must be in the system command range.
ASSERT((IDM_ABOUTBOX & 0xFFF0) == IDM_ABOUTBOX);
ASSERT(IDM_ABOUTBOX < 0xF000);
CMenu* pSysMenu = GetSystemMenu(FALSE);
if (pSysMenu != NULL)
{
CString strAboutMenu;
strAboutMenu.LoadString(IDS_ABOUTBOX);
if (!strAboutMenu.IsEmpty())
{
pSysMenu->AppendMenu(MF_SEPARATOR);
pSysMenu->AppendMenu(MF_STRING, IDM_ABOUTBOX, strAboutMenu);
}
}
// Set the icon for this dialog. The framework does this automatically
// when the application's main window is not a dialog
SetIcon(m_hIcon, TRUE); // Set big icon
SetIcon(m_hIcon, FALSE); // Set small icon
// TODO: Add extra initialization here
return TRUE; // return TRUE unless you set the focus to a control
}
void CCalculatorDlg::OnSysCommand(UINT nID, LPARAM lParam)
{
if ((nID & 0xFFF0) == IDM_ABOUTBOX)
{
CAboutDlg dlgAbout;
dlgAbout.DoModal();
}
else
{
CDialog::OnSysCommand(nID, lParam);
}
}
// If you add a minimize button to your dialog, you will need the code below
// to draw the icon. For MFC applications using the document/view model,
// this is automatically done for you by the framework.
void CCalculatorDlg::OnPaint()
{
if (IsIconic())
{
CPaintDC dc(this); // device context for painting
SendMessage(WM_ICONERASEBKGND, reinterpret_cast<WPARAM>(dc.GetSafeHdc()), 0);
// Center icon in client rectangle
int cxIcon = GetSystemMetrics(SM_CXICON);
int cyIcon = GetSystemMetrics(SM_CYICON);
CRect rect;
GetClientRect(&rect);
int x = (rect.Width() - cxIcon + 1) / 2;
int y = (rect.Height() - cyIcon + 1) / 2;
// Draw the icon
dc.DrawIcon(x, y, m_hIcon);
}
else
{
CDialog::OnPaint();
}
}
// The system calls this function to obtain the cursor to display while the user drags
// the minimized window.
HCURSOR CCalculatorDlg::OnQueryDragIcon()
{
return static_cast<HCURSOR>(m_hIcon);
}
void CCalculatorDlg::OnBnClickedButton1()
{
/*
CString s="ABC";
LPCTSTR str_name = _T("Hello ")*/;
SetDlgItemText(IDC_EDIT1,_T"9");
/*CAboutDlg::myValue="9";*/
}
void CCalculatorDlg::OnBnClickedButton3(){}
void CCalculatorDlg::OnBnClickedButton2(){}
void CCalculatorDlg::OnBnClickedButton6(){}
void CCalculatorDlg::OnBnClickedButton5(){}
void CCalculatorDlg::OnBnClickedButton4(){}
void CCalculatorDlg::OnBnClickedButton9(){}
void CCalculatorDlg::OnBnClickedButton8(){}
void CCalculatorDlg::OnBnClickedButton7(){}
If your project uses precompiled headers (with 99.9999% probability it uses it as default MFC project setting), you can declare this variable in precompiled header file, typically its name is stdafx.h and define it in global scope of any appropriate translation unit (.cpp file). Typically this could be YourProjectName.cpp file that contains application class derived from CWinApp.
// stdafx.h
extern int globalVar; // Global variable declaration, note extern keyword
// YourProjectName.cpp - global scope
int globalVar = 42; // Global variable definition
Precompiled header stdafx.h is included first in every .cpp file of project, so globalVar will be available everywhere in your project code.
Also would like to mention that global objects are not recommended to be used, it's considered as bad design and anti-pattern.
Put the global variable in a header file and add it to Name Forced Include File.