Project64: Have nag use the registry

This commit is contained in:
zilmar 2020-10-22 12:41:19 +10:30
parent 8ed4a8016c
commit 890e9b5c2c
17 changed files with 771 additions and 148 deletions

View File

@ -455,17 +455,20 @@
* Support Window *
*********************************************************************************/
#1200# "Support Project64"
#1201# "Project64 is a software package designed to emulate a Nintendo64 video game system on a Microsoft Windows based PC. This allows you to play real N64 software in much the same way as it would be on the original hardware system.\n\nIf you like Project64 and have gotten some value out of it then please support project64 as either a thank you, or your desire to see it continually improved.\n\nIf you have supported project64:"
#1202# "Enter notification code"
#1201# "Project64 is a free and open source Nintendo64 emulator. This allows you to play real N64 software in much the same way as it would be on the original hardware system.\n\nI am sorry about the inconvenience of this prompt, but you are being asked to wait for a few seconds in order to enjoy the result of hundreds of hours of work.\n\nIf you can and would like to support Project64 or you have gotten some value out of it then please support project64 as either a thank you, or your a desire to see removal of this prompt.\n\nIf you have supported Project64:"
#1202# "Enter/Request Notification Code"
#1203# "Support Project64"
#1204# "Continue"
#1205# "Please enter the support code"
#1206# "Incorrect support code"
#1206# "Failed to validate the code\n\nMake sure the code matches in email based on your machine"
#1207# "Thank you"
#1208# "Enter code"
#1209# "Please enter the code in the email"
#1208# "Please enter your support code"
#1209# "Please enter the code you recieved in the email.\n\nThis email will be sent to the email address used to support project64.\n\nPlease note that the code is will only work for a unique machine. This computer id is:"
#1210# "OK"
#1211# "Cancel"
#1212# "Request Code"
#1213# "Code has been sent to your email"
#1214# "Failed to send code, please make sure it is the email you supported with"
/*********************************************************************************
* Messages *

View File

@ -107,6 +107,7 @@ enum LanguageStringID
MENU_ABOUT_PJ64 = 182,
MENU_FORUM = 183,
MENU_HOMEPAGE = 184,
MENU_SUPPORT_PROJECT64 = 185,
//Current Save Slot menu
MENU_SLOT_DEFAULT = 190,
@ -506,6 +507,9 @@ enum LanguageStringID
MSG_SUPPORT_ENTER_CODE_DESC = 1209,
MSG_SUPPORT_OK = 1210,
MSG_SUPPORT_CANCEL = 1211,
MSG_SUPPORT_REQUESTCODE_TITLE = 1212,
MSG_SUPPORT_REQUESTCODE_SUCCESS = 1213,
MSG_SUPPORT_REQUESTCODE_FAIL = 1214,
/*********************************************************************************
* Messages *

View File

@ -114,6 +114,7 @@ void CLanguage::LoadDefaultStrings(void)
DEF_STR(MENU_ABOUT_PJ64, "&About Project64");
DEF_STR(MENU_FORUM, "Support &Forum");
DEF_STR(MENU_HOMEPAGE, "&Homepage");
DEF_STR(MENU_SUPPORT_PROJECT64, "Support Project64");
//Current Save Slot menu
DEF_STR(MENU_SLOT_DEFAULT, "Default");
@ -460,17 +461,20 @@ void CLanguage::LoadDefaultStrings(void)
* Support Window *
*********************************************************************************/
DEF_STR(MSG_SUPPORT_TITLE, "Support Project64");
DEF_STR(MSG_SUPPORT_INFO, "Project64 is a software package designed to emulate a Nintendo64 video game system on a Microsoft Windows based PC. This allows you to play real N64 software in much the same way as it would be on the original hardware system.\n\nIf you like Project64 and have gotten some value out of it then please support project64 as either a thank you, or your desire to see it continually improved.\n\nIf you have supported project64:");
DEF_STR(MSG_SUPPORT_ENTER_CODE, "Enter notification code");
DEF_STR(MSG_SUPPORT_INFO, "Project64 is a free and open source Nintendo64 emulator. This allows you to play real N64 software in much the same way as it would be on the original hardware system.\n\nI am sorry about the inconvenience of this prompt, but you are being asked to wait for a few seconds in order to enjoy the result of hundreds of hours of work.\n\nIf you can and would like to support Project64 or you have gotten some value out of it then please support project64 as either a thank you, or your a desire to see removal of this prompt.\n\nIf you have supported Project64:");
DEF_STR(MSG_SUPPORT_ENTER_CODE, "Enter/Request Notification Code");
DEF_STR(MSG_SUPPORT_PROJECT64, "Support Project64");
DEF_STR(MSG_SUPPORT_CONTINUE, "Continue");
DEF_STR(MSG_SUPPORT_ENTER_SUPPORT_CODE, "Please enter the support code");
DEF_STR(MSG_SUPPORT_INCORRECT_CODE, "Incorrect support code");
DEF_STR(MSG_SUPPORT_INCORRECT_CODE, "Failed to validate the code\n\nMake sure the code matches in email based on your machine");
DEF_STR(MSG_SUPPORT_COMPLETE, "Thank you");
DEF_STR(MSG_SUPPORT_ENTER_CODE_TITLE, "Enter code");
DEF_STR(MSG_SUPPORT_ENTER_CODE_DESC, "Please enter the code in the email");
DEF_STR(MSG_SUPPORT_ENTER_CODE_TITLE, "Please enter your support code");
DEF_STR(MSG_SUPPORT_ENTER_CODE_DESC, "Please enter the code you recieved in the email.\n\nThis email will be sent to the email address used to support project64.\n\nPlease note that the code is will only work for a unique machine. This computer id is:");
DEF_STR(MSG_SUPPORT_OK, "OK");
DEF_STR(MSG_SUPPORT_CANCEL, "Cancel");
DEF_STR(MSG_SUPPORT_REQUESTCODE_TITLE, "Request Code");
DEF_STR(MSG_SUPPORT_REQUESTCODE_SUCCESS, "Code has been sent to your email");
DEF_STR(MSG_SUPPORT_REQUESTCODE_FAIL, "Failed to send code, please make sure it is the email you supported with");
/*********************************************************************************
* Messages *

View File

@ -91,6 +91,7 @@
<ClCompile Include="UserInterface\MenuClass.cpp" />
<ClCompile Include="UserInterface\MenuShortCuts.cpp" />
<ClCompile Include="UserInterface\Notification.cpp" />
<ClCompile Include="UserInterface\ProjectSupport.cpp" />
<ClCompile Include="UserInterface\RomBrowserClass.cpp" />
<ClCompile Include="UserInterface\RomInformationClass.cpp" />
<ClCompile Include="UserInterface\SettingsConfig.cpp" />
@ -166,6 +167,7 @@
<ClInclude Include="UserInterface\MenuClass.h" />
<ClInclude Include="UserInterface\MenuShortCuts.h" />
<ClInclude Include="UserInterface\Notification.h" />
<ClInclude Include="UserInterface\ProjectSupport.h" />
<ClInclude Include="UserInterface\resource.h" />
<ClInclude Include="UserInterface\RomBrowser.h" />
<ClInclude Include="UserInterface\RomInformationClass.h" />

View File

@ -246,6 +246,9 @@
<ClCompile Include="UserInterface\WTLControls\GetCWindowText.cpp">
<Filter>Source Files\User Interface Source\WTL Controls Source</Filter>
</ClCompile>
<ClCompile Include="UserInterface\ProjectSupport.cpp">
<Filter>Source Files\User Interface Source</Filter>
</ClCompile>
</ItemGroup>
<ItemGroup>
<ClInclude Include="UserInterface\resource.h">
@ -485,6 +488,9 @@
<ClInclude Include="UserInterface\WTLControls\wtl-BitmapPicture.h">
<Filter>Header Files\User Interface Headers\WTL Controls Headers</Filter>
</ClInclude>
<ClInclude Include="UserInterface\ProjectSupport.h">
<Filter>Header Files</Filter>
</ClInclude>
</ItemGroup>
<ItemGroup>
<None Include="res\divider.cur">

View File

@ -271,7 +271,7 @@ void CMainMenu::OnLodState(HWND hWnd)
g_BaseSystem->ExternalEvent(SysEvent_ResumeCPU_LoadGame);
}
void CMainMenu::OnCheats(HWND hWnd)
void CMainMenu::OnCheats(HWND /*hWnd*/)
{
m_Gui->DisplayCheatsUI(false);
}
@ -281,6 +281,11 @@ void CMainMenu::OnSettings(HWND hWnd)
CSettingConfig().Display(hWnd);
}
void CMainMenu::OnSupportProject64(HWND hWnd)
{
CSupportWindow(m_Gui->Support()).Show(hWnd, false);
}
bool CMainMenu::ProcessMessage(HWND hWnd, DWORD /*FromAccelerator*/, DWORD MenuID)
{
switch (MenuID)
@ -568,6 +573,7 @@ bool CMainMenu::ProcessMessage(HWND hWnd, DWORD /*FromAccelerator*/, DWORD MenuI
g_Notify->DisplayMessage(3, stdstr_f(GS(MENU_SLOT_SAVE), GetSaveSlotString((MenuID - ID_CURRENT_SAVE_1) + 1).c_str()).c_str());
g_Settings->SaveDword(Game_CurrentSaveState, (DWORD)((MenuID - ID_CURRENT_SAVE_1) + 1));
break;
case ID_HELP_SUPPORT_PROJECT64: OnSupportProject64(hWnd); break;
case ID_HELP_SUPPORTFORUM: ShellExecute(NULL, L"open", L"http://forum.pj64-emu.com/", NULL, NULL, SW_SHOWMAXIMIZED); break;
case ID_HELP_HOMEPAGE: ShellExecute(NULL, L"open", L"http://www.pj64-emu.com", NULL, NULL, SW_SHOWMAXIMIZED); break;
case ID_HELP_ABOUT: m_Gui->AboutBox(); break;
@ -1284,7 +1290,7 @@ void CMainMenu::FillOutMenu(HMENU hMenu)
/* Help Menu
****************/
MenuItemList HelpMenu;
HelpMenu.push_back(MENU_ITEM(ID_HELP_SUPPORT_PROJECT64, MENU_SUPPORT_PROJECT64));
HelpMenu.push_back(MENU_ITEM(ID_HELP_SUPPORTFORUM, MENU_FORUM));
HelpMenu.push_back(MENU_ITEM(ID_HELP_HOMEPAGE, MENU_HOMEPAGE));
HelpMenu.push_back(MENU_ITEM(SPLITER));

View File

@ -53,7 +53,7 @@ enum MainMenuID
ID_PROFILE_PROFILE, ID_PROFILE_RESETCOUNTER, ID_PROFILE_GENERATELOG,
//Help Menu
ID_HELP_SUPPORTFORUM, ID_HELP_HOMEPAGE, ID_HELP_ABOUTSETTINGFILES, ID_HELP_ABOUT,
ID_HELP_SUPPORT_PROJECT64, ID_HELP_SUPPORTFORUM, ID_HELP_HOMEPAGE, ID_HELP_ABOUTSETTINGFILES, ID_HELP_ABOUT,
};
class CMainMenu :
@ -83,6 +83,7 @@ private:
void OnLodState(HWND hWnd);
void OnCheats(HWND hWnd);
void OnSettings(HWND hWnd);
void OnSupportProject64(HWND hWnd);
void FillOutMenu(HMENU hMenu);
std::wstring GetSaveSlotString(int Slot);

View File

@ -14,6 +14,7 @@
#include <Project64/UserInterface/Debugger/debugger.h>
#include <Project64-core/Plugins/PluginClass.h>
#include <Project64\UserInterface\CheatClassUI.h>
#include <Project64\UserInterface\ProjectSupport.h>
class CGfxPlugin; //Plugin that controls the rendering
class CAudioPlugin; //Plugin for audio, need the hwnd
@ -95,10 +96,12 @@ public:
void * GetStatusBar(void) const { return m_hStatusWnd; }
void * GetModuleInstance(void) const;
inline CProjectSupport & Support(void) { return m_Support; }
private:
CMainGui(void); // Disable default constructor
CMainGui(const CMainGui&); // Disable copy constructor
CMainGui& operator=(const CMainGui&); // Disable assignment
CMainGui(void);
CMainGui(const CMainGui&);
CMainGui& operator=(const CMainGui&);
friend class CGfxPlugin;
friend class CAudioPlugin;
@ -131,6 +134,7 @@ private:
HWND m_hMainWindow, m_hStatusWnd;
DWORD m_ThreadId;
CCheatsUI m_CheatsUI;
CProjectSupport m_Support;
const bool m_bMainWindow;
bool m_Created;

View File

@ -0,0 +1,273 @@
#include "stdafx.h"
#include <Common\md5.h>
#include <windows.h>
#include <Wininet.h>
#pragma comment(lib, "Wininet.lib")
CProjectSupport::CProjectSupport() :
m_SupportInfo({0})
{
LoadSupportInfo();
}
bool CProjectSupport::RequestCode(const char * Email)
{
stdstr_f PostData("task=RequestCode&email=%s&machine=%s", Email, MachineID());
std::vector<std::string> Headers;
DWORD StatusCode;
if (!PerformRequest(L"/index.php?option=com_project64", PostData, StatusCode, Headers))
{
return false;
}
if (StatusCode == 200)
{
for (size_t i = 0, n = Headers.size(); i < n; i++)
{
if (strcmp(Headers[i].c_str(), "Email: Sent") == 0)
{
return true;
}
}
}
return false;
}
bool CProjectSupport::ValidateCode(const char * Code)
{
stdstr_f PostData("task=ValidateCode&code=%s&machine=%s", Code, MachineID());
std::vector<std::string> Headers;
DWORD StatusCode;
if (PerformRequest(L"/index.php?option=com_project64", PostData, StatusCode, Headers) && StatusCode == 200)
{
std::string Name, Email;
struct
{
const char * Key;
std::string & Value;
}
Test[] =
{
{ "SupporterName: ", Name },
{ "SupporterEmail: ", Email },
};
for (size_t i = 0, n = Headers.size(); i < n; i++)
{
for (size_t t = 0; t < sizeof(Test) / sizeof(Test[0]); t++)
{
size_t KeyLen = strlen(Test[t].Key);
if (strncmp(Headers[i].c_str(), Test[t].Key, KeyLen) == 0)
{
Test[t].Value = stdstr(&Headers[i][KeyLen]).Trim();
break;
}
}
}
if (Name.length() > 0 && Email.length() > 0)
{
strncpy(m_SupportInfo.Code, Code, sizeof(m_SupportInfo.Code));
strncpy(m_SupportInfo.Email, Email.c_str(), sizeof(m_SupportInfo.Email));
strncpy(m_SupportInfo.Name, Name.c_str(), sizeof(m_SupportInfo.Name));
m_SupportInfo.Validated = true;
SaveSupportInfo();
}
}
return m_SupportInfo.Validated;
}
std::string CProjectSupport::GenerateMachineID(void)
{
wchar_t ComputerName[256];
DWORD Length = sizeof(ComputerName) / sizeof(ComputerName[0]);
GetComputerName(ComputerName, &Length);
wchar_t SysPath[MAX_PATH] = { 0 }, VolumePath[MAX_PATH] = { 0 };
GetSystemDirectory(SysPath, sizeof(SysPath) / sizeof(SysPath[0]));
GetVolumePathName(SysPath, VolumePath, sizeof(VolumePath) / sizeof(VolumePath[0]));
DWORD SerialNumber = 0;
GetVolumeInformation(VolumePath, NULL, NULL, &SerialNumber, NULL, NULL, NULL, NULL);
wchar_t MachineGuid[200] = { 0 };
HKEY hKey;
if (RegOpenKeyEx(HKEY_LOCAL_MACHINE, L"SOFTWARE\\Microsoft\\Cryptography", 0, KEY_QUERY_VALUE | KEY_WOW64_64KEY, &hKey) == ERROR_SUCCESS)
{
DWORD Type, dwDataSize = sizeof(MachineGuid);
RegQueryValueEx(hKey, L"MachineGuid", nullptr, &Type, (LPBYTE)MachineGuid, &dwDataSize);
RegCloseKey(hKey);
}
stdstr_f Machine("%s.%ud.%s", stdstr().FromUTF16(ComputerName).c_str(), SerialNumber, stdstr().FromUTF16(MachineGuid).c_str());
return std::string(MD5((const unsigned char *)Machine.c_str(), Machine.size()).hex_digest());
}
void CProjectSupport::IncrementRunCount()
{
m_SupportInfo.RunCount += 1;
SaveSupportInfo();
}
bool CProjectSupport::PerformRequest(const wchar_t * Url, const std::string & PostData, DWORD & StatusCode, std::vector<std::string> & Headers)
{
StatusCode = 0;
Headers.clear();
HINTERNET hSession = InternetOpen(L"Project64", INTERNET_OPEN_TYPE_PRECONFIG, nullptr, nullptr, 0);
if (hSession == nullptr)
{
return false;
}
HINTERNET hConnect = InternetConnect(hSession, L"www.pj64-emu.com", INTERNET_DEFAULT_HTTPS_PORT, L"", L"", INTERNET_SERVICE_HTTP, 0, 0);
if (hConnect == nullptr)
{
return false;
}
LPCWSTR lpszAcceptTypes[] =
{
L"text/*",
nullptr
};
HINTERNET hRequest = HttpOpenRequest(hConnect, L"POST", Url, NULL, NULL, lpszAcceptTypes, INTERNET_FLAG_SECURE | INTERNET_FLAG_NO_AUTO_REDIRECT | INTERNET_FLAG_PRAGMA_NOCACHE | INTERNET_FLAG_NO_CACHE_WRITE, (LPARAM)0);
if (hRequest == nullptr)
{
InternetCloseHandle(hRequest);
return false;
}
wchar_t hdheaders[] = _T("Content-Type: application/x-www-form-urlencoded\r\n");
BOOL Success = HttpSendRequest(hRequest, hdheaders, _tcslen(hdheaders), (LPVOID)PostData.c_str(), PostData.length());
if (!Success)
{
InternetCloseHandle(hRequest);
return false;
}
DWORD StatusCodeSize = sizeof(StatusCode);
if (!HttpQueryInfo(hRequest, HTTP_QUERY_STATUS_CODE | HTTP_QUERY_FLAG_NUMBER, &StatusCode, &StatusCodeSize, NULL))
{
InternetCloseHandle(hRequest);
return false;
}
DWORD dwSize = 0;
if (!HttpQueryInfo(hRequest, HTTP_QUERY_RAW_HEADERS_CRLF, NULL, &dwSize, NULL) && GetLastError() == ERROR_INSUFFICIENT_BUFFER)
{
std::vector<uint8_t> RawHeaderData(dwSize);
if (!HttpQueryInfo(hRequest, HTTP_QUERY_RAW_HEADERS_CRLF, RawHeaderData.data(), &dwSize, NULL))
{
InternetCloseHandle(hRequest);
return false;
}
strvector RawHeader = stdstr().FromUTF16((wchar_t *)RawHeaderData.data()).Tokenize("\n");
for (size_t i = 0, n = RawHeader.size(); i < n; i++)
{
RawHeader[i].Replace("\r", "");
RawHeader[i].Trim();
if (RawHeader[i].length() > 0)
{
Headers.push_back(RawHeader[i]);
}
}
}
return true;
}
void CProjectSupport::SaveSupportInfo(void)
{
std::string hash = MD5((const unsigned char *)&m_SupportInfo, sizeof(m_SupportInfo)).hex_digest();
std::vector<uint8_t> InData(sizeof(m_SupportInfo) + hash.length());
memcpy(InData.data(), (const unsigned char *)&m_SupportInfo, sizeof(m_SupportInfo));
memcpy(InData.data() + sizeof(m_SupportInfo), hash.data(), hash.length());
std::vector<uint8_t> OutData(InData.size());
z_stream defstream;
defstream.zalloc = Z_NULL;
defstream.zfree = Z_NULL;
defstream.opaque = Z_NULL;
defstream.avail_in = (uInt)InData.size();
defstream.next_in = (Bytef *)InData.data();
defstream.avail_out = (uInt)OutData.size();
defstream.next_out = (Bytef *)OutData.data();
deflateInit(&defstream, Z_BEST_COMPRESSION);
deflate(&defstream, Z_FINISH);
deflateEnd(&defstream);
OutData.resize(defstream.total_out);
for (size_t i = 0, n = OutData.size(); i < n; i++)
{
OutData[i] ^= 0xAA;
}
HKEY hKeyResults = 0;
DWORD Disposition = 0;
long lResult = RegCreateKeyEx(HKEY_CURRENT_USER, L"SOFTWARE\\Project64", 0, L"", REG_OPTION_NON_VOLATILE, KEY_ALL_ACCESS, NULL, &hKeyResults, &Disposition);
if (lResult == ERROR_SUCCESS)
{
RegSetValueEx(hKeyResults, L"user", 0, REG_BINARY, (BYTE *)OutData.data(), OutData.size());
RegCloseKey(hKeyResults);
}
}
void CProjectSupport::LoadSupportInfo(void)
{
std::string MachineID = GenerateMachineID();
std::vector<uint8_t> InData;
HKEY hKeyResults = 0;
long lResult = RegOpenKeyEx(HKEY_CURRENT_USER, L"SOFTWARE\\Project64", 0, KEY_READ, &hKeyResults);
if (lResult == ERROR_SUCCESS)
{
DWORD DataSize = 0;
if (RegQueryValueEx(hKeyResults, L"user", NULL, NULL, NULL, &DataSize) == ERROR_SUCCESS)
{
InData.resize(DataSize);
if (RegQueryValueEx(hKeyResults, L"user", NULL, NULL, InData.data(), &DataSize) != ERROR_SUCCESS)
{
InData.clear();
}
}
}
if (hKeyResults != NULL)
{
RegCloseKey(hKeyResults);
NULL;
}
std::vector<uint8_t> OutData;
if (InData.size() > 0)
{
for (size_t i = 0, n = InData.size(); i < n; i++)
{
InData[i] ^= 0xAA;
}
OutData.resize(sizeof(m_SupportInfo) + 100);
uLongf DestLen = OutData.size();
if (uncompress(OutData.data(), &DestLen, InData.data(), InData.size()) >= 0)
{
OutData.resize(DestLen);
}
else
{
OutData.clear();
}
}
if (OutData.size() > 0)
{
SupportInfo * Info = (SupportInfo *)OutData.data();
const char * CurrentHash = (const char *)(OutData.data() + sizeof(SupportInfo));
std::string hash = MD5((const unsigned char *)Info, sizeof(SupportInfo)).hex_digest();
if (strcmp(hash.c_str(), CurrentHash) == 0 && strcmp(Info->MachineID, MachineID.c_str()) == 0)
{
memcpy(&m_SupportInfo, Info, sizeof(SupportInfo));
}
}
strcpy(m_SupportInfo.MachineID, MachineID.c_str());
}

View File

@ -0,0 +1,39 @@
#pragma once
#include <string>
#include <vector>
class CProjectSupport
{
typedef struct
{
char Code[300];
char Email[300];
char Name[300];
char MachineID[300];
uint32_t RunCount;
bool Validated;
} SupportInfo;
public:
CProjectSupport();
bool RequestCode(const char * Email);
bool ValidateCode(const char * Code);
void IncrementRunCount();
inline uint32_t RunCount() const { return m_SupportInfo.RunCount; }
inline const char * MachineID(void) const { return m_SupportInfo.MachineID; }
inline bool Validated(void) const { return m_SupportInfo.Validated; }
private:
CProjectSupport(const CProjectSupport&);
CProjectSupport& operator=(const CProjectSupport&);
std::string GenerateMachineID();
bool PerformRequest(const wchar_t * Url, const std::string & PostData, DWORD & StatusCode, std::vector<std::string> & Headers);
void SaveSupportInfo(void);
void LoadSupportInfo(void);
SupportInfo m_SupportInfo;
};

View File

@ -3,34 +3,137 @@
#include <Project64-core/Settings/SettingType/SettingsType-Application.h>
#include "resource.h"
class CRequestCode :
public CDialogImpl<CRequestCode>
{
public:
BEGIN_MSG_MAP_EX(CRequestCode)
MESSAGE_HANDLER(WM_INITDIALOG, OnInitDialog)
MESSAGE_HANDLER(WM_CTLCOLORSTATIC, OnColorStatic)
MESSAGE_HANDLER(WM_ERASEBKGND, OnEraseBackground)
COMMAND_ID_HANDLER(IDOK, OnOkCmd)
COMMAND_ID_HANDLER(IDCANCEL, OnCloseCmd)
END_MSG_MAP()
enum { IDD = IDD_Support_RequestCode };
CRequestCode(CProjectSupport & Support);
private:
CRequestCode(void);
CRequestCode(const CRequestCode&);
CRequestCode& operator=(const CRequestCode&);
LRESULT OnInitDialog(UINT /*uMsg*/, WPARAM /*wParam*/, LPARAM /*lParam*/, BOOL& /*bHandled*/);
LRESULT OnColorStatic(UINT /*uMsg*/, WPARAM wParam, LPARAM lParam, BOOL& bHandled);
LRESULT OnEraseBackground(UINT /*uMsg*/, WPARAM wParam, LPARAM /*lParam*/, BOOL& bHandled);
LRESULT OnOkCmd(WORD /*wNotifyCode*/, WORD wID, HWND /*hWndCtl*/, BOOL& /*bHandled*/);
LRESULT OnCloseCmd(WORD /*wNotifyCode*/, WORD wID, HWND /*hWndCtl*/, BOOL& /*bHandled*/);
CProjectSupport & m_Support;
};
CSupportEnterCode::CSupportEnterCode(CProjectSupport & Support) :
m_Support(Support)
{
}
LRESULT CSupportEnterCode::OnInitDialog(UINT /*uMsg*/, WPARAM /*wParam*/, LPARAM /*lParam*/, BOOL& /*bHandled*/)
{
::SetWindowTextW(m_hWnd, wGS(MSG_SUPPORT_ENTER_CODE_TITLE).c_str());
::SetWindowTextW(GetDlgItem(IDOK), wGS(MSG_SUPPORT_OK).c_str());
::SetWindowTextW(GetDlgItem(IDCANCEL), wGS(MSG_SUPPORT_CANCEL).c_str());
::SetWindowTextW(GetDlgItem(IDC_DESCRIPTION), wGS(MSG_SUPPORT_ENTER_CODE_DESC).c_str());
SetWindowText(wGS(MSG_SUPPORT_ENTER_CODE_TITLE).c_str());
CWindow hDescription = GetDlgItem(IDC_DESCRIPTION);
CWindow MachineId = GetDlgItem(IDC_MACHINE_ID);
CWindow OkBtn = GetDlgItem(IDOK);
CWindow CancelBtn = GetDlgItem(IDCANCEL);
std::wstring DescriptionText = wGS(MSG_SUPPORT_ENTER_CODE_DESC);
hDescription.SetWindowText(DescriptionText.c_str());
MachineId.SetWindowText(stdstr(m_Support.MachineID()).ToUTF16().c_str());
OkBtn.SetWindowText(wGS(MSG_SUPPORT_OK).c_str());
CancelBtn.SetWindowText(wGS(MSG_SUPPORT_CANCEL).c_str());
m_RequestLink.SubclassWindow(GetDlgItem(IDC_REQUEST_LINK));
m_RequestLink.SetHyperLinkExtendedStyle(HLINK_COMMANDBUTTON, HLINK_COMMANDBUTTON);
CRect rcWin = { 0 };
hDescription.GetClientRect(&rcWin);
CDC hDC = hDescription.GetDC();
HFONT hFont = hDescription.GetFont();
if (hFont == nullptr)
{
hFont = (HFONT)::GetStockObject(SYSTEM_FONT);
}
hDC.SelectFont(hFont);
if (hDC.DrawText(DescriptionText.c_str(), DescriptionText.length(), &rcWin, DT_LEFT | DT_CALCRECT | DT_WORDBREAK | DT_NOCLIP) > 0)
{
hDescription.SetWindowPos(NULL, 0, 0, rcWin.right, rcWin.bottom, SWP_NOACTIVATE | SWP_NOMOVE | SWP_NOOWNERZORDER);
}
hDescription.GetWindowRect(&rcWin);
::MapWindowPoints(NULL, m_hWnd, (LPPOINT)&rcWin, 2);
MachineId.SetWindowPos(NULL, rcWin.left, rcWin.bottom + 4, 0, 0, SWP_NOACTIVATE | SWP_NOSIZE | SWP_NOOWNERZORDER);
MachineId.GetWindowRect(&rcWin);
::MapWindowPoints(NULL, m_hWnd, (LPPOINT)&rcWin, 2);
CWindow Code = GetDlgItem(IDC_CODE);
Code.SetWindowPos(NULL, rcWin.left, rcWin.bottom + 4, 0, 0, SWP_NOACTIVATE | SWP_NOSIZE | SWP_NOOWNERZORDER);
Code.GetWindowRect(&rcWin);
::MapWindowPoints(NULL, m_hWnd, (LPPOINT)&rcWin, 2);
CWindow RequestDescption = GetDlgItem(IDC_REQUEST_DESCPTION);
RequestDescption.ShowWindow(SWP_HIDEWINDOW);
RequestDescption.SetWindowPos(NULL, rcWin.left, rcWin.bottom + 10, 0, 0, SWP_NOACTIVATE | SWP_NOSIZE | SWP_NOOWNERZORDER);
RequestDescption.GetWindowRect(&rcWin);
::MapWindowPoints(NULL, m_hWnd, (LPPOINT)&rcWin, 2);
CWindow RequestLink = GetDlgItem(IDC_REQUEST_LINK);
RequestLink.ShowWindow(SWP_HIDEWINDOW);
RequestLink.SetWindowPos(NULL, rcWin.left, rcWin.bottom + 4, 0, 0, SWP_NOACTIVATE | SWP_NOSIZE | SWP_NOOWNERZORDER);
RequestLink.GetWindowRect(&rcWin);
::MapWindowPoints(NULL, m_hWnd, (LPPOINT)&rcWin, 2);
RECT CancelBtnWin = { 0 };
CancelBtn.GetWindowRect(&CancelBtnWin);
::MapWindowPoints(NULL, m_hWnd, (LPPOINT)&CancelBtnWin, 2);
CancelBtn.SetWindowPos(NULL, CancelBtnWin.left, rcWin.bottom + 40, 0, 0, SWP_NOACTIVATE | SWP_NOSIZE | SWP_NOOWNERZORDER);
RECT OkBtnWin = { 0 };
OkBtn.GetWindowRect(&OkBtnWin);
::MapWindowPoints(NULL, m_hWnd, (LPPOINT)&OkBtnWin, 2);
OkBtn.SetWindowPos(NULL, OkBtnWin.left, rcWin.bottom + 40, 0, 0, SWP_NOACTIVATE | SWP_NOSIZE | SWP_NOOWNERZORDER);
OkBtn.GetWindowRect(&OkBtnWin);
::MapWindowPoints(NULL, m_hWnd, (LPPOINT)&OkBtnWin, 2);
GetWindowRect(&rcWin);
SetRect(&rcWin, 0, 0, rcWin.Width(), OkBtnWin.bottom + 30);
AdjustWindowRectEx(&rcWin, GetStyle(), GetMenu() != NULL, GetExStyle());
int32_t Left = (GetSystemMetrics(SM_CXSCREEN) - rcWin.Width()) / 2;
int32_t Top = (GetSystemMetrics(SM_CYSCREEN) - rcWin.Height()) / 2;
MoveWindow(Left, Top, rcWin.Width(), rcWin.Height(), TRUE);
return TRUE;
}
LRESULT CSupportEnterCode::OnColorStatic(UINT /*uMsg*/, WPARAM wParam, LPARAM /*lParam*/, BOOL& /*bHandled*/)
{
HDC hdcStatic = (HDC)wParam;
SetTextColor(hdcStatic, RGB(0, 0, 0));
SetBkMode(hdcStatic, TRANSPARENT);
CDCHandle hdcStatic = (HDC)wParam;
hdcStatic.SetTextColor(RGB(0, 0, 0));
hdcStatic.SetBkMode(TRANSPARENT);
return (LONG)(LRESULT)((HBRUSH)GetStockObject(NULL_BRUSH));
}
LRESULT CSupportEnterCode::OnEraseBackground(UINT /*uMsg*/, WPARAM wParam, LPARAM /*lParam*/, BOOL& /*bHandled*/)
{
static HPEN outline = CreatePen(PS_SOLID, 1, 0x00FFFFFF);
static HBRUSH fill = CreateSolidBrush(0x00FFFFFF);
SelectObject((HDC)wParam, outline);
SelectObject((HDC)wParam, fill);
static HPEN Outline = CreatePen(PS_SOLID, 1, 0x00FFFFFF);
static HBRUSH Fill = CreateSolidBrush(0x00FFFFFF);
CDCHandle hdc = (HDC)wParam;
hdc.SelectPen(Outline);
hdc.SelectBrush(Fill);
RECT rect;
GetClientRect(&rect);
Rectangle((HDC)wParam, rect.left, rect.top, rect.right, rect.bottom);
hdc.Rectangle(&rect);
return TRUE;
}
@ -48,14 +151,99 @@ LRESULT CSupportEnterCode::OnOkCmd(WORD /*wNotifyCode*/, WORD wID, HWND /*hWndCt
MessageBox(wGS(MSG_SUPPORT_ENTER_SUPPORT_CODE).c_str(), wGS(MSG_SUPPORT_PROJECT64).c_str(), MB_OK);
return false;
}
if (_wcsicmp(code,L"thank you from project64") != 0)
GetDlgItem(IDOK).EnableWindow(false);
GetDlgItem(IDCANCEL).EnableWindow(false);
bool ValidCode = false;
if (_wcsicmp(code,L"thank you from project64") == 0)
{
UISettingsSaveDword(SupportWindows_RunCount, (uint32_t)-1);
CSettingTypeApplication::Flush();
ValidCode = true;
}
else if (m_Support.ValidateCode(stdstr().FromUTF16(code).c_str()))
{
ValidCode = true;
}
if (ValidCode)
{
MessageBox(wGS(MSG_SUPPORT_COMPLETE).c_str(), wGS(MSG_SUPPORT_PROJECT64).c_str(), MB_OK);
EndDialog(wID);
}
else
{
MessageBox(wGS(MSG_SUPPORT_INCORRECT_CODE).c_str(), wGS(MSG_SUPPORT_PROJECT64).c_str(), MB_OK);
return false;
GetDlgItem(IDOK).EnableWindow(TRUE);
GetDlgItem(IDCANCEL).EnableWindow(TRUE);
}
UISettingsSaveDword(SupportWindows_RunCount, (uint32_t) -1);
CSettingTypeApplication::Flush();
MessageBox(wGS(MSG_SUPPORT_COMPLETE).c_str(), wGS(MSG_SUPPORT_PROJECT64).c_str(), MB_OK);
return TRUE;
}
CRequestCode::CRequestCode(CProjectSupport & Support) :
m_Support(Support)
{
}
LRESULT CSupportEnterCode::OnRequestCode(WORD /*wNotifyCode*/, WORD /*wID*/, HWND /*hWndCtl*/, BOOL& /*bHandled*/)
{
CRequestCode RequestWindow(m_Support);
RequestWindow.DoModal(m_hWnd);
return 0;
}
LRESULT CRequestCode::OnInitDialog(UINT /*uMsg*/, WPARAM /*wParam*/, LPARAM /*lParam*/, BOOL& /*bHandled*/)
{
return TRUE;
}
LRESULT CRequestCode::OnColorStatic(UINT /*uMsg*/, WPARAM wParam, LPARAM /*lParam*/, BOOL& /*bHandled*/)
{
CDCHandle hdcStatic = (HDC)wParam;
hdcStatic.SetTextColor(RGB(0, 0, 0));
hdcStatic.SetBkMode(TRANSPARENT);
return (LONG)(LRESULT)((HBRUSH)GetStockObject(NULL_BRUSH));
}
LRESULT CRequestCode::OnEraseBackground(UINT /*uMsg*/, WPARAM wParam, LPARAM /*lParam*/, BOOL& /*bHandled*/)
{
static HPEN Outline = CreatePen(PS_SOLID, 1, 0x00FFFFFF);
static HBRUSH Fill = CreateSolidBrush(0x00FFFFFF);
CDCHandle hdc = (HDC)wParam;
hdc.SelectPen(Outline);
hdc.SelectBrush(Fill);
RECT rect;
GetClientRect(&rect);
hdc.Rectangle(&rect);
return TRUE;
}
LRESULT CRequestCode::OnOkCmd(WORD /*wNotifyCode*/, WORD wID, HWND /*hWndCtl*/, BOOL& /*bHandled*/)
{
CWindow EmailWnd(GetDlgItem(IDC_EMAIL));
int EmailLen = EmailWnd.GetWindowTextLength();
std::wstring Email;
Email.resize(EmailLen + 1);
EmailWnd.GetWindowText((wchar_t *)Email.c_str(), Email.length());
GetDlgItem(IDOK).EnableWindow(false);
GetDlgItem(IDCANCEL).EnableWindow(false);
if (m_Support.RequestCode(stdstr().FromUTF16(Email.c_str()).c_str()))
{
MessageBox(wGS(MSG_SUPPORT_REQUESTCODE_SUCCESS).c_str(), wGS(MSG_SUPPORT_REQUESTCODE_TITLE).c_str(), MB_OK);
EndDialog(wID);
}
else
{
MessageBox(wGS(MSG_SUPPORT_REQUESTCODE_FAIL).c_str(), wGS(MSG_SUPPORT_REQUESTCODE_TITLE).c_str(), MB_OK);
GetDlgItem(IDOK).EnableWindow(true);
GetDlgItem(IDCANCEL).EnableWindow(true);
}
return TRUE;
}
LRESULT CRequestCode::OnCloseCmd(WORD /*wNotifyCode*/, WORD wID, HWND /*hWndCtl*/, BOOL& /*bHandled*/)
{
EndDialog(wID);
return TRUE;
}

View File

@ -1,4 +1,5 @@
#pragma once
#include "resource.h"
class CSupportEnterCode :
public CDialogImpl<CSupportEnterCode>
@ -10,14 +11,25 @@ public:
MESSAGE_HANDLER(WM_ERASEBKGND, OnEraseBackground)
COMMAND_ID_HANDLER(IDOK, OnOkCmd)
COMMAND_ID_HANDLER(IDCANCEL, OnCloseCmd)
COMMAND_ID_HANDLER(IDC_REQUEST_LINK, OnRequestCode)
END_MSG_MAP()
enum { IDD = IDD_Support_EnterCode };
CSupportEnterCode(CProjectSupport & Support);
private:
CSupportEnterCode(void);
CSupportEnterCode(const CSupportEnterCode&);
CSupportEnterCode& operator=(const CSupportEnterCode&);
LRESULT OnInitDialog(UINT /*uMsg*/, WPARAM /*wParam*/, LPARAM /*lParam*/, BOOL& /*bHandled*/);
LRESULT OnColorStatic(UINT /*uMsg*/, WPARAM wParam, LPARAM lParam, BOOL& bHandled);
LRESULT OnEraseBackground(UINT /*uMsg*/, WPARAM wParam, LPARAM /*lParam*/, BOOL& bHandled);
LRESULT OnOkCmd(WORD /*wNotifyCode*/, WORD wID, HWND /*hWndCtl*/, BOOL& /*bHandled*/);
LRESULT OnCloseCmd(WORD /*wNotifyCode*/, WORD wID, HWND /*hWndCtl*/, BOOL& /*bHandled*/);
LRESULT OnRequestCode(WORD /*wNotifyCode*/, WORD wID, HWND /*hWndCtl*/, BOOL& /*bHandled*/);
CHyperLink m_RequestLink;
CProjectSupport & m_Support;
};

