如何在不保存文件的情况下制作并将打印屏幕发送到FTP服务器?我的工作代码将文件保存到HDD

时间:2017-01-13 22:53:35

标签: c++ ftp gdi+

在发表这篇文章之前,我搜索并尝试了4天所有的事情,比如https://www.codeproject.com/kb/gdi-plus/memimage.aspx,但我是编程新手。

这段代码(不是我的),制作了一个打印屏幕,保存到文件然后发送到ftp服务器。我想这样做而不将文件保存到HDD,从内存到FTP。

// The print-screen and save to file (jpg) code:

wstring wtmp;
tmp =   sDate + pictureName + ".jpeg";
wtmp = ToStringW(tmp);
screenName = wtmp.c_str();
ftpScreenName = wtmp.c_str();
fileToRemove = tmp.c_str();
using namespace Gdiplus;
GdiplusStartupInput gdiplusStartupInput;
ULONG_PTR gdiplusToken;

GdiplusStartup(&gdiplusToken, &gdiplusStartupInput, NULL);
{
HDC scrdc, memdc;
HBITMAP membit;
scrdc = ::GetDC(0);
int Height = GetSystemMetrics(SM_CYSCREEN);
int Width = GetSystemMetrics(SM_CXSCREEN);
memdc = CreateCompatibleDC(scrdc);
membit = CreateCompatibleBitmap(scrdc, Width, Height);
HBITMAP hOldBitmap = (HBITMAP)SelectObject(memdc, membit);
BitBlt(memdc, 0, 0, Width, Height, scrdc, 0, 0, SRCCOPY);
Gdiplus::Bitmap bitmap(membit, NULL);

EncoderParameters encoderParameters;
ULONG quality;

CLSID clsid;
GetEncoderClsid(L"image/jpeg", &clsid);
encoderParameters.Count = 1;
encoderParameters.Parameter[0].Guid = EncoderQuality;
encoderParameters.Parameter[0].Type = EncoderParameterValueTypeLong;
encoderParameters.Parameter[0].NumberOfValues = 1;

// Save the image as a JPEG with quality level 80.
quality = 80;
encoderParameters.Parameter[0].Value = &quality;

int result;
result = bitmap.Save(screenName, &clsid); //saving the file to HDD

//send to ftp with given info
saveFTP(server, user, password, ftpScreenName, screenName);
}
GdiplusShutdown(gdiplusToken);

//这里是FTP客户端部分:

bool saveFTP(LPCWSTR l_server, LPCWSTR l_user, LPCWSTR l_pass, LPCWSTR l_ftpfile, LPCWSTR l_screen)
{
HINTERNET internet = InternetOpen(L"tester", INTERNET_OPEN_TYPE_DIRECT, NULL, NULL, INTERNET_FLAG_ASYNC);
HINTERNET inter = InternetConnect(internet, l_server, INTERNET_DEFAULT_FTP_PORT, l_user, l_pass, INTERNET_SERVICE_FTP, 0, 0);
bool result;
result = FtpPutFile(inter, l_screen, l_ftpfile, FTP_TRANSFER_TYPE_BINARY, 0);
InternetCloseHandle(inter);
InternetCloseHandle(internet);
return result;
}

1 个答案:

答案 0 :(得分:1)

使用FtpOpenFile()InternetWriteFile()代替FtpPutFile()。这在FtpPutFile()文档中明确说明:

  

FtpPutFile是一个高级例程,它处理与在本地读取文件并将其存储在FTP服务器上相关的所有簿记和开销。 只需要发送文件数据或需要严格控制文件传输的应用程序应使用FtpOpenFileInternetWriteFile函数

以及WinInet的FTP Sessions文档

  

