If one or more dynamic listbox objects were created via the SendListDynamic LDL command during the execution of an ispec transaction, those listbox objects is available in the returned GenericClass object.
This method can be used to retrieve a listbox object. The index of the required listbox is passed as a parameter. The index is zero-based, with the first listbox always having an index of 0.
The listbox object is returned as an IStream pointer containing the contents of the listbox. The first four bytes of each listbox row contains the number of bytes in that row. To process the listbox information in the IStream you should do the following:
Read the first four bytes and convert to a number — this is the row length.
Read the next <row length> bytes this is the first row of listbox data.
Repeat until end-of-stream.
The listbox data is encoded as Unicode for a dynamic list. In a MultiByte system (Japanese) the listbox data is encoded as Shift-JIS.
The following is sample Managed C++ code to retrieve and process a dynamic listbox object:
GenericClass::IStream* pList = pOutput->GetDynamicList(0); System::Runtime::InteropServices::ComTypes::IStream *managedList; managedList = __try_cast<System::Runtime::InteropServices::ComTypes::IStream*>(pList); System::Runtime::InteropServices::ComTypes::STATSTG stats; managedList->Stat(&stats, 0); String* listName = stats.pwcsName; do { //read the first 4 bytes to find out the size of the following item. unsigned char buffer __gc[] = new unsigned char __gc[4]; System::IntPtr bytesRead = new int; managedList->Read(buffer, 4, bytesRead); unsigned int * bytesReadPtr = (unsigned int*)bytesRead.ToPointer(); if (*bytesReadPtr == 0) { break; // EOF - break out of the loop } unsigned int rowLength = System::BitConverter::ToUInt32(buffer, 0); //read the next <rowlength> bytes with the item into a String. buffer = new unsigned char __gc[rowLength]; managedList->Read(buffer, rowLength, bytesRead); bytesReadPtr = (unsigned int*)bytesRead.ToPointer(); System::String* rowData; Encoding * unicodeChars = Encoding::Unicode; Char myChars[] = new Char[unicodeChars->GetCharCount(buffer)]; unicodeChars->GetChars(buffer, 0, buffer->Length, myChars, 0); rowData = new String(myChars); // rowdata contains a single listbox file line - process it here. }
The following is sample Managed C# code to retrieve and process a dynamic listbox object:
GenericClass.IStream DynList = outParams.GetDynamicList(i); System.Runtime.InteropServices.ComTypes.IStream managedList; managedList = (System.Runtime.InteropServices.ComTypes.IStream)(DynList); System.Runtime.InteropServices.ComTypes.STATSTG stats = new System.Runtime.InteropServices.ComTypes.STATSTG(); managedList.Stat(out stats, 0); string listName = stats.pwcsName; unsafe { string rowData; byte[] Buffer = new byte[4]; int bytesRead = 0; int* ptr = &bytesRead; do { managedList.Read(Buffer, 4, (IntPtr)ptr); uint bytesReadPtr = (uint)bytesRead; if (bytesReadPtr == 0) Stop = true; else { int rowLength = System.BitConverter.ToInt32(Buffer, 0); Buffer = new byte[rowLength]; managedList.Read(Buffer, rowLength, (IntPtr)ptr); bytesReadPtr = (uint)(bytesRead); //Dynamic ListBoxes are encoded in UNICODE rowData = System.Text.UnicodeEncoding.Unicode.GetString(Buffer,0,rowLength); // rowData contains a single listbox row process it here } } }