📄 asyncdemo.cpp
字号:
//write the callback information to the buffer
sprintf(szBuffer,"%s: RECEIVEING_RESPONSE (%d)",
cpContext->szMemo, dwStatusInformationLength);
break;
case INTERNET_STATUS_RESPONSE_RECEIVED:
//write the callback information to the buffer
sprintf(szBuffer,"%s: RESPONSE_RECEIVED (%d)",
cpContext->szMemo, dwStatusInformationLength);
break;
case INTERNET_STATUS_REDIRECT:
//write the callback information to the buffer
sprintf(szBuffer,"%s: REDIRECT (%d)",
cpContext->szMemo, dwStatusInformationLength);
break;
case INTERNET_STATUS_REQUEST_COMPLETE:
//check for errors
if (LPINTERNET_ASYNC_RESULT(lpvStatusInformation)->dwError == 0)
{
//check if the completed request is from AsyncDirect
if (strcmp(cpContext->szMemo, "AsyncDirect"))
{
//set the resource handle to the HINTERNET handle
//returned in the callback
cpContext->hResource = HINTERNET(
LPINTERNET_ASYNC_RESULT(lpvStatusInformation)->dwResult);
//write the callback information to the buffer
sprintf(szBuffer,"%s: REQUEST_COMPLETE (%d)",
cpContext->szMemo, dwStatusInformationLength);
//create a thread to handle the header and
//resource download
cpContext->hThread = CreateThread(NULL, 0,
(LPTHREAD_START_ROUTINE)Threader,LPVOID(cpContext), 0,
&cpContext->dwThreadID);
}
else
{
sprintf(szBuffer,"%s(%d): REQUEST_COMPLETE (%d)",
cpContext->szMemo,
cpContext->nURL, dwStatusInformationLength);
}
}
else
{
sprintf(szBuffer,
"%s: REQUEST_COMPLETE (%d) Error (%d) encountered",
cpContext->szMemo, dwStatusInformationLength,
GetLastError());
}
break;
case INTERNET_STATUS_REQUEST_SENT:
//write the callback information to the buffer
sprintf(szBuffer,"%s: REQUEST_SENT (%d)",
cpContext->szMemo, dwStatusInformationLength);
break;
case INTERNET_STATUS_RESOLVING_NAME:
//write the callback information to the buffer
sprintf(szBuffer,"%s: RESOLVING_NAME (%d)",
cpContext->szMemo, dwStatusInformationLength);
break;
case INTERNET_STATUS_SENDING_REQUEST:
//write the callback information to the buffer
sprintf(szBuffer,"%s: SENDING_REQUEST (%d)",
cpContext->szMemo, dwStatusInformationLength);
break;
case INTERNET_STATUS_STATE_CHANGE:
//write the callback information to the buffer
sprintf(szBuffer,"%s: STATE_CHANGE (%d)",
cpContext->szMemo, dwStatusInformationLength);
break;
default:
//write the callback information to the buffer
sprintf(szBuffer,"%s: Unknown: Status %d Given", dwInternetStatus);
break;
}
//add the callback information to the callback list box
SendDlgItemMessage(cpContext->hWindow,IDC_CallbackList,
LB_ADDSTRING,0,(LPARAM)szBuffer);
}
/*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Threader is a thread function to handle the retrieval of the header
and resource information. Since the WinInet functions involved in
both of these operations work synchronously, using a separate
thread will help avoid any blocking.
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
DWORD Threader(LPVOID lpvContext)
{
REQUEST_CONTEXT *cpContext;
//copy the pointer to a REQUEST_CONTEXT pointer to ease calls
cpContext= (REQUEST_CONTEXT*)lpvContext;
//set szMemo to the name of the function to be called
sprintf(cpContext->szMemo, "Header(%d)", cpContext->nURL);
//call the header function
Header(cpContext->hWindow, cpContext->nHeader, -1, cpContext->hResource);
//set szMemo to the name of the function to be called
sprintf(cpContext->szMemo, "Dump(%d)", cpContext->nURL);
//call the dump function
Dump(cpContext->hWindow, cpContext->nResource, cpContext->hResource);
return S_OK;
}
/*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Header handles the retrieval of the HTTP header information.
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
int WINAPI Header(HWND hX,int intControl, int intCustom, HINTERNET hHttp)
{
DWORD dwHeaderType=-1;
DWORD dwSize=0;
LPVOID lpOutBuffer = NULL;
char szError[80];
//change the cursor
SetCursor(LoadCursor(NULL,IDC_WAIT));
//set the header type to be requested, which is all headers in
//this case
dwHeaderType = HTTP_QUERY_RAW_HEADERS_CRLF;
retry:
//call HttpQueryInfo.
//first time with a zero buffer size to get the size of the buffer
//needed and to check if the header exists
if(!HttpQueryInfo(hHttp,dwHeaderType,(LPVOID)lpOutBuffer,&dwSize,NULL))
{
//check if the header was not found
if (GetLastError()==ERROR_HTTP_HEADER_NOT_FOUND)
{
sprintf(szError,"Error %d encountered", GetLastError());
SetDlgItemText(hX,intControl, szError);
SetCursor(LoadCursor(NULL,IDC_ARROW));
return TRUE;
}
else
{
//check if the buffer was insufficient
if (GetLastError()==ERROR_INSUFFICIENT_BUFFER)
{
//allocate the buffer
lpOutBuffer = new char[dwSize+1];
goto retry;
}
else
{
//display other errors in header edit box
sprintf(szError,"Error %d encountered", GetLastError());
SetDlgItemText(hX,intControl, szError);
SetCursor(LoadCursor(NULL,IDC_ARROW));
return FALSE;
}
}
}
SetDlgItemText(hX,intControl,(LPSTR)lpOutBuffer);
delete[]lpOutBuffer;
SetCursor(LoadCursor(NULL,IDC_ARROW));
return 1;
}
/*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
int WINAPI Dump(HWND hX, int intCtrlID, HINTERNET hResource)
{
LPSTR lpszData; // buffer for the data
DWORD dwSize; // size of the data available
DWORD dwDownloaded; // size of the downloaded data
DWORD dwSizeSum=0; // size of the data in the textbox
LPSTR lpszHolding; // buffer to merge the textbox data and buffer
char szError[80]; // buffer for error information
// Set the cursor to an hourglass.
SetCursor(LoadCursor(NULL,IDC_WAIT));
int nCounter; // counter used to display something while
// I/O is pending.
// This loop handles reading the data.
do
{
try_again:
// The call to InternetQueryDataAvailable determines the amount of
// data available to download.
if (!InternetQueryDataAvailable(hResource,&dwSize,0,0))
{
if (GetLastError()== ERROR_IO_PENDING)
{
nCounter = 0;
while(GetLastError()==ERROR_IO_PENDING)
{
nCounter++;
if (nCounter==2000)
break;
}
goto try_again;
}
sprintf(szError,"Error %d encountered by InternetQueryDataAvailable",
GetLastError());
SetDlgItemText(hX,intCtrlID, szError);
SetCursor(LoadCursor(NULL,IDC_ARROW));
break;
}
else
{
// Allocates a buffer of the size returned by InternetQueryDataAvailable
lpszData = new char[dwSize+1];
// Reads the data from the HINTERNET handle.
if(!InternetReadFile(hResource,(LPVOID)lpszData,dwSize,&dwDownloaded))
{
if (GetLastError()== ERROR_IO_PENDING)
{
nCounter = 0;
while(GetLastError()==ERROR_IO_PENDING)
{
nCounter++;
}
goto keep_going;
}
sprintf(szError,"Error %d encountered by InternetReadFile",
GetLastError());
SetDlgItemText(hX,intCtrlID, szError);
delete[] lpszData;
break;
}
else
{
keep_going:
// Adds a null terminator to the end of the data buffer
lpszData[dwDownloaded]='\0';
// Allocates the holding buffer
lpszHolding = new char[dwSizeSum + dwDownloaded + 1];
// Checks if there has been any data written to the textbox
if (dwSizeSum != 0)
{
// Retrieves the data stored in the textbox if any
GetDlgItemText(hX,intCtrlID,(LPSTR)lpszHolding,dwSizeSum);
// Adds a null terminator at the end of the textbox data
lpszHolding[dwSizeSum]='\0';
}
else
{
// Make the holding buffer an empty string.
lpszHolding[0]='\0';
}
// Adds the new data to the holding buffer
strcat(lpszHolding,lpszData);
// Writes the holding buffer to the textbox
SetDlgItemText(hX,intCtrlID,(LPSTR)lpszHolding);
// Delete the two buffers
delete[] lpszHolding;
delete[] lpszData;
// Add the size of the downloaded data to the textbox data size
dwSizeSum = dwSizeSum + dwDownloaded + 1;
// Check the size of the remaining data. If it is zero, break.
if (dwDownloaded == 0)
break;
}
}
}
while(TRUE);
// Close the HINTERNET handle
InternetCloseHandle(hResource);
// Set the cursor back to an arrow
SetCursor(LoadCursor(NULL,IDC_ARROW));
// Return
return TRUE;
}
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
//
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -