[PATCH] winecfg: Use a listview for speaker configuration

Andrew Eikum aeikum at codeweavers.com
Tue Apr 14 14:01:46 CDT 2015


There was some confusion around how these controls should be used; see
bugs 38006 and 37957. I think a listview makes the controls more
intuitive and more similar to other winecfg tab behaviors.
---
 programs/winecfg/audio.c    | 105 ++++++++++++++++++++++++++++++++------------
 programs/winecfg/resource.h |   4 +-
 programs/winecfg/winecfg.rc |  12 ++---
 3 files changed, 88 insertions(+), 33 deletions(-)

diff --git a/programs/winecfg/audio.c b/programs/winecfg/audio.c
index 5b03f45..4b22f3d 100644
--- a/programs/winecfg/audio.c
+++ b/programs/winecfg/audio.c
@@ -225,6 +225,10 @@ static void initAudioDlg (HWND hDlg)
     BOOL have_driver = FALSE;
     HRESULT hr;
     UINT i;
+    LVCOLUMNW lvcol;
+    WCHAR colW[64], speaker_str[256];
+    RECT rect;
+    DWORD width;
 
     WINE_TRACE("\n");
 
@@ -271,8 +275,6 @@ static void initAudioDlg (HWND hDlg)
 
     i = 0;
     while (speaker_configs[i].text_id != 0) {
-        WCHAR speaker_str[256];
-
         LoadStringW(GetModuleHandleW(NULL), speaker_configs[i].text_id,
             speaker_str, sizeof(speaker_str) / sizeof(*speaker_str));
 
@@ -282,19 +284,35 @@ static void initAudioDlg (HWND hDlg)
         i++;
     }
 
