Jump to content
Xtreme .Net Talk

Recommended Posts

  • Administrators
Posted

Have you looked at http://www.pinvoke.net - there are an awful lot of P/Invoke declarations there.

 

Other than that the common conversions from VB6 are normally Longs become Integers or IntPtrs and Integers become Shorts. In fact if you are using VS 2005 it even gives you a menu entry under the Tools menu to convert VB6 code that might help in converting simple Declare statements.

 

Other than that which parts of the post are relevant as there may be an easier or an alternate way that won't involve interop and P/Invoke.

Posting Guidelines FAQ Post Formatting

 

Intellectuals solve problems; geniuses prevent them.

-- Albert Einstein

Posted
Have you looked at http://www.pinvoke.net - there are an awful lot of P/Invoke declarations there.

 

No I haven't, cause I don't know exactly how to look for what I want... I know that the above code will work, cause the example used is almost what I want to do...

 

Other than that the common conversions from VB6 are normally Longs become Integers or IntPtrs and Integers become Shorts. In fact if you are using VS 2005 it even gives you a menu entry under the Tools menu to convert VB6 code that might help in converting simple Declare statements.

 

I'll try to convert it again and post the results here...

Posted

This is the code from DrMemory converted to VB.NET:

 

DrMemory.vb

[VBNET]'=======================================================================

'

' drMemory - Cross-Process Memory Buffer support

'

' © 2003 "Dr Memory" ==> Jim White

' MathImagics

' Uki, NSW, Australia

' Puttenham, Surrey, UK

'

' This module contains functions that provide both WinNT and Win9x

' style cross-process memory buffer allocation, read and write

' functions.

'

' These functions are typically required when trying to use

' SendMessage to exchange data with windows in another process.

'

'

'=======================================================================

' Usage guide:

'

' 1. Allocate buffer(s) in the target process

'

' xpWindow& = <<target control window handle>>

' xpBuffer& = drMemoryAlloc(xpWindow, nBytes)

'

' 2. Prepare the data to be passed to the control

' and copy it into the buffer

'

' drMemoryWrite xpBuffer, myBuffer, nBytes

'

' 3. SendMessage xpWindow, MSG_CODE, wParam, ByVal xpBuffer

' ==============

'

' 4. Extract return data

'

' drMemoryRead xpBuffer, myBuffer, nBytes

'

' (repeat 3/4 as necessary)

'

' 5. Release the buffer

'

' drMemoryFree xpBuffer

'

'=======================================================================

 

Imports System.Runtime.InteropServices

 

Module DrMemory

 

Private PlatformKnown As Boolean ' have we identified the platform?

Private NTflag As Boolean ' if so, are we NT family (NT, 2K,XP) or non-NT (9x)?

 

Private fpHandle As Integer ' the foreign-process instance handle. When we want

' memory on NT platforms, this is returned to us by

' OpenProcess, and we pass it in to VirtualAllocEx.

 

' We must preserve it, as we need it for read/write

' operations, and to release the memory when we've

' finished with it.

 

' For this reason, on NT/2K/XP platforms this module should only be used to

' interface with ONE TARGET PROCESS at a time. In the future I'll rewrite

' this as a class, which can handle multiple-targets, automatic allocation

' de-allocation, etc

'

 

Private WIN As OperatingSystem = Environment.OSVersion

 

'================== Win95/98 Process Memory functions

Private Declare Function CreateFileMapping Lib "kernel32" (ByVal hFile As Integer, ByVal lpFileMappigAttributes As Integer, ByVal flProtect As Integer, ByVal dwMaximumSizeHigh As Integer, ByVal dwMaximumSizeLow As Integer, ByVal lpName As String) As Integer

Private Declare Function MapViewOfFile Lib "kernel32" (ByVal hFileMappingObject As Integer, ByVal dwDesiredAccess As Integer, ByVal dwFileOffsetHigh As Integer, ByVal dwFileOffsetLow As Integer, ByVal dwNumberOfBytesToMap As Integer) As Integer

Private Declare Function UnmapViewOfFile Lib "kernel32" (ByRef lpBaseAddress As Integer) As Integer

