/******************************************************************************** Copyright (C) 2012 Hugh Bailey 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 of the License, 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 this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA. ********************************************************************************/ #include "Main.h" enum SettingsSelection { Settings_General, Settings_Encoding, Settings_Publish, Settings_Video, Settings_Audio, Settings_Hotkeys, }; BOOL CALLBACK MonitorInfoEnumProc(HMONITOR hMonitor, HDC hdcMonitor, LPRECT lprcMonitor, List &monitors); INT_PTR CALLBACK OBS::GeneralSettingsProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam) { switch(message) { case WM_INITDIALOG: { HWND hwndTemp = GetDlgItem(hwnd, IDC_LANGUAGE); OSFindData ofd; HANDLE hFind; if(hFind = OSFindFirstFile(TEXT("locale/*.txt"), ofd)) { do { String langCode = GetPathFileName(ofd.fileName); LocaleNativeName *langInfo = GetLocaleNativeName(langCode); if(langInfo) { UINT id = (UINT)SendMessage(hwndTemp, CB_ADDSTRING, 0, (LPARAM)langInfo->lpNative); SendMessage(hwndTemp, CB_SETITEMDATA, id, (LPARAM)langInfo->lpCode); if(App->strLanguage.CompareI(langCode)) SendMessage(hwndTemp, CB_SETCURSEL, id, 0); } } while(OSFindNextFile(hFind, ofd)); OSFindClose(hFind); } LocalizeWindow(hwnd); App->SetChangedSettings(false); return TRUE; } case WM_COMMAND: switch(LOWORD(wParam)) { case IDC_LANGUAGE: if(HIWORD(wParam) != CBN_SELCHANGE) break; App->SetChangedSettings(true); ShowWindow(GetDlgItem(hwnd, IDC_INFO), SW_SHOW); break; } } return FALSE; } int LoadSettingEditInt(HWND hwnd, CTSTR lpConfigSection, CTSTR lpConfigName, int defVal) { int iLoadVal; if(!AppConfig->HasKey(lpConfigSection, lpConfigName)) { AppConfig->SetInt(lpConfigSection, lpConfigName, defVal); iLoadVal = defVal; } else iLoadVal = AppConfig->GetInt(lpConfigSection, lpConfigName, defVal); SendMessage(hwnd, WM_SETTEXT, 0, (LPARAM)IntString(iLoadVal).Array()); return iLoadVal; } String LoadSettingEditString(HWND hwnd, CTSTR lpConfigSection, CTSTR lpConfigName, CTSTR lpDefault) { String strLoadVal; if(!AppConfig->HasKey(lpConfigSection, lpConfigName)) { if(lpDefault) AppConfig->SetString(lpConfigSection, lpConfigName, lpDefault); strLoadVal = lpDefault; } else strLoadVal = AppConfig->GetString(lpConfigSection, lpConfigName, lpDefault); SendMessage(hwnd, WM_SETTEXT, 0, (LPARAM)strLoadVal.Array()); return strLoadVal; } int LoadSettingComboInt(HWND hwnd, CTSTR lpConfigSection, CTSTR lpConfigName, int defVal, int maxVal) { int curVal = AppConfig->GetInt(lpConfigSection, lpConfigName, defVal); int id = curVal; if(!AppConfig->HasKey(lpConfigSection, lpConfigName) || curVal < 0 || (maxVal != 0 && curVal > maxVal)) { AppConfig->SetInt(lpConfigSection, lpConfigName, defVal); curVal = defVal; } SendMessage(hwnd, CB_SETCURSEL, (WPARAM)id, 0); return curVal; } String LoadSettingComboString(HWND hwnd, CTSTR lpConfigSection, CTSTR lpConfigName, CTSTR lpDefault) { String strVal = AppConfig->GetString(lpConfigSection, lpConfigName, lpDefault); int id = (int)SendMessage(hwnd, CB_FINDSTRINGEXACT, 0, (LPARAM)strVal.Array()); if(!AppConfig->HasKey(lpConfigSection, lpConfigName) || id == CB_ERR) { if(lpDefault) { AppConfig->SetString(lpConfigSection, lpConfigName, lpDefault); if(id == CB_ERR) { id = (int)SendMessage(hwnd, CB_FINDSTRINGEXACT, -1, (LPARAM)lpDefault); strVal = lpDefault; } } else id = 0; } SendMessage(hwnd, CB_SETCURSEL, (WPARAM)id, 0); return strVal; } String LoadSettingTextComboString(HWND hwnd, CTSTR lpConfigSection, CTSTR lpConfigName, CTSTR lpDefault) { String strVal = AppConfig->GetString(lpConfigSection, lpConfigName, lpDefault); int id = (int)SendMessage(hwnd, CB_FINDSTRINGEXACT, -1, (LPARAM)strVal.Array()); if(!AppConfig->HasKey(lpConfigSection, lpConfigName)) { if(lpDefault) AppConfig->SetString(lpConfigSection, lpConfigName, lpDefault); } SendMessage(hwnd, CB_SETCURSEL, (WPARAM)id, 0); return strVal; } CTSTR preset_names[10] = {TEXT("ultrafast"), TEXT("superfast"), TEXT("veryfast"), TEXT("faster"), TEXT("fast"), TEXT("medium"), TEXT("slow"), TEXT("slower"), TEXT("veryslow"), TEXT("placebo")}; INT_PTR CALLBACK OBS::EncoderSettingsProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam) { switch(message) { case WM_INITDIALOG: { HWND hwndTemp; LocalizeWindow(hwnd); //-------------------------------------------- hwndTemp = GetDlgItem(hwnd, IDC_QUALITY); for(int i=0; i<=10; i++) SendMessage(hwndTemp, CB_ADDSTRING, 0, (LPARAM)IntString(i).Array()); LoadSettingComboString(hwndTemp, TEXT("Video Encoding"), TEXT("Quality"), TEXT("8")); //-------------------------------------------- hwndTemp = GetDlgItem(hwnd, IDC_PRESET); for(int i=0; i<10; i++) SendMessage(hwndTemp, CB_ADDSTRING, 0, (LPARAM)preset_names[i]); LoadSettingComboString(hwndTemp, TEXT("Video Encoding"), TEXT("Preset"), TEXT("veryfast")); //-------------------------------------------- LoadSettingEditInt(GetDlgItem(hwnd, IDC_MAXBITRATE), TEXT("Video Encoding"), TEXT("MaxBitrate"), 2000); LoadSettingEditInt(GetDlgItem(hwnd, IDC_BUFFERSIZE), TEXT("Video Encoding"), TEXT("BufferSize"), 1000); //-------------------------------------------- BOOL bUse444 = AppConfig->GetInt(TEXT("Video Encoding"), TEXT("Use444"), 0); SendMessage(GetDlgItem(hwnd, IDC_USEI444), BM_SETCHECK, bUse444 ? BST_CHECKED : 0, 0); //-------------------------------------------- hwndTemp = GetDlgItem(hwnd, IDC_AUDIOCODEC); SendMessage(hwndTemp, CB_ADDSTRING, 0, (LPARAM)TEXT("AAC")); SendMessage(hwndTemp, CB_ADDSTRING, 0, (LPARAM)TEXT("MP3")); LoadSettingComboString(hwndTemp, TEXT("Audio Encoding"), TEXT("Codec"), TEXT("AAC")); //-------------------------------------------- hwndTemp = GetDlgItem(hwnd, IDC_AUDIOBITRATE); SendMessage(hwndTemp, CB_ADDSTRING, 0, (LPARAM)TEXT("48")); SendMessage(hwndTemp, CB_ADDSTRING, 0, (LPARAM)TEXT("64")); SendMessage(hwndTemp, CB_ADDSTRING, 0, (LPARAM)TEXT("96")); SendMessage(hwndTemp, CB_ADDSTRING, 0, (LPARAM)TEXT("128")); SendMessage(hwndTemp, CB_ADDSTRING, 0, (LPARAM)TEXT("192")); SendMessage(hwndTemp, CB_ADDSTRING, 0, (LPARAM)TEXT("256")); SendMessage(hwndTemp, CB_ADDSTRING, 0, (LPARAM)TEXT("320")); LoadSettingComboString(hwndTemp, TEXT("Audio Encoding"), TEXT("Bitrate"), TEXT("96")); //-------------------------------------------- hwndTemp = GetDlgItem(hwnd, IDC_AUDIOFORMAT); SendMessage(hwndTemp, CB_ADDSTRING, 0, (LPARAM)TEXT("44.1khz mono")); SendMessage(hwndTemp, CB_ADDSTRING, 0, (LPARAM)TEXT("44.1khz stereo")); LoadSettingComboInt(hwndTemp, TEXT("Audio Encoding"), TEXT("Format"), 1, 1); //-------------------------------------------- ShowWindow(GetDlgItem(hwnd, IDC_INFO), SW_HIDE); App->SetChangedSettings(false); return TRUE; } case WM_COMMAND: { bool bDataChanged = false; switch(LOWORD(wParam)) { case IDC_QUALITY: case IDC_PRESET: case IDC_AUDIOCODEC: case IDC_AUDIOBITRATE: case IDC_AUDIOFORMAT: if(HIWORD(wParam) == CBN_SELCHANGE) bDataChanged = true; break; case IDC_MAXBITRATE: case IDC_BUFFERSIZE: if(HIWORD(wParam) == EN_CHANGE) bDataChanged = true; break; case IDC_USEI444: if(HIWORD(wParam) == BN_CLICKED) bDataChanged = true; break; } if(bDataChanged) { ShowWindow(GetDlgItem(hwnd, IDC_INFO), SW_SHOW); App->SetChangedSettings(true); } break; } } return FALSE; } enum { PublishMode_LiveStream, PublishMode_Serve, PublishMode_BandwidthInfo }; INT_PTR CALLBACK OBS::PublishSettingsProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam) { HWND hwndTemp; switch(message) { case WM_INITDIALOG: { LocalizeWindow(hwnd); //-------------------------------------------- hwndTemp = GetDlgItem(hwnd, IDC_MODE); SendMessage(hwndTemp, CB_ADDSTRING, 0, (LPARAM)Str("Settings.Publish.Mode.LiveStream")); SendMessage(hwndTemp, CB_ADDSTRING, 0, (LPARAM)Str("Settings.Publish.Mode.Serve")); //SendMessage(hwndTemp, CB_ADDSTRING, 0, (LPARAM)Str("Settings.Publish.Mode.SaveToFile")); int mode = LoadSettingComboInt(hwndTemp, TEXT("Publish"), TEXT("Mode"), 0, 2); //-------------------------------------------- hwndTemp = GetDlgItem(hwnd, IDC_SERVICE); SendMessage(hwndTemp, CB_ADDSTRING, 0, (LPARAM)TEXT("Custom")); UINT numServices = 0; XConfig serverData; if(serverData.Open(TEXT("services.xconfig"))) { XElement *services = serverData.GetElement(TEXT("services")); if(services) { numServices = services->NumElements(); for(UINT i=0; iGetElementByID(i); SendMessage(hwndTemp, CB_ADDSTRING, 0, (LPARAM)service->GetName()); } } } int serviceID = LoadSettingComboInt(hwndTemp, TEXT("Publish"), TEXT("Service"), 1, 0); if(mode != 0) ShowWindow(hwndTemp, SW_HIDE); //-------------------------------------------- /*hwndTemp = GetDlgItem(hwnd, IDC_USERNAME); LoadSettingEditString(hwndTemp, TEXT("Publish"), TEXT("Username"), NULL); if(mode != 0) ShowWindow(hwndTemp, SW_HIDE);*/ hwndTemp = GetDlgItem(hwnd, IDC_CHANNELNAME); LoadSettingEditString(hwndTemp, TEXT("Publish"), TEXT("Channel"), NULL); if(mode != 0) ShowWindow(hwndTemp, SW_HIDE); hwndTemp = GetDlgItem(hwnd, IDC_PLAYPATH); LoadSettingEditString(hwndTemp, TEXT("Publish"), TEXT("PlayPath"), NULL); if(mode != 0) ShowWindow(hwndTemp, SW_HIDE); if(serviceID == 0) //custom { ShowWindow(GetDlgItem(hwnd, IDC_SERVERLIST), SW_HIDE); hwndTemp = GetDlgItem(hwnd, IDC_SERVEREDIT); LoadSettingEditString(hwndTemp, TEXT("Publish"), TEXT("Server"), NULL); } else { ShowWindow(GetDlgItem(hwnd, IDC_SERVEREDIT), SW_HIDE); hwndTemp = GetDlgItem(hwnd, IDC_SERVERLIST); XElement *services = serverData.GetElement(TEXT("services")); if(services) { XElement *service = services->GetElementByID(serviceID-1); if(service) { XElement *servers = service->GetElement(TEXT("servers")); if(servers) { UINT numServers = servers->NumDataItems(); for(UINT i=0; iGetDataItemByID(i); SendMessage(hwndTemp, CB_ADDSTRING, 0, (LPARAM)server->GetName()); } } CTSTR lpDefaultChannel = service->GetString(TEXT("useChannel")); if(lpDefaultChannel) { SendMessage(GetDlgItem(hwnd, IDC_CHANNELNAME), WM_SETTEXT, 0, (LPARAM)lpDefaultChannel); EnableWindow(GetDlgItem(hwnd, IDC_CHANNELNAME), FALSE); } else EnableWindow(GetDlgItem(hwnd, IDC_CHANNELNAME), TRUE); } } LoadSettingComboString(hwndTemp, TEXT("Publish"), TEXT("Server"), NULL); } if(mode != 0) ShowWindow(hwndTemp, SW_HIDE); if(mode != 0) { ShowWindow(GetDlgItem(hwnd, IDC_SERVICE_STATIC), SW_HIDE); //ShowWindow(GetDlgItem(hwnd, IDC_USERNAME_STATIC), SW_HIDE); ShowWindow(GetDlgItem(hwnd, IDC_PLAYPATH_STATIC), SW_HIDE); ShowWindow(GetDlgItem(hwnd, IDC_CHANNELNAME_STATIC), SW_HIDE); ShowWindow(GetDlgItem(hwnd, IDC_SERVER_STATIC), SW_HIDE); } ShowWindow(GetDlgItem(hwnd, IDC_INFO), SW_HIDE); App->SetChangedSettings(false); return TRUE; } case WM_COMMAND: { bool bDataChanged = false; switch(LOWORD(wParam)) { case IDC_MODE: { if(HIWORD(wParam) != CBN_SELCHANGE) break; int mode = (int)SendMessage((HWND)lParam, CB_GETCURSEL, 0, 0); int swShowControls = (mode == 0) ? SW_SHOW : SW_HIDE; ShowWindow(GetDlgItem(hwnd, IDC_SERVICE), swShowControls); //ShowWindow(GetDlgItem(hwnd, IDC_USERNAME), swShowControls); ShowWindow(GetDlgItem(hwnd, IDC_PLAYPATH), swShowControls); ShowWindow(GetDlgItem(hwnd, IDC_CHANNELNAME), swShowControls); int serviceID = (int)SendMessage(GetDlgItem(hwnd, IDC_SERVICE), CB_GETCURSEL, 0, 0); if(serviceID == 0) { ShowWindow(GetDlgItem(hwnd, IDC_SERVERLIST), SW_HIDE); ShowWindow(GetDlgItem(hwnd, IDC_SERVEREDIT), swShowControls); } else { ShowWindow(GetDlgItem(hwnd, IDC_SERVERLIST), swShowControls); ShowWindow(GetDlgItem(hwnd, IDC_SERVEREDIT), SW_HIDE); } ShowWindow(GetDlgItem(hwnd, IDC_SERVICE_STATIC), swShowControls); //ShowWindow(GetDlgItem(hwnd, IDC_USERNAME_STATIC), swShowControls); ShowWindow(GetDlgItem(hwnd, IDC_PLAYPATH_STATIC), swShowControls); ShowWindow(GetDlgItem(hwnd, IDC_CHANNELNAME_STATIC), swShowControls); ShowWindow(GetDlgItem(hwnd, IDC_SERVER_STATIC), swShowControls); bDataChanged = true; break; } case IDC_SERVICE: if(HIWORD(wParam) == CBN_SELCHANGE) { int serviceID = (int)SendMessage((HWND)lParam, CB_GETCURSEL, 0, 0); if(serviceID == 0) { ShowWindow(GetDlgItem(hwnd, IDC_SERVERLIST), SW_HIDE); ShowWindow(GetDlgItem(hwnd, IDC_SERVEREDIT), SW_SHOW); SetWindowText(GetDlgItem(hwnd, IDC_CHANNELNAME), NULL); SetWindowText(GetDlgItem(hwnd, IDC_SERVEREDIT), NULL); EnableWindow(GetDlgItem(hwnd, IDC_CHANNELNAME), TRUE); } else { ShowWindow(GetDlgItem(hwnd, IDC_SERVEREDIT), SW_HIDE); hwndTemp = GetDlgItem(hwnd, IDC_SERVERLIST); ShowWindow(hwndTemp, SW_SHOW); SendMessage(hwndTemp, CB_RESETCONTENT, 0, 0); XConfig serverData; if(serverData.Open(TEXT("services.xconfig"))) { XElement *services = serverData.GetElement(TEXT("services")); if(services) { XElement *service = services->GetElementByID(serviceID-1); if(service) { XElement *servers = service->GetElement(TEXT("servers")); if(servers) { UINT numServers = servers->NumDataItems(); for(UINT i=0; iGetDataItemByID(i); SendMessage(hwndTemp, CB_ADDSTRING, 0, (LPARAM)server->GetName()); } } CTSTR lpDefaultChannel = service->GetString(TEXT("useChannel")); if(lpDefaultChannel) { SendMessage(GetDlgItem(hwnd, IDC_CHANNELNAME), WM_SETTEXT, 0, (LPARAM)lpDefaultChannel); EnableWindow(GetDlgItem(hwnd, IDC_CHANNELNAME), FALSE); } else EnableWindow(GetDlgItem(hwnd, IDC_CHANNELNAME), TRUE); } } } SendMessage(hwndTemp, CB_SETCURSEL, 0, 0); } SetWindowText(GetDlgItem(hwnd, IDC_PLAYPATH), NULL); //SetWindowText(GetDlgItem(hwnd, IDC_USERNAME), NULL); bDataChanged = true; } break; //case IDC_USERNAME: case IDC_PLAYPATH: case IDC_CHANNELNAME: case IDC_SERVEREDIT: if(HIWORD(wParam) == EN_CHANGE) bDataChanged = true; break; case IDC_SERVERLIST: if(HIWORD(wParam) == CBN_EDITCHANGE || HIWORD(wParam) == CBN_SELCHANGE) bDataChanged = true; break; } if(bDataChanged) { ShowWindow(GetDlgItem(hwnd, IDC_INFO), SW_SHOW); App->SetChangedSettings(true); } break; } } return FALSE; } const int multiplierCount = 5; const float downscaleMultipliers[multiplierCount] = {1.0f, 1.5f, 2.0f, 2.25f, 3.0f}; void OBS::RefreshDownscales(HWND hwnd, int cx, int cy) { int lastID = (int)SendMessage(hwnd, CB_GETCURSEL, 0, 0); SendMessage(hwnd, CB_RESETCONTENT, 0, 0); float downscale = AppConfig->GetFloat(TEXT("Video"), TEXT("Downscale")); bool bFoundVal = false; for(int i=0; iSetFloat(TEXT("Video"), TEXT("Downscale"), 1.0f); if(lastID == CB_ERR) SendMessage(hwnd, CB_SETCURSEL, 0, 0); SetChangedSettings(true); } if(lastID != CB_ERR) SendMessage(hwnd, CB_SETCURSEL, lastID, 0); } FARPROC editProc = NULL; LRESULT WINAPI ResolutionEditSubclassProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam) { if( ((message == WM_KEYDOWN) && (wParam == VK_RETURN)) || (message == WM_KILLFOCUS) ) { String strText = GetEditText(hwnd); if(ValidIntString(strText)) { int iVal = strText.ToInt(); if(iVal < 128) strText = TEXT("128"); else if(iVal > 4096) strText = TEXT("4096"); else return CallWindowProc((WNDPROC)editProc, hwnd, message, wParam, lParam); } else strText = TEXT("128"); SetWindowText(hwnd, strText); } return CallWindowProc((WNDPROC)editProc, hwnd, message, wParam, lParam); } INT_PTR CALLBACK OBS::VideoSettingsProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam) { HWND hwndTemp; switch(message) { case WM_INITDIALOG: { LocalizeWindow(hwnd); //-------------------------------------------- hwndTemp = GetDlgItem(hwnd, IDC_MONITOR); App->monitors.Clear(); EnumDisplayMonitors(NULL, NULL, (MONITORENUMPROC)MonitorInfoEnumProc, (LPARAM)&App->monitors); for(UINT i=0; imonitors.Num(); i++) SendMessage(hwndTemp, CB_ADDSTRING, 0, (LPARAM)IntString(i+1).Array()); int monitorID = LoadSettingComboInt(hwndTemp, TEXT("Video"), TEXT("Monitor"), 0, App->monitors.Num()-1); //-------------------------------------------- SendMessage(GetDlgItem(hwnd, IDC_USECUSTOM), BM_SETCHECK, BST_CHECKED, 0); EnableWindow(GetDlgItem(hwnd, IDC_MONITOR), FALSE); //-------------------------------------------- int cx, cy; if(!AppConfig->HasKey(TEXT("Video"), TEXT("BaseWidth")) || !AppConfig->HasKey(TEXT("Video"), TEXT("BaseHeight"))) { cx = App->monitors[monitorID].rect.right - App->monitors[monitorID].rect.left; cy = App->monitors[monitorID].rect.bottom - App->monitors[monitorID].rect.top; AppConfig->SetInt(TEXT("Video"), TEXT("BaseWidth"), cx); AppConfig->SetInt(TEXT("Video"), TEXT("BaseHeight"), cy); } else { cx = AppConfig->GetInt(TEXT("Video"), TEXT("BaseWidth")); cy = AppConfig->GetInt(TEXT("Video"), TEXT("BaseHeight")); if(cx < 128) cx = 128; else if(cx > 4096) cx = 4096; if(cy < 128) cy = 128; else if(cy > 4096) cy = 4096; } hwndTemp = GetDlgItem(hwnd, IDC_SIZEX); editProc = (FARPROC)GetWindowLongPtr(hwndTemp, GWLP_WNDPROC); SetWindowLongPtr(hwndTemp, GWLP_WNDPROC, (LONG_PTR)ResolutionEditSubclassProc); SetWindowText(hwndTemp, IntString(cx).Array()); hwndTemp = GetDlgItem(hwnd, IDC_SIZEY); SetWindowLongPtr(hwndTemp, GWLP_WNDPROC, (LONG_PTR)ResolutionEditSubclassProc); SetWindowText(hwndTemp, IntString(cy).Array()); //-------------------------------------------- BOOL bDisableAero = AppConfig->GetInt(TEXT("Video"), TEXT("DisableAero"), 0); SendMessage(GetDlgItem(hwnd, IDC_DISABLEAERO), BM_SETCHECK, bDisableAero ? BST_CHECKED : 0, 0); //-------------------------------------------- hwndTemp = GetDlgItem(hwnd, IDC_FPS); SendMessage(hwndTemp, UDM_SETRANGE32, 5, 60); int fps = AppConfig->GetInt(TEXT("Video"), TEXT("FPS"), 25); if(!AppConfig->HasKey(TEXT("Video"), TEXT("FPS")) || fps < 5 || fps > 60) { AppConfig->SetInt(TEXT("Video"), TEXT("FPS"), 25); fps = 25; } SendMessage(hwndTemp, UDM_SETPOS32, 0, fps); //-------------------------------------------- App->RefreshDownscales(GetDlgItem(hwnd, IDC_DOWNSCALE), cx, cy); //-------------------------------------------- ShowWindow(GetDlgItem(hwnd, IDC_INFO), SW_HIDE); App->SetChangedSettings(false); return TRUE; } case WM_COMMAND: { bool bDataChanged = false; switch(LOWORD(wParam)) { case IDC_MONITOR: { if(HIWORD(wParam) != CBN_SELCHANGE) break; int sel = (int)SendMessage(GetDlgItem(hwnd, IDC_MONITOR), CB_GETCURSEL, 0, 0); if(sel != CB_ERR) { MonitorInfo &monitor = App->monitors[sel]; int cx, cy; cx = monitor.rect.right - monitor.rect.left; cy = monitor.rect.bottom - monitor.rect.top; SetWindowText(GetDlgItem(hwnd, IDC_SIZEX), IntString(cx).Array()); SetWindowText(GetDlgItem(hwnd, IDC_SIZEY), IntString(cy).Array()); } break; } case IDC_USECUSTOM: SendMessage(GetDlgItem(hwnd, IDC_SIZEX), EM_SETREADONLY, FALSE, 0); SendMessage(GetDlgItem(hwnd, IDC_SIZEY), EM_SETREADONLY, FALSE, 0); EnableWindow(GetDlgItem(hwnd, IDC_MONITOR), FALSE); break; case IDC_USEMONITOR: { SendMessage(GetDlgItem(hwnd, IDC_SIZEX), EM_SETREADONLY, TRUE, 0); SendMessage(GetDlgItem(hwnd, IDC_SIZEY), EM_SETREADONLY, TRUE, 0); EnableWindow(GetDlgItem(hwnd, IDC_MONITOR), TRUE); int sel = (int)SendMessage(GetDlgItem(hwnd, IDC_MONITOR), CB_GETCURSEL, 0, 0); if(sel != CB_ERR) { MonitorInfo &monitor = App->monitors[sel]; int cx, cy; cx = monitor.rect.right - monitor.rect.left; cy = monitor.rect.bottom - monitor.rect.top; SetWindowText(GetDlgItem(hwnd, IDC_SIZEX), IntString(cx).Array()); SetWindowText(GetDlgItem(hwnd, IDC_SIZEY), IntString(cy).Array()); } break; } case IDC_SIZEX: case IDC_SIZEY: { if(HIWORD(wParam) != EN_CHANGE) break; String strInt = GetEditText((HWND)lParam); int iVal = strInt.ToInt(); int cx = GetEditText(GetDlgItem(hwnd, IDC_SIZEX)).ToInt(); int cy = GetEditText(GetDlgItem(hwnd, IDC_SIZEY)).ToInt(); if(cx < 128) cx = 128; else if(cx > 4096) cx = 4096; if(cy < 128) cy = 128; else if(cy > 4096) cy = 4096; App->RefreshDownscales(GetDlgItem(hwnd, IDC_DOWNSCALE), cx, cy); bDataChanged = true; break; } case IDC_DISABLEAERO: if(HIWORD(wParam) == BN_CLICKED) bDataChanged = true; break; case IDC_FPS_EDIT: if(HIWORD(wParam) == EN_CHANGE) bDataChanged = true; break; case IDC_DOWNSCALE: if(HIWORD(wParam) == CBN_SELCHANGE) bDataChanged = true; break; } if(bDataChanged) { ShowWindow(GetDlgItem(hwnd, IDC_INFO), SW_SHOW); App->SetChangedSettings(true); } break; } } return FALSE; } INT_PTR CALLBACK OBS::AudioSettingsProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam) { switch(message) { case WM_INITDIALOG: { LocalizeWindow(hwnd); //-------------------------------------------- AudioDeviceList *audioDevices = new AudioDeviceList; GetAudioDevices(*audioDevices); HWND hwndTemp = GetDlgItem(hwnd, IDC_MICDEVICES); for(UINT i=0; idevices.Num(); i++) SendMessage(hwndTemp, CB_ADDSTRING, 0, (LPARAM)audioDevices->devices[i].strName.Array()); String strDeviceID = AppConfig->GetString(TEXT("Audio"), TEXT("Device"), audioDevices->devices[0].strID); UINT iDevice; for(iDevice=0; iDevicedevices.Num(); iDevice++) { if(audioDevices->devices[iDevice].strID == strDeviceID) { SendMessage(hwndTemp, CB_SETCURSEL, iDevice, 0); break; } } if(iDevice == audioDevices->devices.Num()) { AppConfig->SetString(TEXT("Audio"), TEXT("Device"), audioDevices->devices[0].strID); SendMessage(hwndTemp, CB_SETCURSEL, 0, 0); } SetWindowLongPtr(hwnd, DWLP_USER, (LONG_PTR)audioDevices); return TRUE; } case WM_DESTROY: { AudioDeviceList *audioDevices = (AudioDeviceList*)GetWindowLongPtr(hwnd, DWLP_USER); delete audioDevices; } case WM_COMMAND: { bool bDataChanged = false; switch(LOWORD(wParam)) { case IDC_MICDEVICES: if(HIWORD(wParam) == CBN_SELCHANGE) bDataChanged = true; break; } if(bDataChanged) { ShowWindow(GetDlgItem(hwnd, IDC_INFO), SW_SHOW); App->SetChangedSettings(true); } break; } } return FALSE; } INT_PTR CALLBACK OBS::HotkeysSettingsProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam) { switch(message) { case WM_INITDIALOG: LocalizeWindow(hwnd); App->SetChangedSettings(false); return TRUE; } return FALSE; } void OBS::ApplySettings() { HWND hwndTemp; switch(curSettingsSelection) { case Settings_General: { hwndTemp = GetDlgItem(hwndCurrentSettings, IDC_LANGUAGE); int curSel = (int)SendMessage(hwndTemp, CB_GETCURSEL, 0, 0); if(curSel != CB_ERR) { String strLanguageCode = (CTSTR)SendMessage(hwndTemp, CB_GETITEMDATA, curSel, 0); AppConfig->SetString(TEXT("General"), TEXT("Language"), strLanguageCode); } break; } case Settings_Encoding: { int quality = (int)SendMessage(GetDlgItem(hwndCurrentSettings, IDC_QUALITY), CB_GETCURSEL, 0, 0); if(quality != CB_ERR) AppConfig->SetInt(TEXT("Video Encoding"), TEXT("Quality"), quality); String strTemp = GetCBText(GetDlgItem(hwndCurrentSettings, IDC_PRESET)); AppConfig->SetString(TEXT("Video Encoding"), TEXT("Preset"), strTemp); UINT bitrate = GetEditText(GetDlgItem(hwndCurrentSettings, IDC_MAXBITRATE)).ToInt(); if(bitrate < 100) bitrate = 100; AppConfig->SetInt(TEXT("Video Encoding"), TEXT("MaxBitrate"), bitrate); UINT bufSize = GetEditText(GetDlgItem(hwndCurrentSettings, IDC_BUFFERSIZE)).ToInt(); if(bufSize < 100) bitrate = bufSize; AppConfig->SetInt(TEXT("Video Encoding"), TEXT("BufferSize"), bufSize); BOOL bUse444 = SendMessage(GetDlgItem(hwndCurrentSettings, IDC_USEI444), BM_GETCHECK, 0, 0) == BST_CHECKED; AppConfig->SetInt(TEXT("Video Encoding"), TEXT("Use444"), bUse444); strTemp = GetCBText(GetDlgItem(hwndCurrentSettings, IDC_AUDIOCODEC)); AppConfig->SetString(TEXT("Audio Encoding"), TEXT("Codec"), strTemp); strTemp = GetCBText(GetDlgItem(hwndCurrentSettings, IDC_AUDIOBITRATE)); AppConfig->SetString(TEXT("Audio Encoding"), TEXT("Bitrate"), strTemp); int curSel = (int)SendMessage(GetDlgItem(hwndCurrentSettings, IDC_AUDIOFORMAT), CB_GETCURSEL, 0, 0); if(curSel != CB_ERR) AppConfig->SetInt(TEXT("Audio Encoding"), TEXT("Format"), curSel); break; } case Settings_Publish: { int curSel = (int)SendMessage(GetDlgItem(hwndCurrentSettings, IDC_MODE), CB_GETCURSEL, 0, 0); if(curSel != CB_ERR) AppConfig->SetInt(TEXT("Publish"), TEXT("Mode"), curSel); int serviceID = (int)SendMessage(GetDlgItem(hwndCurrentSettings, IDC_SERVICE), CB_GETCURSEL, 0, 0); if(serviceID != CB_ERR) AppConfig->SetInt(TEXT("Publish"), TEXT("Service"), serviceID); /*String strTemp = GetEditText(GetDlgItem(hwndCurrentSettings, IDC_USERNAME)); AppConfig->SetString(TEXT("Publish"), TEXT("Username"), strTemp);*/ String strTemp = GetEditText(GetDlgItem(hwndCurrentSettings, IDC_CHANNELNAME)); AppConfig->SetString(TEXT("Publish"), TEXT("Channel"), strTemp); strTemp = GetEditText(GetDlgItem(hwndCurrentSettings, IDC_PLAYPATH)); AppConfig->SetString(TEXT("Publish"), TEXT("PlayPath"), strTemp); if(serviceID == 0) { strTemp = GetEditText(GetDlgItem(hwndCurrentSettings, IDC_SERVEREDIT)); AppConfig->SetString(TEXT("Publish"), TEXT("Server"), strTemp); } else { strTemp = GetCBText(GetDlgItem(hwndCurrentSettings, IDC_SERVERLIST)); AppConfig->SetString(TEXT("Publish"), TEXT("Server"), strTemp); } break; } case Settings_Video: { int curSel = (int)SendMessage(GetDlgItem(hwndCurrentSettings, IDC_MONITOR), CB_GETCURSEL, 0, 0); if(curSel != CB_ERR) AppConfig->SetInt(TEXT("Video"), TEXT("Monitor"), curSel); int iVal = GetEditText(GetDlgItem(hwndCurrentSettings, IDC_SIZEX)).ToInt(); if(iVal >= 128) AppConfig->SetInt(TEXT("Video"), TEXT("BaseWidth"), iVal); iVal = GetEditText(GetDlgItem(hwndCurrentSettings, IDC_SIZEY)).ToInt(); if(iVal >= 128) AppConfig->SetInt(TEXT("Video"), TEXT("BaseHeight"), iVal); BOOL bDisableAero = SendMessage(GetDlgItem(hwndCurrentSettings, IDC_DISABLEAERO), BM_GETCHECK, 0, 0) == BST_CHECKED ? TRUE : FALSE; AppConfig->SetInt(TEXT("Video"), TEXT("DisableAero"), bDisableAero); BOOL bFailed; int fps = (int)SendMessage(GetDlgItem(hwndCurrentSettings, IDC_FPS), UDM_GETPOS32, 0, (LPARAM)&bFailed); AppConfig->SetInt(TEXT("Video"), TEXT("FPS"), (bFailed) ? 25 : fps); curSel = (int)SendMessage(GetDlgItem(hwndCurrentSettings, IDC_DOWNSCALE), CB_GETCURSEL, 0, 0); if(curSel != CB_ERR) AppConfig->SetFloat(TEXT("Video"), TEXT("Downscale"), downscaleMultipliers[curSel]); if(!bRunning) ResizeWindow(false); break; } case Settings_Audio: { AudioDeviceList *audioDevices = (AudioDeviceList*)GetWindowLongPtr(hwndCurrentSettings, DWLP_USER); UINT iDevice = (UINT)SendMessage(GetDlgItem(hwndCurrentSettings, IDC_MICDEVICES), CB_GETCURSEL, 0, 0); String strDevice; if(iDevice == CB_ERR) strDevice = TEXT("Disable"); else strDevice = audioDevices->devices[iDevice].strID; AppConfig->SetString(TEXT("Audio"), TEXT("Device"), strDevice); if(strDevice.CompareI(TEXT("Disable"))) EnableWindow(GetDlgItem(hwndMain, ID_MICVOLUME), FALSE); else EnableWindow(GetDlgItem(hwndMain, ID_MICVOLUME), TRUE); break; } case Settings_Hotkeys: { break; } } bSettingsChanged = false; EnableWindow(GetDlgItem(hwndSettings, IDC_APPLY), FALSE); } INT_PTR CALLBACK OBS::SettingsDialogProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam) { switch(message) { case WM_INITDIALOG: { App->hwndSettings = hwnd; LocalizeWindow(hwnd); SendMessage(GetDlgItem(hwnd, IDC_SETTINGSLIST), LB_ADDSTRING, 0, (LPARAM)Str("Settings.General")); SendMessage(GetDlgItem(hwnd, IDC_SETTINGSLIST), LB_ADDSTRING, 0, (LPARAM)Str("Settings.Encoding")); SendMessage(GetDlgItem(hwnd, IDC_SETTINGSLIST), LB_ADDSTRING, 0, (LPARAM)Str("Settings.Publish")); SendMessage(GetDlgItem(hwnd, IDC_SETTINGSLIST), LB_ADDSTRING, 0, (LPARAM)Str("Settings.Video")); SendMessage(GetDlgItem(hwnd, IDC_SETTINGSLIST), LB_ADDSTRING, 0, (LPARAM)Str("Settings.Audio")); //SendMessage(GetDlgItem(hwnd, IDC_SETTINGSLIST), LB_ADDSTRING, 0, (LPARAM)Str("Settings.Hotkeys")); RECT subDialogRect; GetWindowRect(GetDlgItem(hwnd, IDC_SUBDIALOG), &subDialogRect); ScreenToClient(hwnd, (LPPOINT)&subDialogRect.left); SendMessage(GetDlgItem(hwnd, IDC_SETTINGSLIST), LB_SETCURSEL, 0, 0); App->curSettingsSelection = 0; App->hwndCurrentSettings = CreateDialog(hinstMain, MAKEINTRESOURCE(IDD_SETTINGS_GENERAL), hwnd, (DLGPROC)OBS::GeneralSettingsProc); SetWindowPos(App->hwndCurrentSettings, NULL, subDialogRect.left, subDialogRect.top, 0, 0, SWP_NOSIZE); ShowWindow(App->hwndCurrentSettings, SW_SHOW); return TRUE; } case WM_COMMAND: switch(LOWORD(wParam)) { case IDC_SETTINGSLIST: { if(HIWORD(wParam) != LBN_SELCHANGE) break; int sel = (int)SendMessage((HWND)lParam, LB_GETCURSEL, 0, 0); if(sel == App->curSettingsSelection) break; else if(App->bSettingsChanged) { int id = MessageBox(hwnd, Str("Settings.SaveChangesPrompt"), Str("Settings.SaveChangesTitle"), MB_YESNOCANCEL); if(id == IDCANCEL) { SendMessage((HWND)lParam, LB_SETCURSEL, App->curSettingsSelection, 0); break; } else if(id == IDYES) App->ApplySettings(); } App->curSettingsSelection = sel; DestroyWindow(App->hwndCurrentSettings); App->hwndCurrentSettings = NULL; RECT subDialogRect; GetWindowRect(GetDlgItem(hwnd, IDC_SUBDIALOG), &subDialogRect); ScreenToClient(hwnd, (LPPOINT)&subDialogRect.left); switch(sel) { case Settings_General: App->hwndCurrentSettings = CreateDialog(hinstMain, MAKEINTRESOURCE(IDD_SETTINGS_GENERAL), hwnd, (DLGPROC)OBS::GeneralSettingsProc); break; case Settings_Encoding: App->hwndCurrentSettings = CreateDialog(hinstMain, MAKEINTRESOURCE(IDD_SETTINGS_ENCODING), hwnd, (DLGPROC)OBS::EncoderSettingsProc); break; case Settings_Publish: App->hwndCurrentSettings = CreateDialog(hinstMain, MAKEINTRESOURCE(IDD_SETTINGS_PUBLISH), hwnd, (DLGPROC)OBS::PublishSettingsProc); break; case Settings_Video: App->hwndCurrentSettings = CreateDialog(hinstMain, MAKEINTRESOURCE(IDD_SETTINGS_VIDEO), hwnd, (DLGPROC)OBS::VideoSettingsProc); break; case Settings_Audio: App->hwndCurrentSettings = CreateDialog(hinstMain, MAKEINTRESOURCE(IDD_SETTINGS_AUDIO), hwnd, (DLGPROC)OBS::AudioSettingsProc); break; case Settings_Hotkeys: break; } if(App->hwndCurrentSettings) { SetWindowPos(App->hwndCurrentSettings, NULL, subDialogRect.left, subDialogRect.top, 0, 0, SWP_NOSIZE); ShowWindow(App->hwndCurrentSettings, SW_SHOW); } break; } case IDOK: if(App->bSettingsChanged) App->ApplySettings(); EndDialog(hwnd, IDOK); App->hwndSettings = NULL; break; case IDCANCEL: EndDialog(hwnd, IDCANCEL); App->hwndSettings = NULL; break; case IDC_APPLY: if(App->bSettingsChanged) App->ApplySettings(); break; } break; } return FALSE; }