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.
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);
Maybe take a look at using C dynamic memory allocation functions: malloc and realloc. Reference: http://en.wikipedia.org/wiki/C_dynamic_memory_allocation
See also: https://github.com/jtanx/tSubGet/blob/master/tSubGet/tSubInputList.c
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
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
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);
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
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.
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.
Thanks for the post.
Jim
You are most welcome. I hope it's useful.