View File

@ -2,12 +2,13 @@
#include "SupportEnterCode.h"
#include <time.h>
HWND CSupportWindow::m_hParent = NULL;
CSupportWindow * CSupportWindow::m_this = NULL;
uint32_t CSupportWindow::m_RunCount = 0;
uint32_t CSupportWindow::m_TimeOutTime = 30;
CSupportWindow * CSupportWindow::m_this = nullptr;
CSupportWindow::CSupportWindow(void)
CSupportWindow::CSupportWindow(CProjectSupport & Support) :
m_Support(Support),
m_TimeOutTime(30),
m_hParent(nullptr),
m_Delay(false)
{
}
@ -18,27 +19,32 @@ CSupportWindow::~CSupportWindow(void)
void CALLBACK CSupportWindow::TimerProc(HWND, UINT, UINT_PTR idEvent, DWORD)
{
::KillTimer(NULL, idEvent);
CSupportWindow SupportWindow;
SupportWindow.DoModal(m_hParent);
m_this->DoModal(m_this->m_hParent);
}
void CSupportWindow::Show(HWND hParent)
void CSupportWindow::Show(HWND hParent, bool Delay)
{
m_RunCount = UISettingsLoadDword(SupportWindows_RunCount);
if (m_RunCount == -1)
m_Delay = Delay;
if (Delay)
{
return;
}
UISettingsSaveDword(SupportWindows_RunCount, m_RunCount + 1);
if (m_RunCount < 3)
if (UISettingsLoadDword(SupportWindows_RunCount) == -1 || m_Support.Validated())
{
return;
}
m_Support.IncrementRunCount();
if (m_Support.RunCount() < 7)
{
return;
}
m_hParent = hParent;
m_this = this;
::SetTimer(NULL, 0, 2500, TimerProc);
::SetTimer(nullptr, 0, 2500, TimerProc);
}
else
{
DoModal(hParent);
}
}
void CSupportWindow::EnableContinue()
@ -50,72 +56,101 @@ void CSupportWindow::EnableContinue()
LRESULT CSupportWindow::OnInitDialog(UINT /*uMsg*/, WPARAM /*wParam*/, LPARAM /*lParam*/, BOOL& /*bHandled*/)
{
::SetWindowTextW(m_hWnd, wGS(MSG_SUPPORT_TITLE).c_str());
::SetWindowTextW(GetDlgItem(IDC_ENTER_CODE), wGS(MSG_SUPPORT_ENTER_CODE).c_str());
::SetWindowTextW(GetDlgItem(ID_SUPPORT_PJ64), wGS(MSG_SUPPORT_PROJECT64).c_str());
::SetWindowTextW(GetDlgItem(IDCANCEL), wGS(MSG_SUPPORT_CONTINUE).c_str());
m_Logo.SubclassWindow(GetDlgItem(IDC_BMP_LOGO));
m_Logo.SetBitmap(MAKEINTRESOURCE(IDB_ABOUT_LOGO));
{
HWND hInfo = GetDlgItem(IDC_INFO);
std::wstring InfoText = wGS(MSG_SUPPORT_INFO);
RECT rcWin = { 0 };
::GetClientRect(hInfo,&rcWin);
SetWindowText(wGS(MSG_SUPPORT_TITLE).c_str());
GetDlgItem(IDC_ENTER_CODE).SetWindowText(wGS(MSG_SUPPORT_ENTER_CODE).c_str());
GetDlgItem(ID_SUPPORT_PJ64).SetWindowText(wGS(MSG_SUPPORT_PROJECT64).c_str());
GetDlgItem(IDCANCEL).SetWindowText(wGS(MSG_SUPPORT_CONTINUE).c_str());
HDC hDC = ::GetDC(hInfo);
HFONT hFont = (HFONT)::SendMessage(hInfo, WM_GETFONT, 0, 0L);
if(hFont == NULL)
m_EnterLink.SubclassWindow(GetDlgItem(IDC_ENTER_CODE));
m_EnterLink.SetHyperLinkExtendedStyle(HLINK_COMMANDBUTTON, HLINK_COMMANDBUTTON);
m_EnterLink.EnableWindow(!m_Support.Validated());
CWindow hInfo = GetDlgItem(IDC_INFO);
CRect rcWin = { 0 };
hInfo.GetClientRect(&rcWin);
CDC hDC = hInfo.GetDC();
HFONT hFont = hInfo.GetFont();
if(hFont == nullptr)
{
hFont = (HFONT)::GetStockObject(SYSTEM_FONT);
}
SelectObject(hDC, hFont);
if (DrawTextW(hDC,InfoText.c_str(),InfoText.length(),&rcWin,DT_LEFT | DT_CALCRECT | DT_WORDBREAK | DT_NOCLIP) > 0)
hDC.SelectFont(hFont);
if (hDC.DrawText(InfoText.c_str(),InfoText.length(),&rcWin,DT_LEFT | DT_CALCRECT | DT_WORDBREAK | DT_NOCLIP) > 0)
{
::SetWindowPos(hInfo,NULL,0,0,rcWin.right, rcWin.bottom,SWP_NOACTIVATE|SWP_NOMOVE|SWP_NOOWNERZORDER);
hInfo.SetWindowPos(NULL,0,0,rcWin.right, rcWin.bottom,SWP_NOACTIVATE|SWP_NOMOVE|SWP_NOOWNERZORDER);
}
::SetWindowTextW(hInfo, InfoText.c_str());
::GetWindowRect(hInfo,&rcWin);
hInfo.SetWindowText(InfoText.c_str());
hInfo.GetWindowRect(&rcWin);
::MapWindowPoints(NULL, m_hWnd, (LPPOINT)&rcWin, 2);
::SetWindowPos(GetDlgItem(IDC_ENTER_CODE),NULL,rcWin.left,rcWin.bottom + 4,0,0,SWP_NOACTIVATE|SWP_NOSIZE|SWP_NOOWNERZORDER);
m_EnterLink.SubclassWindow(GetDlgItem(IDC_ENTER_CODE));
m_EnterLink.SetHyperLinkExtendedStyle(HLINK_COMMANDBUTTON,HLINK_COMMANDBUTTON);
}
if (m_RunCount >= 10)
CWindow EnterCode = GetDlgItem(IDC_ENTER_CODE);
EnterCode.SetWindowPos(NULL,rcWin.left,rcWin.bottom + 4,0,0,SWP_NOACTIVATE|SWP_NOSIZE|SWP_NOOWNERZORDER);
EnterCode.GetWindowRect(&rcWin);
::MapWindowPoints(NULL, m_hWnd, (LPPOINT)&rcWin, 2);
CWindow SupportBtn = GetDlgItem(ID_SUPPORT_PJ64);
RECT SupportBtnWin = { 0 };
SupportBtn.GetWindowRect(&SupportBtnWin);
::MapWindowPoints(NULL, m_hWnd, (LPPOINT)&SupportBtnWin, 2);
SupportBtn.SetWindowPos(NULL, SupportBtnWin.left, rcWin.bottom + 40, 0, 0, SWP_NOACTIVATE | SWP_NOSIZE | SWP_NOOWNERZORDER);
CWindow CancelBtn = GetDlgItem(IDCANCEL);
RECT CancelBtnWin = { 0 };
CancelBtn.GetWindowRect(&CancelBtnWin);
::MapWindowPoints(NULL, m_hWnd, (LPPOINT)&CancelBtnWin, 2);
CancelBtn.SetWindowPos(NULL, CancelBtnWin.left, rcWin.bottom + 40, 0, 0, SWP_NOACTIVATE | SWP_NOSIZE | SWP_NOOWNERZORDER);
GetWindowRect(&rcWin);
SupportBtn.GetWindowRect(&SupportBtnWin);
::MapWindowPoints(NULL, m_hWnd, (LPPOINT)&SupportBtnWin, 2);
SetRect(&rcWin, 0, 0, rcWin.Width(), SupportBtnWin.bottom + 30);
AdjustWindowRectEx(&rcWin, GetStyle(), GetMenu() != NULL, GetExStyle());
int32_t Left = (GetSystemMetrics(SM_CXSCREEN) - rcWin.Width()) / 2;
int32_t Top = (GetSystemMetrics(SM_CYSCREEN) - rcWin.Height()) / 2;
MoveWindow(Left, Top, rcWin.Width(), rcWin.Height(), TRUE);
/*if (m_Delay && m_RunCount >= 10)
{
HMENU menu = GetSystemMenu(false);
RemoveMenu(menu, SC_CLOSE, MF_BYCOMMAND);
CMenuHandle menu = GetSystemMenu(false);
menu.RemoveMenu(SC_CLOSE, MF_BYCOMMAND);
DWORD dwStyle = GetWindowLong(GWL_STYLE);
dwStyle |= CS_NOCLOSE;
SetWindowLong(GWL_STYLE, dwStyle);
::EnableWindow(GetDlgItem(IDCANCEL), false);
GetDlgItem(IDCANCEL).EnableWindow(false);
srand ((uint32_t)time(NULL));
SetTimer(0, 1000, NULL);
}
}*/
return TRUE;
}
LRESULT CSupportWindow::OnColorStatic(UINT /*uMsg*/, WPARAM wParam, LPARAM /*lParam*/, BOOL& /*bHandled*/)
{
HDC hdcStatic = (HDC)wParam;
SetTextColor(hdcStatic, RGB(0, 0, 0));
SetBkMode(hdcStatic, TRANSPARENT);
CDCHandle hdcStatic = (HDC)wParam;
hdcStatic.SetTextColor(RGB(0, 0, 0));
hdcStatic.SetBkMode(TRANSPARENT);
return (LONG)(LRESULT)((HBRUSH)GetStockObject(NULL_BRUSH));
}
LRESULT CSupportWindow::OnEraseBackground(UINT /*uMsg*/, WPARAM wParam, LPARAM /*lParam*/, BOOL& /*bHandled*/)
{
static HPEN outline = CreatePen(PS_SOLID, 1, 0x00FFFFFF);
static HBRUSH fill = CreateSolidBrush(0x00FFFFFF);
SelectObject((HDC)wParam, outline);
SelectObject((HDC)wParam, fill);
static HPEN Outline = CreatePen(PS_SOLID, 1, 0x00FFFFFF);
static HBRUSH Fill = CreateSolidBrush(0x00FFFFFF);
CDCHandle hdc = (HDC)wParam;
hdc.SelectPen(Outline);
hdc.SelectBrush(Fill);
RECT rect;
GetClientRect(&rect);
Rectangle((HDC)wParam, rect.left, rect.top, rect.right, rect.bottom);
hdc.Rectangle(&rect);
return TRUE;
}
@ -127,8 +162,8 @@ LRESULT CSupportWindow::OnTimer(UINT /*uMsg*/, WPARAM wParam, LPARAM /*lParam*/,
KillTimer(wParam);
EnableContinue();
}
stdstr_f continue_txt(m_TimeOutTime > 0 ? "%s (%d)" : "%s", GS(MSG_SUPPORT_CONTINUE), m_TimeOutTime);
::SetWindowTextW(GetDlgItem(IDCANCEL), continue_txt.ToUTF16().c_str());
stdstr_f Continue_txt(m_TimeOutTime > 0 ? "%s (%d)" : "%s", GS(MSG_SUPPORT_CONTINUE), m_TimeOutTime);
GetDlgItem(IDCANCEL).SetWindowText(Continue_txt.ToUTF16().c_str());
return true;
}
@ -140,18 +175,22 @@ LRESULT CSupportWindow::OnCloseCmd(WORD /*wNotifyCode*/, WORD wID, HWND /*hWndCt
LRESULT CSupportWindow::OnSupportProject64(WORD /*wNotifyCode*/, WORD /*wID*/, HWND /*hWndCtl*/, BOOL& /*bHandled*/)
{
stdstr SupportURL = stdstr_f("http://www.pj64-emu.com/support-project64.html?ver=%s", VER_FILE_VERSION_STR);
stdstr SupportURL = stdstr_f("https://www.pj64-emu.com/support-project64.html?ver=%s&machine=%s", VER_FILE_VERSION_STR, m_Support.MachineID());
ShellExecute(NULL, L"open", SupportURL.ToUTF16().c_str(), NULL, NULL, SW_SHOWMAXIMIZED);
return TRUE;
}
LRESULT CSupportWindow::OnEnterCode(WORD /*wNotifyCode*/, WORD wID, HWND /*hWndCtl*/, BOOL& /*bHandled*/)
{
CSupportEnterCode EnterCodeWindow;
CSupportEnterCode EnterCodeWindow(m_Support);
EnterCodeWindow.DoModal(m_hWnd);
if (UISettingsLoadDword(SupportWindows_RunCount) == -1)
{
EndDialog(wID);
}
if (m_Support.Validated())
{
EndDialog(wID);
}
return TRUE;
}