Private Declare Function CloseHandle Lib "kernel32" (ByVal hObject As Integer) As Integer

 

'================== WinNT/2000 Process Memory functions

Private Declare Function OpenProcess Lib "kernel32" (ByVal dwDesiredAccess As Integer, ByVal bInheritHandle As Integer, ByVal dwProcId As Integer) As Integer

Private Declare Function VirtualAllocEx Lib "kernel32" (ByVal hProcess As Integer, ByVal lpAddress As Integer, ByVal dwSize As Integer, ByVal flAllocationType As Integer, ByVal flProtect As Integer) As Integer

Private Declare Function VirtualFreeEx Lib "kernel32" (ByVal hProcess As Integer, ByVal lpAddress As Integer, ByVal dwSize As Integer, ByVal dwFreeType As Integer) As Integer

Private Declare Function WriteProcessMemory Lib "kernel32" (ByVal hProcess As Integer, ByVal lpBaseAddress As Integer, ByVal lpBuffer As Integer, ByVal nSize As Integer, ByRef lpNumberOfBytesWritten As Integer) As Integer

Private Declare Function ReadProcessMemory Lib "kernel32" (ByVal hProcess As Integer, ByVal lpBaseAddress As Integer, ByVal lpBuffer As Integer, ByVal nSize As Integer, ByRef lpNumberOfBytesWritten As Integer) As Integer

 

'================== Common Platform

Private Declare Function GetWindowThreadProcessId Lib "user32" (ByVal hwnd As Integer, ByRef lpdwProcessId As Integer) As Integer

Private Declare Sub CopyMemory Lib "kernel32" (ByVal lpDest As Integer, ByVal lpSource As Integer, ByVal cBytes As Integer)

Private Declare Function lstrlenA Lib "kernel32" (ByVal lpsz As Integer) As Integer

Private Declare Function lstrlenW Lib "kernel32" (ByVal lpString As Integer) As Integer

Private Declare Function GetClassName Lib "user32" (ByVal hwnd As Integer, ByVal lpClassName As String, ByVal nMaxCount As Integer) As Integer

Public Declare Function GetParent Lib "user32" (ByVal hwnd As Integer) As Integer

 

 

' ----------

Const PAGE_READWRITE As Short = &H4S

Const MEM_RESERVE As Integer = &H2000

Const MEM_RELEASE As Integer = &H8000

Const MEM_COMMIT As Integer = &H1000

Const PROCESS_VM_OPERATION As Short = &H8S

Const PROCESS_VM_READ As Short = &H10S

Const PROCESS_VM_WRITE As Short = &H20S

Const STANDARD_RIGHTS_REQUIRED As Integer = &HF0000

Const SECTION_QUERY As Short = &H1S

Const SECTION_MAP_WRITE As Short = &H2S

Const SECTION_MAP_READ As Short = &H4S

Const SECTION_MAP_EXECUTE As Short = &H8S

Const SECTION_EXTEND_SIZE As Short = &H10S

Const SECTION_ALL_ACCESS As Boolean = CBool(STANDARD_RIGHTS_REQUIRED Or SECTION_QUERY Or SECTION_MAP_WRITE Or SECTION_MAP_READ Or SECTION_MAP_EXECUTE Or SECTION_EXTEND_SIZE)

Const FILE_MAP_ALL_ACCESS As Boolean = SECTION_ALL_ACCESS

 

 

Public Function drMemoryAlloc(ByVal xpWindow As Integer, ByVal nBytes As Integer) As Integer

'

' Returns pointer to a share-able buffer (size nBytes) in target process

' that owns xpWindow

'

Dim xpThread As Integer ' target control's thread id

Dim xpID As Integer ' process id

If WindowsNT() Then

xpThread = GetWindowThreadProcessId(xpWindow, xpID)

drMemoryAlloc = VirtualAllocNT(xpID, nBytes)

Else

drMemoryAlloc = VirtualAlloc9X(nBytes)

End If

End Function

 

Public Sub drMemoryFree(ByVal mPointer As Integer)

If WindowsNT() Then

VirtualFreeNT(mPointer)

Else

VirtualFree9X(mPointer)

