void OBS::GetProfiles(StringList &profileList) { String strProfilesWildcard; OSFindData ofd; HANDLE hFind; profileList.Clear(); strProfilesWildcard << lpAppDataPath << TEXT("\\profiles\\*.ini"); if(hFind = OSFindFirstFile(strProfilesWildcard, ofd)) { do { if(ofd.bDirectory) continue; profileList << GetPathWithoutExtension(ofd.fileName); } while(OSFindNextFile(hFind, ofd)); OSFindClose(hFind); } }
BOOL CALLBACK OpenModuleDialogProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam) { traceIn(OpenModuleDialogProc); switch(message) { case WM_INITDIALOG: { OSFindData findData; //todo: AppWarning(TEXT("fix this thingy please")); HANDLE hFind = OSFindFirstFile(TEXT("*.xxt"), findData); if(hFind) { do { findData.fileName[slen(findData.fileName)-4] = 0; if(!IsModuleLoaded(findData.fileName)) SendMessage(GetDlgItem(hwnd, IDC_MODULELIST), LB_ADDSTRING, 0, (LPARAM)findData.fileName); }while(OSFindNextFile(hFind, findData)); OSFindClose(hFind); SendMessage(GetDlgItem(hwnd, IDC_MODULELIST), LB_SETCURSEL, 0, 0); SendMessage(GetDlgItem(hwnd, IDC_MODULELIST), EM_LIMITTEXT, 250, 0); } break; } case WM_COMMAND: switch(LOWORD(wParam)) { case IDC_MODULELIST: if(HIWORD(wParam) == LBN_DBLCLK) PostMessage(hwnd, WM_COMMAND, MAKEWPARAM(IDOK, BN_CLICKED), lParam); break; case IDOK: { DWORD dwCurSel = SendMessage(GetDlgItem(hwnd, IDC_MODULELIST), LB_GETCURSEL, 0, 0); if(dwCurSel != LB_ERR) { String strModuleName; strModuleName.SetLength(255); SendMessage(GetDlgItem(hwnd, IDC_MODULELIST), LB_GETTEXT, dwCurSel, (LPARAM)(CTSTR)strModuleName); if(!level->LoadLevelModule(strModuleName)) MessageBox(hwnd, String() << TEXT("Unable to open module '") << strModuleName << TEXT("'."), NULL, MB_OK); else { EndDialog(hwnd, IDOK); UpdateObjectTreeAndModules(); } } else MessageBox(hwnd, TEXT("You need to select a module first"), NULL, MB_OK); break; } case IDCANCEL: EndDialog(hwnd, IDCANCEL); break; } break; case WM_CLOSE: EndDialog(hwnd, IDCANCEL); break; } return FALSE; traceOut; }
INT_PTR SettingsGeneral::ProcMessage(UINT message, WPARAM wParam, LPARAM lParam) { switch(message) { case WM_INITDIALOG: { LocalizeWindow(hwnd); //---------------------------------------------- HWND hwndTemp = GetDlgItem(hwnd, IDC_LANGUAGE); OSFindData ofd; HANDLE hFind; if(hFind = OSFindFirstFile(TEXT("locale/*.txt"), ofd)) { do { if(ofd.bDirectory) continue; 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); } //---------------------------------------------- String strCurProfile = GlobalConfig->GetString(TEXT("General"), TEXT("Profile")); hwndTemp = GetDlgItem(hwnd, IDC_PROFILE); StringList profileList; App->GetProfiles(profileList); for(UINT i=0; i<profileList.Num(); i++) { UINT id = (UINT)SendMessage(hwndTemp, CB_ADDSTRING, 0, (LPARAM)profileList[i].Array()); if(profileList[i].CompareI(strCurProfile)) SendMessage(hwndTemp, CB_SETCURSEL, id, 0); } EnableWindow(hwndTemp, !App->bRunning); EnableWindow(GetDlgItem(hwnd, IDC_ADD), FALSE); EnableWindow(GetDlgItem(hwnd, IDC_RENAME), FALSE); UINT numItems = (UINT)SendMessage(hwndTemp, CB_GETCOUNT, 0, 0); EnableWindow(GetDlgItem(hwnd, IDC_REMOVE), (numItems > 1) && !App->bRunning); //---------------------------------------------- bool bShowNotificationAreaIcon = AppConfig->GetInt(TEXT("General"), TEXT("ShowNotificationAreaIcon"), 0) != 0; SendMessage(GetDlgItem(hwnd, IDC_NOTIFICATIONICON), BM_SETCHECK, bShowNotificationAreaIcon ? BST_CHECKED : BST_UNCHECKED, 0); bool bMinimizeToNotificationArea = AppConfig->GetInt(TEXT("General"), TEXT("MinimizeToNotificationArea"), 0) != 0; SendMessage(GetDlgItem(hwnd, IDC_MINIZENOTIFICATION), BM_SETCHECK, bMinimizeToNotificationArea ? BST_CHECKED : BST_UNCHECKED, 0); //---------------------------------------------- App->bEnableProjectorCursor = GlobalConfig->GetInt(L"General", L"EnableProjectorCursor", 1) != 0; SendMessage(GetDlgItem(hwnd, IDC_ENABLEPROJECTORCURSOR), BM_SETCHECK, App->bEnableProjectorCursor ? BST_CHECKED : BST_UNCHECKED, 0); //---------------------------------------------- bool showLogWindowOnLaunch = GlobalConfig->GetInt(TEXT("General"), TEXT("ShowLogWindowOnLaunch")) != 0; SendMessage(GetDlgItem(hwnd, IDC_SHOWLOGWINDOWONLAUNCH), BM_SETCHECK, showLogWindowOnLaunch ? BST_CHECKED : BST_UNCHECKED, 0); //---------------------------------------------- SetChangedSettings(false); return TRUE; } case WM_COMMAND: switch(LOWORD(wParam)) { case IDC_LANGUAGE: { if(HIWORD(wParam) != CBN_SELCHANGE) break; HWND hwndTemp = (HWND)lParam; SetWindowText(GetDlgItem(hwnd, IDC_INFO), Str("Settings.General.Restart")); ShowWindow(GetDlgItem(hwnd, IDC_INFO), SW_SHOW); SetChangedSettings(true); break; } case IDC_PROFILE: if (App->bRunning) { HWND cb = (HWND)lParam; String curProfile = GlobalConfig->GetString(TEXT("General"), TEXT("Profile")); UINT numItems = (UINT)SendMessage(cb, CB_GETCOUNT, 0, 0); for (UINT i = 0; i < numItems; i++) { if (GetCBText(cb, i).Compare(curProfile)) SendMessage(cb, CB_SETCURSEL, i, 0); } break; } if(HIWORD(wParam) == CBN_EDITCHANGE) { String strText = GetEditText((HWND)lParam).KillSpaces(); EnableWindow(GetDlgItem(hwnd, IDC_REMOVE), FALSE); if(strText.IsValid()) { if(IsValidFileName(strText)) { String strCurProfile = GlobalConfig->GetString(TEXT("General"), TEXT("Profile")); UINT id = (UINT)SendMessage((HWND)lParam, CB_FINDSTRINGEXACT, -1, (LPARAM)strText.Array()); EnableWindow(GetDlgItem(hwnd, IDC_ADD), (id == CB_ERR)); EnableWindow(GetDlgItem(hwnd, IDC_RENAME), (id == CB_ERR) || strCurProfile.CompareI(strText)); ShowWindow(GetDlgItem(hwnd, IDC_INFO), SW_HIDE); break; } SetWindowText(GetDlgItem(hwnd, IDC_INFO), Str("Settings.General.InvalidName")); ShowWindow(GetDlgItem(hwnd, IDC_INFO), SW_SHOW); } else ShowWindow(GetDlgItem(hwnd, IDC_INFO), SW_HIDE); EnableWindow(GetDlgItem(hwnd, IDC_ADD), FALSE); EnableWindow(GetDlgItem(hwnd, IDC_RENAME), FALSE); } else if(HIWORD(wParam) == CBN_SELCHANGE) { EnableWindow(GetDlgItem(hwnd, IDC_ADD), FALSE); EnableWindow(GetDlgItem(hwnd, IDC_RENAME), FALSE); String strProfile = GetCBText((HWND)lParam); String strProfilePath; strProfilePath << lpAppDataPath << TEXT("\\profiles\\") << strProfile << TEXT(".ini"); if(!AppConfig->Open(strProfilePath)) { OBSMessageBox(hwnd, TEXT("Error - unable to open ini file"), NULL, 0); break; } App->ReloadIniSettings(); SetWindowText(GetDlgItem(hwnd, IDC_INFO), Str("Settings.Info")); ShowWindow(GetDlgItem(hwnd, IDC_INFO), SW_SHOW); GlobalConfig->SetString(TEXT("General"), TEXT("Profile"), strProfile); App->ResetProfileMenu(); App->ResetApplicationName(); App->UpdateNotificationAreaIcon(); UINT numItems = (UINT)SendMessage(GetDlgItem(hwnd, IDC_PROFILE), CB_GETCOUNT, 0, 0); EnableWindow(GetDlgItem(hwnd, IDC_REMOVE), (numItems > 1)); App->ResizeWindow(false); } break; case IDC_RENAME: case IDC_ADD: if (App->bRunning) break; if(HIWORD(wParam) == BN_CLICKED) { HWND hwndProfileList = GetDlgItem(hwnd, IDC_PROFILE); String strProfile = GetEditText(hwndProfileList).KillSpaces(); SetWindowText(hwndProfileList, strProfile); if(strProfile.IsEmpty()) break; bool bRenaming = (LOWORD(wParam) == IDC_RENAME); String strCurProfile = GlobalConfig->GetString(TEXT("General"), TEXT("Profile")); String strCurProfilePath; strCurProfilePath << lpAppDataPath << TEXT("\\profiles\\") << strCurProfile << TEXT(".ini"); String strProfilePath; strProfilePath << lpAppDataPath << TEXT("\\profiles\\") << strProfile << TEXT(".ini"); if((!bRenaming || !strProfilePath.CompareI(strCurProfilePath)) && OSFileExists(strProfilePath)) OBSMessageBox(hwnd, Str("Settings.General.ProfileExists"), NULL, 0); else { if(bRenaming) { if(!MoveFile(strCurProfilePath, strProfilePath)) break; AppConfig->SetFilePath(strProfilePath); UINT curID = (UINT)SendMessage(hwndProfileList, CB_FINDSTRINGEXACT, -1, (LPARAM)strCurProfile.Array()); if(curID != CB_ERR) SendMessage(hwndProfileList, CB_DELETESTRING, curID, 0); } else { if(!AppConfig->SaveAs(strProfilePath)) { OBSMessageBox(hwnd, TEXT("Error - unable to create new profile, could not create file"), NULL, 0); break; } } UINT id = (UINT)SendMessage(hwndProfileList, CB_ADDSTRING, 0, (LPARAM)strProfile.Array()); SendMessage(hwndProfileList, CB_SETCURSEL, id, 0); GlobalConfig->SetString(TEXT("General"), TEXT("Profile"), strProfile); UINT numItems = (UINT)SendMessage(hwndProfileList, CB_GETCOUNT, 0, 0); EnableWindow(GetDlgItem(hwnd, IDC_REMOVE), (numItems > 1)); EnableWindow(GetDlgItem(hwnd, IDC_RENAME), FALSE); EnableWindow(GetDlgItem(hwnd, IDC_ADD), FALSE); App->ResetProfileMenu(); App->ResetApplicationName(); } } break; case IDC_REMOVE: if (App->bRunning) break; { HWND hwndProfileList = GetDlgItem(hwnd, IDC_PROFILE); String strCurProfile = GlobalConfig->GetString(TEXT("General"), TEXT("Profile")); UINT numItems = (UINT)SendMessage(hwndProfileList, CB_GETCOUNT, 0, 0); String strConfirm = Str("Settings.General.ConfirmDelete"); strConfirm.FindReplace(TEXT("$1"), strCurProfile); if(OBSMessageBox(hwnd, strConfirm, Str("DeleteConfirm.Title"), MB_YESNO) == IDYES) { UINT id = (UINT)SendMessage(hwndProfileList, CB_FINDSTRINGEXACT, -1, (LPARAM)strCurProfile.Array()); if(id != CB_ERR) { SendMessage(hwndProfileList, CB_DELETESTRING, id, 0); if(id == numItems-1) id--; SendMessage(hwndProfileList, CB_SETCURSEL, id, 0); DialogProc(hwnd, WM_COMMAND, MAKEWPARAM(IDC_PROFILE, CBN_SELCHANGE), (LPARAM)hwndProfileList); String strCurProfilePath; strCurProfilePath << lpAppDataPath << TEXT("\\profiles\\") << strCurProfile << TEXT(".ini"); OSDeleteFile(strCurProfilePath); App->ResetProfileMenu(); } } break; } case IDC_NOTIFICATIONICON: if (SendMessage(GetDlgItem(hwnd, IDC_NOTIFICATIONICON), BM_GETCHECK, 0, 0) == BST_UNCHECKED) { SendMessage(GetDlgItem(hwnd, IDC_MINIZENOTIFICATION), BM_SETCHECK, BST_UNCHECKED, 0); } SetChangedSettings(true); break; case IDC_MINIZENOTIFICATION: if (SendMessage(GetDlgItem(hwnd, IDC_MINIZENOTIFICATION), BM_GETCHECK, 0, 0) == BST_CHECKED) { SendMessage(GetDlgItem(hwnd, IDC_NOTIFICATIONICON), BM_SETCHECK, BST_CHECKED, 0); } SetChangedSettings(true); break; case IDC_ENABLEPROJECTORCURSOR: case IDC_SHOWLOGWINDOWONLAUNCH: SetChangedSettings(true); break; } } return FALSE; }
OBS::OBS() { App = this; __cpuid(cpuInfo, 1); bSSE2Available = (cpuInfo[3] & (1<<26)) != 0; hSceneMutex = OSCreateMutex(); hAuxAudioMutex = OSCreateMutex(); monitors.Clear(); EnumDisplayMonitors(NULL, NULL, (MONITORENUMPROC)MonitorInfoEnumProc, (LPARAM)&monitors); INITCOMMONCONTROLSEX ecce; ecce.dwSize = sizeof(ecce); ecce.dwICC = ICC_STANDARD_CLASSES; if(!InitCommonControlsEx(&ecce)) CrashError(TEXT("Could not initalize common shell controls")); InitHotkeyExControl(hinstMain); InitColorControl(hinstMain); InitVolumeControl(); InitVolumeMeter(); //----------------------------------------------------- // load locale if(!locale->LoadStringFile(TEXT("locale/en.txt"))) AppWarning(TEXT("Could not open locale string file '%s'"), TEXT("locale/en.txt")); strLanguage = GlobalConfig->GetString(TEXT("General"), TEXT("Language"), TEXT("en")); if(!strLanguage.CompareI(TEXT("en"))) { String langFile; langFile << TEXT("locale/") << strLanguage << TEXT(".txt"); if(!locale->LoadStringFile(langFile)) AppWarning(TEXT("Could not open locale string file '%s'"), langFile.Array()); } //----------------------------------------------------- // load classes RegisterSceneClass(TEXT("Scene"), Str("Scene"), (OBSCREATEPROC)CreateNormalScene, NULL); RegisterImageSourceClass(TEXT("DesktopImageSource"), Str("Sources.SoftwareCaptureSource"), (OBSCREATEPROC)CreateDesktopSource, (OBSCONFIGPROC)ConfigureDesktopSource); RegisterImageSourceClass(TEXT("BitmapImageSource"), Str("Sources.BitmapSource"), (OBSCREATEPROC)CreateBitmapSource, (OBSCONFIGPROC)ConfigureBitmapSource); RegisterImageSourceClass(TEXT("BitmapTransitionSource"), Str("Sources.TransitionSource"), (OBSCREATEPROC)CreateBitmapTransitionSource, (OBSCONFIGPROC)ConfigureBitmapTransitionSource); RegisterImageSourceClass(TEXT("GlobalSource"), Str("Sources.GlobalSource"), (OBSCREATEPROC)CreateGlobalSource, (OBSCONFIGPROC)OBS::ConfigGlobalSource); RegisterImageSourceClass(TEXT("TextSource"), Str("Sources.TextSource"), (OBSCREATEPROC)CreateTextSource, (OBSCONFIGPROC)ConfigureTextSource); //----------------------------------------------------- // render frame class WNDCLASS wc; zero(&wc, sizeof(wc)); wc.hInstance = hinstMain; wc.hCursor = LoadCursor(NULL, IDC_ARROW); wc.lpszClassName = OBS_RENDERFRAME_CLASS; wc.lpfnWndProc = (WNDPROC)OBS::RenderFrameProc; wc.hbrBackground = (HBRUSH)GetStockObject(GRAY_BRUSH); if(!RegisterClass(&wc)) CrashError(TEXT("Could not register render frame class")); //----------------------------------------------------- // main window class wc.lpszClassName = OBS_WINDOW_CLASS; wc.lpfnWndProc = (WNDPROC)OBSProc; wc.hIcon = LoadIcon(hinstMain, MAKEINTRESOURCE(IDI_ICON1)); wc.hbrBackground = (HBRUSH)COLOR_WINDOW; wc.lpszMenuName = MAKEINTRESOURCE(IDR_MAINMENU); if(!RegisterClass(&wc)) CrashError(TEXT("Could not register main window class")); //----------------------------------------------------- // create main window int fullscreenX = GetSystemMetrics(SM_CXFULLSCREEN); int fullscreenY = GetSystemMetrics(SM_CYFULLSCREEN); borderXSize = borderYSize = 0; borderXSize += GetSystemMetrics(SM_CXSIZEFRAME)*2; borderYSize += GetSystemMetrics(SM_CYSIZEFRAME)*2; borderYSize += GetSystemMetrics(SM_CYMENU); borderYSize += GetSystemMetrics(SM_CYCAPTION); clientWidth = GlobalConfig->GetInt(TEXT("General"), TEXT("Width"), 700); clientHeight = GlobalConfig->GetInt(TEXT("General"), TEXT("Height"), 553); if(clientWidth < minClientWidth) clientWidth = minClientWidth; if(clientHeight < minClientHeight) clientHeight = minClientHeight; int maxCX = fullscreenX-borderXSize; int maxCY = fullscreenY-borderYSize; if(clientWidth > maxCX) clientWidth = maxCX; if(clientHeight > maxCY) clientHeight = maxCY; int cx = clientWidth + borderXSize; int cy = clientHeight + borderYSize; int x = (fullscreenX/2)-(cx/2); int y = (fullscreenY/2)-(cy/2); int posX = GlobalConfig->GetInt(TEXT("General"), TEXT("PosX")); int posY = GlobalConfig->GetInt(TEXT("General"), TEXT("PosY")); bool bInsideMonitors = false; if(posX || posY) { for(UINT i=0; i<monitors.Num(); i++) { if( posX >= monitors[i].rect.left && posX < monitors[i].rect.right && posY >= monitors[i].rect.top && posY < monitors[i].rect.bottom ) { bInsideMonitors = true; break; } } } if(bInsideMonitors) { x = posX; y = posY; } hwndMain = CreateWindowEx(WS_EX_CONTROLPARENT|WS_EX_WINDOWEDGE, OBS_WINDOW_CLASS, OBS_VERSION_STRING, WS_OVERLAPPED | WS_THICKFRAME | WS_MINIMIZEBOX | WS_CAPTION | WS_SYSMENU | WS_CLIPCHILDREN, x, y, cx, cy, NULL, NULL, hinstMain, NULL); if(!hwndMain) CrashError(TEXT("Could not create main window")); HMENU hMenu = GetMenu(hwndMain); LocalizeMenu(hMenu); //----------------------------------------------------- // render frame hwndRenderFrame = CreateWindow(OBS_RENDERFRAME_CLASS, NULL, WS_CHILDWINDOW|WS_VISIBLE, 0, 0, 0, 0, hwndMain, NULL, hinstMain, NULL); if(!hwndRenderFrame) CrashError(TEXT("Could not create render frame")); //----------------------------------------------------- // scenes listbox HWND hwndTemp; hwndTemp = CreateWindowEx(WS_EX_CLIENTEDGE, TEXT("LISTBOX"), NULL, WS_CHILDWINDOW|WS_VISIBLE|WS_TABSTOP|LBS_HASSTRINGS|WS_VSCROLL|LBS_NOTIFY|LBS_NOINTEGRALHEIGHT|WS_CLIPSIBLINGS, 0, 0, 0, 0, hwndMain, (HMENU)ID_SCENES, 0, 0); SendMessage(hwndTemp, WM_SETFONT, (WPARAM)GetStockObject(DEFAULT_GUI_FONT), TRUE); listboxProc = (WNDPROC)GetWindowLongPtr(hwndTemp, GWLP_WNDPROC); SetWindowLongPtr(hwndTemp, GWLP_WNDPROC, (LONG_PTR)OBS::ListboxHook); //----------------------------------------------------- // elements listview hwndTemp = CreateWindowEx(WS_EX_CLIENTEDGE, WC_LISTVIEW, NULL, WS_CHILDWINDOW|WS_VISIBLE|WS_TABSTOP|WS_VSCROLL|WS_CLIPSIBLINGS|LVS_REPORT|LVS_NOCOLUMNHEADER| LVS_SHOWSELALWAYS | LVS_ALIGNLEFT | LVS_NOLABELWRAP, 0, 0, 0, 0, hwndMain, (HMENU)ID_SOURCES, 0, 0); SendMessage(hwndTemp, WM_SETFONT, (WPARAM)GetStockObject(DEFAULT_GUI_FONT), TRUE); ListView_SetExtendedListViewStyle(hwndTemp, LVS_EX_CHECKBOXES | LVS_EX_FULLROWSELECT | LVS_EX_DOUBLEBUFFER); //add single column needed for report style LVCOLUMN column; column.mask = LVCF_TEXT; column.fmt = LVCFMT_FIXED_WIDTH; column.cx = 0; column.pszText = TEXT(""); ListView_InsertColumn(hwndTemp, 0, &column); ListView_InsertColumn(hwndTemp, 1, &column); listviewProc = (WNDPROC)GetWindowLongPtr(hwndTemp, GWLP_WNDPROC); SetWindowLongPtr(hwndTemp, GWLP_WNDPROC, (LONG_PTR)OBS::ListboxHook); HWND hwndSources = hwndTemp; //----------------------------------------------------- // status control hwndTemp = CreateWindowEx(0, STATUSCLASSNAME, NULL, WS_CHILD|WS_VISIBLE|SBARS_SIZEGRIP|WS_CLIPSIBLINGS, 0, 0, 0, 0, hwndMain, (HMENU)ID_STATUS, 0, 0); SendMessage(hwndTemp, WM_SETFONT, (WPARAM)GetStockObject(DEFAULT_GUI_FONT), TRUE); //----------------------------------------------------- // mic volume control hwndTemp = CreateWindow(VOLUME_CONTROL_CLASS, NULL, WS_CHILDWINDOW|WS_VISIBLE|WS_CLIPSIBLINGS, 0, 0, 0, 0, hwndMain, (HMENU)ID_MICVOLUME, 0, 0); SetVolumeControlIcons(hwndTemp, GetIcon(hinstMain, IDI_SOUND_MIC), GetIcon(hinstMain, IDI_SOUND_MIC_MUTED)); //----------------------------------------------------- // mic volume meter hwndTemp = CreateWindow(VOLUME_METER_CLASS, NULL, WS_CHILDWINDOW|WS_VISIBLE|WS_CLIPSIBLINGS, 0, 0, 0, 0, hwndMain, (HMENU)ID_MICVOLUMEMETER, 0, 0); //----------------------------------------------------- // desktop volume meter hwndTemp = CreateWindow(VOLUME_METER_CLASS, NULL, WS_CHILDWINDOW|WS_VISIBLE|WS_CLIPSIBLINGS, 0, 0, 0, 0, hwndMain, (HMENU)ID_DESKTOPVOLUMEMETER, 0, 0); //----------------------------------------------------- // desktop volume control hwndTemp = CreateWindow(VOLUME_CONTROL_CLASS, NULL, WS_CHILDWINDOW|WS_VISIBLE|WS_CLIPSIBLINGS, 0, 0, 0, 0, hwndMain, (HMENU)ID_DESKTOPVOLUME, 0, 0); SetVolumeControlIcons(hwndTemp, GetIcon(hinstMain, IDI_SOUND_DESKTOP), GetIcon(hinstMain, IDI_SOUND_DESKTOP_MUTED)); //----------------------------------------------------- // settings button hwndTemp = CreateWindow(TEXT("BUTTON"), Str("Settings"), WS_CHILDWINDOW|WS_VISIBLE|WS_TABSTOP|BS_TEXT|BS_PUSHBUTTON|WS_CLIPSIBLINGS, 0, 0, 0, 0, hwndMain, (HMENU)ID_SETTINGS, 0, 0); SendMessage(hwndTemp, WM_SETFONT, (WPARAM)GetStockObject(DEFAULT_GUI_FONT), TRUE); //----------------------------------------------------- // start/stop stream button hwndTemp = CreateWindow(TEXT("BUTTON"), Str("MainWindow.StartStream"), WS_CHILDWINDOW|WS_VISIBLE|WS_TABSTOP|BS_TEXT|BS_PUSHBUTTON|WS_CLIPSIBLINGS, 0, 0, 0, 0, hwndMain, (HMENU)ID_STARTSTOP, 0, 0); SendMessage(hwndTemp, WM_SETFONT, (WPARAM)GetStockObject(DEFAULT_GUI_FONT), TRUE); //----------------------------------------------------- // edit scene button hwndTemp = CreateWindow(TEXT("BUTTON"), Str("MainWindow.SceneEditor"), WS_CHILDWINDOW|WS_VISIBLE|WS_TABSTOP|BS_TEXT|BS_AUTOCHECKBOX|BS_PUSHLIKE|WS_DISABLED|WS_CLIPSIBLINGS, 0, 0, 0, 0, hwndMain, (HMENU)ID_SCENEEDITOR, 0, 0); SendMessage(hwndTemp, WM_SETFONT, (WPARAM)GetStockObject(DEFAULT_GUI_FONT), TRUE); //----------------------------------------------------- // global sources button hwndTemp = CreateWindow(TEXT("BUTTON"), Str("GlobalSources"), WS_CHILDWINDOW|WS_VISIBLE|WS_TABSTOP|BS_TEXT|BS_PUSHBUTTON|WS_CLIPSIBLINGS, 0, 0, 0, 0, hwndMain, (HMENU)ID_GLOBALSOURCES, 0, 0); SendMessage(hwndTemp, WM_SETFONT, (WPARAM)GetStockObject(DEFAULT_GUI_FONT), TRUE); //----------------------------------------------------- // test stream button hwndTemp = CreateWindow(TEXT("BUTTON"), Str("MainWindow.TestStream"), WS_CHILDWINDOW|WS_VISIBLE|WS_TABSTOP|BS_TEXT|BS_PUSHBUTTON|WS_CLIPSIBLINGS, 0, 0, 0, 0, hwndMain, (HMENU)ID_TESTSTREAM, 0, 0); SendMessage(hwndTemp, WM_SETFONT, (WPARAM)GetStockObject(DEFAULT_GUI_FONT), TRUE); //----------------------------------------------------- // plugins button hwndTemp = CreateWindow(TEXT("BUTTON"), Str("MainWindow.Plugins"), WS_CHILDWINDOW|WS_VISIBLE|WS_TABSTOP|BS_TEXT|BS_PUSHBUTTON|WS_CLIPSIBLINGS, 0, 0, 0, 0, hwndMain, (HMENU)ID_PLUGINS, 0, 0); SendMessage(hwndTemp, WM_SETFONT, (WPARAM)GetStockObject(DEFAULT_GUI_FONT), TRUE); //----------------------------------------------------- // dashboard button hwndTemp = CreateWindow(TEXT("BUTTON"), Str("MainWindow.Dashboard"), WS_CHILDWINDOW|WS_VISIBLE|WS_TABSTOP|BS_TEXT|BS_PUSHBUTTON|WS_CLIPSIBLINGS, 0, 0, 0, 0, hwndMain, (HMENU)ID_DASHBOARD, 0, 0); SendMessage(hwndTemp, WM_SETFONT, (WPARAM)GetStockObject(DEFAULT_GUI_FONT), TRUE); //----------------------------------------------------- // exit button hwndTemp = CreateWindow(TEXT("BUTTON"), Str("MainWindow.Exit"), WS_CHILDWINDOW|WS_VISIBLE|WS_TABSTOP|BS_TEXT|BS_PUSHBUTTON|WS_CLIPSIBLINGS, 0, 0, 0, 0, hwndMain, (HMENU)ID_EXIT, 0, 0); SendMessage(hwndTemp, WM_SETFONT, (WPARAM)GetStockObject(DEFAULT_GUI_FONT), TRUE); //----------------------------------------------------- // scenes text hwndTemp = CreateWindow(TEXT("STATIC"), Str("MainWindow.Scenes"), WS_CHILDWINDOW|WS_VISIBLE|WS_CLIPSIBLINGS, 0, 0, 0, 0, hwndMain, (HMENU)ID_SCENES_TEXT, 0, 0); SendMessage(hwndTemp, WM_SETFONT, (WPARAM)GetStockObject(DEFAULT_GUI_FONT), TRUE); //----------------------------------------------------- // scenes text hwndTemp = CreateWindow(TEXT("STATIC"), Str("MainWindow.Sources"), WS_CHILDWINDOW|WS_VISIBLE|WS_CLIPSIBLINGS, 0, 0, 0, 0, hwndMain, (HMENU)ID_SOURCES_TEXT, 0, 0); SendMessage(hwndTemp, WM_SETFONT, (WPARAM)GetStockObject(DEFAULT_GUI_FONT), TRUE); //----------------------------------------------------- // populate scenes hwndTemp = GetDlgItem(hwndMain, ID_SCENES); String strScenesConfig; strScenesConfig << lpAppDataPath << TEXT("\\scenes.xconfig"); if(!scenesConfig.Open(strScenesConfig)) CrashError(TEXT("Could not open '%s'"), strScenesConfig); XElement *scenes = scenesConfig.GetElement(TEXT("scenes")); if(!scenes) scenes = scenesConfig.CreateElement(TEXT("scenes")); UINT numScenes = scenes->NumElements(); if(!numScenes) { XElement *scene = scenes->CreateElement(Str("Scene")); scene->SetString(TEXT("class"), TEXT("Scene")); numScenes++; } for(UINT i=0; i<numScenes; i++) { XElement *scene = scenes->GetElementByID(i); scene->SetString(TEXT("class"), TEXT("Scene")); SendMessage(hwndTemp, LB_ADDSTRING, 0, (LPARAM)scene->GetName()); } //----------------------------------------------------- // populate sources if(numScenes) { String strScene = AppConfig->GetString(TEXT("General"), TEXT("CurrentScene")); int id = (int)SendMessage(hwndTemp, LB_FINDSTRINGEXACT, -1, 0); if(id == LB_ERR) id = 0; SendMessage(hwndTemp, LB_SETCURSEL, (WPARAM)id, 0); SendMessage(hwndMain, WM_COMMAND, MAKEWPARAM(ID_SCENES, LBN_SELCHANGE), (LPARAM)GetDlgItem(hwndMain, ID_SCENES)); } //----------------------------------------------------- hHotkeyMutex = OSCreateMutex(); hInfoMutex = OSCreateMutex(); hStartupShutdownMutex = OSCreateMutex(); //----------------------------------------------------- API = CreateOBSApiInterface(); ResizeWindow(false); ShowWindow(hwndMain, SW_SHOW); // make sure sources listview column widths are as expected after obs window is shown ListView_SetColumnWidth(hwndSources,0,LVSCW_AUTOSIZE_USEHEADER); ListView_SetColumnWidth(hwndSources,1,LVSCW_AUTOSIZE_USEHEADER); //----------------------------------------------------- for(UINT i=0; i<numScenes; i++) { XElement *scene = scenes->GetElementByID(i); DWORD hotkey = scene->GetInt(TEXT("hotkey")); if(hotkey) { SceneHotkeyInfo hotkeyInfo; hotkeyInfo.hotkey = hotkey; hotkeyInfo.scene = scene; hotkeyInfo.hotkeyID = API->CreateHotkey(hotkey, SceneHotkey, 0); if(hotkeyInfo.hotkeyID) sceneHotkeys << hotkeyInfo; } } //----------------------------------------------------- // load plugins OSFindData ofd; HANDLE hFind = OSFindFirstFile(TEXT("plugins/*.dll"), ofd); if(hFind) { do { if(!ofd.bDirectory) //why would someone give a directory a .dll extension in the first place? pranksters. { String strLocation; strLocation << TEXT("plugins/") << ofd.fileName; HMODULE hPlugin = LoadLibrary(strLocation); if(hPlugin) { LOADPLUGINPROC loadPlugin = (LOADPLUGINPROC)GetProcAddress(hPlugin, "LoadPlugin"); if(loadPlugin && loadPlugin()) { PluginInfo *pluginInfo = plugins.CreateNew(); pluginInfo->hModule = hPlugin; pluginInfo->strFile = ofd.fileName; GETPLUGINNAMEPROC getName = (GETPLUGINNAMEPROC)GetProcAddress(hPlugin, "GetPluginName"); CTSTR lpName; if(getName) lpName = getName(); else lpName = TEXT("<unknown>"); //FIXME: log this somewhere else, it comes before the OBS version info and looks weird. //Log(TEXT("Loaded plugin '%s', %s"), lpName, strLocation); } else { Log(TEXT("Failed to initialize plugin %s"), strLocation); FreeLibrary(hPlugin); } } else { Log(TEXT("Failed to load plugin %s, %d"), strLocation, GetLastError()); } } } while (OSFindNextFile(hFind, ofd)); OSFindClose(hFind); } //----------------------------------------------------- ReloadIniSettings(); ResetProfileMenu(); //----------------------------------------------------- bAutoReconnect = AppConfig->GetInt(TEXT("Publish"), TEXT("AutoReconnect"), 1) != 0; reconnectTimeout = AppConfig->GetInt(TEXT("Publish"), TEXT("AutoReconnectTimeout"), 10); if(reconnectTimeout < 5) reconnectTimeout = 5; hHotkeyThread = OSCreateThread((XTHREAD)HotkeyThread, NULL); #ifndef OBS_DISABLE_AUTOUPDATE ULARGE_INTEGER lastUpdateTime; ULARGE_INTEGER currentTime; FILETIME systemTime; lastUpdateTime.QuadPart = GlobalConfig->GetInt(TEXT("General"), TEXT("LastUpdateCheck"), 0); GetSystemTimeAsFileTime(&systemTime); currentTime.LowPart = systemTime.dwLowDateTime; currentTime.HighPart = systemTime.dwHighDateTime; //OBS doesn't support 64 bit ints in the config file, so we have to normalize it to a 32 bit int currentTime.QuadPart /= 10000000; currentTime.QuadPart -= 13000000000; if (currentTime.QuadPart - lastUpdateTime.QuadPart >= 3600) { GlobalConfig->SetInt(TEXT("General"), TEXT("LastUpdateCheck"), (int)currentTime.QuadPart); OSCloseThread(OSCreateThread((XTHREAD)CheckUpdateThread, NULL)); } #endif bRenderViewEnabled = true; if(GlobalConfig->GetInt(TEXT("General"), TEXT("ShowWebrootWarning"), TRUE) && IsWebrootLoaded()) MessageBox(hwndMain, TEXT("Webroot Secureanywhere appears to be active. This product will cause problems with OBS as the security features block OBS from accessing Windows GDI functions. It is highly recommended that you disable Secureanywhere and restart OBS.\r\n\r\nOf course you can always just ignore this message if you want, but it may prevent you from being able to stream certain things. Please do not report any bugs you may encounter if you leave Secureanywhere enabled."), TEXT("Just a slight issue you might want to be aware of"), MB_OK); }