This is a Windows program in the simplest variation. In the main window - a vertical splitter, in the left pane a tree (tree control), in the right pane a list (list control). Graphic design is easily executed even on pure WinAPI, with any framework without any problems at all. Perhaps the easiest is Visual C ++ and MFC - in the MFC project templates there is an 'Explorer' that creates this application completely, all that remains is to add specific content (that is, work with the registry). To work with the registry, you can use the CRegKey class.
ADDITION
Above there was a long dispute over whether to read the registry asynchronously for later display in treectrl and listctrl. I consider such optimization a complete stupidity, and in order not to be unfounded, I decided to write a small test that reads the main branches and reports the time spent. The original version with GetTickCount returned all zeros, so I had to redo it with a high resolution timer.
static double frequency; void EnumReg(LPCTSTR szHiveName, HKEY hHive) { LARGE_INTEGER tm0; if (!::QueryPerformanceCounter(&tm0)) throw win_error(); TCHAR szName[MAX_PATH]; DWORD uNameLen; DWORD nKeys = 0; LONG lr; for (;;) { uNameLen = MAX_PATH; lr = ::RegEnumKeyEx(hHive, nKeys++, szName, &uNameLen, NULL, NULL, NULL, NULL); if (lr == ERROR_NO_MORE_ITEMS) break; if (lr != ERROR_SUCCESS) throw win_error(lr); } LARGE_INTEGER elaps; if (!::QueryPerformanceCounter(&elaps)) throw win_error(); elaps.QuadPart -= tm0.QuadPart; double elapsed = (double)elaps.QuadPart; elapsed *= 1.0e3; // We need milliseconds elapsed /= frequency; _tprintf(_TEXT("%s:\t%u subkeys, elapsed time %7.3fms\n"), szHiveName, nKeys, elapsed); } void main() { try { LARGE_INTEGER freq; if (!::QueryPerformanceFrequency(&freq)) throw win_error(); frequency = (double)freq.QuadPart; EnumReg(_TEXT("HKEY_LOCAL_MACHINE"), HKEY_LOCAL_MACHINE); EnumReg(_TEXT("HKEY_CURRENT_USER"), HKEY_CURRENT_USER); EnumReg(_TEXT("HKEY_CLASSES_ROOT"), HKEY_CLASSES_ROOT); } catch (generic_error &se) { printf("\n\n"); printf(se.Message()); } TCHAR pat[120]; printf("\nPress any key..."); _getts(pat); }
The result is the following:

From this it is obvious that the time of filling and updating the control will be at least an order of magnitude longer than the time of reading the registry. This is speaking of a uniquely huge HKCR branch. For any other key, the read time will be microseconds, so any multi-threaded optimizations will be inappropriate here.