Click here to Skip to main content
15,895,746 members
Articles / Desktop Programming / WTL

Device Information

Rate me:
Please Sign up or sign in to vote.
4.91/5 (11 votes)
13 Dec 2008CPOL6 min read 114.3K   12.9K   69  
Use two C++ classes which wrap various setup API calls to obtain, filter and display device names and information
// MainDlg.h : interface of the CMainDlg class
//
/////////////////////////////////////////////////////////////////////////////
#pragma once

#include <setupapi.h>
#pragma comment(lib, "setupapi.lib")
#include <devguid.h>					// GUID_DEVCLASS_PORTS etc
#include "..\DeviceImages.h"
#include "..\DeviceInfo.h"

// SetupDiGetClassImageList requires #include <setupapi.h> and to link to setupapi.lib

class CMainDlg : public CDialogImpl<CMainDlg>, public CUpdateUI<CMainDlg>,
		public CMessageFilter, public CIdleHandler, public CDialogResize<CMainDlg>
{
public:
	enum { IDD = IDD_MAINDLG };

	virtual BOOL PreTranslateMessage(MSG* pMsg)
	{
		return CWindow::IsDialogMessage(pMsg);
	}

	virtual BOOL OnIdle()
	{
		return FALSE;
	}

	CDeviceImageList m_DevImageList;
	CListViewCtrl m_wndListView;
	HICON m_hIcon;
	HICON m_hIconSmall;

	BEGIN_UPDATE_UI_MAP(CMainDlg)
	END_UPDATE_UI_MAP()

	BEGIN_MSG_MAP(CMainDlg)
		MESSAGE_HANDLER(WM_INITDIALOG, OnInitDialog)
		MESSAGE_HANDLER(WM_DESTROY, OnDestroy)
		COMMAND_ID_HANDLER(ID_APP_ABOUT, OnAppAbout)
		COMMAND_ID_HANDLER(IDOK, OnOK)
		COMMAND_ID_HANDLER(IDCANCEL, OnCancel)
		CHAIN_MSG_MAP(CDialogResize<CMainDlg>)				// Pass size messages to CDialogResize
	END_MSG_MAP()

    BEGIN_DLGRESIZE_MAP(CMainDlg)
		DLGRESIZE_CONTROL(IDC_LIST1, DLSZ_SIZE_X | DLSZ_SIZE_Y)
		DLGRESIZE_CONTROL(IDOK, DLSZ_MOVE_X)
        DLGRESIZE_CONTROL(IDCANCEL, DLSZ_MOVE_X)
        DLGRESIZE_CONTROL(ID_APP_ABOUT, DLSZ_MOVE_X)
    END_DLGRESIZE_MAP()

	LRESULT OnInitDialog(UINT /*uMsg*/, WPARAM /*wParam*/, LPARAM /*lParam*/, BOOL& /*bHandled*/)
	{
		// center the dialog on the screen
		CenterWindow();

		// Initialize the CDialogResize code - especially the WS_THICKFRAME which is needed.
        DlgResize_Init(true, true, WS_THICKFRAME | WS_CLIPCHILDREN);

		// set icons
		m_hIcon = (HICON)::LoadImage(_Module.GetResourceInstance(), MAKEINTRESOURCE(IDR_MAINFRAME), 
			IMAGE_ICON, ::GetSystemMetrics(SM_CXICON), ::GetSystemMetrics(SM_CYICON), LR_DEFAULTCOLOR);
		SetIcon(m_hIcon, TRUE);
		m_hIconSmall = (HICON)::LoadImage(_Module.GetResourceInstance(), MAKEINTRESOURCE(IDR_MAINFRAME), 
			IMAGE_ICON, ::GetSystemMetrics(SM_CXSMICON), ::GetSystemMetrics(SM_CYSMICON), LR_DEFAULTCOLOR);
		SetIcon(m_hIconSmall, FALSE);

		// register object for message filtering and idle updates
		CMessageLoop* pLoop = _Module.GetMessageLoop();
		ATLASSERT(pLoop != NULL);
		pLoop->AddMessageFilter(this);
		pLoop->AddIdleHandler(this);

		UIAddChildWindowContainer(m_hWnd);

		// A listbox with one column (must be in report mode)
		m_wndListView.Attach(GetDlgItem(IDC_LIST1));
		m_wndListView.InsertColumn(0, _T("Name"), LVCFMT_LEFT, 200, 0);
		m_wndListView.InsertColumn(1, _T("Friendly-Name"), LVCFMT_LEFT, 200, 0);
		m_wndListView.InsertColumn(2, _T("Driver"), LVCFMT_LEFT, 200, 0);
		m_wndListView.InsertColumn(3, _T("Mfg"), LVCFMT_LEFT, 200, 0);
		m_wndListView.InsertColumn(4, _T("Physical Device"), LVCFMT_LEFT, 200, 0);
		m_wndListView.SetImageList(m_DevImageList, 1);

		CDevInfo cDevInfo(m_hWnd);
		
		int a = 0;
		while(cDevInfo.EnumDeviceInfo())
		{
			wchar_t  szBuf[MAX_PATH] = {0};
			if(cDevInfo.GetDeviceRegistryProperty(SPDRP_CLASS, (PBYTE)szBuf))
			{
				wchar_t  szFriendlyName[MAX_PATH] = {0};
				cDevInfo.GetDeviceRegistryProperty(SPDRP_FRIENDLYNAME, (PBYTE)szFriendlyName);

				wchar_t  szDriver[MAX_PATH] = {0};
				cDevInfo.GetDeviceRegistryProperty(SPDRP_DRIVER, (PBYTE)szDriver);

				wchar_t  szMfg[MAX_PATH] = {0};
				cDevInfo.GetDeviceRegistryProperty(SPDRP_MFG, (PBYTE)szMfg);

				wchar_t  szPhysical[MAX_PATH] = {0};
				cDevInfo.GetDeviceRegistryProperty(SPDRP_PHYSICAL_DEVICE_OBJECT_NAME, (PBYTE)szPhysical);

				int ImageIndex = 0;
				if(cDevInfo.GetClassImageIndex(m_DevImageList, &ImageIndex))
				{
					wchar_t  szDesc[MAX_PATH] = {0};
					if(cDevInfo.GetClassDescription(szDesc))
					{
						ATLTRACE(szDesc);
						ATLTRACE(_T("\n"));
					}
					m_wndListView.InsertItem(a,szDesc,ImageIndex);
					m_wndListView.SetItemText(a,1,szFriendlyName);
					m_wndListView.SetItemText(a,2,szDriver);
					m_wndListView.SetItemText(a,3,szMfg);
					m_wndListView.SetItemText(a,4,szPhysical);
				}
			}
		}
		return TRUE;
	}

	LRESULT OnDestroy(UINT /*uMsg*/, WPARAM /*wParam*/, LPARAM /*lParam*/, BOOL& /*bHandled*/)
	{
		// Unregister message filtering and idle updates
		CMessageLoop* pLoop = _Module.GetMessageLoop();
		ATLASSERT(pLoop != NULL);
		pLoop->RemoveMessageFilter(this);
		pLoop->RemoveIdleHandler(this);

		// Free icon resources
		DestroyIcon(m_hIcon);
		DestroyIcon(m_hIconSmall);

		return 0;
	}

	LRESULT OnAppAbout(WORD /*wNotifyCode*/, WORD /*wID*/, HWND /*hWndCtl*/, BOOL& /*bHandled*/)
	{
		CAboutDlg dlg;
		dlg.DoModal();
		return 0;
	}

	LRESULT OnOK(WORD /*wNotifyCode*/, WORD wID, HWND /*hWndCtl*/, BOOL& /*bHandled*/)
	{
		CloseDialog(wID);
		return 0;
	}

	LRESULT OnCancel(WORD /*wNotifyCode*/, WORD wID, HWND /*hWndCtl*/, BOOL& /*bHandled*/)
	{
		CloseDialog(wID);
		return 0;
	}

	void CloseDialog(int nVal)
	{
		DestroyWindow();
		::PostQuitMessage(nVal);
	}
};

