MORE INFORMATION
If you select multiple items in the list box, the following
is sent when you use the HTML in the Sample Code section:
MFCIsapiCommand=WorksOn&Name=ssm&Days=Monday&Days=Tuesday
The code in CallFunction below modifies the input as follows:
MFCIsapiCommand=WorksOn&Name=ssm&Days=Monday,Tuesday
In the parse map function, the variable associated with the list box
contains a string with all the selected items in the list box, delimited by
','. If a comma is not a good delimiter then change the line:
#define DELIMITER ','
and specify a different character. Note that &, ?, =, + have
special meanings and should not be used as delimiters.
Sample Code
HTML Form that calls the sample dll:
<HTML>
<form action="/scripts/MyIsapi.dll?" method="Post">
<input type=hidden Name=MFCIsapiCommand Value=WorksOn>
Name <input name="Name" >
<p>
Works on
<SELECT MULTIPLE NAME="Days">
<OPTION VALUE="">NONE
<OPTION>Sunday
<OPTION>Monday
<OPTION>Tuesday
<OPTION>Wednesday
<OPTION>Thursday
<OPTION>Friday
<OPTION>Saturday
</SELECT>
<p>
<input type=submit>
</form>
</HTML>
MFC ISAPI PARSE_MAP entries and function for the above:
ON_PARSE_COMMAND(WorksOn, CMyIsapiExtension, ITS_PSTR ITS_PSTR)
ON_PARSE_COMMAND_PARAMS("Name=~ Days=~")
void CFirstISAPIExtension::WorksOn (CHttpServerContext* pCtxt,
LPCTSTR Name, LPTSTR Days)
{
StartContent(pCtxt);
*pCtxt << Name << " works on the following Days : <p>" << Days;
EndContent(pCtxt);
}
The code above generates the error message when more than one day is
selected in the list box.
The following override of CallFunction
modifies the input so that the parse maps can handle multiple selections:
#define DELIMITER ","
int CMyIsapiExtension::CallFunction(CHttpServerContext* pCtxt,
LPTSTR pszQuery, LPTSTR pszCommand)
{
LPTSTR queryIn = pszQuery;
LPTSTR queryOut = new TCHAR[_tcslen(queryIn) + sizeof(TCHAR)];
LPTSTR pOut = queryOut;
*pOut = NULL;
LPTSTR pIn = queryIn;
// Copy everything till the first ?
if (_tcschr(pIn, '?'))
{
pIn = _tcschr(pIn, '?');
pIn++;
memcpy(pOut, queryIn, (pIn - queryIn)); //copy till the ?
pOut += (pIn - queryIn);
*pOut = NULL;
}
LPTSTR lastParameter = NULL;
int nLastParameterLen = 0;
while (pIn && *pIn)
{
// Is there a '=' in the input string
LPTSTR q = _tcschr(pIn, '=');
if (!q)
{
// No. Copy till end of the buffer and break out
// No more parameter/value pairs.
_tcscpy(pOut, pIn);
break;
}
int paramLen = (q - pIn);
// Is the last parameter name the same as the present
// parameter name?
if (paramLen &&
nLastParameterLen == paramLen &&
_tcsncmp(lastParameter, pIn, nLastParameterLen) == 0)
{
// Yes! replace & with , and just copy the value
// of the parameter.
q++;
if (*q)
{
LPTSTR r = _tcschr(q, '&');
*(pOut - 1) = ',';
//copy the value
if (r)
{
_tcsncpy(pOut, q, (r - q) + 1);
pOut+=(r - q) + 1;
pIn = r + 1;
}
else
{
_tcscpy(pOut, q);
break;
}
}
else
{
*(pOut - 1) = ',';
*pOut = NULL;
break;
}
}
else
{
nLastParameterLen = paramLen;
lastParameter = pIn;
q = _tcschr(pIn, '&');
if (q)
{
if (paramLen)
{
_tcsncpy(pOut, pIn, (q - pIn) + 1);
pOut += (q - pIn) + 1;
}
pIn = q + 1;
}
else
{
if (paramLen)
{
_tcscpy(pOut, pIn);
break;
}
else
{
if (pOut == queryOut)
*pOut = NULL;
else
*(pOut - 1) = NULL;
break;
}
}
}
}
pszQuery = queryOut;
int nRet = CHttpServer::CallFunction(pCtxt,
pszQuery, pszCommand);
delete []queryOut;
return nRet;
}
The following modification to the WorksOn function prints the days on
different lines:
void CMyIsapiExtension::WorksOn (CHttpServerContext* pCtxt,
LPCTSTR Name, LPTSTR Days)
{
StartContent(pCtxt);
*pCtxt << Name << " works on the following Days<p>";
LPTSTR p = (LPTSTR)Days;
while (p)
{
LPCTSTR q = p;
p = _tcschr(p, ',');
if (p)
*p++ = NULL;
*pCtxt << q << "<p>";
}
EndContent(pCtxt);
}