End If

End Sub

 

Public Sub drMemoryRead(ByVal xpBuffer As Integer, ByVal myBuffer As Integer, ByVal nBytes As Integer)

If WindowsNT() Then

ReadProcessMemory(fpHandle, xpBuffer, myBuffer, nBytes, 0)

Else

CopyMemory(myBuffer, xpBuffer, nBytes)

End If

End Sub

 

Public Sub drMemoryWrite(ByVal xpBuffer As Integer, ByVal myBuffer As Integer, ByVal nBytes As Integer)

If WindowsNT() Then

WriteProcessMemory(fpHandle, xpBuffer, myBuffer, nBytes, 0)

Else

CopyMemory(xpBuffer, myBuffer, nBytes)

End If

End Sub

 

Public Function WindowsNT() As Boolean

' return TRUE if NT-like platform (NT, 2000, XP, etc)

If Not PlatformKnown Then GetWindowsVersion()

WindowsNT = NTflag

End Function

 

Public Function WindowsXP() As Boolean

' return TRUE only if XP

If Not PlatformKnown Then GetWindowsVersion()

WindowsXP = NTflag And (WIN.Version.MinorRevision <> 0)

End Function

 

Public Sub GetWindowsVersion()

If WIN.Platform = PlatformID.Win32NT Then

NTflag = True

PlatformKnown = True

ElseIf WIN.Platform = PlatformID.Win32Windows Then

PlatformKnown = True

End If

End Sub

 

'============================================

' The NT/2000 Allocate and Release functions

'============================================

 

Private Function VirtualAllocNT(ByVal fpID As Integer, ByVal memSize As Integer) As Integer

fpHandle = OpenProcess(PROCESS_VM_OPERATION Or PROCESS_VM_READ Or PROCESS_VM_WRITE, CInt(False), fpID)

VirtualAllocNT = VirtualAllocEx(fpHandle, 0, memSize, MEM_RESERVE Or MEM_COMMIT, PAGE_READWRITE)

End Function

 

Private Sub VirtualFreeNT(ByVal MemAddress As Integer)

Call VirtualFreeEx(fpHandle, MemAddress, 0, MEM_RELEASE)

CloseHandle(fpHandle)

End Sub

 

'============================================

' The 95/98 Allocate and Release functions

'============================================

 

Private Function VirtualAlloc9X(ByVal memSize As Integer) As Integer

fpHandle = CreateFileMapping(&HFFFFFFFF, 0, PAGE_READWRITE, 0, memSize, vbNullString)

VirtualAlloc9X = MapViewOfFile(fpHandle, CInt(FILE_MAP_ALL_ACCESS), 0, 0, 0)

End Function

 

Private Sub VirtualFree9X(ByVal lpMem As Integer)

UnmapViewOfFile(lpMem)

CloseHandle(fpHandle)

End Sub

 

Public Function dmWindowClass(ByVal hWindow As Integer) As String

Dim className As String

Dim cLen As Integer

className = New String(Chr(0), 64)

cLen = GetClassName(hWindow, className, 63)

If cLen > 0 Then className = Left(className, cLen)

dmWindowClass = className

End Function

 

End Module[/VBNET]

Posted

And the rest of the code is the following. The program compiles and runs but it doesn't work as expected.

 

Program.vb

[VBNET]Imports System.Runtime.InteropServices

Imports TrayTest.Common

 

Module Program

Public Const WM_USER As Short = &H400S

Public Const TB_GETBUTTON As Integer = (WM_USER + 23)

Public Const TB_BUTTONCOUNT As Integer = (WM_USER + 24)

Public Const TB_COMMANDTOINDEX As Integer = (WM_USER + 25)

Public Const TB_GETBUTTONTEXTA As Integer = (WM_USER + 45)

 

Public Sub Main()

Dim hWndTray As IntPtr = GetToolbarWindowHandle()

GetToolbarButtons(hWndTray)

End Sub

 

Private Function GetToolbarWindowHandle() As IntPtr

Dim hWnd As IntPtr

 

hWnd = User32.FindWindow("Shell_TrayWnd", Nothing)

