[v2] Add a GUI for dxdiag program

Ruslan Kabatsayev b7.10110111 at gmail.com
Sat Aug 27 03:26:26 CDT 2016


This adds a dialog with only System tab, reflecting what save-to-file
functionality currently provides. It can also save the report as file
from the GUI in a way similar to its Windows counterpart.
This version now also shows DMI information which current dxdiagn.dll doesn't
provide, but may do so in the future. Also some spacing issues are fixed.

Signed-off-by: Ruslan Kabatsayev <b7.10110111 at gmail.com>
---
 programs/dxdiag/Makefile.in      |    3 +-
 programs/dxdiag/dxdiag.rc        |   64 +++++++++++
 programs/dxdiag/dxdiag_private.h |    9 +-
 programs/dxdiag/main.c           |   20 ++--
 programs/dxdiag/main_dialog.c    |  220 ++++++++++++++++++++++++++++++++++++++
 programs/dxdiag/resource.h       |   56 ++++++++++
 6 files changed, 356 insertions(+), 16 deletions(-)
 create mode 100644 programs/dxdiag/main_dialog.c
 create mode 100644 programs/dxdiag/resource.h

diff --git a/programs/dxdiag/Makefile.in b/programs/dxdiag/Makefile.in
index 437cc5e..d971a55 100644
--- a/programs/dxdiag/Makefile.in
+++ b/programs/dxdiag/Makefile.in
@@ -1,10 +1,11 @@
 MODULE    = dxdiag.exe
 APPMODE   = -mwindows -municode
-IMPORTS   = dxguid ole32 oleaut32 user32
+IMPORTS   = dxguid ole32 oleaut32 user32 comdlg32
 
 C_SRCS = \
 	information.c \
 	main.c \
+    main_dialog.c \
 	output.c
 
 RC_SRCS = dxdiag.rc
diff --git a/programs/dxdiag/dxdiag.rc b/programs/dxdiag/dxdiag.rc
index a37b28d..ff6ba34 100644
--- a/programs/dxdiag/dxdiag.rc
+++ b/programs/dxdiag/dxdiag.rc
@@ -2,6 +2,7 @@
  * Resources for the DirectX Diagnostic Tool
  *
  * Copyright 2011 Andrew Nguyen
+ * Copyright 2016 Ruslan Kabatsayev
  *
  * This library is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
@@ -20,6 +21,10 @@
 
 #include "dxdiag_private.h"
 
+#include <windows.h>
+#include <commctrl.h>
+#include "resource.h"
+
 #pragma makedep po
 
 LANGUAGE LANG_ENGLISH, SUBLANG_DEFAULT
