Add comboboxes and list control to the dialog. master
authorPat Thoyts <patthoyts@users.sourceforge.net>
Wed, 5 Mar 2025 15:54:02 +0000 (15:54 +0000)
committerPat Thoyts <patthoyts@users.sourceforge.net>
Wed, 5 Mar 2025 15:54:02 +0000 (15:54 +0000)
ButtonProvider.cpp
ButtonProvider.h
PolyButton.cpp
PolyButton.h
main.cpp
main.rc
resource.h

index 1e402e94c9f2ee50e2640dcce57a2ed423f2b4a5..1213299e20cb429d3307b53edf8db49c7e7c38c6 100644 (file)
@@ -3,6 +3,7 @@
 #include <UIAutomationClient.h>
 #include <UIAutomationCoreApi.h>
 #include <new>
+#include <string>
 #include <stdio.h>
 
 HRESULT ButtonProvider::CreateInstance(HWND hwnd, IRawElementProviderSimple **ppProvider)
@@ -118,11 +119,10 @@ DECLSPEC_NOTHROW STDMETHODIMP ButtonProvider::GetPropertyValue(PROPERTYID proper
     else if (propertyId == UIA_NamePropertyId)
     {
         int len = GetWindowTextLengthW(_hwnd) + 1;
-        wchar_t *name = new (std::nothrow) wchar_t[len]();
-        GetWindowTextW(_hwnd, name, len);
+        std::wstring name(len - 1, L'\0');
+        GetWindowTextW(_hwnd, name.data(), len);
         pVal->vt = VT_BSTR;
-        pVal->bstrVal = SysAllocString(name);
-        delete[] name;
+        pVal->bstrVal = SysAllocString(name.c_str());
     }
     else
     {
@@ -172,7 +172,7 @@ DECLSPEC_NOTHROW STDMETHODIMP ButtonProvider::get_ToggleState(ToggleState *pVal)
             hr = static_cast<HRESULT>(UIA_E_ELEMENTNOTAVAILABLE);
         else
         {
-            auto state = SendMessage(_hwnd, BM_GETCHECK, WPARAM(0), LPARAM(0));
+            int state = static_cast<int>(SendMessage(_hwnd, BM_GETCHECK, WPARAM(0), LPARAM(0)));
             *pVal = (state == BST_CHECKED) ? ToggleState_On : ToggleState_Off;
             hr = S_OK;
         }
index 080b0258a4047b42d9b727d1267811cff0aa9b52..b8549b3bc3d444b2019b439b37783df7a4fc233d 100644 (file)
@@ -22,7 +22,7 @@ public:
     STDMETHOD(get_ToggleState)(ToggleState *pVal);
 
 private:
-    ButtonProvider() : _refcount(0), _hwnd(HWND_DESKTOP) {}
+    ButtonProvider() = delete;
     ButtonProvider(HWND hwnd) : _refcount(0), _hwnd(hwnd) {}
     virtual ~ButtonProvider() {}
     unsigned long _refcount;
index 45ae6f4e6f59244a517b8ee376155aff01e7689f..fd664b78de48bf18d452758803a0b7db37d73c61 100644 (file)
@@ -7,6 +7,7 @@
 #include <new>
 #include <string>
 #include <vector>
+#include <memory>
 
 static LRESULT CALLBACK WndProc(HWND hwnd, UINT messageId, WPARAM wparam, LPARAM lparam);
 
@@ -132,7 +133,7 @@ inline Gdiplus::RectF RectItoF (const Gdiplus::Rect &rc)
     return Gdiplus::RectF(float(rc.X), float(rc.Y), float(rc.Width), float(rc.Height));
 }
 
-std::vector<Gdiplus::Point> CalculatePoints(Gdiplus::Rect rc, int sidesCount)
+static std::vector<Gdiplus::Point> CalculatePoints(Gdiplus::Rect rc, int sidesCount)
 {
     std::vector<Gdiplus::Point> points;
     Gdiplus::Point center(rc.Width / 2, rc.Height / 2);
@@ -150,7 +151,7 @@ std::vector<Gdiplus::Point> CalculatePoints(Gdiplus::Rect rc, int sidesCount)
     return points;
 }
 
-void PolyButton::OnPaint()
+void PolyButton::OnPaint() const
 {
     PAINTSTRUCT ps = {0};
     RECT rc;
@@ -174,10 +175,9 @@ void PolyButton::OnPaint()
         format.SetAlignment(Gdiplus::StringAlignmentCenter);
         format.SetLineAlignment(Gdiplus::StringAlignmentCenter);
         int len = GetWindowTextLength(_hwnd) + 1;
-        wchar_t *label = new wchar_t[len]();
-        GetWindowTextW(_hwnd, label, len);
-        g.DrawString(label, len, &font, layoutRect, &format, &textBrush);
-        delete [] label;
+        std::wstring label(len - 1, L'\0');
+        GetWindowTextW(_hwnd, label.data(), len);
+        g.DrawString(label.c_str(), len, &font, layoutRect, &format, &textBrush);
     }
     if ((_state & PolyButtonState::Focussed) == PolyButtonState::Focussed)
         DrawFocusRect(hdc, &rc);
@@ -204,4 +204,4 @@ void PolyButton::InvokeButton()
         }
         InvalidateRect(_hwnd, nullptr, TRUE);
     }
