Results 1 to 11 of 11

Thread: [RESOLVED] How to get a class event raised from a Function called trhrough addressof?

  1. #1

    Thread Starter
    Fanatic Member Dnereb's Avatar
    Join Date
    Aug 2005
    Location
    Netherlands
    Posts
    863

    Resolved [RESOLVED] How to get a class event raised from a Function called trhrough addressof?

    Hi All,

    I'm adding some API functionality to my ClsFiles Class.

    So I'm wrapping CopyFileEx
    (Public Declare Function CopyFileEx Lib "kernel32.dll" Alias "CopyFileExA" (ByVal lpExistingFileName As String, ByVal lpNewFileName As String, ByVal lpProgressRoutine As Long, lpData As Any, ByRef pbCancel As Long, ByVal dwCopyFlags As Long) As Long)

    Now the progress can be evaluted in the function given the adres for:
    CopyFileEx("c:\verybigfile.ext", "c:\copy.ext", AddressOf CopyProgressRoutine, ByVal 0&, bCancel, COPY_FILE_RESTARTABLE)

    but that routine has to reside in a bas module to be able to pass an base adres.

    This part goes fine but I need to raise an event in the class that sends this progress to the calling object so is can be proccessed in a progressbar, label etc...

    Does anyone knows a trick to get that information from the function CopyProgressRoutine in the bas module to the class that can be created anywhere, keeping the code reusable (that is without re-writing it for every situation)

    Hoping for a positive answer.....

    sincerly yours Dnereb.
    why can't programmers keep and 31 Oct and 25 dec apart. Why Rating is Useful
    for every question you ask provide an answer on another thread.

  2. #2
    PowerPoster
    Join Date
    Oct 2002
    Location
    British Columbia
    Posts
    9,758

    Re: How to get a class event raised from a Function called trhrough addressof?

    Can you make use of the lpData parameter? CopyFileEx will pass that value to the CopyProgressRoutine. I don't know if this will work but if lpData contained a reference to the class instance that called CopyFile, CopyProgressRoutine would then be able to call any method within the class.

  3. #3
    PowerPoster jcis's Avatar
    Join Date
    Jan 2003
    Location
    Argentina
    Posts
    4,430

    Re: How to get a class event raised from a Function called trhrough addressof?

    I'm not totally sure this is what you want, I never did something like this, but i used some Classes written by Joacim Andersson that do what you want to do, or at least, very close. The purpose of this Class Objects is allow the user to see copy Progress when Downloading/Uploading files to a FTP Server, but most importantly: The Class has Public events that fire in between the process to update Progress/ show errors and I think this is what you need, the Class name is CFtp, you can download these Classes here:
    http://www.vbforums.com/showthread.php?t=393703
    All that is very easy to run (if you need to see it working) using the example in that post. You just need a FTP Server and password to log in.
    Last edited by jcis; Apr 13th, 2007 at 11:47 AM.

  4. #4

    Thread Starter
    Fanatic Member Dnereb's Avatar
    Join Date
    Aug 2005
    Location
    Netherlands
    Posts
    863

    Re: How to get a class event raised from a Function called trhrough addressof?

    the LpData solution would be really beautifull, althoug I suspect I need to pass a pointer to the class. The ftp example will get my attention as well.

    Thanks for the pointers... I will get back on this.
    why can't programmers keep and 31 Oct and 25 dec apart. Why Rating is Useful
    for every question you ask provide an answer on another thread.

  5. #5

    Thread Starter
    Fanatic Member Dnereb's Avatar
    Join Date
    Aug 2005
    Location
    Netherlands
    Posts
    863

    Re: How to get a class event raised from a Function called trhrough addressof?

    Well Wasted the main part of today fiddling around to get the class send to the callback function to no avail

    I've finally figured out that the Lpdata Long doesn't point to the object send along in LpData as Any in the FileCopyEx Api.

    the code line
    Debug.Print ObjPtr(Me) & " Should be the same as the lpdata pointer: " & Recieved
    in the Filesclass shows the problem.

    If Anyone has a trick up his sleeve, let me know.
    for know I've used a global var of the class to contain the class
    So I can adress it in the callback routine (ugly solution) but I can't find a nicer way to do so.

    The main problem now is two filecopy's running at the same time will flunk for Sure.

    But anyways thx for your time and if you like to you can take a peak at the problem in this little test project.
    Attached Files Attached Files
    why can't programmers keep and 31 Oct and 25 dec apart. Why Rating is Useful
    for every question you ask provide an answer on another thread.

  6. #6
    I'm about to be a PowerPoster! Joacim Andersson's Avatar
    Join Date
    Jan 1999
    Location
    Sweden
    Posts
    14,649

    Re: How to get a class event raised from a Function called trhrough addressof?

    What you need to do is to get a reference of the object in use without increasing the reference counter. You can do that if you have the address of the object, and use CopyMemory to copy this address into a new reference variable. However you must then remove this reference by making the reference variable point to NULL, you do that simply by copy 0, to the reference variable. So your callback procedure should look like this:
    vb Code:
    1. Public Function CopyProgressRoutine(ByVal TotalFileSize As Currency, ByVal TotalBytesTransferred As Currency, ByVal StreamSize As Currency, ByVal StreamBytesTransferred As Currency, ByVal dwStreamNumber As Long, ByVal dwCallbackReason As Long, ByVal hSourceFile As Long, ByVal hDestinationFile As Long, ByVal lpData As Long) As Long
    2.     Dim Pr As Double
    3.     Dim DataPointer As Long
    4.     Dim CfilesCopyFrame As ClsFiles
    5.     Dim CfilesCopyContent As ClsFiles
    6.        
    7. '    Recieved = lpData
    8.     Pr = (TotalBytesTransferred * 10000) / (TotalFileSize * 10000) * 100
    9.    
    10.     CopyMemory FilesClass, lpData, 4
    11.     FilesClass.ShowProgress Pr, "Test"
    12.     CopyMemory FilesClass, 0, 4
    13.    
    14.     'continue filecopy
    15.     CopyProgressRoutine = PROGRESS_CONTINUE
    16. End Function
    You have FilesClass already declared, however I personally would move that declaration into the function as a local variable. I haven't done that above since I didn't want to make to much of a change to your code.

    You must also change the code in your class module where you call CopyFilesEx, you almost had the correct code in the line you had comment out. The only difference is that you must pass the ObjPtr byval otherwise you pass a pointer to that pointer....
    vb Code:
    1. Ret = CopyFileEx(source, Target, AddressOf CopyProgressRoutine, ByVal ObjPtr(Me), bCancel, COPY_FILE_RESTARTABLE)
    Good luck!

  7. #7

    Thread Starter
    Fanatic Member Dnereb's Avatar
    Join Date
    Aug 2005
    Location
    Netherlands
    Posts
    863

    Re: How to get a class event raised from a Function called trhrough addressof?

    Tried that already (soft backpointer)
    It seams the problem was in the declaration of the copyfilewithprogress API.
    Ommitting ByRef or ByVal did the trick.

    I wil be back on this next week with a working sample passing the class to the progress callback routine for completeness, I currently implementing IProgressDialog in a separate class to be able to show a transfer animation.

    This is between phonecalls, drawings signing etc... so it can take a while.

    But thanks for your effort.... be back soon.
    why can't programmers keep and 31 Oct and 25 dec apart. Why Rating is Useful
    for every question you ask provide an answer on another thread.

  8. #8
    I'm about to be a PowerPoster! Joacim Andersson's Avatar
    Join Date
    Jan 1999
    Location
    Sweden
    Posts
    14,649

    Re: How to get a class event raised from a Function called trhrough addressof?

    I'm not sure I understand you, but I've got your code working with the changes I've posted above... If you've, as you said, tried that already why post the question? You can't have tried it the way I posted since it works

  9. #9

    Thread Starter
    Fanatic Member Dnereb's Avatar
    Join Date
    Aug 2005
    Location
    Netherlands
    Posts
    863

    Re: How to get a class event raised from a Function called trhrough addressof?

    The problem was in the declaration of the CopyFileEx declaration:

    Works:
    Private Declare Function CopyFileEx Lib "kernel32" Alias "CopyFileExA" _
    (ByVal lpExistingFileName As String, _
    ByVal lpNewFileName As String, _
    ByVal lpProgressRoutine As Long, _
    lpData As Any, _
    pbCancel As Long, _
    ByVal dwCopyFlags As Long) As Long
    Didn't somehow, althoughn I still don't understand why
    Private Declare Function CopyFileEx Lib "kernel32" Alias "CopyFileExA" _
    (ByVal lpExistingFileName As String, _
    ByVal lpNewFileName As String, _
    ByVal lpProgressRoutine As Long, _
    ByRef lpData As Any, _
    pbCancel As Long, _
    ByVal dwCopyFlags As Long) As Long

    In my Queest to solve it I've tried ObjPtr() in a ByVal lpData As Any as well... didn't workout either probably due to the specifig ByVal specification, but I'm stioll not entirely sure what was wrong, for I've experimented quit a lot it became a blur at some moments.

    Using the first declaration withyout a ByRef or ByVal does work and I can Pass the class just fine. To early bind I've altered the callback routine to specify the object like this:

    Code:
    Public Function CopyProgressRoutine(ByVal TotalFileSize As Currency, ByVal TotalBytesTransferred As Currency, _
                                        ByVal StreamSize As Currency, ByVal StreamBytesTransferred As Currency, _
                                        ByVal dwStreamNumber As Long, ByVal dwCallbackReason As Long, _
                                        ByVal hSourceFile As Long, ByVal hDestinationFile As Long, _
                                        ByVal lpData As ClsAPIFiles) As Long

    In the callback routine this line starts a methode that raises an event in the calling parent code of the class instance.
    lpData.ShowProgress Pr, "Copy or MoveFile"

    I will work it out a bit to specify Copy or Move in the class as well.
    why can't programmers keep and 31 Oct and 25 dec apart. Why Rating is Useful
    for every question you ask provide an answer on another thread.

  10. #10
    I'm about to be a PowerPoster! Joacim Andersson's Avatar
    Join Date
    Jan 1999
    Location
    Sweden
    Posts
    14,649

    Re: How to get a class event raised from a Function called trhrough addressof?

    I still don't understand... Obviously you didn't care about trying out the code I posted. The small changes I made to the code you attached earlier works just fine. I did not change the declaration of any APIs, but still got it working. If you want to go with another approach that's your prerogative, but since you asked the question I thought you wanted a solution. Attached you'll find the same project you attached earlier with the small changes I made, it works just fine. The progressbar comes up on the Form which also change caption.
    Attached Files Attached Files

  11. #11

    Thread Starter
    Fanatic Member Dnereb's Avatar
    Join Date
    Aug 2005
    Location
    Netherlands
    Posts
    863

    Re: How to get a class event raised from a Function called trhrough addressof?

    @ Joacim Andersson,

    Your posted code solution and my own solution came roughly at the same moment.
    I've attached my solution in the little copy test enviroment, so you can see the diffrence. I'm not using copymemorty but declared the recieving lpData as the class object. Without using copy memory to set the adress and emptying the object afterwards to avoid an inbalanced reference counter.

    @All contributors,
    I will put this thread on resolved although, I still don't know what I did wrong initially (I'm sure I've tried this several times without getting a result).

    Thanks for your input, have a nice day
    Attached Files Attached Files
    why can't programmers keep and 31 Oct and 25 dec apart. Why Rating is Useful
    for every question you ask provide an answer on another thread.

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