Replace dialog with regular window + other stuff

No caption anymore
Can drag the window from anywhere
Drag cursor
Rounded corners
Prevent DPI resizing
Ready text
This commit is contained in:
Grayson Riffe 2026-06-07 20:29:31 -05:00
parent 4eae4af911
commit 1763bf72da
Signed by: grayson
SSH Key Fingerprint: SHA256:23HJg9tnL2m6u0uUb26QIrOTFymFZ+xgSH/2UPEBB/I
5 changed files with 183 additions and 139 deletions

View File

@ -44,51 +44,6 @@ END
#endif // APSTUDIO_INVOKED #endif // APSTUDIO_INVOKED
/////////////////////////////////////////////////////////////////////////////
//
// Dialog
//
IDD_DIALOGMAIN DIALOGEX 0, 0, 300, 114
STYLE DS_SETFONT | DS_FIXEDSYS | WS_CAPTION
EXSTYLE WS_EX_TOPMOST | WS_EX_TOOLWINDOW
CAPTION "Dialog"
FONT 8, "MS Shell Dlg", 400, 0, 0x1
BEGIN
CTEXT "Lower",IDC_STATICLOWER,7,85,286,22,SS_CENTERIMAGE,WS_EX_TRANSPARENT
END
/////////////////////////////////////////////////////////////////////////////
//
// DESIGNINFO
//
#ifdef APSTUDIO_INVOKED
GUIDELINES DESIGNINFO
BEGIN
IDD_DIALOGMAIN, DIALOG
BEGIN
LEFTMARGIN, 7
RIGHTMARGIN, 293
TOPMARGIN, 7
BOTTOMMARGIN, 107
END
END
#endif // APSTUDIO_INVOKED
/////////////////////////////////////////////////////////////////////////////
//
// AFX_DIALOG_LAYOUT
//
IDD_DIALOGMAIN AFX_DIALOG_LAYOUT
BEGIN
0
END
///////////////////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////////////////
// //
// Version // Version

View File

