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