[Win32k]
[reactos.git] / base / applications / dxdiag / dxdiag.c
1 /*
2 * PROJECT: ReactX Diagnosis Application
3 * LICENSE: LGPL - See COPYING in the top level directory
4 * FILE: base/applications/dxdiag/dxdiag.c
5 * PURPOSE: ReactX diagnosis application entry
6 * COPYRIGHT: Copyright 2008 Johannes Anderwald
7 *
8 */
9
10 #include "precomp.h"
11
12 /* globals */
13 HINSTANCE hInst = 0;
14 HWND hTabCtrlWnd;
15
16 ////////////////////////////////////////////////////////////////////////////////
17 // Taken from WinSpy++ 1.7
18 // http://www.catch22.net/software/winspy
19 // Copyright (c) 2002 by J Brown
20 //
21
22 //
23 // Copied from uxtheme.h
24 // If you have this new header, then delete these and
25 // #include <uxtheme.h> instead!
26 //
27 #define ETDT_DISABLE 0x00000001
28 #define ETDT_ENABLE 0x00000002
29 #define ETDT_USETABTEXTURE 0x00000004
30 #define ETDT_ENABLETAB (ETDT_ENABLE | ETDT_USETABTEXTURE)
31
32 //
33 typedef HRESULT (WINAPI * ETDTProc) (HWND, DWORD);
34
35 //
36 // Try to call EnableThemeDialogTexture, if uxtheme.dll is present
37 //
38 BOOL EnableDialogTheme(HWND hwnd)
39 {
40 HMODULE hUXTheme;
41 ETDTProc fnEnableThemeDialogTexture;
42
43 hUXTheme = LoadLibraryA("uxtheme.dll");
44
45 if(hUXTheme)
46 {
47 fnEnableThemeDialogTexture =
48 (ETDTProc)GetProcAddress(hUXTheme, "EnableThemeDialogTexture");
49
50 if(fnEnableThemeDialogTexture)
51 {
52 fnEnableThemeDialogTexture(hwnd, ETDT_ENABLETAB);
53
54 FreeLibrary(hUXTheme);
55 return TRUE;
56 }
57 else
58 {
59 // Failed to locate API!
60 FreeLibrary(hUXTheme);
61 return FALSE;
62 }
63 }
64 else
65 {
66 // Not running under XP? Just fail gracefully
67 return FALSE;
68 }
69 }
70
71 //---------------------------------------------------------------
72 VOID
73 DestroyTabCtrlDialogs(PDXDIAG_CONTEXT pContext)
74 {
75 UINT Index;
76
77 /* destroy default dialogs */
78 for(Index = 0; Index < sizeof(pContext->hDialogs) / sizeof(HWND); Index++)
79 {
80 if (pContext->hDialogs[Index])
81 DestroyWindow(pContext->hDialogs[Index]);
82 }
83
84 /* destroy display dialogs */
85 for(Index = 0; Index < pContext->NumDisplayAdapter; Index++)
86 {
87 if (pContext->hDisplayWnd[Index])
88 DestroyWindow(pContext->hDisplayWnd[Index]);
89 }
90
91 /* destroy audio dialogs */
92 for(Index = 0; Index < pContext->NumSoundAdapter; Index++)
93 {
94 if (pContext->hSoundWnd[Index])
95 DestroyWindow(pContext->hSoundWnd[Index]);
96 }
97
98 }
99
100 //---------------------------------------------------------------
101 VOID
102 InsertTabCtrlItem(HWND hDlgCtrl, INT Position, LPWSTR uId)
103 {
104 WCHAR szName[100];
105 TCITEMW item;
106
107 /* setup item info */
108 memset(&item, 0, sizeof(TCITEMW));
109 item.mask = TCIF_TEXT;
110
111 /* load item name */
112 if (!HIWORD(uId))
113 {
114 szName[0] = L'\0';
115 if (!LoadStringW(hInst, LOWORD(uId), szName, 100))
116 return;
117 szName[99] = L'\0';
118 item.pszText = szName;
119 }
120 else
121 {
122 item.pszText = uId;
123 }
124
125
126 SendMessageW(hDlgCtrl, TCM_INSERTITEM, Position, (LPARAM)&item);
127 }
128
129 VOID
130 TabCtrl_OnSelChange(PDXDIAG_CONTEXT pContext)
131 {
132 INT Index;
133 INT CurSel;
134
135 /* retrieve new page */
136 CurSel = TabCtrl_GetCurSel(hTabCtrlWnd);
137 if (CurSel < 0 || CurSel > pContext->NumDisplayAdapter + pContext->NumSoundAdapter + 5)
138 return;
139
140 /* hide all windows */
141 for(Index = 0; Index < 5; Index++)
142 ShowWindow(pContext->hDialogs[Index], SW_HIDE);
143
144 for(Index = 0; Index < pContext->NumDisplayAdapter; Index++)
145 ShowWindow(pContext->hDisplayWnd[Index], SW_HIDE);
146
147 for(Index = 0; Index < pContext->NumSoundAdapter; Index++)
148 ShowWindow(pContext->hSoundWnd[Index], SW_HIDE);
149
150
151 if (CurSel == 0 || CurSel > pContext->NumDisplayAdapter + pContext->NumSoundAdapter)
152 {
153 if (CurSel)
154 CurSel -= pContext->NumDisplayAdapter + pContext->NumSoundAdapter;
155 ShowWindow(pContext->hDialogs[CurSel], SW_SHOW);
156 return;
157 }
158
159 if (CurSel -1 < pContext->NumDisplayAdapter)
160 {
161 ShowWindow(pContext->hDisplayWnd[CurSel-1], SW_SHOW);
162 return;
163 }
164
165 CurSel -= pContext->NumDisplayAdapter + 1;
166 ShowWindow(pContext->hSoundWnd[CurSel], SW_SHOW);
167 }
168
169 VOID
170 InitializeTabCtrl(HWND hwndDlg, PDXDIAG_CONTEXT pContext)
171 {
172 /* get tabctrl */
173 hTabCtrlWnd = GetDlgItem(hwndDlg, IDC_TAB_CONTROL);
174 pContext->hTabCtrl = hTabCtrlWnd;
175
176 /* create the dialogs */
177 pContext->hDialogs[0] = CreateDialogParamW(hInst, MAKEINTRESOURCEW(IDD_SYSTEM_DIALOG), pContext->hMainDialog, SystemPageWndProc, (LPARAM)pContext); EnableDialogTheme(pContext->hDialogs[0]);
178 pContext->hDialogs[1] = CreateDialogParamW(hInst, MAKEINTRESOURCEW(IDD_MUSIC_DIALOG), pContext->hMainDialog, MusicPageWndProc, (LPARAM)pContext); EnableDialogTheme(pContext->hDialogs[1]);
179 pContext->hDialogs[2] = CreateDialogParamW(hInst, MAKEINTRESOURCEW(IDD_INPUT_DIALOG), pContext->hMainDialog, InputPageWndProc, (LPARAM)pContext); EnableDialogTheme(pContext->hDialogs[2]);
180 pContext->hDialogs[3] = CreateDialogParamW(hInst, MAKEINTRESOURCEW(IDD_NETWORK_DIALOG), pContext->hMainDialog, NetworkPageWndProc, (LPARAM)pContext); EnableDialogTheme(pContext->hDialogs[3]);
181 pContext->hDialogs[4] = CreateDialogParamW(hInst, MAKEINTRESOURCEW(IDD_HELP_DIALOG), pContext->hMainDialog, HelpPageWndProc, (LPARAM)pContext); EnableDialogTheme(pContext->hDialogs[4]);
182
183 /* insert tab ctrl items */
184 InsertTabCtrlItem(hTabCtrlWnd, 0, MAKEINTRESOURCEW(IDS_SYSTEM_DIALOG));
185 InitializeDisplayAdapters(pContext);
186 InitializeDirectSoundPage(pContext);
187 InsertTabCtrlItem(hTabCtrlWnd, pContext->NumDisplayAdapter + pContext->NumSoundAdapter + 1, MAKEINTRESOURCEW(IDS_MUSIC_DIALOG));
188 InsertTabCtrlItem(hTabCtrlWnd, pContext->NumDisplayAdapter + pContext->NumSoundAdapter + 2, MAKEINTRESOURCEW(IDS_INPUT_DIALOG));
189 InsertTabCtrlItem(hTabCtrlWnd, pContext->NumDisplayAdapter + pContext->NumSoundAdapter + 3, MAKEINTRESOURCEW(IDS_NETWORK_DIALOG));
190 InsertTabCtrlItem(hTabCtrlWnd, pContext->NumDisplayAdapter + pContext->NumSoundAdapter + 4, MAKEINTRESOURCEW(IDS_HELP_DIALOG));
191 TabCtrl_OnSelChange(pContext);
192 }
193
194 VOID
195 InitializeDxDiagDialog(HWND hwndDlg)
196 {
197 PDXDIAG_CONTEXT pContext;
198 HICON hIcon;
199
200 pContext = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(DXDIAG_CONTEXT));
201 if (!pContext)
202 return;
203
204 /* store window handle */
205 pContext->hMainDialog = hwndDlg;
206
207 /* store the context */
208 SetWindowLongPtr(hwndDlg, DWLP_USER, (LONG_PTR)pContext);
209
210 /* initialize the tab ctrl */
211 InitializeTabCtrl(hwndDlg, pContext);
212
213 /* load application icon */
214 hIcon = LoadImageW(hInst, MAKEINTRESOURCEW(IDI_APPICON), IMAGE_ICON, 16, 16, 0);
215 if (!hIcon)
216 return;
217 /* display icon */
218 SendMessage(hwndDlg, WM_SETICON, ICON_SMALL, (LPARAM)hIcon);
219 }
220
221
222 INT_PTR CALLBACK
223 DxDiagWndProc(HWND hwndDlg, UINT message, WPARAM wParam, LPARAM lParam)
224 {
225 LPNMHDR pnmh;
226 PDXDIAG_CONTEXT pContext;
227
228 pContext = (PDXDIAG_CONTEXT)GetWindowLongPtr(hwndDlg, DWLP_USER);
229
230 switch (message)
231 {
232 case WM_INITDIALOG:
233 InitializeDxDiagDialog(hwndDlg);
234 return TRUE;
235 case WM_COMMAND:
236 if (LOWORD(wParam) == IDC_BUTTON_SAVE_INFO)
237 {
238 //TODO
239 /* handle save information */
240 return TRUE;
241 }
242
243 if (LOWORD(wParam) == IDC_BUTTON_NEXT)
244 {
245 INT CurSel;
246
247 /* retrieve current page */
248 CurSel = TabCtrl_GetCurSel(hTabCtrlWnd);
249 CurSel++;
250
251 /* enable/disable next button */
252 EnableWindow(GetDlgItem(hwndDlg, IDC_BUTTON_NEXT),
253 (CurSel != TabCtrl_GetItemCount(hTabCtrlWnd) - 1));
254
255 /* switch to next tab */
256 SendMessageW(hTabCtrlWnd, TCM_SETCURSEL, CurSel, 0L);
257
258 /* show next page */
259 TabCtrl_OnSelChange(pContext);
260 return TRUE;
261 }
262
263 if (LOWORD(wParam) == IDC_BUTTON_HELP)
264 {
265 //TODO
266 /* handle help button */
267 return TRUE;
268 }
269
270 if (LOWORD(wParam) == IDCANCEL || LOWORD(wParam) == IDC_BUTTON_EXIT) {
271 EndDialog(hwndDlg, LOWORD(wParam));
272 return TRUE;
273 }
274 break;
275
276 case WM_NOTIFY:
277 pnmh = (LPNMHDR)lParam;
278 if ((pnmh->hwndFrom == hTabCtrlWnd) && (pnmh->idFrom == IDC_TAB_CONTROL) && (pnmh->code == TCN_SELCHANGE))
279 {
280 INT CurSel = TabCtrl_GetCurSel(hTabCtrlWnd);
281
282 /* enable/disable next button */
283 EnableWindow(GetDlgItem(hwndDlg, IDC_BUTTON_NEXT),
284 (CurSel != TabCtrl_GetItemCount(hTabCtrlWnd) - 1));
285
286 TabCtrl_OnSelChange(pContext);
287 }
288 break;
289 case WM_DESTROY:
290 DestroyTabCtrlDialogs(pContext);
291 return DefWindowProc(hwndDlg, message, wParam, lParam);
292 }
293 return 0;
294 }
295
296 int APIENTRY wWinMain(HINSTANCE hInstance,
297 HINSTANCE hPrevInstance,
298 LPWSTR lpCmdLine,
299 int nCmdShow)
300 {
301
302 INITCOMMONCONTROLSEX InitControls;
303
304 UNREFERENCED_PARAMETER(hPrevInstance);
305 UNREFERENCED_PARAMETER(lpCmdLine);
306 UNREFERENCED_PARAMETER(nCmdShow);
307
308 InitControls.dwSize = sizeof(INITCOMMONCONTROLSEX);
309 InitControls.dwICC = ICC_TAB_CLASSES | ICC_LISTVIEW_CLASSES | ICC_STANDARD_CLASSES | ICC_TREEVIEW_CLASSES;
310 InitCommonControlsEx(&InitControls);
311
312 hInst = hInstance;
313
314 DialogBox(hInst, MAKEINTRESOURCE(IDD_MAIN_DIALOG), NULL, DxDiagWndProc);
315
316 return 0;
317 }