View File

@ -1,4 +1,6 @@
#pragma once
#include <Project64\UserInterface\WTLControls\wtl-BitmapPicture.h>
#include "resource.h"
class CSupportWindow :
public CDialogImpl<CSupportWindow>
@ -16,12 +18,16 @@ public:
enum { IDD = IDD_Support_Project64 };
CSupportWindow(void);
CSupportWindow(CProjectSupport & Support);
~CSupportWindow(void);
void Show(HWND hParent);
void Show(HWND hParent, bool Delay);
private:
CSupportWindow();
CSupportWindow(const CSupportWindow&);
CSupportWindow& operator=(const CSupportWindow&);
LRESULT OnInitDialog(UINT /*uMsg*/, WPARAM /*wParam*/, LPARAM /*lParam*/, BOOL& /*bHandled*/);
LRESULT OnColorStatic(UINT /*uMsg*/, WPARAM wParam, LPARAM lParam, BOOL& bHandled);
LRESULT OnEraseBackground(UINT /*uMsg*/, WPARAM wParam, LPARAM /*lParam*/, BOOL& bHandled);
@ -34,11 +40,12 @@ private:
CHyperLink m_EnterLink;
static DWORD CALLBACK SupportWindowProc(HWND hWnd, DWORD uMsg, DWORD wParam, DWORD lParam);
static void CALLBACK TimerProc(HWND, UINT, UINT_PTR idEvent, DWORD);
static HWND m_hParent;
CProjectSupport & m_Support;
CBitmapPicture m_Logo;
bool m_Delay;
uint32_t m_TimeOutTime;
HWND m_hParent;
static CSupportWindow * m_this;
static uint32_t m_RunCount;
static uint32_t m_TimeOutTime;
};

