Update of /cvsroot/perl-win32-gui/Win32-GUI
In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv10102

Modified Files:
        GUI.pm GUI.xs GUI_Helpers.cpp GUI_Options.cpp MonthCal.xs 
Log Message:
Add ClassData() method and fix memory leaks

Index: GUI_Options.cpp
===================================================================
RCS file: /cvsroot/perl-win32-gui/Win32-GUI/GUI_Options.cpp,v
retrieving revision 1.14
retrieving revision 1.15
diff -C2 -d -r1.14 -r1.15
*** GUI_Options.cpp     13 Apr 2006 22:17:07 -0000      1.14
--- GUI_Options.cpp     23 Jun 2006 18:35:33 -0000      1.15
***************
*** 1014,1017 ****
      // Free if not use.
      if (hvEvents != NULL)
!         hv_undef(hvEvents);
  }
--- 1014,1017 ----
      // Free if not use.
      if (hvEvents != NULL)
!         SvREFCNT_dec(hvEvents);
  }

Index: GUI.xs
===================================================================
RCS file: /cvsroot/perl-win32-gui/Win32-GUI/GUI.xs,v
retrieving revision 1.59
retrieving revision 1.60
diff -C2 -d -r1.59 -r1.60
*** GUI.xs      11 Jun 2006 21:00:15 -0000      1.59
--- GUI.xs      23 Jun 2006 18:35:33 -0000      1.60
***************
*** 1779,1820 ****
    
      
###########################################################################
!     # (@)METHOD:UserData([value])
!     # Sets or reads user data associated with the window or control.
!     #
!     #  my $data=$win->UserData();#retrieve any data associated with the window
!     #  $win->UserData('some string');#associate user data to the window
!     #
!     # User data can be any perl scalar or reference.
! void
! UserData(handle,...)
      HWND handle
  PREINIT:
      LPPERLWIN32GUI_USERDATA perlud;
! PPCODE:
!     if(items > 2) {
!       CROAK("Usage: UserData(handle, [value]);\n");
!     }
      perlud = (LPPERLWIN32GUI_USERDATA) GetWindowLong(handle, GWL_USERDATA);
      if( ! ValidUserData(perlud) ) {
          XSRETURN_UNDEF;
-     } else {
-       if(items==1){//reading the user data
-         if (perlud->userData!=NULL) {
-           //Just return the SV
-           XPUSHs(perlud->userData);
-         } else {
-           XSRETURN_UNDEF;
-         }
-       }
-       else {//setting user data
-         //need to free previous!
-         if (perlud->userData!=NULL) {
-           SvREFCNT_dec(perlud->userData); 
-         }
-         perlud->userData=ST(1);
-         SvREFCNT_inc(perlud->userData);
-       }
      }
  
      
###########################################################################
      # (@)METHOD:FindWindow(CLASSNAME, WINDOWNAME)
--- 1779,1803 ----
    
      
###########################################################################
!     # (@)INTERNAL:_UserData()
!     # Return a reference to an HV, stored in the perlud.UserData member
!     # of the PERLWIN32GUI_USERDATA struct
! HV *
! _UserData(handle)
      HWND handle
  PREINIT:
      LPPERLWIN32GUI_USERDATA perlud;
! CODE:
      perlud = (LPPERLWIN32GUI_USERDATA) GetWindowLong(handle, GWL_USERDATA);
      if( ! ValidUserData(perlud) ) {
          XSRETURN_UNDEF;
      }
  
+     if(perlud->userData == NULL)
+         perlud->userData = (SV*)newHV();
+ 
+     RETVAL = (HV*)perlud->userData;
+ OUTPUT:
+     RETVAL
+ 
      
###########################################################################
      # (@)METHOD:FindWindow(CLASSNAME, WINDOWNAME)
***************
*** 3596,3603 ****
            newarray = newAV();
            av_push(newarray, coderef);
