473,386 Members | 2,050 Online
Bytes | Software Development & Data Engineering Community
Post Job

Home Posts Topics Members FAQ

Join Bytes to post your question to a community of 473,386 software developers and data experts.

How to copy an address into a pointer

I know (or at least think) the following is not correct.

The comment says what I want to do, but I think the code will copy the data
not the address.

Is this one of the things that can't be done with VB?

Any suggestions?

Thanks

Public Declare Auto Sub CopyMemory1 Lib "KERNEL32" Alias "RtlMoveMemory"
(ByVal pDest As Integer, ByRef Source As Byte, ByVal cbCopy As Integer)


'Copy address of lDevModeAsByte into lPrtInfo2 structure

Kernel.CopyMemory1(lPrtInfo2.pDevMode, lDevModeAsByte(0), 4)
Nov 21 '05 #1
7 2716
In article <un**************@TK2MSFTNGP12.phx.gbl>, Just Me wrote:
I know (or at least think) the following is not correct.

The comment says what I want to do, but I think the code will copy the data
not the address.

Is this one of the things that can't be done with VB?

Any suggestions?

Thanks

Public Declare Auto Sub CopyMemory1 Lib "KERNEL32" Alias "RtlMoveMemory"
(ByVal pDest As Integer, ByRef Source As Byte, ByVal cbCopy As Integer)


'Copy address of lDevModeAsByte into lPrtInfo2 structure

Kernel.CopyMemory1(lPrtInfo2.pDevMode, lDevModeAsByte(0), 4)


CopyMemory is a almost always a bad idea to use in VB.NET. There are
almost always better alternatives. If you need to pass an address of a
managed object to an unmanaged function, then the address needs to be
pinned for the duration of that operation. The reason being, that GC
could kick in which may result in the relocation of the object - and
that could be bad ju-ju for the unmanaged code. However, there are
performance issues involved here, since leaving a lot of objects pinned
for a long time can result in heap fragmentation. So the idea, is pin
the object, do your deed, and unpin as soon as possible.

You can achive this pinning using the GCHandle class's Allocate method:

Dim objHandle As GCHandle = _
GCHandle.Allocate (myObject, GCHandleType.Pinned)

Try

Dim objectAddress As IntPtr = objHandle.AddrOfPinnedObject ()

Call MyFunckyUnmanagedCodeWithObjectAddress (objectAddress)

Finally
'Were done, so unpin this sucker...
objHandle.Free ()
End Try

You have to make sure that for each handle that Free is only called
once. Anyway, it would be more helpful if we knew exactly what you were
trying to accomplish. It's pretty obvious that your trying to call a
Win32 api of some sort - but knowing which one would be helpful.
Working with API's is, IMHO, significantly different in VB.NET then
VB.CLASSIC.

--
Tom Shelton [MVP]
Nov 21 '05 #2
> Anyway, it would be more helpful if we knew exactly what you were
trying to accomplish. It's pretty obvious that your trying to call a
Win32 api of some sort - but knowing which one would be helpful.
Working with API's is, IMHO, significantly different in VB.NET then
VB.CLASSIC.

--
Tom Shelton [MVP]


Thanks

I'm trying to use an old routine for setting the system default printer's
Landscape mode.

Any other suggestion?

Thanks again

Public Shared Sub SetPrinterSettings(ByRef windowHandle As IntPtr, ByRef
printerName As String, ByRef isLandscape As Boolean) ', ByRef aNewPaperSize
As Short, ByRef aNewDuplex As Short)

Dim lPrinterHandle As IntPtr

Dim lDevMode As GDI.DEVMODE

Dim lDevModeAsByte() As Byte

Dim lDevModeAsByteSize As Integer

Dim lPrtInfo2 As WinSpool.PRINTER_INFO_2

Dim lPrtInfo2AsByte() As Byte

Dim lPrtInfo2AsByteSize As Integer

Dim lFlag As Integer

