Hello 

I have change and add some function in GUI.xs (see file attach)

I have change GetOpenFileName for support multiple selection and correct
a problem with filter buffer allocation.
I have add a GetSaveFileName function and a Selection method on TextField.

Aldo, are you agree for add it ?

Laurent
MODULE = Win32::GUI     PACKAGE = Win32::GUI


    ###########################################################################
    # (@)METHOD:GetOpenFileName(%OPTIONS)
    # Allowed %OPTIONS are:
    #  -owner => WINDOW
    #      Identifies the window that owns the dialog box.
    #  -title => STRING
    #      The title for the dialog
    #  -directory => STRING
    #      Specifies the initial directory
    #  -file => STRING
    #      Specifies a name that will appear on the dialog's edit field
    #  -filter => ARRAY REFERENCE
    #      Specifies an array containing pairs of filter strings.
    #      The first string in each pair is a display string that describes the filter
    #      (for example, "Text Files"), and the second string specifies the filter 
pattern
    #      (for example, "*.TXT"). To specify multiple filter patterns for a single 
display
    #      string, use a semicolon to separate the patterns (for example, 
"*.TXT;*.DOC;*.BAK").
    #      A pattern string can be a combination of valid filename characters and the 
asterisk (*)
    #      wildcard character. Do not include spaces in the pattern string.
    #  -multiple => BOOLEAN
    #      Specifies that the File Name list box allows multiple selections
    #      If the user selects more than one file then return filename with full path.
    #      If the user selects more than one file then return an array with the path
    #      to the current directory followed by the filenames of the selected files.
    #  -defaultextention => STRING
    #      This extension is append to the filename if the user fails to type an 
extension.
    #      This string can be any length, but only the first three characters are 
appended.
    #      The string should not contain a period.
    #  -defaultfilter => NUMBER
    #      Specifies the index of the currently selected filter in the File Types 
control.
    #      The first pair of strings has an index value of 0, the second pair 1, and 
