?
Solved

ListView and SendMessage

Posted on 2006-04-28
22
Medium Priority
?
1,653 Views
Last Modified: 2012-06-27
I have a ListView in C# but needed to do some code in delphi, so i made a Dll in delphi and pass it the ListView handle.

i can add items, using the listview handle, but any items i do add are not in ListView.Items, so is there a way to populate Items with the actual items in the list.
0
Comment
Question by:heretoread
  • 10
  • 10
  • +1
22 Comments
 
LVL 96

Expert Comment

by:Bob Learned
ID: 16566546
1) Why Delphi?

2) How are you interfacing with the Delphi DLL?

Bob
0
 
LVL 11

Expert Comment

by:vo1d
ID: 16566992
of course the listviewitems are not in ListView.Items, because it is a .net collection, which is not updated if an item is added from outside the collection.
if you wanna do it this way, you will have to make it with win32 api and use some of the LVM and LVN messages and more  but that is alot of work.why do you have to go with a delphi dll?
0
 
LVL 48

Expert Comment

by:AlexFM
ID: 16567584
Change interface of Delphi Dll. It must create string or list of strings, and pass them to C# client using parameters. C# client must fill ListView itself, it is impossible to do from unmanaged code.
0
What does it mean to be "Always On"?

Is your cloud always on? With an Always On cloud you won't have to worry about downtime for maintenance or software application code updates, ensuring that your bottom line isn't affected.

 
LVL 11

Expert Comment

by:vo1d
ID: 16568333
the listview gets a listviewnotify message if a listviewitem is added. you will have 2 possibilities:
1.if such a message arrived, get the nodehandle of that node, remove the node via windowsmessage and add the node in managed code to the ListView.Items collection.
2.you will do all by windowsmessages.

both possibilities are not the best solution, so i still got the question, why do you need an extra delphi dll?
0
 
LVL 2

Author Comment

by:heretoread
ID: 16568613
I did the dll in delphi because it uses various ntdll.dll api to obtain some information and i'm not sure if C# can handle the same code.

I need to allocate memory for a struct, then if it's to small reallocate more memory.
0
 
LVL 11

Expert Comment

by:vo1d
ID: 16568749
yes you can with the marshal class.
here is an example:
http://blogs.msdn.com/jeremykuhne/archive/2005/07/19/440264.aspx
0
 
LVL 2

Author Comment

by:heretoread
ID: 16568867
hmm, this is what i'm using in Delphi, i would prefer to have it in C#, Points to anyone who can port this to C#.

type
  SYSTEM_HANDLE_INFORMATION = packed record
    NumberOfHandles: Integer;
    Handles: array[0..0] of SYSTEM_HANDLE_TABLE_ENTRY_INFO;
  end;
  PSYSTEM_HANDLE_INFORMATION = ^SYSTEM_HANDLE_INFORMATION;

var
  P:PSYSTEM_HANDLE_INFORMATION;
  N, dummy:Integer;
begin
N:= $1000;
GetMem(P, N * SizeOf(Integer));
Status:= NtQuerySystemInformation(SystemHandleInformation, P, N * SizeOf(Integer), dummy);
while Status = STATUS_INFO_LENGTH_MISMATCH do begin
  N:= N * 2;
  ReAllocMem(P, N * SizeOf(Integer));
  Status:= NtQuerySystemInformation(SystemHandleInformation, P, N * SizeOf(Integer), dummy);
end;
0
 
LVL 11

Expert Comment

by:vo1d
ID: 16570447
could you post the info for SYSTEM_HANDLE_TABLE_ENTRY_INFO please?
0
 
LVL 2

Author Comment

by:heretoread
ID: 16572325
 SYSTEM_HANDLE_TABLE_ENTRY_INFO = packed record
    UniqueProcessId: Word;
    CreatorBackTraceIndex: Word;
    ObjectTypeIndex: Byte;
    HandleAttributes: Byte;
    HandleValue: Word;
    Object_: THandle;
    GrantedAccess: ACCESS_MASK;
  end;

function NtQuerySystemInformation(dwInfoType: Integer; lpStructure: Pointer; dwSize: Integer; var dwReserved: Integer): ULONG; stdcall; external 'ntdll.dll';
0
 
LVL 11

Expert Comment

by:vo1d
ID: 16572940
and ACCESS_MASK ?
0
 
LVL 2

Author Comment

by:heretoread
ID: 16573755
ACCESS_MASK, THandle = LongWord.
0
 
LVL 2

Author Comment

by:heretoread
ID: 16590321
Can you let me know if it's possible, the project is on halt while i'm waiting, so i need to know if it can be done in C# or if i'm going to recode the dll.
0
 
LVL 11

Expert Comment

by:vo1d
ID: 16598300
yes it can be done, im very busy right now but i will try to make it tomorrow. is it ok for you?
0
 
LVL 2

Author Comment

by:heretoread
ID: 16601044
Yep, i just needed to know if i should wait or just use my delphi dll.
points are waiting for you :)
0
 
LVL 11

Expert Comment

by:vo1d
ID: 16607625
could you please tell me, what information you are trying to get from the system?
i took a look at msdn for the specification of NtQuerySystemInformation but did not found a param like: SYSTEM_HANDLE_INFORMATION

do you wanna get the handlìnfo for a process or something like that?
please specify because i think, there will be a predefined equivalent in the framework.

one more comment to NtQuerySystemInformation. a remark from msdn is as follows:
The NtQuerySystemInformation function and the structures that it returns are internal to the operating system and subject to change from one release of Windows to another. To maintain the compatibility of your application, it is better to the alternate functions mentioned above instead.

please answer so that i'm able to decide, if there is an equivalent or not.
if not, i will make some code for that.
0
 
LVL 2

Author Comment

