Results 1 to 17 of 17

Thread: Please fill in the blanks (only 2)

  1. #1

    Thread Starter
    Hyperactive Member Alan777's Avatar
    Join Date
    Jan 2001
    Location
    New Zealand
    Posts
    303

    Please fill in the blanks (only 2)

    New to C++. Please help me fill in the blanks which I have commented in the code below. I don't understand how to directly access char array arguments in a function.
    (This is a Dll Export function to be called from VB)
    The third parameter is a string which will be changed by the function. That is what I don't know how to do.
    Apart from that, this code already works - I have tested it.

    Code:
    int _stdcall ShowOpenDlgAjP(HWND hOwner, char Filter[],/* this is where I need a buffer for the return path */  )
    {
    	OPENFILENAME ofn;
    	int result;
    
    	memset(&ofn,0,sizeof(OPENFILENAME));
    
    	ofn.lStructSize  = sizeof(OPENFILENAME);
    	ofn.hwndOwner = hOwner;
    	ofn.lpstrFilter = Filter;
    	ofn.nFilterIndex = 1;
    	ofn.lpstrFile = "";
    	ofn.nMaxFile = 256;
    	ofn.Flags = OFN_FILEMUSTEXIST|OFN_HIDEREADONLY;
    
    	result = GetOpenFileName(&ofn);
    	
    	//this is where I want to assign ofn.lpstrFile to the return buffer 
    	return result;
    }
    Last edited by Alan777; Mar 29th, 2002 at 03:53 AM.
    "Today's mighty oak is just yesterday's nut,
    that held its ground."

  2. #2
    Fanatic Member MoMad's Avatar
    Join Date
    Oct 2000
    Location
    Seattle, WA
    Posts
    625
    First off, you are doing it all wrong.... But in C/C++ when you are assigning strings, you have to remember that they are an array of "char"s... so use a strcpy (string copy) function to copy the strings.., like this:


    Code:
    strcpy (Filter, ofn.lpstrFilter);
    where the first parameter of the function is where you want the string to copied to, and the second, the string you want to copy from.

    By the way, you need to #include <string.h>

    Good luck.
    :MoMad:
    Nice Sig!

    http://go.to/momad/ Status: Not Ready

  3. #3

    Thread Starter
    Hyperactive Member Alan777's Avatar
    Join Date
    Jan 2001
    Location
    New Zealand
    Posts
    303
    MoMad thanks for your reply. The code actually works perfectly except I don't know how to change the value of the char array that I pass to the function. By the way, it is a dll export function to be called from VB. It works when I use this:
    int _stdcall ShowOpenDlgAjP(HWND hOwner, char Filter[], char[255] Buffer)

    But I know you can't change the value of the original Buffer string when using the by-value way. My question is just what do I change this parameter to so that I can get a return value.
    In other words, how do I use a pointer to do it?

    Thanks for the help.
    "Today's mighty oak is just yesterday's nut,
    that held its ground."

  4. #4
    Zaei
    Guest
    MoMad: The code WILL work, but only because Filter is already at some memory location. He is simply assigning that location to the Filter variable in the ofn structure, which will read the string correctly. Otherwise, he would have had to go and screw with new and delete, and such like.

    Change both of your parameter types to char*. Then, at the last line, just add this line:
    Code:
    strcpy(Buffer, ofn.lpstrFile);
    Make sure that your VB string is long enough to hold the buffer value though (Dim s As String * 256).

    Z.

  5. #5
    Fanatic Member MoMad's Avatar
    Join Date
    Oct 2000
    Location
    Seattle, WA
    Posts
    625
    Zaei, you cannot do pointer arithmatics like that... most of the time it will work but its usually unsafe.

    lpstrFilter is declared as char [256] and not a char *pointer...

    most things compile just fine and sometimes even work as expected in c, but think of the worst case scenarios.

    Im gald to help... by the way, instead of including the entirety of string.h, just use similar functions from a library that you are using for other purpose, say stdlib.h...

    or make ur own:

    PHP Code:

    char
    strcopychardest, const charsrc )
    {

        
    charbuff dest;
        while (*
    buff++ = *src++);
        *
    buff 0;

        return 
    dest;

    Thats all folks!

    By the way stdlib.h has:

    sprintf() which does the exact same as printf on a string!!
    :MoMad:
    Nice Sig!

    http://go.to/momad/ Status: Not Ready

  6. #6
    Zaei
    Guest
    From MSDN:
    Code:
    lpstrFilter 
    Long pointer to a buffer that contains pairs of null-terminated 
    filter strings. The last string in the buffer must be terminated by 
    two NULL characters. 
    
    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 file name characters and the 
    asterisk (*) wildcard character. Do not include spaces in the 
    pattern string. 
    
    
    The system does not change the order of the filters. It displays 
    them in the File Types combo box in the order specified in 
    lpstrFilter. 
    
    
    If lpstrFilter is NULL, the dialog box does not display any filters.
    It IS a pointer, and you CAN do pointer arithmetic that way =). That is the reason that pointers are so good.

    Z.

  7. #7
    Fanatic Member MoMad's Avatar
    Join Date
    Oct 2000
    Location
    Seattle, WA
    Posts
    625
    Very cool!!

    but did you have to put it in a CODE section? it makes the page so big..

    You are right Zaei, Pointers are the best!! Thats why C/C++ OWNZZ you all!!!!!!!!!

    mwahahahahhhahahahhahhahahahhaha

    <laughs frantically>...

    Regards,
    MoMad
    :MoMad:
    Nice Sig!

    http://go.to/momad/ Status: Not Ready

  8. #8
    Zaei
    Guest
    Better =).

    Z.

  9. #9

    Thread Starter
    Hyperactive Member Alan777's Avatar
    Join Date
    Jan 2001
    Location
    New Zealand
    Posts
    303
    Thanks for the replies guys.

    After much testing I have found the 1 and only line which is failing
    in the function: strcpy(str, ofn.lpstrFile); (in red below)
    The strange thing is, this line only fails when calling the function from VB. If I call the same function from C++ it works perfectly.
    I have found that strcpy only fails if using ofn.lpstrFile
    If I assign a string in quotes or a char[] it works fine and returns the string to VB. What's the deal? Do I need to convert the ofn.lpstrFile first or what? If so, how?
    How do you convert from LPSTR to char[260] ?
    Code:
    int _stdcall ShowOpenDlgAjP(HWND hOwner, char Filter[], char str[260])
    {
    	OPENFILENAME ofn;
    	int result = 0;
    
    	memset(&ofn,0,sizeof(OPENFILENAME));
    
    	ofn.lStructSize  = sizeof(OPENFILENAME);
    	ofn.hwndOwner = hOwner;
    	ofn.lpstrFilter = Filter;
    	ofn.nFilterIndex = 1;
    	ofn.lpstrFile = 0;
    	ofn.nMaxFile = MAX_PATH;
    	ofn.Flags = OFN_FILEMUSTEXIST|OFN_HIDEREADONLY;
    
    	result = GetOpenFileName(&ofn);
    
    	strcpy(str, ofn.lpstrFile); 
    
    	return result;
    }
    By the way, I did try this:
    Change both of your parameter types to char*.
    and that failed big time.
    I got an opinion from an experienced C++ programmer and he said the above is the correct way to do it. But he could not explain why it fails when calling from VB. (He does not use VB)
    Last edited by Alan777; Mar 31st, 2002 at 06:01 AM.
    "Today's mighty oak is just yesterday's nut,
    that held its ground."

  10. #10
    Fanatic Member MoMad's Avatar
    Join Date
    Oct 2000
    Location
    Seattle, WA
    Posts
    625
    DOnt do str[260] just pass str[] like that.

    Also you have to know that VB doesnt pass string arguments with array notation, it just doesnt... it passes char* by value but not by reference... if you want to modify a vb string pass it like this:

    Code:
    int _stdcall ShowOpenDlgAjP(HWND hOwner, LPSTR Filter, LPSTR* str);
    
    and in VB:
    
    ShowOpenDlgAjP(hOwner as long, byval Filter as string, byref str as string)
    That should fix your little problem!

    .. oh and your strcpy line should be changed to:

    Code:
    strcpy(*str, ofn.lpstrFile);
    ... also make sure you reserve space in VB BEFORE passing in the string parameter like:

    VB Code:
    1. Dim str as string
    2.  
    3. str = Space(260)
    4.  
    5. ShowOpenDlgAjP(me.hwnd, "somefilter", str)

    And that should end your misserable problems... by the way, if it doesnt work in the IDE make an EXE and try it... the IDE has some sort of a bug that prevents you to run functions from dll's!
    :MoMad:
    Nice Sig!

    http://go.to/momad/ Status: Not Ready

  11. #11
    Zaei
    Guest
    You can also define your string in VB as:
    Code:
    Dim St As String * 256 ' where 256 is the length of string you  want.
    Z.

  12. #12
    Fanatic Member MoMad's Avatar
    Join Date
    Oct 2000
    Location
    Seattle, WA
    Posts
    625
    Yup, thats right!!
    :MoMad:
    Nice Sig!

    http://go.to/momad/ Status: Not Ready

  13. #13

    Thread Starter
    Hyperactive Member Alan777's Avatar
    Join Date
    Jan 2001
    Location
    New Zealand
    Posts
    303
    Ok MoMad, I just tried both things you said above and neither of them work. Same problem. Memory can't be 'read' error.

    Also, in all the APIs I can think of where you pass a string to be modified by the function, it is always passed ByVal.

    That is what I want to do with my code. And as I said, the code I already have works just fine from C++. Also, I have already successfully modified VB strings using this method in testing.
    As I said above. It ONLY fails when assigning from the OPENFILENAME structure. Or probably any struct. (haven't tried others yet)

    Is it possible that you could try to run this code and see for yourself what's going on? I'd really appreciate it. Once I know the answer for this, I can carry on and apply it to many other functions without all these questions.

    I'd use MSDN, but the MSDN documentation assumes a full working knowledge of C++ before you start - kind of defeating the purpose of the whole thing.

    BTW guys, my question has nothing to do with lpstrFilter.
    There is no issue there.
    Last edited by Alan777; Apr 1st, 2002 at 06:45 AM.
    "Today's mighty oak is just yesterday's nut,
    that held its ground."

  14. #14

    Thread Starter
    Hyperactive Member Alan777's Avatar
    Join Date
    Jan 2001
    Location
    New Zealand
    Posts
    303
    I've got the answer now. Thanks for your help guys. You were a big help in getting the final answer.

    Final code:
    Code:
    int _stdcall ShowOpenDlgAjP(HWND hOwner, char Filter[], char str[])
    {
    	OPENFILENAME ofn;
    	int result = 0;
    	unsigned int ctr = 0;
    	unsigned int max;
    
    	max = strlen(Filter);
    
                    // also added this to make it easier to send the filter
    	//replace | with null
    	for (ctr = 0; ctr < max; ctr++)
    	{
    		if (Filter[ctr] == 124) // ascii 124 = "|"
    		Filter[ctr] = 0;
    	}
    
    	memset(&ofn,0,sizeof(OPENFILENAME));
    
    	ofn.lStructSize  = sizeof(OPENFILENAME);
    	ofn.hwndOwner = hOwner;
    	ofn.lpstrFilter = Filter;
    	ofn.nFilterIndex = 1;
    	ofn.lpstrFile = str;
    	ofn.nMaxFile = MAX_PATH;
    	ofn.Flags = OFN_FILEMUSTEXIST|OFN_HIDEREADONLY;
    
    	result = GetOpenFileName(&ofn);
    
    	strcpy(str, ofn.lpstrFile);
    
    	return result;
    }
    Last edited by Alan777; Apr 2nd, 2002 at 01:59 AM.
    "Today's mighty oak is just yesterday's nut,
    that held its ground."

  15. #15
    Fanatic Member MoMad's Avatar
    Join Date
    Oct 2000
    Location
    Seattle, WA
    Posts
    625
    btw: you could just write '|' instead of 128. single quoting a char will return its ASCII value.

    and you dont have to get the length of the string with strlen, just put in the middle term of your loop: Filter[i] != '\0'

    AND, if you already assigned lpstrFile to str:

    Code:
    ...
    ofn.lpstrFile = str;
    Then you dont have to do a strcpy at the end. So infact, you do not need the library string.h at all!
    Last edited by MoMad; Apr 2nd, 2002 at 12:05 PM.
    :MoMad:
    Nice Sig!

    http://go.to/momad/ Status: Not Ready

  16. #16

    Thread Starter
    Hyperactive Member Alan777's Avatar
    Join Date
    Jan 2001
    Location
    New Zealand
    Posts
    303
    Originally posted by MoMad

    AND, if you already assigned lpstrFile to str:

    Code:
    ...
    ofn.lpstrFile = str;
    Then you dont have to do a strcpy at the end. So infact, you do not need the library string.h at all!
    Yes I do. That's for the return value! (ie. the whole point of the function)
    The assignment of str at the beginning is for a default file name if required.
    Thanks for the other tips though

  17. #17
    Fanatic Member MoMad's Avatar
    Join Date
    Oct 2000
    Location
    Seattle, WA
    Posts
    625
    Wait, I just realized something...

    the default value for the filename of the dialog box is 'str', which is also the name of the file the user chooses. Then why dont you just do something like:

    return ofn.lpstr or NULL instead of the error code? wouldnt that save you an extra parameter? hehe.. but I know why you would need such a thing, error codes are better as return values than the actual retval.

    So from your code, i see that you are making something in c (perhaps in dll) that pops up the browse for folder or file dialog... so whats next? how about checking for 'cancel' button etc...

    hey have fun with that and post here if you find something interesting/boring/funny/hedious, etc.. and also if you wanna share some thoughts etc..

    I was trying to do a search-in-file-and-replace function that is supposed to be fast... and also use regular expressions (but that could be step 2 or 3 or 4 or ...) anyways, the point being vb is too slow so i need c++ dll, and then its very hard to get much info on c++ stuff these days, especially on win32 stuff and all their c++ side-effects. anyways, so far i got it to 'search and find', (the replace will come soon) and also the speed bonuses and optimizations... so if anyone wants to learn something from these, just say something... or i might even throw together a tutorial on how its all done. (Note, i am extremely busy and might not be seen back here in vbforums for a long time, but i will eventually be back, so thanks in advance for all your patience and all your impatience, etc. etc. etc...); I am taking 5 college classes (including Calculus II and Physics III, the rest are programming related)

    thanks,
    MoMad
    :MoMad:
    Nice Sig!

    http://go.to/momad/ Status: Not Ready

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •  



Click Here to Expand Forum to Full Width