设置日历的尺寸覆盖的DateTimePicker添加周数时(Setting calendar siz

2019-07-18 19:47发布

我试图创建DateTimePicker ,其中显示,星期数如下所示(代码项目的例子) 。

它的工作原理相当不错,除了一个小细节; 轧光机弹出时,试图选择一个日期是不正确的大小。 正如你可以看到,历面积是有点“拥挤”,特别是沿右边缘。

我在这里可以点击右下角,将其拖出了一点 - 只要足够使其看起来正确,扩展它:

我似乎无法找到任何办法强迫日历是从一开始就正确/全尺寸,或调整其大小。 任何想法将不胜感激。

Answer 1:

最后发现,似乎工作的解决方案 - 至少目前是这样。

它似乎有在日历部分两个窗口DateTimePicker 。 显然,我的代码会自动找到内一个(或多或少至少?)正确的尺寸,而不是外部的。

研究有点导致了下面的代码。 下面的链接提供了一些有用的相关信息:

  • GetWindowLong功能 (用于获取有关编辑窗口信息)
  • 功能的getParent (寻找外窗,所以我们可以设置应用到太)

诀窍是一点点添加到(内)窗口的高度和宽度,然后将相同的高度和宽度与外窗(我访问使用GetParrent()函数)。 我通过反复试验发现了“正确”的大小:当大小匹配,需要什么样的日历的内容,它不能被调整下去。

是的,这感觉有点像一个黑客,没有,我一直无法验证它完美的作品就比我的其他电脑呢。 我有点担心不必给出具体的值的高度和宽度,但我希望这不会被屏幕分辨率或其他任何影响。

希望其他人在类似情况下会发现代码中非常有用。
以下可以直接取代常规DateTimePicker显示日历中的周数

using System;
using System.ComponentModel;
using System.Drawing;
using System.Runtime.InteropServices;
using System.Windows.Forms;

public class DatePickerWithWeekNumbers : DateTimePicker
{
    [DllImport("User32.dll")]
    private static extern int GetWindowLong(IntPtr handleToWindow, 
                                            int offsetToValueToGet);

    [DllImport("User32.dll")]
    private static extern int SetWindowLong(IntPtr h, 
                                            int index, 
                                            int value);

    private const int McmFirst = 0x1000;
    private const int McmGetminreqrect = (McmFirst + 9);
    private const int McsWeeknumbers = 0x4;
    private const int DtmFirst = 0x1000;
    private const int DtmGetmonthcal = (DtmFirst + 8);


    [DllImport("User32.dll")]
    private static extern IntPtr SendMessage(IntPtr h,
                                             int msg, 
                                             int param, 
                                             int data);

    [DllImport("User32.dll")]
    private static extern IntPtr GetParent(IntPtr h);

    [DllImport("User32.dll")]
    private static extern int SendMessage(IntPtr h, 
                                          int msg,
                                          int param, 
                                          ref Rectangle data);

    [DllImport("User32.dll")]
    private static extern int MoveWindow(IntPtr h, 
                                         int x, 
                                         int y,
                                         int width, 
                                         int height, 
                                         bool repaint);

    [Browsable(true), DesignerSerializationVisibility(
        DesignerSerializationVisibility.Visible)]
    public bool DisplayWeekNumbers { get; set; }

    protected override void OnDropDown(EventArgs e)
    {
        // Hex value to specify that we want the style-attributes
        // for the window:
        const int offsetToGetWindowsStyles = (-16);

        IntPtr pointerToCalenderWindow = SendMessage(Handle, 
                                                     DtmGetmonthcal,  
                                                     0,  
                                                     0);
        int styleForWindow = GetWindowLong(pointerToCalenderWindow, 
                                           offsetToGetWindowsStyles);

        // Check properties for the control - matches available 
        // property in the graphical properties for the DateTimePicker:
        if (DisplayWeekNumbers)
        {
            styleForWindow = styleForWindow | McsWeeknumbers;
        }
        else
        {
            styleForWindow = styleForWindow & ~McsWeeknumbers;
        }

        // Get the size needed to display the calendar (inner window)
        var rect = new Rectangle();
        SendMessage(pointerToCalenderWindow, McmGetminreqrect, 0, ref rect);

        // Add to size as needed (I don't know why 
        // this was not correct initially!)
        rect.Width = rect.Width + 28;
        rect.Height = rect.Height + 6;

        // Set window styles..
        SetWindowLong(pointerToCalenderWindow, 
                      offsetToGetWindowsStyles, 
                      styleForWindow);

        // Dont move the window - just resize it as needed:
        MoveWindow(pointerToCalenderWindow, 
                   0, 
                   0, 
                   rect.Right, 
                   rect.Bottom, 
                   true);

        // Now access the parrent window..
        var parentWindow = GetParent(pointerToCalenderWindow);
        // ...and resize that the same way:
        MoveWindow(parentWindow, 0, 0, rect.Right, rect.Bottom, true);

        base.OnDropDown(e);
    }
}


Answer 2:

好了,试评行的Program.cs

Application.EnableVisualStyles();

然后尝试执行。



文章来源: Setting calendar size when overriding DateTimePicker to add week numbers