@@ -28,4 +33,63 @@ STRINGTABLE
 {
     STRING_DXDIAG_TOOL, "DirectX Diagnostic Tool"
     STRING_USAGE, "Usage: dxdiag [/whql:off | /whql:on] [/t filename | /x filename]"
+    STRING_INFO_COLLECTION_FAILED, "Failed to collect DxDiag information"
+    STRING_ERROR, "Error"
+    STRING_SYSTEM_TAB, "System"
+}
+
+
+IDD_MAIN DIALOG 0, 0, 400, 250
+STYLE DS_3DLOOK | DS_ABSALIGN | DS_CENTER | DS_SHELLFONT | WS_CAPTION | WS_VISIBLE | WS_GROUP | WS_SYSMENU
+CAPTION "DirectX Diagnostic Tool"
+FONT 8, "Ms Shell Dlg"
+{
+    DEFPUSHBUTTON   "&Next Page", IDC_NEXT_PAGE, 132, 231, 85, 14, 0, WS_EX_LEFT
+    PUSHBUTTON      "&Save All Information...", IDC_SAVE_INFO, 222, 231, 85, 14, 0, WS_EX_LEFT
+    PUSHBUTTON      "E&xit", IDC_EXIT, 312, 231, 85, 14, 0, WS_EX_LEFT
+    CONTROL         "", IDC_MAIN_TABS, WC_TABCONTROLA, 0, 2, 0, 396, 226, WS_EX_LEFT
+}
+
+IDD_SYSTEM_TAB DIALOG 0, 0, 387, 176
+STYLE DS_SETFONT | WS_CHILDWINDOW
+FONT 8, "Ms Shell Dlg"
+{
+    GROUPBOX        "System Information", IDC_SYSINFO_GROUP, 3, 65, 381, 136, 0, WS_EX_LEFT
+    LTEXT           "If you know what area is causing the problem, click the appropriate tab above. Otherwise, you can use the ""Next Page"" button below to visit each page in sequence.", IDC_SYSTEMTAB_LABEL1, 9, 37, 344, 17, SS_LEFT, WS_EX_LEFT
+    LTEXT           "This tool reports information about the DirectX components and drivers installed on your system. It lets you test functionality and diagnose problems.", IDC_SYSTEMTAB_LABEL2, 9, 11, 370, 17, SS_LEFT, WS_EX_LEFT
+
+    RTEXT           "Current Date/Time:", IDC_SYSTEMTAB_DATETIME_LABEL, 10, 74, 140, 9, SS_RIGHT, WS_EX_LEFT
+    LTEXT           "",                   IDC_SYSTEMTAB_DATETIME_VALUE, 153, 74, 227, 9, SS_LEFT, WS_EX_LEFT
+
+    RTEXT           "Computer name:", IDC_SYSTEMTAB_PCNAME_LABEL, 10, 84, 140, 9, SS_RIGHT, WS_EX_LEFT
+    LTEXT           "",               IDC_SYSTEMTAB_PCNAME_VALUE, 153, 84, 227, 9, SS_LEFT, WS_EX_LEFT
+
+    RTEXT           "Operating System:", IDC_SYSTEMTAB_OS_LABEL, 10, 94, 140, 9, SS_RIGHT, WS_EX_LEFT
+    LTEXT           "",                  IDC_SYSTEMTAB_OS_VALUE, 153, 94, 227, 9, SS_LEFT, WS_EX_LEFT
+
+    RTEXT           "Language:", IDC_SYSTEMTAB_LANG_LABEL, 10, 104, 140, 9, SS_RIGHT, WS_EX_LEFT
+    LTEXT           "",          IDC_SYSTEMTAB_LANG_VALUE, 153, 104, 227, 9, SS_LEFT, WS_EX_LEFT
+
+    RTEXT           "System Manufacturer:", IDC_SYSTEMTAB_VENDOR_LABEL, 10, 114, 140, 9, SS_RIGHT, WS_EX_LEFT
+    LTEXT           "",                     IDC_SYSTEMTAB_VENDOR_VALUE, 153, 114, 227, 9, SS_LEFT, WS_EX_LEFT
+
+    RTEXT           "System Model:", IDC_SYSTEMTAB_MODEL_LABEL, 10, 124, 140, 9, SS_RIGHT, WS_EX_LEFT
+    LTEXT           "",              IDC_SYSTEMTAB_MODEL_VALUE, 153, 124, 227, 9, SS_LEFT, WS_EX_LEFT
+
+    RTEXT           "BIOS:", IDC_SYSTEMTAB_BIOS_LABEL, 10, 134, 140, 9, SS_RIGHT, WS_EX_LEFT
+    LTEXT           "",      IDC_SYSTEMTAB_BIOS_VALUE, 153, 134, 227, 9, SS_LEFT, WS_EX_LEFT
+
+    RTEXT           "Processor:", IDC_SYSTEMTAB_CPU_LABEL, 10, 144, 140, 9, SS_RIGHT, WS_EX_LEFT
+    LTEXT           "",           IDC_SYSTEMTAB_CPU_VALUE, 153, 144, 227, 9, SS_LEFT, WS_EX_LEFT
+
+    RTEXT           "Memory:", IDC_SYSTEMTAB_RAM_LABEL, 10, 154, 140, 9, SS_RIGHT, WS_EX_LEFT
+    LTEXT           "",        IDC_SYSTEMTAB_RAM_VALUE, 153, 154, 227, 9, SS_LEFT, WS_EX_LEFT
+
+    RTEXT           "Page File:", IDC_SYSTEMTAB_PAGEFILE_LABEL, 10, 164, 140, 9, SS_RIGHT, WS_EX_LEFT
+    LTEXT           "",           IDC_SYSTEMTAB_PAGEFILE_VALUE, 153, 164, 227, 9, SS_LEFT, WS_EX_LEFT
+
+    RTEXT           "DirectX Version:", IDC_SYSTEMTAB_DXVERSION_LABEL, 10, 174, 140, 9, SS_RIGHT, WS_EX_LEFT
+    LTEXT           "",                 IDC_SYSTEMTAB_DXVERSION_VALUE, 153, 174, 227, 9, SS_LEFT, WS_EX_LEFT
+
+    AUTOCHECKBOX    "Check for WHQL digital signatures", IDC_WHQL_CHECKBOX, 10, 186, 369, 9, 0, WS_EX_LEFT
 }
