Added the project scenesw: The OBS Scene Switcher.

Includes changes to rundir:
- Copying the dll file.
- English locale.

Includes scenesw in the installer.
master
Eric Bataille 2015-02-24 23:35:44 +01:00 committed by Richard Stanway
parent 88b1ebc810
commit 9a9639a2f4
18 changed files with 1376 additions and 0 deletions

View File

@ -59,6 +59,11 @@ Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "ObsNvenc", "ObsNvenc\ObsNve
EndProject
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "libMinHook", "minhook\build\libMinHook.vcxproj", "{65021938-D251-46FA-BC3D-85C385D4C06D}"
EndProject
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "scenesw", "scenesw\scenesw.vcxproj", "{6AC307E3-7D59-4DB2-944F-961E299F063A}"
ProjectSection(ProjectDependencies) = postProject
{11A35235-DD48-41E2-8F40-825C78024BC0} = {11A35235-DD48-41E2-8F40-825C78024BC0}
EndProjectSection
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Win32 = Debug|Win32
@ -187,6 +192,14 @@ Global
{65021938-D251-46FA-BC3D-85C385D4C06D}.Release|Win32.Build.0 = Release|Win32
{65021938-D251-46FA-BC3D-85C385D4C06D}.Release|x64.ActiveCfg = Release|x64
{65021938-D251-46FA-BC3D-85C385D4C06D}.Release|x64.Build.0 = Release|x64
{6AC307E3-7D59-4DB2-944F-961E299F063A}.Debug|Win32.ActiveCfg = Debug|Win32
{6AC307E3-7D59-4DB2-944F-961E299F063A}.Debug|Win32.Build.0 = Debug|Win32
{6AC307E3-7D59-4DB2-944F-961E299F063A}.Debug|x64.ActiveCfg = Debug|x64
{6AC307E3-7D59-4DB2-944F-961E299F063A}.Debug|x64.Build.0 = Debug|x64
{6AC307E3-7D59-4DB2-944F-961E299F063A}.Release|Win32.ActiveCfg = Release|Win32
{6AC307E3-7D59-4DB2-944F-961E299F063A}.Release|Win32.Build.0 = Release|Win32
{6AC307E3-7D59-4DB2-944F-961E299F063A}.Release|x64.ActiveCfg = Release|x64
{6AC307E3-7D59-4DB2-944F-961E299F063A}.Release|x64.Build.0 = Release|x64
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE

View File

@ -9,6 +9,8 @@ mkdir 32bit\plugins\DShowPlugin\shaders
mkdir 32bit\plugins\GraphicsCapture
mkdir 32bit\plugins\PSVPlugin
mkdir 32bit\plugins\PSVPlugin\locale
mkdir 32bit\plugins\scenesw
mkdir 32bit\plugins\scenesw\locale
mkdir 64bit
mkdir 64bit\locale
@ -20,6 +22,8 @@ mkdir 64bit\plugins\DShowPlugin\shaders
mkdir 64bit\plugins\GraphicsCapture
mkdir 64bit\plugins\PSVPlugin
mkdir 64bit\plugins\PSVPlugin\locale
mkdir 64bit\plugins\scenesw
mkdir 64bit\plugins\scenesw\locale
mkdir pdbs
mkdir pdbs\32bit
@ -35,9 +39,11 @@ copy ..\rundir\shaders\*.?Shader .\32bit\shaders\
copy ..\dshowplugin\release\dshowplugin.dll .\32bit\plugins
copy ..\noisegate\release\noisegate.dll .\32bit\plugins
copy ..\psvplugin\release\psvplugin.dll .\32bit\plugins
copy ..\scenesw\release\scenesw.dll .\32bit\plugins
copy ..\rundir\plugins\dshowplugin\locale\*.txt .\32bit\plugins\dshowplugin\locale\
copy ..\rundir\plugins\dshowplugin\shaders\*.?Shader .\32bit\plugins\dshowplugin\shaders\
copy ..\rundir\plugins\psvplugin\locale\*.txt .\32bit\plugins\psvplugin\locale\
copy ..\rundir\plugins\scenesw\locale\*.txt .\32bit\plugins\scenesw\locale\
copy ..\graphicscapture\release\graphicscapture.dll .\32bit\plugins
copy ..\graphicscapture\graphicscapturehook\release\graphicscapturehook.dll .\32bit\plugins\graphicscapture
copy ..\graphicscapture\graphicscapturehook\x64\release\graphicscapturehook64.dll .\32bit\plugins\graphicscapture
@ -58,9 +64,11 @@ copy ..\rundir\shaders\*.?Shader .\64bit\shaders\
copy ..\dshowplugin\x64\release\dshowplugin.dll .\64bit\plugins
copy ..\noisegate\x64\release\noisegate.dll .\64bit\plugins
copy ..\psvplugin\x64\release\psvplugin.dll .\64bit\plugins
copy ..\scenesw\x64\release\scenesw.dll .\64bit\plugins
copy ..\rundir\plugins\dshowplugin\locale\*.txt .\64bit\plugins\dshowplugin\locale\
copy ..\rundir\plugins\dshowplugin\shaders\*.?Shader .\64bit\plugins\dshowplugin\shaders\
copy ..\rundir\plugins\psvplugin\locale\*.txt .\64bit\plugins\psvplugin\locale\
copy ..\rundir\plugins\scenesw\locale\*.txt .\64bit\plugins\scenesw\locale\
copy ..\graphicscapture\x64\release\graphicscapture.dll .\64bit\plugins
copy ..\graphicscapture\graphicscapturehook\release\graphicscapturehook.dll .\64bit\plugins\graphicscapture
copy ..\graphicscapture\graphicscapturehook\x64\release\graphicscapturehook64.dll .\64bit\plugins\graphicscapture
@ -97,6 +105,11 @@ mkdir upload\PSVPlugin\32bit
mkdir upload\PSVPlugin\32bit\PSVPlugin\locale
mkdir upload\PSVPlugin\64bit
mkdir upload\PSVPlugin\64bit\PSVPlugin\locale
mkdir upload\scenesw
mkdir upload\scenesw\32bit
mkdir upload\scenesw\32bit\scenesw\locale
mkdir upload\scenesw\64bit
mkdir upload\scenesw\64bit\scenesw\locale
mkdir upload\OBS
mkdir upload\OBS\32bit
mkdir upload\OBS\64bit
@ -133,6 +146,12 @@ copy 32bit\plugins\psvplugin\locale\*.txt .\upload\PSVPlugin\32bit\PSVPlugin\loc
copy 64bit\plugins\psvplugin.dll .\upload\PSVPlugin\64bit\
copy 64bit\plugins\psvplugin\locale\*.txt .\upload\PSVPlugin\64bit\PSVPlugin\locale\
copy 32bit\plugins\scenesw.dll .\upload\scenesw\32bit\
copy 32bit\plugins\scenesw\locale\*.txt .\upload\scenesw\32bit\scenesw\locale\
copy 64bit\plugins\scenesw.dll .\upload\scenesw\64bit\
copy 64bit\plugins\scenesw\locale\*.txt .\upload\scenesw\64bit\scenesw\locale\
copy 32bit\obs.exe .\upload\OBS\32bit\
copy 32bit\obsapi.dll .\upload\OBS\32bit\
copy 32bit\*.pdb .\upload\OBS\32bit\

View File