@ -5,32 +5,59 @@
#include "resource.h" #include "resource.h"
#define WINDOW_WIDTH 450
#define WINDOW_HEIGHT 185
#define WINDOW_STYLE WS_POPUP
#define EX_WINDOW_STYLE WS_EX_TOOLWINDOW
#define WM_TRAYICON WM_USER // Tray icon window message #define WM_TRAYICON WM_USER // Tray icon window message
#define IDM_ABOUT 1001 // "About" menu identifier #define IDM_ABOUT 1001 // "About" menu identifier
#define IDM_EXIT 1002 // "Exit" menu identifier #define IDM_EXIT 1002 // "Exit" menu identifier
#define IDT_UPDATE 1 // Update timer identifier #define IDT_UPDATE 1 // Update timer identifier
#define WM_UPDATE WM_USER + 1 // Update window message #define WM_UPDATE WM_USER + 1 // Update window message
// Enable visual styles
#pragma comment(linker, "\"/manifestdependency:type='win32' \
name='Microsoft.Windows.Common-Controls' version='6.0.0.0' \
processorArchitecture='*' publicKeyToken='6595b64144ccf1df' language='*'\"")
namespace watchfuleye { namespace watchfuleye {
Application::Application(const char* appName, const char* appVersion, unsigned int maximumMinutes, const char* driveToDetect) Application::Application(const char* appName, const char* appVersion, unsigned int maximumMinutes, const char* driveToDetect)
: m_appName(appName) : m_appName(appName)
, m_appVersion(appVersion) , m_appVersion(appVersion)
, m_mainDlg(nullptr) , m_window(nullptr)
, m_running(true) , m_running(true)
, m_active(false) , m_active(false)
, m_overTime(false) , m_overTime(false)
, m_maxMinutes(maximumMinutes) , m_maxMinutes(maximumMinutes)
, m_drive(driveToDetect) , m_drive(driveToDetect)
, m_startTime() , m_startTime()
, m_taskbarCreatedMessage(-1)
, m_region(nullptr)
, m_timeFont(nullptr)
, m_lowerFont(nullptr)
, m_greenBrush(nullptr)
, m_yellowBrush(nullptr)
, m_redBrush(nullptr)
{ {
std::cout << std::format("{} {}\n", m_appName, m_appVersion); std::cout << std::format("{} {}\n", m_appName, m_appVersion);
} }
void Application::run() { void Application::run() {
// Create dialog // Create window
SetProcessDpiAwarenessContext(DPI_AWARENESS_CONTEXT_PER_MONITOR_AWARE_V2); SetProcessDpiAwarenessContext(DPI_AWARENESS_CONTEXT_PER_MONITOR_AWARE_V2); // Don't mess with the window size
m_mainDlg = CreateDialogParam(nullptr, MAKEINTRESOURCE(IDD_DIALOGMAIN), nullptr, reinterpret_cast<DLGPROC>(mainDlgProc), reinterpret_cast<LPARAM>(this)); WNDCLASS wc = {};
std::string windowClassName = "WatchfulEyeWindow";
wc.lpszClassName = windowClassName.c_str();
wc.hCursor = LoadCursor(NULL, IDC_SIZEALL);
wc.lpfnWndProc = wndProc;
RegisterClass(&wc);
m_window = CreateWindowEx(EX_WINDOW_STYLE, windowClassName.c_str(), m_appName.c_str(), WINDOW_STYLE, 0, 0, 0, 0, nullptr, nullptr, nullptr, this);
// Create tray icon // Create tray icon
createTrayIcon(); createTrayIcon();
@ -38,60 +65,86 @@ namespace watchfuleye {
// Create drive query thread // Create drive query thread
std::thread queryThread(&Application::queryThreadFunction, this); std::thread queryThread(&Application::queryThreadFunction, this);
ShowWindow(m_mainDlg, SW_SHOW); ShowWindow(m_window, SW_SHOW);
MSG msg = {}; MSG msg = {};
while (GetMessage(&msg, nullptr, 0, 0)) while (GetMessage(&msg, nullptr, 0, 0)) {
IsDialogMessage(m_mainDlg, &msg); TranslateMessage(&msg);
DispatchMessage(&msg);
}
m_running = false; m_running = false;
queryThread.join(); queryThread.join();
} }
BOOL CALLBACK Application::mainDlgProc(HWND dlg, UINT msg, WPARAM wParam, LPARAM lParam) { LRESULT CALLBACK Application::wndProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam) {
static Application* app = nullptr; static Application* app = nullptr;
static UINT taskbarCreatedMessage = 0;
static HFONT timeFont = nullptr;
static HBRUSH greenBackgroundBrush = CreateSolidBrush(RGB(150, 255, 150));
static HBRUSH yellowBackgroundBrush = CreateSolidBrush(RGB(255, 255, 150));
static HBRUSH redBackgroundBrush = CreateSolidBrush(RGB(255, 150, 150));
switch (msg) { switch (msg) {
case WM_INITDIALOG: { case WM_CREATE: {
app = reinterpret_cast<Application*>(lParam); app = reinterpret_cast<Application*>(reinterpret_cast<CREATESTRUCT*>(lParam)->lpCreateParams);
SetWindowText(dlg, app->m_appName.c_str()); app->sizeWindow(hWnd);
// Round the window's corners
app->m_region = CreateRoundRectRgn(0, 0, WINDOW_WIDTH, WINDOW_HEIGHT, 20, 20);
SetWindowRgn(hWnd, app->m_region, TRUE);
// Spawn in the lower right corner of the virtual screen (might be problematic in some cases) // Spawn in the lower right corner of the virtual screen (might be problematic in some cases)
int cornerX = GetSystemMetrics(SM_XVIRTUALSCREEN) + GetSystemMetrics(SM_CXVIRTUALSCREEN); int cornerX = GetSystemMetrics(SM_XVIRTUALSCREEN) + GetSystemMetrics(SM_CXVIRTUALSCREEN);
int cornerY = GetSystemMetrics(SM_YVIRTUALSCREEN) + GetSystemMetrics(SM_CYVIRTUALSCREEN); int cornerY = GetSystemMetrics(SM_YVIRTUALSCREEN) + GetSystemMetrics(SM_CYVIRTUALSCREEN);
SetWindowPos(dlg, nullptr, cornerX - 550, cornerY - 540, NULL, NULL, SWP_NOZORDER | SWP_NOSIZE);
taskbarCreatedMessage = RegisterWindowMessage("TaskbarCreated"); // And set topmost flag
SetWindowPos(hWnd, HWND_TOPMOST, cornerX - 500, cornerY - 400, 0, 0, SWP_NOSIZE);
app->m_taskbarCreatedMessage = RegisterWindowMessage("TaskbarCreated");
// Set up UI // Set up UI
LOGFONT lFont = {}; LOGFONT lFont = {};
strcpy(lFont.lfFaceName, "Consolas"); strcpy(lFont.lfFaceName, "Consolas");
lFont.lfHeight = 35; lFont.lfHeight = 35;
HFONT upperFont = CreateFontIndirect(&lFont); app->m_lowerFont = CreateFontIndirect(&lFont);
SendMessage(GetDlgItem(dlg, IDC_STATICLOWER), WM_SETFONT, reinterpret_cast<WPARAM>(upperFont), NULL);
lFont.lfHeight = 180; lFont.lfHeight = 180;
lFont.lfWeight = FW_BOLD; lFont.lfWeight = FW_BOLD;
timeFont = CreateFontIndirect(&lFont); app->m_timeFont = CreateFontIndirect(&lFont);
SendMessage(dlg, WM_UPDATE, NULL, NULL); app->m_greenBrush = CreateSolidBrush(RGB(150, 255, 150));
SetTimer(dlg, IDT_UPDATE, 1000, nullptr); app->m_yellowBrush = CreateSolidBrush(RGB(255, 255, 150));
app->m_redBrush = CreateSolidBrush(RGB(255, 150, 150));
return TRUE; // App will update (repaint) every second
SendMessage(hWnd, WM_UPDATE, NULL, NULL);
SetTimer(hWnd, IDT_UPDATE, 1000, nullptr);
return 0;
}
case WM_DPICHANGED: { // Prevents the window from resizing because of DPI changes
app->sizeWindow(hWnd);
return 0;
}
case WM_NCHITTEST: { // Allows the window to be moved by dragging from anywhere within it
LRESULT result = DefWindowProc(hWnd, msg, wParam, lParam);
if (result == HTCLIENT)
return HTCAPTION;
return result;
}
case WM_SETCURSOR: { // Allows the cursor to change with the above WM_NCHITTEST code
if (LOWORD(lParam) == HTCAPTION)
lParam = MAKELPARAM(HTCLIENT, HIWORD(lParam));
break;
} }
case WM_TRAYICON: { case WM_TRAYICON: {
if (LOWORD(lParam) == WM_LBUTTONDOWN || if (LOWORD(lParam) == WM_LBUTTONDOWN ||
LOWORD(lParam) == WM_RBUTTONDOWN) { LOWORD(lParam) == WM_RBUTTONDOWN) {
SetForegroundWindow(dlg); SetForegroundWindow(hWnd);
POINT cursor = {}; POINT cursor = {};
GetCursorPos(&cursor); GetCursorPos(&cursor);
@ -100,130 +153,152 @@ namespace watchfuleye {
AppendMenu(popupMenu, MF_STRING, IDM_ABOUT, "About"); AppendMenu(popupMenu, MF_STRING, IDM_ABOUT, "About");
AppendMenu(popupMenu, MF_STRING, IDM_EXIT, "Exit"); AppendMenu(popupMenu, MF_STRING, IDM_EXIT, "Exit");
TrackPopupMenu(popupMenu, NULL, cursor.x, cursor.y, NULL, dlg, nullptr); // Will block here. Might be problematic. TrackPopupMenu(popupMenu, NULL, cursor.x, cursor.y, NULL, hWnd, nullptr);
DestroyMenu(popupMenu); DestroyMenu(popupMenu);
return 0;
} }
return TRUE; break;
} }
case WM_COMMAND: { case WM_COMMAND: {
if (HIWORD(wParam) == 0 && LOWORD(wParam) == IDM_ABOUT) if (HIWORD(wParam) == 0 && LOWORD(wParam) == IDM_ABOUT) {
MessageBox(dlg, std::format("{} {}\nCopyright Grayson Riffe 2026\ngraysonriffe.com\n\n" MessageBox(hWnd, std::format("{} {}\nCopyright Grayson Riffe 2026\ngraysonriffe.com\n\n"
"\t{} is a simple countdown application\n" "\t{} is a simple countdown application\n"
"specifically designed for this electronics testing labratory.\n\n" "specifically designed for this electronics testing labratory.\n\n"
"Hopefully, it's working!", app->m_appName, app->m_appVersion, "Hopefully, it's working!", app->m_appName, app->m_appVersion,
app->m_appName).c_str(), std::format("About {}", app->m_appName).c_str(), MB_OK); app->m_appName).c_str(), std::format("About {}", app->m_appName).c_str(), MB_OK);
else if (HIWORD(wParam) == 0 && LOWORD(wParam) == IDM_EXIT) return 0;
DestroyWindow(dlg); }
return TRUE; else if (HIWORD(wParam) == 0 && LOWORD(wParam) == IDM_EXIT) {
DestroyWindow(hWnd);
return 0;
}
break;
}
case WM_TIMER: {
if (wParam == IDT_UPDATE) {
SendMessage(hWnd, WM_UPDATE, NULL, NULL);
return 0;
}
break;
}
case WM_UPDATE: {
InvalidateRect(hWnd, nullptr, TRUE);
UpdateWindow(hWnd);
return 0;
} }
case WM_ERASEBKGND: { case WM_ERASEBKGND: {
HDC hDC = reinterpret_cast<HDC>(wParam); HDC hDC = reinterpret_cast<HDC>(wParam);
RECT clientRect = {}; RECT clientRect = {};
GetClientRect(dlg, &clientRect); GetClientRect(hWnd, &clientRect);
HBRUSH backgroundBrush = nullptr; HBRUSH backgroundBrush = nullptr;
if (!app->m_active) if (!app->m_active)
backgroundBrush = greenBackgroundBrush; backgroundBrush = app->m_greenBrush;
else if (app->m_overTime) else if (app->m_overTime)
backgroundBrush = redBackgroundBrush; backgroundBrush = app->m_redBrush;
else else
backgroundBrush = yellowBackgroundBrush; backgroundBrush = app->m_yellowBrush;
FillRect(hDC, &clientRect, backgroundBrush); FillRect(hDC, &clientRect, backgroundBrush);
return TRUE; return 1;
}
case WM_CTLCOLORSTATIC: {
if (GetWindowLongPtr(reinterpret_cast<HWND>(lParam), GWL_EXSTYLE) & WS_EX_TRANSPARENT) {
SetBkMode(reinterpret_cast<HDC>(wParam), TRANSPARENT);
return reinterpret_cast<INT_PTR>(GetStockObject(NULL_BRUSH));
}
return FALSE;
}
case WM_TIMER: {
if (wParam == IDT_UPDATE) {
SendMessage(dlg, WM_UPDATE, NULL, NULL);
return TRUE;
}
return FALSE;
}
case WM_UPDATE: {
InvalidateRect(dlg, nullptr, TRUE);
UpdateWindow(dlg);
return TRUE;
} }
case WM_PAINT: { case WM_PAINT: {
PAINTSTRUCT ps = {}; PAINTSTRUCT ps = {};
HDC hDC = BeginPaint(dlg, &ps); HDC hDC = BeginPaint(hWnd, &ps);
// Setup RECTs
RECT timeRect = {}; RECT timeRect = {};
GetClientRect(dlg, &timeRect); GetClientRect(hWnd, &timeRect);
timeRect.top -= 25, timeRect.bottom -= 25; timeRect.top -= 25, timeRect.bottom -= 25;
RECT lowerRect = { .top = WINDOW_HEIGHT - 65, .right = WINDOW_WIDTH, .bottom = WINDOW_HEIGHT };
// Setup text options
SetTextColor(hDC, RGB(0, 0, 0)); SetTextColor(hDC, RGB(0, 0, 0));
SetBkMode(hDC, TRANSPARENT); SetBkMode(hDC, TRANSPARENT);
SelectObject(hDC, timeFont);
// Calculate time
Seconds elapsed = Duration(Clock::now() - app->m_startTime).count(); Seconds elapsed = Duration(Clock::now() - app->m_startTime).count();
if (!app->m_active) Seconds remaining = app->m_maxMinutes * 60;
elapsed = 0; if (app->m_active)
remaining -= elapsed;
Seconds remaining = app->m_maxMinutes * 60 - elapsed; if (!app->m_active || (app->m_active && !app->m_overTime)) { // Draw time
SelectObject(hDC, app->m_timeFont);
if (app->m_overTime) {
SetDlgItemText(dlg, IDC_STATICLOWER, "Please Eject Your USB");
DrawText(hDC, "STOP", -1, &timeRect, DT_SINGLELINE | DT_NOCLIP | DT_CENTER | DT_VCENTER);
}
else {
SetDlgItemText(dlg, IDC_STATICLOWER, "Time Remaining on Tester");
unsigned int minutes = remaining % (3600) / 60, seconds = remaining % 60; unsigned int minutes = remaining % (3600) / 60, seconds = remaining % 60;
DrawText(hDC, std::format("{:02}:{:02}", minutes, seconds).c_str(), -1, &timeRect, DT_SINGLELINE | DT_NOCLIP | DT_CENTER | DT_VCENTER); DrawText(hDC, std::format("{:02}:{:02}", minutes, seconds).c_str(), -1, &timeRect, DT_SINGLELINE | DT_NOCLIP | DT_CENTER | DT_VCENTER);
} }
if (!app->m_active) { // Ready (green)
SelectObject(hDC, app->m_lowerFont);
DrawText(hDC, "Ready", -1, &lowerRect, DT_SINGLELINE | DT_NOCLIP | DT_CENTER | DT_VCENTER);
}
else if (!app->m_overTime) { // Counting (yellow)
SelectObject(hDC, app->m_lowerFont);
DrawText(hDC, "Time Remaining on Tester", -1, &lowerRect, DT_SINGLELINE | DT_NOCLIP | DT_CENTER | DT_VCENTER);
}
else { // Over time (red)
SelectObject(hDC, app->m_lowerFont);
DrawText(hDC, "Please Eject Your USB", -1, &lowerRect, DT_SINGLELINE | DT_NOCLIP | DT_CENTER | DT_VCENTER);
SelectObject(hDC, app->m_timeFont);
DrawText(hDC, "STOP", -1, &timeRect, DT_SINGLELINE | DT_NOCLIP | DT_CENTER | DT_VCENTER);
}
if (remaining <= 0) if (remaining <= 0)
app->m_overTime = true; app->m_overTime = true;
EndPaint(dlg, &ps); EndPaint(hWnd, &ps);
return TRUE; return 0;
} }
case WM_CLOSE: { case WM_CLOSE: {
// Do nothing // Do nothing
return TRUE; return 0;
} }
case WM_DESTROY: { case WM_DESTROY: {
PostQuitMessage(0); PostQuitMessage(0);
return TRUE; return 0;
} }
} }
if (msg == taskbarCreatedMessage) if (app && msg == app->m_taskbarCreatedMessage) {
app->createTrayIcon(); app->createTrayIcon();
return 0;
}
return FALSE; return DefWindowProc(hWnd, msg, wParam, lParam);
}
void Application::sizeWindow(const HWND& hWnd) {
RECT clientRect = { .right = WINDOW_WIDTH, .bottom = WINDOW_HEIGHT };
AdjustWindowRectExForDpi(&clientRect, WINDOW_STYLE, FALSE, EX_WINDOW_STYLE, GetDpiForWindow(hWnd));
SetWindowPos(hWnd, nullptr, 0, 0, clientRect.right - clientRect.left, clientRect.bottom - clientRect.top, SWP_NOZORDER | SWP_NOMOVE);
} }
void Application::createTrayIcon() { void Application::createTrayIcon() {
NOTIFYICONDATA iconData = {}; NOTIFYICONDATA iconData = {};
iconData.cbSize = sizeof(iconData); iconData.cbSize = sizeof(iconData);
iconData.uVersion = NOTIFYICON_VERSION_4; iconData.uVersion = NOTIFYICON_VERSION_4;
iconData.hWnd = m_mainDlg; iconData.hWnd = m_window;
iconData.uFlags = NIF_MESSAGE | NIF_ICON | NIF_TIP; iconData.uFlags = NIF_MESSAGE | NIF_ICON | NIF_TIP;
iconData.uCallbackMessage = WM_TRAYICON; iconData.uCallbackMessage = WM_TRAYICON;
iconData.hIcon = LoadIcon(GetModuleHandle(NULL), MAKEINTRESOURCE(IDI_ICONMAIN)); iconData.hIcon = LoadIcon(GetModuleHandle(NULL), MAKEINTRESOURCE(IDI_ICONMAIN));
@ -250,4 +325,15 @@ namespace watchfuleye {
std::this_thread::sleep_for(std::chrono::milliseconds(100)); std::this_thread::sleep_for(std::chrono::milliseconds(100));
} }
} }
Application::~Application() {
DeleteObject(m_region);
DeleteObject(m_timeFont);
DeleteObject(m_lowerFont);
DeleteObject(m_greenBrush);
DeleteObject(m_yellowBrush);
DeleteObject(m_redBrush);
}
} }

