mirror of
https://github.com/scp-fs2open/fs2open.github.com.git
synced 2026-11-12 19:06:09 -10:00
319 lines
6.6 KiB
C++
319 lines
6.6 KiB
C++
// TabRegOptions.cpp : implementation file
|
|
//
|
|
|
|
#include "stdafx.h"
|
|
#include "Launcher.h"
|
|
#include "TabRegOptions.h"
|
|
#include "win32func.h"
|
|
#include "launcher_settings.h"
|
|
#include "misc.h"
|
|
|
|
#ifdef _DEBUG
|
|
#define new DEBUG_NEW
|
|
#undef THIS_FILE
|
|
static char THIS_FILE[] = __FILE__;
|
|
#endif
|
|
|
|
enum
|
|
{
|
|
REG_TYPE_SZ,
|
|
REG_TYPE_DWORD,
|
|
REG_TYPE_UNSUPPORTED,
|
|
MAX_REG_TYPES
|
|
};
|
|
|
|
char *string_reps[MAX_REG_TYPES] =
|
|
{
|
|
"String",
|
|
"DWORD",
|
|
"N\\A"
|
|
};
|
|
|
|
/////////////////////////////////////////////////////////////////////////////
|
|
// CTabRegOptions dialog
|
|
|
|
|
|
CTabRegOptions::CTabRegOptions(CWnd* pParent /*=NULL*/)
|
|
: CDialog(CTabRegOptions::IDD, pParent)
|
|
{
|
|
//{{AFX_DATA_INIT(CTabRegOptions)
|
|
// NOTE: the ClassWizard will add member initialization here
|
|
//}}AFX_DATA_INIT
|
|
}
|
|
|
|
|
|
void CTabRegOptions::DoDataExchange(CDataExchange* pDX)
|
|
{
|
|
CDialog::DoDataExchange(pDX);
|
|
//{{AFX_DATA_MAP(CTabRegOptions)
|
|
DDX_Control(pDX, IDC_REG_LIST, m_reg_option_list);
|
|
//}}AFX_DATA_MAP
|
|
}
|
|
|
|
|
|
BEGIN_MESSAGE_MAP(CTabRegOptions, CDialog)
|
|
//{{AFX_MSG_MAP(CTabRegOptions)
|
|
ON_BN_CLICKED(IDC_SET, OnSet)
|
|
ON_NOTIFY(LVN_ITEMCHANGED, IDC_REG_LIST, OnItemchangedRegList)
|
|
//}}AFX_MSG_MAP
|
|
END_MESSAGE_MAP()
|
|
|
|
/////////////////////////////////////////////////////////////////////////////
|
|
// CTabRegOptions message handlers
|
|
|
|
/**
|
|
*
|
|
*/
|
|
BOOL CTabRegOptions::OnInitDialog()
|
|
{
|
|
CDialog::OnInitDialog();
|
|
|
|
m_reg_option_list.SetExtendedStyle(LVS_EX_FULLROWSELECT);
|
|
m_reg_option_list.InsertColumn(0, "Name", LVCFMT_LEFT, 125);
|
|
m_reg_option_list.InsertColumn(1, "Type", LVCFMT_LEFT, 60);
|
|
m_reg_option_list.InsertColumn(2, "Data", LVCFMT_LEFT, 129);
|
|
|
|
return TRUE; // return TRUE unless you set the focus to a control
|
|
// EXCEPTION: OCX Property Pages should return FALSE
|
|
}
|
|
|
|
/**
|
|
*
|
|
*/
|
|
void CTabRegOptions::InsertItem(char *name, int type, void *data, DWORD size)
|
|
{
|
|
// Insert name and get new value, may differ from requested index value
|
|
int new_value = m_reg_option_list.InsertItem(m_list_count, name, 0);
|
|
|
|
// Buffer for REG_TYPE_DWORD (have to declare now because of use in switch)
|
|
char *buffer = NULL;
|
|
|
|
// Insert type
|
|
LVITEM item;
|
|
|
|
item.iItem = new_value;
|
|
item.iSubItem = 1;
|
|
item.mask = LVIF_TEXT;
|
|
item.pszText = string_reps[type];
|
|
|
|
if(m_reg_option_list.SetItem(&item) == FALSE)
|
|
{
|
|
MessageBox("Failed to set item");
|
|
return;
|
|
}
|
|
|
|
item.iSubItem = 2;
|
|
|
|
if(data)
|
|
{
|
|
switch(type)
|
|
{
|
|
case REG_TYPE_SZ:
|
|
item.pszText = (char *) data;
|
|
m_reg_option_list.SetItem(&item);
|
|
break;
|
|
case REG_TYPE_DWORD:
|
|
buffer = new char[size+2];
|
|
if (buffer == NULL)
|
|
{
|
|
break;
|
|
}
|
|
// Restrict the data copy to passed "size" rather than the actual size of "buffer"
|
|
_snprintf(buffer, size, "%d", *(DWORD *) data);
|
|
item.pszText = buffer;
|
|
m_reg_option_list.SetItem(&item);
|
|
delete[] buffer;
|
|
break;
|
|
case REG_TYPE_UNSUPPORTED: break;
|
|
}
|
|
}
|
|
|
|
m_reg_option_list.SetItemData(new_value, type);
|
|
}
|
|
|
|
/**
|
|
*
|
|
*/
|
|
void CTabRegOptions::FillRegList()
|
|
{
|
|
int count = 0;
|
|
LONG result;
|
|
|
|
m_reg_option_list.DeleteAllItems();
|
|
|
|
if(LauncherSettings::get_exe_type() == EXE_TYPE_NONE)
|
|
{
|
|
GetDlgItem(IDC_REG_LOCATION)->SetWindowText("No valid game exe chosen");
|
|
return;
|
|
}
|
|
|
|
if(strlen(LauncherSettings::get_reg_path()) == 0)
|
|
{
|
|
return;
|
|
}
|
|
|
|
HKEY hkey = reg_open_dir(LauncherSettings::get_reg_path());
|
|
|
|
// Try to open the correct registry dir
|
|
if(hkey == NULL)
|
|
{
|
|
return;
|
|
}
|
|
|
|
GetDlgItem(IDC_REG_LOCATION)->SetWindowText(LauncherSettings::get_reg_path());
|
|
|
|
// Now find and display all the items at this path
|
|
do
|
|
{
|
|
unsigned long subkey_size = MAX_PATH;
|
|
char subkey_name[MAX_PATH];
|
|
DWORD subkey_type;
|
|
DWORD data_len = 100;
|
|
BYTE *pdata = NULL;
|
|
|
|
{ // Cheap way to determine size of data space needed, data_len is updated with the actual size of the value
|
|
result = RegEnumValue(
|
|
hkey,
|
|
count,
|
|
subkey_name,
|
|
&subkey_size,
|
|
0, // reserved
|
|
&subkey_type,
|
|
NULL,
|
|
&data_len);
|
|
|
|
if (result == ERROR_NO_MORE_ITEMS)
|
|
{
|
|
break;
|
|
}
|
|
|
|
pdata = new BYTE[data_len+2];
|
|
|
|
if (pdata == NULL)
|
|
{
|
|
MessageBox("An error has occured reading from the registry; cancelling...");
|
|
break;
|
|
}
|
|
} // end cheap data space check
|
|
|
|
// account for the NULL char, otherwise we lose the last character of the key name
|
|
subkey_size++;
|
|
|
|
result = RegEnumValue(
|
|
hkey,
|
|
count,
|
|
subkey_name,
|
|
&subkey_size,
|
|
0, // reserved
|
|
&subkey_type,
|
|
pdata,
|
|
&data_len);
|
|
|
|
if(result == ERROR_NO_MORE_ITEMS)
|
|
{
|
|
delete[] pdata;
|
|
break;
|
|
}
|
|
|
|
if(result != ERROR_SUCCESS && result != ERROR_NO_MORE_ITEMS && result != ERROR_MORE_DATA)
|
|
{
|
|
delete[] pdata;
|
|
MessageBox("An error has occured reading from the registry; cancelling...");
|
|
break;
|
|
}
|
|
|
|
int reg_type = REG_TYPE_UNSUPPORTED;
|
|
|
|
switch(subkey_type)
|
|
{
|
|
case REG_DWORD: reg_type = REG_TYPE_DWORD; break;
|
|
case REG_SZ: reg_type = REG_TYPE_SZ; break;
|
|
}
|
|
|
|
InsertItem(subkey_name, reg_type, (void *) pdata, data_len);
|
|
delete[] pdata;
|
|
count++;
|
|
|
|
} while(1);
|
|
|
|
// Close this path now we have all the info we need
|
|
RegCloseKey(hkey);
|
|
|
|
// Nothing is selected so this should be blank
|
|
GetDlgItem(IDC_NEW_VALUE)->SetWindowText("");
|
|
}
|
|
|
|
/**
|
|
*
|
|
*/
|
|
void CTabRegOptions::OnSet()
|
|
{
|
|
// Check the paths are valid
|
|
if(strlen(LauncherSettings::get_reg_path()) == 0)
|
|
{
|
|
MessageBox("No reg path for this exe");
|
|
FillRegList();
|
|
return;
|
|
}
|
|
|
|
// Check a valid item is selected
|
|
int selection = (int) m_reg_option_list.GetFirstSelectedItemPosition() - 1;
|
|
|
|
if(selection == -1)
|
|
{
|
|
MessageBox("No entry chosen");
|
|
return;
|
|
}
|
|
|
|
CString new_value, name = m_reg_option_list.GetItemText(selection, 0);
|
|
|
|
// Get the new value
|
|
GetDlgItem(IDC_NEW_VALUE)->GetWindowText(new_value);
|
|
|
|
const int data_type = m_reg_option_list.GetItemData(selection);
|
|
bool result;
|
|
|
|
switch(data_type)
|
|
{
|
|
case REG_TYPE_SZ:
|
|
{
|
|
result = reg_set_sz(LauncherSettings::get_reg_path(), name, (LPCTSTR) new_value);
|
|
break;
|
|
}
|
|
case REG_TYPE_DWORD:
|
|
{
|
|
DWORD number = atoi( (LPCTSTR) new_value );
|
|
result = reg_set_dword(LauncherSettings::get_reg_path(), name, number);
|
|
break;
|
|
}
|
|
default:
|
|
case REG_TYPE_UNSUPPORTED:
|
|
MessageBox("Viewing or changing this registry type is not supported");
|
|
return;
|
|
}
|
|
|
|
if(result == false)
|
|
{
|
|
MessageBox("Failed to set reg value");
|
|
}
|
|
|
|
// Lets update the list the slow way and ensure everything is how it should be
|
|
FillRegList();
|
|
}
|
|
|
|
/**
|
|
*
|
|
*/
|
|
void CTabRegOptions::OnItemchangedRegList(NMHDR* pNMHDR, LRESULT* pResult)
|
|
{
|
|
NM_LISTVIEW* pNMListView = (NM_LISTVIEW*)pNMHDR;
|
|
|
|
// Get the name and type and data
|
|
POSITION selection = m_reg_option_list.GetFirstSelectedItemPosition();
|
|
CString data = m_reg_option_list.GetItemText((int) selection - 1, 2);
|
|
|
|
GetDlgItem(IDC_NEW_VALUE)->SetWindowText(data);
|
|
|
|
*pResult = 0;
|
|
}
|