hWnd = User32.FindWindowEx(hWnd, Nothing, "TrayNotifyWnd", Nothing)

hWnd = User32.FindWindowEx(hWnd, Nothing, "SysPager", Nothing)

hWnd = User32.FindWindowEx(hWnd, Nothing, "ToolbarWindow32", Nothing)

 

Return hWnd

End Function

 

Private Sub GetToolbarButtons(ByVal hWndTray As IntPtr)

Dim bInfo As TBBUTTON

 

Dim xpBuffer As Integer

Dim bText As String

 

Dim tbCount As Integer

Dim lret As Integer

 

' Get button count

tbCount = User32.SendMessage(hWndTray, TB_BUTTONCOUNT, 0, 0)

 

If tbCount <= 0 Then Exit Sub

 

' Need a buffer? Ask Dr Memory!

xpBuffer = drMemoryAlloc(CInt(hWndTray), 4096)

 

For tbIndex As Integer = 0 To tbCount - 1

' TB_GETBUTTON

User32.SendMessage(hWndTray, TB_GETBUTTON, tbIndex, xpBuffer)

drMemoryRead(xpBuffer, VarPtr(bInfo), Len(bInfo))

 

lret = User32.SendMessage(hWndTray, TB_GETBUTTONTEXTA, bInfo.idCommand, xpBuffer)

 

If lret > 0 Then

bText = New String(Chr(0), lret + 1)

drMemoryRead(xpBuffer, VarPtr(bText), lret)

Else

bText = ""

End If

Next

 

drMemoryFree(xpBuffer)

End Sub

 

Private Function VarPtr(ByVal o As Object) As Integer

Dim GC As GCHandle = GCHandle.Alloc(o, GCHandleType.Pinned)

Dim vAddress As IntPtr = GC.AddrOfPinnedObject

 

GC.Free()

 

Return Marshal.ReadInt32(vAddress)

End Function

 

End Module[/VBNET]

 

User32.vb

[VBNET]Imports System.Runtime.InteropServices

 

Namespace Common

 

#Region " Strcuture Declarations "

 

<StructLayout(LayoutKind.Sequential)> _

Friend Structure TBBUTTON

Public iBitmap As Integer

Public idCommand As Integer

Public fsState As Byte

Public fsStyle As Byte

Public bReserved1 As Byte

Public bReserved2 As Byte

Public dwData As Integer

Public iString As Integer

End Structure

 

#End Region

 

#Region " API Declarations "

 

Friend Class User32

<DllImport("user32.dll")> _

Public Shared Function SendMessage( _

ByVal hWnd As IntPtr, _

ByVal msg As Integer, _

ByVal wParam As Integer, _

ByVal lParam As Integer) As Integer

End Function

 

<DllImport("user32.dll", CharSet:=CharSet.Auto)> _

Public Shared Function FindWindow( _

ByVal lpClassName As String, _

ByVal lpWindowName As String) As IntPtr

End Function

 

<DllImport("user32.dll", CharSet:=CharSet.Unicode)> _

Public Shared Function FindWindowEx( _

ByVal hwndParent As IntPtr, _

ByVal hwndChildAfter As IntPtr, _

ByVal lpszClass As String, _

ByVal lpszWindow As String) As IntPtr

End Function

End Class

 

#End Region

 

End Namespace[/VBNET]

 

What code program do and what's supposed to do:

First, it will find the systray (notification area) window handler, count all the toolbar buttons (icons in the systray) and then get the text (tooltip) from each button and store it in bText. The tooltip value isn't saved, the code just loops through every button, get's the text and does nothing with it. This is what the code is supposed to do. Everything works except the part to get the tooltip text from the button. I don't understand why but bInfo is always "empty" (zeros in most values).

 

Any suggestions?

Posted

Here it is... The variable bText is supposed to get the tooltip from each systray icon (doesn't do anything with it, but while debugging I checked and there was only an empty string). Also bInfo values should have some values in each structure element but they are all the same through the button loop and almost all zeros.

 

Hope you find a way to sort it out, I must be doing something wrong...

TrayTest.zip

  • 4 months later...
Guest
Reply to this topic...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

×
×
  • Create New...