View File

@ -11,15 +11,19 @@ namespace watchfuleye {
Application(const char* appName, const char* appVersion, unsigned int maximumMinutes, const char* driveToDetect); Application(const char* appName, const char* appVersion, unsigned int maximumMinutes, const char* driveToDetect);
void run(); void run();
~Application();
private: private:
static BOOL CALLBACK mainDlgProc(HWND dlg, UINT msg, WPARAM wParam, LPARAM lParam); static LRESULT CALLBACK wndProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam);
void sizeWindow(const HWND& hWnd);
void createTrayIcon(); void createTrayIcon();
void queryThreadFunction(); void queryThreadFunction();
std::string m_appName, m_appVersion; std::string m_appName, m_appVersion;
HWND m_mainDlg; HWND m_window;
bool m_running; // Is the application running? bool m_running; // Is the application running?
bool m_active; // Is the timer ticking? bool m_active; // Is the timer ticking?
@ -29,5 +33,10 @@ namespace watchfuleye {
const char* m_drive; const char* m_drive;
TimePoint m_startTime; TimePoint m_startTime;
UINT m_taskbarCreatedMessage;
HRGN m_region;
HFONT m_timeFont, m_lowerFont;
HBRUSH m_greenBrush, m_yellowBrush, m_redBrush;
}; };
} }

