SftTree/DLL 7.5 - Tree Control
SftBox/OCX 5.0 - Combo Box Control
SftButton/OCX 3.0 - Button Control
SftMask/OCX 7.0 - Masked Edit Control
SftTabs/OCX 6.5 - Tab Control (VB6 only)
SftTree/OCX 7.5 - Tree Control
SftPrintPreview/DLL 2.0 - Print Preview Control (discontinued)
SftTree/DLL 7.5 - Tree Control
SftBox/OCX 5.0 - Combo Box Control
SftButton/OCX 3.0 - Button Control
SftDirectory 3.5 - File/Folder Control (discontinued)
SftMask/OCX 7.0 - Masked Edit Control
SftOptions 1.0 - Registry/INI Control (discontinued)
SftPrintPreview/OCX 1.0 - Print Preview Control (discontinued)
SftTabs/OCX 6.5 - Tab Control (VB6 only)
SftTree/OCX 7.5 - Tree Control
SftTabs/NET 6.0 - Tab Control (discontinued)
SftTree/NET 2.0 - Tree Control
This sample illustrates SftButton creation and configuration from a C++/MFC application. It covers process-wide registration, attaching CSftButton instances to dialog template controls through DDX_Control, configuring buttons through SFTBUTTON_CONTROL, loading and freeing GDI+ images for the Picture1 / Picture2 slots, runtime dark-mode and theme toggles, and routing dark-mode painting through the SftDarkMode helper.
The dialog hosts three SftButton controls and two checkboxes:
The source code is located at C:\Program Files (x86)\Softelvdm\SftButton DLL 3.0\Samples\MFC\Simple\ (or C:\Program Files\Softelvdm\SftButton DLL 3.0\Samples\MFC\Simple\ on 32-bit Windows versions).
The CWinApp-derived class registers the SftButton window class in InitInstance and unregisters it in ExitInstance. SftDarkMode_Init runs alongside so dark-mode painting is available before the main dialog is shown.
/****************************************************************************/
/* SftButton/DLL 3.0 - Button Control for C/C++ */
/* Copyright (C) 2026 Softel vdm, Inc. All Rights Reserved. */
/****************************************************************************/
#include "stdafx.h"
#include "Simple.h"
#include "Maindlg.h"
#ifdef _DEBUG
#undef THIS_FILE
static char BASED_CODE THIS_FILE[] = __FILE__;
#endif
BEGIN_MESSAGE_MAP(CSimpleApp, CWinApp)
END_MESSAGE_MAP()
CSimpleApp::CSimpleApp()
{
}
CSimpleApp NEAR theApp;
BOOL CSimpleApp::InitInstance()
{
SftDarkMode_Init(); // Dark mode support
CSftButton::RegisterApp(); // Register with SftButton/DLL
CMainDlg dlg;
m_pMainWnd = &dlg;
dlg.DoModal();
return FALSE;
}
int CSimpleApp::ExitInstance()
{
CSftButton::UnregisterApp(); // Unregister from SftButton/DLL
return CWinApp::ExitInstance();
}CMainDlg embeds three CSftButton members - one per dialog control - and two LPVOID slots for the GDI+ images that Button 2 displays. DDX_Control attaches the embedded CSftButton instances to the dialog-template controls in DoDataExchange.
/****************************************************************************/
/* SftButton/DLL 3.0 - Button Control for C/C++ */
/* Copyright (C) 2026 Softel vdm, Inc. All Rights Reserved. */
/****************************************************************************/
class CMainDlg : public CDialog
{
public:
CMainDlg(CWnd* pParent = NULL);
enum { IDD = IDD_MAIN };
CSftButton m_Button1;
CSftButton m_Button2;
CSftButton m_Button3;
LPVOID m_pImg1; // GDI+ image for Button2 Picture1
LPVOID m_pImg2; // GDI+ image for Button2 Picture2
protected:
virtual void DoDataExchange(CDataExchange* pDX);
virtual BOOL OnInitDialog();
virtual LRESULT WindowProc(UINT message, WPARAM wParam, LPARAM lParam);
afx_msg void OnButton1();
afx_msg void OnButton2();
afx_msg void OnButton3();
afx_msg void OnButton3DropDown();
afx_msg void OnUseThemes();
afx_msg void OnDarkMode();
afx_msg void OnDestroy();
afx_msg void OnSettingChange(UINT uFlags, LPCTSTR lpszSection);
DECLARE_MESSAGE_MAP()
};OnInitDialog configures each button through GetControlInfo / SetControlInfo, loads the GDI+ images for Button 2, and applies dark mode to the dialog itself with SftDarkMode_ApplyToDialog. ON_BN_CLICKED and ON_CONTROL entries in the message map dispatch click and drop-down notifications. OnDestroy frees the GDI+ images with SftButton_FreeGDIPlusImageLoadedFromFile after the controls have stopped using them. WindowProc forwards messages to SftDarkMode_HandleDialogMessage so the dialog repaints correctly under dark mode. OnSettingChange forwards WM_SETTINGCHANGE / ImmersiveColorSet to each button so AUTO-mode buttons re-render when the user flips the Windows "Choose your mode" setting at runtime.
/****************************************************************************/ /* SftButton/DLL 3.0 - Button Control for C/C++ */ /* Copyright (C) 2026 Softel vdm, Inc. All Rights Reserved. */ /****************************************************************************/ #include "stdafx.h" #include "Simple.h" #include "Maindlg.h" #ifdef _DEBUG #undef THIS_FILE static char BASED_CODE THIS_FILE[] = __FILE__; #endif #define SFTBUTTONN_DROPDOWNCLICK 17 CMainDlg::CMainDlg(CWnd* pParent /*=NULL*/) : CDialog(CMainDlg::IDD, pParent) , m_pImg1(NULL) , m_pImg2(NULL) { } void CMainDlg::DoDataExchange(CDataExchange* pDX) { CDialog::DoDataExchange(pDX); DDX_Control(pDX, IDC_SFTBUTTON1, m_Button1); DDX_Control(pDX, IDC_SFTBUTTON2, m_Button2); DDX_Control(pDX, IDC_SFTBUTTON3, m_Button3); } BEGIN_MESSAGE_MAP(CMainDlg, CDialog) ON_BN_CLICKED(IDC_SFTBUTTON1, OnButton1) ON_BN_CLICKED(IDC_SFTBUTTON2, OnButton2) ON_BN_CLICKED(IDC_SFTBUTTON3, OnButton3) ON_CONTROL(SFTBUTTONN_DROPDOWNCLICK, IDC_SFTBUTTON3, OnButton3DropDown) ON_BN_CLICKED(IDC_USE_THEMES, OnUseThemes) ON_BN_CLICKED(IDC_DARK_MODE, OnDarkMode) ON_WM_DESTROY() ON_WM_SETTINGCHANGE() END_MESSAGE_MAP() BOOL CMainDlg::OnInitDialog() { CDialog::OnInitDialog(); // Set dialog icon HICON hIcon = AfxGetApp()->LoadIcon(IDI_ICON1); SetIcon(hIcon, TRUE); SetIcon(hIcon, FALSE); // Apply dark mode to dialog SftDarkMode_ApplyToDialog(m_hWnd); // Configure SftButton control 1 { SFTBUTTON_CONTROL Ctl; Ctl.cbSize = sizeof(SFTBUTTON_CONTROL); m_Button1.GetControlInfo(&Ctl); Ctl.nDarkMode = SFTBUTTON_DARKMODE_AUTO;/* automatic dark mode support */ m_Button1.SetControlInfo(&Ctl); } // Configure SftButton control 2 { SFTBUTTON_CONTROL Ctl; Ctl.cbSize = sizeof(SFTBUTTON_CONTROL); m_Button2.GetControlInfo(&Ctl); Ctl.nDarkMode = SFTBUTTON_DARKMODE_AUTO;/* automatic dark mode support */ Ctl.Text.align = SFT_PICALIGN_LEFT;/* text horizontal alignment */ m_pImg1 = SftButton_LoadGDIPlusImageFromFile(_T("Res\\pic_world_48.png")); if (m_pImg1) Sft_SetPictureGDIPlusImage(&Ctl.Picture1, m_pImg1); Ctl.Picture1.align = SFT_PICALIGN_CENTER; Ctl.Picture1.valign = SFT_PICALIGN_VCENTER; m_pImg2 = SftButton_LoadGDIPlusImageFromFile(_T("Res\\pic_go_32.png")); if (m_pImg2) Sft_SetPictureGDIPlusImage(&Ctl.Picture2, m_pImg2); Ctl.Picture2.align = SFT_PICALIGN_LEFT; Ctl.Picture2.valign = SFT_PICALIGN_VCENTER; m_Button2.SetControlInfo(&Ctl); } // Configure SftButton control 3 { SFTBUTTON_CONTROL Ctl; Ctl.cbSize = sizeof(SFTBUTTON_CONTROL); m_Button3.GetControlInfo(&Ctl); Ctl.fShowDropDown = TRUE;/* show drop-down arrow */ Ctl.nDarkMode = SFTBUTTON_DARKMODE_AUTO;/* automatic dark mode support */ m_Button3.SetControlInfo(&Ctl); } CheckDlgButton(IDC_USE_THEMES, BST_CHECKED); CheckDlgButton(IDC_DARK_MODE, SftDarkMode_IsActive() ? BST_CHECKED : BST_UNCHECKED); return TRUE; } void CMainDlg::OnButton1() { AfxMessageBox(_T("Button 1 clicked!")); } void CMainDlg::OnButton2() { AfxMessageBox(_T("Button 2 clicked!")); } void CMainDlg::OnButton3() { AfxMessageBox(_T("Button 3 clicked!")); } void CMainDlg::OnButton3DropDown() { AfxMessageBox(_T("Button 3 drop-down clicked!")); } void CMainDlg::OnUseThemes() { int useThemes = (IsDlgButtonChecked(IDC_USE_THEMES) == BST_CHECKED) ? SFTBUTTON_THEME_YES : SFTBUTTON_THEME_NO; CSftButton* btns[] = { &m_Button1, &m_Button2, &m_Button3 }; for (int i = 0; i < (int)(sizeof(btns) / sizeof(btns[0])); ++i) { SFTBUTTON_CONTROL Ctl; Ctl.cbSize = sizeof(SFTBUTTON_CONTROL); btns[i]->GetControlInfo(&Ctl); Ctl.nUseThemes = useThemes; btns[i]->SetControlInfo(&Ctl); } } void CMainDlg::OnDarkMode() { BOOL fDark = (IsDlgButtonChecked(IDC_DARK_MODE) == BST_CHECKED); int btnMode = fDark ? SFTBUTTON_DARKMODE_ON : SFTBUTTON_DARKMODE_OFF; m_Button1.SetDarkMode(btnMode); m_Button2.SetDarkMode(btnMode); m_Button3.SetDarkMode(btnMode); SftDarkMode_SetActive(fDark); SftDarkMode_ApplyToDialog(m_hWnd); InvalidateRect(NULL, TRUE); } void CMainDlg::OnDestroy() { // Free GDI+ images now that the controls no longer reference them. if (m_pImg1) { SftButton_FreeGDIPlusImageLoadedFromFile(m_pImg1); m_pImg1 = NULL; } if (m_pImg2) { SftButton_FreeGDIPlusImageLoadedFromFile(m_pImg2); m_pImg2 = NULL; } CDialog::OnDestroy(); } LRESULT CMainDlg::WindowProc(UINT message, WPARAM wParam, LPARAM lParam) { // Route through SftDarkMode first so it can handle WM_CTLCOLOR*, WM_ERASEBKGND, etc. INT_PTR dmResult; if (SftDarkMode_HandleDialogMessage(m_hWnd, message, wParam, lParam, &dmResult)) return dmResult; return CDialog::WindowProc(message, wParam, lParam); } void CMainDlg::OnSettingChange(UINT uFlags, LPCTSTR lpszSection) { CDialog::OnSettingChange(uFlags, lpszSection); // Forward to the SftButton controls so they can update (AUTO mode) if (lpszSection && lstrcmpW((LPCWSTR)lpszSection, L"ImmersiveColorSet") == 0) { SftDarkMode_Init(); SftDarkMode_ApplyToDialog(m_hWnd); m_Button1.SendMessage(WM_SETTINGCHANGE, uFlags, (LPARAM)lpszSection); m_Button2.SendMessage(WM_SETTINGCHANGE, uFlags, (LPARAM)lpszSection); m_Button3.SendMessage(WM_SETTINGCHANGE, uFlags, (LPARAM)lpszSection); InvalidateRect(NULL, TRUE); } }
See Also Using C++/MFC | MFC and Notifications | Dark Mode | GDI+
