我有这个相当简单的代码,它应该制作截图并将其上传到服务器,但我无法使用已安装的Windows32 API版本3.17-2 + GDI +'在devc ++下编译它,因为它失败了
第83行no matching function for call to Gdiplus::Bitmap::Save(IStream*&, CLSID*)
还有一些
invalid initialization of non-const reference of type srd::string& from a temporary of type std::
代码由我的朋友编写,但他用Visual-Studio编写。当我们使用不同的编辑器时,即使我在我的devcpp上安装了Win32 API / GDI +,它可能是一个问题吗?有人可以告诉我如何解决这个错误?我真的需要我的项目代码,我需要明天完成!所以请帮忙!!!
#include <WinSock2.h>
#include <ws2tcpip.h>
#include <windows.h>
#include <gdiplus.h>
#pragma comment(lib, "gdiplus.lib")
#pragma comment(lib, "ws2_32.lib")
#include <string>
#include <vector>
#include <cstdint>
#include <sstream>
//http://msdn.microsoft.com/en-us/library/windows/desktop/ms533843%28v=vs.85%29.aspx
int GetEncoderCLSID(const WCHAR* format, CLSID* pClsid)
{
UINT num = 0; // number of image encoders
UINT size = 0; // size of the image encoder array in bytes
Gdiplus::ImageCodecInfo* pImageCodecInfo = NULL;
Gdiplus::GetImageEncodersSize(&num, &size);
if(size == 0)
return -1; // Failure
pImageCodecInfo = (Gdiplus::ImageCodecInfo*)(malloc(size));
if(pImageCodecInfo == NULL)
return -1; // Failure
Gdiplus::GetImageEncoders(num, size, pImageCodecInfo);
for(UINT j = 0; j < num; ++j)
{
if( wcscmp(pImageCodecInfo[j].MimeType, format) == 0 )
{
*pClsid = pImageCodecInfo[j].Clsid;
free(pImageCodecInfo);
return j; // Success
}
}
free(pImageCodecInfo);
return -1; // Failure
}
inline void SendString(SOCKET s, std::string string)
{
send(s, string.c_str(), string.size(), 0);
}
inline void AppendVector(std::vector<uint8_t> &vector, std::string &string)
{
vector.insert(vector.end(), string.begin(), string.end());
}
template<typename T>
inline std::string ToString(T data)
{
std::stringstream str;
str << data;
return str.str();
}
void ProcessHotKey()
{
//Capture
size_t width = GetSystemMetrics(SM_CXVIRTUALSCREEN);
size_t height = GetSystemMetrics(SM_CYVIRTUALSCREEN);
size_t left = GetSystemMetrics(SM_XVIRTUALSCREEN);
size_t top = GetSystemMetrics(SM_YVIRTUALSCREEN);
HDC screenDC = GetDC(NULL);
HDC memDC = CreateCompatibleDC(screenDC);
HBITMAP bmp = CreateCompatibleBitmap(screenDC, width, height);
SelectObject(memDC, bmp);
BitBlt(memDC, 0, 0, width, height, screenDC, left, top, SRCCOPY);
CLSID pngClsid;
GetEncoderCLSID(L"image/png", &pngClsid);
Gdiplus::Bitmap bitmap(bmp, NULL);
IStream *memStream;
CreateStreamOnHGlobal(NULL, TRUE, &memStream);
bitmap.Save(memStream, &pngClsid);
STATSTG stat;
memStream->Stat(&stat, 0);
DeleteObject(bmp);
DeleteDC(memDC);
SYSTEMTIME st;
FILETIME ft;
GetSystemTime(&st);
SystemTimeToFileTime(&st, &ft);
uint64_t epoch = ((uint64_t)ft.dwHighDateTime << 32) | ft.dwLowDateTime;
#define WINDOWS_TICK 10000000
#define SEC_TO_UNIX_EPOCH 11644473600LL
epoch = epoch / WINDOWS_TICK - SEC_TO_UNIX_EPOCH;
std::string filename = "scrshot-" + ToString(epoch) + ".png";
std::string hostname = "dlunch.net";
std::string uri = "/scrshot.php";
std::string boundary = "---------------Boundary151235fa";
//Prepare body
std::vector<uint8_t> body;
AppendVector(body, "--" + boundary + "\r\n");
AppendVector(body, "Content-Disposition: form-data; name=\"file\"; filename=\"" + filename + "\"\r\n");
AppendVector(body, std::string("Content-Type: application/octet-stream\r\n\r\n"));
size_t oldSize = body.size();
body.resize(oldSize + (size_t)stat.cbSize.QuadPart);
LARGE_INTEGER zero;
zero.QuadPart = 0;
memStream->Seek(zero, STREAM_SEEK_SET, NULL);
memStream->Read(&*(body.begin() + oldSize), (size_t)stat.cbSize.QuadPart, NULL);
memStream->Release();
AppendVector(body, "\r\n--" + boundary + "--\r\n\r\n");
//Upload
addrinfo *info;
getaddrinfo(hostname.c_str(), "http", NULL, &info);
SOCKET s = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
connect(s, info->ai_addr, info->ai_addrlen);
SendString(s, "POST " + uri + " HTTP/1.1\r\n");
SendString(s, "Host:" + hostname + "\r\n");
SendString(s, "Content-Type: multipart/form-data; boundary=" + boundary + "\r\n");
SendString(s, "Content-Length: " + ToString(body.size()) + "\r\n\r\n");
send(s, (const char *)&*body.begin(), body.size(), 0);
bool flag = false;
int begin, end = 0;
std::string data;
while(true)
{
char buf[256];
int n = recv(s, buf, 255, 0);
if(n <= 0)
break;
buf[n] = 0;
data.append(buf);
while(true)
{
begin = data.find("\r\n", end + 1) + 2;
end = data.find("\r\n", begin);
if(begin == std::string::npos || end == std::string::npos)
break;
std::string line = data.substr(begin, end - begin + 1);
if(line.substr(0, 7) == "http://")
{
HGLOBAL hMem = GlobalAlloc(GMEM_MOVEABLE, line.size());
memcpy(GlobalLock(hMem), line.c_str(), line.size());
GlobalUnlock(hMem);
OpenClipboard(0);
EmptyClipboard();
SetClipboardData(CF_TEXT, hMem);
CloseClipboard();
flag = true;
break;
}
}
if(flag)
break;
}
closesocket(s);
}
int CALLBACK WndProc(HWND hWnd, UINT iMessage, WPARAM wParam, LPARAM lParam);
int APIENTRY WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nShowCmd)
{
Gdiplus::GdiplusStartupInput gdiplusStartupInput;
ULONG_PTR gdiplusToken;
Gdiplus::GdiplusStartup(&gdiplusToken, &gdiplusStartupInput, NULL);
WSADATA ws;
WSAStartup(MAKEWORD(2, 2), &ws);
CoInitialize(NULL);
//We need to create windows to receive hotkey notifications
WNDCLASSEX wcex;
ZeroMemory(&wcex, sizeof(wcex));
wcex.cbSize = sizeof(wcex);
wcex.hbrBackground = (HBRUSH)(COLOR_WINDOW + 1);
wcex.lpszClassName = TEXT("Screenshot");
wcex.lpfnWndProc = (WNDPROC)WndProc;
HWND hWnd = CreateWindowEx(NULL, (LPCWSTR)RegisterClassEx(&wcex), TEXT("Screenshot"), WS_OVERLAPPED, -1, -1, -1, -1, NULL, NULL, NULL, NULL);
ShowWindow(hWnd, SW_HIDE);
MSG msg;
while(GetMessage(&msg, 0, 0, 0))
{
TranslateMessage(&msg);
DispatchMessage(&msg);
}
CoUninitialize();
WSACleanup();
Gdiplus::GdiplusShutdown(gdiplusToken);
return msg.wParam;
}
int CALLBACK WndProc(HWND hWnd, UINT iMessage, WPARAM wParam, LPARAM lParam)
{
switch(iMessage)
{
case WM_CREATE:
RegisterHotKey(hWnd, 0, NULL, VK_SNAPSHOT);
break;
case WM_HOTKEY:
ProcessHotKey();
break;
}
return DefWindowProc(hWnd, iMessage, wParam, lParam);
}