+    GetClientRect(GetDlgItem(hDlg, IDC_LIST_AUDIO_DEVICES), &rect);
+    width = (rect.right - rect.left) * 3 / 5;
+
+    LoadStringW(GetModuleHandleW(NULL), IDS_AUDIO_DEVICE, colW, sizeof(colW)/sizeof(*colW));
+    lvcol.mask = LVCF_TEXT | LVCF_WIDTH | LVCF_SUBITEM;
+    lvcol.pszText = colW;
+    lvcol.cchTextMax = lstrlenW(colW);
+    lvcol.cx = width;
+    SendDlgItemMessageW(hDlg, IDC_LIST_AUDIO_DEVICES, LVM_INSERTCOLUMNW, 0, (LPARAM)&lvcol);
+
+    LoadStringW(GetModuleHandleW(NULL), IDS_AUDIO_SPEAKER_CONFIG, colW, sizeof(colW)/sizeof(*colW));
+    lvcol.pszText = colW;
+    lvcol.cchTextMax = lstrlenW(colW);
+    lvcol.cx = rect.right - rect.left - width;
+    SendDlgItemMessageW(hDlg, IDC_LIST_AUDIO_DEVICES, LVM_INSERTCOLUMNW, 1, (LPARAM)&lvcol);
+
+    EnableWindow(GetDlgItem(hDlg, IDC_SPEAKERCONFIG_SPEAKERS), 0);
+
     if(have_driver){
         WCHAR *reg_out_dev, *reg_vout_dev, *reg_in_dev, *reg_vin_dev;
-        BOOL default_dev_found = FALSE;
 
         reg_out_dev = get_reg_keyW(HKEY_CURRENT_USER, g_drv_keyW, reg_out_nameW, NULL);
         reg_vout_dev = get_reg_keyW(HKEY_CURRENT_USER, g_drv_keyW, reg_vout_nameW, NULL);
         reg_in_dev = get_reg_keyW(HKEY_CURRENT_USER, g_drv_keyW, reg_in_nameW, NULL);
         reg_vin_dev = get_reg_keyW(HKEY_CURRENT_USER, g_drv_keyW, reg_vin_nameW, NULL);
 
-        SendDlgItemMessageW(hDlg, IDC_SPEAKERCONFIG_DEVICE, CB_SETCURSEL, i, 0);
-        SendDlgItemMessageW(hDlg, IDC_SPEAKERCONFIG_SPEAKERS, CB_SETCURSEL, render_devs[i].speaker_config, 0);
-
         for(i = 0; i < num_render_devs; ++i){
+            LVITEMW lvitem;
+
             if(!render_devs[i].id)
                 continue;
 
@@ -303,14 +321,9 @@ static void initAudioDlg (HWND hDlg)
             SendDlgItemMessageW(hDlg, IDC_AUDIOOUT_DEVICE, CB_SETITEMDATA,
                     i + 1, (LPARAM)&render_devs[i]);
 
-            SendDlgItemMessageW(hDlg, IDC_SPEAKERCONFIG_DEVICE, CB_ADDSTRING,
-                    0, (LPARAM)render_devs[i].name.u.pwszVal);
-
             if(reg_out_dev && !lstrcmpW(render_devs[i].id, reg_out_dev)){
                 SendDlgItemMessageW(hDlg, IDC_AUDIOOUT_DEVICE, CB_SETCURSEL, i + 1, 0);
-                SendDlgItemMessageW(hDlg, IDC_SPEAKERCONFIG_DEVICE, CB_SETCURSEL, i, 0);
                 SendDlgItemMessageW(hDlg, IDC_SPEAKERCONFIG_SPEAKERS, CB_SETCURSEL, render_devs[i].speaker_config, 0);
-                default_dev_found = TRUE;
             }
 
             SendDlgItemMessageW(hDlg, IDC_VOICEOUT_DEVICE, CB_ADDSTRING,
@@ -319,11 +332,26 @@ static void initAudioDlg (HWND hDlg)
                     i + 1, (LPARAM)&render_devs[i]);
             if(reg_vout_dev && !lstrcmpW(render_devs[i].id, reg_vout_dev))
                 SendDlgItemMessageW(hDlg, IDC_VOICEOUT_DEVICE, CB_SETCURSEL, i + 1, 0);
-        }
 
-        if(!default_dev_found && num_render_devs > 0){
-            SendDlgItemMessageW(hDlg, IDC_SPEAKERCONFIG_DEVICE, CB_SETCURSEL, 0, 0);
-            SendDlgItemMessageW(hDlg, IDC_SPEAKERCONFIG_SPEAKERS, CB_SETCURSEL, render_devs[0].speaker_config, 0);
+            lvitem.mask = LVIF_TEXT | LVIF_PARAM;
+            lvitem.iItem = i;
+            lvitem.iSubItem = 0;
+            lvitem.pszText = render_devs[i].name.u.pwszVal;
+            lvitem.cchTextMax = lstrlenW(lvitem.pszText);
+            lvitem.lParam = (LPARAM)&render_devs[i];
+
+            SendDlgItemMessageW(hDlg, IDC_LIST_AUDIO_DEVICES, LVM_INSERTITEMW, 0, (LPARAM)&lvitem);
+
+            LoadStringW(GetModuleHandleW(NULL), speaker_configs[render_devs[i].speaker_config].text_id,
+                speaker_str, sizeof(speaker_str) / sizeof(*speaker_str));
+
+            lvitem.mask = LVIF_TEXT;
+            lvitem.iItem = i;
+            lvitem.iSubItem = 1;
+            lvitem.pszText = speaker_str;
+            lvitem.cchTextMax = lstrlenW(lvitem.pszText);
+
+            SendDlgItemMessageW(hDlg, IDC_LIST_AUDIO_DEVICES, LVM_SETITEMW, 0, (LPARAM)&lvitem);
         }
 
         for(i = 0; i < num_capture_devs; ++i){
@@ -436,6 +464,22 @@ static void apply_speaker_configs(void)
     IMMDeviceEnumerator_Release(devenum);
 }
 
+static void listview_changed(HWND hDlg)
+{
+    int idx;
+
+    idx = SendDlgItemMessageW(hDlg, IDC_LIST_AUDIO_DEVICES, LVM_GETNEXTITEM, -1, LVNI_SELECTED);
+    if(idx < 0) {
+        EnableWindow(GetDlgItem(hDlg, IDC_SPEAKERCONFIG_SPEAKERS), 0);
+        return;
+    }
+
+    SendDlgItemMessageW(hDlg, IDC_SPEAKERCONFIG_SPEAKERS, CB_SETCURSEL,
+            render_devs[idx].speaker_config, 0);
+
+    EnableWindow(GetDlgItem(hDlg, IDC_SPEAKERCONFIG_SPEAKERS), 1);
+}
+
 INT_PTR CALLBACK
 AudioDlgProc (HWND hDlg, UINT uMsg, WPARAM wParam, LPARAM lParam)
 {
@@ -469,26 +513,30 @@ AudioDlgProc (HWND hDlg, UINT uMsg, WPARAM wParam, LPARAM lParam)
                   SendMessageW(GetParent(hDlg), PSM_CHANGED, 0, 0);
               }
               break;
-          case IDC_SPEAKERCONFIG_DEVICE:
-              if(HIWORD(wParam) == CBN_SELCHANGE){
-                  UINT idx;
-
-                  idx = SendDlgItemMessageW(hDlg, IDC_SPEAKERCONFIG_DEVICE, CB_GETCURSEL, 0, 0);
-
-                  if(idx < num_render_devs){
-                      SendDlgItemMessageW(hDlg, IDC_SPEAKERCONFIG_SPEAKERS, CB_SETCURSEL, render_devs[idx].speaker_config, 0);
-                  }
-              }
-              break;
           case IDC_SPEAKERCONFIG_SPEAKERS:
               if(HIWORD(wParam) == CBN_SELCHANGE){
                   UINT dev, idx;
 
                   idx = SendDlgItemMessageW(hDlg, IDC_SPEAKERCONFIG_SPEAKERS, CB_GETCURSEL, 0, 0);
-                  dev = SendDlgItemMessageW(hDlg, IDC_SPEAKERCONFIG_DEVICE, CB_GETCURSEL, 0, 0);
+                  dev = SendDlgItemMessageW(hDlg, IDC_LIST_AUDIO_DEVICES, LVM_GETNEXTITEM, -1, LVNI_SELECTED);
 
                   if(dev < num_render_devs){
+                      WCHAR speaker_str[256];
+                      LVITEMW lvitem;
+
                       render_devs[dev].speaker_config = idx;
+
+                      LoadStringW(GetModuleHandleW(NULL), speaker_configs[idx].text_id,
+                          speaker_str, sizeof(speaker_str) / sizeof(*speaker_str));
+
+                      lvitem.mask = LVIF_TEXT;
+                      lvitem.iItem = dev;
+                      lvitem.iSubItem = 1;
+                      lvitem.pszText = speaker_str;
+                      lvitem.cchTextMax = lstrlenW(lvitem.pszText);
+
+                      SendDlgItemMessageW(hDlg, IDC_LIST_AUDIO_DEVICES, LVM_SETITEMW, 0, (LPARAM)&lvitem);
+
                       SendMessageW(GetParent(hDlg), PSM_CHANGED, 0, 0);
                   }
               }
@@ -512,6 +560,9 @@ AudioDlgProc (HWND hDlg, UINT uMsg, WPARAM wParam, LPARAM lParam)
               break;
             case PSN_SETACTIVE:
               break;
+            case LVN_ITEMCHANGED:
+              listview_changed(hDlg);
+              break;
         }
         break;
       case WM_INITDIALOG:
