세상을 이롭게

[MFC] COMBOBOX에 존재하는 Comport 목록 띄우기(Feat.Registry) 본문

MFC

[MFC] COMBOBOX에 존재하는 Comport 목록 띄우기(Feat.Registry)

2021. 7. 30. 09:01

시리얼통신이 필요한데, 하드코딩되어있던 부분을 바꾸기위해 해보다가 포스팅합니다.

https://stackoverflow.com/questions/1388871/how-do-i-get-a-list-of-available-serial-ports-in-win32 

 

How do I get a list of available serial ports in Win32?

I have some legacy code that provides a list of the available COM ports on the PC by calling the EnumPorts() function and then filtering for the port names that start with "COM". For testing purpo...

stackoverflow.com

스택플로우에 좋은 글이 있어 적용해보려 합니다.
https://webnautes.tistory.com/654

 

MFC 사용 가능한 시리얼 포트 읽어오기

노트북에 USB TO SERIAL을 이용해서 연결된 장비의 경우 시리얼포트가 고정되어 있지 않을 경우도 있고.. 고정되더라도 COM1이 아니라 엉뚱한 숫자로 매번 접속할 때 마다 장비에서 사용하는 포트를

webnautes.tistory.com

좋은 글도 있어 참고해봅니다.

COMBOBOX를 Dialog안에 넣어줍니다.
속성에서 해당 ID 값을 바꿔줍니다.

이미 엔터를 친 상태에서 다시 눌렀다면 Resource.h에 등록이 된 상태라고 보시면 됩니다. 

일단 바꾸었습니다.

Resource.h 에 등록이 되었다는것이 무엇인지 보여드리겠습니다.
저는 클린한게 컨셉이기 때문에 Resource.h까지 수정하려합니다.(안해도 상관없다는 이야기입니다.)

같은 번호가 두개입니다. 먼저 생성된것을 지워주겠습니다.

무턱대고 지웠다가 뭔가 오류가 뜨고 오류목록에

이런 에러메시지를 받으신분~?


Key~~ 에러가 뜨신다면 Dialog에 남아있는 객체를 지우신 겁니다.
당황하지 않고 .rc 파일에 가서 확인후 지워줍니다.(혹은 Resource.h를 복구하세요)

COMBOBOX와 매칭되는 멤버 변수를 만들도록 하겠습니다.
MFC Class Wizard 를 실행 합니다. 단축키는 Cntl + Shift + x 입니다.

멤버변수 - 사용자 지정 변수 - 변수추가를 눌러줍니다
원하는 이름으로 넣고 확인
잘 들어갔으면 적용 -> 확인
cpp 파일에 멤버변수를 자동으로 연결해주는 함수가 추가되었습니다.
.h 파일에도 변수가 추가됨을 볼 수 있습니다.

즉 이 부분을 직접 써넣어 주면 MFC Class Wizard 없이도 만들 수 있다는 말입니다.
가끔 에러때문에 안되시는 분들은 이방법으로 만들어 주시면 되겠습니다.

콤보박스에 이벤트를 입혀야 겠죠. 콤보박스를 살짝 한번만 눌러줍니다. 두번 누르면 다른 이벤트를 갖게 되니까요...
우리는 DropDown이벤트를 사용하겠습니다.

속성 - 이벤트 클릭
DropDown시에 레지스트리에서 컴포트를 불러올 수 있도록 하겠습니다.
.cpp에 잘 등록된것을 볼 수 있었습니다.
.h 에도 잘 등록된 것을 볼 수 있었습니다.

ComportDlg.h 에 시리얼 포트를 가져오는 함수를 하나 선언해 주겠습니다.

리턴타입 void, 함수명 getSerialPort, 매개변수 없음.

당연히 선언을 했으면 구현을 해줘야 겠죠?

void CComportDlg::OnCbnDropdownComboComport()
{
	getSerialPort();
}

void CComportDlg::getSerialPort(){
	HKEY hKey;
	RegOpenKey(HKEY_LOCAL_MACHINE,TEXT("HARDWARE\\DEVICEMAP\\SERIALCOMM"),&hKey);

	TCHAR szData[20];
	TCHAR szName[100];
	DWORD index = 0;
	DWORD dwSize = 100;
	DWORD dwSize2 = 20;
	DWORD dwType = REG_SZ;
	m_comport.ResetContent();
	memset(szData,0x00,sizeof(szData));
	memset(szName,0x00,sizeof(szName));

	while(ERROR_SUCCESS == RegEnumValue(hKey,index,szName,&dwSize,NULL,NULL,NULL,NULL)){
		index++;
		RegQueryValueEx(hKey,szName,NULL,&dwType,(LPBYTE)szData,&dwSize2);
		m_comport.AddString(CString(szData));

		memset(szData, 0x00, sizeof(szData));
		memset(szName, 0x00, sizeof(szName));
		dwSize =100;
		dwSize2 =20;
	}
	RegCloseKey(hKey);
}

