Skip to content

Commit bbd4f08

Browse files
committed
option to capture secondary windows
1 parent f165f0f commit bbd4f08

File tree

5 files changed

+50
-20
lines changed

5 files changed

+50
-20
lines changed

CHANGELOG.md

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,9 @@
11
Changelog
22
=========
33

4+
##### 2025.11.23
5+
* option to capture secondary windows (popups & dialogs) on Windows 11 24H2 and up
6+
47
##### 2025.05.25
58
* fix screen capture framerate on Windows 11 24H2
69

README.md

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -56,7 +56,8 @@ dropped frames during recording, try reducing video resolution and framerate.
5656

5757
Capture of mouse cursor can be disabled only when using Windows 10 version 2004, May 2020 Update (20H1) or newer.
5858

59-
On Windows 11 you can disable yellow recording borders, or rounded window corners.
59+
On Windows 11 you can disable yellow recording borders, or rounded window corners. On Windows 11 24H2 version can enable secondary
60+
window capture, when they intersect main window in window-only capture mode - for popups & tool windows like "Open File" dialog.
6061

6162
HEVC Software Encoding
6263
======================

wcap.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -261,7 +261,7 @@ static void StartRecording(ID3D11Device* Device, HWND Window)
261261
gRecordingNextEncode = 0;
262262
gRecordingLastFrame = 0;
263263
gRecordingDroppedFrames = 0;
264-
ScreenCapture_Start(&gCapture, gConfig.MouseCursor, gConfig.ShowRecordingBorder);
264+
ScreenCapture_Start(&gCapture, gConfig.MouseCursor, gConfig.ShowRecordingBorder, gConfig.IncludeSecondaryWindows);
265265