By viewing downloads associated with this article you agree to the Terms of Service and the article's licence.

If a file you wish to view isn't highlighted, and is a text file (not binary), please let us know and we'll add colourisation support for it.

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)


Written By
Founder JGD Projects Ltd
United Kingdom United Kingdom
May 2013: Project Management distance-learning MSc completed. I looked at graphical languages in manufacturing projects. In 2011 I was modelling part and data flow through a new casting facility planned for the UK working with software from their Software Centre of Excellence. In 2012 I was project managing a part identification system to go inside the factory, mostly using data matrices: inkjetted, laser printed and dot peened.

The need to find some software design tools first led me to Object Orientated Analysis and Design (OOA and OOD) and then to the Unified Modelling Language (UML) with Rational Rose in 2002.

Having been asked to write Windows image-processing s/w for new Bacterial Colony Picking robots for use on the Human Genome Project in 2000 I turned to C++.

I then got introduced to COM by Dale Rogerson’s ‘Inside COM’. My first COM objects used MFC but I soon moved onto the Active Template Library (ATL), Windows Template Library (WTL) and Standard template Library (STL).

Whilst my software design targets have now expanded from ‘control’ into domains such as Windows, firmware and communications design, the more general Project Management route I’ve taken has brought me into areas where I can happily deal with corporate management and clients directly.

This move has, it seems, completed a circle. I’m now able to manage the technical aspects of multi-discipline projects whilst working with clients, suppliers and anyone else needed to keep a project on track and to use techniques such as value management to ensure that any code written by the team is code that the client wants and appreciates.

Along the way I’ve become a Chartered Engineer and a Member of both the IET, and the Association for Project and have just joined INCOSE UK.

Comments and Discussions