diff --git a/programs/winecfg/resource.h b/programs/winecfg/resource.h
index 3118fb6..8604fb4 100644
--- a/programs/winecfg/resource.h
+++ b/programs/winecfg/resource.h
@@ -149,12 +149,14 @@
 #define IDS_AUDIO_TEST_FAILED           1309
 #define IDS_AUDIO_TEST_FAILED_TITLE     1310
 #define IDS_AUDIO_SYSDEFAULT            1311
-#define IDC_SPEAKERCONFIG_DEVICE        1312
+#define IDS_AUDIO_DEVICE                1312
 #define IDC_SPEAKERCONFIG_SPEAKERS      1313
 #define IDS_AUDIO_SPEAKER_5POINT1       1314
 #define IDS_AUDIO_SPEAKER_QUAD          1315
 #define IDS_AUDIO_SPEAKER_STEREO        1316
 #define IDS_AUDIO_SPEAKER_MONO          1317
+#define IDC_LIST_AUDIO_DEVICES          1318
+#define IDS_AUDIO_SPEAKER_CONFIG        1319
 
 /* desktop integration tab */
 #define IDC_THEME_COLORCOMBO            1401
diff --git a/programs/winecfg/winecfg.rc b/programs/winecfg/winecfg.rc
index f82159e..8be447e 100644
--- a/programs/winecfg/winecfg.rc
+++ b/programs/winecfg/winecfg.rc
@@ -85,6 +85,8 @@ BEGIN
     IDS_AUDIO_TEST_FAILED "Audio test failed!"
     IDS_AUDIO_TEST_FAILED_TITLE "Error"
     IDS_AUDIO_SYSDEFAULT "(System default)"