View File

@ -650,22 +650,25 @@ STYLE DS_SETFONT | DS_MODALFRAME | DS_FIXEDSYS | DS_CENTER | WS_POPUP | WS_CAPTI
CAPTION "Support Project64"
FONT 8, "MS Shell Dlg", 0, 0, 0x1
BEGIN
CONTROL IDD_About_Ini,IDC_STATIC,"Static",SS_BITMAP,0,0,233,74
CONTROL "",IDC_BMP_LOGO,"Static",SS_BLACKFRAME,1,0,232,74
DEFPUSHBUTTON "Support Project64",ID_SUPPORT_PJ64,19,186,71,14
PUSHBUTTON "Continue",IDCANCEL,139,186,71,14
LTEXT "Project64 is a software package",IDC_INFO,7,76,213,79
LTEXT "Enter notification code",IDC_ENTER_CODE,8,164,213,8
END
IDD_Support_EnterCode DIALOGEX 0, 0, 161, 68
IDD_Support_EnterCode DIALOGEX 0, 0, 174, 117
STYLE DS_SETFONT | DS_MODALFRAME | DS_FIXEDSYS | DS_CENTER | WS_POPUP | WS_CAPTION | WS_SYSMENU
CAPTION "Enter Code"
FONT 8, "MS Shell Dlg", 0, 0, 0x1
BEGIN
DEFPUSHBUTTON "OK",IDOK,50,47,50,14
PUSHBUTTON "Cancel",IDCANCEL,104,47,50,14
LTEXT "Please enter the code in email",IDC_DESCRIPTION,7,7,147,15
EDITTEXT IDC_CODE,7,25,147,12,ES_AUTOHSCROLL
DEFPUSHBUTTON "OK",IDOK,64,96,50,14
PUSHBUTTON "Cancel",IDCANCEL,117,96,50,14
LTEXT "Please enter the code in email",IDC_DESCRIPTION,7,8,160,8,SS_NOPREFIX
EDITTEXT IDC_CODE,7,38,160,12,ES_AUTOHSCROLL
LTEXT "Please enter the code in email",IDC_REQUEST_DESCPTION,7,57,160,10
LTEXT "Request Code",IDC_REQUEST_LINK,7,72,160,8
LTEXT "Machine ID",IDC_MACHINE_ID,7,24,160,10,SS_NOPREFIX
END
IDD_Debugger_Commands DIALOGEX 0, 0, 535, 327
@ -1411,6 +1414,17 @@ BEGIN
COMBOBOX IDC_DISKSAVETYPE,95,104,115,30,CBS_DROPDOWNLIST | CBS_SORT | WS_VSCROLL | WS_TABSTOP
END
IDD_Support_RequestCode DIALOGEX 0, 0, 165, 96
STYLE DS_SETFONT | DS_MODALFRAME | DS_FIXEDSYS | DS_CENTER | WS_POPUP | WS_CAPTION | WS_SYSMENU
CAPTION "Request Code"
FONT 8, "MS Shell Dlg", 0, 0, 0x1
BEGIN
LTEXT "Please enter the email used to support Project64",IDC_DESCRIPTION,8,8,148,15
EDITTEXT IDC_EMAIL,8,34,148,12,ES_AUTOHSCROLL
DEFPUSHBUTTON "OK",IDOK,55,75,50,14
PUSHBUTTON "Cancel",IDCANCEL,108,75,50,14
END
/////////////////////////////////////////////////////////////////////////////
//
@ -1646,8 +1660,6 @@ BEGIN
IDD_Support_Project64, DIALOG
BEGIN
LEFTMARGIN, 7
RIGHTMARGIN, 170
TOPMARGIN, 7
BOTTOMMARGIN, 200
END
@ -1655,9 +1667,9 @@ BEGIN
IDD_Support_EnterCode, DIALOG
BEGIN
LEFTMARGIN, 7
RIGHTMARGIN, 154
RIGHTMARGIN, 167
TOPMARGIN, 7
BOTTOMMARGIN, 61
BOTTOMMARGIN, 110
END
IDD_Debugger_Commands, DIALOG
@ -1882,6 +1894,13 @@ BEGIN
TOPMARGIN, 7
BOTTOMMARGIN, 148
END
IDD_Support_RequestCode, DIALOG
BEGIN
RIGHTMARGIN, 155
TOPMARGIN, 7
BOTTOMMARGIN, 89
END
END
#endif // APSTUDIO_INVOKED
@ -2231,6 +2250,21 @@ BEGIN
0
END
IDD_Support_Project64 AFX_DIALOG_LAYOUT
BEGIN
0
END
IDD_Support_EnterCode AFX_DIALOG_LAYOUT
BEGIN
0
END
IDD_Support_RequestCode AFX_DIALOG_LAYOUT
BEGIN
0
END
/////////////////////////////////////////////////////////////////////////////
//

