使用MCN_GETDAYSTATE事件处理程序和动态MONTHDAYSTATE数组会导致错误

时间:2018-06-21 21:12:07

标签: mfc monthcalendar

这是我遇到的一个有趣的问题。我在import React, { Component } from "react"; import { withStyles } from "@material-ui/core/styles"; const styles = theme => ({ root: { color: "#ff0000", "&:hover": { color: "#0000ff" } } }); class JssTest extends Component { render() { return ( <div> <h1 style={styles("").root}>JSS Test</h1> </div> ); } } //<h1 classes={styles("").root}>JSS Test</h1> //Styles nothing and Renders as //<h1 classes="[object Object]">JSS Test</h1> //<h1 style={styles("").root}>JSS Test</h1> //Renders just the color but not the '&:hover' //<h1 style="color: rgb(255, 0, 0);">JSS Test</h1> //<h1 classes={classes.root}>JSS Test</h1> //get Line 18: 'classes' is not defined no-undef //<h1 classes={styles.root}>JSS Test</h1> //renders as //<h1>JSS Test</h1> export default withStyles(styles)(JssTest); 上使用MCN_GETDAYSTATE事件处理程序已有好几年了。处理程序如下所示:

CMonthCalendarControl

它一直运行良好。窗口中的日历如下所示:

Calendar

现在,在过去的两天内,我已经升级了此窗口以支持调整大小,因此我已经设置了日历以调整大小。示例:

MultipleCalendar

我调整了事件处理程序(因为我们可能有任意数量的日历),如下所示:

void CHomeAwayMaintPage::OnGetDayStateCalendar(NMHDR* pNMHDR, LRESULT* pResult) 
{
    NMDAYSTATE      *pDayState = (NMDAYSTATE*)pNMHDR;
    MONTHDAYSTATE   mdState[3]; // last, this, next
    COleDateTime    datStart(pDayState->stStart);

    if (pDayState != nullptr)
    {
        InitDayStateArray(pDayState->cDayState, mdState, datStart);
        pDayState->prgDayState = mdState;
    }

    *pResult = 0;
}

但是,当我关闭窗口时,VS2017会引发此错误:

Error 1

我试图注释掉void CHomeAwayMaintPage::OnGetDayStateCalendar(NMHDR* pNMHDR, LRESULT* pResult) { NMDAYSTATE *pDayState = (NMDAYSTATE*)pNMHDR; COleDateTime datStart(pDayState->stStart); DWORD dwCount = MonthCal_GetMonthRange(m_Calender.GetSafeHwnd(), GMR_DAYSTATE, NULL); MONTHDAYSTATE *pmdState = new MONTHDAYSTATE[dwCount]; if (pDayState != nullptr) { InitDayStateArray(pDayState->cDayState, pmdState, datStart); pDayState->prgDayState = pmdState; } delete[] pmdState; *pResult = 0; } 行,但没有区别。尝试显示窗口时,我也经常收到此错误:

Error 2

如果我将日历控件的动态布局重置为仅移动控件而不调整其大小(因此一个月可见),并将我的日状态事件处理程序恢复为以前的状态,则这两个错误将消失,像以前一样变得稳定。

那我在做什么错了?

更新

这是delete[] pmdState;方法。只需读取数据库:

InitDayStateArray

1 个答案:

答案 0 :(得分:3)

  

<input type="string" name="mysite_addr" autocomplete="on">

documentation说第三个参数不能为DWORD dwCount = MonthCal_GetMonthRange(m_Calender.GetSafeHwnd(), GMR_DAYSTATE, NULL);

  

指向NULL结构的两元素数组的指针,该数组将接收dwFlag指定的范围的上下限。下限和上限分别位于SYSTEMTIMElprgSysTimeArray[0]中。这些结构的时间成员将不会被修改。此参数必须是有效地址,不能为lprgSysTimeArray[1]

运行代码时,我得到NULLdwCount = 4

结果:

pDayState->cDayState = 395234

请注意,MONTHDAYSTATE *pmdState = new MONTHDAYSTATE[4]; ... InitDayStateArray(...) { iMonthCount = pDayState->cDayState pDayState = pmdState; memset(pDayState, 0, sizeof(MONTHDAYSTATE)*395234); ... } 导致缓冲区溢出memset,这可能会导致严重的问题。

您可以按以下方式重写代码:

(395234 - 4) * sizeof(MONTHDAYSTATE)

更新

基于上面的答案(谢谢)和此处的评论,我能够简化事件处理程序并正确执行操作:

void CHomeAwayMaintPage::OnMcnSelchangeMonthcalendar1(NMHDR *pNMHDR, LRESULT *pResult)
{
    SYSTEMTIME systime[2];
    int month_count = MonthCal_GetMonthRange(m_Calender.GetSafeHwnd(),
            GMR_DAYSTATE, &systime);
    std::vector<MONTHDAYSTATE> vec(month_count); //or use new/delete

    COleDateTime date(systime[0]);
    COleDateTime end(systime[1]);
    COleDateTimeSpan spnDay;
    spnDay.SetDateTimeSpan(1, 0, 0, 0);
    while (date < end)
    {
        CString str = date.Format(_T("%Y-%m-%d"));
        TRACE(_T("datDay %s\n"), str.GetString());
        date = date + spnDay;
    }
    *pResult = 0;
}

Here它说:

  

“它接收提供此数据的数组的地址。”

this让我很困惑,在这里您必须设置缓冲区。

如您所见,传入的结构已经分配了一个缓冲区。我只需要调整值。任何地方都没有内存分配。