Dim lPrinterDefaults As WinSpool.PRINTER_DEFAULTS

Dim lErrorCode As Integer

'You should probably look at the PtrToStructure and StructureToPtr methods
rather than Copy.

Kernel.ZeroMemory(lPrinterDefaults, Marshal.SizeOf(lPrinterDefaults))

lPrinterDefaults.DesiredAccess = WinSpool.PRINTER_ALL_ACCESS

'lPrinterDefaults.DesiredAccess = WinSpool.PRINTER_ACCESS_ADMINISTER

'Get a handle to the printer.

lFlag = WinSpool.OpenPrinter(printerName, lPrinterHandle, lPrinterDefaults)

If lFlag = 0 Then

lErrorCode = Marshal.GetLastWin32Error()

If lErrorCode = User.ERROR_ACCESS_DENIED Then

MessageBox.Show("Requires adminstrative rights to change default printer",
"Error", MessageBoxButtons.OK, MessageBoxIcon.Exclamation)

End If

Exit Sub

End If

'This GetPrinter call determines the size needed for lPrtInfo2AsByte

lFlag = WinSpool.GetPrinter(lPrinterHandle, 2, 0, 0, lPrtInfo2AsByteSize)

If lFlag = 0 Then

lErrorCode = Marshal.GetLastWin32Error()

If lErrorCode <> 122 Then GoTo CLEAN_UP

End If

'Allocate space for lPrtInfo2AsByte

ReDim lPrtInfo2AsByte(lPrtInfo2AsByteSize - 1)

'The second GetPrinter call fills lPrtInfo2AsByte with the current settings

lFlag = WinSpool.GetPrinter(lPrinterHandle, 2, lPrtInfo2AsByte(0),
lPrtInfo2AsByteSize, lPrtInfo2AsByteSize)

If lFlag = 0 Then

lErrorCode = Marshal.GetLastWin32Error()

'Console.WriteLine("GetPrinter exited with code : {0}", lErrorCode)

End If

'Copy lPrtInfo2AsByte to the structure

Kernel.CopyMemory2(lPrtInfo2, lPrtInfo2AsByte(0), Marshal.SizeOf(lPrtInfo2))

'Get the total size of the DeviceMode bytes (lDevModeAsByte)

lDevModeAsByteSize = WinSpool.DocumentProperties(windowHandle,
lPrinterHandle, printerName, 0, 0, 0)

'Reserve memory for the total size of the DeviceMode bytes

ReDim lDevModeAsByte(lDevModeAsByteSize - 1)

'Fill the DeviceMode bytes from the printer.

lFlag = WinSpool.DocumentProperties(windowHandle, lPrinterHandle,
printerName, lDevModeAsByte(0), 0, GDI.DM_OUT_BUFFER)

If lFlag < 0 Then

lErrorCode = Marshal.GetLastWin32Error()

Console.WriteLine("DocumentProperties exited with code: {0}", lErrorCode)

End If

'Copy the Public shared (predefined) portion of the DeviceMode bytes to the
structure

Kernel.CopyMemory3(lDevMode, lDevModeAsByte(0), Marshal.SizeOf(lDevMode))

'Set the dmFields bit flag to indicate what we are changing

lDevMode.dmFields = GDI.DM_ORIENTATION 'Or DM_DUPLEX Or DM_PAPERSIZE

If isLandscape Then

lDevMode.u.dmOrientation = GDI.DMORIENT_LANDSCAPE

Else

lDevMode.u.dmOrientation = GDI.DMORIENT_PORTRAIT

End If

'Set/Change PaperSize

'lDevMode.dmPaperSize = aNewPaperSize

'On Error Resume Next

'lDevMode.dmDuplex = aNewDuplex

'On Error GoTo 0

'Copy changed structure back to the bytes

Kernel.CopyMemory4(lDevModeAsByte(0), lDevMode, Marshal.SizeOf(lDevMode))

