CMonthCalCtrl 日历页脚文本(今天日期)

Posted

技术标签:

【中文标题】CMonthCalCtrl 日历页脚文本(今天日期)【英文标题】:CMonthCalCtrl calendar footer text (today date) 【发布时间】:2020-02-12 15:26:35 【问题描述】:

我正在尝试自定义 CMonthCalCtrl,但我不明白如何获取页脚文本(用于导航到“今天”日期的文本):

我尝试使用带有MCGIP_FOOTERMCGIF_NAME 标志的GetCalendarGridInfo 函数,但它不返回字符串:

    CString cText;
    MCGRIDINFO mcFooterInfo =  sizeof(MCGRIDINFO) ;
    mcFooterInfo.dwPart = MCGIP_FOOTER;
    mcFooterInfo.dwFlags = MCGIF_NAME;
    mcFooterInfo.pszName = cText.GetBuffer(_MAX_PATH);
    mcFooterInfo.cchName = _MAX_PATH;
    GetCalendarGridInfo(&mcFooterInfo);

    // at this point mcFooterInfo.pszName contains "9" instead of "Сегодня: 12.02.2020"

这将返回“9”而不是页脚文本。

我不能自己格式化日期,因为我需要支持当前的用户语言,并且我需要知道如何拼写“今天:”部分。

有人知道怎么解决吗?

【问题讨论】:

dwPart 请求 MCGIF_NAME MCGIP_FOOTER does not appear to be supported。 另外,请务必注意GetCalendarGridInfo() 的返回值。如果返回 FALSE,cText 的内容将是未定义的。 "我需要知道如何拼写 "Today:" 部分" - 根据documentation: "月份-日历控件获取它的格式和所有字符串来自 LOCALE_USER_DEFAULT.”,因此可以只从语言环境中查询“Today”字符串本身,而无需询问 MonthCal 控件。除了according to this,“Today”字符串的本地化方式与其余 MonthCal 字符串的本地化方式不同。所以你可能是这方面的 SOL。 不清楚您到底想定制什么。看起来不像Сегодня。如果只是日期算today,请看docs.microsoft.com/en-us/cpp/mfc/reference/… API 是 GetLocaleInfoEx(),但我认为它没有办法查询“今天”或“明天”等的翻译 - 只有一周中的几天等。 【参考方案1】:

我将分享一种获取该文本的方法,即使我不会使用它,也不建议其他人使用它。

我发现this topic 描述了获取本地化 Windows 字符串的方式。我开始使用它,发现ComCtl32.dll 包含似乎是日历控件使用的资源字符串。包含“Today:”字符串的资源具有ID: 4432。但这不是文档区域,因此没有人可以依赖它,并且可能会因版本而异。

但是,这里是获取不同语言的“Today:”字符串的代码示例:

    GetTodayString(GetUserDefaultUILanguage()); // Сегодня:
    GetTodayString(MAKELANGID(LANG_ENGLISH, SUBLANG_DEFAULT)); // Today:
    GetTodayString(MAKELANGID(LANG_FRENCH, SUBLANG_DEFAULT)); // Aujourd’hui :
    GetTodayString(MAKELANGID(LANG_GERMAN, SUBLANG_DEFAULT)); // Heute:
    GetTodayString(MAKELANGID(LANG_SPANISH, SUBLANG_SPANISH_MODERN)); // Hoy:
    GetTodayString(MAKELANGID(LANG_UKRAINIAN, SUBLANG_DEFAULT)); // Сьогодні:

    CString GetTodayString(LANGID langId)
    
        HMODULE hComCtl32 = LoadLibrary(_T("comctl32.dll"));
        if (!hComCtl32)
            return _T("");

        UINT nResourceId = 4432; // I don't think that anyone should rely on this
        CString cResourceStr = FindStringResourceEx(hComCtl32, nResourceId, langId);

        FreeLibrary(hComCtl32);

        int delimiterIdx = cResourceStr.Find(_T('\x6'));
        CString cTodayStr = cResourceStr.Left(delimiterIdx);

        return cTodayStr;
    

    CString FindStringResourceEx(HINSTANCE hinst, UINT uId, UINT langId)
    
        // Convert the string ID into a bundle number
        LPCWSTR pwsz = NULL;
        HRSRC hrsrc = FindResourceEx(hinst, RT_STRING,
            MAKEINTRESOURCE(uId / 16 + 1),
            langId);
        if (hrsrc) 
            HGLOBAL hglob = LoadResource(hinst, hrsrc);
            if (hglob) 
                pwsz = reinterpret_cast<LPCWSTR>
                    (LockResource(hglob));
                if (pwsz) 
                    // okay now walk the string table
                    for (int i = 0; i < (uId & 15); i++) 
                        pwsz += 1 + (UINT)*pwsz;
                    

                    pwsz += 1;
                
            
        
        return CString(pwsz);
    

正如我所说,我不会使用这种方法,可能我会简单地省略“今天:”文本并仅在页脚中显示格式化的今天日期。

【讨论】:

以上是关于CMonthCalCtrl 日历页脚文本(今天日期)的主要内容,如果未能解决你的问题,请参考以下文章

p:今天的日历按钮

如何使用今天的日期预先填充 jQuery Datepicker 文本框?

如何在默认情况下停止 datetimepicker 在文本框中设置今天的日期 onclick

jquery日历插件问题

vb编程里,如何实现点击窗体中一个文本框出现日历控件,然后可以选择相应的日期,填入文本框,日历控件消失?

如何在我的完整日历议程中显示今天的日期