__declspec(dllexport) void GetCurrentTopology(DISPLAYCONFIG_TOPOLOGY_ID *peCurrentTopology) { // Get the current topology - make sure that we aren't resetting the topology to the same that it // currently is - otherwise it can cause unnecessary flashing on the screen. LONG result; UINT32 NumPathArrayElements; UINT32 NumModeInfoArrayElements; DISPLAYCONFIG_PATH_INFO *pPathInfoArray; DISPLAYCONFIG_MODE_INFO *pModeInfoArray; result = GetDisplayConfigBufferSizes(QDC_DATABASE_CURRENT, &NumPathArrayElements, &NumModeInfoArrayElements); if (result != ERROR_SUCCESS) return; if (peCurrentTopology == NULL) return; // The only reason to allocate these structures is that the documentation says that QueryDisplayConfig // cannot take null for the pPathInfoArray and pModeInfoArray elements. I have tried to have static // structures that get passed in with only one element and have had things fail in the past // The only way that I've gotten this interface to reliably work is to call GetDisplayConfigBufferSizes // and then allocate AND ZERO the structures that are passed in. This interface is incredibly // fragile and you are going to want to do everything that it expects, or it will return // "invalid parameter" pPathInfoArray = (DISPLAYCONFIG_PATH_INFO *)malloc(NumPathArrayElements * sizeof(DISPLAYCONFIG_PATH_INFO)); if (!pPathInfoArray) return; pModeInfoArray = (DISPLAYCONFIG_MODE_INFO *)malloc(NumModeInfoArrayElements * sizeof(DISPLAYCONFIG_MODE_INFO)); if (!pModeInfoArray) { if (pPathInfoArray) free(pPathInfoArray); return; } memset(pPathInfoArray, 0, NumPathArrayElements * sizeof(DISPLAYCONFIG_PATH_INFO)); memset(pModeInfoArray, 0, NumModeInfoArrayElements * sizeof(DISPLAYCONFIG_MODE_INFO)); result = QueryDisplayConfig(QDC_DATABASE_CURRENT, &NumPathArrayElements, pPathInfoArray, &NumModeInfoArrayElements, pModeInfoArray, peCurrentTopology); // Free the structures, don't care what is in them free(pPathInfoArray); free(pModeInfoArray); if (result != ERROR_SUCCESS) return; return; }
int getCurrentSettings(UINT32* num_of_paths, UINT32* num_of_modes, DISPLAYCONFIG_PATH_INFO** displayPaths, DISPLAYCONFIG_MODE_INFO** displayModes) { // Get number of paths, and number of modes in query if (!Result_DCGDI(GetDisplayConfigBufferSizes(QDC_ALL_PATHS, num_of_paths, num_of_modes))) return 0; // Allocate paths and modes dynamically *displayPaths = (DISPLAYCONFIG_PATH_INFO*)calloc((int)num_of_paths, sizeof(DISPLAYCONFIG_PATH_INFO)); *displayModes = (DISPLAYCONFIG_MODE_INFO*)calloc((int)num_of_modes, sizeof(DISPLAYCONFIG_MODE_INFO)); // Query for the information (fill in the arrays above) if (!Result_QDC(QueryDisplayConfig(QDC_ALL_PATHS, num_of_paths, (*displayPaths), num_of_modes, (*displayModes), NULL))) return 0; return 1; }
// Get current refresh rate on Win7 double W7GetRefreshRate(int monitorIdx) { UINT32 uNumPathArrayElements = 0; UINT32 uNumModeInfoArrayElements = 0; DISPLAYCONFIG_PATH_INFO* pPathInfoArray = NULL; DISPLAYCONFIG_MODE_INFO* pModeInfoArray = NULL; DISPLAYCONFIG_TOPOLOGY_ID* pCurrentTopologyId = NULL; LONG result; double refreshRate = -1; DISPLAY_DEVICE displayDevice; displayDevice.cb = sizeof(DISPLAY_DEVICE); DEVMODE devMode; devMode.dmSize = sizeof(DEVMODE); DEVMODE *paDeviceMode; if(EnumDisplayDevices(NULL, monitorIdx, &displayDevice, 0)) { EnumDisplaySettings(displayDevice.DeviceName, ENUM_CURRENT_SETTINGS, &devMode); } paDeviceMode = &devMode; // Get size of buffers for QueryDisplayConfig result = GetDisplayConfigBufferSizes(QDC_ONLY_ACTIVE_PATHS, &uNumPathArrayElements, &uNumModeInfoArrayElements); if (result != 0) { return(refreshRate); } // allocate memory for QueryDisplayConfig buffers pPathInfoArray = (DISPLAYCONFIG_PATH_INFO*)calloc(uNumPathArrayElements, sizeof(DISPLAYCONFIG_PATH_INFO)); if (pPathInfoArray == NULL) { return(refreshRate); } pModeInfoArray = (DISPLAYCONFIG_MODE_INFO*)calloc(uNumModeInfoArrayElements, sizeof(DISPLAYCONFIG_MODE_INFO)); if (pModeInfoArray == NULL) { // freeing memory free(pPathInfoArray); return(refreshRate); } // get display configuration result = QueryDisplayConfig(QDC_ONLY_ACTIVE_PATHS, &uNumPathArrayElements, pPathInfoArray, &uNumModeInfoArrayElements, pModeInfoArray, pCurrentTopologyId); if (result == 0) { //// Get information from active target path and based on current dimension (support for multiple displays) for (UINT i = 0; i < uNumPathArrayElements; ++i) { UINT iModIdx = pPathInfoArray[i].sourceInfo.modeInfoIdx; if(pPathInfoArray[i].flags == DISPLAYCONFIG_PATH_ACTIVE && paDeviceMode[0].dmPosition.x == pModeInfoArray[iModIdx].sourceMode.position.x && paDeviceMode[0].dmPosition.y == pModeInfoArray[iModIdx].sourceMode.position.y) { if(paDeviceMode[0].dmPelsHeight == pModeInfoArray[iModIdx].sourceMode.height && paDeviceMode[0].dmPelsWidth == pModeInfoArray[iModIdx].sourceMode.width) { monitorIdx = i; DISPLAYCONFIG_PATH_TARGET_INFO target; target = pPathInfoArray[monitorIdx].targetInfo; LONG numerator = target.refreshRate.Numerator; LONG denominator = target.refreshRate.Denominator; refreshRate = (double)numerator/(double)denominator; break; } } } } // freeing memory free(pPathInfoArray); free(pModeInfoArray); return(refreshRate); }