'Merge the printer driver's current print settings with the settings in the
lDevModeAsByte

lFlag = WinSpool.DocumentProperties(windowHandle, lPrinterHandle,
printerName, lDevModeAsByte(0), lDevModeAsByte(0), GDI.DM_IN_BUFFER Or
GDI.DM_OUT_BUFFER)

' lFlag = WinSpool.DocumentProperties(windowHandle, lPrinterHandle,
printerName, lDevModeAsByte(0), lDevModeAsByte(0), GDI.DM_IN_PROMPT)

'Copy address of lDevModeAsByte into lPrtInfo2 structure

' Kernel.CopyMemory1(lPrtInfo2.pDevMode, lDevModeAsByte(0),
Marshal.SizeOf(lDevMode))

Kernel.CopyMemory1(lPrtInfo2.pDevMode, lDevModeAsByte(0), 4)

'Update lPrinterInfoAsByte with the updated structure

Kernel.CopyMemory5(lPrtInfo2AsByte(0), lPrtInfo2, Marshal.SizeOf(lDevMode))

lFlag = WinSpool.SetPrinter(lPrinterHandle, 2, lPrtInfo2AsByte(0), 0)

If lFlag = 0 Then

lErrorCode = Marshal.GetLastWin32Error()

Console.WriteLine("SetPrinter exited with code : {0}", lErrorCode)

End If

CLEAN_UP:

WinSpool.ClosePrinter(lPrinterHandle) 'Close the handle

End Sub
Nov 21 '05 #3
On 2005-06-03, Just Me <gr****@a-znet.com> wrote:
Anyway, it would be more helpful if we knew exactly what you were
trying to accomplish. It's pretty obvious that your trying to call a
Win32 api of some sort - but knowing which one would be helpful.
Working with API's is, IMHO, significantly different in VB.NET then
VB.CLASSIC.

--
Tom Shelton [MVP]


Thanks

I'm trying to use an old routine for setting the system default printer's
Landscape mode.

Any other suggestion?


The System.Drawing.Printing.PageSettings class?

Dim doc As New PrintDocument ()

doc.DefaultPageSettings.Landscape = True

' Do your printing...

--
Tom Shelton [MVP]
Nov 21 '05 #4
I'm trying to set the system wide orientation properties.

BTW
what are
doc.PrinterSettings.DefaultPageSettings
used for?

I've been trying for a while to find out.

Thanks

"Tom Shelton" <ts******@YOUKNOWTHEDRILLcomcast.net> wrote in message
news:%2****************@TK2MSFTNGP14.phx.gbl...
On 2005-06-03, Just Me <gr****@a-znet.com> wrote:
Anyway, it would be more helpful if we knew exactly what you were
trying to accomplish. It's pretty obvious that your trying to call a
Win32 api of some sort - but knowing which one would be helpful.
Working with API's is, IMHO, significantly different in VB.NET then
VB.CLASSIC.

--
Tom Shelton [MVP]


Thanks

I'm trying to use an old routine for setting the system default
printer's
Landscape mode.

Any other suggestion?


The System.Drawing.Printing.PageSettings class?

Dim doc As New PrintDocument ()

doc.DefaultPageSettings.Landscape = True

' Do your printing...

--
Tom Shelton [MVP]

Nov 21 '05 #5
On 2005-06-04, Just Me <gr****@a-znet.com> wrote:
I'm trying to set the system wide orientation properties.

Well... What can I say. I'm looking at the code. First off, you may
want to spend some time with the interop and marshalling documentation.
At first glance, I think you can dispense with all of the calls to
RtlMoveMemory... You probably can do this using Marshalling attributes
and the methods of the System.Runtime.InteropServices.Marshal class -
though, I will say that this routine would probably be easier to write
in C# using unsafe code (and probably would performe better). I will
try and see if I can get time to convert this function, but right now I
can't promise anything.

