272 lines
5.8 KiB
C
272 lines
5.8 KiB
C
|
#include "stdafx.h"
|
||
|
#include "GrbyCfg.h"
|
||
|
#define MAX_LOADSTRING 100
|
||
|
#include <stdio.h>
|
||
|
|
||
|
INT_PTR CALLBACK ConfigDlgProc(HWND, UINT, WPARAM, LPARAM);
|
||
|
|
||
|
/**
|
||
|
* Print an error with a given context before bailing out
|
||
|
*/
|
||
|
void Die(LPTSTR lpContextMsg)
|
||
|
{
|
||
|
LPCTSTR lpszFmt = "%s: %s";
|
||
|
int iFullLen;
|
||
|
LPTSTR lpszError = NULL,
|
||
|
lpszFullMsg = NULL;
|
||
|
|
||
|
// The whole point of this is to print an actual message, so get the
|
||
|
// actual message
|
||
|
if (!FormatMessage(FORMAT_MESSAGE_ALLOCATE_BUFFER |
|
||
|
FORMAT_MESSAGE_FROM_SYSTEM |
|
||
|
FORMAT_MESSAGE_IGNORE_INSERTS,
|
||
|
NULL,
|
||
|
GetLastError(),
|
||
|
0,
|
||
|
(LPTSTR) &lpszError,
|
||
|
0,
|
||
|
NULL))
|
||
|
{
|
||
|
if (lpszError != NULL) LocalFree(lpszError);
|
||
|
lpszError = _T("unknown error");
|
||
|
}
|
||
|
|
||
|
// Create our WMU_* messages
|
||
|
InitUserMsgs();
|
||
|
|
||
|
iFullLen = _sctprintf(lpszFmt, lpContextMsg, lpszError);
|
||
|
lpszFullMsg = (LPTSTR) LocalAlloc(LPTR, sizeof(TCHAR) * (iFullLen + 1));
|
||
|
|
||
|
if (lpszFullMsg == NULL) {
|
||
|
// I'm honestly gonna guess if we get here, we're out of memory.
|
||
|
// So let's print what we have and bail
|
||
|
MessageBox(NULL,
|
||
|
lpContextMsg,
|
||
|
_T("Catastrophic Error"),
|
||
|
MB_OK | MB_ICONERROR);
|
||
|
} else {
|
||
|
_sntprintf(lpszFullMsg, iFullLen, lpszFmt, lpContextMsg, lpszError);
|
||
|
MessageBox(NULL,
|
||
|
lpszFullMsg,
|
||
|
_T("Fatal Error"),
|
||
|
MB_OK | MB_ICONERROR);
|
||
|
}
|
||
|
|
||
|
ExitProcess(1);
|
||
|
}
|
||
|
|
||
|
HINSTANCE g_hInstance = NULL;
|
||
|
|
||
|
int APIENTRY _tWinMain(HINSTANCE hInstance,
|
||
|
HINSTANCE hPrevInstance,
|
||
|
LPTSTR lpCmdLine,
|
||
|
int nCmdShow)
|
||
|
{
|
||
|
BOOL bRet;
|
||
|
MSG msg;
|
||
|
HWND hDlg;
|
||
|
INITCOMMONCONTROLSEX lpInitCtrls = {0};
|
||
|
HRESULT hrRet;
|
||
|
|
||
|
g_hInstance = hInstance;
|
||
|
|
||
|
// Required for tab control
|
||
|
lpInitCtrls.dwSize = sizeof(INITCOMMONCONTROLSEX);
|
||
|
lpInitCtrls.dwICC = ICC_WIN95_CLASSES;
|
||
|
if (!InitCommonControlsEx(&lpInitCtrls)) {
|
||
|
MessageBox(NULL,
|
||
|
_T("Couldn't initialize comctl32! Not sure why..."),
|
||
|
_T("Ooh, rare bug!"),
|
||
|
MB_OK | MB_ICONERROR);
|
||
|
return 1;
|
||
|
}
|
||
|
|
||
|
// Required for folder browse dialog
|
||
|
hrRet = CoInitializeEx(NULL,
|
||
|
COINIT_APARTMENTTHREADED);
|
||
|
if (hrRet != S_OK) {
|
||
|
MessageBox(NULL,
|
||
|
_T("Couldn't initialize COM!?"),
|
||
|
_T("dot com bust u_u"),
|
||
|
MB_OK | MB_ICONERROR);
|
||
|
return 1;
|
||
|
}
|
||
|
|
||
|
hDlg = CreateDialog(hInstance,
|
||
|
MAKEINTRESOURCE(IDD_CONFIGDIALOG),
|
||
|
NULL,
|
||
|
ConfigDlgProc);
|
||
|
|
||
|
if (!hDlg) {
|
||
|
Die("CreateDialog failed");
|
||
|
}
|
||
|
|
||
|
ShowWindow(hDlg, nCmdShow);
|
||
|
|
||
|
while ((bRet = GetMessage(&msg, hDlg, 0, 0)) != FALSE) {
|
||
|
if (bRet == -1) {
|
||
|
// TODO: error handling
|
||
|
break;
|
||
|
} else {
|
||
|
TranslateMessage(&msg);
|
||
|
DispatchMessage(&msg);
|
||
|
}
|
||
|
}
|
||
|
|
||
|
return (int)msg.wParam;
|
||
|
}
|
||
|
|
||
|
// Helper macro to create a new text (i.e., no icon) tab for config
|
||
|
// items.
|
||
|
//
|
||
|
// NOTE: This is written to use <name>Tab_DlgProc for dlgProc. This
|
||
|
// assumes that tabs will always be valid (enough) for a function
|
||
|
// identifier.
|
||
|
#define NEW_TEXTTAB(name, res) {{ \
|
||
|
TCIF_TEXT, \
|
||
|
0, 0, \
|
||
|
_T(#name), \
|
||
|
sizeof(_T(#name)) / sizeof(TCHAR), \
|
||
|
0, 0 \
|
||
|
}, \
|
||
|
res, \
|
||
|
name##Tab_DlgProc, \
|
||
|
NULL \
|
||
|
}
|
||
|
|
||
|
INT_PTR CALLBACK
|
||
|
ConfigDlgProc(HWND hWnd,
|
||
|
UINT uMsg,
|
||
|
WPARAM wParam,
|
||
|
LPARAM lParam)
|
||
|
{
|
||
|
// Define the tab metadata
|
||
|
static struct {
|
||
|
TCITEM tciTab;
|
||
|
int child;
|
||
|
DLGPROC dlgProc;
|
||
|
HWND hWnd;
|
||
|
} tabs[] = {
|
||
|
NEW_TEXTTAB(General,
|
||
|
IDD_GENCONFIG),
|
||
|
NEW_TEXTTAB(Upload,
|
||
|
IDD_UPLOADCONFIG)
|
||
|
};
|
||
|
BOOL bClose = FALSE;
|
||
|
|
||
|
const int tabCount = (sizeof(tabs) / sizeof(tabs[0]));
|
||
|
|
||
|
switch (uMsg) {
|
||
|
case WM_INITDIALOG: {
|
||
|
RECT rcTab;
|
||
|
int i;
|
||
|
HWND hTabCtrl = GetDlgItem(hWnd, IDC_TABVIEW);
|
||
|
|
||
|
if (!hTabCtrl) {
|
||
|
Die("Couldn't get tab control");
|
||
|
}
|
||
|
|
||
|
for (i = 0; i < tabCount; i++) {
|
||
|
int iResult = TabCtrl_InsertItem(
|
||
|
hTabCtrl,
|
||
|
i,
|
||
|
&tabs[i].tciTab);
|
||
|
if (iResult == -1) {
|
||
|
Die("Couldn't create tabs");
|
||
|
}
|
||
|
|
||
|
// Attach the child dialog
|
||
|
tabs[i].hWnd = CreateDialog(g_hInstance,
|
||
|
MAKEINTRESOURCE(tabs[i].child),
|
||
|
hWnd,
|
||
|
tabs[i].dlgProc);
|
||
|
if (!tabs[i].hWnd) {
|
||
|
Die("Couldn't create child tab");
|
||
|
}
|
||
|
}
|
||
|
|
||
|
// This has to happen after the tabs are inserted,
|
||
|
// or else we get the wrong client area (tabs don't
|
||
|
// exist yet!)
|
||
|
GetWindowRect(hTabCtrl, &rcTab);
|
||
|
MapWindowPoints(NULL, hWnd, (LPPOINT)&rcTab, 2);
|
||
|
TabCtrl_AdjustRect(hTabCtrl, FALSE, &rcTab);
|
||
|
|
||
|
for (i = 0; i < tabCount; i++) {
|
||
|
SetWindowPos(tabs[i].hWnd,
|
||
|
HWND_TOP,
|
||
|
rcTab.left,
|
||
|
rcTab.top,
|
||
|
rcTab.right - rcTab.left,
|
||
|
rcTab.bottom - rcTab.top,
|
||
|
(i == 0) ? SWP_SHOWWINDOW : 0);
|
||
|
}
|
||
|
}
|
||
|
break;
|
||
|
|
||
|
case WM_COMMAND:
|
||
|
switch (LOWORD(wParam)) {
|
||
|
case IDCANCEL:
|
||
|
DestroyWindow(hWnd);
|
||
|
break;
|
||
|
case IDOK:
|
||
|
bClose = TRUE;
|
||
|
/* PASSTHRU */
|
||
|
case IDC_APPLY: {
|
||
|
int i;
|
||
|
for (i = 0; i < tabCount; i++) {
|
||
|
SendMessage(tabs[i].hWnd,
|
||
|
WMU_SAVE_CONFIG,
|
||
|
0, 0);
|
||
|
}
|
||
|
|
||
|
EnableWindow(GetDlgItem(hWnd, IDC_APPLY), FALSE);
|
||
|
// Handle OK button (Apply + Close)
|
||
|
if (bClose) SendMessage(hWnd,
|
||
|
WM_CLOSE,
|
||
|
0,
|
||
|
0);
|
||
|
}
|
||
|
break;
|
||
|
default:
|
||
|
// TODO: other buttons
|
||
|
break;
|
||
|
}
|
||
|
break;
|
||
|
|
||
|
case WM_CLOSE:
|
||
|
DestroyWindow(hWnd);
|
||
|
break;
|
||
|
|
||
|
case WM_NOTIFY:
|
||
|
{
|
||
|
LPNMHDR pnmh = (LPNMHDR)lParam;
|
||
|
if (pnmh->code == TCN_SELCHANGE) {
|
||
|
int idx = TabCtrl_GetCurSel(pnmh->hwndFrom);
|
||
|
if (idx < tabCount) {
|
||
|
int i;
|
||
|
for (i = 0; i < tabCount; i++) {
|
||
|
if (tabs[i].hWnd) {
|
||
|
// If it's the child we want, show it.
|
||
|
// If not, hide it.
|
||
|
ShowWindow(tabs[i].hWnd,
|
||
|
(i == idx) ? SW_SHOW : SW_HIDE);
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
// If idx >= tabCount, ignore the message
|
||
|
}
|
||
|
}
|
||
|
break;
|
||
|
default:
|
||
|
// User-defined messages
|
||
|
if (uMsg == WMU_SETTING_CHANGED) {
|
||
|
EnableWindow(GetDlgItem(hWnd, IDC_APPLY), TRUE);
|
||
|
} else {
|
||
|
// Not our message, ignore
|
||
|
return FALSE;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
return TRUE;
|
||
|
}
|