mirror of
https://github.com/berkeleydb/libdb.git
synced 2024-11-16 17:16:25 +00:00
486 lines
13 KiB
C++
486 lines
13 KiB
C++
/*-
|
|
* See the file LICENSE for redistribution information.
|
|
*
|
|
* Copyright (c) 2007, 2012 Oracle and/or its affiliates. All rights reserved.
|
|
*
|
|
* $Id$
|
|
*/
|
|
|
|
// TpcbUI.cpp : Defines the entry point for the application.
|
|
//
|
|
|
|
#include <windows.h>
|
|
#include "resource.h"
|
|
#include "TpcbExample.h"
|
|
#include <commctrl.h>
|
|
|
|
#define MAX_LOADSTRING 100
|
|
|
|
// Global Variables:
|
|
HINSTANCE hInst; // The current instance
|
|
HWND hWndDlgMain; // Handle to the main dialog window.
|
|
HWND hWndFrame; // Handle to the main window.
|
|
TpcbExample *tpcb;
|
|
|
|
// Forward declarations of functions included in this code module:
|
|
ATOM MyRegisterClass (HINSTANCE, LPTSTR);
|
|
BOOL InitInstance (HINSTANCE, int);
|
|
LRESULT CALLBACK WndProc (HWND, UINT, WPARAM, LPARAM);
|
|
LRESULT CALLBACK MainDialog (HWND, UINT, WPARAM, LPARAM);
|
|
LRESULT CALLBACK InitDialog (HWND, UINT, WPARAM, LPARAM);
|
|
LRESULT CALLBACK AdvancedDialog (HWND, UINT, WPARAM, LPARAM);
|
|
LRESULT CALLBACK RunDialog (HWND, UINT, WPARAM, LPARAM);
|
|
BOOL GetHomeDirectory(HWND, BOOL);
|
|
BOOL RecursiveDirRemove(wchar_t *);
|
|
|
|
int WINAPI WinMain( HINSTANCE hInstance,
|
|
HINSTANCE hPrevInstance,
|
|
LPTSTR lpCmdLine,
|
|
int nCmdShow)
|
|
{
|
|
MSG msg;
|
|
HACCEL hAccelTable;
|
|
|
|
hWndDlgMain = NULL;
|
|
// Initialize the tpcb object.
|
|
tpcb = new TpcbExample();
|
|
|
|
// Perform application initialization:
|
|
if (!InitInstance (hInstance, nCmdShow))
|
|
{
|
|
return FALSE;
|
|
}
|
|
|
|
hAccelTable = LoadAccelerators(hInstance, (LPCTSTR)IDC_WCE_TPCB);
|
|
|
|
// Main message loop:
|
|
while (GetMessage(&msg, NULL, 0, 0))
|
|
{
|
|
if (!TranslateAccelerator(msg.hwnd, hAccelTable, &msg))
|
|
{
|
|
TranslateMessage(&msg);
|
|
DispatchMessage(&msg);
|
|
}
|
|
}
|
|
|
|
return msg.wParam;
|
|
}
|
|
|
|
//
|
|
// FUNCTION: MyRegisterClass()
|
|
//
|
|
// PURPOSE: Registers the window class.
|
|
//
|
|
// COMMENTS:
|
|
//
|
|
// It is important to call this function so that the application
|
|
// will get 'well formed' small icons associated with it.
|
|
//
|
|
ATOM MyRegisterClass(HINSTANCE hInstance, LPTSTR szWindowClass)
|
|
{
|
|
WNDCLASS wc;
|
|
|
|
wc.style = CS_HREDRAW | CS_VREDRAW;
|
|
wc.lpfnWndProc = (WNDPROC) WndProc;
|
|
wc.cbClsExtra = 0;
|
|
wc.cbWndExtra = 0;
|
|
wc.hInstance = hInstance;
|
|
wc.hIcon = LoadIcon(hInstance, MAKEINTRESOURCE(IDI_WCE_TPCB));
|
|
wc.hCursor = 0;
|
|
wc.hbrBackground = (HBRUSH) GetStockObject(WHITE_BRUSH);
|
|
wc.lpszMenuName = 0;
|
|
wc.lpszClassName = szWindowClass;
|
|
|
|
return RegisterClass(&wc);
|
|
}
|
|
|
|
//
|
|
// FUNCTION: InitInstance(HANDLE, int)
|
|
//
|
|
// PURPOSE: Saves instance handle and creates main window
|
|
//
|
|
// COMMENTS:
|
|
//
|
|
// In this function, we save the instance handle in a global variable and
|
|
// create and display the main program window.
|
|
//
|
|
BOOL InitInstance(HINSTANCE hInstance, int nCmdShow)
|
|
{
|
|
TCHAR szTitle[MAX_LOADSTRING]; // The title bar text
|
|
TCHAR szWindowClass[MAX_LOADSTRING]; // The window class name
|
|
|
|
hInst = hInstance; // Store instance handle in our global variable
|
|
// Initialize global strings
|
|
LoadString(hInstance, IDC_WCE_TPCB, szWindowClass, MAX_LOADSTRING);
|
|
MyRegisterClass(hInstance, szWindowClass);
|
|
LoadString(hInstance, IDS_APP_TITLE, szTitle, MAX_LOADSTRING);
|
|
|
|
hWndFrame = CreateWindow(szWindowClass, szTitle,
|
|
WS_VISIBLE | WS_MINIMIZEBOX, CW_USEDEFAULT, CW_USEDEFAULT,
|
|
CW_USEDEFAULT, CW_USEDEFAULT, NULL, NULL, hInstance, NULL);
|
|
|
|
if (!hWndFrame)
|
|
{
|
|
return FALSE;
|
|
}
|
|
|
|
ShowWindow(hWndDlgMain, nCmdShow);
|
|
UpdateWindow(hWndDlgMain);
|
|
|
|
return TRUE;
|
|
}
|
|
|
|
//
|
|
// FUNCTION: WndProc(HWND, unsigned, WORD, LONG)
|
|
//
|
|
// PURPOSE: Processes messages for the main window.
|
|
//
|
|
// WM_COMMAND - process the application menu
|
|
// WM_DESTROY - post a quit message and return
|
|
//
|
|
//
|
|
LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
|
|
{
|
|
HWND hDlg;
|
|
|
|
switch (message)
|
|
{
|
|
case WM_COMMAND:
|
|
DefWindowProc(hWnd, message, wParam, lParam);
|
|
break;
|
|
case WM_CREATE:
|
|
hDlg = CreateDialog(hInst,
|
|
MAKEINTRESOURCE(IDD_MAINDIALOG), hWnd,
|
|
(DLGPROC)MainDialog);
|
|
break;
|
|
case WM_DESTROY:
|
|
PostQuitMessage(0);
|
|
break;
|
|
default:
|
|
return DefWindowProc(hWnd, message, wParam, lParam);
|
|
}
|
|
return 0;
|
|
}
|
|
|
|
// Message handler for the Main dialog box
|
|
LRESULT CALLBACK MainDialog(HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam)
|
|
{
|
|
RECT rt;
|
|
HWND hCurrentRadioButton;
|
|
wchar_t wdirname[MAX_PATH], msg[1024], *title;
|
|
int ret, valid, ntxns, written;
|
|
|
|
switch (message)
|
|
{
|
|
case WM_INITDIALOG:
|
|
// maximize the dialog.
|
|
GetClientRect(GetParent(hDlg), &rt);
|
|
SetWindowPos(hDlg, HWND_TOP, 0, 0, rt.right, rt.bottom,
|
|
SWP_SHOWWINDOW);
|
|
CheckRadioButton(hDlg, IDC_MEDIUM_RADIO,
|
|
IDC_SMALL_RADIO, IDC_SMALL_RADIO);
|
|
SetDlgItemText(hDlg, IDC_HOME_EDIT,
|
|
tpcb->getHomeDirW(wdirname, MAX_PATH));
|
|
SetDlgItemInt(hDlg, IDC_TXN_EDIT, 1000, 0);
|
|
|
|
SetWindowText(hDlg, L"BDB TPCB Example app");
|
|
ShowWindow(hDlg, SW_SHOWNORMAL);
|
|
return TRUE;
|
|
case WM_COMMAND:
|
|
if (LOWORD(wParam) == IDC_INIT_BUTTON ||
|
|
LOWORD(wParam) == IDC_RUN_BUTTON ) {
|
|
hCurrentRadioButton = GetDlgItem(hDlg,
|
|
IDC_SMALL_RADIO);
|
|
if(BST_CHECKED ==
|
|
SendMessage(hCurrentRadioButton,
|
|
BM_GETCHECK, NULL, NULL)) {
|
|
tpcb->accounts = 500;
|
|
tpcb->branches = 10;
|
|
tpcb->tellers = 50;
|
|
tpcb->history = 5000;
|
|
}
|
|
hCurrentRadioButton = GetDlgItem(hDlg,
|
|
IDC_MEDIUM_RADIO);
|
|
if(BST_CHECKED ==
|
|
SendMessage(hCurrentRadioButton,
|
|
BM_GETCHECK, NULL, NULL)) {
|
|
tpcb->accounts = 1000;
|
|
tpcb->branches = 10;
|
|
tpcb->tellers = 100;
|
|
tpcb->history = 10000;
|
|
}
|
|
hCurrentRadioButton = GetDlgItem(hDlg,
|
|
IDC_LARGE_RADIO);
|
|
if(BST_CHECKED ==
|
|
SendMessage(hCurrentRadioButton,
|
|
BM_GETCHECK, NULL, NULL)) {
|
|
tpcb->accounts = 100000;
|
|
tpcb->branches = 10;
|
|
tpcb->tellers = 100;
|
|
tpcb->history = 259200;
|
|
}
|
|
EnableWindow(GetDlgItem(hDlg, IDC_INIT_BUTTON),
|
|
FALSE);
|
|
EnableWindow(GetDlgItem(hDlg, IDC_RUN_BUTTON),
|
|
FALSE);
|
|
EnableWindow(GetDlgItem(hDlg, IDC_ADV_BUTTON),
|
|
FALSE);
|
|
}
|
|
if (LOWORD(wParam) == IDC_ADV_BUTTON) {
|
|
CreateDialog(hInst,
|
|
MAKEINTRESOURCE(IDD_ADVANCEDDIALOG), hDlg,
|
|
(DLGPROC)AdvancedDialog);
|
|
} else if (LOWORD(wParam) == IDC_INIT_BUTTON) {
|
|
// Close the environment first.
|
|
// In case this is a re-initialization.
|
|
tpcb->closeEnv();
|
|
GetHomeDirectory(hDlg, TRUE);
|
|
tpcb->createEnv(0);
|
|
ret = tpcb->populate();
|
|
} else if (LOWORD(wParam) == IDC_RUN_BUTTON) {
|
|
GetHomeDirectory(hDlg, FALSE);
|
|
if (GetFileAttributes(
|
|
tpcb->getHomeDirW(wdirname, MAX_PATH)) !=
|
|
FILE_ATTRIBUTE_DIRECTORY) {
|
|
_snwprintf(msg, 1024,
|
|
L"Target directory: %s does not exist, or is not a directory.\nMake sure the "
|
|
L"directory name is correct, and that you ran the initialization phase.",
|
|
wdirname);
|
|
MessageBox(hDlg, msg, L"Error", MB_OK);
|
|
EnableWindow(GetDlgItem(hDlg,
|
|
IDC_INIT_BUTTON), TRUE);
|
|
EnableWindow(GetDlgItem(hDlg,
|
|
IDC_RUN_BUTTON), TRUE);
|
|
EnableWindow(GetDlgItem(hDlg,
|
|
IDC_ADV_BUTTON), TRUE);
|
|
return FALSE;
|
|
}
|
|
// TODO: Check for an empty directory?
|
|
ntxns = GetDlgItemInt(hDlg, IDC_TXN_EDIT,
|
|
&valid, FALSE);
|
|
if (valid == FALSE) {
|
|
MessageBox(hDlg,
|
|
L"Invalid number in transaction field.",
|
|
L"Error", MB_OK);
|
|
EnableWindow(GetDlgItem(hDlg,
|
|
IDC_INIT_BUTTON), TRUE);
|
|
EnableWindow(GetDlgItem(hDlg,
|
|
IDC_RUN_BUTTON), TRUE);
|
|
EnableWindow(GetDlgItem(hDlg,
|
|
IDC_ADV_BUTTON), TRUE);
|
|
return FALSE;
|
|
}
|
|
tpcb->createEnv(0);
|
|
ret = tpcb->run(ntxns);
|
|
} else if (LOWORD(wParam) == IDC_EXIT_BUTTON) {
|
|
tpcb->closeEnv();
|
|
EndDialog(hDlg, LOWORD(wParam));
|
|
DestroyWindow(hDlg);
|
|
DestroyWindow(hWndFrame);
|
|
return FALSE;
|
|
}
|
|
if (LOWORD(wParam) == IDC_INIT_BUTTON ||
|
|
LOWORD(wParam) == IDC_RUN_BUTTON ) {
|
|
if (ret == 0)
|
|
title = L"Results";
|
|
else
|
|
title = L"Error message";
|
|
written = MultiByteToWideChar(CP_ACP, NULL,
|
|
tpcb->msgString, strlen(tpcb->msgString),
|
|
msg, sizeof(msg)/sizeof(msg[0]));
|
|
msg[written] = L'\0';
|
|
MessageBox(hDlg, msg, title, MB_OK);
|
|
EnableWindow(GetDlgItem(hDlg, IDC_INIT_BUTTON), TRUE);
|
|
EnableWindow(GetDlgItem(hDlg, IDC_RUN_BUTTON),
|
|
TRUE);
|
|
EnableWindow(GetDlgItem(hDlg, IDC_ADV_BUTTON),
|
|
TRUE);
|
|
}
|
|
break;
|
|
case WM_DESTROY:
|
|
// Same functionality as WM_COMMAND->IDC_EXIT_BUTTON
|
|
tpcb->closeEnv();
|
|
EndDialog(hDlg, LOWORD(wParam));
|
|
DestroyWindow(hDlg);
|
|
DestroyWindow(hWndFrame);
|
|
return FALSE;
|
|
default:
|
|
return DefWindowProc(hDlg, message, wParam, lParam);
|
|
}
|
|
return TRUE;
|
|
}
|
|
|
|
// Message handler for the Advanced dialog box
|
|
LRESULT CALLBACK AdvancedDialog(HWND hDlg, UINT message,
|
|
WPARAM wParam, LPARAM lParam)
|
|
{
|
|
RECT rt;
|
|
HWND hCurrentCheckBox;
|
|
int currentInt, valid;
|
|
|
|
switch (message)
|
|
{
|
|
case WM_INITDIALOG:
|
|
GetClientRect(GetParent(hDlg), &rt);
|
|
SetWindowPos(hDlg, HWND_TOP, 0, 0, rt.right, rt.bottom,
|
|
SWP_SHOWWINDOW);
|
|
if (tpcb->fast_mode == 0) {
|
|
hCurrentCheckBox =
|
|
GetDlgItem(hDlg, IDC_FASTMODE_CHECK);
|
|
SendMessage(hCurrentCheckBox, BM_SETCHECK,
|
|
BST_CHECKED, 0);
|
|
}
|
|
if (tpcb->verbose == 1) {
|
|
hCurrentCheckBox =
|
|
GetDlgItem(hDlg, IDC_VERBOSE_CHECK);
|
|
SendMessage(hCurrentCheckBox, BM_SETCHECK,
|
|
BST_CHECKED, 0);
|
|
}
|
|
if (tpcb->cachesize != 0) {
|
|
SetDlgItemInt(hDlg, IDC_CACHE_EDIT,
|
|
tpcb->cachesize/1024, FALSE);
|
|
}
|
|
break;
|
|
case WM_COMMAND:
|
|
if (LOWORD(wParam) == IDC_DONE_BUTTON) {
|
|
hCurrentCheckBox =
|
|
GetDlgItem(hDlg, IDC_FASTMODE_CHECK);
|
|
if(BST_CHECKED == SendMessage(hCurrentCheckBox,
|
|
BM_GETCHECK, NULL, NULL))
|
|
tpcb->fast_mode = 0;
|
|
else
|
|
tpcb->fast_mode = 1;
|
|
hCurrentCheckBox =
|
|
GetDlgItem(hDlg, IDC_VERBOSE_CHECK);
|
|
if(BST_CHECKED == SendMessage(hCurrentCheckBox,
|
|
BM_GETCHECK, NULL, NULL))
|
|
tpcb->verbose = 1;
|
|
else
|
|
tpcb->verbose = 0;
|
|
currentInt = GetDlgItemInt(hDlg,
|
|
IDC_RANDOM_EDIT, &valid, FALSE);
|
|
if (valid != FALSE)
|
|
tpcb->rand_seed = currentInt;
|
|
currentInt = GetDlgItemInt(hDlg,
|
|
IDC_CACHE_EDIT, &valid, FALSE);
|
|
if (valid != FALSE) {
|
|
if (currentInt < 20) {
|
|
MessageBox(hDlg,
|
|
L"Min cache size is 20kb.",
|
|
L"Error", MB_OK);
|
|
return FALSE;
|
|
}
|
|
tpcb->cachesize = currentInt*1024;
|
|
}
|
|
EndDialog(hDlg, LOWORD(wParam));
|
|
DestroyWindow(hDlg);
|
|
}
|
|
break;
|
|
default:
|
|
return DefWindowProc(hDlg, message, wParam, lParam);
|
|
}
|
|
return TRUE;
|
|
}
|
|
|
|
// Utility function to retrieve the directory name
|
|
// from the control, and set it in the tpcb object.
|
|
// Optionally remove and create requested directory.
|
|
BOOL
|
|
GetHomeDirectory(HWND hDlg, BOOL init)
|
|
{
|
|
wchar_t wdirname[MAX_PATH];
|
|
DWORD attrs;
|
|
|
|
if (GetDlgItemText(hDlg, IDC_HOME_EDIT, wdirname, MAX_PATH) == 0)
|
|
tpcb->setHomeDir(TESTDIR);
|
|
else
|
|
tpcb->setHomeDirW(wdirname);
|
|
|
|
if (init == TRUE) {
|
|
// Ensure that wdirname holds the correct version:
|
|
tpcb->getHomeDirW(wdirname, MAX_PATH);
|
|
|
|
// If the directory exists, ensure that it is empty.
|
|
attrs = GetFileAttributes(wdirname);
|
|
if (attrs == FILE_ATTRIBUTE_DIRECTORY)
|
|
RecursiveDirRemove(wdirname);
|
|
else if (attrs == FILE_ATTRIBUTE_NORMAL)
|
|
DeleteFile(wdirname);
|
|
else if (attrs != 0xFFFFFFFF) {
|
|
// Not a directory or normal file, don't try to remove
|
|
// it, or create a new directory over the top.
|
|
return FALSE;
|
|
}
|
|
|
|
// Create the requested directory.
|
|
return CreateDirectory(wdirname, NULL);
|
|
}
|
|
return TRUE;
|
|
}
|
|
|
|
BOOL
|
|
RecursiveDirRemove(wchar_t *dirname)
|
|
{
|
|
HANDLE hFind; // file handle
|
|
WIN32_FIND_DATA findFileData;
|
|
|
|
wchar_t DirPath[MAX_PATH];
|
|
wchar_t FileName[MAX_PATH];
|
|
|
|
wcscpy(DirPath, dirname);
|
|
wcscat(DirPath, L"\\*"); // searching all files
|
|
wcscpy(FileName, dirname);
|
|
wcscat(FileName, L"\\");
|
|
|
|
MessageBox(hWndDlgMain, L"Cleaning directory.", L"Message", MB_OK);
|
|
// find the first file
|
|
if ((hFind = FindFirstFile(DirPath,&findFileData)) ==
|
|
INVALID_HANDLE_VALUE)
|
|
return FALSE;
|
|
|
|
wcscpy(DirPath,FileName);
|
|
MessageBox(hWndDlgMain, L"Found files in directory.",
|
|
L"Message", MB_OK);
|
|
|
|
bool bSearch = true;
|
|
do {
|
|
|
|
wcscpy(FileName + wcslen(DirPath), findFileData.cFileName);
|
|
if (findFileData.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY)
|
|
{
|
|
// we have found a directory, recurse
|
|
if (!RecursiveDirRemove(FileName))
|
|
break; // directory couldn't be deleted
|
|
} else {
|
|
if (findFileData.dwFileAttributes &
|
|
FILE_ATTRIBUTE_READONLY)
|
|
SetFileAttributes(findFileData.cFileName,
|
|
FILE_ATTRIBUTE_NORMAL);
|
|
if (!DeleteFile(FileName)) {
|
|
MessageBox(hWndDlgMain, L"Delete failed.",
|
|
L"Message", MB_OK);
|
|
break; // file couldn't be deleted
|
|
}
|
|
}
|
|
} while (FindNextFile(hFind,&findFileData));
|
|
|
|
FindClose(hFind); // closing file handle
|
|
return RemoveDirectory(dirname); // remove the empty directory
|
|
}
|
|
|
|
// Callback function used to receive error messages from DB
|
|
// Needs to have a C calling convention.
|
|
// Using this function, since the implementation is presenting
|
|
// the error to the user in a message box.
|
|
extern "C" {
|
|
void tpcb_errcallback(const DB_ENV *, const char *errpfx, const char *errstr)
|
|
{
|
|
wchar_t wstr[ERR_STRING_MAX];
|
|
memset(wstr, 0, sizeof(wstr));
|
|
MultiByteToWideChar(CP_ACP, 0, errstr, strlen(errstr),
|
|
wstr, ERR_STRING_MAX-1);
|
|
MessageBox(hWndDlgMain, wstr, L"Error Message", MB_OK);
|
|
exit(1);
|
|
}
|
|
}
|
|
|