Also, you should not EVER call GetLastError from VB.NET (or from VB.CLASSIC
for that matter). The return result is meaningless since the runtime
may call API functions that set that value before you call it. You should
either use Marshal.GetLastWin32Error () or the intrinsic VB.NET Err object's
LastDllError property. Both of thes methods preserve the last user called API
error codes.
BTW
what are
doc.PrinterSettings.DefaultPageSettings
used for?

Setting printer settings... System.Drawing.Printing would be the
relavent namespace to start looking at the docs..
I've been trying for a while to find out.

Thanks

"Tom Shelton" <ts******@YOUKNOWTHEDRILLcomcast.net> wrote in message
news:%2****************@TK2MSFTNGP14.phx.gbl...
On 2005-06-03, Just Me <gr****@a-znet.com> wrote:
Anyway, it would be more helpful if we knew exactly what you were
trying to accomplish. It's pretty obvious that your trying to call a
Win32 api of some sort - but knowing which one would be helpful.
Working with API's is, IMHO, significantly different in VB.NET then
VB.CLASSIC.

--
Tom Shelton [MVP]

Thanks

I'm trying to use an old routine for setting the system default
printer's
Landscape mode.

Any other suggestion?


The System.Drawing.Printing.PageSettings class?

Dim doc As New PrintDocument ()

doc.DefaultPageSettings.Landscape = True

' Do your printing...

--
Tom Shelton [MVP]


--
Tom Shelton [MVP]
Nov 21 '05 #6
Thanks

I took your eariler advise and got rid of the RtlMoveMemory's

I'll keep plugging and learning as I go along.

Thanks

BTW this is where I am now:

Public Shared Sub SetPrinterSettings(ByRef windowHandle As IntPtr, ByRef
printerName As String, ByRef isLandscape As Boolean) ', ByRef aNewPaperSize
As Short, ByRef aNewDuplex As Short)

Dim lPrinterHandle As IntPtr

Dim lFlag As Integer

Dim lPrinterDefaults As WinSpool.PRINTER_DEFAULTS

Dim lErrorCode As Integer

Dim lDevMode As GDI.DEVMODE

Dim lDevModeSize As Integer

Dim lPointerToDevMode As IntPtr

Dim lPrtInfo2 As WinSpool.PRINTER_INFO_2 = New WinSpool.PRINTER_INFO_2

Dim lPrtInfo2Size As Integer

Dim lPointerToPrinterInfo2 As IntPtr

lPrinterDefaults.DesiredAccess = WinSpool.PRINTER_ALL_ACCESS

'lPrinterDefaults.DesiredAccess = WinSpool.PRINTER_ACCESS_ADMINISTER

'Get a handle to the printer.

lFlag = WinSpool.OpenPrinter(printerName, lPrinterHandle, lPrinterDefaults)

If lFlag = 0 Then

lErrorCode = Marshal.GetLastWin32Error()

If lErrorCode = User.ERROR_ACCESS_DENIED Then

MessageBox.Show("Requires adminstrative rights to change default printer",
"Error", MessageBoxButtons.OK, MessageBoxIcon.Exclamation)

End If

Exit Sub

End If

'This GetPrinter call determines the size needed for lPointerToPrinterInfo2

lFlag = WinSpool.GetPrinter(lPrinterHandle, 2, IntPtr.Zero, 0,
lPrtInfo2Size)

If lFlag = 0 Then

lErrorCode = Marshal.GetLastWin32Error()

If lErrorCode <> 122 Then GoTo CLEAN_UP

End If

'Allocate space for lPointerToPrinterInfo2 data

lPointerToPrinterInfo2 = Marshal.AllocCoTaskMem(lPrtInfo2Size)

'The second GetPrinter call fills lPointerToPrinterInfo2 data with the
current settings

lFlag = WinSpool.GetPrinter(lPrinterHandle, 2, lPointerToPrinterInfo2,
lPrtInfo2Size, lPrtInfo2Size)

