为MinDate属性指定了一个大于MaxDate当前值的值

    单位一应用软件,在一台电脑上运行某功能时提示“为MinDate属性指定了一个大于MaxDate当前值的值”,在其它电脑使用都正常。

    经查询发现“为MinDate属性指定了一个大于MaxDate当前值的值” 提示是微软DTPicker控件的提示。表示为该控件MinDate属性设置值时大于了该控件MaxDate设置的值。

    观察正常电脑上的情况,该控件MinDate会设置为从数据库中取出的一个值,MaxDate会设置为当前时间。

    为啥就这台电脑会出错呢?没有思路直接重装机器,我晕,还是同样故障。

   根据 https://support.microsoft.com/zh-cn/kb/198880内容发现设置这两个属性时会调用SendMessage给该控件发送消息。

 

/*
当试图设置 MinDate 或 MaxDate 属性时,SendMessage API 的调用会将"DTM_SETRANGE"消息发送到该控件以通知其新的日期范围设置。
此消息有三种设置方式(wParam):
只设置最小日期,不设置最大日期。
只设置最大日期,不设置最小日期。
同时设置最小日期和最大日期。

lParam
必须设置为指向一个两元素数组,数组元素为SYSTEMTIME 结构。
第一个元素用于指定最小日期信息,第二个元素用于指定最大日期信息。

创建一个新的标准 EXE 项目。默认情况下创建 Form1。
从 项目 菜单中选择 引用 选择"Microsoft Windows 公共控件-2 6.0",然后单击确定。
向 Form1 中添加一个 DTPicker 控件。
向 Form1 中添加五个命令按钮。

从 项目 菜单中选择 添加模块 并添加到项目的标准模块。
将以下代码粘贴到模块:
*/
      Option Explicit

      Public Type SYSTEMTIME
         wYear As Integer
         wMonth As Integer
         wDayOfWeek As Integer
         wDay As Integer
         wHour As Integer
         wMinute As Integer
         wSecond As Integer
         wMilliseconds As Integer
      End Type

      Public Declare Function SendMessage Lib "user32" Alias _
         "SendMessageA" (ByVal hwnd As Long, ByVal wMsg As Long, _
         ByVal wParam As Long, lParam As Any) As Long

      Public Const DTM_SETRANGE = &H1004&
      Public Const GDTR_MIN = 1
      Public Const GDTR_MAX = 2


'将以下代码粘贴到 Form1 的代码窗口:

   Option Explicit

   Private Sub Command1_Click()
      ' Set DTPicker MinDate through normal means.
      Me.DTPicker1.MinDate = "1/10/99"
   End Sub

   Private Sub Command2_Click()
      'Set DTPicker MaxDate through normal means.
      Me.DTPicker1.MaxDate = "1/17/99"
   End Sub

   Private Sub Command3_Click()
      Dim TimeArray(1) As SYSTEMTIME
      Dim result As Long

      ' Define first element of SYSTEMTIME Array to be minimum date.
      TimeArray(0).wDay = 10
      TimeArray(0).wMonth = 1
      TimeArray(0).wYear = 1999

      ' Call API to send message to control to set MinDate.
      result = SendMessage(Me.DTPicker1.hwnd, DTM_SETRANGE, _
         GDTR_MIN, TimeArray(0))
   End Sub

   Private Sub Command4_Click()
      Dim TimeArray(1) As SYSTEMTIME
      Dim result As Long

      ' Define second element of SYSTEMTIME Array to be maximum date.
      TimeArray(1).wDay = 17
      TimeArray(1).wMonth = 1
      TimeArray(1).wYear = 1999

      ' Call API to send message to control to set MaxDate.
      result = SendMessage(Me.DTPicker1.hwnd, DTM_SETRANGE, _
         GDTR_MAX, TimeArray(0))
   End Sub

   Private Sub Command5_Click()
      Dim TimeArray(1) As SYSTEMTIME
      Dim result As Long

      ' Define first element of SYSTEMTIME Array to be minimum date.
      TimeArray(0).wDay = 10
      TimeArray(0).wMonth = 1
      TimeArray(0).wYear = 1999

      ' Define second element of SYSTEMTIME Array to be maximum date.
      TimeArray(1).wDay = 17
      TimeArray(1).wMonth = 1
      TimeArray(1).wYear = 1999

      ' Call API to send message to control to set MinDate and MaxDate.
      result = SendMessage(Me.DTPicker1.hwnd, DTM_SETRANGE, _
         GDTR_MIN + GDTR_MAX, TimeArray(0))
   End Sub

   Private Sub Form_Load()
      Me.Command1.Caption = "Set DTPicker MinDate Normally"
      Me.Command2.Caption = "Set DTPicker MaxDate Normally"
      Me.Command3.Caption = "Set DTPicker MinDate Via API"
      Me.Command4.Caption = "Set DTPicker MaxDate Via API"
      Me.Command5.Caption = "Set DTPicker Min and MaxDate Via API"
   End Sub

    上windbg调试器,设置断点:

    bp User32!SendMessageA ".if(poi(esp+8) == 0x00001004) {} .else {gc}"

    表示当调用SendMessageA函数并且第二个参数(消息类型)是0x00001004(DTM_SETRANGE消息)时中断,否则继续执行。

跟踪到一个结果如下:

0:000> g
eax=0012d700 ebx=03e93744 ecx=00120024 edx=00000006 esi=03e93780 edi=0012d710
eip=77d2f3c2 esp=0012d6e0 ebp=0012d720 iopl=0         nv up ei pl nz na po nc
cs=001b  ss=0023  ds=0023  es=0023  fs=003b  gs=0000             efl=00000202
USER32!SendMessageA:
77d2f3c2 8bff            mov     edi,edi
0:000> dd esp
0012d6e0  277d48d8 00050a50 00001004 00000003
0012d6f0  0012d700 00000000 0012d97c 277ca680
0012d700  00010641 00010001 00000000 00000000
0012d710  000707df 000d0001 0006000f 00000024
0012d720  0012d740 77105cd9 03e93744 258bf259
0012d730  00000001 0012d774 0ffaa4dc 0012d734
0012d740  0012d7d0 771062e8 03e93744 00000094
0012d750  00000004 0000000a 00000001 002097d4

可以看到第一个参数00050a50表示控件的hwnd,第二个参数00001004表示消息,第三个参数00000003表示同时设置mindate和maxdate,第四个参数0012d700是SYSTEMTIME结构数组地址。
0012d700地址行正好是mindate所有参数,00010641表示年月(interger类型为16位),0641表示1601年,0001表示1月,
0012d710地址行正好是maxdate所有参数,000707df表示年月(interger类型为16位),07df  表示2015年,0007表示7月,000d0001中的000d表示日13号。

等等,不对呀,今天应该是23号的。
在看系统时间,完了,果然是2015年7月13日。这就对了,前面说过“该控件MinDate会设置为从数据库中取出的一个值,MaxDate会设置为当前时间",
数据库中记录的值一定小于当前时间。系统时间设置过小了直接导致小于数据库中的时间。因此出错了。
本来以为当前时间会从数据库中取的,结果是这样。

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值