Extender Coding Question

Started by JTaylor, April 11, 2014, 07:23:31 PM

Previous topic - Next topic

JTaylor

Not sure of the best place to post this but since it relates to Dialogs I decided on here.   I would appreciate it if anyone is willing to help improve my knowledge.  The following is a section out of the ComControl Extender I created.  It works so don't need help with that but I am sure it is not done very well and was looking for pointers on how I "should" have done it.  Thanks.

Jim

One of the questions is how to use the lb_cnt for the size of the buf array.  VS gives an error if all the declarations aren't at the top.

Code (winbatch) Select

      HWND ControlHandle = LongToHandle(lpvvArg[0].x);
      int* buf[32767];   
      int  lb_res       = 0;
      int  x            = 0;
      int  from         = 0;
      char iline[40960] = "";

      int lb_cnt = SendMessage(ControlHandle, LB_GETSELCOUNT, 0, 0);
                 
      lb_resp = SendMessage(ControlHandle, LB_GETSELITEMS, lb_cnt, (LPARAM)buf);
     
     // IF ITEMLISTBOX IS SET TO SINGLE-SELECT THE ABOVE WILL RETURN LB_ERR.   IT MAY BE  A BAD ASSUMPTION BUT I ASSUME IF IT RETURNS AN ERROR IT IS BECAUSE OF THIS SO I MAKE ANOTHER CALL ASSUMING SINGLE SELECT.
      if (lb_resp==-1)
        {
          lb_resp = SendMessage(ControlHandle, LB_GETCURSEL, lb_cnt, (LPARAM)buf);
          lb_resp = lb_resp + 1;
          MyLtoa(lb_resp, szWork, 10);
          strcat(iline, szWork);
        }
      else
      {
        // IF NOTHING IS SELECTED I RETURN ZERO
        if (lb_resp==0)
        {
          from = 0;
          MyLtoa(from, szWork, 10);   
          strcat(iline,szWork);
        };
       //OTHERWISE I LOOP AND BUILD A TAB DELIMITED STRING.
        for(x = 0; x <= lb_resp-1; x++)
        {
          from = buf[x];
          from = from + 1;
          MyLtoa(from, szWork, 10);
          //MessageBox(hWnd, szWork, "Count", MB_OK);

          strcat(iline,szWork);
     
          if (x<lb_resp-1)
          {
           strcat(iline,"\t");
          }
        }
   
      };

      RETSTRING(iline);
       

Deana

Deana F.
Technical Support
Wilson WindowWare Inc.

JTaylor

Appreciate the links, and I assure you, I have spent many hours reading such pages but what I would find very helpful, if someone were willing to take the few minutes needed, is if a "real" C programmer would rewrite that same code and post it.  Having it for comparison would be very educational.   Not sure if anyone is willing but thought I would ask.  If I need to post any comments about what is happening there I can but most of it is probably self-evident.

Jim

Deana

Quote from: JTaylor on April 14, 2014, 08:38:08 AM
Appreciate the links, and I assure you, I have spent many hours reading such pages but what I would find very helpful, if someone were willing to take the few minutes needed, is if a "real" C programmer would rewrite that same code and post it.  Having it for comparison would be very educational.   Not sure if anyone is willing but thought I would ask.  If I need to post any comments about what is happening there I can but most of it is probably self-evident.

Jim

Jim,
Did you happen to take a look at the link I posted. It contains the code that should help you use malloc. Search this code for LB_GETSELITEMS: https://github.com/jtanx/tSubGet/blob/master/tSubGet/tSubInputList.c
Deana F.
Technical Support
Wilson WindowWare Inc.

Deana

TOTALLY UNDEBUGGED. see lines marked by //////

HWND ControlHandle = LongToHandle(lpvvArg[0].x);
int* buf;   
int  lb_res       = 0;
int  x            = 0;
int  from         = 0;
char iline[40960] = "";

int lb_cnt = SendMessage(ControlHandle, LB_GETSELCOUNT, 0, 0);

buf = malloc(sizeof(int) * lb_cnt); /////// Dynamically Allocate
if (!buf) RETERROR(-1,999); /////// Modify to fit your needs
           
