mirror of
https://github.com/PCSX2/pcsx2.git
synced 2026-09-10 23:02:59 +02:00
The old implementation saved the current value of a GSSetting as uint in a field called 'id'. The implementation of GSSettings suggests that GSSettings could be saved in a database with id as primary key. This would require a translation look up from id to value but could have all advantages of a database. However the interface to GSSetting was never implemented like that. In the new implementation GSSetting has a 'value' field that stores an int representative value of the desired state. Additionally the constructor is 'overloaded' as template to reduce casting in the consumer code. However all consumer values need to be castable to int. Accordingly combobox initialization was adjusted.
337 lines
7.8 KiB
C++
337 lines
7.8 KiB
C++
/*
|
|
* Copyright (C) 2007-2009 Gabest
|
|
* http://www.gabest.org
|
|
*
|
|
* This Program is free software; you can redistribute it and/or modify
|
|
* it under the terms of the GNU General Public License as published by
|
|
* the Free Software Foundation; either version 2, or (at your option)
|
|
* any later version.
|
|
*
|
|
* This Program is distributed in the hope that it will be useful,
|
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
* GNU General Public License for more details.
|
|
*
|
|
* You should have received a copy of the GNU General Public License
|
|
* along with GNU Make; see the file COPYING. If not, write to
|
|
* the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA USA.
|
|
* http://www.gnu.org/copyleft/gpl.html
|
|
*
|
|
*/
|
|
|
|
#include "StdAfx.h"
|
|
#include <Shlwapi.h>
|
|
#include <CommCtrl.h>
|
|
#include "GSdx.h"
|
|
#include "GSDialog.h"
|
|
#include "GSVector.h"
|
|
|
|
GSDialog::GSDialog(UINT id)
|
|
: m_id(id)
|
|
, m_hWnd(NULL)
|
|
{
|
|
}
|
|
|
|
INT_PTR GSDialog::DoModal()
|
|
{
|
|
return DialogBoxParam(theApp.GetModuleHandle(), MAKEINTRESOURCE(m_id), GetActiveWindow(), DialogProc, (LPARAM)this);
|
|
}
|
|
|
|
INT_PTR CALLBACK GSDialog::DialogProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
|
|
{
|
|
GSDialog* dlg = NULL;
|
|
|
|
if(message == WM_INITDIALOG)
|
|
{
|
|
dlg = (GSDialog*)lParam;
|
|
SetWindowLongPtr(hWnd, GWLP_USERDATA, (LONG_PTR)dlg);
|
|
dlg->m_hWnd = hWnd;
|
|
|
|
MONITORINFO mi;
|
|
mi.cbSize = sizeof(mi);
|
|
GetMonitorInfo(MonitorFromWindow(hWnd, MONITOR_DEFAULTTONEAREST), &mi);
|
|
|
|
GSVector4i r;
|
|
GetWindowRect(hWnd, r);
|
|
|
|
int x = (mi.rcWork.left + mi.rcWork.right - r.width()) / 2;
|
|
int y = (mi.rcWork.top + mi.rcWork.bottom - r.height()) / 2;
|
|
|
|
SetWindowPos(hWnd, NULL, x, y, -1, -1, SWP_NOSIZE | SWP_NOZORDER | SWP_NOACTIVATE);
|
|
|
|
dlg->OnInit();
|
|
|
|
return true;
|
|
}
|
|
|
|
dlg = (GSDialog*)GetWindowLongPtr(hWnd, GWLP_USERDATA);
|
|
|
|
if (message == WM_NOTIFY)
|
|
{
|
|
if (((LPNMHDR)lParam)->code == TTN_GETDISPINFO)
|
|
{
|
|
LPNMTTDISPINFO pInfo = (LPNMTTDISPINFO)lParam;
|
|
UINT id = GetWindowLongPtr((HWND)pInfo->hdr.idFrom, GWL_ID);
|
|
|
|
// lpszText is used only if hinst is NULL. Seems to be NULL already,
|
|
// but it can't hurt to explicitly set it.
|
|
pInfo->hinst = NULL;
|
|
pInfo->lpszText = (LPTSTR)dialog_message(id);
|
|
SendMessage(pInfo->hdr.hwndFrom, TTM_SETMAXTIPWIDTH, 0, 500);
|
|
return true;
|
|
}
|
|
}
|
|
|
|
return dlg != NULL ? dlg->OnMessage(message, wParam, lParam) : FALSE;
|
|
}
|
|
|
|
// Tooltips will only show if the TOOLINFO cbSize <= the struct size. If it's
|
|
// smaller some functionality might be disabled. So let's try and use the
|
|
// correct size.
|
|
UINT GSDialog::GetTooltipStructSize()
|
|
{
|
|
DLLGETVERSIONPROC dllGetVersion = (DLLGETVERSIONPROC)GetProcAddress(GetModuleHandle("ComCtl32.dll"), "DllGetVersion");
|
|
if (dllGetVersion) {
|
|
DLLVERSIONINFO2 dllversion = { 0 };
|
|
dllversion.info1.cbSize = sizeof(DLLVERSIONINFO2);
|
|
|
|
if (dllGetVersion((DLLVERSIONINFO*)&dllversion) == S_OK) {
|
|
// Minor, then major version.
|
|
DWORD version = MAKELONG(dllversion.info1.dwMinorVersion, dllversion.info1.dwMajorVersion);
|
|
DWORD tooltip_v3 = MAKELONG(0, 6);
|
|
if (version >= tooltip_v3)
|
|
return TTTOOLINFOA_V3_SIZE;
|
|
}
|
|
}
|
|
// Should be fine for XP and onwards, comctl versions >= 4.7 should at least
|
|
// be this size.
|
|
return TTTOOLINFOA_V2_SIZE;
|
|
}
|
|
|
|
bool GSDialog::OnMessage(UINT message, WPARAM wParam, LPARAM lParam)
|
|
{
|
|
return message == WM_COMMAND ? OnCommand((HWND)lParam, LOWORD(wParam), HIWORD(wParam)) : false;
|
|
}
|
|
|
|
bool GSDialog::OnCommand(HWND hWnd, UINT id, UINT code)
|
|
{
|
|
if(id == IDOK || id == IDCANCEL)
|
|
{
|
|
EndDialog(m_hWnd, id);
|
|
|
|
return true;
|
|
}
|
|
|
|
return false;
|
|
}
|
|
|
|
string GSDialog::GetText(UINT id)
|
|
{
|
|
string s;
|
|
|
|
char* buff = NULL;
|
|
|
|
for(int size = 256, limit = 65536; size < limit; size <<= 1)
|
|
{
|
|
buff = new char[size];
|
|
|
|
if(GetDlgItemText(m_hWnd, id, buff, size))
|
|
{
|
|
s = buff;
|
|
size = limit;
|
|
}
|
|
|
|
delete [] buff;
|
|
}
|
|
|
|
return s;
|
|
}
|
|
|
|
int GSDialog::GetTextAsInt(UINT id)
|
|
{
|
|
return atoi(GetText(id).c_str());
|
|
}
|
|
|
|
void GSDialog::SetText(UINT id, const char* str)
|
|
{
|
|
SetDlgItemText(m_hWnd, id, str);
|
|
}
|
|
|
|
void GSDialog::SetTextAsInt(UINT id, int i)
|
|
{
|
|
char buff[32] = {0};
|
|
itoa(i, buff, 10);
|
|
SetText(id, buff);
|
|
}
|
|
|
|
void GSDialog::ComboBoxInit(UINT id, const vector<GSSetting>& settings, int32_t selectionValue, int32_t maxValue)
|
|
{
|
|
HWND hWnd = GetDlgItem(m_hWnd, id);
|
|
|
|
SendMessage(hWnd, CB_RESETCONTENT, 0, 0);
|
|
|
|
for(size_t i = 0; i < settings.size(); i++)
|
|
{
|
|
const GSSetting& s = settings[i];
|
|
|
|
if(s.value <= maxValue)
|
|
{
|
|
string str(s.name);
|
|
|
|
if(!s.note.empty())
|
|
{
|
|
str = str + " (" + s.note + ")";
|
|
}
|
|
|
|
ComboBoxAppend(id, str.c_str(), (LPARAM)s.value, s.value == selectionValue);
|
|
}
|
|
}
|
|
|
|
ComboBoxFixDroppedWidth(id);
|
|
}
|
|
|
|
int GSDialog::ComboBoxAppend(UINT id, const char* str, LPARAM data, bool select)
|
|
{
|
|
HWND hWnd = GetDlgItem(m_hWnd, id);
|
|
|
|
int item = (int)SendMessage(hWnd, CB_ADDSTRING, 0, (LPARAM)str);
|
|
|
|
SendMessage(hWnd, CB_SETITEMDATA, item, (LPARAM)data);
|
|
|
|
if(select)
|
|
{
|
|
SendMessage(hWnd, CB_SETCURSEL, item, 0);
|
|
}
|
|
|
|
return item;
|
|
}
|
|
|
|
bool GSDialog::ComboBoxGetSelData(UINT id, INT_PTR& data)
|
|
{
|
|
HWND hWnd = GetDlgItem(m_hWnd, id);
|
|
|
|
int item = SendMessage(hWnd, CB_GETCURSEL, 0, 0);
|
|
|
|
if(item >= 0)
|
|
{
|
|
data = SendMessage(hWnd, CB_GETITEMDATA, item, 0);
|
|
|
|
return true;
|
|
}
|
|
|
|
return false;
|
|
}
|
|
|
|
void GSDialog::ComboBoxFixDroppedWidth(UINT id)
|
|
{
|
|
HWND hWnd = GetDlgItem(m_hWnd, id);
|
|
|
|
int count = (int)SendMessage(hWnd, CB_GETCOUNT, 0, 0);
|
|
|
|
if(count > 0)
|
|
{
|
|
HDC hDC = GetDC(hWnd);
|
|
|
|
SelectObject(hDC, (HFONT)SendMessage(hWnd, WM_GETFONT, 0, 0));
|
|
|
|
int width = (int)SendMessage(hWnd, CB_GETDROPPEDWIDTH, 0, 0);
|
|
|
|
for(int i = 0; i < count; i++)
|
|
{
|
|
int len = (int)SendMessage(hWnd, CB_GETLBTEXTLEN, i, 0);
|
|
|
|
if(len > 0)
|
|
{
|
|
char* buff = new char[len + 1];
|
|
|
|
SendMessage(hWnd, CB_GETLBTEXT, i, (LPARAM)buff);
|
|
|
|
SIZE size;
|
|
|
|
if(GetTextExtentPoint32(hDC, buff, strlen(buff), &size))
|
|
{
|
|
size.cx += 10;
|
|
|
|
if(size.cx > width) width = size.cx;
|
|
}
|
|
|
|
delete [] buff;
|
|
}
|
|
}
|
|
|
|
ReleaseDC(hWnd, hDC);
|
|
|
|
if(width > 0)
|
|
{
|
|
SendMessage(hWnd, CB_SETDROPPEDWIDTH, width, 0);
|
|
}
|
|
}
|
|
}
|
|
|
|
void GSDialog::OpenFileDialog(UINT id, const char *title)
|
|
{
|
|
char filename[512];
|
|
OPENFILENAME ofn = { 0 };
|
|
ofn.lStructSize = sizeof(OPENFILENAME);
|
|
ofn.hwndOwner = m_hWnd;
|
|
ofn.Flags = OFN_EXPLORER | OFN_FILEMUSTEXIST;
|
|
ofn.lpstrFile = filename;
|
|
ofn.lpstrFile[0] = 0;
|
|
ofn.nMaxFile = 512;
|
|
ofn.lpstrTitle = title;
|
|
|
|
// GetOpenFileName changes the current directory, so we need to save and
|
|
// restore the current directory or everything using relative paths will
|
|
// break.
|
|
char current_directory[512];
|
|
GetCurrentDirectory(512, current_directory);
|
|
|
|
if (GetOpenFileName(&ofn))
|
|
SendMessage(GetDlgItem(m_hWnd, id), WM_SETTEXT, 0, (LPARAM)filename);
|
|
|
|
SetCurrentDirectory(current_directory);
|
|
|
|
}
|
|
|
|
void GSDialog::AddTooltip(UINT id)
|
|
{
|
|
static UINT tooltipStructSize = GetTooltipStructSize();
|
|
bool hasTooltip;
|
|
|
|
dialog_message(id, &hasTooltip);
|
|
if (!hasTooltip)
|
|
return;
|
|
|
|
HWND hWnd = GetDlgItem(m_hWnd, id);
|
|
if (hWnd == NULL)
|
|
return;
|
|
|
|
// TTS_NOPREFIX allows tabs and '&' to be used.
|
|
HWND hwndTip = CreateWindowEx(WS_EX_TOPMOST, TOOLTIPS_CLASS, NULL,
|
|
TTS_ALWAYSTIP | TTS_NOPREFIX,
|
|
CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT,
|
|
m_hWnd, NULL, theApp.GetModuleHandle(), NULL);
|
|
if (hwndTip == NULL)
|
|
return;
|
|
|
|
TOOLINFO toolInfo = { 0 };
|
|
toolInfo.cbSize = tooltipStructSize;
|
|
toolInfo.hwnd = m_hWnd;
|
|
toolInfo.uFlags = TTF_IDISHWND | TTF_SUBCLASS;
|
|
toolInfo.uId = (UINT_PTR)hWnd;
|
|
// Can't directly add the tooltip string - it doesn't work for long messages
|
|
toolInfo.lpszText = LPSTR_TEXTCALLBACK;
|
|
SendMessage(hwndTip, TTM_ADDTOOL, 0, (LPARAM)&toolInfo);
|
|
// 32.767s is the max show time.
|
|
SendMessage(hwndTip, TTM_SETDELAYTIME, TTDT_AUTOPOP, 32767);
|
|
}
|
|
|
|
void GSDialog::InitCommonControls()
|
|
{
|
|
INITCOMMONCONTROLSEX icex;
|
|
icex.dwSize = sizeof(INITCOMMONCONTROLSEX);
|
|
icex.dwICC = ICC_TAB_CLASSES;
|
|
|
|
InitCommonControlsEx(&icex);
|
|
}
|