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);