diff --git a/programs/dxdiag/dxdiag_private.h b/programs/dxdiag/dxdiag_private.h
index 010bb94..1dc0622 100644
--- a/programs/dxdiag/dxdiag_private.h
+++ b/programs/dxdiag/dxdiag_private.h
@@ -19,12 +19,7 @@
  */
 
 #include <windef.h>
-
-/* Resource definitions. */
-#define MAX_STRING_LEN          1024
-
-#define STRING_DXDIAG_TOOL      101
-#define STRING_USAGE            102
+#include "resource.h"
 
 /* Information collection definitions. */
 struct system_information
@@ -83,3 +78,5 @@ static inline const char *debugstr_output_type(enum output_type type)
 
 const WCHAR *get_output_extension(enum output_type type);
 BOOL output_dxdiag_information(struct dxdiag_information *dxdiag_info, const WCHAR *filename, enum output_type type);
+
+INT_PTR CALLBACK main_dlg_proc(HWND hdlg, UINT msg, WPARAM wparam, LPARAM lparam);
diff --git a/programs/dxdiag/main.c b/programs/dxdiag/main.c
index 3ced122..6b5aa35 100644
--- a/programs/dxdiag/main.c
+++ b/programs/dxdiag/main.c
@@ -30,6 +30,7 @@
 WINE_DEFAULT_DEBUG_CHANNEL(dxdiag);
 
 HINSTANCE hInstance;
