callback fields of DateTimePicker (Handling of DTN_FORMAT)

R

reddog

The System.Windows.Forms.DateTimePicker doesn't support a callback fields at
a custom format. I need to use it, so tring to implement it.

I made a new NewDTP class inherited DateTimePicker, and override WndProc
and handled DTN_FORMAT, DTN_FORMATQUERY and DTN_WMKEYDOWN
messages. But The callback fields was shown empty. could you help me?

It seems to me that DTN_FORMAT handling has something problem.

This is a entire project file.
http://reddog.s35.xrea.com/software/NewDTPTest.zip

This is a NewDTP class I wrote.

namespace NewDTPTest {
using System;
using System.Windows.Forms;
using System.Drawing;
using System.Runtime.InteropServices;
using System.ComponentModel;
using System.Diagnostics;

public class NewDTP : DateTimePicker {
#region Win32 Defines
private const int WM_NOTIFY = 0x004e;
private const int WM_REFLECT = 0x2000;
private const int DTN_FORMAT = -743;
private const int DTN_FORMATQUERY = -742;
private const int DTN_WMKEYDOWN = -744;

[StructLayout(LayoutKind.Sequential)]
protected struct NMHDR {
public IntPtr hwndFrom;
public IntPtr idFrom;
public int code;
}

[StructLayout(LayoutKind.Sequential)]
protected struct SIZE {
public long cx;
public long cy;
}

[StructLayout(LayoutKind.Sequential)]
protected struct SYSTEMTIME {
[MarshalAs(UnmanagedType.I2)]public short wYear;
[MarshalAs(UnmanagedType.I2)]public short wMonth;
[MarshalAs(UnmanagedType.I2)]public short wDayOfWeek;
[MarshalAs(UnmanagedType.I2)]public short wDay;
[MarshalAs(UnmanagedType.I2)]public short wHour;
[MarshalAs(UnmanagedType.I2)]public short wMinute;
[MarshalAs(UnmanagedType.I2)]public short wSecond;
[MarshalAs(UnmanagedType.I2)]public short wMilliseconds;
}

[StructLayout(LayoutKind.Sequential)]
protected struct NMDATETIMEFORMAT {
public NMHDR nmhdr;
public IntPtr pszFormat;
public SYSTEMTIME st;
public IntPtr pszDisplay;
[MarshalAs(UnmanagedType.ByValTStr, SizeConst=64)] public string szDisplay;
}

[StructLayout(LayoutKind.Sequential)]
protected struct NMDATETIMEFORMATQUERY {
public NMHDR nmhdr;
public IntPtr pszFormat;
public SIZE szMax;
}

[StructLayout(LayoutKind.Sequential)]
protected struct NMDATETIMEWMKEYDOWN {
public NMHDR nmhdr;
public int nVirtKey;
public IntPtr pszFormat;
public SYSTEMTIME st;
}
#endregion


public NewDTP():base() {
}

#region Handles


private void WmFormat(ref Message m) {
NMDATETIMEFORMAT nmdatetimeformat =
(NMDATETIMEFORMAT)m.GetLParam(typeof(NMDATETIMEFORMAT));
string format = Marshal.PtrToStringAuto(nmdatetimeformat.pszFormat);
DateTime time = SysTimeToDateTime(nmdatetimeformat.st);

// XXX: Here is the problem. The "ABCD" does not shown in custom fields.
Marshal.Copy("ABCD".ToCharArray(), 0, nmdatetimeformat.pszDisplay, 4);
m.Result = IntPtr.Zero;
}


private void WmFormatQuery(ref Message m) {
NMDATETIMEFORMATQUERY nmdatetimeformatquery =
(NMDATETIMEFORMATQUERY)m.GetLParam(typeof(NMDATETIMEFORMATQUERY));
string format = Marshal.PtrToStringAuto(nmdatetimeformatquery.pszFormat);
IntPtr dst = (IntPtr)(m.LParam.ToInt64() +
Marshal.OffsetOf(typeof(NMDATETIMEFORMATQUERY), "szMax").ToInt64());

// TODO: the Size value is for debugging.
Marshal.Copy(new long[] { 60, 16 }, 0, dst, 2);
m.Result = IntPtr.Zero;
}


private void WmKeyDown(ref Message m) {
NMDATETIMEWMKEYDOWN nmdatetimewmkeydown =
(NMDATETIMEWMKEYDOWN)m.GetLParam(typeof(NMDATETIMEWMKEYDOWN));
string format = Marshal.PtrToStringAuto(nmdatetimewmkeydown.pszFormat);

//TODO: Do Something

m.Result = IntPtr.Zero;
}
#endregion


private DateTime SysTimeToDateTime(SYSTEMTIME st) {
return new DateTime(st.wYear, st.wMonth, st.wDay, st.wHour, st.wMinute,
st.wSecond);
}

/// <summary>
///
/// </summary>
/// <param name="m"></param>
/// <returns>If we handled the message return true, else false</returns>
private bool WmReflectCommand(ref Message m) {
if (m.HWnd == Handle) {
NMHDR nmhdr = (NMHDR)m.GetLParam(typeof(NMHDR));

switch (nmhdr.code) {
case DTN_FORMAT:
WmFormat(ref m);
return true;

case DTN_FORMATQUERY:
WmFormatQuery(ref m);
return true;

case DTN_WMKEYDOWN:
WmKeyDown(ref m);
return true;
}
}
return false;
}


[System.Security.Permissions.PermissionSet(System.Security.Permissions.SecurityAction.Demand, Name = "FullTrust")]
protected override void WndProc(ref Message m) {
switch (m.Msg) {
case WM_REFLECT + WM_NOTIFY:
if (WmReflectCommand(ref m) == false) {
break;
}
return;
}
base.WndProc(ref m);
}

}
}
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Top