mirror of
https://github.com/twisterarmy/twister-core.git
synced 2025-01-11 07:17:53 +00:00
GUI-less build target bitcoind that links to wxBase and shouldn't need GTK,
split init and shutdown from ui.cpp into init.cpp, support wxUSE_GUI=0 -- version 0.2.7
This commit is contained in:
parent
30158c77e9
commit
5eede9d4d9
@ -21,9 +21,11 @@
|
|||||||
#include <wx/wx.h>
|
#include <wx/wx.h>
|
||||||
#include <wx/clipbrd.h>
|
#include <wx/clipbrd.h>
|
||||||
#include <wx/snglinst.h>
|
#include <wx/snglinst.h>
|
||||||
#include <wx/taskbar.h>
|
|
||||||
#include <wx/stdpaths.h>
|
#include <wx/stdpaths.h>
|
||||||
#include <wx/utils.h>
|
#include <wx/utils.h>
|
||||||
|
#if wxUSE_GUI
|
||||||
|
#include <wx/taskbar.h>
|
||||||
|
#endif
|
||||||
#include <openssl/ecdsa.h>
|
#include <openssl/ecdsa.h>
|
||||||
#include <openssl/evp.h>
|
#include <openssl/evp.h>
|
||||||
#include <openssl/rand.h>
|
#include <openssl/rand.h>
|
||||||
@ -100,8 +102,11 @@ using namespace boost;
|
|||||||
#include "irc.h"
|
#include "irc.h"
|
||||||
#include "main.h"
|
#include "main.h"
|
||||||
#include "rpc.h"
|
#include "rpc.h"
|
||||||
|
#if wxUSE_GUI
|
||||||
#include "uibase.h"
|
#include "uibase.h"
|
||||||
|
#endif
|
||||||
#include "ui.h"
|
#include "ui.h"
|
||||||
|
#include "init.h"
|
||||||
|
|
||||||
#include "xpm/addressbook16.xpm"
|
#include "xpm/addressbook16.xpm"
|
||||||
#include "xpm/addressbook20.xpm"
|
#include "xpm/addressbook20.xpm"
|
||||||
|
625
init.cpp
Normal file
625
init.cpp
Normal file
@ -0,0 +1,625 @@
|
|||||||
|
// Copyright (c) 2009-2010 Satoshi Nakamoto
|
||||||
|
// Distributed under the MIT/X11 software license, see the accompanying
|
||||||
|
// file license.txt or http://www.opensource.org/licenses/mit-license.php.
|
||||||
|
|
||||||
|
#include "headers.h"
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
void ExitTimeout(void* parg)
|
||||||
|
{
|
||||||
|
#ifdef __WXMSW__
|
||||||
|
Sleep(5000);
|
||||||
|
ExitProcess(0);
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
void Shutdown(void* parg)
|
||||||
|
{
|
||||||
|
static CCriticalSection cs_Shutdown;
|
||||||
|
static bool fTaken;
|
||||||
|
bool fFirstThread;
|
||||||
|
CRITICAL_BLOCK(cs_Shutdown)
|
||||||
|
{
|
||||||
|
fFirstThread = !fTaken;
|
||||||
|
fTaken = true;
|
||||||
|
}
|
||||||
|
static bool fExit;
|
||||||
|
if (fFirstThread)
|
||||||
|
{
|
||||||
|
fShutdown = true;
|
||||||
|
nTransactionsUpdated++;
|
||||||
|
DBFlush(false);
|
||||||
|
StopNode();
|
||||||
|
DBFlush(true);
|
||||||
|
CreateThread(ExitTimeout, NULL);
|
||||||
|
Sleep(50);
|
||||||
|
printf("Bitcoin exiting\n\n");
|
||||||
|
fExit = true;
|
||||||
|
exit(0);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
while (!fExit)
|
||||||
|
Sleep(500);
|
||||||
|
Sleep(100);
|
||||||
|
ExitThread(0);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
//////////////////////////////////////////////////////////////////////////////
|
||||||
|
//
|
||||||
|
// Startup folder
|
||||||
|
//
|
||||||
|
|
||||||
|
#ifdef __WXMSW__
|
||||||
|
typedef WINSHELLAPI BOOL (WINAPI *PSHGETSPECIALFOLDERPATHA)(HWND hwndOwner, LPSTR lpszPath, int nFolder, BOOL fCreate);
|
||||||
|
|
||||||
|
string MyGetSpecialFolderPath(int nFolder, bool fCreate)
|
||||||
|
{
|
||||||
|
char pszPath[MAX_PATH+100] = "";
|
||||||
|
|
||||||
|
// SHGetSpecialFolderPath is not usually available on NT 4.0
|
||||||
|
HMODULE hShell32 = LoadLibraryA("shell32.dll");
|
||||||
|
if (hShell32)
|
||||||
|
{
|
||||||
|
PSHGETSPECIALFOLDERPATHA pSHGetSpecialFolderPath =
|
||||||
|
(PSHGETSPECIALFOLDERPATHA)GetProcAddress(hShell32, "SHGetSpecialFolderPathA");
|
||||||
|
if (pSHGetSpecialFolderPath)
|
||||||
|
(*pSHGetSpecialFolderPath)(NULL, pszPath, nFolder, fCreate);
|
||||||
|
FreeModule(hShell32);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Backup option
|
||||||
|
if (pszPath[0] == '\0')
|
||||||
|
{
|
||||||
|
if (nFolder == CSIDL_STARTUP)
|
||||||
|
{
|
||||||
|
strcpy(pszPath, getenv("USERPROFILE"));
|
||||||
|
strcat(pszPath, "\\Start Menu\\Programs\\Startup");
|
||||||
|
}
|
||||||
|
else if (nFolder == CSIDL_APPDATA)
|
||||||
|
{
|
||||||
|
strcpy(pszPath, getenv("APPDATA"));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return pszPath;
|
||||||
|
}
|
||||||
|
|
||||||
|
string StartupShortcutPath()
|
||||||
|
{
|
||||||
|
return MyGetSpecialFolderPath(CSIDL_STARTUP, true) + "\\Bitcoin.lnk";
|
||||||
|
}
|
||||||
|
|
||||||
|
bool GetStartOnSystemStartup()
|
||||||
|
{
|
||||||
|
return wxFileExists(StartupShortcutPath());
|
||||||
|
}
|
||||||
|
|
||||||
|
void SetStartOnSystemStartup(bool fAutoStart)
|
||||||
|
{
|
||||||
|
// If the shortcut exists already, remove it for updating
|
||||||
|
remove(StartupShortcutPath().c_str());
|
||||||
|
|
||||||
|
if (fAutoStart)
|
||||||
|
{
|
||||||
|
CoInitialize(NULL);
|
||||||
|
|
||||||
|
// Get a pointer to the IShellLink interface.
|
||||||
|
IShellLink* psl = NULL;
|
||||||
|
HRESULT hres = CoCreateInstance(CLSID_ShellLink, NULL,
|
||||||
|
CLSCTX_INPROC_SERVER, IID_IShellLink,
|
||||||
|
reinterpret_cast<void**>(&psl));
|
||||||
|
|
||||||
|
if (SUCCEEDED(hres))
|
||||||
|
{
|
||||||
|
// Get the current executable path
|
||||||
|
TCHAR pszExePath[MAX_PATH];
|
||||||
|
GetModuleFileName(NULL, pszExePath, sizeof(pszExePath));
|
||||||
|
|
||||||
|
// Set the path to the shortcut target
|
||||||
|
psl->SetPath(pszExePath);
|
||||||
|
PathRemoveFileSpec(pszExePath);
|
||||||
|
psl->SetWorkingDirectory(pszExePath);
|
||||||
|
psl->SetShowCmd(SW_SHOWMINNOACTIVE);
|
||||||
|
|
||||||
|
// Query IShellLink for the IPersistFile interface for
|
||||||
|
// saving the shortcut in persistent storage.
|
||||||
|
IPersistFile* ppf = NULL;
|
||||||
|
hres = psl->QueryInterface(IID_IPersistFile,
|
||||||
|
reinterpret_cast<void**>(&ppf));
|
||||||
|
if (SUCCEEDED(hres))
|
||||||
|
{
|
||||||
|
WCHAR pwsz[MAX_PATH];
|
||||||
|
// Ensure that the string is ANSI.
|
||||||
|
MultiByteToWideChar(CP_ACP, 0, StartupShortcutPath().c_str(), -1, pwsz, MAX_PATH);
|
||||||
|
// Save the link by calling IPersistFile::Save.
|
||||||
|
hres = ppf->Save(pwsz, TRUE);
|
||||||
|
ppf->Release();
|
||||||
|
}
|
||||||
|
psl->Release();
|
||||||
|
}
|
||||||
|
CoUninitialize();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#else
|
||||||
|
bool GetStartOnSystemStartup() { return false; }
|
||||||
|
void SetStartOnSystemStartup(bool fAutoStart) { }
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
//////////////////////////////////////////////////////////////////////////////
|
||||||
|
//
|
||||||
|
// CMyApp
|
||||||
|
//
|
||||||
|
|
||||||
|
// Define a new application
|
||||||
|
class CMyApp: public wxApp
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
wxLocale m_locale;
|
||||||
|
|
||||||
|
CMyApp(){};
|
||||||
|
~CMyApp(){};
|
||||||
|
bool OnInit();
|
||||||
|
bool OnInit2();
|
||||||
|
int OnExit();
|
||||||
|
|
||||||
|
// Hook Initialize so we can start without GUI
|
||||||
|
virtual bool Initialize(int& argc, wxChar** argv);
|
||||||
|
|
||||||
|
// 2nd-level exception handling: we get all the exceptions occurring in any
|
||||||
|
// event handler here
|
||||||
|
virtual bool OnExceptionInMainLoop();
|
||||||
|
|
||||||
|
// 3rd, and final, level exception handling: whenever an unhandled
|
||||||
|
// exception is caught, this function is called
|
||||||
|
virtual void OnUnhandledException();
|
||||||
|
|
||||||
|
// and now for something different: this function is called in case of a
|
||||||
|
// crash (e.g. dereferencing null pointer, division by 0, ...)
|
||||||
|
virtual void OnFatalException();
|
||||||
|
};
|
||||||
|
|
||||||
|
IMPLEMENT_APP(CMyApp)
|
||||||
|
|
||||||
|
bool CMyApp::Initialize(int& argc, wxChar** argv)
|
||||||
|
{
|
||||||
|
if (argc > 1 && argv[1][0] != '-' && (!fWindows || argv[1][0] != '/') &&
|
||||||
|
wxString(argv[1]) != "start")
|
||||||
|
{
|
||||||
|
fCommandLine = true;
|
||||||
|
}
|
||||||
|
else if (!fGUI)
|
||||||
|
{
|
||||||
|
fDaemon = true;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// wxApp::Initialize will remove environment-specific parameters,
|
||||||
|
// so it's too early to call ParseParameters yet
|
||||||
|
for (int i = 1; i < argc; i++)
|
||||||
|
{
|
||||||
|
wxString str = argv[i];
|
||||||
|
#ifdef __WXMSW__
|
||||||
|
if (str.size() >= 1 && str[0] == '/')
|
||||||
|
str[0] = '-';
|
||||||
|
str = str.MakeLower();
|
||||||
|
#endif
|
||||||
|
// haven't decided which argument to use for this yet
|
||||||
|
if (str == "-daemon" || str == "-d" || str == "start")
|
||||||
|
fDaemon = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (fDaemon)
|
||||||
|
fprintf(stdout, "bitcoin server starting\n");
|
||||||
|
|
||||||
|
#ifdef __WXGTK__
|
||||||
|
if (fDaemon || fCommandLine)
|
||||||
|
{
|
||||||
|
// Call the original Initialize while suppressing error messages
|
||||||
|
// and ignoring failure. If unable to initialize GTK, it fails
|
||||||
|
// near the end so hopefully the last few things don't matter.
|
||||||
|
{
|
||||||
|
wxLogNull logNo;
|
||||||
|
wxApp::Initialize(argc, argv);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (fDaemon)
|
||||||
|
{
|
||||||
|
// Daemonize
|
||||||
|
pid_t pid = fork();
|
||||||
|
if (pid < 0)
|
||||||
|
{
|
||||||
|
fprintf(stderr, "Error: fork() returned %d errno %d\n", pid, errno);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
if (pid > 0)
|
||||||
|
pthread_exit((void*)0);
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
return wxApp::Initialize(argc, argv);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool CMyApp::OnInit()
|
||||||
|
{
|
||||||
|
bool fRet = false;
|
||||||
|
try
|
||||||
|
{
|
||||||
|
fRet = OnInit2();
|
||||||
|
}
|
||||||
|
catch (std::exception& e) {
|
||||||
|
PrintException(&e, "OnInit()");
|
||||||
|
} catch (...) {
|
||||||
|
PrintException(NULL, "OnInit()");
|
||||||
|
}
|
||||||
|
if (!fRet)
|
||||||
|
Shutdown(NULL);
|
||||||
|
return fRet;
|
||||||
|
}
|
||||||
|
|
||||||
|
extern int g_isPainting;
|
||||||
|
|
||||||
|
bool CMyApp::OnInit2()
|
||||||
|
{
|
||||||
|
#ifdef _MSC_VER
|
||||||
|
// Turn off microsoft heap dump noise
|
||||||
|
_CrtSetReportMode(_CRT_WARN, _CRTDBG_MODE_FILE);
|
||||||
|
_CrtSetReportFile(_CRT_WARN, CreateFileA("NUL", GENERIC_WRITE, 0, NULL, OPEN_EXISTING, 0, 0));
|
||||||
|
#endif
|
||||||
|
#if defined(__WXMSW__) && defined(__WXDEBUG__) && wxUSE_GUI
|
||||||
|
// Disable malfunctioning wxWidgets debug assertion
|
||||||
|
g_isPainting = 10000;
|
||||||
|
#endif
|
||||||
|
#if wxUSE_GUI
|
||||||
|
wxImage::AddHandler(new wxPNGHandler);
|
||||||
|
#endif
|
||||||
|
#ifdef __WXMSW__
|
||||||
|
SetAppName("Bitcoin");
|
||||||
|
#else
|
||||||
|
SetAppName("bitcoin");
|
||||||
|
umask(077);
|
||||||
|
#endif
|
||||||
|
#ifdef __WXMSW__
|
||||||
|
#if wxUSE_UNICODE
|
||||||
|
// Hack to set wxConvLibc codepage to UTF-8 on Windows,
|
||||||
|
// may break if wxMBConv_win32 implementation in strconv.cpp changes.
|
||||||
|
class wxMBConv_win32 : public wxMBConv
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
long m_CodePage;
|
||||||
|
size_t m_minMBCharWidth;
|
||||||
|
};
|
||||||
|
if (((wxMBConv_win32*)&wxConvLibc)->m_CodePage == CP_ACP)
|
||||||
|
((wxMBConv_win32*)&wxConvLibc)->m_CodePage = CP_UTF8;
|
||||||
|
#endif
|
||||||
|
#endif
|
||||||
|
|
||||||
|
// Load locale/<lang>/LC_MESSAGES/bitcoin.mo language file
|
||||||
|
m_locale.Init(wxLANGUAGE_DEFAULT, 0);
|
||||||
|
m_locale.AddCatalogLookupPathPrefix("locale");
|
||||||
|
if (!fWindows)
|
||||||
|
{
|
||||||
|
m_locale.AddCatalogLookupPathPrefix("/usr/share/locale");
|
||||||
|
m_locale.AddCatalogLookupPathPrefix("/usr/local/share/locale");
|
||||||
|
}
|
||||||
|
m_locale.AddCatalog("wxstd"); // wxWidgets standard translations, if any
|
||||||
|
m_locale.AddCatalog("bitcoin");
|
||||||
|
|
||||||
|
//
|
||||||
|
// Parameters
|
||||||
|
//
|
||||||
|
if (fCommandLine)
|
||||||
|
{
|
||||||
|
int ret = CommandLineRPC(argc, argv);
|
||||||
|
exit(ret);
|
||||||
|
}
|
||||||
|
|
||||||
|
ParseParameters(argc, argv);
|
||||||
|
if (mapArgs.count("-?") || mapArgs.count("--help"))
|
||||||
|
{
|
||||||
|
wxString strUsage = string() +
|
||||||
|
_("Usage: bitcoin [options]") + "\t\t\t\t\t\t\n" +
|
||||||
|
_("Options:\n") +
|
||||||
|
" -gen \t\t " + _("Generate coins\n") +
|
||||||
|
" -gen=0 \t\t " + _("Don't generate coins\n") +
|
||||||
|
" -min \t\t " + _("Start minimized\n") +
|
||||||
|
" -datadir=<dir> \t " + _("Specify data directory\n") +
|
||||||
|
" -proxy=<ip:port>\t " + _("Connect through socks4 proxy\n") +
|
||||||
|
" -addnode=<ip> \t " + _("Add a node to connect to\n") +
|
||||||
|
" -connect=<ip> \t " + _("Connect only to the specified node\n") +
|
||||||
|
" -? \t\t " + _("This help message\n");
|
||||||
|
|
||||||
|
if (fWindows && fGUI)
|
||||||
|
{
|
||||||
|
// Remove spaces, the tabs make the columns line up in the message box
|
||||||
|
for (int i = 0; i < 50; i++)
|
||||||
|
strUsage.Replace(" \t", "\t");
|
||||||
|
wxMessageBox(strUsage, "Bitcoin", wxOK);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// Remove tabs
|
||||||
|
strUsage.Replace("\t", "");
|
||||||
|
fprintf(stderr, "%s", ((string)strUsage).c_str());
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (mapArgs.count("-datadir"))
|
||||||
|
strlcpy(pszSetDataDir, mapArgs["-datadir"].c_str(), sizeof(pszSetDataDir));
|
||||||
|
|
||||||
|
if (mapArgs.count("-debug"))
|
||||||
|
fDebug = true;
|
||||||
|
|
||||||
|
if (mapArgs.count("-printtodebugger"))
|
||||||
|
fPrintToDebugger = true;
|
||||||
|
|
||||||
|
if (!fDebug && !pszSetDataDir[0])
|
||||||
|
ShrinkDebugFile();
|
||||||
|
printf("\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n");
|
||||||
|
printf("Bitcoin version 0.%d.%d%s beta, OS version %s\n", VERSION/100, VERSION%100, pszSubVer, ((string)wxGetOsDescription()).c_str());
|
||||||
|
printf("System default language is %d %s\n", m_locale.GetSystemLanguage(), ((string)m_locale.GetSysName()).c_str());
|
||||||
|
printf("Language file %s (%s)\n", (string("locale/") + (string)m_locale.GetCanonicalName() + "/LC_MESSAGES/bitcoin.mo").c_str(), ((string)m_locale.GetLocale()).c_str());
|
||||||
|
|
||||||
|
if (mapArgs.count("-loadblockindextest"))
|
||||||
|
{
|
||||||
|
CTxDB txdb("r");
|
||||||
|
txdb.LoadBlockIndex();
|
||||||
|
PrintBlockTree();
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// Limit to single instance per user
|
||||||
|
// Required to protect the database files if we're going to keep deleting log.*
|
||||||
|
//
|
||||||
|
#ifdef __WXMSW__
|
||||||
|
// todo: wxSingleInstanceChecker wasn't working on Linux, never deleted its lock file
|
||||||
|
// maybe should go by whether successfully bind port 8333 instead
|
||||||
|
wxString strMutexName = wxString("bitcoin_running.") + getenv("HOMEPATH");
|
||||||
|
for (int i = 0; i < strMutexName.size(); i++)
|
||||||
|
if (!isalnum(strMutexName[i]))
|
||||||
|
strMutexName[i] = '.';
|
||||||
|
wxSingleInstanceChecker* psingleinstancechecker = new wxSingleInstanceChecker(strMutexName);
|
||||||
|
if (psingleinstancechecker->IsAnotherRunning())
|
||||||
|
{
|
||||||
|
printf("Existing instance found\n");
|
||||||
|
unsigned int nStart = GetTime();
|
||||||
|
loop
|
||||||
|
{
|
||||||
|
// TODO: find out how to do this in Linux, or replace with wxWidgets commands
|
||||||
|
// Show the previous instance and exit
|
||||||
|
HWND hwndPrev = FindWindowA("wxWindowClassNR", "Bitcoin");
|
||||||
|
if (hwndPrev)
|
||||||
|
{
|
||||||
|
if (IsIconic(hwndPrev))
|
||||||
|
ShowWindow(hwndPrev, SW_RESTORE);
|
||||||
|
SetForegroundWindow(hwndPrev);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (GetTime() > nStart + 60)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
// Resume this instance if the other exits
|
||||||
|
delete psingleinstancechecker;
|
||||||
|
Sleep(1000);
|
||||||
|
psingleinstancechecker = new wxSingleInstanceChecker(strMutexName);
|
||||||
|
if (!psingleinstancechecker->IsAnotherRunning())
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
// Bind to the port early so we can tell if another instance is already running.
|
||||||
|
// This is a backup to wxSingleInstanceChecker, which doesn't work on Linux.
|
||||||
|
string strErrors;
|
||||||
|
if (!BindListenPort(strErrors))
|
||||||
|
{
|
||||||
|
wxMessageBox(strErrors, "Bitcoin");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// Load data files
|
||||||
|
//
|
||||||
|
bool fFirstRun;
|
||||||
|
strErrors = "";
|
||||||
|
int64 nStart;
|
||||||
|
|
||||||
|
printf("Loading addresses...\n");
|
||||||
|
nStart = GetTimeMillis();
|
||||||
|
if (!LoadAddresses())
|
||||||
|
strErrors += _("Error loading addr.dat \n");
|
||||||
|
printf(" addresses %15"PRI64d"ms\n", GetTimeMillis() - nStart);
|
||||||
|
|
||||||
|
printf("Loading block index...\n");
|
||||||
|
nStart = GetTimeMillis();
|
||||||
|
if (!LoadBlockIndex())
|
||||||
|
strErrors += _("Error loading blkindex.dat \n");
|
||||||
|
printf(" block index %15"PRI64d"ms\n", GetTimeMillis() - nStart);
|
||||||
|
|
||||||
|
printf("Loading wallet...\n");
|
||||||
|
nStart = GetTimeMillis();
|
||||||
|
if (!LoadWallet(fFirstRun))
|
||||||
|
strErrors += _("Error loading wallet.dat \n");
|
||||||
|
printf(" wallet %15"PRI64d"ms\n", GetTimeMillis() - nStart);
|
||||||
|
|
||||||
|
printf("Done loading\n");
|
||||||
|
|
||||||
|
//// debug print
|
||||||
|
printf("mapBlockIndex.size() = %d\n", mapBlockIndex.size());
|
||||||
|
printf("nBestHeight = %d\n", nBestHeight);
|
||||||
|
printf("mapKeys.size() = %d\n", mapKeys.size());
|
||||||
|
printf("mapPubKeys.size() = %d\n", mapPubKeys.size());
|
||||||
|
printf("mapWallet.size() = %d\n", mapWallet.size());
|
||||||
|
printf("mapAddressBook.size() = %d\n", mapAddressBook.size());
|
||||||
|
|
||||||
|
if (!strErrors.empty())
|
||||||
|
{
|
||||||
|
wxMessageBox(strErrors, "Bitcoin");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Add wallet transactions that aren't already in a block to mapTransactions
|
||||||
|
ReacceptWalletTransactions();
|
||||||
|
|
||||||
|
//
|
||||||
|
// Parameters
|
||||||
|
//
|
||||||
|
if (mapArgs.count("-printblockindex") || mapArgs.count("-printblocktree"))
|
||||||
|
{
|
||||||
|
PrintBlockTree();
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (mapArgs.count("-printblock"))
|
||||||
|
{
|
||||||
|
string strMatch = mapArgs["-printblock"];
|
||||||
|
int nFound = 0;
|
||||||
|
for (map<uint256, CBlockIndex*>::iterator mi = mapBlockIndex.begin(); mi != mapBlockIndex.end(); ++mi)
|
||||||
|
{
|
||||||
|
uint256 hash = (*mi).first;
|
||||||
|
if (strncmp(hash.ToString().c_str(), strMatch.c_str(), strMatch.size()) == 0)
|
||||||
|
{
|
||||||
|
CBlockIndex* pindex = (*mi).second;
|
||||||
|
CBlock block;
|
||||||
|
block.ReadFromDisk(pindex);
|
||||||
|
block.BuildMerkleTree();
|
||||||
|
block.print();
|
||||||
|
printf("\n");
|
||||||
|
nFound++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (nFound == 0)
|
||||||
|
printf("No blocks matching %s were found\n", strMatch.c_str());
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (mapArgs.count("-gen"))
|
||||||
|
{
|
||||||
|
if (mapArgs["-gen"].empty())
|
||||||
|
fGenerateBitcoins = true;
|
||||||
|
else
|
||||||
|
fGenerateBitcoins = (atoi(mapArgs["-gen"].c_str()) != 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (mapArgs.count("-proxy"))
|
||||||
|
{
|
||||||
|
fUseProxy = true;
|
||||||
|
addrProxy = CAddress(mapArgs["-proxy"]);
|
||||||
|
if (!addrProxy.IsValid())
|
||||||
|
{
|
||||||
|
wxMessageBox(_("Invalid -proxy address"), "Bitcoin");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (mapArgs.count("-addnode"))
|
||||||
|
{
|
||||||
|
foreach(string strAddr, mapMultiArgs["-addnode"])
|
||||||
|
{
|
||||||
|
CAddress addr(strAddr, NODE_NETWORK);
|
||||||
|
addr.nTime = 0; // so it won't relay unless successfully connected
|
||||||
|
if (addr.IsValid())
|
||||||
|
AddAddress(addr);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// Create the main window and start the node
|
||||||
|
//
|
||||||
|
if (!fDaemon)
|
||||||
|
CreateMainWindow();
|
||||||
|
|
||||||
|
if (!CheckDiskSpace())
|
||||||
|
return false;
|
||||||
|
|
||||||
|
RandAddSeedPerfmon();
|
||||||
|
|
||||||
|
if (!CreateThread(StartNode, NULL))
|
||||||
|
wxMessageBox("Error: CreateThread(StartNode) failed", "Bitcoin");
|
||||||
|
|
||||||
|
if (mapArgs.count("-server") || fDaemon)
|
||||||
|
CreateThread(ThreadRPCServer, NULL);
|
||||||
|
|
||||||
|
if (fFirstRun)
|
||||||
|
SetStartOnSystemStartup(true);
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
int CMyApp::OnExit()
|
||||||
|
{
|
||||||
|
Shutdown(NULL);
|
||||||
|
return wxApp::OnExit();
|
||||||
|
}
|
||||||
|
|
||||||
|
bool CMyApp::OnExceptionInMainLoop()
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
throw;
|
||||||
|
}
|
||||||
|
catch (std::exception& e)
|
||||||
|
{
|
||||||
|
PrintException(&e, "CMyApp::OnExceptionInMainLoop()");
|
||||||
|
wxLogWarning("Exception %s %s", typeid(e).name(), e.what());
|
||||||
|
Sleep(1000);
|
||||||
|
throw;
|
||||||
|
}
|
||||||
|
catch (...)
|
||||||
|
{
|
||||||
|
PrintException(NULL, "CMyApp::OnExceptionInMainLoop()");
|
||||||
|
wxLogWarning("Unknown exception");
|
||||||
|
Sleep(1000);
|
||||||
|
throw;
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
void CMyApp::OnUnhandledException()
|
||||||
|
{
|
||||||
|
// this shows how we may let some exception propagate uncaught
|
||||||
|
try
|
||||||
|
{
|
||||||
|
throw;
|
||||||
|
}
|
||||||
|
catch (std::exception& e)
|
||||||
|
{
|
||||||
|
PrintException(&e, "CMyApp::OnUnhandledException()");
|
||||||
|
wxLogWarning("Exception %s %s", typeid(e).name(), e.what());
|
||||||
|
Sleep(1000);
|
||||||
|
throw;
|
||||||
|
}
|
||||||
|
catch (...)
|
||||||
|
{
|
||||||
|
PrintException(NULL, "CMyApp::OnUnhandledException()");
|
||||||
|
wxLogWarning("Unknown exception");
|
||||||
|
Sleep(1000);
|
||||||
|
throw;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void CMyApp::OnFatalException()
|
||||||
|
{
|
||||||
|
wxMessageBox(_("Program has crashed and will terminate. "), "Bitcoin", wxOK | wxICON_ERROR);
|
||||||
|
}
|
7
init.h
Normal file
7
init.h
Normal file
@ -0,0 +1,7 @@
|
|||||||
|
// Copyright (c) 2009-2010 Satoshi Nakamoto
|
||||||
|
// Distributed under the MIT/X11 software license, see the accompanying
|
||||||
|
// file license.txt or http://www.opensource.org/licenses/mit-license.php.
|
||||||
|
|
||||||
|
void Shutdown(void* parg);
|
||||||
|
bool GetStartOnSystemStartup();
|
||||||
|
void SetStartOnSystemStartup(bool fAutoStart);
|
4
main.cpp
4
main.cpp
@ -55,6 +55,8 @@ int64 nTransactionFee = 0;
|
|||||||
CAddress addrIncoming;
|
CAddress addrIncoming;
|
||||||
int fLimitProcessors = false;
|
int fLimitProcessors = false;
|
||||||
int nLimitProcessors = 1;
|
int nLimitProcessors = 1;
|
||||||
|
int fMinimizeToTray = true;
|
||||||
|
int fMinimizeOnClose = true;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
@ -2990,7 +2992,7 @@ string SendMoneyToBitcoinAddress(string strAddress, int64 nValue, CWalletTx& wtx
|
|||||||
if (nValue <= 0)
|
if (nValue <= 0)
|
||||||
return _("Invalid amount");
|
return _("Invalid amount");
|
||||||
if (nValue + nTransactionFee > GetBalance())
|
if (nValue + nTransactionFee > GetBalance())
|
||||||
return _("You don't have enough money");
|
return _("Insufficient funds");
|
||||||
|
|
||||||
// Parse bitcoin address
|
// Parse bitcoin address
|
||||||
CScript scriptPubKey;
|
CScript scriptPubKey;
|
||||||
|
2
main.h
2
main.h
@ -45,6 +45,8 @@ extern int64 nTransactionFee;
|
|||||||
extern CAddress addrIncoming;
|
extern CAddress addrIncoming;
|
||||||
extern int fLimitProcessors;
|
extern int fLimitProcessors;
|
||||||
extern int nLimitProcessors;
|
extern int nLimitProcessors;
|
||||||
|
extern int fMinimizeToTray;
|
||||||
|
extern int fMinimizeOnClose;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
@ -18,18 +18,20 @@ LIBPATHS= \
|
|||||||
-L"/openssl/out" \
|
-L"/openssl/out" \
|
||||||
-L"/wxwidgets/lib/gcc_lib"
|
-L"/wxwidgets/lib/gcc_lib"
|
||||||
|
|
||||||
|
WXLIBS= \
|
||||||
|
-l wxmsw29ud_html -l wxmsw29ud_core -l wxmsw29ud_adv -l wxbase29ud -l wxtiffd -l wxjpegd -l wxpngd -l wxzlibd
|
||||||
|
|
||||||
LIBS= \
|
LIBS= \
|
||||||
-l libboost_system-mgw34-mt-d -l libboost_filesystem-mgw34-mt-d \
|
-l libboost_system-mgw34-mt-d -l libboost_filesystem-mgw34-mt-d \
|
||||||
-l db_cxx \
|
-l db_cxx \
|
||||||
-l eay32 \
|
-l eay32 \
|
||||||
-l wxmsw29ud_html -l wxmsw29ud_core -l wxmsw29ud_adv -l wxbase29ud -l wxtiffd -l wxjpegd -l wxpngd -l wxzlibd \
|
|
||||||
-l kernel32 -l user32 -l gdi32 -l comdlg32 -l winspool -l winmm -l shell32 -l comctl32 -l ole32 -l oleaut32 -l uuid -l rpcrt4 -l advapi32 -l ws2_32 -l shlwapi
|
-l kernel32 -l user32 -l gdi32 -l comdlg32 -l winspool -l winmm -l shell32 -l comctl32 -l ole32 -l oleaut32 -l uuid -l rpcrt4 -l advapi32 -l ws2_32 -l shlwapi
|
||||||
|
|
||||||
WXDEFS=-DWIN32 -D__WXMSW__ -D_WINDOWS -DNOPCH
|
WXDEFS=-DWIN32 -D__WXMSW__ -D_WINDOWS -DNOPCH
|
||||||
DEBUGFLAGS=-g -D__WXDEBUG__
|
DEBUGFLAGS=-g -D__WXDEBUG__
|
||||||
CFLAGS=-mthreads -O0 -w -Wno-invalid-offsetof -Wformat $(DEBUGFLAGS) $(WXDEFS) $(INCLUDEPATHS)
|
CFLAGS=-mthreads -O0 -w -Wno-invalid-offsetof -Wformat $(DEBUGFLAGS) $(WXDEFS) $(INCLUDEPATHS)
|
||||||
HEADERS=headers.h strlcpy.h serialize.h uint256.h util.h key.h bignum.h base58.h script.h db.h net.h irc.h main.h rpc.h uibase.h ui.h
|
HEADERS=headers.h strlcpy.h serialize.h uint256.h util.h key.h bignum.h base58.h \
|
||||||
|
script.h db.h net.h irc.h main.h rpc.h uibase.h ui.h init.h sha.h
|
||||||
|
|
||||||
|
|
||||||
all: bitcoin.exe
|
all: bitcoin.exe
|
||||||
@ -38,49 +40,37 @@ all: bitcoin.exe
|
|||||||
headers.h.gch: headers.h $(HEADERS)
|
headers.h.gch: headers.h $(HEADERS)
|
||||||
g++ -c $(CFLAGS) -o $@ $<
|
g++ -c $(CFLAGS) -o $@ $<
|
||||||
|
|
||||||
obj/util.o: util.cpp $(HEADERS)
|
obj/%.o: %.cpp $(HEADERS) headers.h.gch
|
||||||
g++ -c $(CFLAGS) -o $@ $<
|
|
||||||
|
|
||||||
obj/script.o: script.cpp $(HEADERS)
|
|
||||||
g++ -c $(CFLAGS) -o $@ $<
|
|
||||||
|
|
||||||
obj/db.o: db.cpp $(HEADERS)
|
|
||||||
g++ -c $(CFLAGS) -o $@ $<
|
|
||||||
|
|
||||||
obj/net.o: net.cpp $(HEADERS)
|
|
||||||
g++ -c $(CFLAGS) -o $@ $<
|
|
||||||
|
|
||||||
obj/main.o: main.cpp $(HEADERS) sha.h
|
|
||||||
g++ -c $(CFLAGS) -o $@ $<
|
|
||||||
|
|
||||||
obj/ui.o: ui.cpp $(HEADERS)
|
|
||||||
g++ -c $(CFLAGS) -o $@ $<
|
|
||||||
|
|
||||||
obj/uibase.o: uibase.cpp uibase.h
|
|
||||||
g++ -c $(CFLAGS) -o $@ $<
|
g++ -c $(CFLAGS) -o $@ $<
|
||||||
|
|
||||||
obj/sha.o: sha.cpp sha.h
|
obj/sha.o: sha.cpp sha.h
|
||||||
g++ -c $(CFLAGS) -O3 -o $@ $<
|
g++ -c $(CFLAGS) -O3 -o $@ $<
|
||||||
|
|
||||||
obj/irc.o: irc.cpp $(HEADERS)
|
|
||||||
g++ -c $(CFLAGS) -o $@ $<
|
|
||||||
|
|
||||||
obj/rpc.o: rpc.cpp $(HEADERS)
|
|
||||||
g++ -c $(CFLAGS) -o $@ $<
|
|
||||||
|
|
||||||
obj/ui_res.o: ui.rc rc/bitcoin.ico rc/check.ico rc/send16.bmp rc/send16mask.bmp rc/send16masknoshadow.bmp rc/send20.bmp rc/send20mask.bmp rc/addressbook16.bmp rc/addressbook16mask.bmp rc/addressbook20.bmp rc/addressbook20mask.bmp
|
obj/ui_res.o: ui.rc rc/bitcoin.ico rc/check.ico rc/send16.bmp rc/send16mask.bmp rc/send16masknoshadow.bmp rc/send20.bmp rc/send20mask.bmp rc/addressbook16.bmp rc/addressbook16mask.bmp rc/addressbook20.bmp rc/addressbook20mask.bmp
|
||||||
windres $(WXDEFS) $(INCLUDEPATHS) -o $@ -i $<
|
windres $(WXDEFS) $(INCLUDEPATHS) -o $@ -i $<
|
||||||
|
|
||||||
|
OBJS= \
|
||||||
|
obj/util.o \
|
||||||
|
obj/script.o \
|
||||||
|
obj/db.o \
|
||||||
|
obj/net.o \
|
||||||
|
obj/irc.o \
|
||||||
|
obj/main.o \
|
||||||
|
obj/rpc.o \
|
||||||
|
obj/init.o
|
||||||
|
|
||||||
|
bitcoin.exe: $(OBJS) obj/ui.o obj/uibase.o obj/sha.o obj/ui_res.o
|
||||||
|
g++ $(CFLAGS) -mwindows -Wl,--subsystem,windows -o $@ $(LIBPATHS) $^ $(WXLIBS) $(LIBS)
|
||||||
|
|
||||||
|
|
||||||
OBJS=obj/util.o obj/script.o obj/db.o obj/net.o obj/main.o \
|
obj/nogui/%.o: %.cpp $(HEADERS)
|
||||||
obj/ui.o obj/uibase.o obj/sha.o obj/irc.o obj/rpc.o \
|
g++ -c $(CFLAGS) -DwxUSE_GUI=0 -o $@ $<
|
||||||
obj/ui_res.o
|
|
||||||
|
bitcoind.exe: $(OBJS:obj/%=obj/nogui/%) obj/sha.o obj/ui_res.o
|
||||||
|
g++ $(CFLAGS) -o $@ $(LIBPATHS) $^ -l wxbase29ud $(LIBS)
|
||||||
|
|
||||||
bitcoin.exe: headers.h.gch $(OBJS)
|
|
||||||
-kill /f bitcoin.exe
|
|
||||||
g++ $(CFLAGS) -mwindows -Wl,--subsystem,windows -o $@ $(LIBPATHS) $(OBJS) $(LIBS)
|
|
||||||
|
|
||||||
clean:
|
clean:
|
||||||
-del /Q obj\*
|
-del /Q obj\*
|
||||||
|
-del /Q obj\nogui\*
|
||||||
-del /Q headers.h.gch
|
-del /Q headers.h.gch
|
||||||
|
@ -13,20 +13,25 @@ LIBPATHS= \
|
|||||||
-L"/usr/lib" \
|
-L"/usr/lib" \
|
||||||
-L"/usr/local/lib"
|
-L"/usr/local/lib"
|
||||||
|
|
||||||
|
WXLIBS= \
|
||||||
|
-Wl,-Bstatic \
|
||||||
|
-l wx_gtk2ud-2.9 \
|
||||||
|
-Wl,-Bdynamic \
|
||||||
|
-l gtk-x11-2.0 -l SM
|
||||||
|
|
||||||
LIBS= \
|
LIBS= \
|
||||||
-Wl,-Bstatic \
|
-Wl,-Bstatic \
|
||||||
-l boost_system-mt -l boost_filesystem-mt \
|
-l boost_system-mt -l boost_filesystem-mt \
|
||||||
-l db_cxx \
|
-l db_cxx \
|
||||||
-l wx_gtk2ud-2.9 \
|
|
||||||
-Wl,-Bdynamic \
|
-Wl,-Bdynamic \
|
||||||
-l crypto \
|
-l crypto \
|
||||||
-l gtk-x11-2.0 -l gthread-2.0 -l SM
|
-l gthread-2.0
|
||||||
|
|
||||||
WXDEFS=-D__WXGTK__ -DNOPCH
|
WXDEFS=-D__WXGTK__ -DNOPCH
|
||||||
DEBUGFLAGS=-g -D__WXDEBUG__
|
DEBUGFLAGS=-g -D__WXDEBUG__
|
||||||
CFLAGS=-O0 -Wno-invalid-offsetof -Wformat $(DEBUGFLAGS) $(WXDEFS) $(INCLUDEPATHS)
|
CFLAGS=-O0 -Wno-invalid-offsetof -Wformat $(DEBUGFLAGS) $(WXDEFS) $(INCLUDEPATHS)
|
||||||
HEADERS=headers.h strlcpy.h serialize.h uint256.h util.h key.h bignum.h base58.h script.h db.h net.h irc.h main.h rpc.h uibase.h ui.h
|
HEADERS=headers.h strlcpy.h serialize.h uint256.h util.h key.h bignum.h base58.h \
|
||||||
|
script.h db.h net.h irc.h main.h rpc.h uibase.h ui.h init.h sha.h
|
||||||
|
|
||||||
|
|
||||||
all: bitcoin
|
all: bitcoin
|
||||||
@ -35,44 +40,34 @@ all: bitcoin
|
|||||||
headers.h.gch: headers.h $(HEADERS)
|
headers.h.gch: headers.h $(HEADERS)
|
||||||
g++ -c $(CFLAGS) -o $@ $<
|
g++ -c $(CFLAGS) -o $@ $<
|
||||||
|
|
||||||
obj/util.o: util.cpp $(HEADERS)
|
obj/%.o: %.cpp $(HEADERS) headers.h.gch
|
||||||
g++ -c $(CFLAGS) -o $@ $<
|
|
||||||
|
|
||||||
obj/script.o: script.cpp $(HEADERS)
|
|
||||||
g++ -c $(CFLAGS) -o $@ $<
|
|
||||||
|
|
||||||
obj/db.o: db.cpp $(HEADERS)
|
|
||||||
g++ -c $(CFLAGS) -o $@ $<
|
|
||||||
|
|
||||||
obj/net.o: net.cpp $(HEADERS)
|
|
||||||
g++ -c $(CFLAGS) -o $@ $<
|
|
||||||
|
|
||||||
obj/main.o: main.cpp $(HEADERS) sha.h
|
|
||||||
g++ -c $(CFLAGS) -o $@ $<
|
|
||||||
|
|
||||||
obj/ui.o: ui.cpp $(HEADERS)
|
|
||||||
g++ -c $(CFLAGS) -o $@ $<
|
|
||||||
|
|
||||||
obj/uibase.o: uibase.cpp uibase.h
|
|
||||||
g++ -c $(CFLAGS) -o $@ $<
|
g++ -c $(CFLAGS) -o $@ $<
|
||||||
|
|
||||||
obj/sha.o: sha.cpp sha.h
|
obj/sha.o: sha.cpp sha.h
|
||||||
g++ -c $(CFLAGS) -O3 -o $@ $<
|
g++ -c $(CFLAGS) -O3 -o $@ $<
|
||||||
|
|
||||||
obj/irc.o: irc.cpp $(HEADERS)
|
OBJS= \
|
||||||
g++ -c $(CFLAGS) -o $@ $<
|
obj/util.o \
|
||||||
|
obj/script.o \
|
||||||
|
obj/db.o \
|
||||||
|
obj/net.o \
|
||||||
|
obj/irc.o \
|
||||||
|
obj/main.o \
|
||||||
|
obj/rpc.o \
|
||||||
|
obj/init.o
|
||||||
|
|
||||||
obj/rpc.o: rpc.cpp $(HEADERS)
|
bitcoin: $(OBJS) obj/ui.o obj/uibase.o obj/sha.o
|
||||||
g++ -c $(CFLAGS) -o $@ $<
|
g++ $(CFLAGS) -o $@ $(LIBPATHS) $^ $(WXLIBS) $(LIBS)
|
||||||
|
|
||||||
|
|
||||||
|
obj/nogui/%.o: %.cpp $(HEADERS)
|
||||||
|
g++ -c $(CFLAGS) -DwxUSE_GUI=0 -o $@ $<
|
||||||
|
|
||||||
OBJS=obj/util.o obj/script.o obj/db.o obj/net.o obj/main.o \
|
bitcoind: $(OBJS:obj/%=obj/nogui/%) obj/sha.o
|
||||||
obj/ui.o obj/uibase.o obj/sha.o obj/irc.o obj/rpc.o
|
g++ $(CFLAGS) -o $@ $(LIBPATHS) $^ -l wx_baseud-2.9 $(LIBS)
|
||||||
|
|
||||||
bitcoin: headers.h.gch $(OBJS)
|
|
||||||
g++ $(CFLAGS) -o $@ $(LIBPATHS) $(OBJS) $(LIBS)
|
|
||||||
|
|
||||||
clean:
|
clean:
|
||||||
-rm obj/*
|
-rm obj/*
|
||||||
|
-rm obj/nogui/*
|
||||||
-rm headers.h.gch
|
-rm headers.h.gch
|
||||||
|
79
makefile.vc
79
makefile.vc
@ -28,56 +28,79 @@ LIBS= \
|
|||||||
WXDEFS=/DWIN32 /D__WXMSW__ /D_WINDOWS /DNOPCH
|
WXDEFS=/DWIN32 /D__WXMSW__ /D_WINDOWS /DNOPCH
|
||||||
DEBUGFLAGS=/Zi /Od /D__WXDEBUG__
|
DEBUGFLAGS=/Zi /Od /D__WXDEBUG__
|
||||||
CFLAGS=/c /nologo /Ob0 /MDd /EHsc /GR /Zm300 $(DEBUGFLAGS) $(WXDEFS) $(INCLUDEPATHS)
|
CFLAGS=/c /nologo /Ob0 /MDd /EHsc /GR /Zm300 $(DEBUGFLAGS) $(WXDEFS) $(INCLUDEPATHS)
|
||||||
HEADERS=headers.h strlcpy.h serialize.h uint256.h util.h key.h bignum.h base58.h script.h db.h net.h irc.h main.h rpc.h uibase.h ui.h
|
HEADERS=headers.h strlcpy.h serialize.h uint256.h util.h key.h bignum.h base58.h \
|
||||||
|
script.h db.h net.h irc.h main.h rpc.h uibase.h ui.h init.h sha.h
|
||||||
|
|
||||||
|
|
||||||
all: bitcoin.exe
|
all: bitcoin.exe
|
||||||
|
|
||||||
|
|
||||||
obj\util.obj: util.cpp $(HEADERS)
|
.cpp{obj}.obj:
|
||||||
cl $(CFLAGS) /Fo$@ %s
|
cl $(CFLAGS) /Fo$@ %s
|
||||||
|
|
||||||
obj\script.obj: script.cpp $(HEADERS)
|
obj\util.obj: $(HEADERS)
|
||||||
cl $(CFLAGS) /Fo$@ %s
|
|
||||||
|
|
||||||
obj\db.obj: db.cpp $(HEADERS)
|
obj\script.obj: $(HEADERS)
|
||||||
cl $(CFLAGS) /Fo$@ %s
|
|
||||||
|
|
||||||
obj\net.obj: net.cpp $(HEADERS)
|
obj\db.obj: $(HEADERS)
|
||||||
cl $(CFLAGS) /Fo$@ %s
|
|
||||||
|
|
||||||
obj\main.obj: main.cpp $(HEADERS) sha.h
|
obj\net.obj: $(HEADERS)
|
||||||
cl $(CFLAGS) /Fo$@ %s
|
|
||||||
|
|
||||||
obj\ui.obj: ui.cpp $(HEADERS)
|
obj\irc.obj: $(HEADERS)
|
||||||
cl $(CFLAGS) /Fo$@ %s
|
|
||||||
|
|
||||||
obj\uibase.obj: uibase.cpp uibase.h
|
obj\main.obj: $(HEADERS)
|
||||||
cl $(CFLAGS) /Fo$@ %s
|
|
||||||
|
obj\rpc.obj: $(HEADERS)
|
||||||
|
|
||||||
|
obj\init.obj: $(HEADERS)
|
||||||
|
|
||||||
|
obj\ui.obj: $(HEADERS)
|
||||||
|
|
||||||
|
obj\uibase.obj: $(HEADERS)
|
||||||
|
|
||||||
obj\sha.obj: sha.cpp sha.h
|
obj\sha.obj: sha.cpp sha.h
|
||||||
cl $(CFLAGS) /O2 /Fo$@ %s
|
cl $(CFLAGS) /O2 /Fo$@ %s
|
||||||
|
|
||||||
obj\irc.obj: irc.cpp $(HEADERS)
|
|
||||||
cl $(CFLAGS) /Fo$@ %s
|
|
||||||
|
|
||||||
obj\rpc.obj: rpc.cpp $(HEADERS)
|
|
||||||
cl $(CFLAGS) /Fo$@ %s
|
|
||||||
|
|
||||||
obj\ui.res: ui.rc rc/bitcoin.ico rc/check.ico rc/send16.bmp rc/send16mask.bmp rc/send16masknoshadow.bmp rc/send20.bmp rc/send20mask.bmp rc/addressbook16.bmp rc/addressbook16mask.bmp rc/addressbook20.bmp rc/addressbook20mask.bmp
|
obj\ui.res: ui.rc rc/bitcoin.ico rc/check.ico rc/send16.bmp rc/send16mask.bmp rc/send16masknoshadow.bmp rc/send20.bmp rc/send20mask.bmp rc/addressbook16.bmp rc/addressbook16mask.bmp rc/addressbook20.bmp rc/addressbook20mask.bmp
|
||||||
rc $(INCLUDEPATHS) $(WXDEFS) /Fo$@ %s
|
rc $(INCLUDEPATHS) $(WXDEFS) /Fo$@ %s
|
||||||
|
|
||||||
|
OBJS= \
|
||||||
|
obj\util.obj \
|
||||||
|
obj\script.obj \
|
||||||
|
obj\db.obj \
|
||||||
|
obj\net.obj \
|
||||||
|
obj\irc.obj \
|
||||||
|
obj\main.obj \
|
||||||
|
obj\rpc.obj \
|
||||||
|
obj\init.obj
|
||||||
|
|
||||||
|
bitcoin.exe: $(OBJS) obj\ui.obj obj\uibase.obj obj\sha.obj obj\ui.res
|
||||||
OBJS=obj\util.obj obj\script.obj obj\db.obj obj\net.obj obj\main.obj \
|
|
||||||
obj\ui.obj obj\uibase.obj obj\sha.obj obj\irc.obj obj\rpc.obj \
|
|
||||||
obj\ui.res
|
|
||||||
|
|
||||||
bitcoin.exe: $(OBJS)
|
|
||||||
-kill /f bitcoin.exe & sleep 1
|
|
||||||
link /nologo /DEBUG /SUBSYSTEM:WINDOWS /OUT:$@ $(LIBPATHS) $** $(LIBS)
|
link /nologo /DEBUG /SUBSYSTEM:WINDOWS /OUT:$@ $(LIBPATHS) $** $(LIBS)
|
||||||
|
|
||||||
|
|
||||||
|
.cpp{obj\nogui}.obj:
|
||||||
|
cl $(CFLAGS) /DwxUSE_GUI=0 /Fo$@ %s
|
||||||
|
|
||||||
|
obj\nogui\util.obj: $(HEADERS)
|
||||||
|
|
||||||
|
obj\nogui\script.obj: $(HEADERS)
|
||||||
|
|
||||||
|
obj\nogui\db.obj: $(HEADERS)
|
||||||
|
|
||||||
|
obj\nogui\net.obj: $(HEADERS)
|
||||||
|
|
||||||
|
obj\nogui\irc.obj: $(HEADERS)
|
||||||
|
|
||||||
|
obj\nogui\main.obj: $(HEADERS)
|
||||||
|
|
||||||
|
obj\nogui\rpc.obj: $(HEADERS)
|
||||||
|
|
||||||
|
obj\nogui\init.obj: $(HEADERS)
|
||||||
|
|
||||||
|
bitcoind.exe: $(OBJS:obj\=obj\nogui\) obj\sha.obj obj\ui.res
|
||||||
|
link /nologo /DEBUG /OUT:$@ $(LIBPATHS) $** $(LIBS)
|
||||||
|
|
||||||
|
|
||||||
clean:
|
clean:
|
||||||
-del /Q obj\*
|
-del /Q obj\*
|
||||||
-del *.ilk
|
-del *.ilk
|
||||||
|
10
rpc.cpp
10
rpc.cpp
@ -676,18 +676,18 @@ int CommandLineRPC(int argc, char *argv[])
|
|||||||
string strResult = (result.type() == str_type ? result.get_str() : write_string(result, true));
|
string strResult = (result.type() == str_type ? result.get_str() : write_string(result, true));
|
||||||
if (result.type() != null_type)
|
if (result.type() != null_type)
|
||||||
{
|
{
|
||||||
if (fWindows)
|
if (fWindows && fGUI)
|
||||||
// Windows GUI apps can't print to command line,
|
// Windows GUI apps can't print to command line,
|
||||||
// so for now settle for a message box yuck
|
// so settle for a message box yuck
|
||||||
wxMessageBox(strResult.c_str(), "Bitcoin", wxOK);
|
MyMessageBox(strResult.c_str(), "Bitcoin", wxOK);
|
||||||
else
|
else
|
||||||
fprintf(stdout, "%s\n", strResult.c_str());
|
fprintf(stdout, "%s\n", strResult.c_str());
|
||||||
}
|
}
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
catch (std::exception& e) {
|
catch (std::exception& e) {
|
||||||
if (fWindows)
|
if (fWindows && fGUI)
|
||||||
wxMessageBox(strprintf("error: %s\n", e.what()).c_str(), "Bitcoin", wxOK);
|
MyMessageBox(strprintf("error: %s\n", e.what()).c_str(), "Bitcoin", wxOK);
|
||||||
else
|
else
|
||||||
fprintf(stderr, "error: %s\n", e.what());
|
fprintf(stderr, "error: %s\n", e.what());
|
||||||
} catch (...) {
|
} catch (...) {
|
||||||
|
@ -19,7 +19,7 @@ class CScript;
|
|||||||
class CDataStream;
|
class CDataStream;
|
||||||
class CAutoFile;
|
class CAutoFile;
|
||||||
|
|
||||||
static const int VERSION = 206;
|
static const int VERSION = 207;
|
||||||
static const char* pszSubVer = ".0";
|
static const char* pszSubVer = ".0";
|
||||||
|
|
||||||
|
|
||||||
|
655
ui.cpp
655
ui.cpp
@ -7,38 +7,18 @@
|
|||||||
#include <crtdbg.h>
|
#include <crtdbg.h>
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
bool GetStartOnSystemStartup();
|
|
||||||
void SetStartOnSystemStartup(bool fAutoStart);
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
DEFINE_EVENT_TYPE(wxEVT_UITHREADCALL)
|
DEFINE_EVENT_TYPE(wxEVT_UITHREADCALL)
|
||||||
|
|
||||||
CMainFrame* pframeMain = NULL;
|
CMainFrame* pframeMain = NULL;
|
||||||
CMyTaskBarIcon* ptaskbaricon = NULL;
|
CMyTaskBarIcon* ptaskbaricon = NULL;
|
||||||
extern int g_isPainting;
|
|
||||||
bool fClosedToTray = false;
|
bool fClosedToTray = false;
|
||||||
|
|
||||||
// Settings
|
|
||||||
int fMinimizeToTray = true;
|
|
||||||
int fMinimizeOnClose = true;
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
int MyMessageBox(const wxString& message, const wxString& caption="Message", int style=wxOK, wxWindow* parent=NULL, int x=-1, int y=-1)
|
|
||||||
{
|
|
||||||
if (fDaemon)
|
|
||||||
{
|
|
||||||
printf("wxMessageBox %s: %s\n", string(caption).c_str(), string(message).c_str());
|
|
||||||
fprintf(stderr, "%s: %s\n", string(caption).c_str(), string(message).c_str());
|
|
||||||
return wxOK;
|
|
||||||
}
|
|
||||||
return wxMessageBox(message, caption, style, parent, x, y);
|
|
||||||
}
|
|
||||||
#define wxMessageBox MyMessageBox
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
@ -48,47 +28,6 @@ int MyMessageBox(const wxString& message, const wxString& caption="Message", int
|
|||||||
// Util
|
// Util
|
||||||
//
|
//
|
||||||
|
|
||||||
void ExitTimeout(void* parg)
|
|
||||||
{
|
|
||||||
#ifdef __WXMSW__
|
|
||||||
Sleep(5000);
|
|
||||||
ExitProcess(0);
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
|
|
||||||
void Shutdown(void* parg)
|
|
||||||
{
|
|
||||||
static CCriticalSection cs_Shutdown;
|
|
||||||
static bool fTaken;
|
|
||||||
bool fFirstThread;
|
|
||||||
CRITICAL_BLOCK(cs_Shutdown)
|
|
||||||
{
|
|
||||||
fFirstThread = !fTaken;
|
|
||||||
fTaken = true;
|
|
||||||
}
|
|
||||||
static bool fExit;
|
|
||||||
if (fFirstThread)
|
|
||||||
{
|
|
||||||
fShutdown = true;
|
|
||||||
nTransactionsUpdated++;
|
|
||||||
DBFlush(false);
|
|
||||||
StopNode();
|
|
||||||
DBFlush(true);
|
|
||||||
CreateThread(ExitTimeout, NULL);
|
|
||||||
Sleep(50);
|
|
||||||
printf("Bitcoin exiting\n\n");
|
|
||||||
fExit = true;
|
|
||||||
exit(0);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
while (!fExit)
|
|
||||||
Sleep(500);
|
|
||||||
Sleep(100);
|
|
||||||
ExitThread(0);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void HandleCtrlA(wxKeyEvent& event)
|
void HandleCtrlA(wxKeyEvent& event)
|
||||||
{
|
{
|
||||||
// Ctrl-a select all
|
// Ctrl-a select all
|
||||||
@ -312,7 +251,7 @@ CMainFrame::CMainFrame(wxWindow* parent) : CMainFrameBase(parent)
|
|||||||
m_staticTextBalance->SetSize(140, 17);
|
m_staticTextBalance->SetSize(140, 17);
|
||||||
// resize to fit ubuntu's huge default font
|
// resize to fit ubuntu's huge default font
|
||||||
dResize = 1.22;
|
dResize = 1.22;
|
||||||
SetSize(dResize * GetSize().GetWidth(), 1.09 * GetSize().GetHeight());
|
SetSize(dResize * GetSize().GetWidth(), 1.15 * GetSize().GetHeight());
|
||||||
#endif
|
#endif
|
||||||
m_staticTextBalance->SetLabel(FormatMoney(GetBalance()) + " ");
|
m_staticTextBalance->SetLabel(FormatMoney(GetBalance()) + " ");
|
||||||
m_listCtrl->SetFocus();
|
m_listCtrl->SetFocus();
|
||||||
@ -1630,7 +1569,6 @@ void COptionsDialog::OnButtonApply(wxCommandEvent& event)
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
//////////////////////////////////////////////////////////////////////////////
|
//////////////////////////////////////////////////////////////////////////////
|
||||||
//
|
//
|
||||||
// CAboutDialog
|
// CAboutDialog
|
||||||
@ -2014,7 +1952,7 @@ void CSendingDialog::StartTransfer()
|
|||||||
// Make sure we have enough money
|
// Make sure we have enough money
|
||||||
if (nPrice + nTransactionFee > GetBalance())
|
if (nPrice + nTransactionFee > GetBalance())
|
||||||
{
|
{
|
||||||
Error(_("You don't have enough money"));
|
Error(_("Insufficient funds"));
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -2081,7 +2019,7 @@ void CSendingDialog::OnReply2(CDataStream& vRecv)
|
|||||||
return;
|
return;
|
||||||
if (nPrice + nTransactionFee > GetBalance())
|
if (nPrice + nTransactionFee > GetBalance())
|
||||||
{
|
{
|
||||||
Error(_("You don't have enough money"));
|
Error(_("Insufficient funds"));
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
CKey key;
|
CKey key;
|
||||||
@ -2562,386 +2500,11 @@ wxMenu* CMyTaskBarIcon::CreatePopupMenu()
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
//////////////////////////////////////////////////////////////////////////////
|
|
||||||
//
|
|
||||||
// CMyApp
|
|
||||||
//
|
|
||||||
|
|
||||||
// Define a new application
|
|
||||||
class CMyApp: public wxApp
|
|
||||||
|
void CreateMainWindow()
|
||||||
{
|
{
|
||||||
public:
|
|
||||||
wxLocale m_locale;
|
|
||||||
|
|
||||||
CMyApp(){};
|
|
||||||
~CMyApp(){};
|
|
||||||
bool OnInit();
|
|
||||||
bool OnInit2();
|
|
||||||
int OnExit();
|
|
||||||
|
|
||||||
// Hook Initialize so we can start without GUI
|
|
||||||
virtual bool Initialize(int& argc, wxChar** argv);
|
|
||||||
|
|
||||||
// 2nd-level exception handling: we get all the exceptions occurring in any
|
|
||||||
// event handler here
|
|
||||||
virtual bool OnExceptionInMainLoop();
|
|
||||||
|
|
||||||
// 3rd, and final, level exception handling: whenever an unhandled
|
|
||||||
// exception is caught, this function is called
|
|
||||||
virtual void OnUnhandledException();
|
|
||||||
|
|
||||||
// and now for something different: this function is called in case of a
|
|
||||||
// crash (e.g. dereferencing null pointer, division by 0, ...)
|
|
||||||
virtual void OnFatalException();
|
|
||||||
};
|
|
||||||
|
|
||||||
IMPLEMENT_APP(CMyApp)
|
|
||||||
|
|
||||||
bool CMyApp::Initialize(int& argc, wxChar** argv)
|
|
||||||
{
|
|
||||||
if (argc > 1 && argv[1][0] != '-' && (!fWindows || argv[1][0] != '/') &&
|
|
||||||
wxString(argv[1]) != "start")
|
|
||||||
{
|
|
||||||
fCommandLine = true;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
// wxApp::Initialize will remove environment-specific parameters,
|
|
||||||
// so it's too early to call ParseParameters yet
|
|
||||||
for (int i = 1; i < argc; i++)
|
|
||||||
{
|
|
||||||
wxString str = argv[i];
|
|
||||||
#ifdef __WXMSW__
|
|
||||||
if (str.size() >= 1 && str[0] == '/')
|
|
||||||
str[0] = '-';
|
|
||||||
str = str.MakeLower();
|
|
||||||
#endif
|
|
||||||
// haven't decided which argument to use for this yet
|
|
||||||
if (str == "-daemon" || str == "-d" || str == "start")
|
|
||||||
fDaemon = true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#ifdef __WXGTK__
|
|
||||||
if (fDaemon || fCommandLine)
|
|
||||||
{
|
|
||||||
// Call the original Initialize while suppressing error messages
|
|
||||||
// and ignoring failure. If unable to initialize GTK, it fails
|
|
||||||
// near the end so hopefully the last few things don't matter.
|
|
||||||
{
|
|
||||||
wxLogNull logNo;
|
|
||||||
wxApp::Initialize(argc, argv);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (fDaemon)
|
|
||||||
{
|
|
||||||
fprintf(stdout, "bitcoin server starting\n");
|
|
||||||
|
|
||||||
// Daemonize
|
|
||||||
pid_t pid = fork();
|
|
||||||
if (pid < 0)
|
|
||||||
{
|
|
||||||
fprintf(stderr, "Error: fork() returned %d errno %d\n", pid, errno);
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
if (pid > 0)
|
|
||||||
pthread_exit((void*)0);
|
|
||||||
}
|
|
||||||
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
return wxApp::Initialize(argc, argv);
|
|
||||||
}
|
|
||||||
|
|
||||||
bool CMyApp::OnInit()
|
|
||||||
{
|
|
||||||
bool fRet = false;
|
|
||||||
try
|
|
||||||
{
|
|
||||||
fRet = OnInit2();
|
|
||||||
}
|
|
||||||
catch (std::exception& e) {
|
|
||||||
PrintException(&e, "OnInit()");
|
|
||||||
} catch (...) {
|
|
||||||
PrintException(NULL, "OnInit()");
|
|
||||||
}
|
|
||||||
if (!fRet)
|
|
||||||
Shutdown(NULL);
|
|
||||||
return fRet;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool CMyApp::OnInit2()
|
|
||||||
{
|
|
||||||
#ifdef _MSC_VER
|
|
||||||
// Turn off microsoft heap dump noise
|
|
||||||
_CrtSetReportMode(_CRT_WARN, _CRTDBG_MODE_FILE);
|
|
||||||
_CrtSetReportFile(_CRT_WARN, CreateFileA("NUL", GENERIC_WRITE, 0, NULL, OPEN_EXISTING, 0, 0));
|
|
||||||
#endif
|
|
||||||
#if defined(__WXMSW__) && defined(__WXDEBUG__)
|
|
||||||
// Disable malfunctioning wxWidgets debug assertion
|
|
||||||
g_isPainting = 10000;
|
|
||||||
#endif
|
|
||||||
wxImage::AddHandler(new wxPNGHandler);
|
|
||||||
#ifdef __WXMSW__
|
|
||||||
SetAppName("Bitcoin");
|
|
||||||
#else
|
|
||||||
SetAppName("bitcoin");
|
|
||||||
umask(077);
|
|
||||||
#endif
|
|
||||||
#ifdef __WXMSW__
|
|
||||||
#if wxUSE_UNICODE
|
|
||||||
// Hack to set wxConvLibc codepage to UTF-8 on Windows,
|
|
||||||
// may break if wxMBConv_win32 implementation in strconv.cpp changes.
|
|
||||||
class wxMBConv_win32 : public wxMBConv
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
long m_CodePage;
|
|
||||||
size_t m_minMBCharWidth;
|
|
||||||
};
|
|
||||||
if (((wxMBConv_win32*)&wxConvLibc)->m_CodePage == CP_ACP)
|
|
||||||
((wxMBConv_win32*)&wxConvLibc)->m_CodePage = CP_UTF8;
|
|
||||||
#endif
|
|
||||||
#endif
|
|
||||||
|
|
||||||
// Load locale/<lang>/LC_MESSAGES/bitcoin.mo language file
|
|
||||||
m_locale.Init(wxLANGUAGE_DEFAULT, 0);
|
|
||||||
m_locale.AddCatalogLookupPathPrefix("locale");
|
|
||||||
if (!fWindows)
|
|
||||||
{
|
|
||||||
m_locale.AddCatalogLookupPathPrefix("/usr/share/locale");
|
|
||||||
m_locale.AddCatalogLookupPathPrefix("/usr/local/share/locale");
|
|
||||||
}
|
|
||||||
m_locale.AddCatalog("wxstd"); // wxWidgets standard translations, if any
|
|
||||||
m_locale.AddCatalog("bitcoin");
|
|
||||||
|
|
||||||
//
|
|
||||||
// Parameters
|
|
||||||
//
|
|
||||||
if (fCommandLine)
|
|
||||||
{
|
|
||||||
int ret = CommandLineRPC(argc, argv);
|
|
||||||
exit(ret);
|
|
||||||
}
|
|
||||||
|
|
||||||
ParseParameters(argc, argv);
|
|
||||||
if (mapArgs.count("-?") || mapArgs.count("--help"))
|
|
||||||
{
|
|
||||||
wxString strUsage = string() +
|
|
||||||
_("Usage: bitcoin [options]") + "\t\t\t\t\t\t\n" +
|
|
||||||
_("Options:\n") +
|
|
||||||
" -gen \t\t " + _("Generate coins\n") +
|
|
||||||
" -gen=0 \t\t " + _("Don't generate coins\n") +
|
|
||||||
" -min \t\t " + _("Start minimized\n") +
|
|
||||||
" -datadir=<dir> \t " + _("Specify data directory\n") +
|
|
||||||
" -proxy=<ip:port>\t " + _("Connect through socks4 proxy\n") +
|
|
||||||
" -addnode=<ip> \t " + _("Add a node to connect to\n") +
|
|
||||||
" -connect=<ip> \t " + _("Connect only to the specified node\n") +
|
|
||||||
" -? \t\t " + _("This help message\n");
|
|
||||||
|
|
||||||
if (fWindows)
|
|
||||||
{
|
|
||||||
// Remove spaces, the tabs make the columns line up in the message box
|
|
||||||
for (int i = 0; i < 50; i++)
|
|
||||||
strUsage.Replace(" \t", "\t");
|
|
||||||
wxMessageBox(strUsage, "Bitcoin", wxOK);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
// Remove tabs
|
|
||||||
strUsage.Replace("\t", "");
|
|
||||||
fprintf(stderr, "%s", ((string)strUsage).c_str());
|
|
||||||
}
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (mapArgs.count("-datadir"))
|
|
||||||
strlcpy(pszSetDataDir, mapArgs["-datadir"].c_str(), sizeof(pszSetDataDir));
|
|
||||||
|
|
||||||
if (mapArgs.count("-debug"))
|
|
||||||
fDebug = true;
|
|
||||||
|
|
||||||
if (mapArgs.count("-printtodebugger"))
|
|
||||||
fPrintToDebugger = true;
|
|
||||||
|
|
||||||
if (!fDebug && !pszSetDataDir[0])
|
|
||||||
ShrinkDebugFile();
|
|
||||||
printf("\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n");
|
|
||||||
printf("Bitcoin version 0.%d.%d%s beta, OS version %s\n", VERSION/100, VERSION%100, pszSubVer, ((string)wxGetOsDescription()).c_str());
|
|
||||||
printf("System default language is %d %s\n", m_locale.GetSystemLanguage(), ((string)m_locale.GetSysName()).c_str());
|
|
||||||
printf("Language file %s (%s)\n", (string("locale/") + (string)m_locale.GetCanonicalName() + "/LC_MESSAGES/bitcoin.mo").c_str(), ((string)m_locale.GetLocale()).c_str());
|
|
||||||
|
|
||||||
if (mapArgs.count("-loadblockindextest"))
|
|
||||||
{
|
|
||||||
CTxDB txdb("r");
|
|
||||||
txdb.LoadBlockIndex();
|
|
||||||
PrintBlockTree();
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
//
|
|
||||||
// Limit to single instance per user
|
|
||||||
// Required to protect the database files if we're going to keep deleting log.*
|
|
||||||
//
|
|
||||||
#ifdef __WXMSW__
|
|
||||||
// todo: wxSingleInstanceChecker wasn't working on Linux, never deleted its lock file
|
|
||||||
// maybe should go by whether successfully bind port 8333 instead
|
|
||||||
wxString strMutexName = wxString("bitcoin_running.") + getenv("HOMEPATH");
|
|
||||||
for (int i = 0; i < strMutexName.size(); i++)
|
|
||||||
if (!isalnum(strMutexName[i]))
|
|
||||||
strMutexName[i] = '.';
|
|
||||||
wxSingleInstanceChecker* psingleinstancechecker = new wxSingleInstanceChecker(strMutexName);
|
|
||||||
if (psingleinstancechecker->IsAnotherRunning())
|
|
||||||
{
|
|
||||||
printf("Existing instance found\n");
|
|
||||||
unsigned int nStart = GetTime();
|
|
||||||
loop
|
|
||||||
{
|
|
||||||
// TODO: find out how to do this in Linux, or replace with wxWidgets commands
|
|
||||||
// Show the previous instance and exit
|
|
||||||
HWND hwndPrev = FindWindowA("wxWindowClassNR", "Bitcoin");
|
|
||||||
if (hwndPrev)
|
|
||||||
{
|
|
||||||
if (IsIconic(hwndPrev))
|
|
||||||
ShowWindow(hwndPrev, SW_RESTORE);
|
|
||||||
SetForegroundWindow(hwndPrev);
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (GetTime() > nStart + 60)
|
|
||||||
return false;
|
|
||||||
|
|
||||||
// Resume this instance if the other exits
|
|
||||||
delete psingleinstancechecker;
|
|
||||||
Sleep(1000);
|
|
||||||
psingleinstancechecker = new wxSingleInstanceChecker(strMutexName);
|
|
||||||
if (!psingleinstancechecker->IsAnotherRunning())
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
// Bind to the port early so we can tell if another instance is already running.
|
|
||||||
// This is a backup to wxSingleInstanceChecker, which doesn't work on Linux.
|
|
||||||
string strErrors;
|
|
||||||
if (!BindListenPort(strErrors))
|
|
||||||
{
|
|
||||||
wxMessageBox(strErrors, "Bitcoin");
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
//
|
|
||||||
// Load data files
|
|
||||||
//
|
|
||||||
bool fFirstRun;
|
|
||||||
strErrors = "";
|
|
||||||
int64 nStart;
|
|
||||||
|
|
||||||
printf("Loading addresses...\n");
|
|
||||||
nStart = GetTimeMillis();
|
|
||||||
if (!LoadAddresses())
|
|
||||||
strErrors += _("Error loading addr.dat \n");
|
|
||||||
printf(" addresses %15"PRI64d"ms\n", GetTimeMillis() - nStart);
|
|
||||||
|
|
||||||
printf("Loading block index...\n");
|
|
||||||
nStart = GetTimeMillis();
|
|
||||||
if (!LoadBlockIndex())
|
|
||||||
strErrors += _("Error loading blkindex.dat \n");
|
|
||||||
printf(" block index %15"PRI64d"ms\n", GetTimeMillis() - nStart);
|
|
||||||
|
|
||||||
printf("Loading wallet...\n");
|
|
||||||
nStart = GetTimeMillis();
|
|
||||||
if (!LoadWallet(fFirstRun))
|
|
||||||
strErrors += _("Error loading wallet.dat \n");
|
|
||||||
printf(" wallet %15"PRI64d"ms\n", GetTimeMillis() - nStart);
|
|
||||||
|
|
||||||
printf("Done loading\n");
|
|
||||||
|
|
||||||
//// debug print
|
|
||||||
printf("mapBlockIndex.size() = %d\n", mapBlockIndex.size());
|
|
||||||
printf("nBestHeight = %d\n", nBestHeight);
|
|
||||||
printf("mapKeys.size() = %d\n", mapKeys.size());
|
|
||||||
printf("mapPubKeys.size() = %d\n", mapPubKeys.size());
|
|
||||||
printf("mapWallet.size() = %d\n", mapWallet.size());
|
|
||||||
printf("mapAddressBook.size() = %d\n", mapAddressBook.size());
|
|
||||||
|
|
||||||
if (!strErrors.empty())
|
|
||||||
{
|
|
||||||
wxMessageBox(strErrors, "Bitcoin");
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Add wallet transactions that aren't already in a block to mapTransactions
|
|
||||||
ReacceptWalletTransactions();
|
|
||||||
|
|
||||||
//
|
|
||||||
// Parameters
|
|
||||||
//
|
|
||||||
if (mapArgs.count("-printblockindex") || mapArgs.count("-printblocktree"))
|
|
||||||
{
|
|
||||||
PrintBlockTree();
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (mapArgs.count("-printblock"))
|
|
||||||
{
|
|
||||||
string strMatch = mapArgs["-printblock"];
|
|
||||||
int nFound = 0;
|
|
||||||
for (map<uint256, CBlockIndex*>::iterator mi = mapBlockIndex.begin(); mi != mapBlockIndex.end(); ++mi)
|
|
||||||
{
|
|
||||||
uint256 hash = (*mi).first;
|
|
||||||
if (strncmp(hash.ToString().c_str(), strMatch.c_str(), strMatch.size()) == 0)
|
|
||||||
{
|
|
||||||
CBlockIndex* pindex = (*mi).second;
|
|
||||||
CBlock block;
|
|
||||||
block.ReadFromDisk(pindex);
|
|
||||||
block.BuildMerkleTree();
|
|
||||||
block.print();
|
|
||||||
printf("\n");
|
|
||||||
nFound++;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (nFound == 0)
|
|
||||||
printf("No blocks matching %s were found\n", strMatch.c_str());
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (mapArgs.count("-gen"))
|
|
||||||
{
|
|
||||||
if (mapArgs["-gen"].empty())
|
|
||||||
fGenerateBitcoins = true;
|
|
||||||
else
|
|
||||||
fGenerateBitcoins = (atoi(mapArgs["-gen"].c_str()) != 0);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (mapArgs.count("-proxy"))
|
|
||||||
{
|
|
||||||
fUseProxy = true;
|
|
||||||
addrProxy = CAddress(mapArgs["-proxy"]);
|
|
||||||
if (!addrProxy.IsValid())
|
|
||||||
{
|
|
||||||
wxMessageBox(_("Invalid -proxy address"), "Bitcoin");
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (mapArgs.count("-addnode"))
|
|
||||||
{
|
|
||||||
foreach(string strAddr, mapMultiArgs["-addnode"])
|
|
||||||
{
|
|
||||||
CAddress addr(strAddr, NODE_NETWORK);
|
|
||||||
addr.nTime = 0; // so it won't relay unless successfully connected
|
|
||||||
if (addr.IsValid())
|
|
||||||
AddAddress(addr);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
//
|
|
||||||
// Create the main frame window
|
|
||||||
//
|
|
||||||
if (!fDaemon)
|
|
||||||
{
|
|
||||||
pframeMain = new CMainFrame(NULL);
|
pframeMain = new CMainFrame(NULL);
|
||||||
if (mapArgs.count("-min"))
|
if (mapArgs.count("-min"))
|
||||||
pframeMain->Iconize(true);
|
pframeMain->Iconize(true);
|
||||||
@ -2950,219 +2513,13 @@ bool CMyApp::OnInit2()
|
|||||||
fClosedToTray = true;
|
fClosedToTray = true;
|
||||||
pframeMain->Show(!fClosedToTray);
|
pframeMain->Show(!fClosedToTray);
|
||||||
ptaskbaricon->Show(fMinimizeToTray || fClosedToTray);
|
ptaskbaricon->Show(fMinimizeToTray || fClosedToTray);
|
||||||
|
|
||||||
CreateThread(ThreadDelayedRepaint, NULL);
|
CreateThread(ThreadDelayedRepaint, NULL);
|
||||||
}
|
|
||||||
|
|
||||||
if (!CheckDiskSpace())
|
|
||||||
return false;
|
|
||||||
|
|
||||||
RandAddSeedPerfmon();
|
|
||||||
|
|
||||||
if (!CreateThread(StartNode, NULL))
|
|
||||||
wxMessageBox("Error: CreateThread(StartNode) failed", "Bitcoin");
|
|
||||||
|
|
||||||
if (mapArgs.count("-server") || fDaemon)
|
|
||||||
CreateThread(ThreadRPCServer, NULL);
|
|
||||||
|
|
||||||
if (fFirstRun)
|
|
||||||
SetStartOnSystemStartup(true);
|
|
||||||
|
|
||||||
|
|
||||||
//
|
|
||||||
// Tests
|
|
||||||
//
|
|
||||||
#ifdef __WXMSW__
|
|
||||||
if (argc >= 2 && stricmp(argv[1], "-send") == 0)
|
|
||||||
#else
|
|
||||||
if (argc >= 2 && strcmp(argv[1], "-send") == 0)
|
|
||||||
#endif
|
|
||||||
{
|
|
||||||
int64 nValue = 1;
|
|
||||||
if (argc >= 3)
|
|
||||||
ParseMoney(argv[2], nValue);
|
|
||||||
|
|
||||||
string strAddress;
|
|
||||||
if (argc >= 4)
|
|
||||||
strAddress = argv[3];
|
|
||||||
CAddress addr(strAddress);
|
|
||||||
|
|
||||||
CWalletTx wtx;
|
|
||||||
wtx.mapValue["to"] = strAddress;
|
|
||||||
wtx.mapValue["from"] = addrLocalHost.ToString();
|
|
||||||
wtx.mapValue["message"] = "command line send";
|
|
||||||
|
|
||||||
// Send to IP address
|
|
||||||
CSendingDialog* pdialog = new CSendingDialog(pframeMain, addr, nValue, wtx);
|
|
||||||
if (!pdialog->ShowModal())
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
int CMyApp::OnExit()
|
|
||||||
{
|
|
||||||
Shutdown(NULL);
|
|
||||||
return wxApp::OnExit();
|
|
||||||
}
|
|
||||||
|
|
||||||
bool CMyApp::OnExceptionInMainLoop()
|
|
||||||
{
|
|
||||||
try
|
|
||||||
{
|
|
||||||
throw;
|
|
||||||
}
|
|
||||||
catch (std::exception& e)
|
|
||||||
{
|
|
||||||
PrintException(&e, "CMyApp::OnExceptionInMainLoop()");
|
|
||||||
wxLogWarning("Exception %s %s", typeid(e).name(), e.what());
|
|
||||||
Sleep(1000);
|
|
||||||
throw;
|
|
||||||
}
|
|
||||||
catch (...)
|
|
||||||
{
|
|
||||||
PrintException(NULL, "CMyApp::OnExceptionInMainLoop()");
|
|
||||||
wxLogWarning("Unknown exception");
|
|
||||||
Sleep(1000);
|
|
||||||
throw;
|
|
||||||
}
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
void CMyApp::OnUnhandledException()
|
|
||||||
{
|
|
||||||
// this shows how we may let some exception propagate uncaught
|
|
||||||
try
|
|
||||||
{
|
|
||||||
throw;
|
|
||||||
}
|
|
||||||
catch (std::exception& e)
|
|
||||||
{
|
|
||||||
PrintException(&e, "CMyApp::OnUnhandledException()");
|
|
||||||
wxLogWarning("Exception %s %s", typeid(e).name(), e.what());
|
|
||||||
Sleep(1000);
|
|
||||||
throw;
|
|
||||||
}
|
|
||||||
catch (...)
|
|
||||||
{
|
|
||||||
PrintException(NULL, "CMyApp::OnUnhandledException()");
|
|
||||||
wxLogWarning("Unknown exception");
|
|
||||||
Sleep(1000);
|
|
||||||
throw;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void CMyApp::OnFatalException()
|
|
||||||
{
|
|
||||||
wxMessageBox(_("Program has crashed and will terminate. "), "Bitcoin", wxOK | wxICON_ERROR);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
#ifdef __WXMSW__
|
|
||||||
typedef WINSHELLAPI BOOL (WINAPI *PSHGETSPECIALFOLDERPATHA)(HWND hwndOwner, LPSTR lpszPath, int nFolder, BOOL fCreate);
|
|
||||||
|
|
||||||
string MyGetSpecialFolderPath(int nFolder, bool fCreate)
|
|
||||||
{
|
|
||||||
char pszPath[MAX_PATH+100] = "";
|
|
||||||
|
|
||||||
// SHGetSpecialFolderPath is not usually available on NT 4.0
|
|
||||||
HMODULE hShell32 = LoadLibraryA("shell32.dll");
|
|
||||||
if (hShell32)
|
|
||||||
{
|
|
||||||
PSHGETSPECIALFOLDERPATHA pSHGetSpecialFolderPath =
|
|
||||||
(PSHGETSPECIALFOLDERPATHA)GetProcAddress(hShell32, "SHGetSpecialFolderPathA");
|
|
||||||
if (pSHGetSpecialFolderPath)
|
|
||||||
(*pSHGetSpecialFolderPath)(NULL, pszPath, nFolder, fCreate);
|
|
||||||
FreeModule(hShell32);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Backup option
|
|
||||||
if (pszPath[0] == '\0')
|
|
||||||
{
|
|
||||||
if (nFolder == CSIDL_STARTUP)
|
|
||||||
{
|
|
||||||
strcpy(pszPath, getenv("USERPROFILE"));
|
|
||||||
strcat(pszPath, "\\Start Menu\\Programs\\Startup");
|
|
||||||
}
|
|
||||||
else if (nFolder == CSIDL_APPDATA)
|
|
||||||
{
|
|
||||||
strcpy(pszPath, getenv("APPDATA"));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return pszPath;
|
|
||||||
}
|
|
||||||
|
|
||||||
string StartupShortcutPath()
|
|
||||||
{
|
|
||||||
return MyGetSpecialFolderPath(CSIDL_STARTUP, true) + "\\Bitcoin.lnk";
|
|
||||||
}
|
|
||||||
|
|
||||||
bool GetStartOnSystemStartup()
|
|
||||||
{
|
|
||||||
return wxFileExists(StartupShortcutPath());
|
|
||||||
}
|
|
||||||
|
|
||||||
void SetStartOnSystemStartup(bool fAutoStart)
|
|
||||||
{
|
|
||||||
// If the shortcut exists already, remove it for updating
|
|
||||||
remove(StartupShortcutPath().c_str());
|
|
||||||
|
|
||||||
if (fAutoStart)
|
|
||||||
{
|
|
||||||
CoInitialize(NULL);
|
|
||||||
|
|
||||||
// Get a pointer to the IShellLink interface.
|
|
||||||
IShellLink* psl = NULL;
|
|
||||||
HRESULT hres = CoCreateInstance(CLSID_ShellLink, NULL,
|
|
||||||
CLSCTX_INPROC_SERVER, IID_IShellLink,
|
|
||||||
reinterpret_cast<void**>(&psl));
|
|
||||||
|
|
||||||
if (SUCCEEDED(hres))
|
|
||||||
{
|
|
||||||
// Get the current executable path
|
|
||||||
TCHAR pszExePath[MAX_PATH];
|
|
||||||
GetModuleFileName(NULL, pszExePath, sizeof(pszExePath));
|
|
||||||
|
|
||||||
// Set the path to the shortcut target
|
|
||||||
psl->SetPath(pszExePath);
|
|
||||||
PathRemoveFileSpec(pszExePath);
|
|
||||||
psl->SetWorkingDirectory(pszExePath);
|
|
||||||
psl->SetShowCmd(SW_SHOWMINNOACTIVE);
|
|
||||||
|
|
||||||
// Query IShellLink for the IPersistFile interface for
|
|
||||||
// saving the shortcut in persistent storage.
|
|
||||||
IPersistFile* ppf = NULL;
|
|
||||||
hres = psl->QueryInterface(IID_IPersistFile,
|
|
||||||
reinterpret_cast<void**>(&ppf));
|
|
||||||
if (SUCCEEDED(hres))
|
|
||||||
{
|
|
||||||
WCHAR pwsz[MAX_PATH];
|
|
||||||
// Ensure that the string is ANSI.
|
|
||||||
MultiByteToWideChar(CP_ACP, 0, StartupShortcutPath().c_str(), -1, pwsz, MAX_PATH);
|
|
||||||
// Save the link by calling IPersistFile::Save.
|
|
||||||
hres = ppf->Save(pwsz, TRUE);
|
|
||||||
ppf->Release();
|
|
||||||
}
|
|
||||||
psl->Release();
|
|
||||||
}
|
|
||||||
CoUninitialize();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
#else
|
|
||||||
bool GetStartOnSystemStartup() { return false; }
|
|
||||||
void SetStartOnSystemStartup(bool fAutoStart) { }
|
|
||||||
#endif
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
49
ui.h
49
ui.h
@ -4,27 +4,62 @@
|
|||||||
|
|
||||||
DECLARE_EVENT_TYPE(wxEVT_UITHREADCALL, -1)
|
DECLARE_EVENT_TYPE(wxEVT_UITHREADCALL, -1)
|
||||||
|
|
||||||
|
#if wxUSE_GUI
|
||||||
|
static const bool fGUI=true;
|
||||||
|
#else
|
||||||
|
static const bool fGUI=false;
|
||||||
|
#endif
|
||||||
|
|
||||||
extern map<string, string> mapArgs;
|
inline int MyMessageBox(const wxString& message, const wxString& caption="Message", int style=wxOK, wxWindow* parent=NULL, int x=-1, int y=-1)
|
||||||
|
{
|
||||||
|
#if wxUSE_GUI
|
||||||
|
if (!fDaemon)
|
||||||
|
return wxMessageBox(message, caption, style, parent, x, y);
|
||||||
|
#endif
|
||||||
|
printf("wxMessageBox %s: %s\n", string(caption).c_str(), string(message).c_str());
|
||||||
|
fprintf(stderr, "%s: %s\n", string(caption).c_str(), string(message).c_str());
|
||||||
|
return wxOK;
|
||||||
|
}
|
||||||
|
#define wxMessageBox MyMessageBox
|
||||||
|
|
||||||
// Settings
|
|
||||||
extern int fMinimizeToTray;
|
|
||||||
extern int fMinimizeOnClose;
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
void HandleCtrlA(wxKeyEvent& event);
|
void HandleCtrlA(wxKeyEvent& event);
|
||||||
string FormatTxStatus(const CWalletTx& wtx);
|
string FormatTxStatus(const CWalletTx& wtx);
|
||||||
void UIThreadCall(boost::function0<void>);
|
void UIThreadCall(boost::function0<void>);
|
||||||
void MainFrameRepaint();
|
|
||||||
void Shutdown(void* parg);
|
|
||||||
int ThreadSafeMessageBox(const string& message, const string& caption="Message", int style=wxOK, wxWindow* parent=NULL, int x=-1, int y=-1);
|
int ThreadSafeMessageBox(const string& message, const string& caption="Message", int style=wxOK, wxWindow* parent=NULL, int x=-1, int y=-1);
|
||||||
bool ThreadSafeAskFee(int64 nFeeRequired, const string& strCaption, wxWindow* parent);
|
bool ThreadSafeAskFee(int64 nFeeRequired, const string& strCaption, wxWindow* parent);
|
||||||
|
void MainFrameRepaint();
|
||||||
|
void CreateMainWindow();
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
#if !wxUSE_GUI
|
||||||
|
inline int ThreadSafeMessageBox(const string& message, const string& caption, int style, wxWindow* parent, int x, int y)
|
||||||
|
{
|
||||||
|
return MyMessageBox(message, caption, style, parent, x, y);
|
||||||
|
}
|
||||||
|
|
||||||
|
inline bool ThreadSafeAskFee(int64 nFeeRequired, const string& strCaption, wxWindow* parent)
|
||||||
|
{
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
inline void MainFrameRepaint()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
inline void CreateMainWindow()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
#else // wxUSE_GUI
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
class CMainFrame : public CMainFrameBase
|
class CMainFrame : public CMainFrameBase
|
||||||
{
|
{
|
||||||
@ -331,3 +366,5 @@ public:
|
|||||||
|
|
||||||
DECLARE_EVENT_TABLE()
|
DECLARE_EVENT_TABLE()
|
||||||
};
|
};
|
||||||
|
|
||||||
|
#endif // wxUSE_GUI
|
||||||
|
5
util.cpp
5
util.cpp
@ -459,6 +459,7 @@ const char* wxGetTranslation(const char* pszEnglish)
|
|||||||
mapCache[pszEnglish] = pszCached;
|
mapCache[pszEnglish] = pszCached;
|
||||||
return pszCached;
|
return pszCached;
|
||||||
}
|
}
|
||||||
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -502,8 +503,8 @@ void PrintException(std::exception* pex, const char* pszThread)
|
|||||||
FormatException(pszMessage, pex, pszThread);
|
FormatException(pszMessage, pex, pszThread);
|
||||||
printf("\n\n************************\n%s\n", pszMessage);
|
printf("\n\n************************\n%s\n", pszMessage);
|
||||||
fprintf(stderr, "\n\n************************\n%s\n", pszMessage);
|
fprintf(stderr, "\n\n************************\n%s\n", pszMessage);
|
||||||
if (wxTheApp && !fDaemon)
|
if (wxTheApp && !fDaemon && fGUI)
|
||||||
wxMessageBox(pszMessage, "Error", wxOK | wxICON_ERROR);
|
MyMessageBox(pszMessage, "Error", wxOK | wxICON_ERROR);
|
||||||
throw;
|
throw;
|
||||||
//DebugBreak();
|
//DebugBreak();
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user