要在F​​TP服务器上传或放置文件,应用程序可以使用FtpPutFileFtpOpenFile(以及InternetWriteFile。如果文件已在本地存在,则可以使用FtpPutFile;如果需要将数据写入FTP服务器上的文件,则可以使用FtpOpenFileInternetWriteFile

Gdiplus::Bitmap可以保存为HDD文件或IStream。您可以使用 CreateStreamOnHGlobal()SHCreateMemStream()创建内存流,然后将Bitmap保存到流中,最后使用FtpOpenFile()InternetWriteFile()上传流的内容

例如(为简洁省略了错误处理,请不要在实际代码中省略它!):

tmp = sDate + pictureName + ".jpeg";
wstring wtmp = ToStringW(tmp);
IStream *strm = SHCreateMemStream(NULL, 0);

using namespace Gdiplus;

GdiplusStartupInput gdiplusStartupInput;
ULONG_PTR gdiplusToken;
GdiplusStartup(&gdiplusToken, &gdiplusStartupInput, NULL);

CLSID clsid;
GetEncoderClsid(L"image/jpeg", &clsid);
EncoderParameters encoderParameters;
encoderParameters.Count = 1;
encoderParameters.Parameter[0].Guid = EncoderQuality;
encoderParameters.Parameter[0].Type = EncoderParameterValueTypeLong;
encoderParameters.Parameter[0].NumberOfValues = 1;

// Save the image as a JPEG with quality level 80.
ULONG quality = 80;
encoderParameters.Parameter[0].Value = &quality;

HDC scrdc = ::GetDC(0);
int Height = GetSystemMetrics(SM_CYSCREEN);
int Width = GetSystemMetrics(SM_CXSCREEN);
HDC memdc = CreateCompatibleDC(scrdc);
HBITMAP membit = CreateCompatibleBitmap(scrdc, Width, Height);
HBITMAP hOldBitmap = (HBITMAP) SelectObject(memdc, membit);
BitBlt(memdc, 0, 0, Width, Height, scrdc, 0, 0, SRCCOPY);

{
Gdiplus::Bitmap bitmap(membit, NULL);
bitmap.Save(strm, &clsid); //saving the file to HDD
}

SelectObject(memdc, hOldBitmap);
DeleteObject(membit);
DeleteDC(memdc);
::ReleaseDC(0, scrdc);

GdiplusShutdown(gdiplusToken);

LARGE_INTEGER li;
li.QuadPart = 0;
strm->Seek(li, STREAM_SEEK_SET, NULL);

//send to ftp with given info
saveFTP(server, user, password, wtmp.c_str(), strm);
strm->Release();

bool saveFTP(LPCWSTR l_server, LPCWSTR l_user, LPCWSTR l_pass, LPCWSTR l_ftpfile, IStream *l_screen)
{
    HINTERNET internet = InternetOpen(L"tester", INTERNET_OPEN_TYPE_DIRECT, NULL, NULL, INTERNET_FLAG_ASYNC);
    HINTERNET conn = InternetConnect(internet, l_server, INTERNET_DEFAULT_FTP_PORT, l_user, l_pass, INTERNET_SERVICE_FTP, 0, 0);
    HINTERNET file = FtpOpenFile(conn, l_ftpfile, GENERIC_WRITE, FTP_TRANSFER_TYPE_BINARY, 0);

    BYTE buffer[1024], *pbuf;
    ULONG ulRead;
    DWORD dwWritten;
    HRESULT hr;
    bool success = true;

    do
    {
        hr = l_screen->Read(buffer, sizeof(buffer), &ulRead);
        if (FAILED(hr))
        {
            success = false;
            break;
        }

        pbuf = buffer;
        while (ulRead != 0)
        {
            if (!InternetWriteFile(file, pbuf, ulRead, &dwWritten))
            {
                success = false;
                break;
            }
            pbuf += dwWritten;
            ulRead -= dwWritten;
        }
    }
    while (hr == S_OK);

    InternetCloseHandle(file);
    InternetCloseHandle(conn);
    InternetCloseHandle(internet);

    return success;
}