by:heretoread
ID: 16609378
There are a lot of internal functions that are subject to change, but i dought they would as a lot of software uses them.

SYSTEM_HANDLE_INFORMATION is an array of all the handles open on the system. There is a handles property in the process class, but that only has handle count.
0
 
LVL 11

Expert Comment

by:vo1d
ID: 16620886
so you are trying to get all running processes of the local system?
you can get it with this command:
System.Diagnostics.Process[] sysProcesses = System.Diagnostics.Process.GetProcesses();
0
 
LVL 2

Author Comment

by:heretoread
ID: 16621083
This is going nowhere, I'm trying to get info specific to a SINGLE process.
If you are unable to do what i ask just say.
0
 
LVL 11

Expert Comment

by:vo1d
ID: 16621525
im not unable to do what you ask for but why reinvent the wheel, if there could be a predefined methods.
you just have to explain, what's the information you need so i could check out, if that solution comes directly from the framework or not.
you say, you need specific process information, thats all. that is not much information.
so for that, the solution is the method i gave you. you will have all the information about ALL running processes like their handles, modules, threads etc.
going through pinvoke of the framework is not necessary in many cases because their are much managed equivalent objects / methods.


0
 
LVL 2

Author Comment

by:heretoread
ID: 16623038
The process class doesn't have what i need, hence the question here.
It has the Process handle and handle count, but not an actual array of open handles.
0
 
LVL 11

Accepted Solution

by:
vo1d earned 2000 total points
ID: 16625721
you have to compile this example with /unsafe:

using System;
using System.Text;
using System.Diagnostics;
using System.Runtime.InteropServices;
using System.ComponentModel;

namespace ConsoleApplication2
{
    class Program
    {
        private static int STATUS_INFO_LENGTH_MISMATCH      = -1073741820;        
       
        [StructLayout(LayoutKind.Sequential)]
            public class SYSTEM_HANDLE_INFORMATION
            {
                  public int NumberOfHandles;                  
                  public IntPtr Handles;
                  public SYSTEM_HANDLE_INFORMATION(){}
            }
      
            [StructLayout(LayoutKind.Sequential)]
            public struct SYSTEM_HANDLE_TABLE_ENTRY_INFO
            {
                  public ushort      UniqueProcessId;
                  public ushort      CreatorBackTraceIndex;
                  public byte            ObjectTypeIndex;
                  public byte            HandleAttributes;
                  public ushort      HandleValue;
                  public IntPtr      Object;
                  public IntPtr      GrantedAccess;
            }
               
            [DllImport("ntdll.dll", CharSet=CharSet.Auto)]
            public static extern int NtQuerySystemInformation(int query, IntPtr dataPtr, int size, out int returnedSize);
 
            private static unsafe void GetHandleInfos(IntPtr dataPtr)
            {                  
                  SYSTEM_HANDLE_INFORMATION handleInfo                  = Marshal.PtrToStructure(dataPtr, typeof(SYSTEM_HANDLE_INFORMATION)) as SYSTEM_HANDLE_INFORMATION;
                  IntPtr pHandleTableInfo                                          = handleInfo.Handles;
                  SYSTEM_HANDLE_TABLE_ENTRY_INFO* pCurrentHandle      = ((SYSTEM_HANDLE_TABLE_ENTRY_INFO*)( &pHandleTableInfo));
                  
                  for(int handleCount = 0; handleCount < handleInfo.NumberOfHandles; handleCount++)
                  {                        
                        //do whatever you want with the current handle entry                        
                        pCurrentHandle++;                        
                  }                  
            }
            
        static void Main(string[] args)
        {                  
                  int dwSize1 = Marshal.SizeOf(typeof(SYSTEM_HANDLE_INFORMATION));
                  int dwSize2 = 0;
                  IntPtr ptr = Marshal.AllocHGlobal(dwSize1);
                  try
                  {
                        int result = NtQuerySystemInformation(0x10, ptr, dwSize1, out dwSize2);
                        while(result == STATUS_INFO_LENGTH_MISMATCH)
                        {                               
                                dwSize1 <<= 1;
                                Marshal.FreeHGlobal(ptr);
                                ptr = Marshal.AllocHGlobal(dwSize1);
                                result = NtQuerySystemInformation(0x10, ptr, dwSize1, out dwSize2);                               
                        }
                        if (result < 0)
                        {
                                throw new InvalidOperationException("Could not get System handle info", new Win32Exception(result));
                        }
                        GetHandleInfos(ptr);
                  }
                  finally
                  {
                        Marshal.FreeHGlobal(ptr);
                  }
        }
    }
}

0
 
LVL 2

Author Comment

by:heretoread
ID: 16626735
Thanks, Great help.
0

Featured Post

Concerto Cloud for Software Providers & ISVs

Can Concerto Cloud Services help you focus on evolving your application offerings, while delivering the best cloud experience to your customers? From DevOps to revenue models and customer support, the answer is yes!

Learn how Concerto can help you.

Question has a verified solution.

If you are experiencing a similar issue, please ask a related question

This article introduced a TextBox that supports transparent background.   Introduction TextBox is the most widely used control component in GUI design. Most GUI controls do not support transparent background and more or less do not have the…
Introduction Hi all and welcome to my first article on Experts Exchange. A while ago, someone asked me if i could do some tutorials on object oriented programming. I decided to do them on C#. Now you may ask me, why's that? Well, one of the re…
This Micro Tutorial will teach you how to add a cinematic look to any film or video out there. There are very few simple steps that you will follow to do so. This will be demonstrated using Adobe Premiere Pro CS6.
When cloud platforms entered the scene, users and companies jumped on board to take advantage of the many benefits, like the ability to work and connect with company information from various locations. What many didn't foresee was the increased risk…
Suggested Courses

850 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question