+    IDS_AUDIO_DEVICE "Device"
+    IDS_AUDIO_SPEAKER_CONFIG "Speaker configuration"
     IDS_AUDIO_SPEAKER_5POINT1 "5.1 Surround"
     IDS_AUDIO_SPEAKER_QUAD "Quadraphonic"
     IDS_AUDIO_SPEAKER_STEREO "Stereo"
@@ -271,11 +273,11 @@ BEGIN
     COMBOBOX        IDC_AUDIOIN_DEVICE,110,75,135,14,CBS_DROPDOWNLIST | WS_VSCROLL | WS_TABSTOP
     COMBOBOX        IDC_VOICEIN_DEVICE,110,91,135,14,CBS_DROPDOWNLIST | WS_VSCROLL | WS_TABSTOP
     PUSHBUTTON      "&Test Sound",IDC_AUDIO_TEST,8,113,69,14
-    GROUPBOX        "Speaker configuration",IDC_STATIC,8,132,244,44
-    LTEXT           "Device:",IDC_STATIC,18,144,230,8
-    COMBOBOX        IDC_SPEAKERCONFIG_DEVICE,110,142,135,14,CBS_DROPDOWNLIST | WS_VSCROLL | WS_TABSTOP
-    LTEXT           "Speakers:",IDC_STATIC,18,160,230,8
-    COMBOBOX        IDC_SPEAKERCONFIG_SPEAKERS,110,158,135,14,CBS_DROPDOWNLIST | WS_VSCROLL | WS_TABSTOP
+    GROUPBOX        "Speaker configuration",IDC_STATIC,8,132,244,86
+    CONTROL         "",IDC_LIST_AUDIO_DEVICES,"SysListView32",LVS_REPORT | LVS_AUTOARRANGE | LVS_ALIGNLEFT |
+                    LVS_SINGLESEL | WS_BORDER | WS_TABSTOP | LVS_NOSORTHEADER, 15,146,232,52
+    LTEXT           "Speakers:",IDC_STATIC,18,202,230,8
+    COMBOBOX        IDC_SPEAKERCONFIG_SPEAKERS,110,200,135,14,CBS_DROPDOWNLIST | WS_VSCROLL | WS_TABSTOP
 END
 
 IDD_DESKTOP_INTEGRATION DIALOG  0, 0, 260, 220
-- 
2.3.5




More information about the wine-patches mailing list