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

SysMonthCal32 support

Expand Messages
  • jonnyroberts1978
    Does anyone know if there is any support for the SysMonthCal32 class? I was just starting to write some but didn t want to re-invent the wheel!
    Message 1 of 4 , Apr 18, 2007
    • 0 Attachment
      Does anyone know if there is any support for the SysMonthCal32 class?

      I was just starting to write some but didn't want to re-invent the wheel!
    • jonnyroberts1978
      Does anyone know if there is any support for the SysMothCal32 class?
      Message 2 of 4 , Apr 19, 2007
      • 0 Attachment
        Does anyone know if there is any support for the SysMothCal32 class?
      • brentje
        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
        Message 3 of 4 , 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?
          >
        • jonnyroberts1978
          Thanks very much! ... #/---------------------------------------------------------------------------------------- ...
          Message 4 of 4 , Apr 23, 2007
          • 0 Attachment
            Thanks very much!

            --- In perlguitest@yahoogroups.com, "brentje" <brentje@...> wrote:
            >
            > 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?
            > >
            >
          Your message has been successfully submitted and would be delivered to recipients shortly.