@ -9,6 +9,8 @@ mkdir 32bit\plugins\DShowPlugin\shaders
mkdir 32bit\plugins\GraphicsCapture
mkdir 32bit\plugins\PSVPlugin
mkdir 32bit\plugins\PSVPlugin\locale
mkdir 32bit\plugins\scenesw
mkdir 32bit\plugins\scenesw\locale
mkdir 64bit
mkdir 64bit\locale
@ -20,6 +22,8 @@ mkdir 64bit\plugins\DShowPlugin\shaders
mkdir 64bit\plugins\GraphicsCapture
mkdir 64bit\plugins\PSVPlugin
mkdir 64bit\plugins\PSVPlugin\locale
mkdir 64bit\plugins\scenesw
mkdir 64bit\plugins\scenesw\locale
copy ..\release\obs.exe .\32bit\
copy ..\obsapi\release\obsapi.dll .\32bit\
@ -30,14 +34,17 @@ copy ..\rundir\pdb32\DShowPlugin.pdb .\32bit\plugins\
copy ..\rundir\pdb32\GraphicsCapture.pdb .\32bit\plugins\
copy ..\rundir\pdb32\NoiseGate.pdb .\32bit\plugins\
copy ..\rundir\pdb32\PSVPlugin.pdb .\32bit\plugins\
copy ..\rundir\pdb32\scenesw.pdb .\32bit\plugins\
copy ..\rundir\locale\*.txt .\32bit\locale\
copy ..\rundir\shaders\*.?Shader .\32bit\shaders\
copy ..\dshowplugin\release\dshowplugin.dll .\32bit\plugins
copy ..\noisegate\release\noisegate.dll .\32bit\plugins
copy ..\psvplugin\release\psvplugin.dll .\32bit\plugins
copy ..\scenesw\release\scenesw.dll .\32bit\plugins
copy ..\rundir\plugins\dshowplugin\locale\*.txt .\32bit\plugins\dshowplugin\locale\
copy ..\rundir\plugins\dshowplugin\shaders\*.?Shader .\32bit\plugins\dshowplugin\shaders\
copy ..\rundir\plugins\psvplugin\locale\*.txt .\32bit\plugins\psvplugin\locale\
copy ..\rundir\plugins\scenesw\locale\*.txt .\32bit\plugins\scenesw\locale\
copy ..\graphicscapture\release\graphicscapture.dll .\32bit\plugins
copy ..\graphicscapture\graphicscapturehook\release\graphicscapturehook.dll .\32bit\plugins\graphicscapture
copy ..\graphicscapture\graphicscapturehook\x64\release\graphicscapturehook64.dll .\32bit\plugins\graphicscapture
@ -57,14 +64,17 @@ copy ..\rundir\pdb64\DShowPlugin.pdb .\64bit\plugins\
copy ..\rundir\pdb64\GraphicsCapture.pdb .\64bit\plugins\
copy ..\rundir\pdb64\NoiseGate.pdb .\64bit\plugins\
copy ..\rundir\pdb64\PSVPlugin.pdb .\64bit\plugins\
copy ..\rundir\pdb64\scenesw.pdb .\64bit\plugins\
copy ..\rundir\locale\*.txt .\64bit\locale\
copy ..\rundir\shaders\*.?Shader .\64bit\shaders\
copy ..\dshowplugin\x64\release\dshowplugin.dll .\64bit\plugins
copy ..\noisegate\x64\release\noisegate.dll .\64bit\plugins
copy ..\psvplugin\x64\release\psvplugin.dll .\64bit\plugins
copy ..\scenesw\x64\release\scenesw.dll .\64bit\plugins
copy ..\rundir\plugins\dshowplugin\locale\*.txt .\64bit\plugins\dshowplugin\locale\
copy ..\rundir\plugins\dshowplugin\shaders\*.?Shader .\64bit\plugins\dshowplugin\shaders\
copy ..\rundir\plugins\psvplugin\locale\*.txt .\64bit\plugins\psvplugin\locale\
copy ..\rundir\plugins\scenesw\locale\*.txt .\64bit\plugins\scenesw\locale\
copy ..\graphicscapture\x64\release\graphicscapture.dll .\64bit\plugins
copy ..\graphicscapture\graphicscapturehook\release\graphicscapturehook.dll .\64bit\plugins\graphicscapture
copy ..\graphicscapture\graphicscapturehook\x64\release\graphicscapturehook64.dll .\64bit\plugins\graphicscapture

View File

@ -155,6 +155,9 @@ Section "Open Broadcaster Software" Section1
File "32bit\plugins\PSVPlugin.dll"
SetOutPath "$PROGRAMFILES32\OBS\plugins\PSVPlugin\locale\"
File "32bit\plugins\PSVPlugin\locale\*.txt"
File "32bit\plugins\scenesw.dll"
SetOutPath "$PROGRAMFILES32\OBS\plugins\scenesw\locale\"
File "32bit\plugins\scenesw\locale\*.txt"
SetOutPath "$PROGRAMFILES32\OBS\plugins\DShowPlugin\locale\"
File "32bit\plugins\DShowPlugin\locale\*.txt"
SetOutPath "$PROGRAMFILES32\OBS\plugins\DShowPlugin\shaders\"
@ -193,6 +196,9 @@ Section "Open Broadcaster Software" Section1
File "64bit\plugins\PSVPlugin.dll"
SetOutPath "$PROGRAMFILES64\OBS\plugins\PSVPlugin\locale\"
File "64bit\plugins\PSVPlugin\locale\*.txt"
File "64bit\plugins\scenesw.dll"
SetOutPath "$PROGRAMFILES64\OBS\plugins\scenesw\locale\"
File "64bit\plugins\scenesw\locale\*.txt"
SetOutPath "$PROGRAMFILES64\OBS\plugins\DShowPlugin\locale\"
File "64bit\plugins\DShowPlugin\locale\*.txt"
SetOutPath "$PROGRAMFILES64\OBS\plugins\DShowPlugin\shaders\"
@ -280,6 +286,8 @@ Section "un.OBS Program Files"
Delete "$PROGRAMFILES32\OBS\plugins\NoiseGate.dll"
Delete "$PROGRAMFILES32\OBS\plugins\PSVPlugin.dll"
Delete "$PROGRAMFILES32\OBS\plugins\PSVPlugin\locale\*.txt"
Delete "$PROGRAMFILES32\OBS\plugins\scenesw.dll"
Delete "$PROGRAMFILES32\OBS\plugins\scenesw\locale\*.txt"
Delete "$PROGRAMFILES32\OBS\plugins\DShowPlugin\locale\*.txt"
Delete "$PROGRAMFILES32\OBS\plugins\DShowPlugin\shaders\*.?Shader"
Delete "$PROGRAMFILES32\OBS\plugins\GraphicsCapture\*.dll"
@ -301,6 +309,8 @@ Section "un.OBS Program Files"
Delete "$PROGRAMFILES64\OBS\plugins\NoiseGate.dll"
Delete "$PROGRAMFILES64\OBS\plugins\PSVPlugin.dll"
Delete "$PROGRAMFILES64\OBS\plugins\PSVPlugin\locale\*.txt"
Delete "$PROGRAMFILES64\OBS\plugins\scenesw.dll"
Delete "$PROGRAMFILES64\OBS\plugins\scenesw\locale\*.txt"
Delete "$PROGRAMFILES64\OBS\plugins\DShowPlugin\locale\*.txt"
Delete "$PROGRAMFILES64\OBS\plugins\DShowPlugin\shaders\*.?Shader"
Delete "$PROGRAMFILES64\OBS\plugins\GraphicsCapture\*.dll"
@ -315,6 +325,8 @@ Section "un.OBS Program Files"
RMDir "$PROGRAMFILES32\OBS\plugins\DShowPlugin\"
RMDir "$PROGRAMFILES32\OBS\plugins\PSVPlugin\locale\"
RMDir "$PROGRAMFILES32\OBS\plugins\PSVPlugin\"
RMDir "$PROGRAMFILES32\OBS\plugins\scenesw\locale\"
RMDir "$PROGRAMFILES32\OBS\plugins\scenesw\"
RMDir "$PROGRAMFILES32\OBS\plugins"
RMDir "$PROGRAMFILES32\OBS\locale"
RMDir "$PROGRAMFILES32\OBS\shaders"
@ -325,6 +337,8 @@ Section "un.OBS Program Files"
RMDir "$PROGRAMFILES64\OBS\plugins\DShowPlugin\"
RMDir "$PROGRAMFILES64\OBS\plugins\PSVPlugin\locale\"
RMDir "$PROGRAMFILES64\OBS\plugins\PSVPlugin\"
RMDir "$PROGRAMFILES64\OBS\plugins\scenesw\locale\"
RMDir "$PROGRAMFILES64\OBS\plugins\scenesw\"
RMDir "$PROGRAMFILES64\OBS\plugins"
RMDir "$PROGRAMFILES64\OBS\locale"
RMDir "$PROGRAMFILES64\OBS\shaders"

View File

@ -7,6 +7,7 @@ copy ..\graphicscapture\graphicscapturehook\debug\graphicscapturehook.dll .\plug
copy ..\graphicscapture\graphicscapturehook\x64\debug\graphicscapturehook64.dll .\plugins\graphicscapture
copy ..\noisegate\debug\noisegate.dll .\plugins
copy ..\psvplugin\debug\psvplugin.dll .\plugins
copy ..\scenesw\debug\scenesw.dll .\plugins
copy ..\x264\libs\32bit\libx264-142.dll .\
copy ..\injectHelper\Release\injectHelper.exe .\plugins\graphicscapture
copy ..\injectHelper\x64\Release\injectHelper64.exe .\plugins\graphicscapture

View File

