-
Mar 19th, 2025, 01:12 PM
#1
Thread Starter
Addicted Member
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.
-
Mar 20th, 2025, 01:05 AM
#2
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
-
Mar 20th, 2025, 01:55 AM
#3
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
-
Mar 20th, 2025, 03:18 AM
#4
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.
-
Mar 20th, 2025, 03:23 AM
#5
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>
-
Mar 20th, 2025, 05:51 AM
#6
Thread Starter
Addicted Member
Re: Private Declare Sub CopyMemory or Vb6.CopyMemory
Last edited by fabel358; Mar 20th, 2025 at 07:18 AM.
-
Mar 20th, 2025, 08:45 AM
#7
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
-
Mar 20th, 2025, 09:05 AM
#8
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>
-
Mar 20th, 2025, 10:07 AM
#9
Re: Private Declare Sub CopyMemory or Vb6.CopyMemory
 Originally Posted by wqweto
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
-
Mar 21st, 2025, 03:21 AM
#10
Thread Starter
Addicted Member
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.
-
Mar 21st, 2025, 04:51 AM
#11
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>
-
Mar 21st, 2025, 05:09 AM
#12
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.
-
Mar 21st, 2025, 05:38 AM
#13
Thread Starter
Addicted Member
Re: Private Declare Sub CopyMemory or Vb6.CopyMemory
 Originally Posted by wqweto
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.
-
Mar 21st, 2025, 05:42 AM
#14
Re: Private Declare Sub CopyMemory or Vb6.CopyMemory
 Originally Posted by fabel358
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
-
Mar 21st, 2025, 05:46 AM
#15
Thread Starter
Addicted Member
Re: Private Declare Sub CopyMemory or Vb6.CopyMemory
 Originally Posted by Zvoni
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.
-
Mar 21st, 2025, 05:52 AM
#16
Re: Private Declare Sub CopyMemory or Vb6.CopyMemory
 Originally Posted by fabel358
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
-
Mar 21st, 2025, 06:45 AM
#17
Thread Starter
Addicted Member
Re: Private Declare Sub CopyMemory or Vb6.CopyMemory
 Originally Posted by Zvoni
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.
-
Mar 21st, 2025, 12:51 PM
#18
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.
-
Mar 21st, 2025, 01:35 PM
#19
Thread Starter
Addicted Member
Re: Private Declare Sub CopyMemory or Vb6.CopyMemory
 Originally Posted by VanGoghGaming
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.
-
Mar 21st, 2025, 02:20 PM
#20
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.
-
Mar 23rd, 2025, 03:12 AM
#21
Thread Starter
Addicted Member
Re: Private Declare Sub CopyMemory or Vb6.CopyMemory
 Originally Posted by VanGoghGaming
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.
-
Mar 23rd, 2025, 12:39 PM
#22
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!
-
Mar 23rd, 2025, 12:54 PM
#23
Re: Private Declare Sub CopyMemory or Vb6.CopyMemory
 Originally Posted by VanGoghGaming
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>
-
Mar 23rd, 2025, 02:22 PM
#24
Thread Starter
Addicted Member
Re: Private Declare Sub CopyMemory or Vb6.CopyMemory
 Originally Posted by VanGoghGaming
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
-
Mar 23rd, 2025, 02:38 PM
#25
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.
-
Mar 23rd, 2025, 02:41 PM
#26
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>
-
Mar 23rd, 2025, 03:03 PM
#27
Thread Starter
Addicted Member
Re: Private Declare Sub CopyMemory or Vb6.CopyMemory
 Originally Posted by VanGoghGaming
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
-
Forum Rules
|
Click Here to Expand Forum to Full Width
|