Loading ...
Sorry, an error occurred while loading the content.

1777Re: SysMonthCal32 support

Expand Messages
  • brentje
    Apr 20, 2007
    • 0 Attachment
      Let me just jump in before you drive yourself crazy...

      Now my only experience with SysMonthCal32 has been through .Net, but I
      believe I've figured out how to extract data from it. I manipulate it
      through mouse and keyboard commands though, not direct SendMessage
      statements.

      Basically I'm just going to post the code with my comments from when I
      originally wrote it, with some extra info. I'm going to assume you
      know how to work with SendMessage under Perl and Win32:GuiTest. If
      not, Piotr's site has an excellent tutorial.

      #Get the value of a SysMonthCal32 control
      #$H_MonthCalendar is the HWND to the control
      #/----------------------------------------------------------------------------------------\
      sub GetMonthCalendarValue
      {
      my $H_MonthCalendar = shift;

      #OK...so here's what's going on...besides the fact that whoever
      #wrote this control needs to be severely beaten with a large
      #rotting salmon...

      #For some reason, SysMonthCal32 controls are multi-selects,
      #EVEN IF THEY SAY THEY AREN'T by looking with a spy utility.
      #And you need to allocate a virtual buffer inside them, even
      #though the MCM_GETSELRANGE is less then 1024. I'm not exactly
      #sure why it works like that, but that's how they work. On top of
      #that, the documentation on the MSDN site for SysMonthCal32 is
      #wrong...you need to send in an 8 integer struct, which will give
      #you back the range in 2 4-variable integer structs. The last 2
      #variables in the 4-variable struct are for the time I think. We
      #don't need to worry about those here. The first variable is the
      #month and the year. The second is the day. For every month,
      #starting at 65536 for January, it adds 65536. For the year, it
      #just adds the year number. So to get the year, you just
      #modulus the first number by 65536. To get the month, you divide
      #by 65536 and convert to an integer. For the day, it works out to
      #65537 for the first day, and adds 65537 for every day. That's
      #what comes out for the day anyways, but that's not how you get
      #the day. You divide the day variable by 65536 and convert it to
      #an integer. That's the only way I could get it to work
      #consistantly. But once you do that it should work out every
      #time. To get the second date in the range if it actually IS a
      #multi-select, I assume you just do the same math on the second
      #set of 4 variables. Now where's my large rotting salmon...

      my $s_Date;

      my $p_DateTimeStruct;

      my $o_DateTime = AllocateVirtualBuffer( $H_MonthCalendar, 100 );

      my $S_DateTimeStruct = pack('L!8',
      0,
      0,
      0,
      0,
      0,
      0,
      0,
      0,);

      WriteToVirtualBuffer( $o_DateTime, $S_DateTimeStruct );

      #MCM_GETSELRANGE = 0x1005

      if(SendMessage( $H_MonthCalendar, MCM_GETSELRANGE() , 0,
      $o_DateTime->{ 'ptr' } ))
      {

      my $o_DateVar = ReadFromVirtualBuffer( $o_DateTime, 100 );

      my @a_o_DateStruct = unpack( 'L!8', $o_DateVar);

      my $i_Year;
      my $i_Month;
      my $i_Day;

      $i_Year = ($a_o_DateStruct[0] % 65536);

      if(length(int($a_o_DateStruct[0] / 65536)) == 1)
      {
      $i_Month = "0" . (int($a_o_DateStruct[0] / 65536));
      }
      else
      {
      $i_Month = (int($a_o_DateStruct[0] / 65536));
      }

      if(length(int($a_o_DateStruct[1] / 65536)) == 1)
      {
      $i_Day = "0" . (int($a_o_DateStruct[1] / 65536));
      }
      else
      {
      $i_Day = (int($a_o_DateStruct[1] / 65536));
      }

      $s_Date = $i_Year . "-" . $i_Month . "-" . $i_Day;
      }
      else
      {
      return 0;
      }

      FreeVirtualBuffer($o_DateTime);

      return $s_Date;
      }
      #\----------------------------------------------------------------------------------------/
      #GetMonthCalendarValue ---> END

      #Set the value of a SysMonthCal32 control with the given parameter
      #$H_MonthCalendar is the HWND to the control
      #$s_FieldValue is a string containing the date in YYYYMMDD format,
      #or the number of days to move
      #/----------------------------------------------------------------------------------------\
      sub SetMonthCalendarValue
      {
      my $H_MonthCalendar = shift;
      my $s_FieldValue = shift;

      my $i_DaysOffset;

      #Get the number of days between the date we want and the date on
      #the control. 1970 is an arbitrary date to check for whether
      #$s_FieldValue is a date or not
      if($s_FieldValue > 19700000)
      {
      my $C_ControlDate = GetMonthCalendarValue($H_MonthCalendar);

      if($C_ControlDate)
      {
      $C_ControlDate = Date::Simple->new($C_ControlDate);
      my $C_TargetDate = Date::Simple->new($s_FieldValue);
      $i_DaysOffset = $C_TargetDate - $C_ControlDate;
      }
      else
      {
      return 0;
      }
      }
      else
      {
      $i_DaysOffset = $s_FieldValue;
      }


      #Move by the number of day.
      #Multiply by -1 and change the arrow key used to go back to a
      #previous date.
      if($i_DaysOffset)
      {
      my $s_Direction;

      SetFocus( $H_MonthCalendar );

      if($i_DaysOffset > 0)
      {
      $s_Direction = "{RIGHT}";
      }
      else
      {
      $s_Direction = "{LEFT}";
      $i_DaysOffset *= -1;
      }

      for(1 .. $i_DaysOffset)
      {
      SendKeys($s_Direction);
      }
      }

      select(undef, undef, undef, 1.00);
      return 1;
      }
      #\----------------------------------------------------------------------------------------/
      #SetMonthCalendarValue ---> END

      --- In perlguitest@yahoogroups.com, "jonnyroberts1978"
      <jonnyroberts1978@...> wrote:
      >
      > Does anyone know if there is any support for the SysMothCal32 class?
      >
    • Show all 4 messages in this topic