@ -7,6 +7,7 @@ copy ..\graphicscapture\graphicscapturehook\debug\graphicscapturehook.dll .\plug
copy ..\graphicscapture\graphicscapturehook\x64\debug\graphicscapturehook64.dll .\plugins\graphicscapture
copy ..\noisegate\x64\debug\noisegate.dll .\plugins
copy ..\psvplugin\x64\debug\psvplugin.dll .\plugins
copy ..\scenesw\x64\debug\scenesw.dll .\plugins
copy ..\x264\libs\64bit\libx264-142.dll .\
copy ..\injectHelper\Release\injectHelper.exe .\plugins\graphicscapture
copy ..\injectHelper\x64\Release\injectHelper64.exe .\plugins\graphicscapture

View File

@ -7,6 +7,7 @@ copy ..\graphicscapture\graphicscapturehook\release\graphicscapturehook.dll .\pl
copy ..\graphicscapture\graphicscapturehook\x64\release\graphicscapturehook64.dll .\plugins\graphicscapture
copy ..\noisegate\release\noisegate.dll .\plugins
copy ..\psvplugin\release\psvplugin.dll .\plugins
copy ..\scenesw\release\scenesw.dll .\plugins
copy ..\x264\libs\32bit\libx264-142.dll .\
copy ..\injectHelper\Release\injectHelper.exe .\plugins\graphicscapture
copy ..\injectHelper\x64\Release\injectHelper64.exe .\plugins\graphicscapture

View File

@ -7,6 +7,7 @@ copy ..\graphicscapture\graphicscapturehook\release\graphicscapturehook.dll .\pl
copy ..\graphicscapture\graphicscapturehook\x64\release\graphicscapturehook64.dll .\plugins\graphicscapture
copy ..\noisegate\x64\release\noisegate.dll .\plugins
copy ..\psvplugin\x64\release\psvplugin.dll .\plugins
copy ..\scenesw\x64\release\scenesw.dll .\plugins
copy ..\x264\libs\64bit\libx264-142.dll .\
copy ..\injectHelper\Release\injectHelper.exe .\plugins\graphicscapture
copy ..\injectHelper\x64\Release\injectHelper64.exe .\plugins\graphicscapture

View File

@ -0,0 +1,26 @@
Settings.MainWndTitle="Window title to check for:"
Settings.MainWndScene="Scene to switch to on window title:"
Settings.WindowTitle="Window Title"
Settings.Scene="Scene"
Settings.MatchExact="Match exact window name"
Settings.SetToggleHotkey="Set a hotkey to toggle Scene Switcher:"
Settings.NoMatch="When no window title matches"
Settings.SwitchTo="switch to:"
Settings.DontSwitch="don't switch"
Settings.ClearHotkey="Clear Hotkey"
Settings.Up="Up"
Settings.Down="Down"
Settings.Add="Add"
Settings.Remove="Remove"
Settings.CheckEvery="Check active window title every"
Settings.Milliseconds="milliseconds."
Settings.PluginIs="Plugin is"
Settings.Running="running"
Settings.NotRunning="not running"
Settings.Start="Start"
Settings.Stop="Stop"
Settings.StartLaunch="Start at launch if possible"
Plugin.Description="Simple scene switcher. It will switch between several scenes according to your active window.\n\nThe settings can be found in the OBS settings window."
Plugin.Name="OBS Scene switcher"
Plugin.SettingsName="Scene Switcher"

300
scenesw/SceneSwitcher.cpp Normal file
View File