!           SvREFCNT_inc(coderef);  // needed so that av_undef results in 
unchanged ref count.
            if(av_store(perlud->avHooks, WM_TRACKPOPUP_MSGHOOK, 
newRV_noinc((SV*) newarray)) == NULL) {
              // Failed to store new array
!             av_undef(newarray);
              W32G_WARN("TrackPopupMenu failed to store 'coderef' - callback 
not applied");
              coderef = NULL;  // don't set up the hook
--- 3579,3586 ----
            newarray = newAV();
            av_push(newarray, coderef);
!           SvREFCNT_inc(coderef);  // needed so that the ref count remains the 
same after we free
            if(av_store(perlud->avHooks, WM_TRACKPOPUP_MSGHOOK, 
newRV_noinc((SV*) newarray)) == NULL) {
              // Failed to store new array
!             SvREFCNT_dec((SV*) newarray);
              W32G_WARN("TrackPopupMenu failed to store 'coderef' - callback 
not applied");
              coderef = NULL;  // don't set up the hook
***************
*** 3631,3636 ****
        }
        // remove the temporary value stored in the hooks array
!       av_undef(newarray);
!       av_delete(perlud->avHooks, WM_TRACKPOPUP_MSGHOOK, 0);
      }
  OUTPUT:
--- 3614,3618 ----
        }
        // remove the temporary value stored in the hooks array
!       av_delete(perlud->avHooks, WM_TRACKPOPUP_MSGHOOK, G_DISCARD);
      }
  OUTPUT:

Index: MonthCal.xs
===================================================================
RCS file: /cvsroot/perl-win32-gui/Win32-GUI/MonthCal.xs,v
retrieving revision 1.1
retrieving revision 1.2
diff -C2 -d -r1.1 -r1.2
*** MonthCal.xs 8 May 2004 17:31:21 -0000       1.1
--- MonthCal.xs 23 Jun 2006 18:35:33 -0000      1.2
***************
*** 136,140 ****
                          lpnmDS->prgDayState[i] = SvIV(*sv);
                  }
!                 av_undef(av);
              }
              break;
--- 136,140 ----
                          lpnmDS->prgDayState[i] = SvIV(*sv);
                  }
!                 SvREFCNT_dec(av);
              }
              break;