View File

@ -83,6 +83,7 @@
#define IDD_Debugger_ExceptionBP 207
#define IDD_Debugger_Search_SetValue 210
#define IDD_Settings_DiskDrive 215
#define IDD_Support_RequestCode 216
#define IDC_MENU_ITEM_TEXT 1000
#define IDC_CLOSE_BUTTON 1001
#define IDC_LIST2 1003
@ -276,8 +277,11 @@
#define IDC_DESCRIPTION 1102
#define IDC_DIR_FRAME3 1103
#define IDC_OVER_CLOCK_MODIFIER 1103
#define IDC_REQUEST_DESCPTION 1103
#define IDC_DIR_FRAME4 1104
#define IDC_REQUEST_LINK 1104
#define IDC_DIR_FRAME5 1105
#define IDC_MACHINE_ID 1105
#define IDC_MAXROMS_TXT 1111
#define IDC_ROMSEL_TEXT2 1112
#define IDC_R0_EDIT 1112
@ -722,6 +726,7 @@
#define IDC_F1_LBL 1576
#define IDC_SELECT_GAME_DIR 1576
#define IDC_F2_LBL 1577
#define IDC_EMAIL 1577
#define IDC_F3_LBL 1578
#define IDC_F4_LBL 1579
#define IDC_F5_LBL 1580
@ -938,9 +943,9 @@
//
#ifdef APSTUDIO_INVOKED
#ifndef APSTUDIO_READONLY_SYMBOLS
#define _APS_NEXT_RESOURCE_VALUE 220
#define _APS_NEXT_RESOURCE_VALUE 221
#define _APS_NEXT_COMMAND_VALUE 40121
#define _APS_NEXT_CONTROL_VALUE 1577
#define _APS_NEXT_CONTROL_VALUE 1578
#define _APS_NEXT_SYMED_VALUE 102
#endif
#endif