so on.
void
GetOpenFileName(...)
PPCODE:
    OPENFILENAME ofn;
    BOOL retval;
    int i, next_i;
    char filename[MAX_PATH];
    char *option;
    char *filter;
    int ismultiple = 0;

    ZeroMemory(&ofn, sizeof(OPENFILENAME));
    ofn.lStructSize = sizeof(OPENFILENAME);
    ofn.hwndOwner = NULL;
    ofn.lpstrFilter = NULL;
    ofn.lpstrCustomFilter = NULL;
    ofn.nFilterIndex = 0;
    ofn.lpstrFileTitle = NULL;
    ofn.lpstrInitialDir = NULL;
    ofn.lpstrTitle = NULL;
    ofn.lpstrDefExt = NULL;
    ofn.lpTemplateName = NULL;
    ofn.Flags = OFN_HIDEREADONLY | OFN_FILEMUSTEXIST | OFN_EXPLORER;
    filename[0] = 0;
    ofn.lpstrFile = filename;
    ofn.nMaxFile = MAX_PATH;

    next_i = -1;
    for(i = 0; i < items; i++) {
        if(next_i == -1) {
            option = SvPV(ST(i), na);
            if(strcmp(option, "-owner") == 0) {
                next_i = i + 1;
                ofn.hwndOwner = (HWND) handle_From(NOTXSCALL ST(next_i));
            }
            else
            if(strcmp(option, "-title") == 0) {
                next_i = i + 1;
                ofn.lpstrTitle = SvPV(ST(next_i), na);
            }
            else
            if(strcmp(option, "-directory") == 0) {
                next_i = i + 1;
                ofn.lpstrInitialDir = SvPV(ST(next_i), na);
            }
            else
            if(strcmp(option, "-filter") == 0) {
                next_i = i + 1;
                if(SvROK(ST(next_i)) && SvTYPE(SvRV(ST(next_i))) == SVt_PVAV) {
                    AV* filters;
                    SV** t;
                    int i, filterlen = 0;
                    char *fpointer;
                    filters = (AV*)SvRV(ST(next_i));
                    for(i=0; i<=av_len(filters); i++) {
                        t = av_fetch(filters, i, 0);
                        if(t != NULL) {
                            filterlen += SvCUR(*t) + 1;
                        }
                    }
                    filterlen += 2;
                    filter = (char *) safemalloc(filterlen);
                    fpointer = filter;
                    for(i=0; i<=av_len(filters); i++) {
                        t = av_fetch(filters, i, 0);
                        if(t != NULL) {
                            strcpy(fpointer, SvPV(*t, na));
                            fpointer += SvCUR(*t) + 1;
                            *fpointer = 0;
                        }

                    }
                    fpointer++;
                    *fpointer = 0;
                    ofn.lpstrFilter = (LPCTSTR) filter;
                } else {
                    if(dowarn) warn("Win32::GUI: argument to -filter is not an array 
reference!");
                }

            }
            else
            if(strcmp(option, "-file") == 0) {
                next_i = i + 1;
                strcpy(filename, SvPV(ST(next_i), na));
            }
            else
            if(strcmp(option, "-multiple") == 0 ) {
                next_i = i + 1;
                SwitchFlag(ofn.Flags, OFN_ALLOWMULTISELECT, SvIV(ST(next_i)));
                ismultiple = SvIV(ST(next_i));
            }
            else
            if(strcmp(option, "-defaultextention") == 0 ) {
                next_i = i + 1;
                ofn.lpstrDefExt = SvPV(ST(next_i), na);
                SwitchFlag(ofn.Flags, OFN_EXTENSIONDIFFERENT, 1);
            }
            else
            if(strcmp(option, "-defaultfilter") == 0 ) {
                next_i = i + 1;
                ofn.nFilterIndex = SvIV(ST(next_i)) + 1;    
            }
        } else {
            next_i = -1;
        }
    }
    retval = GetOpenFileName(&ofn);
    if(retval) {
      if (ismultiple) {
         int i = 0;
         char * ptr = (char *) ofn.lpstrFile;

         // Count files
         while (*ptr) {
           i ++;
           ptr += strlen(ptr) + 1;
         }

         EXTEND(SP, i);

         i = 0;
         ptr = (char *) ofn.lpstrFile;
         while (*ptr) {
            XST_mPV(i, ptr);
            i ++;
            ptr += strlen(ptr) + 1;
         }

         if(ofn.lpstrFilter != NULL) safefree((void *)filter);
         XSRETURN(i);
      }
      else {
        EXTEND(SP, 1);
        XST_mPV( 0, ofn.lpstrFile);
        if(ofn.lpstrFilter != NULL) safefree((void *)filter);
        XSRETURN(1);
      }
    } else {
        if(ofn.lpstrFilter != NULL) safefree((void *)filter);
        XSRETURN_NO;
    }

    ###########################################################################
    # (@)METHOD:GetSaveFileName(%OPTIONS)
    # Allowed %OPTIONS are:
    #  -owner => WINDOW
    #      Identifies the window that owns the dialog box.
    #  -title => STRING
    #      The title for the dialog
    #  -directory => STRING
    #      Specifies the initial directory
    #  -file => STRING
    #      Specifies a name that will appear on the dialog's edit field
    #  -filter => ARRAY REFERENCE
    #      Specifies an array containing pairs of filter strings.
    #      The first string in each pair is a display string that describes the filter
    #      (for example, "Text Files"), and the second string specifies the filter 
pattern
    #      (for example, "*.TXT"). To specify multiple filter patterns for a single 
display
    #      string, use a semicolon to separate the patterns (for example, 
"*.TXT;*.DOC;*.BAK").
    #      A pattern string can be a combination of valid filename characters and the 
asterisk (*)
    #      wildcard character. Do not include spaces in the pattern string.
    #  -defaultextention => STRING
    #      This extension is append to the filename if the user fails to type an 
extension.
    #      This string can be any length, but only the first three characters are 
appended.
    #      The string should not contain a period.
    #  -defaultfilter => NUMBER
    #      Specifies the index of the currently selected filter in the File Types 
control.
    #      The first pair of strings has an index value of 0, the second pair 1, and 