-}
\ No newline at end of file
+}
index 19d7e9a9ec805130077896b9eb85bde0f022ef9b..bf972fadef0007169d2850a9e5bfe4054ba215d0 100644 (file)
@@ -24,11 +24,11 @@ public:
     void InvokeButton();
     static void RegisterControl(HINSTANCE instance);
     bool IsChecked() const { return ((_state & PolyButtonState::Checked) == PolyButtonState::Checked); }
-    void OnPaint();
+    void OnPaint() const;
     void OnSetFocus();
     void OnKillFocus();
 private:
-    PolyButton() {}
+    PolyButton() = delete;
     HWND _hwnd;
     PolyButtonState _state;
     int _sides;
index ac9dd50ffa89c311501dd990d15b23702d744bb5..533408c0438fb34f8136d0bb47638586d709b389 100644 (file)
--- a/main.cpp
+++ b/main.cpp
@@ -1,5 +1,6 @@
 #include <Windows.h>
 #include <gdiplus.h>
+#include <CommCtrl.h>
 #include "resource.h"
 #include "PolyButton.h"
 
@@ -7,10 +8,31 @@
 #pragma comment(lib, "uiautomationcore")
 #pragma comment(linker,"/manifestdependency:\"type='win32' name='Microsoft.Windows.Common-Controls' version='6.0.0.0' processorArchitecture='*' publicKeyToken='6595b64144ccf1df' language='*'\"")
 