@ -0,0 +1,300 @@
/********************************************************************************
Copyright (C) 2013 Christophe Jeannin <chris.j84@free.fr>
Hugh Bailey <obs.jim@gmail.com>
Eric Bataille <e.c.p.bataille@gmail.com>
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 "scenesw.h"
SceneSwitcher::SceneSwitcher(HINSTANCE hinstMain, OBSHOTKEYPROC ToggleHotkeyProc)
{
hinstDll = hinstMain;
// The localization part
pluginLocale = new LocaleStringLookup;
if(!pluginLocale->LoadStringFile(TEXT("plugins/scenesw/locale/en.txt")))
AppWarning(TEXT("Could not open locale string file '%s'"), TEXT("plugins/scenesw/locale/en.txt"));
if(scmpi(API->GetLanguage(), TEXT("en")) != 0)
{
String pluginStringFile;
pluginStringFile << TEXT("plugins/scenesw/locale/") << API->GetLanguage() << TEXT(".txt");
if(!pluginLocale->LoadStringFile(pluginStringFile))
AppWarning(TEXT("Could not open locale string file '%s'"), pluginStringFile.Array());
}
timeToSleep = TTS_DEFAULT;
thread = 0;
timer = 0;
bKillThread = true;
mainSceneName.Clear();
altSceneName.Clear();
mainWndName.Clear();
altDoSwitch = 1;
matchExact = 1;
// Start with an empty list of window-scene assignments
nWindowsDefined = 0;
scenes.Clear();
windows.Clear();
config.Open(OBSGetPluginDataPath() + CONFIGFILENAME, true);
ReadSettings();
stopReq = CreateEvent(NULL, FALSE, FALSE, NULL);
if(startAuto)
{
StartThread();
}
settings = new SceneSwitcherSettings(this, ToggleHotkeyProc);
OBSAddSettingsPane(settings);
}
SceneSwitcher::~SceneSwitcher()
{
OBSRemoveSettingsPane(settings);
delete settings;
delete pluginLocale;
StopThread();
config.Close();
CloseHandle(stopReq);
}
void SceneSwitcher::ReadSettings()
{
mainWndName = config.GetString(TEXT("General"), TEXT("MainWindow"));
mainSceneName = config.GetString(TEXT("General"), TEXT("MainScene"));
altSceneName = config.GetString(TEXT("General"), TEXT("AltScene"));
startAuto = config.GetInt(TEXT("General"), TEXT("StartAuto"));
timeToSleep = (DWORD)config.GetInt(TEXT("General"), TEXT("CheckFrequency"));
nWindowsDefined = config.GetInt(TEXT("GENERAL"), TEXT("nWindows"));
altDoSwitch = config.GetInt(TEXT("GENERAL"), TEXT("AltDoSwitch"));
toggleHotkey = (DWORD)config.GetInt(TEXT("GENERAL"), TEXT("ToggleHotkey"));
matchExact = config.GetInt(TEXT("GENERAL"), TEXT("MatchExact"), 1);
scenes.Clear();
windows.Clear();
config.GetStringList(TEXT("SceneDef"), TEXT("window"), windows);
config.GetStringList(TEXT("SceneDef"), TEXT("scene"), scenes);
if ((int)windows.Num() < nWindowsDefined) nWindowsDefined = windows.Num();
if ((int)scenes.Num() < nWindowsDefined) nWindowsDefined = scenes.Num();
if(!timeToSleep)
timeToSleep = TTS_DEFAULT;
else
TTS_CLAMP(timeToSleep);
}
void SceneSwitcher::WriteSettings()
{
config.SetString(TEXT("General"), TEXT("MainWindow"), mainWndName);
config.SetString(TEXT("General"), TEXT("MainScene"), mainSceneName);
config.SetString(TEXT("General"), TEXT("AltScene"), altSceneName);
config.SetInt(TEXT("General"), TEXT("StartAuto"), startAuto);
config.SetInt(TEXT("General"), TEXT("CheckFrequency"), timeToSleep);
config.SetInt(TEXT("General"), TEXT("nWindows"), nWindowsDefined);
config.SetInt(TEXT("General"), TEXT("AltDoSwitch"), altDoSwitch);
config.SetInt(TEXT("General"), TEXT("ToggleHotkey"), toggleHotkey);
config.SetInt(TEXT("General"), TEXT("MatchExact"), matchExact);
config.SetStringList(TEXT("SceneDef"), TEXT("window"), windows);
config.SetStringList(TEXT("SceneDef"), TEXT("scene"), scenes);
}
DWORD SceneSwitcher::Run()
{
LARGE_INTEGER dueTime;
if((timer = CreateWaitableTimer(NULL, FALSE, NULL)) == NULL)
return -1;
dueTime.QuadPart=0;
SetWaitableTimer(timer, &dueTime, timeToSleep, NULL, NULL, FALSE);
HANDLE handles[] = { timer, stopReq };
String currentWindowText;
while(!bKillThread)
{
HWND hwndCurrent = GetForegroundWindow();
currentWindowText.SetLength(GetWindowTextLength(hwndCurrent));
GetWindowText(hwndCurrent, currentWindowText, currentWindowText.Length() + 1);
String currentScene = OBSGetSceneName();
String sceneToSwitch;
// See if we get matches
bool found = false;
for (int i = 0; i < nWindowsDefined; i++)
{
bool match = false;
String toCheck = GetWindow(i);
if (currentWindowText == toCheck) match = true;
TCHAR *cwt = currentWindowText.Array();
TCHAR *tch = toCheck.Array();
if (cwt && tch)
if (!IsMatchExact() && sstr(cwt, tch)) match = true;
if (match)
{
sceneToSwitch = GetScene(i);
found = true;
break; // take the first one
}
}
if (!found) // Otherwise, take the alternate scene
sceneToSwitch = altSceneName;
// Make the switch if it isnt already selected
if (sceneToSwitch != currentScene && (found || altDoSwitch != 0))
OBSSetScene(sceneToSwitch, true);
WaitForMultipleObjects(2, handles, FALSE, INFINITE);
}
CloseHandle(timer);
return 0;
}
void SceneSwitcher::StartThread(HWND hDialog)
{
if(!thread)
{
bKillThread = false;
thread = CreateThread(NULL, 0, ThreadProc, (LPVOID)this, 0, NULL);
if(hDialog && thread)
{
SetWindowText(GetDlgItem(hDialog, IDC_RUN), pluginLocale->LookupString(TEXT("Settings.Running")));
SetWindowText(GetDlgItem(hDialog, IDC_STOP), pluginLocale->LookupString(TEXT("Settings.Stop")));
}
}
}
void SceneSwitcher::StopThread(HWND hDialog)
{
if(thread)
{
bKillThread = true;
DWORD retv;
MSG msg;
HANDLE handles[] = {thread};
SetEvent(stopReq);
//process messages while waiting for the thread to complete, otherwise the thread will be locked forever
while((retv = MsgWaitForMultipleObjects(1, handles, FALSE, INFINITE, QS_ALLINPUT)) != WAIT_FAILED)
{
if(retv == WAIT_OBJECT_0)
break;
else if(retv == WAIT_OBJECT_0+1)
while(PeekMessage(&msg, NULL, 0, 0, PM_REMOVE))
{
TranslateMessage(&msg);
DispatchMessage(&msg);
}
}
ResetEvent(stopReq);
if(thread)
{
CloseHandle(thread);
thread = 0;
}
}
if(hDialog)
{
SetWindowText(GetDlgItem(hDialog, IDC_RUN), pluginLocale->LookupString(TEXT("Settings.NotRunning")));
SetWindowText(GetDlgItem(hDialog, IDC_STOP), pluginLocale->LookupString(TEXT("Settings.Start")));
}
}
void SceneSwitcher::ApplyConfig(HWND hDialog)
{
if(!hDialog) // Noes.. Dialog don't exist?
return;
// Get the listbox control handles
HWND hwndMainScn = GetDlgItem(hDialog, IDC_MAINSCN);
HWND hwndAltScn = GetDlgItem(hDialog, IDC_ALTSCN);
HWND hwndAppList = GetDlgItem(hDialog, IDC_APPLIST);
HWND hwndWSMap = GetDlgItem(hDialog, IDC_WSMAP);
HWND hwndHotkey = GetDlgItem(hDialog, IDC_TOGGLEHOTKEY);
// Get the options names from the controls
String newMainSceneName = GetCBText(hwndMainScn, CB_ERR);
String newAltSceneName = GetCBText(hwndAltScn, CB_ERR);
String newMainWndName = GetCBText(hwndAppList, CB_ERR);
// Get the new frequency from the frequency control
DWORD newTimeToSleep = GetDlgItemInt(hDialog, IDC_FREQ, NULL, FALSE);
TTS_CLAMP(newTimeToSleep);
// Get the toggle hotkey if any
toggleHotkey = (DWORD)SendMessage(hwndHotkey, HKM_GETHOTKEY, 0, 0);
// Get the checkboxes state
altDoSwitch = IsDlgButtonChecked(hDialog, IDC_ALTSWITCH);
matchExact = IsDlgButtonChecked(hDialog, IDC_EXACT);
startAuto = IsDlgButtonChecked(hDialog, IDC_STARTAUTO);
if(newAltSceneName.IsEmpty() && IsAltDoSwitch())
StopThread(hDialog); // if we're applying a bad config stop thread first
if((timeToSleep != newTimeToSleep) && thread && timer)
{ // reset timer with new value
LARGE_INTEGER dueTime;
dueTime.QuadPart=0;
SetWaitableTimer(timer, &dueTime, newTimeToSleep, NULL, NULL, FALSE);
}
nWindowsDefined = SendMessage(hwndWSMap, LVM_GETITEMCOUNT, 0, 0);
scenes.Clear();
windows.Clear();
for (int i = 0; i < nWindowsDefined; i++)
{
// Get the window name
String wnd;
wnd.SetLength(256);
ListView_GetItemText(hwndWSMap, i, 0, wnd, 256);
windows.Add(wnd);
// Get the scene name
String scn;
scn.SetLength(256);
ListView_GetItemText(hwndWSMap, i, 1, scn, 256);
scenes.Add(scn);
}
// Set the new global values
timeToSleep = newTimeToSleep;
mainSceneName = newMainSceneName;
altSceneName = newAltSceneName;
mainWndName = newMainWndName;
WriteSettings(); // Write the settings to config
}

134
scenesw/SceneSwitcher.h Normal file
View File

@ -0,0 +1,134 @@
/********************************************************************************
Copyright (C) 2013 Christophe Jeannin <chris.j84@free.fr>
Eric Bataille <e.c.p.bataille@gmail.com>
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 "SettingsPane.h"
#pragma once
#define CONFIGFILENAME TEXT("\\scenesw.ini")
#define TTS_DEFAULT 300
#define TTS_MIN 50
#define TTS_MAX 5000
#define TTS_CLAMP(x) x = (x < TTS_MIN ? TTS_MIN : (x > TTS_MAX ? TTS_MAX : x))
#define PluginStr(text) thePlugin->pluginLocale->LookupString(TEXT2(text))
class SceneSwitcher;
class SceneSwitcherSettings : public SettingsPane {
private:
SceneSwitcher * thePlugin;
OBSHOTKEYPROC ToggleHotkeyProc;
bool pChange;
//-----------------------------------------------------------------------
// Constructor/destructor
public:
SceneSwitcherSettings(SceneSwitcher *thePlugin, OBSHOTKEYPROC ToggleHotkeyProc);
virtual ~SceneSwitcherSettings();
//-----------------------------------------------------------------------
// Fields
public:
UINT hotkeyID;
DWORD hotkey;
//-----------------------------------------------------------------------
// Methods
private:
void RefreshConfig();
void ApplyConfig(HWND hWnd);
void EditItem(bool selChange);
// Message processing
void MsgInitDialog();
void MsgDestroy();
INT_PTR MsgClicked(int controlId, int code, HWND controlHwnd);
public:
// Interface
virtual CTSTR GetCategory() const;
virtual HWND CreatePane(HWND parentHwnd);
virtual void DestroyPane();
virtual INT_PTR ProcMessage(UINT message, WPARAM wParam, LPARAM lParam);
virtual void ApplySettings();
virtual void CancelSettings();
virtual bool HasDefaults() const;
};
class SceneSwitcher
{
friend class SceneSwitcherSettings;
HANDLE thread;
HANDLE timer;
HANDLE stopReq;
DWORD timeToSleep;
String mainSceneName;
String altSceneName;
String mainWndName;
int startAuto;
int matchExact;
bool bKillThread;
ConfigFile config;
int altDoSwitch;
DWORD toggleHotkey;
SceneSwitcherSettings * settings;
int nWindowsDefined;
StringList windows;
StringList scenes;
inline bool CheckSettings() const {return (!altSceneName.IsEmpty());}
void ReadSettings();
void WriteSettings();
DWORD Run();
static DWORD WINAPI ThreadProc(LPVOID pParam){return static_cast<SceneSwitcher*>(pParam)->Run();}
public:
LocaleStringLookup *pluginLocale;
HINSTANCE hinstDll;
inline CTSTR GetmainSceneName() const {return mainSceneName;}
inline CTSTR GetaltSceneName() const {return altSceneName;}
inline CTSTR GetmainWndName() const {return mainWndName;}
inline DWORD GettimeToSleep() const {return timeToSleep;}
inline bool IsRunning() const {return thread!=0;}
inline bool IsStartAuto() const {return startAuto!=0;}
inline bool IsAltDoSwitch() const {return altDoSwitch!=0;}
inline bool IsMatchExact() const {return matchExact!=0;}
inline int GetToggleHotkey() const {return toggleHotkey;}
inline int GetnWindowsDefined() const {return nWindowsDefined;}
inline String GetWindow(int i) const {return windows[i];}
inline String GetScene(int i) const {return scenes[i];}
inline SceneSwitcherSettings* GetSettings() const { return settings; }
SceneSwitcher(HINSTANCE hinstMain, OBSHOTKEYPROC ToggleHotkeyProc);
~SceneSwitcher();
void StartThread(HWND hDialog = NULL);
void StopThread (HWND hDialog = NULL);
void ApplyConfig(HWND hDialog);
};

View File

@ -0,0 +1,489 @@
/********************************************************************************
Copyright (C) 2013 Christophe Jeannin <chris.j84@free.fr>
Eric Bataille <e.c.p.bataille@gmail.com>
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 "scenesw.h"
SceneSwitcherSettings::SceneSwitcherSettings(SceneSwitcher *thePlugin, OBSHOTKEYPROC ToggleHotkeyProc):
SettingsPane(),
thePlugin(thePlugin),
ToggleHotkeyProc(ToggleHotkeyProc)
{
pChange = false;
}
SceneSwitcherSettings::~SceneSwitcherSettings()
{
}
CTSTR SceneSwitcherSettings::GetCategory() const
{
return PluginStr("Plugin.SettingsName");
}
HWND SceneSwitcherSettings::CreatePane(HWND parentHwnd)
{
hwnd = CreateDialogParam(thePlugin->hinstDll, MAKEINTRESOURCE(IDD_SETTINGS_SCENESW),
parentHwnd, (DLGPROC)DialogProc, (LPARAM)this);
return hwnd;
}
void SceneSwitcherSettings::DestroyPane()
{
DestroyWindow(hwnd);
hwnd = NULL;
}
INT_PTR SceneSwitcherSettings::ProcMessage(UINT message, WPARAM wParam, LPARAM lParam)
{
switch(message)
{
case WM_INITDIALOG:
MsgInitDialog();
return TRUE;
case WM_COMMAND:
return MsgClicked(LOWORD(wParam), HIWORD(wParam), (HWND)lParam);
case WM_CTLCOLORSTATIC:
if(GetWindowLong((HWND)lParam, GWL_ID) == IDC_RUN)
{
HDC hdc = (HDC)wParam;
SetTextColor(hdc, thePlugin->IsRunning() ? RGB(0,255,0) : RGB(255,0,0));
SetBkColor(hdc, GetSysColor(COLOR_3DFACE));
return (INT_PTR)GetSysColorBrush(COLOR_3DFACE);
}
break;
case WM_NOTIFY:
switch (LOWORD(wParam)) {
case IDC_WSMAP:
{
const NMITEMACTIVATE* lpnmitem = (LPNMITEMACTIVATE)lParam;
if(lpnmitem->hdr.idFrom == IDC_WSMAP && lpnmitem->hdr.code == NM_CLICK)
{
const int sel = lpnmitem->iItem;
if(sel >= 0)
{
HWND wsMap = GetDlgItem(hwnd, IDC_WSMAP);
HWND hwndAppList = GetDlgItem(hwnd, IDC_APPLIST);
HWND hwndMainScn = GetDlgItem(hwnd, IDC_MAINSCN);
// Get the text from the item
String wnd;
wnd.SetLength(256);
ListView_GetItemText(wsMap, sel, 0, wnd, 256);
String scn;
scn.SetLength(256);
ListView_GetItemText(wsMap, sel, 1, scn, 256);
// Set the combos
SetWindowText(hwndAppList, wnd);
SendMessage(hwndMainScn, CB_SETCURSEL, SendMessage(hwndMainScn, CB_FINDSTRINGEXACT, -1, (LPARAM)scn.Array()), 0);
}
}
return TRUE;
}
break;
}
}
return FALSE;
}
void SceneSwitcherSettings::MsgInitDialog()
{
LocalizeWindow(hwnd, thePlugin->pluginLocale);
HWND hwndAppList = GetDlgItem(hwnd, IDC_APPLIST);
HWND hwndMainScn = GetDlgItem(hwnd, IDC_MAINSCN);
HWND hwndAltScn = GetDlgItem(hwnd, IDC_ALTSCN);
HWND hwndWSMap = GetDlgItem(hwnd, IDC_WSMAP);
HWND hwndSwButton = GetDlgItem(hwnd, IDC_ALTSWITCH);
HWND hwndNoswButton = GetDlgItem(hwnd, IDC_ALTNOSWITCH);
HWND hwndCurrent = GetWindow(GetDesktopWindow(), GW_CHILD); // The top child of the desktop
// let's fill the listcontrol
SendMessage(hwndWSMap, LVM_SETEXTENDEDLISTVIEWSTYLE, LVS_EX_FULLROWSELECT, LVS_EX_FULLROWSELECT);
LVCOLUMN col1;
col1.mask = LVCF_FMT | LVCF_TEXT | LVCF_WIDTH;
col1.fmt = LVCFMT_RIGHT | LVCFMT_FIXED_WIDTH;
col1.cx = 307;
col1.pszText = (LPWSTR)PluginStr("Settings.WindowTitle");
LVCOLUMN col2;
col2.mask = LVCF_FMT | LVCF_TEXT | LVCF_WIDTH;
col2.fmt = LVCFMT_LEFT | LVCFMT_FIXED_WIDTH;
col2.cx = 307;
col2.pszText = (LPWSTR)PluginStr("Settings.Scene");
SendMessage(hwndWSMap, LVM_INSERTCOLUMN, 0, (LPARAM) (LPLVCOLUMN) &col1);
SendMessage(hwndWSMap, LVM_INSERTCOLUMN, 1, (LPARAM) (LPLVCOLUMN) &col2);
// Add the items
for (int i = 0; i < thePlugin->GetnWindowsDefined(); i++)
{
String window = thePlugin->GetWindow(i);
String scene = thePlugin->GetScene(i);
LVITEM item;
item.iItem = 0;
item.iSubItem = 0;
item.mask = LVIF_TEXT;
item.pszText = window;
LVITEM subItem;
subItem.iItem = 0;
subItem.iSubItem = 1;
subItem.mask = LVIF_TEXT;
subItem.pszText = scene;
SendMessage(hwndWSMap, LVM_INSERTITEM, 0, (LPARAM) &item);
SendMessage(hwndWSMap, LVM_SETITEM, 0, (LPARAM) &subItem);
}
// Set the radio buttons and alt scene combo state
SendMessage(hwndSwButton, BM_SETCHECK, (thePlugin->IsAltDoSwitch() ? BST_CHECKED : BST_UNCHECKED), 0);
SendMessage(hwndNoswButton, BM_SETCHECK, (thePlugin->IsAltDoSwitch() ? BST_UNCHECKED : BST_CHECKED), 0);
EnableWindow(hwndAltScn, thePlugin->IsAltDoSwitch());
if(thePlugin->IsMatchExact()) // Match exact window name checkbox
CheckDlgButton(hwnd, IDC_EXACT, BST_CHECKED);
do
{
if(IsWindowVisible(hwndCurrent))
{
// Get the styles for the window
DWORD exStyles = (DWORD)GetWindowLongPtr(hwndCurrent, GWL_EXSTYLE);
DWORD styles = (DWORD)GetWindowLongPtr(hwndCurrent, GWL_STYLE);
if( (exStyles & WS_EX_TOOLWINDOW) == 0 && (styles & WS_CHILD) == 0)
{
// The window is not a toolwindow, and not a child window
String strWindowName;
// Get the name of the window
strWindowName.SetLength(GetWindowTextLength(hwndCurrent));
GetWindowText(hwndCurrent, strWindowName, strWindowName.Length()+1);
// Add the Name of the window to the appList
const int id = (int)SendMessage(hwndAppList, CB_ADDSTRING, 0, (LPARAM)strWindowName.Array());
// Set the data for the added item to be the window handle
SendMessage(hwndAppList, CB_SETITEMDATA, id, (LPARAM)hwndCurrent);
}
}
} // Move down the windows in z-order
while (hwndCurrent = GetNextWindow(hwndCurrent, GW_HWNDNEXT));
// Get the list of scenes from OBS
XElement* scnList = OBSGetSceneListElement();
if(scnList)
{
const DWORD numScn = scnList->NumElements();
for(DWORD i=0; i<numScn; i++)
{
CTSTR sceneName = (scnList->GetElementByID(i))->GetName();
// Add the scene name to both scene lists
SendMessage(hwndMainScn, CB_ADDSTRING, 0, (LPARAM)sceneName);
SendMessage(hwndAltScn, CB_ADDSTRING, 0, (LPARAM)sceneName);
}
}
// Set the selected list items to be the ones from settings
SendMessage(hwndMainScn, CB_SETCURSEL, SendMessage(hwndMainScn, CB_FINDSTRINGEXACT, -1, (LPARAM)thePlugin->GetmainSceneName()), 0);
SendMessage(hwndAltScn, CB_SETCURSEL, SendMessage(hwndAltScn, CB_FINDSTRINGEXACT, -1, (LPARAM)thePlugin->GetaltSceneName()), 0);
SendMessage(hwndAppList, CB_SETCURSEL, SendMessage(hwndAppList, CB_FINDSTRINGEXACT, -1, (LPARAM)thePlugin->GetmainWndName()), 0);
// Set the frequency from the settings
SetDlgItemInt(hwnd, IDC_FREQ, thePlugin->GettimeToSleep(), FALSE);
// Set the autostart checkbox value from the settings
if(thePlugin->IsStartAuto())
CheckDlgButton(hwnd, IDC_STARTAUTO, BST_CHECKED);
// Set the toggle hotkey control
SendMessage(GetDlgItem(hwnd, IDC_TOGGLEHOTKEY), HKM_SETHOTKEY, thePlugin->GetToggleHotkey(), 0);
// If the plugin is running, update the text values
if(thePlugin->IsRunning())
{
SetWindowText(GetDlgItem(hwnd, IDC_RUN), PluginStr("Settings.Running"));
SetWindowText(GetDlgItem(hwnd, IDC_STOP), PluginStr("Settings.Stop"));
}
}
INT_PTR SceneSwitcherSettings::MsgClicked(int controlId, int code, HWND controlHwnd)
{
switch(controlId)
{
case IDC_CLEAR_HOTKEY:
if(code == BN_CLICKED) {
SendMessage(GetDlgItem(hwnd, IDC_TOGGLEHOTKEY), HKM_SETHOTKEY, 0, 0);
SetChangedSettings(pChange = true);
return TRUE;
}
break;
case IDC_STOP:
if(code == BN_CLICKED) // Stop button clicked
{
if(thePlugin->IsRunning())
thePlugin->StopThread(hwnd);
else
{
ApplyConfig(hwnd);
pChange = false;
thePlugin->StartThread(hwnd);
}
SetChangedSettings(pChange);
return TRUE;
}
break;
case IDUP:
{
HWND wsMap = GetDlgItem(hwnd, IDC_WSMAP);
const int sel = SendMessage(wsMap, LVM_GETSELECTIONMARK, 0, 0);
if (sel > 0)
{
// Get the text from the item
String wnd;
wnd.SetLength(256);
ListView_GetItemText(wsMap, sel, 0, wnd, 256);
String scn;
scn.SetLength(256);
ListView_GetItemText(wsMap, sel, 1, scn, 256);
// Delete it
SendMessage(wsMap, LVM_DELETEITEM, sel, 0);
// Add it above
LVITEM lv1;
lv1.mask = LVIF_TEXT;
lv1.iItem = sel - 1;
lv1.iSubItem = 0;
lv1.pszText = wnd;
LVITEM lv2;
lv2.mask = LVIF_TEXT;
lv2.iItem = sel - 1;
lv2.iSubItem = 1;
lv2.pszText = scn;
SendMessage(wsMap, LVM_INSERTITEM, sel - 1, (LPARAM) &lv1);
SendMessage(wsMap, LVM_SETITEM, sel - 1, (LPARAM) &lv2);
// Update the selection mark
SendMessage(wsMap, LVM_SETSELECTIONMARK, 0, sel - 1);
SetChangedSettings(pChange = true);
return TRUE;
}
break;
}
case IDDOWN:
{
HWND wsMap = GetDlgItem(hwnd, IDC_WSMAP);
const int sel = SendMessage(wsMap, LVM_GETSELECTIONMARK, 0, 0);
const int max = SendMessage(wsMap, LVM_GETITEMCOUNT, 0, 0) - 1;
if (sel > -1 && sel < max)
{
// Get the text from the item
String wnd;
wnd.SetLength(256);
ListView_GetItemText(wsMap, sel, 0, wnd, 256);
String scn;
scn.SetLength(256);
ListView_GetItemText(wsMap, sel, 1, scn, 256);
// Delete it
SendMessage(wsMap, LVM_DELETEITEM, sel, 0);
// Add it below
LVITEM lv1;
lv1.mask = LVIF_TEXT;
lv1.iItem = sel + 1;
lv1.iSubItem = 0;
lv1.pszText = wnd;
LVITEM lv2;
lv2.mask = LVIF_TEXT;
lv2.iItem = sel + 1;
lv2.iSubItem = 1;
lv2.pszText = scn;
SendMessage(wsMap, LVM_INSERTITEM, sel + 1, (LPARAM) &lv1);
SendMessage(wsMap, LVM_SETITEM, sel + 1, (LPARAM) &lv2);
// Update the selection mark
SendMessage(wsMap, LVM_SETSELECTIONMARK, 0, sel + 1);
SetChangedSettings(pChange = true);
return TRUE;
}
break;
}
case IDADD:
{
HWND wsMap = GetDlgItem(hwnd, IDC_WSMAP);
HWND appList = GetDlgItem(hwnd, IDC_APPLIST);
HWND scnList = GetDlgItem(hwnd, IDC_MAINSCN);
String wnd = GetEditText(appList);
// First column
LVITEM lv1;
lv1.mask = LVIF_TEXT;
lv1.iItem = 0;
lv1.iSubItem = 0;
lv1.pszText = wnd;
// Second column
String scn = GetCBText(scnList, CB_ERR);
LVITEM lv2;
lv2.mask = LVIF_TEXT;
lv2.iItem = 0;
lv2.iSubItem = 1;
lv2.pszText = scn;
// Add first column then set second
SendMessage(wsMap, LVM_INSERTITEM, 0, (LPARAM)&lv1);
SendMessage(wsMap, LVM_SETITEM, 0, (LPARAM)&lv2);
SetChangedSettings(pChange = true);
return TRUE;
}
break;
case IDREM:
{
// Remove the item
HWND wsMap = GetDlgItem(hwnd, IDC_WSMAP);
const int sel = SendMessage(wsMap, LVM_GETSELECTIONMARK, 0, 0);
if (sel > -1)
SendMessage(wsMap, LVM_DELETEITEM, sel, 0);
SetChangedSettings(pChange = true);
return TRUE;
}
break;
case IDC_ALTSWITCH:
case IDC_ALTNOSWITCH:
if (code == BN_CLICKED)
{
HWND swButton = GetDlgItem(hwnd, IDC_ALTSWITCH);
HWND altCombo = GetDlgItem(hwnd, IDC_ALTSCN);
const bool swChecked = (SendMessage(swButton, BM_GETSTATE, 0, 0) & BST_CHECKED) != 0;
EnableWindow(altCombo, swChecked);
pChange = pChange || (swChecked != thePlugin->IsAltDoSwitch());
SetChangedSettings(pChange);
return TRUE;
}
break;
case IDC_STARTAUTO:
{
HWND control = GetDlgItem(hwnd, IDC_STARTAUTO);
bool newState = (SendMessage(control, BM_GETSTATE, 0, 0) & BST_CHECKED) != 0;
pChange = pChange || (newState != thePlugin->IsStartAuto());
SetChangedSettings(pChange);
return TRUE;
}
break;
case IDC_EXACT:
{
HWND control = GetDlgItem(hwnd, IDC_EXACT);
bool newState = (SendMessage(control, BM_GETSTATE, 0, 0) & BST_CHECKED) != 0;
pChange = pChange || (newState != thePlugin->IsMatchExact());
SetChangedSettings(pChange);
return TRUE;
}
break;
case IDC_TOGGLEHOTKEY:
if (code == EN_CHANGE) {
SetChangedSettings(pChange = true);
return TRUE;
}
break;
case IDC_FREQ:
if(code == EN_CHANGE)
{
DWORD newFreq = GetDlgItemInt(hwnd, IDC_FREQ, NULL, FALSE);
DWORD oldFreq = thePlugin->GettimeToSleep();
pChange = pChange || newFreq != oldFreq;
SetChangedSettings(pChange);
return TRUE;
}
break;
case IDC_APPLIST:
case IDC_MAINSCN:
if (code == CBN_SELCHANGE || code == CBN_EDITCHANGE) {
EditItem(code == CBN_SELCHANGE);
return TRUE;
}
break;
case IDC_ALTSCN:
if (code == CBN_SELCHANGE) {
SetChangedSettings(pChange = true);
return TRUE;
}
break;
}
return FALSE;
}
void SceneSwitcherSettings::EditItem(bool selChange) {
HWND wsMap = GetDlgItem(hwnd, IDC_WSMAP);
HWND appList = GetDlgItem(hwnd, IDC_APPLIST);
HWND scnList = GetDlgItem(hwnd, IDC_MAINSCN);
const int sel = SendMessage(wsMap, LVM_GETSELECTIONMARK, 0, 0);
if (sel < 0) return;
String wnd = selChange ? GetCBText(appList, CB_ERR) : GetEditText(appList);
// First column
LVITEM lv1;
lv1.mask = LVIF_TEXT;
lv1.iItem = sel;
lv1.iSubItem = 0;
lv1.pszText = wnd;
String scn = GetCBText(scnList, CB_ERR);
// Second column
LVITEM lv2;
lv2.mask = LVIF_TEXT;
lv2.iItem = sel;
lv2.iSubItem = 1;
lv2.pszText = scn;
// Set the text
SendMessage(wsMap, LVM_SETITEM, 0, (LPARAM)&lv1);
SendMessage(wsMap, LVM_SETITEM, 0, (LPARAM)&lv2);
SetChangedSettings(pChange = true);
}
void SceneSwitcherSettings::ApplyConfig(HWND hWnd) {
thePlugin->ApplyConfig(hWnd);
// Redefine the hotkey
if (hotkeyID)
OBSDeleteHotkey(hotkeyID);
if (thePlugin->GetToggleHotkey() != 0)
hotkeyID = OBSCreateHotkey((DWORD)thePlugin->GetToggleHotkey(), ToggleHotkeyProc, 0);
}
void SceneSwitcherSettings::ApplySettings()
{
pChange = false;
ApplyConfig(hwnd);
}
void SceneSwitcherSettings::CancelSettings()
{
pChange = false;
}
bool SceneSwitcherSettings::HasDefaults() const
{
return false;
}

BIN
scenesw/resource.h Normal file

Binary file not shown.

87
scenesw/scenesw.cpp Normal file
View File

@ -0,0 +1,87 @@
/********************************************************************************
Copyright (C) 2013 Christophe Jeannin <chris.j84@free.fr>
Eric Bataille <e.c.p.bataille@gmail.com>
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 "scenesw.h"
extern "C" __declspec(dllexport) bool LoadPlugin();
extern "C" __declspec(dllexport) bool LoadPluginEx(UINT apiVer);
extern "C" __declspec(dllexport) void UnloadPlugin();
extern "C" __declspec(dllexport) CTSTR GetPluginName();
extern "C" __declspec(dllexport) CTSTR GetPluginDescription();
HINSTANCE hinstMain = NULL;
SceneSwitcher* thePlugin = NULL;
void STDCALL HotkeyToggle(DWORD hotkey, UPARAM param, bool bDown)
{
if (!bDown) {
if (thePlugin->IsRunning()) {
thePlugin->StopThread();
} else {
thePlugin->StartThread();
}
}
}
bool LoadPluginEx(UINT apiVer)
{
return (apiVer == 0x0103) && LoadPlugin();
}
bool LoadPlugin()
{
InitHotkeyExControl(hinstMain);
thePlugin = new SceneSwitcher(hinstMain, HotkeyToggle);
if (thePlugin == 0) return false;
if (thePlugin->GetToggleHotkey() != 0)
thePlugin->GetSettings()->hotkeyID = OBSCreateHotkey(thePlugin->GetToggleHotkey(), HotkeyToggle, 0);
return true;
}
void UnloadPlugin()
{
if (thePlugin->GetSettings()->hotkeyID)
OBSDeleteHotkey(thePlugin->GetSettings()->hotkeyID);
if(thePlugin)
{
delete thePlugin;
thePlugin = NULL;
}
}
CTSTR GetPluginName()
{
return PluginStr("Plugin.Name");
}
CTSTR GetPluginDescription()
{
return PluginStr("Plugin.Description");
}
BOOL CALLBACK DllMain(HINSTANCE hInst, DWORD dwReason, LPVOID lpBla)
{
if(dwReason == DLL_PROCESS_ATTACH)
hinstMain = hInst;
return TRUE;
}

25
scenesw/scenesw.h Normal file
View File

@ -0,0 +1,25 @@
/********************************************************************************
Copyright (C) 2013 Christophe Jeannin <chris.j84@free.fr>
Eric Bataille <e.c.p.bataille@gmail.com>
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.
********************************************************************************/
#pragma once
#include "OBSApi.h"
#include "SceneSwitcher.h"
#include "resource.h"