+struct dxdiag_information *dxdiag_info;
 
 struct command_line_info
 {
@@ -176,7 +177,6 @@ static BOOL process_command_line(const WCHAR *cmdline, struct command_line_info
 int WINAPI wWinMain(HINSTANCE hInst, HINSTANCE hPrevInst, LPWSTR cmdline, int cmdshow)
 {
     struct command_line_info info;
-    struct dxdiag_information *dxdiag_info;
 
     hInstance = hInst;
 
@@ -190,18 +190,20 @@ int WINAPI wWinMain(HINSTANCE hInst, HINSTANCE hPrevInst, LPWSTR cmdline, int cm
 
     CoInitialize(NULL);
 
-    dxdiag_info = collect_dxdiag_information(info.whql_check);
-    if (!dxdiag_info)
+    if (info.output_type != OUTPUT_NONE)
     {
-        WINE_ERR("DxDiag information collection failed\n");
-        CoUninitialize();
-        return 1;
-    }
+        dxdiag_info = collect_dxdiag_information(info.whql_check);
+        if (!dxdiag_info)
+        {
+            WINE_ERR("DxDiag information collection failed\n");
+            CoUninitialize();
+            return 1;
+        }
 
-    if (info.output_type != OUTPUT_NONE)
         output_dxdiag_information(dxdiag_info, info.outfile, info.output_type);
+    }
     else
-        WINE_FIXME("Information dialog is not implemented\n");
+        DialogBoxW(hInst,(WCHAR*)MAKEINTRESOURCE(IDD_MAIN),NULL,main_dlg_proc);
 
     free_dxdiag_information(dxdiag_info);
 
diff --git a/programs/dxdiag/main_dialog.c b/programs/dxdiag/main_dialog.c
new file mode 100644
index 0000000..65efa09
--- /dev/null
+++ b/programs/dxdiag/main_dialog.c
@@ -0,0 +1,220 @@
+/*
+ * DxDiag main dialog implementation
+ *
+ * Copyright 2016 Ruslan Kabatsayev
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
+ */
+
+#include <windows.h>
+#include <commctrl.h>
+#include <commdlg.h>
+
+#include "dxdiag_private.h"
+
+extern HINSTANCE hInstance;
+extern struct dxdiag_information * dxdiag_info;
+
+HWND main_dialog;
+HWND main_tab_control;
+enum
+{
+    SYSTEM_TAB_INDEX,
+
+    MAIN_DIALOG_TAB_COUNT
+};
+HWND main_dialog_tabs[MAIN_DIALOG_TAB_COUNT];
+
+void set_main_dialog_tab(int new_tab_index)
+{
+    RECT tab_rect;
+    POINT top_left, bottom_right;
+    const HWND new_tab = main_dialog_tabs[new_tab_index];
+    int tab = 0;
+    for(;tab<MAIN_DIALOG_TAB_COUNT;++tab)
+        ShowWindow(main_dialog_tabs[tab], SW_HIDE);
+
+    GetWindowRect(main_tab_control, &tab_rect);
+
+    top_left.x = tab_rect.left;
+    top_left.y = tab_rect.top;
+    bottom_right.x = tab_rect.right;
+    bottom_right.y = tab_rect.bottom;
+    ScreenToClient(main_dialog, &top_left);
+    ScreenToClient(main_dialog, &bottom_right);
+    tab_rect.left = top_left.x;
+    tab_rect.right = bottom_right.x;
+    tab_rect.top = top_left.y;
+    tab_rect.bottom = bottom_right.y;
+
+    SendMessageW(main_tab_control, TCM_ADJUSTRECT, FALSE, (LPARAM)&tab_rect);
+    SetWindowPos(new_tab, HWND_TOP,
+                 tab_rect.left,
+                 tab_rect.top,
+                 tab_rect.right-tab_rect.left,
+                 tab_rect.bottom-tab_rect.top, SWP_SHOWWINDOW);
+}
+
+void main_dialog_insert_tab(int index, int caption_id, int template_id, DLGPROC dlg_proc)
+{
+    WCHAR tab_caption[MAX_STRING_LEN];
+    const TCITEMW tab_item = {.pszText = tab_caption, .mask = TCIF_TEXT};
+    LoadStringW(hInstance, caption_id, tab_caption, sizeof tab_caption/sizeof tab_caption[0]);
+    TabCtrl_InsertItemW(main_tab_control, index, &tab_item);
+    main_dialog_tabs[index] = CreateDialogParamW(hInstance, (WCHAR*)MAKEINTRESOURCE(template_id),
+                                                 main_tab_control, dlg_proc, 0);
+}
+
+void populate_system_tab(void)
+{
+    const HWND page = main_dialog_tabs[SYSTEM_TAB_INDEX];
+    const struct system_information zeros = {0};
+    const struct system_information*const si = dxdiag_info ? &dxdiag_info->system_info : &zeros;
+    SetWindowTextW(GetDlgItem(page, IDC_SYSTEMTAB_DATETIME_VALUE), si->szTimeLocalized);
+    SetWindowTextW(GetDlgItem(page, IDC_SYSTEMTAB_PCNAME_VALUE), si->szMachineNameEnglish);
+    SetWindowTextW(GetDlgItem(page, IDC_SYSTEMTAB_OS_VALUE), si->szOSExLocalized);
+    SetWindowTextW(GetDlgItem(page, IDC_SYSTEMTAB_LANG_VALUE), si->szLanguagesLocalized);
+    SetWindowTextW(GetDlgItem(page, IDC_SYSTEMTAB_VENDOR_VALUE), si->szSystemManufacturerEnglish);
+    SetWindowTextW(GetDlgItem(page, IDC_SYSTEMTAB_MODEL_VALUE), si->szSystemModelEnglish);
+    SetWindowTextW(GetDlgItem(page, IDC_SYSTEMTAB_BIOS_VALUE), si->szBIOSEnglish);
+    SetWindowTextW(GetDlgItem(page, IDC_SYSTEMTAB_CPU_VALUE), si->szProcessorEnglish);
+    SetWindowTextW(GetDlgItem(page, IDC_SYSTEMTAB_RAM_VALUE), si->szPhysicalMemoryEnglish);
+    SetWindowTextW(GetDlgItem(page, IDC_SYSTEMTAB_PAGEFILE_VALUE), si->szPageFileLocalized);
+    SetWindowTextW(GetDlgItem(page, IDC_SYSTEMTAB_DXVERSION_VALUE), si->szDirectXVersionLongEnglish);
+}
+
+void populate_tabs(void)
+{
+    populate_system_tab();
+}
+
+void save_info_dialog(HWND parent)
+{
+    static const WCHAR filter[] = {'T','e','x','t',' ','f','i','l','e',' ','(','*','.','t','x','t',')',0, '*','.','t','x','t',0,
+                                 'X','M','L',' ','f','i','l','e',' ','(','*','.','x','m','l',')',0,     '*','.','x','m','l',0,0};
+    OPENFILENAMEW ofn = {0};
+    WCHAR filename[MAX_PATH];
+    filename[0] = 0;
+
+    ofn.lStructSize = sizeof ofn;
+    ofn.hwndOwner = parent;
+    ofn.lpstrFilter = filter;
+    ofn.lpstrFile = filename;
+    ofn.nMaxFile = MAX_PATH;
+    ofn.Flags = OFN_EXPLORER|OFN_HIDEREADONLY|OFN_OVERWRITEPROMPT;
+    if(GetSaveFileNameW(&ofn))
+    {
+        enum output_type file_type;
+        switch(ofn.nFilterIndex)
+        {
+        case 1: file_type = OUTPUT_TEXT; break;
+        case 2: file_type = OUTPUT_XML; break;
+        default: file_type = OUTPUT_NONE; break;
+        }
+        output_dxdiag_information(dxdiag_info, filename, file_type);
+    }
+}
+
+void update_dxdiag_info(void)
+{
+    const HWND checkbox = GetDlgItem(main_dialog, IDC_WHQL_CHECKBOX);
+    const HWND save_all_button = GetDlgItem(main_dialog, IDC_SAVE_INFO);
+    const BOOL check_whql = SendMessageW(checkbox, BM_GETCHECK, 0L, 0L) == BST_CHECKED;
+    free_dxdiag_information(dxdiag_info);
+    dxdiag_info = collect_dxdiag_information(check_whql);
+    /* update the dialog before showing error message */
+    populate_tabs();
+    if(!dxdiag_info)
+    {
+        WCHAR title[MAX_STRING_LEN];
+        WCHAR message[MAX_STRING_LEN];
+
+        LoadStringW(hInstance, STRING_ERROR, title, sizeof title/sizeof title[0]);
+        LoadStringW(hInstance, STRING_INFO_COLLECTION_FAILED, message, sizeof message/sizeof message[0]);
+        MessageBoxW(main_dialog, message, title, MB_OK|MB_ICONSTOP);
+        EnableWindow(save_all_button, FALSE);
+    }
+    else
+        EnableWindow(save_all_button, TRUE);
+}
+
+INT_PTR CALLBACK system_tab_proc(HWND hsystab, UINT msg, WPARAM wparam, LPARAM lparam)
+{
+    switch(msg)
+    {
+    case WM_COMMAND:
+        switch(HIWORD(wparam))
+        {
+        case BN_CLICKED:
+            switch(wparam)
+            {
+            case IDC_WHQL_CHECKBOX:
+            {
+                update_dxdiag_info();
+                return TRUE;
+            }
+            }
+            break;
+        }
+        break;
+    }
+    return FALSE;
+}
+
+INT_PTR CALLBACK main_dlg_proc(HWND hdlg, UINT msg, WPARAM wparam, LPARAM lparam)
+{
+    switch(msg)
+    {
+    case WM_INITDIALOG:
+    {
+        main_dialog = hdlg;
+        main_tab_control = GetDlgItem(main_dialog, IDC_MAIN_TABS);
+
+        main_dialog_insert_tab(SYSTEM_TAB_INDEX, STRING_SYSTEM_TAB, IDD_SYSTEM_TAB, system_tab_proc);
+        /* TODO: remove this when at least two tabs are present, and "Next Page" button is functional */
+        EnableWindow(GetDlgItem(main_dialog, IDC_NEXT_PAGE), FALSE);
+
+        set_main_dialog_tab(SYSTEM_TAB_INDEX);
+
+        update_dxdiag_info();
+        return TRUE;
+    }
+    case WM_NOTIFY:
+        if(((NMHDR*)lparam)->code == TCN_SELCHANGE)
+            set_main_dialog_tab(SendMessageW(main_tab_control, TCM_GETCURSEL, 0, 0));
+        return TRUE;
+    case WM_CLOSE:
+        if(hdlg == main_dialog)
+            PostQuitMessage(0);
+        break;
+    case WM_COMMAND:
+        switch(HIWORD(wparam))
+        {
+        case BN_CLICKED:
+            switch(wparam)
+            {
+            case IDC_EXIT:
+                PostQuitMessage(0);
+                break;
+            case IDC_SAVE_INFO:
+                save_info_dialog(hdlg);
+                return TRUE;
+            }
+            break;
+        }
+        break;
+    }
+    return FALSE;
+}
diff --git a/programs/dxdiag/resource.h b/programs/dxdiag/resource.h
new file mode 100644
index 0000000..6ec505e
--- /dev/null
+++ b/programs/dxdiag/resource.h
@@ -0,0 +1,56 @@
+#define MAX_STRING_LEN                          1024
+
+#define STRING_DXDIAG_TOOL                      101
+#define STRING_USAGE                            102
+#define STRING_INFO_COLLECTION_FAILED           103
+#define STRING_ERROR                            104
+#define STRING_SYSTEM_TAB                       105
+
+#define IDC_STATIC                              -1
+#define IDD_MAIN                                10001
+#define IDD_SYSTEM_TAB                          10005
+
+#define IDC_NEXT_PAGE                           1001
+#define IDC_SAVE_INFO                           1002
+#define IDC_EXIT                                1003
+#define IDC_MAIN_TABS                           1005
+
+#define IDC_SYSINFO_GROUP                       2000
+
+#define IDC_SYSTEMTAB_LABEL1                    2001
+#define IDC_SYSTEMTAB_LABEL2                    2002
+
+#define IDC_SYSTEMTAB_DATETIME_LABEL            2010
+#define IDC_SYSTEMTAB_DATETIME_VALUE            2011
+
+#define IDC_SYSTEMTAB_PCNAME_LABEL              2012
+#define IDC_SYSTEMTAB_PCNAME_VALUE              2013
+
+#define IDC_SYSTEMTAB_OS_LABEL                  2014
+#define IDC_SYSTEMTAB_OS_VALUE                  2015
+
+#define IDC_SYSTEMTAB_LANG_LABEL                2016
+#define IDC_SYSTEMTAB_LANG_VALUE                2017
+
+#define IDC_SYSTEMTAB_VENDOR_LABEL              2018
+#define IDC_SYSTEMTAB_VENDOR_VALUE              2019
+
+#define IDC_SYSTEMTAB_MODEL_LABEL               2020
+#define IDC_SYSTEMTAB_MODEL_VALUE               2021
+
+#define IDC_SYSTEMTAB_BIOS_LABEL                2022
+#define IDC_SYSTEMTAB_BIOS_VALUE                2023
+
+#define IDC_SYSTEMTAB_CPU_LABEL                 2024
+#define IDC_SYSTEMTAB_CPU_VALUE                 2025
+
+#define IDC_SYSTEMTAB_RAM_LABEL                 2026
+#define IDC_SYSTEMTAB_RAM_VALUE                 2027
+
+#define IDC_SYSTEMTAB_PAGEFILE_LABEL            2028
+#define IDC_SYSTEMTAB_PAGEFILE_VALUE            2029
+
+#define IDC_SYSTEMTAB_DXVERSION_LABEL           2030
+#define IDC_SYSTEMTAB_DXVERSION_VALUE           2031
+
+#define IDC_WHQL_CHECKBOX                       2056
-- 
1.7.10.2




More information about the wine-patches mailing list