Skip to content
  • Categories
  • Recent
  • Tags
  • Popular
  • World
  • Users
  • Groups
Skins
  • Light
  • Cerulean
  • Cosmo
  • Flatly
  • Journal
  • Litera
  • Lumen
  • Lux
  • Materia
  • Minty
  • Morph
  • Pulse
  • Sandstone
  • Simplex
  • Sketchy
  • Spacelab
  • United
  • Yeti
  • Zephyr
  • Dark
  • Cyborg
  • Darkly
  • Quartz
  • Slate
  • Solar
  • Superhero
  • Vapor

  • Default (No Skin)
  • No Skin
Collapse
Code Project
  1. Home
  2. General Programming
  3. COM
  4. SAFEARRAY - Multidimensions

SAFEARRAY - Multidimensions

Scheduled Pinned Locked Moved COM
questionc++data-structuresworkspace
2 Posts 2 Posters 3 Views 1 Watching
  • Oldest to Newest
  • Newest to Oldest
  • Most Votes
Reply
  • Reply as topic
Log in to reply
This topic has been deleted. Only users with topic management privileges can see it.
  • D Offline
    D Offline
    Dave Loeser
    wrote on last edited by
    #1

    Hey all, I'm working on a component that returns a SAFEARRAY. Here's the IDL for the method as well as the C++ declaration: [id(2), helpstring("List of Report Type (Names) available to a user on a specific date")] HRESULT GetReportTypes([in] BSTR UserID, [in] INT CloseDate, [out, retval] VARIANT* pReportTypes); STDMETHODIMP CReports::GetReportTypes(BSTR UserID, INT CloseDate, VARIANT *pReportTypes) Now without loading this up with a ton of code I'll explain what I am doing and then show the important parts of the code. Basically, I want to return a SAFEARRAY that is mulitdimensionl, in this case the array is [x][1] in size and x is determined by the number of records retrieved. So here's how I'm creating the SAFEARRAY: // Setup/Create our SAFEARRAY SAFEARRAYBOUND SABounds[2]; SABounds[0].cElements = (DWORD)pRsHPASReports->RecordCount + 1; // Why do I need to add 1 to this??? SABounds[1].cElements = SABounds[0].cElements; SABounds[0].lLbound = 0; SABounds[1].lLbound = 0; // Initialize the variant and set it up as an array of variants VariantInit(pReportTypes); pReportTypes->vt = VT_VARIANT | VT_ARRAY; pReportTypes->parray = SafeArrayCreate(VT_VARIANT, 2, SABounds); and then after opening the recordset I loop through the records filling in the SAFEARRAY with my data, like so: while(! pRsHPASReports->IsEOF) { ldimension[0] = lLoop++; ldimension[1] = 0; CComVariant bstrTmp( pRsHPASReports->Fields->Item["RptType"]->Value ); TESTHR(SafeArrayPutElement( pReportTypes->parray, ldimension, &bstrTmp )); ldimension[1] = 1; CComVariant bstrTmp2( pRsHPASReports->Fields->Item["Title"]->Value ); TESTHR(SafeArrayPutElement( pReportTypes->parray, ldimension, &bstrTmp2 )); pRsHPASReports->MoveNext(); } pretty standard stuff, right? Well, as you can see from the comment above, If I have a record count of 1 then the SAFEARRAY does not appear to be initialized properly... I'm forced to add 1 to the count so that I can build the array. My question is why can't I create a SAFEARRAY with a size [1][1]? On the client side, when checking the bounds on the SAFEARRAY I see 0 to 1 ... yet the element at postion 1 is empty. I've looked high and low on the web for a soloution and have not been successful... So, anyone know how I can create a SAFEARRAY with just one element? Thanks, Dave "Dak Lozar" Loeser

    V 1 Reply Last reply
    0
    • D Dave Loeser

      Hey all, I'm working on a component that returns a SAFEARRAY. Here's the IDL for the method as well as the C++ declaration: [id(2), helpstring("List of Report Type (Names) available to a user on a specific date")] HRESULT GetReportTypes([in] BSTR UserID, [in] INT CloseDate, [out, retval] VARIANT* pReportTypes); STDMETHODIMP CReports::GetReportTypes(BSTR UserID, INT CloseDate, VARIANT *pReportTypes) Now without loading this up with a ton of code I'll explain what I am doing and then show the important parts of the code. Basically, I want to return a SAFEARRAY that is mulitdimensionl, in this case the array is [x][1] in size and x is determined by the number of records retrieved. So here's how I'm creating the SAFEARRAY: // Setup/Create our SAFEARRAY SAFEARRAYBOUND SABounds[2]; SABounds[0].cElements = (DWORD)pRsHPASReports->RecordCount + 1; // Why do I need to add 1 to this??? SABounds[1].cElements = SABounds[0].cElements; SABounds[0].lLbound = 0; SABounds[1].lLbound = 0; // Initialize the variant and set it up as an array of variants VariantInit(pReportTypes); pReportTypes->vt = VT_VARIANT | VT_ARRAY; pReportTypes->parray = SafeArrayCreate(VT_VARIANT, 2, SABounds); and then after opening the recordset I loop through the records filling in the SAFEARRAY with my data, like so: while(! pRsHPASReports->IsEOF) { ldimension[0] = lLoop++; ldimension[1] = 0; CComVariant bstrTmp( pRsHPASReports->Fields->Item["RptType"]->Value ); TESTHR(SafeArrayPutElement( pReportTypes->parray, ldimension, &bstrTmp )); ldimension[1] = 1; CComVariant bstrTmp2( pRsHPASReports->Fields->Item["Title"]->Value ); TESTHR(SafeArrayPutElement( pReportTypes->parray, ldimension, &bstrTmp2 )); pRsHPASReports->MoveNext(); } pretty standard stuff, right? Well, as you can see from the comment above, If I have a record count of 1 then the SAFEARRAY does not appear to be initialized properly... I'm forced to add 1 to the count so that I can build the array. My question is why can't I create a SAFEARRAY with a size [1][1]? On the client side, when checking the bounds on the SAFEARRAY I see 0 to 1 ... yet the element at postion 1 is empty. I've looked high and low on the web for a soloution and have not been successful... So, anyone know how I can create a SAFEARRAY with just one element? Thanks, Dave "Dak Lozar" Loeser

      V Offline
      V Offline
      Vi2
      wrote on last edited by
      #2

      If you want to have the VB array (a to b) in i-th dimension bounds, you should initialize the SABounds[i].lLbound = a; and SABounds[i].cElements = b-a+1; As a rule, a is equal 0, so cElements = b-0+1 and = b+1. But RecordCount is equal to size of array (cElements), therefore, you haven't to add extra "1". Your array in VB will have (0 to x-1) bounds.

      // Setup/Create our SAFEARRAY
      SAFEARRAYBOUND SABounds[2];
      SABounds[0].cElements = (DWORD)pRsHPASReports->RecordCount;
      SABounds[0].lLbound = 0;
      SABounds[1].cElements = 2; // You have only [0] and [1] in this dimension. Ok?
      SABounds[1].lLbound = 0;

      // Initialize the variant and set it up as an array of variants
      VariantInit(pReportTypes);
      pReportTypes->vt = VT_VARIANT | VT_ARRAY;
      pReportTypes->parray = SafeArrayCreate(VT_VARIANT, 2, SABounds);

      lLoop = 0; // SABounds[0].lLbound
      while(! pRsHPASReports->IsEOF)
      {
      ldimension[0] = lLoop++;
      ldimension[1] = 0; // SABounds[1].lLbound

      CComVariant bstrTmp( pRsHPASReports->Fields->Item\["RptType"\]->Value );
      TESTHR(SafeArrayPutElement( pReportTypes->parray, ldimension, &bstrTmp ));
      
      ldimension\[1\]++;
      CComVariant bstrTmp2( pRsHPASReports->Fields->Item\["Title"\]->Value );
      TESTHR(SafeArrayPutElement( pReportTypes->parray, ldimension, &bstrTmp2 ));
      
      pRsHPASReports->MoveNext();
      

      }

      With best wishes, Vita

      1 Reply Last reply
      0
      Reply
      • Reply as topic
      Log in to reply
      • Oldest to Newest
      • Newest to Oldest
      • Most Votes


      • Login

      • Don't have an account? Register

      • Login or register to search.
      • First post
        Last post
      0
      • Categories
      • Recent
      • Tags
      • Popular
      • World
      • Users
      • Groups