코드 복사 안되신느 분들은 아래 더보기 클릭해서 복사하시면 됩니다. 이런것에 시간낭비 하지 않기를 바라면서... . 

더보기

void CComportDlg::OnCbnDropdownComboComport()
{
getSerialPort();
}

void CComportDlg::getSerialPort(){
HKEY hKey;
RegOpenKey(HKEY_LOCAL_MACHINE,TEXT("HARDWARE\\DEVICEMAP\\SERIALCOMM"),&hKey);

TCHAR szData[20];
TCHAR szName[100];
DWORD index = 0;
DWORD dwSize = 100;
DWORD dwSize2 = 20;
DWORD dwType = REG_SZ;
m_comport.ResetContent();
memset(szData,0x00,sizeof(szData));
memset(szName,0x00,sizeof(szName));

while(ERROR_SUCCESS == RegEnumValue(hKey,index,szName,&dwSize,NULL,NULL,NULL,NULL)){
index++;
RegQueryValueEx(hKey,szName,NULL,&dwType,(LPBYTE)szData,&dwSize2);
m_comport.AddString(CString(szData));

memset(szData, 0x00, sizeof(szData));
memset(szName, 0x00, sizeof(szName));
dwSize =100;
dwSize2 =20;
}
RegCloseKey(hKey);
}

 

COM 포트가 잘 뜨고 있는 것을 확인할 수있습니다.


▷ CComboBox::AddString - 스트링을 더함.
▷ CComboBox::CComboBox - ComboBox 오브젝트를 생성(구성).
▷ CComboBox::Clear -현재 선택을 지움.
▷ CComboBox::CompareItem - 새로운 리스트 항목의 상태적 위치를 결정.
▷ CComboBox::Copy - 현재 선택을 Copy.
▷ CComboBox::Create - CComboBox를 생성.
▷ CComboBox::Cut - 제거된 텍스트를 복사.
▷ CComboBox::DeleteItem- 항목이 Combo 박스에서 제거.
▷ CComboBox::DeleteString - 스트링을 제거.
▷ CComboBox::Dir - 리스트를 더함.
▷ CComboBox::DrawItem - 양상이 변할 때 불려짐.
▷ CComboBox::FindString - 첫 번째 스트링을 찾음.
▷ CComboBox::FindStringExact - 첫 번째 리스트 박스 스트링을 찾음.
▷ CComboBox::GetCount - 항목의 수를 회복.
▷ CComboBox::GetCurSel - 현재 선택된 항목의 색인을 찾음
▷ CComboBox::GetDroppedControlRect - 스크린 좌표를 되찾음.
▷ CComboBox::GetDroppedState - 리스트 박스가 보일지를 결정.
▷ CComboBox::GetEditSel - 시작과 끝나는 문자의 위치를 얻음.
▷ CComboBox::GetExtendedUI - 디폴트, 확장 사용자 인터페이스의 결정.
▷ CComboBox::GetItemData - 항목과 관련된 비트값을 회복.
▷ CComboBox::GetItemDataPtr - 포인터로서 관련된 비트 값을 회복.
▷ CComboBox::GetItemHeight - 리스트 항목의 높이를 회복.
▷ CComboBox::GetLBText - 리스트 박스로 부터 스트링을 얻음.
▷ CComboBox::GetLBTextLen - 스트링의 길이를 지정.
▷ CComboBox::InsertString - 스트링의 삽입.
▷ CComboBox::LimitText - 텍스트의 길이를 제한.
▷ CComboBox::MeasureItem - Combo 박스 치수를 결정하기 위해 불려짐.
▷ CComboBox::Paste - 현재 커서 위치에서 편집 제어로 삽입.
▷ CComboBox::ResetContent - 모든 항목의 제거.
▷ CComboBox::SelectString - 스트링을 선택, 복사.
▷ CComboBox::SetCurSel - 스트링을 선택.
▷ CComboBox::SetEditSel - 편집 제어에서 문자들을 선택.
▷ CComboBox::SetExtendedUI - 디폴트, 확장 사용자 인터페이스의 선택.
▷ CComboBox::SetItemData - 항목과 관련된 값을 정함.
▷ CComboBox::SetItemDataPtr - 포인터에 대한 관련된 값을 정함.
▷ CComboBox::SetItemHeight - 높이를 지정.
▷ CComboBox::ShowDropDown - 리스트 박스를 보여주거나 숨김.