obs/Source/DesktopImageSource.cpp
paibox 38635c4632 Fix Window Capture for windows with no title
Windows with no title now display the process name instead, and does not
break the window order in the list.
2013-11-10 13:38:41 +01:00

2071 lines
78 KiB
C++

/********************************************************************************
Copyright (C) 2012 Hugh Bailey <obs.jim@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 "Main.h"
#include <dwmapi.h>
#define NUM_CAPTURE_TEXTURES 2
class DesktopImageSource : public ImageSource
{
Texture *renderTextures[NUM_CAPTURE_TEXTURES];
Texture *lastRendered;
UINT captureType;
String strWindow, strWindowClass;
BOOL bClientCapture, bCaptureMouse, bCaptureLayered;
HWND hwndFoundWindow;
Shader *colorKeyShader, *alphaIgnoreShader;
int width, height;
RECT captureRect;
UINT frameTime;
int curCaptureTexture;
XElement *data;
UINT warningID;
bool bUseColorKey, bUsePointFiltering;
DWORD keyColor;
UINT keySimilarity, keyBlend;
UINT opacity;
int gamma;
float rotateDegrees;
//-------------------------
// stuff for compatibility mode
bool bCompatibilityMode;
HDC hdcCompatible;
HBITMAP hbmpCompatible, hbmpOld;
BYTE *captureBits;
//-------------------------
// win 8 capture stuff
Texture *cursorTexture;
int xHotspot, yHotspot;
UINT monitor;
UINT deviceOutputID;
float retryAcquire;
bool bWindows8MonitorCapture;
MonitorInfo monitorData;
bool bMouseCaptured;
POINT cursorPos;
HCURSOR hCurrentCursor;
bool bInInit;
OutputDuplicator *duplicator;
public:
DesktopImageSource(UINT frameTime, XElement *data)
{
this->data = data;
duplicator = NULL;
bInInit = true;
UpdateSettings();
bInInit = false;
curCaptureTexture = 0;
this->frameTime = frameTime;
colorKeyShader = CreatePixelShaderFromFile(TEXT("shaders\\ColorKey_RGB.pShader"));
alphaIgnoreShader = CreatePixelShaderFromFile(TEXT("shaders\\AlphaIgnore.pShader"));
if(captureType == 0)
Log(TEXT("Using Monitor Capture"));
else if(captureType == 1)
Log(TEXT("Using Window Capture"));
}
~DesktopImageSource()
{
for(int i=0; i<NUM_CAPTURE_TEXTURES; i++)
delete renderTextures[i];
if(warningID)
App->RemoveStreamInfo(warningID);
delete duplicator;
delete cursorTexture;
delete alphaIgnoreShader;
delete colorKeyShader;
if(bCompatibilityMode)
{
SelectObject(hdcCompatible, hbmpOld);
DeleteDC(hdcCompatible);
DeleteObject(hbmpCompatible);
}
}
void BeginScene()
{
if(bWindows8MonitorCapture && !duplicator)
duplicator = GS->CreateOutputDuplicator(deviceOutputID);
}
void EndScene()
{
if(bWindows8MonitorCapture && duplicator)
{
delete duplicator;
duplicator = NULL;
}
}
//----------------------------------------------------------------------------------
// TODO - have win8 monitor capture behave even when using it as a global source
void GlobalSourceEnterScene()
{
}
void GlobalSourceLeaveScene()
{
}
//----------------------------------------------------------------------------------
void Tick(float fSeconds)
{
if(bWindows8MonitorCapture && !duplicator)
{
retryAcquire += fSeconds;
if(retryAcquire > 1.0f)
{
retryAcquire = 0.0f;
lastRendered = NULL;
duplicator = GS->CreateOutputDuplicator(deviceOutputID);
}
}
}
void PreprocessWindows8MonitorCapture()
{
//----------------------------------------------------------
// capture monitor
if(duplicator)
{
switch(duplicator->AcquireNextFrame(0))
{
case DuplicatorInfo_Lost:
{
delete duplicator;
lastRendered = NULL;
duplicator = GS->CreateOutputDuplicator(deviceOutputID);
return;
}
case DuplicatorInfo_Error:
delete duplicator;
duplicator = NULL;
lastRendered = NULL;
return;
case DuplicatorInfo_Timeout:
return;
}
lastRendered = duplicator->GetCopyTexture();
}
//----------------------------------------------------------
// capture mouse
bMouseCaptured = false;
if(bCaptureMouse)
{
CURSORINFO ci;
zero(&ci, sizeof(ci));
ci.cbSize = sizeof(ci);
if(GetCursorInfo(&ci))
{
mcpy(&cursorPos, &ci.ptScreenPos, sizeof(cursorPos));
if(ci.flags & CURSOR_SHOWING)
{
if(ci.hCursor == hCurrentCursor)
bMouseCaptured = true;
else
{
HICON hIcon = CopyIcon(ci.hCursor);
hCurrentCursor = ci.hCursor;
delete cursorTexture;
cursorTexture = NULL;
if(hIcon)
{
ICONINFO ii;
if(GetIconInfo(hIcon, &ii))
{
xHotspot = int(ii.xHotspot);
yHotspot = int(ii.yHotspot);
UINT width, height;
LPBYTE lpData = GetCursorData(hIcon, ii, width, height);
if(lpData && width && height)
{
cursorTexture = CreateTexture(width, height, GS_BGRA, lpData, FALSE);
if(cursorTexture)
bMouseCaptured = true;
Free(lpData);
}
DeleteObject(ii.hbmColor);
DeleteObject(ii.hbmMask);
}
DestroyIcon(hIcon);
}
}
}
}
}
}
HDC GetCurrentHDC()
{
HDC hDC = NULL;
Texture *captureTexture = renderTextures[curCaptureTexture];
if(bCompatibilityMode)
{
hDC = hdcCompatible;
//zero(captureBits, width*height*4);
}
else if(captureTexture)
captureTexture->GetDC(hDC);
return hDC;
}
void ReleaseCurrentHDC(HDC hDC)
{
Texture *captureTexture = renderTextures[curCaptureTexture];
if(!bCompatibilityMode)
captureTexture->ReleaseDC();
}
void EndPreprocess()
{
if(bCompatibilityMode)
{
renderTextures[0]->SetImage(captureBits, GS_IMAGEFORMAT_BGRA, width*4);
lastRendered = renderTextures[0];
}
else
{
lastRendered = renderTextures[curCaptureTexture];
if(++curCaptureTexture == NUM_CAPTURE_TEXTURES)
curCaptureTexture = 0;
}
}
void Preprocess()
{
if(bWindows8MonitorCapture)
{
PreprocessWindows8MonitorCapture();
return;
}
HDC hDC;
if(hDC = GetCurrentHDC())
{
//----------------------------------------------------------
// capture screen
CURSORINFO ci;
zero(&ci, sizeof(ci));
ci.cbSize = sizeof(ci);
BOOL bMouseCaptured;
bMouseCaptured = bCaptureMouse && GetCursorInfo(&ci);
bool bWindowNotFound = false;
HWND hwndCapture = NULL;
if(captureType == 1)
{
if(hwndFoundWindow && IsWindow(hwndFoundWindow))
{
TCHAR lpClassName[256];
BOOL bSuccess = GetClassName(hwndFoundWindow, lpClassName, 255);
if(bSuccess && scmpi(lpClassName, strWindowClass) == 0)
hwndCapture = hwndFoundWindow;
else
{
hwndCapture = FindWindow(strWindowClass, strWindow);
if(!hwndCapture)
hwndCapture = FindWindow(strWindowClass, NULL);
}
}
else
{
hwndCapture = FindWindow(strWindowClass, strWindow);
if(!hwndCapture)
hwndCapture = FindWindow(strWindowClass, NULL);
}
//note to self - hwndFoundWindow is used to make sure it doesn't pick up another window unintentionally if the title changes
hwndFoundWindow = hwndCapture;
if(!hwndCapture)
bWindowNotFound = true;
if(hwndCapture && (IsIconic(hwndCapture) || !IsWindowVisible(hwndCapture)))
{
ReleaseCurrentHDC(hDC);
//bWindowMinimized = true;
if(!warningID)
{
String strWarning;
strWarning << Str("Sources.SoftwareCaptureSource.WindowMinimized");
warningID = App->AddStreamInfo(strWarning, bWindowNotFound ? StreamInfoPriority_High : StreamInfoPriority_Medium);
}
return;
}
else if(!bWindowNotFound)
{
if(warningID)
{
App->RemoveStreamInfo(warningID);
warningID = 0;
}
}
}
HDC hCaptureDC;
if(hwndCapture && captureType == 1 && !bClientCapture)
hCaptureDC = GetWindowDC(hwndCapture);
else
hCaptureDC = GetDC(hwndCapture);
if(bWindowNotFound)
{
RECT rc = {0, 0, width, height};
FillRect(hDC, &rc, (HBRUSH)GetStockObject(BLACK_BRUSH));
if(!warningID)
warningID = App->AddStreamInfo(Str("Sources.SoftwareCaptureSource.WindowNotFound"), bWindowNotFound ? StreamInfoPriority_High : StreamInfoPriority_Medium);
}
else
{
//CAPTUREBLT causes mouse flicker, so make capturing layered optional
if(!BitBlt(hDC, 0, 0, width, height, hCaptureDC, captureRect.left, captureRect.top, bCaptureLayered ? SRCCOPY|CAPTUREBLT : SRCCOPY))
{
RUNONCE AppWarning(TEXT("Capture BitBlt failed (%d).. just so you know"), GetLastError());
}
}
ReleaseDC(hwndCapture, hCaptureDC);
//----------------------------------------------------------
// capture mouse
if(bMouseCaptured && (captureType == 0 || (captureType == 1 && hwndFoundWindow == GetForegroundWindow())))
{
if(ci.flags & CURSOR_SHOWING)
{
HICON hIcon = CopyIcon(ci.hCursor);
if(hIcon)
{
ICONINFO ii;
if(GetIconInfo(hIcon, &ii))
{
POINT capturePos = {captureRect.left, captureRect.top};
if(captureType == 1)
{
if(bClientCapture)
ClientToScreen(hwndCapture, &capturePos);
else
{
RECT windowRect;
GetWindowRect(hwndCapture, &windowRect);
capturePos.x += windowRect.left;
capturePos.y += windowRect.top;
}
}
int x = ci.ptScreenPos.x - int(ii.xHotspot) - capturePos.x;
int y = ci.ptScreenPos.y - int(ii.yHotspot) - capturePos.y;
DrawIcon(hDC, x, y, hIcon);
DeleteObject(ii.hbmColor);
DeleteObject(ii.hbmMask);
}
DestroyIcon(hIcon);
}
}
}
ReleaseCurrentHDC(hDC);
}
else
{
RUNONCE AppWarning(TEXT("Failed to get DC from capture surface"));
}
EndPreprocess();
}
void Render(const Vect2 &pos, const Vect2 &size)
{
SamplerState *sampler = NULL;
/*if(bWindows8MonitorCapture)
{
RenderWindows8MonitorCapture(pos, size);
return;
}*/
Vect2 ulCoord = Vect2(0.0f, 0.0f),
lrCoord = Vect2(1.0f, 1.0f);
if(bWindows8MonitorCapture)
{
LONG monitorWidth = monitorData.rect.right-monitorData.rect.left;
LONG monitorHeight = monitorData.rect.bottom-monitorData.rect.top;
RECT captureArea = {captureRect.left-monitorData.rect.left,
captureRect.top-monitorData.rect.top,
captureRect.right-monitorData.rect.left,
captureRect.bottom-monitorData.rect.top};
ulCoord.x = float(double(captureArea.left)/double(monitorWidth));
ulCoord.y = float(double(captureArea.top)/double(monitorHeight));
lrCoord.x = float(double(captureArea.right)/double(monitorWidth));
lrCoord.y = float(double(captureArea.bottom)/double(monitorHeight));
}
if(lastRendered)
{
float fGamma = float(-(gamma-100) + 100) * 0.01f;
Shader *lastPixelShader = GetCurrentPixelShader();
float fOpacity = float(opacity)*0.01f;
DWORD opacity255 = DWORD(fOpacity*255.0f);
if(bUseColorKey)
{
LoadPixelShader(colorKeyShader);
HANDLE hGamma = colorKeyShader->GetParameterByName(TEXT("gamma"));
if(hGamma)
colorKeyShader->SetFloat(hGamma, fGamma);
float fSimilarity = float(keySimilarity)*0.01f;
float fBlend = float(keyBlend)*0.01f;
colorKeyShader->SetColor(colorKeyShader->GetParameter(2), keyColor);
colorKeyShader->SetFloat(colorKeyShader->GetParameter(3), fSimilarity);
colorKeyShader->SetFloat(colorKeyShader->GetParameter(4), fBlend);
}
else
{
LoadPixelShader(alphaIgnoreShader);
HANDLE hGamma = alphaIgnoreShader->GetParameterByName(TEXT("gamma"));
if(hGamma)
alphaIgnoreShader->SetFloat(hGamma, fGamma);
}
if(bUsePointFiltering) {
SamplerInfo samplerinfo;
samplerinfo.filter = GS_FILTER_POINT;
sampler = CreateSamplerState(samplerinfo);
LoadSamplerState(sampler, 0);
}
if(bCompatibilityMode)
DrawSpriteEx(lastRendered, (opacity255<<24) | 0xFFFFFF,
pos.x, pos.y+size.y, pos.x+size.x, pos.y,
ulCoord.x, ulCoord.y,
lrCoord.x, lrCoord.y);
else
GS->DrawSpriteExRotate(lastRendered, (opacity255<<24) | 0xFFFFFF,
pos.x, pos.y, pos.x+size.x, pos.y+size.y, 0.0f,
ulCoord.x, ulCoord.y,
lrCoord.x, lrCoord.y, rotateDegrees);
if(bUsePointFiltering) delete(sampler);
LoadPixelShader(lastPixelShader);
//draw mouse
if(bWindows8MonitorCapture && cursorTexture && bMouseCaptured && bCaptureMouse)
{
POINT newPos = {cursorPos.x-xHotspot, cursorPos.y-yHotspot};
if( newPos.x >= captureRect.left && newPos.y >= captureRect.top &&
newPos.x < captureRect.right && newPos.y < captureRect.bottom)
{
Vect2 newCursorPos = Vect2(float(newPos.x-captureRect.left), float(newPos.y-captureRect.top));
Vect2 newCursorSize = Vect2(float(cursorTexture->Width()), float(cursorTexture->Height()));
Vect2 sizeMultiplier = size/GetSize();
newCursorPos *= sizeMultiplier;
newCursorPos += pos;
newCursorSize *= sizeMultiplier;
DrawSprite(cursorTexture, 0xFFFFFFFF, newCursorPos.x, newCursorPos.y, newCursorPos.x+newCursorSize.x, newCursorPos.y+newCursorSize.y);
}
}
}
}
Vect2 GetSize() const
{
return Vect2(float(width), float(height));
}
void UpdateSettings()
{
App->EnterSceneMutex();
UINT newCaptureType = data->GetInt(TEXT("captureType"));
String strNewWindow = data->GetString(TEXT("window"));
String strNewWindowClass= data->GetString(TEXT("windowClass"));
BOOL bNewClientCapture = data->GetInt(TEXT("innerWindow"), 1);
bCaptureMouse = data->GetInt(TEXT("captureMouse"), 1);
bCaptureLayered = data->GetInt(TEXT("captureLayered"), 0);
bool bNewUsePointFiltering = data->GetInt(TEXT("usePointFiltering"), 0) != 0;
int x = data->GetInt(TEXT("captureX"));
int y = data->GetInt(TEXT("captureY"));
int cx = data->GetInt(TEXT("captureCX"), 32);
int cy = data->GetInt(TEXT("captureCY"), 32);
bool bNewCompatibleMode = data->GetInt(TEXT("compatibilityMode")) != 0;
if(bNewCompatibleMode && (OSGetVersion() >= 8 && newCaptureType == 0))
bNewCompatibleMode = false;
gamma = data->GetInt(TEXT("gamma"), 100);
if(gamma < 50) gamma = 50;
else if(gamma > 175) gamma = 175;
UINT newMonitor = data->GetInt(TEXT("monitor"));
if(newMonitor > App->NumMonitors())
newMonitor = 0;
if( captureRect.left != x || captureRect.right != (x+cx) || captureRect.top != cy || captureRect.bottom != (y+cy) ||
newCaptureType != captureType || !strNewWindowClass.CompareI(strWindowClass) || !strNewWindow.CompareI(strWindow) ||
bNewClientCapture != bClientCapture || (OSGetVersion() >= 8 && newMonitor != monitor) ||
bNewCompatibleMode != bCompatibilityMode)
{
for(int i=0; i<NUM_CAPTURE_TEXTURES; i++)
{
delete renderTextures[i];
renderTextures[i] = NULL;
}
if(duplicator)
{
delete duplicator;
duplicator = NULL;
}
if(cursorTexture)
{
delete cursorTexture;
cursorTexture = NULL;
}
if(bCompatibilityMode)
{
SelectObject(hdcCompatible, hbmpOld);
DeleteDC(hdcCompatible);
DeleteObject(hbmpCompatible);
hdcCompatible = NULL;
hbmpCompatible = NULL;
captureBits = NULL;
}
hCurrentCursor = NULL;
captureType = newCaptureType;
strWindow = strNewWindow;
strWindowClass = strNewWindowClass;
bClientCapture = bNewClientCapture;
bCompatibilityMode = bNewCompatibleMode;
bUsePointFiltering = bNewUsePointFiltering;
captureRect.left = x;
captureRect.top = y;
captureRect.right = x+cx;
captureRect.bottom = y+cy;
monitor = newMonitor;
const MonitorInfo &monitorInfo = App->GetMonitor(monitor);
mcpy(&monitorData, &monitorInfo, sizeof(monitorInfo));
rotateDegrees = 0.0f;
if(captureType == 0 && OSGetVersion() >= 8)
{
LONG monitorWidth = monitorInfo.rect.right-monitorInfo.rect.left;
LONG monitorHeight = monitorInfo.rect.bottom-monitorInfo.rect.top;
DeviceOutputs outputs;
GetDisplayDevices(outputs);
bWindows8MonitorCapture = false;
if(outputs.devices.Num())
{
const MonitorInfo &info = App->GetMonitor(monitor);
for(UINT j=0; j<outputs.devices[0].monitors.Num(); j++)
{
if(outputs.devices[0].monitors[j].hMonitor == info.hMonitor)
{
deviceOutputID = j;
rotateDegrees = outputs.devices[0].monitors[j].rotationDegrees;
bWindows8MonitorCapture = true;
}
}
}
}
width = cx;
height = cy;
if(bCompatibilityMode)
{
hdcCompatible = CreateCompatibleDC(NULL);
BITMAPINFO bi;
zero(&bi, sizeof(bi));
BITMAPINFOHEADER &bih = bi.bmiHeader;
bih.biSize = sizeof(bih);
bih.biBitCount = 32;
bih.biWidth = width;
bih.biHeight = height;
bih.biPlanes = 1;
hbmpCompatible = CreateDIBSection(hdcCompatible, &bi, DIB_RGB_COLORS, (void**)&captureBits, NULL, 0);
hbmpOld = (HBITMAP)SelectObject(hdcCompatible, hbmpCompatible);
}
if(bWindows8MonitorCapture && !bInInit)
duplicator = GS->CreateOutputDuplicator(deviceOutputID);
else if(bCompatibilityMode)
renderTextures[0] = CreateTexture(width, height, GS_BGRA, NULL, FALSE, FALSE);
else
{
for(UINT i=0; i<NUM_CAPTURE_TEXTURES; i++)
renderTextures[i] = CreateGDITexture(width, height);
}
lastRendered = NULL;
}
bool bNewUseColorKey = data->GetInt(TEXT("useColorKey"), 0) != 0;
keyColor = data->GetInt(TEXT("keyColor"), 0xFFFFFFFF);
keySimilarity = data->GetInt(TEXT("keySimilarity"), 10);
keyBlend = data->GetInt(TEXT("keyBlend"), 0);
bUsePointFiltering = data->GetInt(TEXT("usePointFiltering"), 0) != 0;
bUseColorKey = bNewUseColorKey;
opacity = data->GetInt(TEXT("opacity"), 100);
App->LeaveSceneMutex();
}
void SetInt(CTSTR lpName, int iVal)
{
if(scmpi(lpName, TEXT("useColorKey")) == 0)
{
bool bNewVal = iVal != 0;
bUseColorKey = bNewVal;
}
else if(scmpi(lpName, TEXT("keyColor")) == 0)
{
keyColor = (DWORD)iVal;
}
else if(scmpi(lpName, TEXT("keySimilarity")) == 0)
{
keySimilarity = iVal;
}
else if(scmpi(lpName, TEXT("keyBlend")) == 0)
{
keyBlend = iVal;
}
else if(scmpi(lpName, TEXT("opacity")) == 0)
{
opacity = (UINT)iVal;
}
else if(scmpi(lpName, TEXT("gamma")) == 0)
{
gamma = iVal;
if(gamma < 50) gamma = 50;
else if(gamma > 175) gamma = 175;
}
}
};
ImageSource* STDCALL CreateDesktopSource(XElement *data)
{
if(!data)
return NULL;
return new DesktopImageSource(App->GetFrameTime(), data);
}
void RefreshWindowList(HWND hwndCombobox, StringList &classList)
{
SendMessage(hwndCombobox, CB_RESETCONTENT, 0, 0);
classList.Clear();
HWND hwndCurrent = GetWindow(GetDesktopWindow(), GW_CHILD);
do
{
if(IsWindowVisible(hwndCurrent) && !IsIconic(hwndCurrent))
{
RECT clientRect;
GetClientRect(hwndCurrent, &clientRect);
DWORD exStyles = (DWORD)GetWindowLongPtr(hwndCurrent, GWL_EXSTYLE);
DWORD styles = (DWORD)GetWindowLongPtr(hwndCurrent, GWL_STYLE);
if( (exStyles & WS_EX_TOOLWINDOW) == 0 && (styles & WS_CHILD) == 0 &&
clientRect.bottom != 0 && clientRect.right != 0 /*&& hwndParent == NULL*/)
{
String strWindowName;
strWindowName.SetLength(GetWindowTextLength(hwndCurrent));
GetWindowText(hwndCurrent, strWindowName, strWindowName.Length()+1);
//-------
DWORD processID;
GetWindowThreadProcessId(hwndCurrent, &processID);
if(processID == GetCurrentProcessId())
continue;
TCHAR fileName[MAX_PATH+1];
scpy(fileName, TEXT("unknown"));
HANDLE hProcess = OpenProcess(PROCESS_QUERY_LIMITED_INFORMATION, FALSE, processID);
if(hProcess)
{
DWORD dwSize = MAX_PATH;
QueryFullProcessImageName(hProcess, 0, fileName, &dwSize);
CloseHandle(hProcess);
}
//-------
String strFileName = fileName;
strFileName.FindReplace(TEXT("\\"), TEXT("/"));
String strText;
strText << TEXT("[") << GetPathFileName(strFileName) << TEXT("]: ") << strWindowName;
if(strWindowName.IsEmpty()) strWindowName = GetPathFileName(strFileName);
int id = (int)SendMessage(hwndCombobox, CB_ADDSTRING, 0, (LPARAM)strWindowName.Array());
SendMessage(hwndCombobox, CB_SETITEMDATA, id, (LPARAM)hwndCurrent);
String strClassName;
strClassName.SetLength(256);
GetClassName(hwndCurrent, strClassName.Array(), 255);
strClassName.SetLength(slen(strClassName));
classList << strClassName;
}
}
} while (hwndCurrent = GetNextWindow(hwndCurrent, GW_HWNDNEXT));
}
struct ConfigDesktopSourceInfo
{
CTSTR lpName;
XElement *data;
int dialogID;
StringList strClasses;
};
void SetDesktopCaptureType(HWND hwnd, UINT type)
{
SendMessage(GetDlgItem(hwnd, IDC_MONITORCAPTURE), BM_SETCHECK, type == 0 ? BST_CHECKED : BST_UNCHECKED, 0);
SendMessage(GetDlgItem(hwnd, IDC_WINDOWCAPTURE), BM_SETCHECK, type == 1 ? BST_CHECKED : BST_UNCHECKED, 0);
EnableWindow(GetDlgItem(hwnd, IDC_MONITOR), type == 0);
EnableWindow(GetDlgItem(hwnd, IDC_WINDOW), type == 1);
EnableWindow(GetDlgItem(hwnd, IDC_REFRESH), type == 1);
EnableWindow(GetDlgItem(hwnd, IDC_OUTERWINDOW), type == 1);
EnableWindow(GetDlgItem(hwnd, IDC_INNERWINDOW), type == 1);
}
void SelectTargetWindow(HWND hwnd, bool bRefresh)
{
HWND hwndWindowList = GetDlgItem(hwnd, IDC_WINDOW);
UINT windowID = (UINT)SendMessage(hwndWindowList, CB_GETCURSEL, 0, 0);
if(windowID == CB_ERR)
return;
String strWindow = GetCBText(hwndWindowList, windowID);
ConfigDesktopSourceInfo *info = (ConfigDesktopSourceInfo*)GetWindowLongPtr(hwnd, DWLP_USER);
if(windowID >= info->strClasses.Num())
return;
HWND hwndTarget = FindWindow(info->strClasses[windowID], strWindow);
if(!hwndTarget)
{
HWND hwndLastKnownHWND = (HWND)SendMessage(hwndWindowList, CB_GETITEMDATA, windowID, 0);
if(IsWindow(hwndLastKnownHWND))
hwndTarget = hwndLastKnownHWND;
else
hwndTarget = FindWindow(info->strClasses[windowID], NULL);
}
if(!hwndTarget)
return;
//------------------------------------------
BOOL bInnerWindow = SendMessage(GetDlgItem(hwnd, IDC_INNERWINDOW), BM_GETCHECK, 0, 0) == BST_CHECKED;
RECT rc;
if(bInnerWindow)
GetClientRect(hwndTarget, &rc);
else
{
GetWindowRect(hwndTarget, &rc);
rc.bottom -= rc.top;
rc.right -= rc.left;
rc.left = rc.top = 0;
}
//------------------------------------------
rc.bottom -= rc.top;
rc.right -= rc.left;
if(rc.right < 16)
rc.right = 16;
if(rc.bottom < 16)
rc.bottom = 16;
BOOL bRegion = SendMessage(GetDlgItem(hwnd, IDC_REGIONCAPTURE), BM_GETCHECK, 0, 0) == BST_CHECKED;
if(!bRegion || bRefresh)
{
SetWindowText(GetDlgItem(hwnd, IDC_POSX), IntString(rc.left).Array());
SetWindowText(GetDlgItem(hwnd, IDC_POSY), IntString(rc.top).Array());
SetWindowText(GetDlgItem(hwnd, IDC_SIZEX), IntString(rc.right).Array());
SetWindowText(GetDlgItem(hwnd, IDC_SIZEY), IntString(rc.bottom).Array());
}
}
struct RegionWindowData
{
HWND hwndConfigDialog, hwndCaptureWindow;
POINT startPos;
RECT captureRect;
bool bMovingWindow;
bool bInnerWindowRegion;
inline RegionWindowData()
{
bMovingWindow = false;
bInnerWindowRegion = false;
}
};
RegionWindowData regionWindowData;
#define CAPTUREREGIONCLASS TEXT("CaptureRegionThingy")
LRESULT WINAPI RegionWindowProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
{
if(message == WM_MOUSEMOVE)
{
RECT client;
GetClientRect(hwnd, &client);
POINT pos;
pos.x = (long)(short)LOWORD(lParam);
pos.y = (long)(short)HIWORD(lParam);
if(regionWindowData.bMovingWindow)
{
RECT rc;
GetWindowRect(hwnd, &rc);
POINT posOffset = {pos.x-regionWindowData.startPos.x, pos.y-regionWindowData.startPos.y};
POINT newPos = {rc.left+posOffset.x, rc.top+posOffset.y};
SIZE windowSize = {rc.right-rc.left, rc.bottom-rc.top};
if(newPos.x < regionWindowData.captureRect.left)
newPos.x = regionWindowData.captureRect.left;
if(newPos.y < regionWindowData.captureRect.top)
newPos.y = regionWindowData.captureRect.top;
POINT newBottomRight = {rc.right+posOffset.x, rc.bottom+posOffset.y};
if(newBottomRight.x > regionWindowData.captureRect.right)
newPos.x -= (newBottomRight.x-regionWindowData.captureRect.right);
if(newBottomRight.y > regionWindowData.captureRect.bottom)
newPos.y -= (newBottomRight.y-regionWindowData.captureRect.bottom);
SetWindowPos(hwnd, NULL, newPos.x, newPos.y, 0, 0, SWP_NOSIZE|SWP_NOZORDER);
}
else
{
BOOL bLeft = (pos.x < 6);
BOOL bTop = (pos.y < 6);
BOOL bRight = (!bLeft && (pos.x > client.right-6));
BOOL bBottom = (!bTop && (pos.y > client.bottom-6));
if(bLeft)
{
if(bTop)
SetCursor(LoadCursor(NULL, IDC_SIZENWSE));
else if(bBottom)
SetCursor(LoadCursor(NULL, IDC_SIZENESW));
else
SetCursor(LoadCursor(NULL, IDC_SIZEWE));
}
else if(bRight)
{
if(bTop)
SetCursor(LoadCursor(NULL, IDC_SIZENESW));
else if(bBottom)
SetCursor(LoadCursor(NULL, IDC_SIZENWSE));
else
SetCursor(LoadCursor(NULL, IDC_SIZEWE));
}
else if(bTop || bBottom)
SetCursor(LoadCursor(NULL, IDC_SIZENS));
}
return 0;
}
else if(message == WM_LBUTTONDOWN)
{
RECT client;
GetClientRect(hwnd, &client);
POINT pos;
pos.x = (long)LOWORD(lParam);
pos.y = (long)HIWORD(lParam);
BOOL bLeft = (pos.x < 6);
BOOL bTop = (pos.y < 6);
BOOL bRight = (!bLeft && (pos.x > client.right-6));
BOOL bBottom = (!bTop && (pos.y > client.bottom-6));
ClientToScreen(hwnd, &pos);
POINTS newPos;
newPos.x = (SHORT)pos.x;
newPos.y = (SHORT)pos.y;
SendMessage(hwnd, WM_MOUSEMOVE, 0, lParam);
if(bLeft)
{
if(bTop)
SendMessage(hwnd, WM_NCLBUTTONDOWN, HTTOPLEFT, (LPARAM)&newPos);
else if(bBottom)
SendMessage(hwnd, WM_NCLBUTTONDOWN, HTBOTTOMLEFT, (LPARAM)&newPos);
else
SendMessage(hwnd, WM_NCLBUTTONDOWN, HTLEFT, (LPARAM)&newPos);
}
else if(bRight)
{
if(bTop)
SendMessage(hwnd, WM_NCLBUTTONDOWN, HTTOPRIGHT, (LPARAM)&newPos);
else if(bBottom)
SendMessage(hwnd, WM_NCLBUTTONDOWN, HTBOTTOMRIGHT, (LPARAM)&newPos);
else
SendMessage(hwnd, WM_NCLBUTTONDOWN, HTRIGHT, (LPARAM)&newPos);
}
else if(bTop)
SendMessage(hwnd, WM_NCLBUTTONDOWN, HTTOP, (LPARAM)&newPos);
else if(bBottom)
SendMessage(hwnd, WM_NCLBUTTONDOWN, HTBOTTOM, (LPARAM)&newPos);
else
{
regionWindowData.bMovingWindow = true; //can't use HTCAPTION -- if holding down long enough, other windows minimize
pos.x = (long)(short)LOWORD(lParam);
pos.y = (long)(short)HIWORD(lParam);
mcpy(&regionWindowData.startPos, &pos, sizeof(pos));
SetCapture(hwnd);
}
return 0;
}
else if(message == WM_LBUTTONUP)
{
if(regionWindowData.bMovingWindow)
{
regionWindowData.bMovingWindow = false;
ReleaseCapture();
}
}
else if(message == WM_PAINT)
{
PAINTSTRUCT ps;
HDC hDC = BeginPaint(hwnd, &ps);
if(hDC)
{
RECT clientRect;
GetClientRect(hwnd, &clientRect);
//-----------------------------------------
HPEN oldPen = (HPEN)SelectObject(hDC, GetStockObject(BLACK_PEN));
MoveToEx(hDC, 0, 0, NULL);
LineTo(hDC, clientRect.right-1, 0);
LineTo(hDC, clientRect.right-1, clientRect.bottom-1);
LineTo(hDC, 0, clientRect.bottom-1);
LineTo(hDC, 0, 0);
MoveToEx(hDC, 5, 5, NULL);
LineTo(hDC, clientRect.right-6, 5);
LineTo(hDC, clientRect.right-6, clientRect.bottom-6);
LineTo(hDC, 5, clientRect.bottom-6);
LineTo(hDC, 5, 5);
SelectObject(hDC, oldPen);
//-----------------------------------------
CTSTR lpStr = Str("Sources.SoftwareCaptureSource.RegionWindowText");
HFONT hFont = (HFONT)GetStockObject(DEFAULT_GUI_FONT);
HFONT hfontOld = (HFONT)SelectObject(hDC, hFont);
SIZE textExtent;
GetTextExtentPoint32(hDC, lpStr, slen(lpStr), &textExtent);
SetBkMode(hDC, TRANSPARENT);
SetTextAlign(hDC, TA_CENTER);
TextOut(hDC, clientRect.right/2, (clientRect.bottom - textExtent.cy)/2, lpStr, slen(lpStr));
//-----------------------------------------
SelectObject(hDC, hfontOld);
EndPaint(hwnd, &ps);
}
}
else if(message == WM_KEYDOWN)
{
if(wParam == VK_ESCAPE || wParam == VK_RETURN || wParam == 'Q')
DestroyWindow(hwnd);
}
else if(message == WM_SIZING)
{
RECT &rc = *(RECT*)lParam;
bool bTop = wParam == WMSZ_TOPLEFT || wParam == WMSZ_TOPRIGHT || wParam == WMSZ_TOP;
bool bLeft = wParam == WMSZ_TOPLEFT || wParam == WMSZ_LEFT || wParam == WMSZ_BOTTOMLEFT;
if(bLeft)
{
if(rc.right-rc.left < 16)
rc.left = rc.right-16;
}
else
{
if(rc.right-rc.left < 16)
rc.right = rc.left+16;
}
if(bTop)
{
if(rc.bottom-rc.top < 16)
rc.top = rc.bottom-16;
}
else
{
if(rc.bottom-rc.top < 16)
rc.bottom = rc.top+16;
}
if(regionWindowData.hwndCaptureWindow)
{
if(rc.left < regionWindowData.captureRect.left)
rc.left = regionWindowData.captureRect.left;
if(rc.top < regionWindowData.captureRect.top)
rc.top = regionWindowData.captureRect.top;
if(rc.right > regionWindowData.captureRect.right)
rc.right = regionWindowData.captureRect.right;
if(rc.bottom > regionWindowData.captureRect.bottom)
rc.bottom = regionWindowData.captureRect.bottom;
}
return TRUE;
}
else if(message == WM_SIZE || message == WM_MOVE)
{
RECT rc;
GetWindowRect(hwnd, &rc);
if(rc.right-rc.left < 16)
rc.right = rc.left+16;
if(rc.bottom-rc.top < 16)
rc.bottom = rc.top+16;
SetWindowText(GetDlgItem(regionWindowData.hwndConfigDialog, IDC_SIZEX), IntString(rc.right-rc.left).Array());
SetWindowText(GetDlgItem(regionWindowData.hwndConfigDialog, IDC_SIZEY), IntString(rc.bottom-rc.top).Array());
if(regionWindowData.hwndCaptureWindow)
{
rc.left -= regionWindowData.captureRect.left;
rc.top -= regionWindowData.captureRect.top;
}
SetWindowText(GetDlgItem(regionWindowData.hwndConfigDialog, IDC_POSX), IntString(rc.left).Array());
SetWindowText(GetDlgItem(regionWindowData.hwndConfigDialog, IDC_POSY), IntString(rc.top).Array());
if(message == WM_SIZE)
RedrawWindow(hwnd, NULL, NULL, RDW_INTERNALPAINT|RDW_ERASE|RDW_INVALIDATE);
}
else if(message == WM_ACTIVATE)
{
if(wParam == WA_INACTIVE)
DestroyWindow(hwnd);
}
return DefWindowProc(hwnd, message, wParam, lParam);
}
struct ColorSelectionData
{
HDC hdcDesktop;
HDC hdcDestination;
HBITMAP hBitmap;
bool bValid;
inline ColorSelectionData() : hdcDesktop(NULL), hdcDestination(NULL), hBitmap(NULL), bValid(false) {}
inline ~ColorSelectionData() {Clear();}
inline bool Init()
{
hdcDesktop = GetDC(NULL);
if(!hdcDesktop)
return false;
hdcDestination = CreateCompatibleDC(hdcDesktop);
if(!hdcDestination)
return false;
hBitmap = CreateCompatibleBitmap(hdcDesktop, 1, 1);
if(!hBitmap)
return false;
SelectObject(hdcDestination, hBitmap);
bValid = true;
return true;
}
inline void Clear()
{
if(hdcDesktop)
{
ReleaseDC(NULL, hdcDesktop);
hdcDesktop = NULL;
}
if(hdcDestination)
{
DeleteDC(hdcDestination);
hdcDestination = NULL;
}
if(hBitmap)
{
DeleteObject(hBitmap);
hBitmap = NULL;
}
bValid = false;
}
inline DWORD GetColor()
{
POINT p;
if(GetCursorPos(&p))
{
BITMAPINFO data;
zero(&data, sizeof(data));
data.bmiHeader.biSize = sizeof(data.bmiHeader);
data.bmiHeader.biWidth = 1;
data.bmiHeader.biHeight = 1;
data.bmiHeader.biPlanes = 1;
data.bmiHeader.biBitCount = 24;
data.bmiHeader.biCompression = BI_RGB;
data.bmiHeader.biSizeImage = 4;
if(BitBlt(hdcDestination, 0, 0, 1, 1, hdcDesktop, p.x, p.y, SRCCOPY|CAPTUREBLT))
{
DWORD buffer;
if(GetDIBits(hdcDestination, hBitmap, 0, 1, &buffer, &data, DIB_RGB_COLORS))
return 0xFF000000|buffer;
}
else
{
int err = GetLastError();
nop();
}
}
return 0xFF000000;
}
};
INT_PTR CALLBACK ConfigDesktopSourceProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
{
static bool bSelectingColor = false;
static bool bMouseDown = false;
static ColorSelectionData colorData;
HWND hwndTemp;
switch(message)
{
case WM_INITDIALOG:
{
SetWindowLongPtr(hwnd, DWLP_USER, (LONG_PTR)lParam);
LocalizeWindow(hwnd);
//--------------------------------------------
HWND hwndToolTip = CreateWindowEx(NULL, TOOLTIPS_CLASS, NULL, WS_POPUP|TTS_NOPREFIX|TTS_ALWAYSTIP,
CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT,
hwnd, NULL, hinstMain, NULL);
TOOLINFO ti;
zero(&ti, sizeof(ti));
ti.cbSize = sizeof(ti);
ti.uFlags = TTF_SUBCLASS|TTF_IDISHWND;
ti.hwnd = hwnd;
SendMessage(hwndToolTip, TTM_SETMAXTIPWIDTH, 0, 500);
SendMessage(hwndToolTip, TTM_SETDELAYTIME, TTDT_AUTOPOP, 8000);
//-----------------------------------------------------
ConfigDesktopSourceInfo *info = (ConfigDesktopSourceInfo*)lParam;
XElement *data = info->data;
if (info->dialogID == IDD_CONFIGUREMONITORCAPTURE || info->dialogID == IDD_CONFIGUREDESKTOPSOURCE) {
hwndTemp = GetDlgItem(hwnd, IDC_MONITOR);
for(UINT i=0; i<App->NumMonitors(); i++)
SendMessage(hwndTemp, CB_ADDSTRING, 0, (LPARAM)UIntString(i+1).Array());
SendMessage(hwndTemp, CB_SETCURSEL, 0, 0);
if (OSGetVersion() > 7) {
EnableWindow(GetDlgItem(hwnd, IDC_CAPTURELAYERED), FALSE);
EnableWindow(GetDlgItem(hwnd, IDC_COMPATIBILITYMODE), (info->dialogID != IDD_CONFIGUREMONITORCAPTURE));
}
}
UINT captureType = data->GetInt(TEXT("captureType"), 0);
if (info->dialogID == IDD_CONFIGUREDESKTOPSOURCE)
SetDesktopCaptureType(hwnd, captureType);
//-----------------------------------------------------
if (info->dialogID == IDD_CONFIGUREMONITORCAPTURE || info->dialogID == IDD_CONFIGUREDESKTOPSOURCE) {
hwndTemp = GetDlgItem(hwnd, IDC_MONITOR);
UINT monitor = data->GetInt(TEXT("monitor"));
SendMessage(hwndTemp, CB_SETCURSEL, monitor, 0);
}
//-----------------------------------------------------
if (info->dialogID == IDD_CONFIGUREMONITORCAPTURE) {
String strWarnings;
if (OSGetVersion() < 8) {
strWarnings << Str("Sources.SoftwareCaptureSource.Warning");
BOOL bComposition;
DwmIsCompositionEnabled(&bComposition);
if (bComposition)
strWarnings << TEXT("\r\n") << Str("Sources.SoftwareCaptureSource.WarningAero");
}
SetWindowText(GetDlgItem(hwnd, IDC_WARNING), strWarnings);
}
//-----------------------------------------------------
bool bFoundWindow = false;
if (info->dialogID == IDD_CONFIGUREWINDOWCAPTURE || info->dialogID == IDD_CONFIGUREDESKTOPSOURCE) {
HWND hwndWindowList = GetDlgItem(hwnd, IDC_WINDOW);
CTSTR lpWindowName = data->GetString(TEXT("window"));
CTSTR lpWindowClass = data->GetString(TEXT("windowClass"));
BOOL bInnerWindow = (BOOL)data->GetInt(TEXT("innerWindow"), 1);
RefreshWindowList(hwndWindowList, info->strClasses);
UINT windowID = 0;
if(lpWindowName)
windowID = (UINT)SendMessage(hwndWindowList, CB_FINDSTRINGEXACT, -1, (LPARAM)lpWindowName);
bFoundWindow = (windowID != CB_ERR);
if(!bFoundWindow)
windowID = 0;
SendMessage(hwndWindowList, CB_SETCURSEL, windowID, 0);
if(bInnerWindow)
SendMessage(GetDlgItem(hwnd, IDC_INNERWINDOW), BM_SETCHECK, BST_CHECKED, 0);
else
SendMessage(GetDlgItem(hwnd, IDC_OUTERWINDOW), BM_SETCHECK, BST_CHECKED, 0);
}
//-----------------------------------------------------
bool bMouseCapture = data->GetInt(TEXT("captureMouse"), 1) != 0;
SendMessage(GetDlgItem(hwnd, IDC_CAPTUREMOUSE), BM_SETCHECK, (bMouseCapture) ? BST_CHECKED : BST_UNCHECKED, 0);
bool bCaptureLayered = data->GetInt(TEXT("captureLayered"), 0) != 0;
SendMessage(GetDlgItem(hwnd, IDC_CAPTURELAYERED), BM_SETCHECK, (bCaptureLayered) ? BST_CHECKED : BST_UNCHECKED, 0);
ti.lpszText = (LPWSTR)Str("Sources.SoftwareCaptureSource.CaptureLayeredTip");
ti.uId = (UINT_PTR)GetDlgItem(hwnd, IDC_CAPTURELAYERED);
SendMessage(hwndToolTip, TTM_ADDTOOL, 0, (LPARAM)&ti);
bool bCompatibilityMode = data->GetInt(TEXT("compatibilityMode"), 0) != 0;
SendMessage(GetDlgItem(hwnd, IDC_COMPATIBILITYMODE), BM_SETCHECK, (bCompatibilityMode) ? BST_CHECKED : BST_UNCHECKED, 0);
//-----------------------------------------------------
bool bRegion = data->GetInt(TEXT("regionCapture")) != FALSE;
if(captureType == 1 && !bFoundWindow)
bRegion = false;
SendMessage(GetDlgItem(hwnd, IDC_REGIONCAPTURE), BM_SETCHECK, (bRegion) ? BST_CHECKED : BST_UNCHECKED, 0);
EnableWindow(GetDlgItem(hwnd, IDC_POSX), bRegion);
EnableWindow(GetDlgItem(hwnd, IDC_POSY), bRegion);
EnableWindow(GetDlgItem(hwnd, IDC_SIZEX), bRegion);
EnableWindow(GetDlgItem(hwnd, IDC_SIZEY), bRegion);
EnableWindow(GetDlgItem(hwnd, IDC_SELECTREGION), bRegion);
int posX = 0, posY = 0, sizeX = 32, sizeY = 32;
if(!data->GetBaseItem(TEXT("captureX")) || !bRegion)
{
if(captureType == 0)
PostMessage(hwnd, WM_COMMAND, MAKEWPARAM(IDC_MONITOR, 0), 0);
else if(captureType == 1)
PostMessage(hwnd, WM_COMMAND, MAKEWPARAM(IDC_WINDOW, 0), 0);
}
else
{
posX = data->GetInt(TEXT("captureX"));
posY = data->GetInt(TEXT("captureY"));
sizeX = data->GetInt(TEXT("captureCX"), 32);
sizeY = data->GetInt(TEXT("captureCY"), 32);
if(sizeX < 16)
sizeX = 16;
if(sizeY < 16)
sizeY = 16;
SetWindowText(GetDlgItem(hwnd, IDC_POSX), IntString(posX).Array());
SetWindowText(GetDlgItem(hwnd, IDC_POSY), IntString(posY).Array());
SetWindowText(GetDlgItem(hwnd, IDC_SIZEX), IntString(sizeX).Array());
SetWindowText(GetDlgItem(hwnd, IDC_SIZEY), IntString(sizeY).Array());
}
ti.lpszText = (LPWSTR)Str("Sources.SoftwareCaptureSource.SelectRegionTooltip");
ti.uId = (UINT_PTR)GetDlgItem(hwnd, IDC_SELECTREGION);
SendMessage(hwndToolTip, TTM_ADDTOOL, 0, (LPARAM)&ti);
//------------------------------------------
BOOL bUseColorKey = data->GetInt(TEXT("useColorKey"), 0);
DWORD keyColor = data->GetInt(TEXT("keyColor"), 0xFFFFFFFF);
UINT similarity = data->GetInt(TEXT("keySimilarity"), 10);
UINT blend = data->GetInt(TEXT("keyBlend"), 0);
BOOL bUsePointFiltering = data->GetInt(TEXT("usePointFiltering"), 0);
SendMessage(GetDlgItem(hwnd, IDC_POINTFILTERING), BM_SETCHECK, bUsePointFiltering ? BST_CHECKED : BST_UNCHECKED, 0);
SendMessage(GetDlgItem(hwnd, IDC_USECOLORKEY), BM_SETCHECK, bUseColorKey ? BST_CHECKED : BST_UNCHECKED, 0);
CCSetColor(GetDlgItem(hwnd, IDC_COLOR), keyColor);
SendMessage(GetDlgItem(hwnd, IDC_BASETHRESHOLD), UDM_SETRANGE32, 0, 100);
SendMessage(GetDlgItem(hwnd, IDC_BASETHRESHOLD), UDM_SETPOS32, 0, similarity);
SendMessage(GetDlgItem(hwnd, IDC_BLEND), UDM_SETRANGE32, 0, 100);
SendMessage(GetDlgItem(hwnd, IDC_BLEND), UDM_SETPOS32, 0, blend);
EnableWindow(GetDlgItem(hwnd, IDC_COLOR), bUseColorKey);
EnableWindow(GetDlgItem(hwnd, IDC_SELECT), bUseColorKey);
EnableWindow(GetDlgItem(hwnd, IDC_BASETHRESHOLD_EDIT), bUseColorKey);
EnableWindow(GetDlgItem(hwnd, IDC_BASETHRESHOLD), bUseColorKey);
EnableWindow(GetDlgItem(hwnd, IDC_BLEND_EDIT), bUseColorKey);
EnableWindow(GetDlgItem(hwnd, IDC_BLEND), bUseColorKey);
//------------------------------------------
UINT opacity = data->GetInt(TEXT("opacity"), 100);
SendMessage(GetDlgItem(hwnd, IDC_OPACITY2), UDM_SETRANGE32, 0, 100);
SendMessage(GetDlgItem(hwnd, IDC_OPACITY2), UDM_SETPOS32, 0, opacity);
//------------------------------------------
int gammaVal = data->GetInt(TEXT("gamma"), 100);
hwndTemp = GetDlgItem(hwnd, IDC_GAMMA);
SendMessage(hwndTemp, TBM_CLEARTICS, FALSE, 0);
SendMessage(hwndTemp, TBM_SETRANGE, FALSE, MAKELPARAM(50, 175));
SendMessage(hwndTemp, TBM_SETTIC, 0, 100);
SendMessage(hwndTemp, TBM_SETPOS, TRUE, gammaVal);
SetSliderText(hwnd, IDC_GAMMA, IDC_GAMMAVAL);
//--------------------------------------------
if (info->dialogID == IDD_CONFIGUREWINDOWCAPTURE)
PostMessage(hwnd, WM_COMMAND, MAKEWPARAM(IDC_WINDOW, 0), 0);
return TRUE;
}
case WM_DESTROY:
if(colorData.bValid)
{
CCSetColor(GetDlgItem(hwnd, IDC_COLOR), colorData.GetColor());
colorData.Clear();
}
break;
case WM_LBUTTONDOWN:
if(bSelectingColor)
{
bMouseDown = true;
CCSetColor(GetDlgItem(hwnd, IDC_COLOR), colorData.GetColor());
ConfigDesktopSourceProc(hwnd, WM_COMMAND, MAKEWPARAM(IDC_COLOR, CCN_CHANGED), (LPARAM)GetDlgItem(hwnd, IDC_COLOR));
}
break;
case WM_MOUSEMOVE:
if(bSelectingColor && bMouseDown)
{
CCSetColor(GetDlgItem(hwnd, IDC_COLOR), colorData.GetColor());
ConfigDesktopSourceProc(hwnd, WM_COMMAND, MAKEWPARAM(IDC_COLOR, CCN_CHANGED), (LPARAM)GetDlgItem(hwnd, IDC_COLOR));
}
break;
case WM_LBUTTONUP:
if(bSelectingColor)
{
colorData.Clear();
ReleaseCapture();
bMouseDown = false;
bSelectingColor = false;
ConfigDesktopSourceInfo *configData = (ConfigDesktopSourceInfo*)GetWindowLongPtr(hwnd, DWLP_USER);
ImageSource *source = API->GetSceneImageSource(configData->lpName);
if(source)
source->SetInt(TEXT("useColorKey"), true);
}
break;
case WM_CAPTURECHANGED:
if(bSelectingColor)
{
if(colorData.bValid)
{
CCSetColor(GetDlgItem(hwnd, IDC_COLOR), colorData.GetColor());
ConfigDesktopSourceProc(hwnd, WM_COMMAND, MAKEWPARAM(IDC_COLOR, CCN_CHANGED), (LPARAM)GetDlgItem(hwnd, IDC_COLOR));
colorData.Clear();
}
ReleaseCapture();
bMouseDown = false;
bSelectingColor = false;
ConfigDesktopSourceInfo *configData = (ConfigDesktopSourceInfo*)GetWindowLongPtr(hwnd, DWLP_USER);
ImageSource *source = API->GetSceneImageSource(configData->lpName);
if(source)
source->SetInt(TEXT("useColorKey"), true);
}
break;
case WM_HSCROLL:
{
if(GetDlgCtrlID((HWND)lParam) == IDC_GAMMA)
{
int gamma = SetSliderText(hwnd, IDC_GAMMA, IDC_GAMMAVAL);
ConfigDesktopSourceInfo *configData = (ConfigDesktopSourceInfo*)GetWindowLongPtr(hwnd, DWLP_USER);
ImageSource *source = API->GetSceneImageSource(configData->lpName);
if(source)
source->SetInt(TEXT("gamma"), gamma);
}
}
break;
case WM_COMMAND:
switch(LOWORD(wParam))
{
case IDC_MONITORCAPTURE:
SetDesktopCaptureType(hwnd, 0);
PostMessage(hwnd, WM_COMMAND, MAKEWPARAM(IDC_MONITOR, 0), 0);
if(OSGetVersion() >= 8)
{
EnableWindow(GetDlgItem(hwnd, IDC_COMPATIBILITYMODE), FALSE);
SendMessage(GetDlgItem(hwnd, IDC_COMPATIBILITYMODE), BM_SETCHECK, BST_UNCHECKED, 0);
}
break;
case IDC_WINDOWCAPTURE:
SetDesktopCaptureType(hwnd, 1);
PostMessage(hwnd, WM_COMMAND, MAKEWPARAM(IDC_WINDOW, 0), 0);
if(OSGetVersion() >= 8)
EnableWindow(GetDlgItem(hwnd, IDC_COMPATIBILITYMODE), TRUE);
break;
case IDC_REGIONCAPTURE:
{
ConfigDesktopSourceInfo *info = (ConfigDesktopSourceInfo*)GetWindowLongPtr(hwnd, DWLP_USER);
UINT captureType = 0;
if (info->dialogID == IDD_CONFIGUREDESKTOPSOURCE)
captureType = (SendMessage(GetDlgItem(hwnd, IDC_WINDOWCAPTURE), BM_GETCHECK, 0, 0) == BST_CHECKED) ? 1 : 0;
else if (info->dialogID == IDD_CONFIGUREMONITORCAPTURE)
captureType = 0;
else
captureType = 1;
BOOL bRegion = SendMessage((HWND)lParam, BM_GETCHECK, 0, 0) == BST_CHECKED;
EnableWindow(GetDlgItem(hwnd, IDC_POSX), bRegion);
EnableWindow(GetDlgItem(hwnd, IDC_POSY), bRegion);
EnableWindow(GetDlgItem(hwnd, IDC_SIZEX), bRegion);
EnableWindow(GetDlgItem(hwnd, IDC_SIZEY), bRegion);
EnableWindow(GetDlgItem(hwnd, IDC_SELECTREGION), bRegion);
if(!bRegion)
{
if(captureType == 0)
PostMessage(hwnd, WM_COMMAND, MAKEWPARAM(IDC_MONITOR, 0), 0);
else
PostMessage(hwnd, WM_COMMAND, MAKEWPARAM(IDC_WINDOW, 0), 0);
}
break;
}
case IDC_SELECTREGION:
{
UINT posX, posY, sizeX, sizeY;
posX = GetEditText(GetDlgItem(hwnd, IDC_POSX)).ToInt();
posY = GetEditText(GetDlgItem(hwnd, IDC_POSY)).ToInt();
sizeX = GetEditText(GetDlgItem(hwnd, IDC_SIZEX)).ToInt();
sizeY = GetEditText(GetDlgItem(hwnd, IDC_SIZEY)).ToInt();
//--------------------------------------------
ConfigDesktopSourceInfo *info = (ConfigDesktopSourceInfo*)GetWindowLongPtr(hwnd, DWLP_USER);
UINT captureType = 0;
if (info->dialogID == IDD_CONFIGUREDESKTOPSOURCE)
captureType = (SendMessage(GetDlgItem(hwnd, IDC_WINDOWCAPTURE), BM_GETCHECK, 0, 0) == BST_CHECKED) ? 1 : 0;
else if (info->dialogID == IDD_CONFIGUREMONITORCAPTURE)
captureType = 0;
else
captureType = 1;
BOOL bRegion = (SendMessage(GetDlgItem(hwnd, IDC_REGIONCAPTURE), BM_GETCHECK, 0, 0) == BST_CHECKED);
if(bRegion && captureType == 1)
{
UINT windowID = (UINT)SendMessage(GetDlgItem(hwnd, IDC_WINDOW), CB_GETCURSEL, 0, 0);
if(windowID == CB_ERR) windowID = 0;
if(windowID >= info->strClasses.Num())
{
MessageBox(hwnd, Str("Sources.SoftwareCaptureSource.WindowNotFound"), NULL, 0);
break;
}
String strWindow = GetCBText(GetDlgItem(hwnd, IDC_WINDOW), windowID);
zero(&regionWindowData, sizeof(regionWindowData));
regionWindowData.hwndCaptureWindow = FindWindow(info->strClasses[windowID], strWindow);
if(!regionWindowData.hwndCaptureWindow)
{
HWND hwndLastKnownHWND = (HWND)SendMessage(GetDlgItem(hwnd, IDC_WINDOW), CB_GETITEMDATA, windowID, 0);
if(IsWindow(hwndLastKnownHWND))
regionWindowData.hwndCaptureWindow = hwndLastKnownHWND;
else
regionWindowData.hwndCaptureWindow = FindWindow(info->strClasses[windowID], NULL);
}
if(!regionWindowData.hwndCaptureWindow)
{
MessageBox(hwnd, Str("Sources.SoftwareCaptureSource.WindowNotFound"), NULL, 0);
break;
}
else if(IsIconic(regionWindowData.hwndCaptureWindow))
{
MessageBox(hwnd, Str("Sources.SoftwareCaptureSource.WindowMinimized"), NULL, 0);
break;
}
regionWindowData.bInnerWindowRegion = SendMessage(GetDlgItem(hwnd, IDC_INNERWINDOW), BM_GETCHECK, 0, 0) == BST_CHECKED;
if(regionWindowData.bInnerWindowRegion)
{
GetClientRect(regionWindowData.hwndCaptureWindow, &regionWindowData.captureRect);
ClientToScreen(regionWindowData.hwndCaptureWindow, (POINT*)&regionWindowData.captureRect);
ClientToScreen(regionWindowData.hwndCaptureWindow, (POINT*)&regionWindowData.captureRect.right);
}
else
GetWindowRect(regionWindowData.hwndCaptureWindow, &regionWindowData.captureRect);
posX += regionWindowData.captureRect.left;
posY += regionWindowData.captureRect.top;
}
else
{
UINT monitorID = (UINT)SendMessage(GetDlgItem(hwnd, IDC_MONITOR), CB_GETCURSEL, 0, 0);
if(monitorID == CB_ERR) monitorID = 0;
const MonitorInfo &monitor = App->GetMonitor(monitorID);
regionWindowData.hwndCaptureWindow = NULL;
mcpy(&regionWindowData.captureRect, &monitor.rect, sizeof(RECT));
}
//--------------------------------------------
regionWindowData.hwndConfigDialog = hwnd;
HWND hwndRegion = CreateWindowEx(WS_EX_TOPMOST, CAPTUREREGIONCLASS, NULL, WS_POPUP|WS_VISIBLE, posX, posY, sizeX, sizeY, hwnd, NULL, hinstMain, NULL);
//everyone better thank homeworld for this
SetWindowLongW(hwndRegion, GWL_EXSTYLE, GetWindowLong(hwndRegion, GWL_EXSTYLE) | WS_EX_LAYERED);
SetLayeredWindowAttributes(hwndRegion, 0x000000, 0xC0, LWA_ALPHA);
break;
}
case IDC_SETSTREAMSIZE:
{
UINT sizeX = (UINT)GetEditText(GetDlgItem(hwnd, IDC_SIZEX)).ToInt();
UINT sizeY = (UINT)GetEditText(GetDlgItem(hwnd, IDC_SIZEY)).ToInt();
if(sizeX < 128)
sizeX = 128;
else if(sizeX > 4096)
sizeX = 4096;
if(sizeY < 128)
sizeY = 128;
else if(sizeY > 4096)
sizeY = 4096;
AppConfig->SetInt(TEXT("Video"), TEXT("BaseWidth"), sizeX);
AppConfig->SetInt(TEXT("Video"), TEXT("BaseHeight"), sizeY);
if(!App->IsRunning())
App->ResizeWindow(false);
}
break;
case IDC_MONITOR:
{
UINT id = (UINT)SendMessage(GetDlgItem(hwnd, IDC_MONITOR), CB_GETCURSEL, 0, 0);
const MonitorInfo &monitor = App->GetMonitor(id);
UINT x, y, cx, cy;
x = monitor.rect.left;
y = monitor.rect.top;
cx = monitor.rect.right-monitor.rect.left;
cy = monitor.rect.bottom-monitor.rect.top;
if(cx < 16)
cx = 16;
if(cy < 16)
cy = 16;
SetWindowText(GetDlgItem(hwnd, IDC_POSX), IntString(x).Array());
SetWindowText(GetDlgItem(hwnd, IDC_POSY), IntString(y).Array());
SetWindowText(GetDlgItem(hwnd, IDC_SIZEX), IntString(cx).Array());
SetWindowText(GetDlgItem(hwnd, IDC_SIZEY), IntString(cy).Array());
break;
}
case IDC_WINDOW:
case IDC_OUTERWINDOW:
case IDC_INNERWINDOW:
SelectTargetWindow(hwnd, HIWORD(wParam)==CBN_SELCHANGE);
break;
case IDC_REFRESH:
{
ConfigDesktopSourceInfo *info = (ConfigDesktopSourceInfo*)GetWindowLongPtr(hwnd, DWLP_USER);
XElement *data = info->data;
CTSTR lpWindowName = data->GetString(TEXT("window"));
HWND hwndWindowList = GetDlgItem(hwnd, IDC_WINDOW);
RefreshWindowList(hwndWindowList, info->strClasses);
UINT windowID = 0;
if(lpWindowName)
windowID = (UINT)SendMessage(hwndWindowList, CB_FINDSTRINGEXACT, -1, (LPARAM)lpWindowName);
if(windowID != CB_ERR)
SendMessage(hwndWindowList, CB_SETCURSEL, windowID, 0);
else
{
SendMessage(hwndWindowList, CB_INSERTSTRING, 0, (LPARAM)lpWindowName);
SendMessage(hwndWindowList, CB_SETCURSEL, 0, 0);
}
break;
}
case IDC_USECOLORKEY:
{
HWND hwndUseColorKey = (HWND)lParam;
BOOL bUseColorKey = SendMessage(hwndUseColorKey, BM_GETCHECK, 0, 0) == BST_CHECKED;
ConfigDesktopSourceInfo *configData = (ConfigDesktopSourceInfo*)GetWindowLongPtr(hwnd, DWLP_USER);
ImageSource *source = API->GetSceneImageSource(configData->lpName);
if(source)
source->SetInt(TEXT("useColorKey"), bUseColorKey);
EnableWindow(GetDlgItem(hwnd, IDC_COLOR), bUseColorKey);
EnableWindow(GetDlgItem(hwnd, IDC_SELECT), bUseColorKey);
EnableWindow(GetDlgItem(hwnd, IDC_BASETHRESHOLD_EDIT), bUseColorKey);
EnableWindow(GetDlgItem(hwnd, IDC_BASETHRESHOLD), bUseColorKey);
EnableWindow(GetDlgItem(hwnd, IDC_BLEND_EDIT), bUseColorKey);
EnableWindow(GetDlgItem(hwnd, IDC_BLEND), bUseColorKey);
break;
}
case IDC_COLOR:
{
ConfigDesktopSourceInfo *configData = (ConfigDesktopSourceInfo*)GetWindowLongPtr(hwnd, DWLP_USER);
ImageSource *source = API->GetSceneImageSource(configData->lpName);
if(source)
{
DWORD color = CCGetColor((HWND)lParam);
source->SetInt(TEXT("keyColor"), color);
}
break;
}
case IDC_SELECT:
{
if(!bSelectingColor)
{
if(colorData.Init())
{
bMouseDown = false;
bSelectingColor = true;
SetCapture(hwnd);
HCURSOR hCursor = (HCURSOR)LoadImage(hinstMain, MAKEINTRESOURCE(IDC_COLORPICKER), IMAGE_CURSOR, 32, 32, 0);
SetCursor(hCursor);
ConfigDesktopSourceInfo *configData = (ConfigDesktopSourceInfo*)GetWindowLongPtr(hwnd, DWLP_USER);
ImageSource *source = API->GetSceneImageSource(configData->lpName);
if(source)
source->SetInt(TEXT("useColorKey"), false);
}
else
colorData.Clear();
}
break;
}
case IDC_OPACITY_EDIT:
case IDC_BASETHRESHOLD_EDIT:
case IDC_BLEND_EDIT:
if(HIWORD(wParam) == EN_CHANGE)
{
ConfigDesktopSourceInfo *configData = (ConfigDesktopSourceInfo*)GetWindowLongPtr(hwnd, DWLP_USER);
if(configData)
{
ImageSource *source = API->GetSceneImageSource(configData->lpName);
if(source)
{
HWND hwndVal = NULL;
switch(LOWORD(wParam))
{
case IDC_BASETHRESHOLD_EDIT: hwndVal = GetDlgItem(hwnd, IDC_BASETHRESHOLD); break;
case IDC_BLEND_EDIT: hwndVal = GetDlgItem(hwnd, IDC_BLEND); break;
case IDC_OPACITY_EDIT: hwndVal = GetDlgItem(hwnd, IDC_OPACITY2); break;
}
int val = (int)SendMessage(hwndVal, UDM_GETPOS32, 0, 0);
switch(LOWORD(wParam))
{
case IDC_BASETHRESHOLD_EDIT: source->SetInt(TEXT("keySimilarity"), val); break;
case IDC_BLEND_EDIT: source->SetInt(TEXT("keyBlend"), val); break;
case IDC_OPACITY_EDIT: source->SetInt(TEXT("opacity"), val); break;
}
}
}
}
break;
case IDOK:
{
ConfigDesktopSourceInfo *info = (ConfigDesktopSourceInfo*)GetWindowLongPtr(hwnd, DWLP_USER);
UINT captureType = 0;
if (info->dialogID == IDD_CONFIGUREDESKTOPSOURCE) {
if(SendMessage(GetDlgItem(hwnd, IDC_MONITORCAPTURE), BM_GETCHECK, 0, 0) == BST_CHECKED)
captureType = 0;
else if(SendMessage(GetDlgItem(hwnd, IDC_WINDOWCAPTURE), BM_GETCHECK, 0, 0) == BST_CHECKED)
captureType = 1;
} else if (info->dialogID == IDD_CONFIGUREMONITORCAPTURE) {
captureType = 0;
} else { //IDD_CONFIGUREWINDOWCAPTURE
captureType = 1;
}
BOOL bRegion = (SendMessage(GetDlgItem(hwnd, IDC_REGIONCAPTURE), BM_GETCHECK, 0, 0) == BST_CHECKED);
UINT monitorID = 0;
if (info->dialogID == IDD_CONFIGUREDESKTOPSOURCE || info->dialogID == IDD_CONFIGUREMONITORCAPTURE)
monitorID = (UINT)SendMessage(GetDlgItem(hwnd, IDC_MONITOR), CB_GETCURSEL, 0, 0);
if(monitorID == CB_ERR) monitorID = 0;
UINT windowID = 0;
if (info->dialogID == IDD_CONFIGUREDESKTOPSOURCE || info->dialogID == IDD_CONFIGUREWINDOWCAPTURE)
windowID = (UINT)SendMessage(GetDlgItem(hwnd, IDC_WINDOW), CB_GETCURSEL, 0, 0);
if(windowID == CB_ERR) windowID = 0;
if(captureType == 1 && windowID >= info->strClasses.Num())
break;
BOOL bInnerWindow = FALSE;
String strWindow;
if (info->dialogID == IDD_CONFIGUREDESKTOPSOURCE || info->dialogID == IDD_CONFIGUREWINDOWCAPTURE) {
strWindow = GetCBText(GetDlgItem(hwnd, IDC_WINDOW), windowID);
bInnerWindow = SendMessage(GetDlgItem(hwnd, IDC_INNERWINDOW), BM_GETCHECK, 0, 0) == BST_CHECKED;
}
UINT posX, posY, sizeX, sizeY;
posX = GetEditText(GetDlgItem(hwnd, IDC_POSX)).ToInt();
posY = GetEditText(GetDlgItem(hwnd, IDC_POSY)).ToInt();
sizeX = GetEditText(GetDlgItem(hwnd, IDC_SIZEX)).ToInt();
sizeY = GetEditText(GetDlgItem(hwnd, IDC_SIZEY)).ToInt();
if(sizeX < 16)
sizeX = 16;
if(sizeY < 16)
sizeY = 16;
BOOL bCaptureLayered = FALSE;
BOOL bCaptureMouse = SendMessage(GetDlgItem(hwnd, IDC_CAPTUREMOUSE), BM_GETCHECK, 0, 0) == BST_CHECKED;
//if (info->dialogID == IDD_CONFIGUREDESKTOPSOURCE || info->dialogID == IDD_CONFIGUREMONITORCAPTURE)
bCaptureLayered = SendMessage(GetDlgItem(hwnd, IDC_CAPTURELAYERED), BM_GETCHECK, 0, 0) == BST_CHECKED;
BOOL bCompatibilityMode = SendMessage(GetDlgItem(hwnd, IDC_COMPATIBILITYMODE), BM_GETCHECK, 0, 0) == BST_CHECKED;
BOOL bUsePointFiltering = SendMessage(GetDlgItem(hwnd, IDC_POINTFILTERING), BM_GETCHECK, 0, 0) == BST_CHECKED;
//---------------------------------
XElement *data = info->data;
data->SetInt(TEXT("captureType"), captureType);
data->SetInt(TEXT("monitor"), monitorID);
if(captureType == 1)
{
data->SetString(TEXT("window"), strWindow);
data->SetString(TEXT("windowClass"),info->strClasses[windowID]);
}
data->SetInt(TEXT("innerWindow"), bInnerWindow);
data->SetInt(TEXT("regionCapture"), bRegion);
data->SetInt(TEXT("captureMouse"), bCaptureMouse);
data->SetInt(TEXT("captureLayered"), bCaptureLayered);
data->SetInt(TEXT("compatibilityMode"), bCompatibilityMode);
data->SetInt(TEXT("usePointFiltering"), bUsePointFiltering);
data->SetInt(TEXT("captureX"), posX);
data->SetInt(TEXT("captureY"), posY);
data->SetInt(TEXT("captureCX"), sizeX);
data->SetInt(TEXT("captureCY"), sizeY);
//---------------------------------
BOOL bUseColorKey = SendMessage(GetDlgItem(hwnd, IDC_USECOLORKEY), BM_GETCHECK, 0, 0) == BST_CHECKED;
DWORD keyColor = CCGetColor(GetDlgItem(hwnd, IDC_COLOR));
UINT keySimilarity = (UINT)SendMessage(GetDlgItem(hwnd, IDC_BASETHRESHOLD), UDM_GETPOS32, 0, 0);
UINT keyBlend = (UINT)SendMessage(GetDlgItem(hwnd, IDC_BLEND), UDM_GETPOS32, 0, 0);
data->SetInt(TEXT("useColorKey"), bUseColorKey);
data->SetInt(TEXT("keyColor"), keyColor);
data->SetInt(TEXT("keySimilarity"), keySimilarity);
data->SetInt(TEXT("keyBlend"), keyBlend);
//---------------------------------
UINT opacity = (UINT)SendMessage(GetDlgItem(hwnd, IDC_OPACITY2), UDM_GETPOS32, 0, 0);
data->SetInt(TEXT("opacity"), opacity);
//---------------------------------
int gamma = (int)SendMessage(GetDlgItem(hwnd, IDC_GAMMA), TBM_GETPOS, 0, 0);
data->SetInt(TEXT("gamma"), gamma);
if (captureType == 0 && OSGetVersion() < 8)
{
BOOL bComposition;
DwmIsCompositionEnabled(&bComposition);
if (bComposition)
MessageBox (hwnd, Str("Sources.SoftwareCaptureSource.WarningAero"), TEXT("Warning"), MB_ICONEXCLAMATION);
}
}
case IDCANCEL:
if(LOWORD(wParam) == IDCANCEL)
{
ConfigDesktopSourceInfo *info = (ConfigDesktopSourceInfo*)GetWindowLongPtr(hwnd, DWLP_USER);
ImageSource *source = API->GetSceneImageSource(info->lpName);
if(source)
{
XElement *data = info->data;
source->SetInt(TEXT("useColorKey"), data->GetInt(TEXT("useColorKey"), 0));
source->SetInt(TEXT("keyColor"), data->GetInt(TEXT("keyColor"), 0xFFFFFFFF));
source->SetInt(TEXT("keySimilarity"), data->GetInt(TEXT("keySimilarity"), 10));
source->SetInt(TEXT("keyBlend"), data->GetInt(TEXT("keyBlend"), 0));
source->SetInt(TEXT("opacity"), data->GetInt(TEXT("opacity"), 100));
source->SetInt(TEXT("gamma"), data->GetInt(TEXT("gamma"), 100));
}
}
EndDialog(hwnd, LOWORD(wParam));
break;
}
}
return FALSE;
}
bool bMadeCaptureRegionClass = false;
static bool STDCALL ConfigureDesktopSource2(XElement *element, bool bInitialize, int dialogID)
{
if(!bMadeCaptureRegionClass)
{
WNDCLASS wc;
zero(&wc, sizeof(wc));
wc.hInstance = hinstMain;
wc.hCursor = LoadCursor(NULL, IDC_ARROW);
wc.lpszClassName = CAPTUREREGIONCLASS;
wc.lpfnWndProc = (WNDPROC)RegionWindowProc;
wc.hbrBackground = (HBRUSH)GetStockObject(WHITE_BRUSH);
RegisterClass(&wc);
bMadeCaptureRegionClass = true;
}
if(!element)
{
AppWarning(TEXT("ConfigureDesktopSource: NULL element"));
return false;
}
XElement *data = element->GetElement(TEXT("data"));
if(!data)
data = element->CreateElement(TEXT("data"));
ConfigDesktopSourceInfo info;
info.data = data;
info.lpName = element->GetName();
info.dialogID = dialogID;
if(DialogBoxParam(hinstMain, MAKEINTRESOURCE(dialogID), hwndMain, ConfigDesktopSourceProc, (LPARAM)&info) == IDOK)
{
element->SetInt(TEXT("cx"), data->GetInt(TEXT("captureCX")));
element->SetInt(TEXT("cy"), data->GetInt(TEXT("captureCY")));
return true;
}
return false;
}
bool STDCALL ConfigureDesktopSource(XElement *element, bool bInitialize)
{
return ConfigureDesktopSource2(element, bInitialize, IDD_CONFIGUREDESKTOPSOURCE);
}
bool STDCALL ConfigureWindowCaptureSource(XElement *element, bool bInitialize)
{
return ConfigureDesktopSource2(element, bInitialize, IDD_CONFIGUREWINDOWCAPTURE);
}
bool STDCALL ConfigureMonitorCaptureSource(XElement *element, bool bInitialize)
{
return ConfigureDesktopSource2(element, bInitialize, IDD_CONFIGUREMONITORCAPTURE);
}