266266
if (gConfig.CaptureAudio)
267267
{

wcap_config.h

Lines changed: 24 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,7 @@ typedef struct
2525
BOOL OnlyClientArea;
2626
BOOL ShowRecordingBorder;
2727
BOOL KeepRoundedWindowCorners;
28+
BOOL IncludeSecondaryWindows;
2829
BOOL HardwareEncoder;
2930
BOOL HardwarePreferIntegrated;
3031
// output
@@ -86,11 +87,12 @@ static BOOL Config_ShowDialog(Config* C);
8687
#define ID_CANCEL IDCANCEL // 2
8788
#define ID_DEFAULTS 3
8889

89-
#define ID_MOUSE_CURSOR 20
90-
#define ID_ONLY_CLIENT_AREA 30
91-
#define ID_SHOW_RECORDING_BORDER 40
92-
#define ID_ROUNDED_CORNERS 50
93-
#define ID_GPU_ENCODER 60
90+
#define ID_MOUSE_CURSOR 20
91+
#define ID_ONLY_CLIENT_AREA 30
92+
#define ID_SHOW_RECORDING_BORDER 40
93+
#define ID_ROUNDED_CORNERS 50
94+
#define ID_INCLUDE_SECONDARY_WINDOWS 55
95+
#define ID_GPU_ENCODER 60
9496

9597
#define ID_OUTPUT_FOLDER 100
9698
#define ID_OPEN_FOLDER 110
@@ -139,7 +141,7 @@ static BOOL Config_ShowDialog(Config* C);
139141
#define COL01W 154
140142
#define COL10W 144
141143
#define COL11W 130
142-
#define ROW0H 84
144+
#define ROW0H 98
143145
#define ROW1H 124
144146
#define ROW2H 56
145147

@@ -321,11 +323,12 @@ static void Config__SetDialogValues(HWND Window, Config* C)
321323
Config__UpdateAudioBitrate(Window, C->AudioCodec, C->AudioBitrate);
322324

323325
// capture
324-
CheckDlgButton(Window, ID_MOUSE_CURSOR, C->MouseCursor);
325-
CheckDlgButton(Window, ID_ONLY_CLIENT_AREA, C->OnlyClientArea);
326-
CheckDlgButton(Window, ID_SHOW_RECORDING_BORDER, C->ShowRecordingBorder);
327-
CheckDlgButton(Window, ID_ROUNDED_CORNERS, C->KeepRoundedWindowCorners);
328-
CheckDlgButton(Window, ID_GPU_ENCODER, C->HardwareEncoder);
326+
CheckDlgButton(Window, ID_MOUSE_CURSOR, C->MouseCursor);
327+
CheckDlgButton(Window, ID_ONLY_CLIENT_AREA, C->OnlyClientArea);
328+
CheckDlgButton(Window, ID_SHOW_RECORDING_BORDER, C->ShowRecordingBorder);
329+
CheckDlgButton(Window, ID_ROUNDED_CORNERS, C->KeepRoundedWindowCorners);
330+
CheckDlgButton(Window, ID_INCLUDE_SECONDARY_WINDOWS, C->IncludeSecondaryWindows);
331+
CheckDlgButton(Window, ID_GPU_ENCODER, C->HardwareEncoder);
329332
SendDlgItemMessageW(Window, ID_GPU_ENCODER + 1, CB_SETCURSEL, C->HardwarePreferIntegrated ? 0 : 1, 0);
330333

331334
// output
@@ -491,6 +494,7 @@ static LRESULT CALLBACK Config__DialogProc(HWND Window, UINT Message, WPARAM WPa
491494
C->OnlyClientArea = IsDlgButtonChecked(Window, ID_ONLY_CLIENT_AREA);
492495
C->ShowRecordingBorder = IsDlgButtonChecked(Window, ID_SHOW_RECORDING_BORDER);
493496
C->KeepRoundedWindowCorners = IsDlgButtonChecked(Window, ID_ROUNDED_CORNERS);
497+
C->IncludeSecondaryWindows = IsDlgButtonChecked(Window, ID_INCLUDE_SECONDARY_WINDOWS);
494498
C->HardwareEncoder = IsDlgButtonChecked(Window, ID_GPU_ENCODER);
495499
C->HardwarePreferIntegrated = (DWORD)SendDlgItemMessageW(Window, ID_GPU_ENCODER + 1, CB_GETCURSEL, 0, 0) == 0;
496500

@@ -848,6 +852,7 @@ void Config_Defaults(Config* C)
848852
.OnlyClientArea = TRUE,
849853
.ShowRecordingBorder = TRUE,
850854
.KeepRoundedWindowCorners = TRUE,
855+
.IncludeSecondaryWindows = FALSE,
851856
.HardwareEncoder = TRUE,
852857
.HardwarePreferIntegrated = FALSE,
853858
// output
@@ -955,6 +960,7 @@ void Config_Load(Config* C, LPCWSTR FileName)
955960
Config__GetBool(FileName, L"OnlyClientArea", &C->OnlyClientArea);
956961
Config__GetBool(FileName, L"ShowRecordingBorder", &C->ShowRecordingBorder);
957962
Config__GetBool(FileName, L"KeepRoundedWindowCorners", &C->KeepRoundedWindowCorners);
963+
Config__GetBool(FileName, L"IncludeSecondaryWindows", &C->IncludeSecondaryWindows);
958964
Config__GetBool(FileName, L"HardwareEncoder", &C->HardwareEncoder);
959965
Config__GetBool(FileName, L"HardwarePreferIntegrated", &C->HardwarePreferIntegrated);
960966
// output
@@ -1005,6 +1011,7 @@ void Config_Save(Config* C, LPCWSTR FileName)
10051011
WritePrivateProfileStringW(INI_SECTION, L"OnlyClientArea", C->OnlyClientArea ? L"1" : L"0", FileName);
10061012
WritePrivateProfileStringW(INI_SECTION, L"ShowRecordingBorder", C->ShowRecordingBorder ? L"1" : L"0", FileName);
10071013
WritePrivateProfileStringW(INI_SECTION, L"KeepRoundedWindowCorners", C->KeepRoundedWindowCorners ? L"1" : L"0", FileName);
1014+
WritePrivateProfileStringW(INI_SECTION, L"IncludeSecondaryWindows", C->IncludeSecondaryWindows ? L"1" : L"0", FileName);
10081015
WritePrivateProfileStringW(INI_SECTION, L"HardwareEncoder", C->HardwareEncoder ? L"1" : L"0", FileName);
10091016
WritePrivateProfileStringW(INI_SECTION, L"HardwarePreferIntegrated", C->HardwarePreferIntegrated ? L"1" : L"0", FileName);
10101017
// output
@@ -1057,11 +1064,12 @@ BOOL Config_ShowDialog(Config* C)
10571064
.Rect = { 0, 0, COL00W, ROW0H },
10581065
.Items = (Config__DialogItem[])
10591066
{
1060-
{ "&Mouse Cursor", ID_MOUSE_CURSOR, ITEM_CHECKBOX },
1061-
{ "Only &Client Area", ID_ONLY_CLIENT_AREA, ITEM_CHECKBOX },
1062-
{ "Show Recording &Border", ID_SHOW_RECORDING_BORDER, ITEM_CHECKBOX },
1063-
{ "Keep &Rounded Window Corners", ID_ROUNDED_CORNERS, ITEM_CHECKBOX },
1064-
{ "GPU &Encoder", ID_GPU_ENCODER, ITEM_CHECKBOX | ITEM_COMBOBOX, 50 },
1067+
{ "&Mouse Cursor", ID_MOUSE_CURSOR, ITEM_CHECKBOX },
1068+
{ "Only &Client Area", ID_ONLY_CLIENT_AREA, ITEM_CHECKBOX },
1069+
{ "Show Recording &Border", ID_SHOW_RECORDING_BORDER, ITEM_CHECKBOX },
1070+
{ "Keep &Rounded Window Corners", ID_ROUNDED_CORNERS, ITEM_CHECKBOX },
1071+
{ "Include Secondar&y Windows", ID_INCLUDE_SECONDARY_WINDOWS, ITEM_CHECKBOX },
1072+
{ "GPU &Encoder", ID_GPU_ENCODER, ITEM_CHECKBOX | ITEM_COMBOBOX, 50 },
10651073
{ NULL },
10661074
},
10671075
},

wcap_screen_capture.h

Lines changed: 20 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -63,6 +63,7 @@ static bool ScreenCapture_IsSupported(void);
6363
static bool ScreenCapture_CanHideMouseCursor(void);
6464
static bool ScreenCapture_CanHideRecordingBorder(void);
6565
static bool ScreenCapture_CanDisableRoundedCorners(void);
66+
static bool ScreenCapture_CanIncludeSecondaryWindows(void);
6667

6768
// if OnFrame is NULL then you need to periodically call GetFrame/ReleaseFrame manually
6869
// if OnFrame is not NULL and CallbackOnThread is false then callback will be invoked from message processing loop on the same thread as Create call
@@ -72,7 +73,7 @@ static void ScreenCapture_Release(ScreenCapture* Capture);
7273

7374
static bool ScreenCapture_CreateForWindow(ScreenCapture* Capture, ID3D11Device* Device, HWND Window, bool OnlyClientArea, bool DisableRoundedCorners);
7475
static bool ScreenCapture_CreateForMonitor(ScreenCapture* Capture, ID3D11Device* Device, HMONITOR Monitor, const RECT* Rect);
75-
static void ScreenCapture_Start(ScreenCapture* Capture, bool WithMouseCursor, bool WithRecordingBorder);
76+
static void ScreenCapture_Start(ScreenCapture* Capture, bool WithMouseCursor, bool WithRecordingBorder, bool IncludeSecondaryWindows);
7677
static void ScreenCapture_Stop(ScreenCapture* Capture);
7778

7879
static bool ScreenCapture_GetFrame(ScreenCapture* Capture, ScreenCaptureFrame* Frame);
@@ -157,6 +158,7 @@ DEFINE_GUID(IID_IClosable, 0x30d5a829, 0x7fa4, 0x4026,
157158
DEFINE_GUID(IID_IGraphicsCaptureSession2, 0x2c39ae40, 0x7d2e, 0x5044, 0x80, 0x4e, 0x8b, 0x67, 0x99, 0xd4, 0xcf, 0x9e);
158159
DEFINE_GUID(IID_IGraphicsCaptureSession3, 0xf2cdd966, 0x22ae, 0x5ea1, 0x95, 0x96, 0x3a, 0x28, 0x93, 0x44, 0xc3, 0xbe);
159160
DEFINE_GUID(IID_IGraphicsCaptureSession5, 0x67c0ea62, 0x1f85, 0x5061, 0x92, 0x5a, 0x23, 0x9b, 0xe0, 0xac, 0x09, 0xcb);
161+
DEFINE_GUID(IID_IGraphicsCaptureSession6, 0xd7419236, 0xbe20, 0x5e9f, 0xbc, 0xd6, 0xc4, 0xe9, 0x8f, 0xd6, 0xaf, 0xdc);
160162
DEFINE_GUID(IID_IGraphicsCaptureItemInterop, 0x3628e81b, 0x3cac, 0x4c60, 0xb7, 0xf4, 0x23, 0xce, 0x0e, 0x0c, 0x33, 0x56);
161163
DEFINE_GUID(IID_IGraphicsCaptureItem, 0x79c3f95b, 0x31f7, 0x4ec2, 0xa4, 0x64, 0x63, 0x2e, 0xf5, 0xd3, 0x07, 0x60);
162164
DEFINE_GUID(IID_IGraphicsCaptureItemHandler, 0xe9c610c0, 0xa68c, 0x5bd9, 0x80, 0x21, 0x85, 0x89, 0x34, 0x6e, 0xee, 0xe2);
@@ -349,6 +351,15 @@ bool ScreenCapture_CanDisableRoundedCorners(void)
349351
return Version.dwMajorVersion > 10 || (Version.dwMajorVersion == 10 && Version.dwBuildNumber >= 22000);
350352
}
351353

354+
bool ScreenCapture_CanIncludeSecondaryWindows(void)
355+
{
356+
RTL_OSVERSIONINFOW Version = { sizeof(Version) };
357+
RtlGetVersion(&Version);
358+
359+
// available since Windows 11 24H2, build 10.0.26100.0
360+
return Version.dwMajorVersion > 10 || (Version.dwMajorVersion == 10 && Version.dwBuildNumber >= 26100);
361+
}
362+
352363
void ScreenCapture_Create(ScreenCapture* Capture, ScreenCapture_OnFrameCallback* OnFrame, bool CallbackOnThread)
353364
{
354365
HR(RoInitialize(RO_INIT_SINGLETHREADED));
@@ -497,7 +508,7 @@ bool ScreenCapture_CreateForMonitor(ScreenCapture* Capture, ID3D11Device* Device
497508
return false;
498509
}
499510

500-
void ScreenCapture_Start(ScreenCapture* Capture, bool WithMouseCursor, bool WithRecordingBorder)
511+
void ScreenCapture_Start(ScreenCapture* Capture, bool WithMouseCursor, bool WithRecordingBorder, bool IncludeSecondaryWindows)
501512
{
502513
__x_ABI_CWindows_CGraphics_CCapture_CIGraphicsCaptureSession* Session;
503514
HR(__x_ABI_CWindows_CGraphics_CCapture_CIDirect3D11CaptureFramePool_CreateCaptureSession(Capture->FramePool, Capture->Item, &Session));
@@ -526,6 +537,13 @@ void ScreenCapture_Start(ScreenCapture* Capture, bool WithMouseCursor, bool With
526537
__x_ABI_CWindows_CGraphics_CCapture_CIGraphicsCaptureSession5_Release(Session5);
527538
}
528539

540+
__x_ABI_CWindows_CGraphics_CCapture_CIGraphicsCaptureSession6* Session6;
541+
if (SUCCEEDED(__x_ABI_CWindows_CGraphics_CCapture_CIGraphicsCaptureSession_QueryInterface(Session, &IID_IGraphicsCaptureSession6, (void**)&Session6)))
542+
{
543+
__x_ABI_CWindows_CGraphics_CCapture_CIGraphicsCaptureSession6_put_IncludeSecondaryWindows(Session6, (boolean)IncludeSecondaryWindows);
544+
__x_ABI_CWindows_CGraphics_CCapture_CIGraphicsCaptureSession6_Release(Session3);
545+
}
546+
529547
if (Capture->OnFrame)
530548
{
531549
HR(__x_ABI_CWindows_CGraphics_CCapture_CIDirect3D11CaptureFramePool_add_FrameArrived(Capture->FramePool, &Capture->OnFrameHandler, &Capture->OnFrameToken));

0 commit comments

Comments
 (0)