If lFlag = 0 Then

lErrorCode = Marshal.GetLastWin32Error()

'Console.WriteLine("GetPrinter exited with code : {0}", lErrorCode)

End If

'Copy lPointerToPrinterInfo2 data to the structure

lPrtInfo2 = Marshal.PtrToStructure(lPointerToPrinterInfo2,
lPrtInfo2.GetType)

'Get the total size of the DeviceMode

lDevModeSize = WinSpool.DocumentProperties(windowHandle, lPrinterHandle,
printerName, 0, 0, 0)

'Reserve lPointerToDevMode data memory for the total size of the DeviceMode

lPointerToDevMode = Marshal.AllocCoTaskMem(lDevModeSize)

'Fill the lPointerToDevMode data from the printer driver

lFlag = WinSpool.DocumentProperties(windowHandle, lPrinterHandle,
printerName, lPointerToDevMode, IntPtr.Zero, GDI.DM_OUT_BUFFER)

If lFlag < 0 Then

lErrorCode = Marshal.GetLastWin32Error()

Console.WriteLine("DocumentProperties exited with code: {0}", lErrorCode)

End If

'Copy the lPointerToDevMode data to the structure

lDevMode = Marshal.PtrToStructure(lPointerToDevMode, lDevMode.GetType)

'Set the dmFields bit flag to indicate what we are changing

lDevMode.dmFields = GDI.DM_ORIENTATION 'Or DM_DUPLEX Or DM_PAPERSIZE

If isLandscape Then

lDevMode.dmOrientation = GDI.DMORIENT_LANDSCAPE

Else

lDevMode.dmOrientation = GDI.DMORIENT_PORTRAIT

End If

'Set/Change PaperSize

'lDevMode.dmPaperSize = aNewPaperSize

'On Error Resume Next

'lDevMode.dmDuplex = aNewDuplex

'On Error GoTo 0

'Copy changed structure back to the lPointerToDevMode data

Marshal.StructureToPtr(lDevMode, lPointerToDevMode, True)

'Merge the printer driver's current print settings with the settings in the
lPointerToDevMode data

' lFlag = WinSpool.DocumentProperties(windowHandle, lPrinterHandle,
printerName, lPointerToDevMode, lPointerToDevMode, GDI.DM_IN_BUFFER Or
GDI.DM_OUT_BUFFER)

lFlag = WinSpool.DocumentProperties(windowHandle, lPrinterHandle,
printerName, lPointerToDevMode, lPointerToDevMode, GDI.DM_IN_BUFFER Or
GDI.DM_OUT_BUFFER Or GDI.DM_IN_PROMPT)

lDevMode = Marshal.PtrToStructure(lPointerToDevMode, lDevMode.GetType)

'Copy address of lPointerToDevMode into lPrtInfo2 structure

'Dim objHandle As GCHandle = GCHandle.Alloc(lPointerToDevMode,
GCHandleType.Pinned)

Dim objHandle As GCHandle = GCHandle.Alloc(lDevMode, GCHandleType.Pinned)

Dim objectAddress As IntPtr = objHandle.AddrOfPinnedObject()

lPrtInfo2.pDevMode = objectAddress

lFlag = WinSpool.SetPrinter(lPrinterHandle, 2, lPointerToPrinterInfo2, 0)

If lFlag = 0 Then

lErrorCode = Marshal.GetLastWin32Error()

Console.WriteLine("SetPrinter exited with code : {0}", lErrorCode)

If lErrorCode = 5 Then

MessageBox.Show("Access denied", "Unable To Set Printer",
MessageBoxButtons.OK, MessageBoxIcon.Exclamation)

End If

End If

lFlag = WinSpool.GetPrinter(lPrinterHandle, 2, lPointerToPrinterInfo2,
lPrtInfo2Size, lPrtInfo2Size)

Marshal.StructureToPtr(lDevMode, lPointerToDevMode, True)

