Results 1 to 27 of 27

Thread: Private Declare Sub CopyMemory or Vb6.CopyMemory

  1. #1

    Thread Starter
    Addicted Member
    Join Date
    Nov 2016
    Location
    Italy
    Posts
    205

    Private Declare Sub CopyMemory or Vb6.CopyMemory

    In my application, I'm using "modCOMDLG32.bas" Module, created By : Kevin Wilson taken from "http://www.TheVBZone.com". This module uses CopyMemory several times. Now, if I use
    Code:
    Private Declare Sub CopyMemory Lib "kernel32.dll" Alias "RtlMoveMemory" (ByRef lpvDest As Any, ByRef lpvSource As Any, ByVal cbCopy As Long)
    everything is OK.
    If I use "Vb6.CopyMemory" from Vb6.tlb, taken from VbSpeed, although it looks absolutely identical (Destination As Any, Source As Any, Length As Long), it doesn't work. In all other cases where I use "Vb6.CopyMemory", I don't have this problem.
    Maybe there are incompatibilities between "Vb6.tlb" and "comdlg32.dll"?
    Of course I used
    Code:
    Private Declare Sub CopyMemory Lib "kernel32.dll" Alias "RtlMoveMemory" (ByRef lpvDest As Any, ByRef lpvSource As Any, ByVal cbCopy As Long)
    in the module header, but I would like to understand the reason for this inconsistency...
    Has anyone experienced a problem and can explain to me why?
    Last edited by fabel358; Mar 21st, 2025 at 03:23 AM.

  2. #2
    Frenzied Member
    Join Date
    Dec 2012
    Posts
    1,581

    Re: Private Declare Sub CopyMemory or Vb6.CopyMemory

    What are the 2 question marks for? I use:
    Private Declare Sub CopyMemory Lib "kernel32" Alias "RtlMoveMemory" (Destination As Any, Source As Any, ByVal Length As Long)

    The DLL file is the default, as is the ByRef.

    J.A. Coutts

  3. #3
    PowerPoster Zvoni's Avatar
    Join Date
    Sep 2012
    Location
    To the moon and then left
    Posts
    5,010

    Re: Private Declare Sub CopyMemory or Vb6.CopyMemory

    although it looks absolutely identical (Destination As Any, Source As Any, Length As Long)
    It doesn't.........
    Last edited by Zvoni; Tomorrow at 31:69 PM.
    ----------------------------------------------------------------------------------------

    One System to rule them all, One Code to find them,
    One IDE to bring them all, and to the Framework bind them,
    in the Land of Redmond, where the Windows lie
    ---------------------------------------------------------------------------------
    People call me crazy because i'm jumping out of perfectly fine airplanes.
    ---------------------------------------------------------------------------------
    Code is like a joke: If you have to explain it, it's bad

  4. #4
    PowerPoster
    Join Date
    Jul 2010
    Location
    NYC
    Posts
    6,982

    Re: Private Declare Sub CopyMemory or Vb6.CopyMemory

    I couldn't find a Vb6.tlb on VBSpeed but the two typelibs they have with it, there is no difference... post some code demonstrating the issue... include this tlb and ideally its source.

  5. #5
    PowerPoster wqweto's Avatar
    Join Date
    May 2011
    Location
    Sofia, Bulgaria
    Posts
    5,846

    Re: Private Declare Sub CopyMemory or Vb6.CopyMemory

    Object Viewer does *not* show ByRef/ByVal modifiers of parameters of methods of interfaces in a typelib for no apparent reason.

    It's not possible to check if both variants are equivalent unless you decompile the typelib with OleView.

    cheers,
    </wqw>

  6. #6

    Thread Starter
    Addicted Member
    Join Date
    Nov 2016
    Location
    Italy
    Posts
    205

    Re: Private Declare Sub CopyMemory or Vb6.CopyMemory

    https://drive.google.com/file/d/10c9...usp=drive_link
    https://drive.google.com/file/d/1vJh...ew?usp=sharing
    Here are the two files in question...
    I don't have VB6.tlb source code; it isn't mine.
    here a discussion: https://www.vbforums.com/showthread....ed-source-code
    Last edited by fabel358; Mar 20th, 2025 at 07:18 AM.

  7. #7
    PowerPoster
    Join Date
    Jul 2010
    Location
    NYC
    Posts
    6,982

    Re: Private Declare Sub CopyMemory or Vb6.CopyMemory

    There's no difference.

    Code:
    Dim x As Long
    Dim y As Long
    Dim z As Long
    x = 5
    modCOMDLG32.CopyMemory y, x, 4
    VB6.Kernel.CopyMemory z, x, 4
    Debug.Print x, y, z
    prints 5 5 5

  8. #8
    PowerPoster wqweto's Avatar
    Join Date
    May 2011
    Location
    Sofia, Bulgaria
    Posts
    5,846

    Re: Private Declare Sub CopyMemory or Vb6.CopyMemory

    Btw, there is nothing suspicious in CopyMemory declaration in VB6.tlb i.e. it matches Destination As Any, Source As Any, ByVal Length As Long params in the API declare.

    Code:
            [entry("RtlMoveMemory"), helpstring("Copies Length Bytes from Source to Destination")]
            void _stdcall CopyMemory(
                            [in] void* Destination, 
                            [in] void* Source, 
                            [in] long Length);
    It must be something in your project that makes the difference.

    cheers,
    </wqw>

  9. #9
    PowerPoster Zvoni's Avatar
    Join Date
    Sep 2012
    Location
    To the moon and then left
    Posts
    5,010

    Re: Private Declare Sub CopyMemory or Vb6.CopyMemory

    Quote Originally Posted by wqweto View Post
    It must be something in your project that makes the difference.

    cheers,
    </wqw>
    First guess: Passing Strings (Pointer to Pointer)
    Last edited by Zvoni; Tomorrow at 31:69 PM.
    ----------------------------------------------------------------------------------------

    One System to rule them all, One Code to find them,
    One IDE to bring them all, and to the Framework bind them,
    in the Land of Redmond, where the Windows lie
    ---------------------------------------------------------------------------------
    People call me crazy because i'm jumping out of perfectly fine airplanes.
    ---------------------------------------------------------------------------------
    Code is like a joke: If you have to explain it, it's bad

  10. #10

    Thread Starter
    Addicted Member
    Join Date
    Nov 2016
    Location
    Italy
    Posts
    205

    Re: Private Declare Sub CopyMemory or Vb6.CopyMemory

    For fafalone: Vb6's copymemory works great and I know; this because I use it in all my applications (Vb6.tlb also has the advantage of the GetMemx and PutMemx functions).
    As any of you may have noticed, it is apparently identical in input to the
    Code:
    Public Declare Sub CopyMemory Lib "kernel32.dll" Alias "RtlMoveMemory" (ByRef lpvDest As Any, ByRef lpvSource As Any, ByVal cbCopy As Long)
    declaration;
    However, if you try to use the ShowPrinter function, you will find that everything seems to work except printing. From my experience, the problem is in the following line:
    Code:
    ' Get the DevInfo structure
    pDevMode = GlobalLock(PrintInfo.hDevMode)
    CopyMemory DevInfo, ByVal pDevMode, Len(DevInfo)
    If CopyMemory is the one in the Header declaration, printing works; if it is Vb6.Copymemory, nothing works.

  11. #11
    PowerPoster wqweto's Avatar
    Join Date
    May 2011
    Location
    Sofia, Bulgaria
    Posts
    5,846

    Re: Private Declare Sub CopyMemory or Vb6.CopyMemory

    Seems like you are bitten by ANSI<->Unicode transcoding.

    Using Len (instead of LenB) is wrong on many levels too but this is a vast topic I don't have the patience to explain here and now (w/ fixed length strings vs byte arrays in UDT).

    Also, DEVMODE struct is a beast to handle esp. when spit by buggy printer drivers.

    cheers,
    </wqw>

  12. #12
    PowerPoster
    Join Date
    Jul 2010
    Location
    NYC
    Posts
    6,982

    Re: Private Declare Sub CopyMemory or Vb6.CopyMemory

    Does VB6 automatically turn it off for typelib APIs with As Any? I know it supports Unicode strings, as input at least, if declared as such.

  13. #13

    Thread Starter
    Addicted Member
    Join Date
    Nov 2016
    Location
    Italy
    Posts
    205

    Re: Private Declare Sub CopyMemory or Vb6.CopyMemory

    Quote Originally Posted by wqweto View Post
    Seems like you are bitten by ANSI<->Unicode transcoding.

    Using Len (instead of LenB) is wrong on many levels too but this is a vast topic I don't have the patience to explain here and now (w/ fixed length strings vs byte arrays in UDT).
    Even with LenB instead of len, nothing works with Vb6.CopyMemory, rather, the application crashes.

    Anyway, with the declaration in the Header, everything works fine and this is the solution I adopted. However I was interested to understand why this huge difference between CopyMemory inside a tlb and as a declaration in the module header, since they are apparently identical.
    Last edited by fabel358; Mar 21st, 2025 at 05:43 AM.

  14. #14
    PowerPoster Zvoni's Avatar
    Join Date
    Sep 2012
    Location
    To the moon and then left
    Posts
    5,010

    Re: Private Declare Sub CopyMemory or Vb6.CopyMemory

    Quote Originally Posted by fabel358 View Post
    Even with LenB instead of len, nothing works with Vb6.CopyMemory.

    Anyway, with the declaration in the Header, everything works fine and this is the solution I adopted. However I was interested to understand why this huge difference between CopyMemory inside a tlb and as a declaration in the module header, since they are apparently identical.
    Now you are contradicting yourself

    If I use "Vb6.CopyMemory" from Vb6.tlb, taken from VbSpeed, although it looks absolutely identical (Destination As Any, Source As Any, Length As Long), it doesn't work.
    In all other cases where I use "Vb6.CopyMemory", I don't have this problem.
    is the CopyMemory from the tlb now working or not?

    Or is the tlb not working just for this Printer-Mess?
    Last edited by Zvoni; Tomorrow at 31:69 PM.
    ----------------------------------------------------------------------------------------

    One System to rule them all, One Code to find them,
    One IDE to bring them all, and to the Framework bind them,
    in the Land of Redmond, where the Windows lie
    ---------------------------------------------------------------------------------
    People call me crazy because i'm jumping out of perfectly fine airplanes.
    ---------------------------------------------------------------------------------
    Code is like a joke: If you have to explain it, it's bad

  15. #15

    Thread Starter
    Addicted Member
    Join Date
    Nov 2016
    Location
    Italy
    Posts
    205

    Re: Private Declare Sub CopyMemory or Vb6.CopyMemory

    Quote Originally Posted by Zvoni View Post
    Now you are contradicting yourself


    is the CopyMemory from the tlb now working or not?

    Or is the tlb not working just for this Printer-Mess?
    Apparently, I was not clear enough.
    Vb6.CopyMemory does NOT work only when I replace CopyMemory (with declaration in Header) inside the module "modCOMDLG32.bas". Everywhere I've used it, it works fine. Read the first post (#1)... Clear now?
    Last edited by fabel358; Mar 21st, 2025 at 05:51 AM.

  16. #16
    PowerPoster Zvoni's Avatar
    Join Date
    Sep 2012
    Location
    To the moon and then left
    Posts
    5,010

    Re: Private Declare Sub CopyMemory or Vb6.CopyMemory

    Quote Originally Posted by fabel358 View Post
    Apparently I was not clear enough.
    Vb6.CopyMemory does NOT work only when I replace CopyMemory (with declaration in Header) inside the module "modCOMDLG32.bas". Everywhere I've used it it works fine. Read the first post (#1)... Clear now?
    No
    From first Post
    In all other cases where I use "Vb6.CopyMemory", I don't have this problem.



    Meaning: You DO USE vb6.CopyMemory (from the TLB) and it works for all OTHER cases
    At least i read it like that
    Last edited by Zvoni; Tomorrow at 31:69 PM.
    ----------------------------------------------------------------------------------------

    One System to rule them all, One Code to find them,
    One IDE to bring them all, and to the Framework bind them,
    in the Land of Redmond, where the Windows lie
    ---------------------------------------------------------------------------------
    People call me crazy because i'm jumping out of perfectly fine airplanes.
    ---------------------------------------------------------------------------------
    Code is like a joke: If you have to explain it, it's bad

  17. #17

    Thread Starter
    Addicted Member
    Join Date
    Nov 2016
    Location
    Italy
    Posts
    205

    Re: Private Declare Sub CopyMemory or Vb6.CopyMemory

    Quote Originally Posted by Zvoni View Post
    No
    From first Post

    [/B][/COLOR]

    Meaning: You DO USE vb6.CopyMemory (from the TLB) and it works for all OTHER cases
    At least i read it like that
    Exactly. So? What was unclear?
    The problem is only for modCOMDLG32.bas which works with CopyMemory declared in Header and doesn't work with Vb6.CopyMemory.
    Last edited by fabel358; Mar 21st, 2025 at 07:09 AM.

  18. #18
    PowerPoster VanGoghGaming's Avatar
    Join Date
    Jan 2020
    Location
    Eve Online - Mining, Missions & Market Trading!
    Posts
    2,337

    Re: Private Declare Sub CopyMemory or Vb6.CopyMemory

    You haven't posted the actual code where you used these CopyMemory functions. If you used them to manipulate strings then the proper usage is to supply "StrPtr(string)" instead of the actual string variable. Then both declarations of CopyMemory will work identically.

  19. #19

    Thread Starter
    Addicted Member
    Join Date
    Nov 2016
    Location
    Italy
    Posts
    205

    Re: Private Declare Sub CopyMemory or Vb6.CopyMemory

    Quote Originally Posted by VanGoghGaming View Post
    You haven't posted the actual code where you used these CopyMemory functions. If you used them to manipulate strings then the proper usage is to supply "StrPtr(string)" instead of the actual string variable. Then both declarations of CopyMemory will work identically.
    Not so: I provided the bas module, I provided Vb6.tlb. Just replace, for example in ShowPrinter, CopyMemory with Vb6.CopyMemory and it turns out that with CopyMemory declared in Header, the printer prints, replacing with Vb6.Copymemory the printer does not print. Apparently Vb6.CopyMemory and CopyMemory about data entry and yet one works, the other does not.
    What I asked was whether anyone had the same problem that I encountered or not. Maybe no one has ever used a tlb with CopyMemory in an application?

    In a Form:
    Code:
    Option Explicit
    
    
    Private Sub Form_Load()
       Dim Max              As Integer
       Dim Min              As Integer
       Dim Fasc             As Boolean
       Dim Orient           As Integer
       Dim SelPaper         As Integer
       Dim FlagSeg          As Long
       Dim Printer1         As String
       Dim StFromPage       As Integer
       Dim StToPage         As Integer
       Dim StCopies         As Integer
    
       On Error Resume Next
    
       StFromPage = 1
       StToPage = 1
       StCopies = 1
       Max = 1
       Min = 1
       StFromPage = Min
    
       StToPage = Max
       Fasc = True
       Orient = 1
       SelPaper = 1
       FlagSeg = FlagSeg Or PD_HIDEPRINTTOFILE Or PD_NOSELECTION Or _
           PD_USEDEVMODECOPIES Or PD_RETURNDC Or PD_CURRENTPAGE
    
       If CD_ShowPrinter(hWnd, FlagSeg, Printer1, StFromPage, StToPage, Min, Max, _
           StCopies, , Orient, SelPaper, , , , Fasc) Then
          Err.Clear
       Else
          Err.Raise CDLCANCEL
       End If
    End Sub
    Last edited by fabel358; Mar 21st, 2025 at 01:52 PM.

  20. #20
    PowerPoster VanGoghGaming's Avatar
    Join Date
    Jan 2020
    Location
    Eve Online - Mining, Missions & Market Trading!
    Posts
    2,337

    Re: Private Declare Sub CopyMemory or Vb6.CopyMemory

    Yeah I've seen it and it was as expected, you are copying stuff into UDTs which contain String members. In this case there is indeed a difference between CopyMemory declared in a TLB vs CopyMemory declared in code.

  21. #21

    Thread Starter
    Addicted Member
    Join Date
    Nov 2016
    Location
    Italy
    Posts
    205

    Re: Private Declare Sub CopyMemory or Vb6.CopyMemory

    Quote Originally Posted by VanGoghGaming View Post
    Yeah I've seen it and it was as expected, you are copying stuff into UDTs which contain String members. In this case there is indeed a difference between CopyMemory declared in a TLB vs CopyMemory declared in code.
    Huh? According to this interpretation, copying "UDTs" with "header's CopyMemory" copies not only the pointers to the strings, but also the strings? instead in ".tlb" the pointer to the strings is copied but not the strings?
    I had obviously realized that there were differences between Header's CopyMemory and in a ".tlb". I'm curious to understand "why"...
    Last edited by fabel358; Mar 23rd, 2025 at 06:29 AM.

  22. #22
    PowerPoster VanGoghGaming's Avatar
    Join Date
    Jan 2020
    Location
    Eve Online - Mining, Missions & Market Trading!
    Posts
    2,337

    Re: Private Declare Sub CopyMemory or Vb6.CopyMemory

    The solution is very simple, do NOT use String members in UDTs!

    Replace variable-length strings with "Long" and fixed-length strings with byte arrays. Then you won't encounter these types of problems anymore!

  23. #23
    PowerPoster wqweto's Avatar
    Join Date
    May 2011
    Location
    Sofia, Bulgaria
    Posts
    5,846

    Re: Private Declare Sub CopyMemory or Vb6.CopyMemory

    Quote Originally Posted by VanGoghGaming View Post
    The solution is very simple, do NOT use String members in UDTs!

    Replace variable-length strings with "Long" and fixed-length strings with byte arrays. Then you won't encounter these types of problems anymore!
    And can use LenB everywhere to get correct sizes on UDTs (incl. correct padding) i.e. matching SDK structs.

    cheers,
    </wqw>

  24. #24

    Thread Starter
    Addicted Member
    Join Date
    Nov 2016
    Location
    Italy
    Posts
    205

    Re: Private Declare Sub CopyMemory or Vb6.CopyMemory

    Quote Originally Posted by VanGoghGaming View Post
    The solution is very simple, do NOT use String members in UDTs!

    Replace variable-length strings with "Long" and fixed-length strings with byte arrays. Then you won't encounter these types of problems anymore!
    For example
    Code:
    Public Type LOGFONT
        lfHeight             As Long            ' Specifies the height, in logical units, of the font’s character cell or character
        lfWidth              As Long            ' Specifies the average width, in logical units, of characters in the font
        lfEscapement         As Long            ' Specifies the angle, in tenths of degrees, between the escapement vector and the x-axis of the device. The escapement vector is parallel to the base line of a row of text
        lfOrientation        As Long            ' Specifies the angle, in tenths of degrees, between each character’s base line and the x-axis of the device
        lfWeight             As Long            ' Specifies the weight of the font in the range 0 through 1000 (See Constants)
        lfItalic             As Byte            ' Specifies an italic font if set to TRUE (1)
        lfUnderline          As Byte            ' Specifies an underlined font if set to TRUE (1)
        lfStrikeOut          As Byte            ' Specifies a strikeout font if set to TRUE (1)
        lfCharSet            As Byte            ' Specifies the character set (See Constants)
        lfOutPrecision       As Byte            ' Specifies the output precision. The output precision defines how closely the output must match the requested font’s height, width, character orientation, escapement, pitch, and font type (See Constants)
        lfClipPrecision      As Byte            ' Specifies the clipping precision. The clipping precision defines how to clip characters that are partially outside the clipping region
        lfQuality            As Byte            ' Specifies the output quality. The output quality defines how carefully the graphics device interface (GDI) must attempt to match the logical-font attributes to those of an actual physical font (See Constants)
        lfPitchAndFamily     As Byte            ' Specifies the pitch and family of the font. The two low-order bits specify the pitch of the font (See Constants) - Bits 4 through 7 of the member specify the font family (See Constants)
        lfFaceName           As String * 31     ' A null-terminated string that specifies the typeface name of the font. The length of this string must not exceed 32 characters, including the null terminator. The EnumFontFamilies function can be used to enumerate the typeface names of all currently available fonts. If lfFaceName is an empty string, GDI uses the first font that matches the other specified attributes.
    End Type
    Somenthing like this?
    Code:
    Public Type LOGFONT
        lfHeight             As Long            ' Specifies the height, in logical units, of the font’s character cell or character
        lfWidth              As Long            ' Specifies the average width, in logical units, of characters in the font
        lfEscapement         As Long            ' Specifies the angle, in tenths of degrees, between the escapement vector and the x-axis of the device. The escapement vector is parallel to the base line of a row of text
        lfOrientation        As Long            ' Specifies the angle, in tenths of degrees, between each character’s base line and the x-axis of the device
        lfWeight             As Long            ' Specifies the weight of the font in the range 0 through 1000 (See Constants)
        lfItalic             As Byte            ' Specifies an italic font if set to TRUE (1)
        lfUnderline          As Byte            ' Specifies an underlined font if set to TRUE (1)
        lfStrikeOut          As Byte            ' Specifies a strikeout font if set to TRUE (1)
        lfCharSet            As Byte            ' Specifies the character set (See Constants)
        lfOutPrecision       As Byte            ' Specifies the output precision. The output precision defines how closely the output must match the requested font’s height, width, character orientation, escapement, pitch, and font type (See Constants)
        lfClipPrecision      As Byte            ' Specifies the clipping precision. The clipping precision defines how to clip characters that are partially outside the clipping region
        lfQuality            As Byte            ' Specifies the output quality. The output quality defines how carefully the graphics device interface (GDI) must attempt to match the logical-font attributes to those of an actual physical font (See Constants)
        lfPitchAndFamily     As Byte            ' Specifies the pitch and family of the font. The two low-order bits specify the pitch of the font (See Constants) - Bits 4 through 7 of the member specify the font family (See Constants)
        lfFaceName(31)       As Byte            ' A null-terminated string that specifies the typeface name of the font. The length of this string must not exceed 32 characters, including the null terminator. The EnumFontFamilies function can be used to enumerate the typeface names of all currently available fonts. If lfFaceName is an empty string, GDI uses the first font that matches the other specified attributes.
    End Type

  25. #25
    PowerPoster VanGoghGaming's Avatar
    Join Date
    Jan 2020
    Location
    Eve Online - Mining, Missions & Market Trading!
    Posts
    2,337

    Re: Private Declare Sub CopyMemory or Vb6.CopyMemory

    Code:
    lfFaceName(31)       As Integer
    ' or
    lfFaceName(63)       As Byte
    A character in a string counts as two bytes.

  26. #26
    PowerPoster wqweto's Avatar
    Join Date
    May 2011
    Location
    Sofia, Bulgaria
    Posts
    5,846

    Re: Private Declare Sub CopyMemory or Vb6.CopyMemory

    > Somenthing like this?

    Depends if you are implementing LOGFONTA struct or LOGFONTW struct. There is no LOGFONT actually, the way there is no spoon.

    cheers,
    </wqw>

  27. #27

    Thread Starter
    Addicted Member
    Join Date
    Nov 2016
    Location
    Italy
    Posts
    205

    Re: Private Declare Sub CopyMemory or Vb6.CopyMemory

    Quote Originally Posted by VanGoghGaming View Post
    Code:
    lfFaceName(31)       As Integer
    ' or
    lfFaceName(63)       As Byte
    A character in a string counts as two bytes.


    Yep. My mistake.
    Last edited by fabel358; Mar 24th, 2025 at 05:10 AM.

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