0b2bf6e5f3feda049c587b6f7c4cb9e524699e21
[reactos.git] / reactos / base / applications / devmgr / devmgr.c
1 /* Device manager
2 * (C) 2005 - Hervé Poussineau (hpoussin@reactos.org)
3 * GUI: Michael Fritscher (michael@fritscher.net)
4 *
5 */
6
7 #define INITGUID
8 #include <windows.h>
9 #include <setupapi.h>
10 #include <stdio.h>
11 #include <tchar.h>
12 #include <commctrl.h>
13 #include <windows.h>
14 #include <commctrl.h>
15 #if defined (__GNUC__)
16 #include <winioctl.h>
17 #endif
18
19 /* FIXME: should be in cfgmgr32.h */
20 typedef DWORD CONFIGRET;
21 typedef DWORD DEVINST, *PDEVINST;
22 #define CM_DRP_DEVICEDESC 0x00000001
23 #define MAX_DEVICE_ID_LEN 200
24 #define MAX_CLASS_NAME_LEN 32
25 #define CR_SUCCESS 0x00000000
26 #define CR_NO_SUCH_DEVINST 0x0000000D
27 #define CR_NO_SUCH_VALUE 0x00000025
28 #ifdef _UNICODE
29 typedef WCHAR *DEVINSTID_W;
30 CONFIGRET WINAPI CM_Get_DevNode_Registry_PropertyW(DEVINST, ULONG, PULONG, PVOID, PULONG, ULONG);
31 CONFIGRET WINAPI CM_Locate_DevNodeW(PDEVINST, DEVINSTID_W, ULONG);
32 #define CM_Get_DevNode_Registry_Property CM_Get_DevNode_Registry_PropertyW
33 #define CM_Locate_DevNode CM_Locate_DevNodeW
34 #else
35 typedef CHAR *DEVINSTID_A;
36 CONFIGRET WINAPI CM_Get_DevNode_Registry_PropertyA(DEVINST, ULONG, PULONG, PVOID, PULONG, ULONG);
37 CONFIGRET WINAPI CM_Locate_DevNodeA(PDEVINST, DEVINSTID_A, ULONG);
38 #define CM_Get_DevNode_Registry_Property CM_Get_DevNode_Registry_PropertyA
39 #define CM_Locate_DevNode CM_Locate_DevNodeA
40 #endif
41 CONFIGRET WINAPI CM_Enumerate_Classes(ULONG, LPGUID, ULONG);
42 CONFIGRET WINAPI CM_Get_Child(PDEVINST, DEVINST, ULONG);
43 CONFIGRET WINAPI CM_Get_Sibling(PDEVINST, DEVINST, ULONG);
44 /* end of cfgmgr32.h */
45
46 /**************************************************************************
47 Function Prototypes
48 **************************************************************************/
49
50 BOOL InitApplication(HINSTANCE);
51 BOOL InitInstance(HINSTANCE, int);
52 LRESULT CALLBACK MainWndProc(HWND, UINT, WPARAM, LPARAM);
53 void CreateListView(HINSTANCE, HWND);
54 void ResizeListView(HWND);
55 BOOL InitListView();
56 void InsertIntoListView(int, LPTSTR, LPTSTR);
57
58
59 LRESULT ListViewNotify(HWND, LPARAM);
60 void SwitchView(HWND, DWORD);
61 BOOL DoContextMenu(HWND, WPARAM, LPARAM);
62 void UpdateMenu(HWND, HMENU);
63 BOOL InsertListViewItems();
64 void PositionHeader();
65
66 void CreateButtons();
67 void ListByClass();
68
69 /**************************************************************************
70 Global Variables
71 **************************************************************************/
72
73 HINSTANCE g_hInst;
74 TCHAR g_szClassName[] = TEXT("VListVwClass");
75 HWND hWnd;
76 HWND hwndListView;
77 HWND hwndButtonListByClass;
78 HWND hwndButtonListByConnection;
79 HWND hwndButtonListByInterface;
80 HWND hwndButtonExit;
81 TCHAR temp [255];
82 HDC hDC;
83 TCHAR empty [255] = TEXT(" ");
84
85 void ListByClass()
86 {
87 GUID ClassGuid;
88 TCHAR ClassDescription[MAX_PATH];
89 TCHAR ClassName[MAX_CLASS_NAME_LEN];
90 TCHAR PropertyBuffer[256];
91 HKEY KeyClass;
92 HDEVINFO hDevInfo;
93 SP_DEVINFO_DATA DeviceInfoData;
94 int i = 0, j;
95 long Size;
96 long rc;
97
98 SendMessage(hwndListView, WM_SETREDRAW, FALSE, 0);
99
100 ListView_DeleteAllItems(hwndListView);
101 while (1)
102 {
103 CONFIGRET res;
104 res = CM_Enumerate_Classes(i, &ClassGuid, 0);
105 if (res == CR_NO_SUCH_VALUE)
106 break;
107
108 i++;
109 ClassName[0] = '\0';
110 if (!SetupDiClassNameFromGuid(
111 &ClassGuid,
112 ClassName,
113 sizeof(ClassName) / sizeof(ClassName[0]),
114 NULL))
115 {
116 _tprintf(_T("SetupDiClassNameFromGuid() failed with status 0x%lx\n"), GetLastError());
117 continue;
118 }
119
120 /* Get class description */
121 KeyClass = SetupDiOpenClassRegKey(
122 &ClassGuid,
123 KEY_READ);
124 if (KeyClass == INVALID_HANDLE_VALUE)
125 {
126 _tprintf(_T("SetupDiOpenClassRegKey() failed with status 0x%lx\n"), GetLastError());
127 continue;
128 }
129 Size = sizeof(ClassDescription);
130 rc = RegQueryValue(KeyClass, NULL, ClassDescription, &Size);
131 if (rc == ERROR_SUCCESS)
132 {
133 InsertIntoListView(i,ClassDescription,ClassName);
134 TextOut(hDC, 200, 40, empty, strlen(empty));
135 TextOut(hDC, 200, 40, ClassDescription, strlen(ClassDescription));
136 _tprintf(_T("%d %s (%s)\n"), i, ClassName, ClassDescription);
137 }
138 else
139 _tprintf(_T("RegQueryValue() failed with status 0x%lx\n"), rc);
140 RegCloseKey(KeyClass);
141
142 /* Enumerate devices in the class */
143 hDevInfo = SetupDiGetClassDevs(
144 &ClassGuid,
145 NULL, /* Enumerator */
146 NULL, /* hWnd parent */
147 DIGCF_PRESENT);
148 if (hDevInfo == INVALID_HANDLE_VALUE)
149 continue;
150
151 j = 0;
152 while (1)
153 {
154 DeviceInfoData.cbSize = sizeof(SP_DEVINFO_DATA);
155 if (!SetupDiEnumDeviceInfo(
156 hDevInfo,
157 j,
158 &DeviceInfoData))
159 {
160 break;
161 }
162 j++;
163 if (SetupDiGetDeviceRegistryProperty(
164 hDevInfo,
165 &DeviceInfoData,
166 SPDRP_DEVICEDESC,
167 NULL, /* Property reg data type */
168 (PBYTE)PropertyBuffer,
169 sizeof(PropertyBuffer),
170 NULL) /* Required size */)
171 {
172 _tprintf(_T("- %s\n"), PropertyBuffer);
173 InsertIntoListView(0,PropertyBuffer," ");
174 }
175 else if (SetupDiGetDeviceRegistryProperty(
176 hDevInfo,
177 &DeviceInfoData,
178 SPDRP_PHYSICAL_DEVICE_OBJECT_NAME,
179 NULL, /* Property reg data type */
180 (PBYTE)PropertyBuffer,
181 sizeof(PropertyBuffer),
182 NULL) /* Required size */)
183 {
184 _tprintf(_T("- %s\n"), PropertyBuffer);
185 InsertIntoListView(0,PropertyBuffer," ");
186 TextOut(hDC, 200, 40, empty, strlen(empty));
187 TextOut(hDC, 200, 40, PropertyBuffer, strlen(PropertyBuffer));
188 }
189 else
190 _tprintf(_T("SetupDiGetDeviceRegistryProperty() failed with status 0x%lx\n"), GetLastError());
191 }
192 SetupDiDestroyDeviceInfoList(hDevInfo);
193 }
194 SendMessage(hwndListView, WM_SETREDRAW, TRUE, 0);
195 }
196
197 CONFIGRET GetDeviceName(DEVINST DevInst, LPTSTR Buffer, DWORD BufferLength)
198 {
199 ULONG BufferSize = BufferLength * sizeof(TCHAR);
200 CONFIGRET cr;
201 cr = CM_Get_DevNode_Registry_Property(DevInst, CM_DRP_DEVICEDESC, NULL, Buffer, &BufferSize, 0);
202 if (cr != CR_SUCCESS)
203 {
204 _tprintf(_T("CM_Get_DevNode_Registry_Property() failed, cr= 0x%lx\n"), cr);
205 }
206 return cr;
207 }
208
209 CONFIGRET ListSubNodes(DEVINST parent, DWORD Level)
210 {
211 CONFIGRET cr;
212 DEVINST child;
213
214 cr = CM_Get_Child(&child, parent, 0);
215 if (cr == CR_NO_SUCH_DEVINST)
216 return CR_SUCCESS;
217 else if (cr != CR_SUCCESS)
218 {
219 _tprintf(_T("CM_Get_Child() failed, cr= 0x%lx\n"), cr);
220 return cr;
221 }
222
223 do
224 {
225 #define DISPLAY_LENGTH (MAX_PATH + MAX_DEVICE_ID_LEN)
226 DWORD DisplayLength = DISPLAY_LENGTH;
227 TCHAR DisplayName[DISPLAY_LENGTH];
228 ULONG i = Level;
229 TCHAR LevelSpaces [ 255 ];
230 cr = GetDeviceName(child, DisplayName, DisplayLength);
231 LevelSpaces[0] = '\0';
232 while (i-- != 0)
233 {
234 _tprintf(_T(" "));
235 sprintf(LevelSpaces,"%s%s",LevelSpaces," ");
236 }
237 if (cr == CR_SUCCESS)
238 {
239 _tprintf(_T("%s\n"), DisplayName);
240 sprintf(temp,"%s%s",LevelSpaces,DisplayName);
241 InsertIntoListView(0,temp," ");
242 TextOut(hDC, 200, 40, empty, strlen(empty));
243 TextOut(hDC, 200, 40, DisplayName, strlen(DisplayName));
244 }
245 else
246 {
247 _tprintf(_T("(unknown device)\n"));
248 sprintf(temp,"%s%s",LevelSpaces,"(unknown device)");
249 InsertIntoListView(0,temp," ");
250 TextOut(hDC, 200, 40, empty, strlen(empty));
251 TextOut(hDC, 200, 40, "(unknown device)", strlen("(unknown device)"));
252 }
253 cr = ListSubNodes(child, Level + 1);
254 if (cr != CR_SUCCESS)
255 return cr;
256 cr = CM_Get_Sibling(&child, child, 0);
257 if (cr != CR_SUCCESS && cr != CR_NO_SUCH_DEVINST)
258 {
259 _tprintf(_T("CM_Get_Sibling() failed, cr= 0x%lx\n"), cr);
260 return cr;
261 }
262 } while (cr == CR_SUCCESS);
263 return CR_SUCCESS;
264 }
265
266 int ListByConnection()
267 {
268 CONFIGRET cr;
269 DEVINST root;
270 ListView_DeleteAllItems(hwndListView);
271
272 cr = CM_Locate_DevNode(&root, NULL, 0);
273
274 if (cr != CR_SUCCESS)
275 {
276 _tprintf(_T("CM_Locate_DevNode() failed, cr= 0x%lx\n"), cr);
277 return 1;
278 }
279 SendMessage(hwndListView, WM_SETREDRAW, FALSE, 0);
280 cr = ListSubNodes(root, 0);
281 SendMessage(hwndListView, WM_SETREDRAW, TRUE, 0);
282 if (cr != CR_SUCCESS)
283 return 2;
284 return 0;
285 }
286
287 int ListByInterface(const GUID* guid)
288 {
289 HDEVINFO hDevInfo;
290 CHAR Buffer[sizeof(SP_DEVICE_INTERFACE_DETAIL_DATA) + 0x100];
291 PSP_DEVICE_INTERFACE_DETAIL_DATA DeviceInterfaceDetailData;
292 DWORD i;
293 SP_DEVICE_INTERFACE_DATA DeviceInterfaceData;
294
295 ListView_DeleteAllItems(hwndListView);
296
297 DeviceInterfaceDetailData = (PSP_DEVICE_INTERFACE_DETAIL_DATA)Buffer;
298 DeviceInterfaceDetailData->cbSize = sizeof(SP_DEVICE_INTERFACE_DETAIL_DATA);
299
300 hDevInfo = SetupDiGetClassDevs(
301 guid,
302 NULL, /* Enumerator */
303 NULL, /* hwndParent */
304 DIGCF_DEVICEINTERFACE);
305 if (hDevInfo == INVALID_HANDLE_VALUE)
306 {
307 printf("SetupDiGetClassDevs() failed with status 0x%lx\n", GetLastError());
308 return 1;
309 }
310
311 i = 0;
312 DeviceInterfaceData.cbSize = sizeof(SP_DEVICE_INTERFACE_DATA);
313 SendMessage(hwndListView, WM_SETREDRAW, FALSE, 0);
314 while (TRUE)
315 {
316 if (!SetupDiEnumDeviceInterfaces(
317 hDevInfo,
318 NULL,
319 guid,
320 i,
321 &DeviceInterfaceData))
322 {
323 if (GetLastError() != ERROR_NO_MORE_ITEMS)
324 printf("SetupDiEnumDeviceInterfaces() failed with status 0x%lx\n", GetLastError());
325 break;
326 }
327 i++;
328 if (SetupDiGetDeviceInterfaceDetail(hDevInfo, &DeviceInterfaceData, DeviceInterfaceDetailData, sizeof(Buffer), NULL, NULL))
329 {
330 _tprintf(_T("- device %-2ld: %s\n"), i, DeviceInterfaceDetailData->DevicePath);
331 TextOut(hDC, 200, 40, empty, strlen(empty));
332 TextOut(hDC, 200, 40, DeviceInterfaceDetailData->DevicePath, strlen(DeviceInterfaceDetailData->DevicePath));
333 InsertIntoListView(i,DeviceInterfaceDetailData->DevicePath," ");
334 }
335 else
336 {
337 _tprintf(_T("- device %ld\n"), i);
338 InsertIntoListView(i," "," ");
339 }
340
341 }
342 SendMessage(hwndListView, WM_SETREDRAW, TRUE, 0);
343 SetupDiDestroyDeviceInfoList(hDevInfo);
344 return 0;
345 }
346
347 /*int main(void)
348 {
349 ListByClass();
350 ListByInterface(&GUID_DEVINTERFACE_SERENUM_BUS_ENUMERATOR);
351 ListByConnection();
352 return 0;
353 }*/
354
355
356
357 //GUI
358 int WINAPI WinMain( HINSTANCE hInstance,
359 HINSTANCE hPrevInstance,
360 LPSTR lpCmdLine,
361 int nCmdShow)
362 {
363 MSG msg;
364
365 g_hInst = hInstance;
366
367 if(!hPrevInstance)
368 if(!InitApplication(hInstance))
369 return FALSE;
370
371 //required to use the common controls
372 InitCommonControls();
373
374 /* Perform initializations that apply to a specific instance */
375
376 if (!InitInstance(hInstance, nCmdShow))
377 return FALSE;
378
379 /* Acquire and dispatch messages until a WM_QUIT uMessage is received. */
380
381 while(GetMessage( &msg, NULL, 0x00, 0x00))
382 {
383 TranslateMessage(&msg);
384 DispatchMessage(&msg);
385 }
386
387 return (int)msg.wParam;
388 }
389
390 BOOL InitApplication(HINSTANCE hInstance)
391 {
392 WNDCLASSEX wcex;
393 ATOM aReturn;
394
395 wcex.cbSize = sizeof(WNDCLASSEX);
396 wcex.style = 0;
397 wcex.lpfnWndProc = (WNDPROC)MainWndProc;
398 wcex.cbClsExtra = 0;
399 wcex.cbWndExtra = 0;
400 wcex.hInstance = hInstance;
401 wcex.hCursor = LoadCursor(NULL, IDC_ARROW);
402 wcex.hbrBackground = (HBRUSH)(COLOR_WINDOW );
403 wcex.lpszMenuName = 0;
404 wcex.lpszClassName = g_szClassName;
405 wcex.hIcon = 0;
406 wcex.hIconSm = 0;
407
408 aReturn = RegisterClassEx(&wcex);
409
410 if(0 == aReturn)
411 {
412 WNDCLASS wc;
413
414 wc.style = 0;
415 wc.lpfnWndProc = (WNDPROC)MainWndProc;
416 wc.cbClsExtra = 0;
417 wc.cbWndExtra = 0;
418 wc.hInstance = hInstance;
419 wc.hIcon = 0;
420 wc.hCursor = 0;
421 wc.hbrBackground = (HBRUSH)(COLOR_WINDOW);
422 wc.lpszMenuName = 0;
423 wc.lpszClassName = g_szClassName;
424
425 aReturn = RegisterClass(&wc);
426 }
427
428 return aReturn;
429 }
430
431 BOOL InitInstance( HINSTANCE hInstance,
432 int nCmdShow)
433 {
434 HWND hWnd;
435 TCHAR szTitle[MAX_PATH] = TEXT("Device viewer");
436
437 g_hInst = hInstance;
438
439 /* Create a main window for this application instance. */
440 hWnd = CreateWindowEx( 0,
441 g_szClassName,
442 szTitle,
443 WS_OVERLAPPEDWINDOW,
444 CW_USEDEFAULT,
445 CW_USEDEFAULT,
446 CW_USEDEFAULT,
447 CW_USEDEFAULT,
448 NULL,
449 NULL,
450 hInstance,
451 NULL);
452
453 /* If window could not be created, return "failure" */
454
455 if (!hWnd)
456 return FALSE;
457
458 /* Make the window visible; update its client area; and return "success" */
459
460 ShowWindow(hWnd, nCmdShow);
461 UpdateWindow(hWnd);
462 hDC = GetDC(hWnd);
463 return TRUE;
464
465 }
466
467 LRESULT CALLBACK MainWndProc( HWND hWnd,
468 UINT uMessage,
469 WPARAM wParam,
470 LPARAM lParam)
471 {
472
473
474 switch (uMessage)
475 {
476 case WM_CREATE:
477 // create the TreeView control
478 CreateListView(g_hInst, hWnd);
479
480 //initialize the TreeView control
481 InitListView();
482
483 CreateButtons(g_hInst, hWnd);
484 TextOut(hDC, 200, 40, empty, strlen(empty));
485 break;
486
487
488 case WM_SIZE:
489 ResizeListView(hWnd);
490 break;
491 case WM_DESTROY:
492 ReleaseDC(hWnd, hDC);
493 PostQuitMessage(0);
494 break;
495 case WM_COMMAND:
496 if (HIWORD(wParam) == BN_CLICKED &&
497 (HWND) lParam == hwndButtonListByClass)
498 {
499 ListByClass();
500 }
501 if (HIWORD(wParam) == BN_CLICKED &&
502 (HWND) lParam == hwndButtonListByConnection)
503 {
504 ListByConnection();
505 }
506 if (HIWORD(wParam) == BN_CLICKED &&
507 (HWND) lParam == hwndButtonListByInterface)
508 {
509 ListByInterface(&GUID_DEVINTERFACE_SERENUM_BUS_ENUMERATOR);
510 }
511 if (HIWORD(wParam) == BN_CLICKED &&
512 (HWND) lParam == hwndButtonExit)
513 {
514 /* Close the window. */
515 DestroyWindow (hWnd);
516 } return 0;
517 break;
518 default:
519 break;
520 }
521 return DefWindowProc(hWnd, uMessage, wParam, lParam);
522 }
523
524 void CreateListView(HINSTANCE hInstance, HWND hwndParent)
525 {
526 DWORD dwStyle;
527
528 dwStyle = WS_TABSTOP |
529 WS_CHILD |
530 WS_BORDER |
531 WS_VISIBLE |
532 LVS_AUTOARRANGE |
533 LVS_REPORT ;//|
534 //LVS_OWNERDATA;
535
536 hwndListView = CreateWindowEx( WS_EX_CLIENTEDGE, // ex style
537 WC_LISTVIEW, // class name - defined in commctrl.h
538 TEXT(""), // dummy text
539 dwStyle, // style
540 0, // x position
541 0, // y position
542 0, // width
543 0, // height
544 hwndParent, // parent
545 0,//(HMENU)ID_LISTVIEW, // ID
546 g_hInst, // instance
547 NULL); // no extra data
548
549
550 ResizeListView(hwndParent);
551 }
552
553 void ResizeListView(HWND hwndParent)
554 {
555 RECT rc;
556
557 GetClientRect(hwndParent, &rc);
558
559 MoveWindow( hwndListView,
560 rc.left,
561 rc.top+60,
562 rc.right - rc.left,
563 rc.bottom - rc.top-60,
564 TRUE);
565 }
566
567 void PositionHeader()
568 {
569 HWND hwndHeader = GetWindow(hwndListView, GW_CHILD);
570 DWORD dwStyle = GetWindowLong(hwndListView, GWL_STYLE);
571
572 /*To ensure that the first item will be visible, create the control without
573 the LVS_NOSCROLL style and then add it here*/
574 dwStyle |= LVS_NOSCROLL;
575 SetWindowLong(hwndListView, GWL_STYLE, dwStyle);
576
577 //only do this if we are in report view and were able to get the header hWnd
578 if(((dwStyle & LVS_TYPEMASK) == LVS_REPORT) && hwndHeader)
579 {
580 RECT rc;
581 HD_LAYOUT hdLayout;
582 WINDOWPOS wpos;
583
584 GetClientRect(hwndListView, &rc);
585 hdLayout.prc = &rc;
586 hdLayout.pwpos = &wpos;
587
588 Header_Layout(hwndHeader, &hdLayout);
589
590 SetWindowPos( hwndHeader,
591 wpos.hwndInsertAfter,
592 wpos.x,
593 wpos.y,
594 wpos.cx,
595 wpos.cy,
596 wpos.flags | SWP_SHOWWINDOW);
597
598 ListView_EnsureVisible(hwndListView, 0, FALSE);
599 }
600 }
601
602 BOOL InitListView()
603 {
604 LV_COLUMN lvColumn;
605 int i;
606 TCHAR szString[3][20] = {TEXT("#"), TEXT("Name"), TEXT("Intern name")};
607
608 //empty the list
609 ListView_DeleteAllItems(hwndListView);
610
611 //initialize the columns
612 lvColumn.mask = LVCF_FMT | LVCF_WIDTH | LVCF_TEXT | LVCF_SUBITEM;
613 lvColumn.fmt = LVCFMT_LEFT;
614 i=0;
615 lvColumn.cx = 20;
616 lvColumn.pszText = szString[i];
617 ListView_InsertColumn(hwndListView, i, &lvColumn);
618 i=1;
619 lvColumn.cx = 400;
620 lvColumn.pszText = szString[i];
621 ListView_InsertColumn(hwndListView, i, &lvColumn);
622 i=2;
623 lvColumn.cx = 150;
624 lvColumn.pszText = szString[i];
625 ListView_InsertColumn(hwndListView, i, &lvColumn);
626
627
628 return TRUE;
629 }
630
631 typedef struct tagLINE_INFO
632 {
633 DWORD dwValType;
634 LPTSTR name;
635 void* val;
636 size_t val_len;
637 } LINE_INFO, *PLINE_INFO;
638
639 void InsertIntoListView(int typ, LPTSTR name, LPTSTR intern_name)
640 {
641 //MessageBox(hWnd, "You just pressed Ctrl+a", "Hotkey", MB_OK | MB_ICONINFORMATION);
642 TCHAR temp[ 255 ];
643 //LINE_INFO* linfo;
644 LVITEM item;
645 int index;
646 //linfo->name = Name;
647 item.mask = LVIF_TEXT;
648 item.iItem = 9999;
649 item.iSubItem = 0;
650 item.state = 0;
651 //item.statemask = 0;
652 item.pszText=malloc(10);
653 if (typ>=1)
654 {
655 sprintf(temp,"%i",typ);
656 item.pszText = temp;
657 }
658 else
659 item.pszText = "";
660 item.cchTextMax = _tcslen(item.pszText);
661 if (item.cchTextMax == 0)
662 item.pszText = LPSTR_TEXTCALLBACK;
663 item.iImage = 0;
664 //item.iIdent = 0;
665 //item.iGroupId = 0;
666 //item.cColumns = 0 ;
667 //item.puColumns = 0;
668 //item.lParam = (LPARAM)linfo;
669 index = ListView_InsertItem(hwndListView, &item);
670 ListView_SetItemText(hwndListView, index, 1, name);
671 ListView_SetItemText(hwndListView, index, 2, intern_name);
672 }
673
674
675
676 void CreateButtons(HINSTANCE hInstance, HWND hwndParent)
677 {
678
679 hwndButtonListByClass = CreateWindowEx (
680 0,
681 "button", /* Builtin button class */
682 "List by Class",
683 WS_CHILD | WS_VISIBLE | BS_PUSHBUTTON,
684 0, 0, 190, 30,
685 hwndParent, /* Parent is this window. */
686 0, /* Control ID: 1 */
687 g_hInst,
688 NULL
689 );
690 hwndButtonListByConnection = CreateWindowEx (
691 0,
692 "button", /* Builtin button class */
693 "List by Connection",
694 WS_CHILD | WS_VISIBLE | BS_PUSHBUTTON,
695 200, 0, 190, 30,
696 hwndParent, /* Parent is this window. */
697 0, /* Control ID: 1 */
698 g_hInst,
699 NULL
700 );
701 hwndButtonListByInterface = CreateWindowEx (
702 0,
703 "button", /* Builtin button class */
704 "List by Interface",
705 WS_CHILD | WS_VISIBLE | BS_PUSHBUTTON,
706 400, 0, 190, 30,
707 hwndParent, /* Parent is this window. */
708 0, /* Control ID: 1 */
709 g_hInst,
710 NULL
711 );
712 hwndButtonExit = CreateWindowEx (
713 0,
714 "button", /* Builtin button class */
715 "Exit",
716 WS_CHILD | WS_VISIBLE | BS_PUSHBUTTON,
717 0, 30, 190, 30,
718 hwndParent, /* Parent is this window. */
719 0, /* Control ID: 1 */
720 g_hInst,
721 NULL
722 );
723 }