CLEAN_UP:

objHandle.Free()

If (lPrinterHandle.ToInt32 <> 0) Then WinSpool.ClosePrinter(lPrinterHandle)

End Sub
Nov 21 '05 #7
Tom,

Thank for the help.
It works now


Nov 21 '05 #8

This thread has been closed and replies have been disabled. Please start a new discussion.

Similar topics

30
by: franky.backeljauw | last post by:
Hello, I am wondering which of these two methods is the fastest: std::copy, which is included in the standard library, or a manually written pointer copy? Do any of you have any experience with...
4
by: xuatla | last post by:
Hi, How to copy a pointer to another pointer? Can I do in the following way: // START double *copyfrom = new double; double *copyto = new double;
25
by: MC | last post by:
Hi I have the following piece of code. int *p; p = malloc(10); int *j; j = p; free(p); Is this legal ? will j still point to the same
11
by: Nindi73 | last post by:
A few days a ago I posted my code for a deep copy pointer which doesn't require the pointee object to have a virtual copy constructor. I need help with checking that it was exception safe and...
10
by: Jason Who | last post by:
I need to make a quick raw copy of a large block of data from one pointer to another. Marshal.Copy let me copy from pointer to array and another call can take it from aray to pointer. That is...
3
by: Immortal_Nephi | last post by:
Sometimes, unsigned char array is located in the file scope. You define A Object and B Object. A Object and B Object need to share unsigned char array. They are very different object. They are...
5
by: DanielJohnson | last post by:
I have two structs as follows: struct i_args{ struct connector *connects; size_t num; }; struct connector{ struct sockaddr_storage addr; int array_num;
0
by: Philip Semanchuk | last post by:
On Oct 22, 2008, at 8:33 PM, Robert Kern wrote: I agree. To deny users of this module access to this param of shmat() would be design arrogance on my part. To do so would be to claim that I...
0
by: taylorcarr | last post by:
A Canon printer is a smart device known for being advanced, efficient, and reliable. It is designed for home, office, and hybrid workspace use and can also be used for a variety of purposes. However,...
0
by: aa123db | last post by:
Variable and constants Use var or let for variables and const fror constants. Var foo ='bar'; Let foo ='bar';const baz ='bar'; Functions function $name$ ($parameters$) { } ...
0
by: ryjfgjl | last post by:
If we have dozens or hundreds of excel to import into the database, if we use the excel import function provided by database editors such as navicat, it will be extremely tedious and time-consuming...
0
by: ryjfgjl | last post by:
In our work, we often receive Excel tables with data in the same format. If we want to analyze these data, it can be difficult to analyze them because the data is spread across multiple Excel files...
0
by: emmanuelkatto | last post by:
Hi All, I am Emmanuel katto from Uganda. I want to ask what challenges you've faced while migrating a website to cloud. Please let me know. Thanks! Emmanuel
0
BarryA
by: BarryA | last post by:
What are the essential steps and strategies outlined in the Data Structures and Algorithms (DSA) roadmap for aspiring data scientists? How can individuals effectively utilize this roadmap to progress...
1
by: Sonnysonu | last post by:
This is the data of csv file 1 2 3 1 2 3 1 2 3 1 2 3 2 3 2 3 3 the lengths should be different i have to store the data by column-wise with in the specific length. suppose the i have to...
0
by: Hystou | last post by:
There are some requirements for setting up RAID: 1. The motherboard and BIOS support RAID configuration. 2. The motherboard has 2 or more available SATA protocol SSD/HDD slots (including MSATA, M.2...
0
jinu1996
by: jinu1996 | last post by:
In today's digital age, having a compelling online presence is paramount for businesses aiming to thrive in a competitive landscape. At the heart of this digital strategy lies an intricately woven...

By using Bytes.com and it's services, you agree to our Privacy Policy and Terms of Use.

To disable or enable advertisements and analytics tracking please visit the manage ads & tracking page.