libdb/examples/cxx/wce_tpcb/TpcbUI.cpp
2012-11-14 16:35:20 -05:00

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);
}
}