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