+static LPCTSTR comboItems[] = { TEXT("One"), TEXT("Two"), TEXT("Three"), TEXT("Four") };
+
 static INT_PTR CALLBACK DlgProc(HWND hDlg, UINT message, WPARAM wParam, LPARAM /*lParam*/)
 {
     switch (message)
     {
+    case WM_INITDIALOG:
+    {
+        HWND hwndCombo = GetDlgItem(hDlg, IDC_COMBO1);
+        HWND hwndComb2 = GetDlgItem(hDlg, IDC_COMBO2);
+        HWND hwndList = GetDlgItem(hDlg, IDC_LIST1);
+        HWND hwndCombx = GetDlgItem(hDlg, IDC_COMBOBOXEX1);
+        COMBOBOXEXITEM item = { 0 };
+        item.mask = CBEIF_TEXT;
+        item.iItem = -1;
+        for (size_t ndx = 0; ndx < sizeof(comboItems) / sizeof(comboItems[0]); ++ndx)
+        {
+            SendMessage(hwndCombo, CB_ADDSTRING, 0, reinterpret_cast<LPARAM>(comboItems[ndx]));
+            SendMessage(hwndComb2, CB_ADDSTRING, 0, reinterpret_cast<LPARAM>(comboItems[ndx]));
+            SendMessage(hwndList, LB_ADDSTRING, 0, reinterpret_cast<LPARAM>(comboItems[ndx]));
+            item.pszText = const_cast<LPTSTR>(comboItems[ndx]);
+            SendMessage(hwndCombx, CBEM_INSERTITEM, 0, reinterpret_cast<LPARAM>(&item));
+        }
+        break;
+    }
     case WM_COMMAND:
         if (LOWORD(wParam) == IDOK || LOWORD(wParam) == IDCANCEL)
         {
@@ -22,16 +44,18 @@ static INT_PTR CALLBACK DlgProc(HWND hDlg, UINT message, WPARAM wParam, LPARAM /
     return FALSE;
 }
 
-int PASCAL
-WinMain(HINSTANCE hinst, HINSTANCE, LPSTR, int)
+int WINAPI WinMain(_In_ HINSTANCE hInstance, _In_opt_ HINSTANCE hPrevInstance, _In_ LPSTR lpCmdLine, _In_ int nShowCmd)
 {
     Gdiplus::GdiplusStartupInput gdiplusStartupInput;
     ULONG_PTR gdiplusToken(0);
-    Gdiplus::GdiplusStartup(&gdiplusToken, &gdiplusStartupInput, NULL);
-    CoInitializeEx(nullptr, COINIT_APARTMENTTHREADED);
-    PolyButton::RegisterControl(hinst);
-    DialogBox(hinst, MAKEINTRESOURCE(IDD_DIALOG1), NULL, DlgProc);
-    CoUninitialize();
+    Gdiplus::GdiplusStartup(&gdiplusToken, &gdiplusStartupInput, nullptr);
+    HRESULT hr = ::CoInitializeEx(nullptr, COINIT_APARTMENTTHREADED);
+    if (SUCCEEDED(hr))
+    {
+        PolyButton::RegisterControl(hInstance);
+        DialogBox(hInstance, MAKEINTRESOURCE(IDD_DIALOG1), nullptr, DlgProc);
+        CoUninitialize();
+    }
     Gdiplus::GdiplusShutdown(gdiplusToken);
     return 0;
 }
diff --git a/main.rc b/main.rc
index e12acb79708eb0c81fe0624b13a07e83748fb79a..a6d2218cc21e168c27696a64e64592a6f79ea672 100644 (file)
--- a/main.rc
+++ b/main.rc
@@ -74,18 +74,18 @@ LANGUAGE LANG_ENGLISH, SUBLANG_ENGLISH_UK
 // TEXTINCLUDE
 //
 
-1 TEXTINCLUDE
+1 TEXTINCLUDE 
 BEGIN
     "resource.h\0"
 END
 
-2 TEXTINCLUDE
+2 TEXTINCLUDE 
 BEGIN
     "#include <winres.h>\r\n"
     "\0"
 END
 
-3 TEXTINCLUDE
+3 TEXTINCLUDE 
 BEGIN
     "\r\n"
     "\0"
@@ -99,7 +99,7 @@ END
 // Dialog
 //
 
-IDD_DIALOG1 DIALOGEX 0, 0, 309, 176
+IDD_DIALOG1 DIALOGEX 0, 0, 275, 173
 STYLE DS_SETFONT | DS_MODALFRAME | DS_FIXEDSYS | WS_POPUP | WS_CAPTION | WS_SYSMENU
 CAPTION "UIA Custom Control Demo"
 FONT 8, "MS Shell Dlg", 400, 0, 0x1
@@ -108,11 +108,21 @@ BEGIN
     GROUPBOX        "Static",IDC_STATIC,7,18,105,38
     CONTROL         "Option 1",IDC_RADIO1,"Button",BS_AUTORADIOBUTTON | WS_GROUP | WS_TABSTOP,15,28,91,10
     CONTROL         "Option 2",IDC_RADIO2,"Button",BS_AUTORADIOBUTTON | WS_TABSTOP,15,42,92,10
-    LTEXT           "Label",IDC_STATIC,7,62,18,8
-    EDITTEXT        IDC_EDIT1,33,59,100,14,ES_AUTOHSCROLL
-    CONTROL         "Hello",IDC_CUSTOM1,"POLYBUTTON",WS_TABSTOP,15,82,60,27
-    DEFPUSHBUTTON   "OK",IDOK,198,155,50,14
-    PUSHBUTTON      "Cancel",IDCANCEL,252,155,50,14
+    LTEXT           "Things",IDC_STATIC,125,7,22,8
+    LISTBOX         IDC_LIST1,151,7,117,40,LBS_NOINTEGRALHEIGHT | WS_VSCROLL | WS_TABSTOP
+    LTEXT           "Edit",IDC_STATIC,7,62,31,8
+    EDITTEXT        IDC_EDIT1,44,59,101,14,ES_AUTOHSCROLL
+    LTEXT           "Combo",IDC_STATIC,7,81,31,8
+    COMBOBOX        IDC_COMBO1,44,79,101,30,CBS_DROPDOWNLIST | WS_VSCROLL | WS_TABSTOP
+    LTEXT           "EditCombo",IDC_STATIC,153,81,35,8
+    COMBOBOX        IDC_COMBO2,191,79,77,30,CBS_DROPDOWN | WS_VSCROLL | WS_TABSTOP
+    LTEXT           "ComboEx",IDC_STATIC,7,98,31,8
+    CONTROL         "",IDC_COMBOBOXEX1,"ComboBoxEx32",CBS_DROPDOWNLIST | CBS_SORT | WS_VSCROLL | WS_TABSTOP,44,97,101,38
+    CONTROL         "Hello",IDC_CUSTOM1,"POLYBUTTON",WS_TABSTOP,21,119,46,40
+    LTEXT           "Text",IDC_STATIC,73,116,16,8
+    EDITTEXT        IDC_EDIT2,95,116,173,33,ES_MULTILINE | ES_AUTOHSCROLL | ES_WANTRETURN | WS_VSCROLL
+    DEFPUSHBUTTON   "OK",IDOK,166,152,50,14
+    PUSHBUTTON      "Cancel",IDCANCEL,218,152,50,14
 END
 
 
@@ -127,9 +137,9 @@ BEGIN
     IDD_DIALOG1, DIALOG
     BEGIN
         LEFTMARGIN, 7
-        RIGHTMARGIN, 302
+        RIGHTMARGIN, 268
         TOPMARGIN, 7
-        BOTTOMMARGIN, 169
+        BOTTOMMARGIN, 166
     END
 END
 #endif    // APSTUDIO_INVOKED
index c312e64ee824e1b47b992288d6e5bcaca2ddac61..0f1dfecac72a26ab6e28b2fda2f12e9757cd24d2 100644 (file)
@@ -2,13 +2,17 @@
 // Microsoft Visual C++ generated include file.
 // Used by main.rc
 //
-
-#define IDD_DIALOG1                                            101
-#define IDC_CHECK1                                             102
-#define IDC_RADIO1                                             103
-#define IDC_RADIO2                                             104
-#define IDC_EDIT1                                              105
-#define IDC_CUSTOM1                                            106
+#define IDD_DIALOG1                     101
+#define IDC_CHECK1                      102
+#define IDC_RADIO1                      103
+#define IDC_RADIO2                      104
+#define IDC_EDIT1                       105
+#define IDC_CUSTOM1                     106
+#define IDC_COMBO1                      1005
+#define IDC_COMBOBOXEX1                 1006
+#define IDC_COMBO2                      1007
+#define IDC_LIST1                       1008
+#define IDC_EDIT2                       1009
 
 // Next default values for new objects
 // 
@@ -16,7 +20,7 @@
 #ifndef APSTUDIO_READONLY_SYMBOLS
 #define _APS_NEXT_RESOURCE_VALUE        103
 #define _APS_NEXT_COMMAND_VALUE         40001
-#define _APS_NEXT_CONTROL_VALUE         1005
+#define _APS_NEXT_CONTROL_VALUE         1010
 #define _APS_NEXT_SYMED_VALUE           101
 #endif
 #endif