so on.
void
GetSaveFileName(...)
PPCODE:
    OPENFILENAME ofn;
    BOOL retval;
    int i, next_i;
    char filename[MAX_PATH];
    char *option;
    char *filter;

    ZeroMemory(&ofn, sizeof(OPENFILENAME));
    ofn.lStructSize = sizeof(OPENFILENAME);
    ofn.hwndOwner = NULL;
    ofn.lpstrFilter = NULL;
    ofn.lpstrCustomFilter = NULL;
    ofn.nFilterIndex = 0;
    ofn.lpstrFileTitle = NULL;
    ofn.lpstrInitialDir = NULL;
    ofn.lpstrTitle = NULL;
    ofn.lpstrDefExt = NULL;
    ofn.lpTemplateName = NULL;
    ofn.Flags = OFN_HIDEREADONLY | OFN_OVERWRITEPROMPT | OFN_PATHMUSTEXIST | 
OFN_EXPLORER;
    filename[0] = 0;
    ofn.lpstrFile = filename;
    ofn.nMaxFile = MAX_PATH;

    next_i = -1;
    for(i = 0; i < items; i++) {
        if(next_i == -1) {
            option = SvPV(ST(i), na);
            if(strcmp(option, "-owner") == 0) {
                next_i = i + 1;
                ofn.hwndOwner = (HWND) handle_From(NOTXSCALL ST(next_i));
            }
            else
            if(strcmp(option, "-title") == 0) {
                next_i = i + 1;
                ofn.lpstrTitle = SvPV(ST(next_i), na);
            }
            else
            if(strcmp(option, "-directory") == 0) {
                next_i = i + 1;
                ofn.lpstrInitialDir = SvPV(ST(next_i), na);
            }
            else
            if(strcmp(option, "-filter") == 0) {
                next_i = i + 1;
                if(SvROK(ST(next_i)) && SvTYPE(SvRV(ST(next_i))) == SVt_PVAV) {
                    AV* filters;
                    SV** t;
                    int i, filterlen = 0;
                    char *fpointer;
                    filters = (AV*)SvRV(ST(next_i));
                    for(i=0; i<=av_len(filters); i++) {
                        t = av_fetch(filters, i, 0);
                        if(t != NULL) {
                            filterlen += SvCUR(*t) + 1;
                        }
                    }
                    filterlen += 2;
                    filter = (char *) safemalloc(filterlen);
                    fpointer = filter;
                    for(i=0; i<=av_len(filters); i++) {
                        t = av_fetch(filters, i, 0);
                        if(t != NULL) {
                            strcpy(fpointer, SvPV(*t, na));
                            fpointer += SvCUR(*t) + 1;
                            *fpointer = 0;
                        }

                    }
                    fpointer++;
                    *fpointer = 0;
                    ofn.lpstrFilter = (LPCTSTR) filter;
                } else {
                    if(dowarn) warn("Win32::GUI: argument to -filter is not an array 
reference!");
                }

            }
            else
            if(strcmp(option, "-file") == 0) {
                next_i = i + 1;
                strcpy(filename, SvPV(ST(next_i), na));
            }
            else
            if(strcmp(option, "-defaultextention") == 0 ) {
                next_i = i + 1;
                ofn.lpstrDefExt = SvPV(ST(next_i), na);
                SwitchFlag(ofn.Flags, OFN_EXTENSIONDIFFERENT, 1);
            }
            else
            if(strcmp(option, "-defaultfilter") == 0 ) {
                next_i = i + 1;               
                ofn.nFilterIndex = SvIV(ST(next_i)) + 1;
            }
        } else {
            next_i = -1;
        }
    }
    retval = GetSaveFileName(&ofn);
    if(retval) {
        EXTEND(SP, 1);
        XST_mPV( 0, ofn.lpstrFile);
        if(ofn.lpstrFilter != NULL) safefree((void *)filter);
        XSRETURN(1);
    } else {
        if(ofn.lpstrFilter != NULL) safefree((void *)filter);
        XSRETURN_NO;
    }

    ###########################################################################
    # (@)PACKAGE:Win32::GUI::Textfield
    ###########################################################################

MODULE = Win32::GUI     PACKAGE = Win32::GUI::Textfield

    ###########################################################################
    # (@)METHOD:Selection()
    # Returns a two elements array containing the current selection start
    # and end.
void
Selection(handle)
    HWND handle
PREINIT:
    DWORD start;
    DWORD end;
PPCODE:

    SendMessage(handle, EM_GETSEL,
               (WPARAM) (LPDWORD) &start, (LPARAM) (LPDWORD) &end
    );
    EXTEND(SP, 2);
    XST_mIV(0, start);
    XST_mIV(1, end);
    XSRETURN(2);

Reply via email to