Невозможно сказать, где у вас проблемы, но похоже, что вы делаете слишком много вещей одновременно.Вы не проверяете возвращаемые значения и не освобождаете ресурсы, поэтому я сделал консольный пример того, как вы можете обрабатывать ресурсы HINTERNET и проверять ошибки с помощью исключений.
#include "pch.h" // if you use precompiled headers
#include <iostream>
#include <vector>
#include <string>
#include <Windows.h>
#include <wininet.h>
// A simple wide string exception class.
class werror {
std::wstring text;
public:
werror(const wchar_t* Text) : text(Text) {}
werror(const std::wstring& Text) : text(Text) {}
const wchar_t* what() const { return text.c_str(); }
};
// base class for HINTERNET resources that will free the resource
// when destroyed
class IBase {
HINTERNET hInternet;
public:
IBase(HINTERNET h) : hInternet(h) {
if (!hInternet) // invalid handle, throw an exception
throw werror(L"Internet error " + std::to_wstring(GetLastError()));
}
// no copying or moving
IBase(const IBase&) = delete;
IBase(IBase&&) = delete;
IBase& operator=(const IBase&) = delete;
IBase& operator=(IBase&&) = delete;
// free the resource when being destroyed
virtual ~IBase() { InternetCloseHandle(hInternet); }
// conversion to HINTERNET for functions that need it
operator HINTERNET () const {
return hInternet;
}
};
// class for an FTP session
class FtpSession : public IBase {
public:
FtpSession(HINTERNET h) : IBase(h) {}
void PutFile(const std::wstring& LocalFile, const std::wstring& NewRemoteFile) {
auto rv = FtpPutFile(
*this, LocalFile.c_str(), NewRemoteFile.c_str(), FTP_TRANSFER_TYPE_BINARY, 0
);
if (!rv) // FtpPutFile failed, throw an exception
throw werror(L"PutFile error " + std::to_wstring(GetLastError()));
}
};
// a class factory to create Ftp (and future) objects
class Internet : public IBase {
public:
Internet(const std::wstring& Agent, DWORD dwAccessType, const std::wstring& Proxy,
const std::wstring& ProxyBypass, DWORD dwFlags) :
IBase(
InternetOpen(
Agent.c_str(),
dwAccessType,
Proxy.size() ? Proxy.c_str() : nullptr,
ProxyBypass.size() ? ProxyBypass.c_str() : nullptr,
dwFlags
)
)
{}
// factory method for creating an Ftp object
FtpSession GetFtpSession(const std::wstring& server,
const std::wstring& user, const std::wstring& pass)
{
return FtpSession(
InternetConnect(
*this, server.c_str(), INTERNET_DEFAULT_FTP_PORT,
user.c_str(), pass.c_str(), INTERNET_SERVICE_FTP, 0, 0
)
);
}
};
// Example: This program will transfer all the files you give on the commandline
// to your FTP server
int wmain(int argc, wchar_t* argv[])
{
std::vector<std::wstring> args(argv + 1, argv + argc);
try {
// "inet" can be used for as long as the program is running to create Ftp
// (and future internet) objects. It's "expensive" to create this object
// so keep it until you are sure you don't need it.
Internet inet(L"user-agent-name", INTERNET_OPEN_TYPE_DIRECT, L"", L"", 0);
for (const auto& file : args) {
// we create one Ftp session per file (probably not needed)
FtpSession ftp = inet.GetFtpSession(L"klokanek.endora.cz", L"oxytram8ucz", L"a1jfGIP69. ");
std::wcout << L"Transferring " << file << L"\n";
ftp.PutFile(file, file);
std::wcout << L"Done with " << file << L"\n";
}
}
catch (const werror& ex) {
std::wcerr << L"Exception: " << ex.what() << L"\n";
}
}
УправлениеВремя жизни ваших других ресурсов также является проблемой, поэтому я привел пример HHOOK
ниже.С помощью этого класса вы можете объявить переменную HookMgr
(например, HookMgr my_mouse_hook;
) в своей основной форме или что-либо еще, что будет жить в течение всей жизни программы, а затем автоматически уничтожаться.
class HookMgr {
HHOOK m_hook;
public:
HookMgr(HHOOK hook = nullptr) : m_hook(hook) {
if(m_hook==nullptr) throw werror(L"Invalid hook");
}
HookMgr(const HookMgr&) = delete;
HookMgr(HookMgr&& o) : m_hook(o.m_hook) { o.m_hook = nullptr; }
HookMgr& operator=(const HookMgr&) = delete;
HookMgr& operator=(HookMgr&& o) {
if (m_hook) UnhookWindowsHookEx(m_hook);
m_hook = o.m_hook;
o.m_hook = nullptr;
return *this;
}
HookMgr& operator=(HHOOK hook) {
if(hook==nullptr) throw werror(L"Invalid hook");
if (m_hook) UnhookWindowsHookEx(m_hook);
m_hook = hook;
return *this;
}
~HookMgr() {
if (m_hook) UnhookWindowsHookEx(m_hook);
}
};
Если вы хотите установить хук, просто наберите
my_mouse_hook = SetWindowsHookEx(WH_MOUSE_LL, hhDLL, hDLL, 0);
и забудьте об этом.Когда программа умирает и HookMgr
уничтожается, она автоматически освобождает установленный хук.Вы можете сделать аналогичные вещи для загрузки / выгрузки DLL: s.