View File

@ -4,11 +4,6 @@
#include "version.h" #include "version.h"
#include "Application.h" #include "Application.h"
// Enable visual styles
#pragma comment(linker, "\"/manifestdependency:type='win32' \
name='Microsoft.Windows.Common-Controls' version='6.0.0.0' \
processorArchitecture='*' publicKeyToken='6595b64144ccf1df' language='*'\"")
#define APPNAME "Watchful Eye" #define APPNAME "Watchful Eye"
// ======== Configuration ======== // ======== Configuration ========
@ -17,6 +12,7 @@ processorArchitecture='*' publicKeyToken='6595b64144ccf1df' language='*'\"")
// =============================== // ===============================
int main(int argc, char* argv[]) { int main(int argc, char* argv[]) {
{ {
watchfuleye::Application app(APPNAME, APPVERSION, MAX_MINUTES, DRIVE_TO_DETECT); watchfuleye::Application app(APPNAME, APPVERSION, MAX_MINUTES, DRIVE_TO_DETECT);
app.run(); app.run();

View File

@ -2,15 +2,13 @@
// Microsoft Visual C++ generated include file. // Microsoft Visual C++ generated include file.
// Used by C:\Users\Grayson\Documents\Visual Studio 18\Solutions\watchful-eye\WatchfulEye\resource.rc // Used by C:\Users\Grayson\Documents\Visual Studio 18\Solutions\watchful-eye\WatchfulEye\resource.rc
// //
#define IDD_DIALOGMAIN 101 #define IDI_ICONMAIN 101
#define IDI_ICONMAIN 103
#define IDC_STATICLOWER 1000
// Next default values for new objects // Next default values for new objects
// //
#ifdef APSTUDIO_INVOKED #ifdef APSTUDIO_INVOKED
#ifndef APSTUDIO_READONLY_SYMBOLS #ifndef APSTUDIO_READONLY_SYMBOLS
#define _APS_NEXT_RESOURCE_VALUE 104 #define _APS_NEXT_RESOURCE_VALUE 102
#define _APS_NEXT_COMMAND_VALUE 40001 #define _APS_NEXT_COMMAND_VALUE 40001
#define _APS_NEXT_CONTROL_VALUE 1001 #define _APS_NEXT_CONTROL_VALUE 1001
#define _APS_NEXT_SYMED_VALUE 101 #define _APS_NEXT_SYMED_VALUE 101