BIN
scenesw/scenesw.rc Normal file

Binary file not shown.

211
scenesw/scenesw.vcxproj Normal file
View File

@ -0,0 +1,211 @@
<?xml version="1.0" encoding="utf-8"?>
<Project DefaultTargets="Build" ToolsVersion="12.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<ItemGroup Label="ProjectConfigurations">
<ProjectConfiguration Include="Debug|Win32">
<Configuration>Debug</Configuration>
<Platform>Win32</Platform>
</ProjectConfiguration>
<ProjectConfiguration Include="Debug|x64">
<Configuration>Debug</Configuration>
<Platform>x64</Platform>
</ProjectConfiguration>
<ProjectConfiguration Include="Release|Win32">
<Configuration>Release</Configuration>
<Platform>Win32</Platform>
</ProjectConfiguration>
<ProjectConfiguration Include="Release|x64">
<Configuration>Release</Configuration>
<Platform>x64</Platform>
</ProjectConfiguration>
</ItemGroup>
<PropertyGroup Label="Globals">
<ProjectGuid>{6AC307E3-7D59-4DB2-944F-961E299F063A}</ProjectGuid>
<Keyword>Win32Proj</Keyword>
<RootNamespace>scenesw</RootNamespace>
</PropertyGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration">
<ConfigurationType>DynamicLibrary</ConfigurationType>
<UseDebugLibraries>true</UseDebugLibraries>
<CharacterSet>Unicode</CharacterSet>
<PlatformToolset>v120</PlatformToolset>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="Configuration">
<ConfigurationType>DynamicLibrary</ConfigurationType>
<UseDebugLibraries>true</UseDebugLibraries>
<CharacterSet>Unicode</CharacterSet>
<PlatformToolset>v120</PlatformToolset>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration">
<ConfigurationType>DynamicLibrary</ConfigurationType>
<UseDebugLibraries>false</UseDebugLibraries>
<WholeProgramOptimization>true</WholeProgramOptimization>
<CharacterSet>Unicode</CharacterSet>
<PlatformToolset>v120</PlatformToolset>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration">
<ConfigurationType>DynamicLibrary</ConfigurationType>
<UseDebugLibraries>false</UseDebugLibraries>
<WholeProgramOptimization>true</WholeProgramOptimization>
<CharacterSet>Unicode</CharacterSet>
<PlatformToolset>v120</PlatformToolset>
</PropertyGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
<ImportGroup Label="ExtensionSettings">
</ImportGroup>
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
</ImportGroup>
<ImportGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="PropertySheets">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
</ImportGroup>
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
</ImportGroup>
<ImportGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="PropertySheets">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
</ImportGroup>
<PropertyGroup Label="UserMacros">
<WindowsSDK80Path Condition="('$(WindowsSDK80Path)'=='')And(Exists('C:\Program Files (x86)\Windows Kits\8.0\'))">C:\Program Files (x86)\Windows Kits\8.0\</WindowsSDK80Path>
<WindowsSDK80Path Condition="('$(WindowsSDK80Path)'=='')And(!Exists('C:\Program Files (x86)\Windows Kits\8.0\'))">$(WindowsSdkDir)</WindowsSDK80Path>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
<LinkIncremental>true</LinkIncremental>
<OutDir>$(Configuration)\</OutDir>
<IncludePath>$(WindowsSDK80Path)Include\um;$(WindowsSDK80Path)Include\shared;$(DXSDK_DIR)Include;$(IncludePath)</IncludePath>
<LibraryPath>$(WindowsSDK80Path)Lib\win8\um\x86;$(DXSDK_DIR)Lib\x86;$(LibraryPath)</LibraryPath>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
<LinkIncremental>true</LinkIncremental>
<OutDir>$(Platform)\$(Configuration)\</OutDir>
<IncludePath>$(WindowsSDK80Path)Include\um;$(WindowsSDK80Path)Include\shared;$(DXSDK_DIR)Include;$(IncludePath)</IncludePath>
<LibraryPath>$(WindowsSDK80Path)Lib\win8\um\x64;$(DXSDK_DIR)Lib\x64;$(LibraryPath)</LibraryPath>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
<LinkIncremental>false</LinkIncremental>
<OutDir>$(Configuration)\</OutDir>
<IncludePath>$(WindowsSDK80Path)Include\um;$(WindowsSDK80Path)Include\shared;$(DXSDK_DIR)Include;$(IncludePath)</IncludePath>
<LibraryPath>$(WindowsSDK80Path)Lib\win8\um\x86;$(DXSDK_DIR)Lib\x86;$(LibraryPath)</LibraryPath>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
<LinkIncremental>false</LinkIncremental>
<OutDir>$(Platform)\$(Configuration)\</OutDir>
<IncludePath>$(WindowsSDK80Path)Include\um;$(WindowsSDK80Path)Include\shared;$(DXSDK_DIR)Include;$(IncludePath)</IncludePath>
<LibraryPath>$(WindowsSDK80Path)Lib\win8\um\x64;$(DXSDK_DIR)Lib\x64;$(LibraryPath)</LibraryPath>
</PropertyGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
<ClCompile>
<PrecompiledHeader>
</PrecompiledHeader>
<WarningLevel>Level3</WarningLevel>
<Optimization>Disabled</Optimization>
<PreprocessorDefinitions>WIN32;_DEBUG;_WINDOWS;_USRDLL;SCENESW_EXPORTS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<AdditionalIncludeDirectories>../OBSApi;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<RuntimeLibrary>MultiThreadedDebug</RuntimeLibrary>
</ClCompile>
<Link>
<SubSystem>Windows</SubSystem>
<GenerateDebugInformation>true</GenerateDebugInformation>
<AdditionalLibraryDirectories>../OBSApi/Debug;%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
<AdditionalDependencies>OBSApi.lib;%(AdditionalDependencies)</AdditionalDependencies>
<ProgramDatabaseFile>..\rundir\pdb32\$(TargetName).pdb</ProgramDatabaseFile>
<StripPrivateSymbols>..\rundir\pdb32\stripped\$(TargetName).pdb</StripPrivateSymbols>
</Link>
<PostBuildEvent>
<Command>copy $(OutDir)$(ProjectName).dll ..\rundir\plugins</Command>
</PostBuildEvent>
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
<ClCompile>
<PrecompiledHeader>
</PrecompiledHeader>
<WarningLevel>Level3</WarningLevel>
<Optimization>Disabled</Optimization>
<PreprocessorDefinitions>WIN32;_DEBUG;_WINDOWS;_USRDLL;SCENESW_EXPORTS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<AdditionalIncludeDirectories>../OBSApi;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<ExceptionHandling>false</ExceptionHandling>
<RuntimeLibrary>MultiThreadedDebug</RuntimeLibrary>
</ClCompile>
<Link>
<SubSystem>Windows</SubSystem>
<GenerateDebugInformation>true</GenerateDebugInformation>
<AdditionalLibraryDirectories>../OBSApi/x64/Debug;%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
<AdditionalDependencies>OBSApi.lib;%(AdditionalDependencies)</AdditionalDependencies>
<ProgramDatabaseFile>..\rundir\pdb64\$(TargetName).pdb</ProgramDatabaseFile>
<StripPrivateSymbols>..\rundir\pdb64\stripped\$(TargetName).pdb</StripPrivateSymbols>
</Link>
<PostBuildEvent>
<Command>copy $(OutDir)$(ProjectName).dll ..\rundir\plugins</Command>
</PostBuildEvent>
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
<ClCompile>
<WarningLevel>Level3</WarningLevel>
<PrecompiledHeader>
</PrecompiledHeader>
<Optimization>MaxSpeed</Optimization>
<FunctionLevelLinking>true</FunctionLevelLinking>
<IntrinsicFunctions>true</IntrinsicFunctions>
<PreprocessorDefinitions>WIN32;NDEBUG;_WINDOWS;_USRDLL;SCENESW_EXPORTS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<AdditionalIncludeDirectories>../OBSApi;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<RuntimeLibrary>MultiThreaded</RuntimeLibrary>
<AdditionalOptions>/Zo %(AdditionalOptions)</AdditionalOptions>
</ClCompile>
<Link>
<SubSystem>Windows</SubSystem>
<GenerateDebugInformation>true</GenerateDebugInformation>
<EnableCOMDATFolding>true</EnableCOMDATFolding>
<OptimizeReferences>true</OptimizeReferences>
<AdditionalLibraryDirectories>../OBSApi/Release;%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
<AdditionalDependencies>OBSApi.lib;%(AdditionalDependencies)</AdditionalDependencies>
<ProgramDatabaseFile>..\rundir\pdb32\$(TargetName).pdb</ProgramDatabaseFile>
<StripPrivateSymbols>..\rundir\pdb32\stripped\$(TargetName).pdb</StripPrivateSymbols>
</Link>
<PostBuildEvent>
<Command>copy $(OutDir)$(ProjectName).dll ..\rundir\plugins</Command>
</PostBuildEvent>
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
<ClCompile>
<WarningLevel>Level3</WarningLevel>
<PrecompiledHeader>
</PrecompiledHeader>
<Optimization>MaxSpeed</Optimization>
<FunctionLevelLinking>true</FunctionLevelLinking>
<IntrinsicFunctions>true</IntrinsicFunctions>
<PreprocessorDefinitions>WIN32;NDEBUG;_WINDOWS;_USRDLL;SCENESW_EXPORTS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<AdditionalIncludeDirectories>../OBSApi;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<RuntimeLibrary>MultiThreaded</RuntimeLibrary>
<AdditionalOptions>/d2Zi+ %(AdditionalOptions)</AdditionalOptions>
</ClCompile>
<Link>
<SubSystem>Windows</SubSystem>
<GenerateDebugInformation>true</GenerateDebugInformation>
<EnableCOMDATFolding>true</EnableCOMDATFolding>
<OptimizeReferences>true</OptimizeReferences>
<AdditionalDependencies>OBSApi.lib;%(AdditionalDependencies)</AdditionalDependencies>
<AdditionalLibraryDirectories>../OBSApi/x64/Release;%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
<ProgramDatabaseFile>..\rundir\pdb64\$(TargetName).pdb</ProgramDatabaseFile>
<StripPrivateSymbols>..\rundir\pdb64\stripped\$(TargetName).pdb</StripPrivateSymbols>
</Link>
<PostBuildEvent>
<Command>copy $(OutDir)$(ProjectName).dll ..\rundir\plugins</Command>
</PostBuildEvent>
</ItemDefinitionGroup>
<ItemGroup>
<ClCompile Include="scenesw.cpp" />
<ClCompile Include="SceneSwitcher.cpp" />
<ClCompile Include="SceneSwitcherSettings.cpp" />
</ItemGroup>
<ItemGroup>
<ClInclude Include="scenesw.h" />
<ClInclude Include="resource.h" />
<ClInclude Include="SceneSwitcher.h" />
</ItemGroup>
<ItemGroup>
<ResourceCompile Include="scenesw.rc" />
</ItemGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
<ImportGroup Label="ExtensionTargets">
</ImportGroup>
</Project>