View File

@ -22,7 +22,6 @@ int WINAPI WinMain(HINSTANCE /*hInstance*/, HINSTANCE /*hPrevInstance*/, LPSTR /
g_Debugger = &Debugger;
g_Plugins->SetRenderWindows(&MainWindow, &HiddenWindow);
Notify().SetMainWindow(&MainWindow);
CSupportWindow SupportWindow;
bool isROMLoaded = false;
if (g_Settings->LoadStringVal(Cmd_RomFile).length() > 0 && g_Settings->LoadStringVal(Cmd_ComboDiskFile).length() > 0)
@ -64,26 +63,23 @@ int WINAPI WinMain(HINSTANCE /*hInstance*/, HINSTANCE /*hPrevInstance*/, LPSTR /
}
}
//Handle Main Window if ROM is not loaded and running
if (!isROMLoaded)
{
SupportWindow.Show(reinterpret_cast<HWND>(MainWindow.GetWindowHandle()));
CSupportWindow(MainWindow.Support()).Show((HWND)MainWindow.GetWindowHandle(), true);
if (UISettingsLoadBool(RomBrowser_Enabled))
{
WriteTrace(TraceUserInterface, TraceDebug, "Show Rom Browser");
//Display the rom browser
MainWindow.ShowRomList();
MainWindow.Show(true); //Show the main window
MainWindow.Show(true);
MainWindow.HighLightLastRom();
}
else
{
WriteTrace(TraceUserInterface, TraceDebug, "Show Main Window");
MainWindow.Show(true); //Show the main window
MainWindow.Show(true);
}
}
//Process Messages till program is closed
WriteTrace(TraceUserInterface, TraceDebug, "Entering Message Loop");
MainWindow.ProcessAllMessages();
WriteTrace(TraceUserInterface, TraceDebug, "Message Loop Finished");