Index: GUI_Helpers.cpp
===================================================================
RCS file: /cvsroot/perl-win32-gui/Win32-GUI/GUI_Helpers.cpp,v
retrieving revision 1.19
retrieving revision 1.20
diff -C2 -d -r1.19 -r1.20
*** GUI_Helpers.cpp     16 May 2006 18:36:11 -0000      1.19
--- GUI_Helpers.cpp     23 Jun 2006 18:35:33 -0000      1.20
***************
*** 67,80 ****
      if (perlud != NULL) {
  
-         // printf ("Free Perlud = %s\n", perlud->szWindowName);
          // Free event hash
          if (perlud->hvEvents != NULL) {
!             hv_undef(perlud->hvEvents);
              perlud->hvEvents = NULL;
          }
          // Free hook hash
          if (perlud->avHooks != NULL) {
!              av_undef (perlud->avHooks);
!              perlud->avHooks = NULL;
          }
          // Free self
--- 67,87 ----
      if (perlud != NULL) {
  
          // Free event hash
          if (perlud->hvEvents != NULL) {
!             // Test ref-count - warn if not one
!             if(SvREFCNT(perlud->hvEvents) != 1)
!                 W32G_WARN("hvEvents ref count not 1 during destruction - 
please report this");
! 
!             SvREFCNT_dec(perlud->hvEvents);
              perlud->hvEvents = NULL;
          }
          // Free hook hash
          if (perlud->avHooks != NULL) {
!             // Test ref-count - warn if not one
!             if(SvREFCNT(perlud->avHooks) != 1)
!                 W32G_WARN("avHooks ref count not 1 during destruction - 
please report this");
! 
!             SvREFCNT_dec(perlud->avHooks);
!             perlud->avHooks = NULL;
          }
          // Free self
***************
*** 93,100 ****
              perlud->svSelf = NULL;
          }
!         // Drop the ref counter on user data
!         if (perlud->userData != NULL && SvREFCNT(perlud->userData) > 0) {
!             SvREFCNT_dec(perlud->userData);
!           }
          // Free perlpud
          safefree (perlud);
--- 100,115 ----
              perlud->svSelf = NULL;
          }
! 
!         // If we stored a hash in userData, drop it's
!         // ref count to free it (and it's members)
!         if (perlud->userData != NULL) {
!             // Test ref-count - warn if not one
!             if(SvREFCNT(perlud->userData) != 1)
!                 W32G_WARN("userData ref count not 1 during destruction - 
please report this");
! 
!             SvREFCNT_dec(perlud->userData);
!             perlud->userData = NULL;
!         }
!         
          // Free perlpud
          safefree (perlud);

Index: GUI.pm
===================================================================
RCS file: /cvsroot/perl-win32-gui/Win32-GUI/GUI.pm,v
retrieving revision 1.49
retrieving revision 1.50
diff -C2 -d -r1.49 -r1.50
*** GUI.pm      15 Jun 2006 23:38:48 -0000      1.49
--- GUI.pm      23 Jun 2006 18:35:33 -0000      1.50
***************
*** 305,308 ****
--- 305,382 ----
  }
  
+     
###########################################################################
+     # (@)METHOD:UserData([value])
+     # Sets or reads user data associated with the window or control.
+     #
+     #  my $data=$win->UserData();#retrieve any data associated with the window
+     #  $win->UserData('some string');#associate user data to the window
+     #
+     # User data can be any perl scalar or reference.
+     #
+     # When reading returns the stored user data, or undef if nothing is 
stored.
+     # When setting returns a true value if the user data is stored correctly, 
or
+     # a false value on error
+     #
+     # If you are writing a class that you expect others to use, then this
+     # method should B<NOT> be used to store class instance data. See
+     # L<ClassData()|ClassData> instead.
+ sub UserData {
+     my $win = shift;
+     my $data = shift;
+ 
+     if(@_) { # more items than expected passed: someone probably tried
+              # passsing and array or hash
+         warn("UserData: too many arguments");
+         return 0;
+     }
+ 
+     if(defined $data) { # Setting user data
+         $win->_UserData()->{UserData} = $data;
+         return 1;
+     }
+     else {              # reading user data
+         return $win->_UserData()->{UserData};
+     }
+ }
+ 
+     
###########################################################################
+     # (@)METHOD:ClassData([value])
+     # Sets or reads class instance data associated with the window or control.
+     #
+     #  my $data=$win->ClassData();#retrieve any data associated with the 
window
+     #  $win->ClassData('some string');#associate data to the window
+     #
+     # Class instance data can be any perl scalar or reference.
+     #
+     # When reading returns the stored instance data, or undef if nothing is
+     # stored.
+     # When setting returns a true value if the instance data is stored
+     # correctly, or a false value on error
+     #
+     # Class instance data is private to the package that sets the data.  I.e. 
it
+     # is only accessable as a method call from within the package that sets 
the
+     # data, not from a sub-class.  So, if you wish to make data stored this 
way
+     # accessible to sub-classes you must proved assessor methods in your 
package.
+ sub ClassData {
+     my $win = shift;
+     my $data = shift;
+ 
+     if(@_) { # more items than expected passed: someone probably tried
+              # passsing and array or hash
+         warn("ClassData: too many arguments");
+         return 0;
+     }
+ 
+     my $callpkg = (caller())[0];
+ 
+     if(defined $data) { # Setting user data
+         $win->_UserData()->{$callpkg} = $data;
+         return 1;
+     }
+     else {              # reading user data
+         return $win->_UserData()->{$callpkg};
+     }
+ }
+ 
  
###############################################################################
  # SUB-PACKAGES


Reply via email to