lb_resp = SendMessage(ControlHandle, LB_GETSELITEMS, lb_cnt, (LPARAM)buf);

// IF ITEMLISTBOX IS SET TO SINGLE-SELECT THE ABOVE WILL RETURN LB_ERR.   IT MAY BE  A BAD ASSUMPTION BUT I ASSUME IF IT RETURNS AN ERROR IT IS BECAUSE OF THIS SO I MAKE ANOTHER CALL ASSUMING SINGLE SELECT.
if (lb_resp==-1)
  {
    lb_resp = SendMessage(ControlHandle, LB_GETCURSEL, lb_cnt, (LPARAM)buf);
    lb_resp = lb_resp + 1;
    MyLtoa(lb_resp, szWork, 10);
    strcat(iline, szWork);
  }
else
{
  // IF NOTHING IS SELECTED I RETURN ZERO
  if (lb_resp==0)
  {
    from = 0;
    MyLtoa(from, szWork, 10);   
    strcat(iline,szWork);
  };
//OTHERWISE I LOOP AND BUILD A TAB DELIMITED STRING.
  for(x = 0; x <= lb_resp-1; x++)
  {
    from = buf[x];
    from = from + 1;
    MyLtoa(from, szWork, 10);
    //MessageBox(hWnd, szWork, "Count", MB_OK);

    strcat(iline,szWork);

    if (x<lb_resp-1)
    {
     strcat(iline,"\t");
    }
  }

};
free(buf); /////// Free memory
RETSTRING(iline);
Deana F.
Technical Support
Wilson WindowWare Inc.

JTaylor

Yes.  Looked at the code but was curious if other changes would be suggested as well.   So the main thing you would improve upon was the array creation?    No better way to convert an array to a tab delimited list or convert the other responses to a string for Return?

Thanks again.

Jim

Deana

Quote from: JTaylor on April 14, 2014, 10:04:38 AM
Yes.  Looked at the code but was curious if other changes would be suggested as well.   So the main thing you would improve upon was the array creation?    No better way to convert an array to a tab delimited list or convert the other responses to a string for Return?

Thanks again.

Jim

FYI. I didn't go through the code with a fine toothed comb.  Your original thread asked ' lb_cnt for the size of the buf array', hence my reply. As for the best code for converting to a tab delimited list. Maybe someone else will chime in.
Deana F.
Technical Support
Wilson WindowWare Inc.

DAG_P6

The C programming language requires all variables to be declared at the top of a function, and the Visual C++ compiler assumes C if the file name extension is .C. OTOH, C++ allows variables to be declared anywhere (before first use, obviously ;)), and Visual C++ treats a file with an extension of .CPP as such.

Regarding conversion of the array of ints to strings, something like the following (not debugged) should get the job done. I've done something similar several times, but I cannot remember right now which routine(s) to search.

// Assume that intNItems is the number of items in the list
// and that lpintIndex points to the first item.

TCHAR chrTab[] = TEXT ( "\t" );

TCHAR chrBuf[34];  // Maximum length of string returned by _ltoa, plus 1 for the obligatory terminal null
TCHAR * lpNewBuf = NULL;
int intBufSize  = -1;
int intCurrItem = 0 ;

_ltoa( intNItems, chrBuf, 10 ) ;  // This is its highest possible value.
intBufSize = _tcslen( chrbuf ) + 2 ) * intNItems ; // Should be more than enough
lpNewBuf = malloc( ( intBufSize ) ;
if ( lpNewBuf == NULL ) { // Out of memory }
memset( lpNewBuf , 0 , intBufSize ) ;

for ( intCurrItem = 1; intCurrItem <= intNItems; intCurrItem++ )
{
    _tcsncat( lpNewBuf, _ltoa( lpintIndex[intCurrItem-1], chrBuf, 10 ), 33 );
    _tcsncat( lpNewBuf, &chrTab ,2);
}


I'm sure there are other ways to do this, but the above code, or something like it, should get the job done.

BTW, turning a double null terminated string of ASCIIZ strings, such as that returned by the FileOpen and FileSave common controls is trivial compared to this.
David A. Gray
You are more important than any technology.

JTaylor


DAG_P6

You are most welcome. I hope it's useful.
David A. Gray
You are more important than any technology.