View File

@ -0,0 +1,44 @@
<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<ItemGroup>
<Filter Include="Source Files">
<UniqueIdentifier>{4FC737F1-C7A5-4376-A066-2A32D752A2FF}</UniqueIdentifier>
<Extensions>cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx</Extensions>
</Filter>
<Filter Include="Header Files">
<UniqueIdentifier>{93995380-89BD-4b04-88EB-625FBE52EBFB}</UniqueIdentifier>
<Extensions>h;hpp;hxx;hm;inl;inc;xsd</Extensions>
</Filter>
<Filter Include="Resource Files">
<UniqueIdentifier>{67DA6AB6-F800-4c08-8B7A-83BB121AAD01}</UniqueIdentifier>
<Extensions>rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms</Extensions>
</Filter>
</ItemGroup>
<ItemGroup>
<ClCompile Include="scenesw.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="SceneSwitcher.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="SceneSwitcherSettings.cpp">
<Filter>Source Files</Filter>
</ClCompile>
</ItemGroup>
<ItemGroup>
<ClInclude Include="scenesw.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="resource.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="SceneSwitcher.h">
<Filter>Header Files</Filter>
</ClInclude>
</ItemGroup>
<ItemGroup>
<ResourceCompile Include="scenesw.rc">
<Filter>Resource Files</Filter>
</ResourceCompile>
</ItemGroup>
</Project>