Перед вами
очередной выпуск рассылки "Программирование на WinApi" Переводы многих функций Win32API, которые часто используются
в данной рассылке, вы можете получать, подписавшись на дружественную
рассылку "WinAPI на
русском". Справочник по функциям Win32API вы
можете посмотреть на сайте BcbDev.ru в разделе MSDN
по-русски.
Как получить имя
исполняемого файла, ассоциированного с данным
окном?
Код ниже - версия примера MS с
исправленной ошибкой:
BOOL MyGetWindowExeFilename (HWND hWnd,
char * pszFilename,
int iSizeofBuff)
{
DWORD dwActiveProcessId;
DWORD CurrentProcessId;
BOOL bFound = FALSE;
char szIndex[512] = "";
DWORD dwBytes = 12000;
DWORD dwProcessIdOffset;
DWORD dwIndex;
int i;
PPERF_DATA_BLOCK pdb;
PPERF_OBJECT_TYPE pot;
PPERF_INSTANCE_DEFINITION pid;
PPERF_COUNTER_BLOCK pcb;
PPERF_COUNTER_DEFINITION pcd;
// Получаем PID соответствующий этому дескриптору окна.
GetWindowThreadProcessId (hWnd, &dwActiveProcessId);
// Получаем индекс объекта PROCESS.
if (GetIndex ("Process", szIndex) != ERROR_SUCCESS)
{
// Здесь мы должны сообщить об ошибке
return FALSE;
}
// Получаем память для PPERF_DATA_BLOCK.
pdb = (PPERF_DATA_BLOCK) HeapAlloc (GetProcessHeap(),
HEAP_ZERO_MEMORY,
dwBytes);
// Получаем данные эффективности.
while (RegQueryValueEx (HKEY_PERFORMANCE_DATA,
(LPTSTR)szIndex,
NULL,
NULL,
(LPBYTE)pdb,
&dwBytes) == ERROR_MORE_DATA)
{
// Увеличиваем память.
dwBytes += 1000;
// Выделенная память слишком мала, выделяем новую память...
pdb = (PPERF_DATA_BLOCK) HeapReAlloc (GetProcessHeap(),
HEAP_ZERO_MEMORY,
(LPVOID)pdb,
dwBytes);
}
// Получаем PERF_OBJECT_TYPE.
pot = (PPERF_OBJECT_TYPE)((PBYTE)pdb + pdb->HeaderLength);
// Получаем определение первого счётчика.
pcd = (PPERF_COUNTER_DEFINITION)((PBYTE)pot + pot->HeaderLength);
// Получаем значение индекса для ID_PROCESS.
szIndex[0] = '\0';
if (GetIndex ("ID Process", szIndex) == ERROR_SUCCESS)
{
dwIndex = (DWORD) atoi(szIndex);
for (i=0; i< (int)pot->NumCounters; i++)
{
if (pcd->CounterNameTitleIndex == dwIndex)
{
dwProcessIdOffset = pcd->CounterOffset;
break;
}
pcd = ((PPERF_COUNTER_DEFINITION)((PBYTE)pcd + pcd->ByteLength));
}
// Получаем первый образец объекта.
pid = (PPERF_INSTANCE_DEFINITION)((PBYTE)pot + pot->DefinitionLength);
// GПолучаем имя первого процесса.
pcb = (PPERF_COUNTER_BLOCK) ((PBYTE)pid + pid->ByteLength );
CurrentProcessId = *((DWORD *) ((PBYTE)pcb + dwProcessIdOffset));
// Ищем объект процесса для переданного PID, и сравниваем его с нашим.
for (i = 1; i < pot->NumInstances && !bFound; i++)
{
if (CurrentProcessId == dwActiveProcessId)
{
if (WideCharToMultiByte (CP_ACP,
WC_COMPOSITECHECK,
(LPCWSTR)((PBYTE)pid + pid->NameOffset),
-1,
pszFilename,
iSizeofBuff,
NULL,
NULL))
{
bFound = TRUE;
}
else
{
//Тут мы сообщаем об ошибке
}
}
else
{
pid = (PPERF_INSTANCE_DEFINITION) ((PBYTE)pcb + pcb->ByteLength);
pcb = (PPERF_COUNTER_BLOCK) ((PBYTE)pid + pid->ByteLength);
CurrentProcessId = *((DWORD *)((PBYTE)pcb + dwProcessIdOffset));
}
}
}
// Освобождаем выделенную память.
HeapFree (GetProcessHeap(), 0, (LPVOID)pdb);
// Закрываем дескриптор открытого ключа.
RegCloseKey (HKEY_PERFORMANCE_DATA);
return bFound ;
}
// -----------------------------------------------------
// Вспомогательная функция:
DWORD GetIndex (char *pszCounter, char *szIndex)
{
char* pszBuffer;
char* pszTemp;
char szObject[256] = "";
char szMasterKey [100] = "SOFTWARE\\Microsoft\\Windows NT\\CurrentVersion\\Perflib\\";
DWORD dwBytes;
HKEY hKeyIndex;
int i = 0;
int j = 0;
DWORD dwRetVal = ERROR_SUCCESS;
// Пример Microsoft в этом месте не правилен.
//Я отделил эту строку, так что она может быть получена
//в другом месте, при необходимости
strcat (szMasterKey, "009");
dwRetVal = RegOpenKeyEx (HKEY_LOCAL_MACHINE,
szMasterKey,
0,
KEY_READ,
&hKeyIndex);
// Открываем ключ.
if (dwRetVal == ERROR_SUCCESS)
{
dwRetVal = RegQueryValueEx (hKeyIndex,
"Counter",
NULL, NULL, NULL,
&dwBytes);
// Выделяем память под буфер.
pszBuffer = (char *) HeapAlloc (GetProcessHeap(),
HEAP_ZERO_MEMORY,
dwBytes);
// Получаем заголовки и счётчики
dwRetVal = RegQueryValueEx (hKeyIndex,
"Counter",
NULL, NULL,
(LPBYTE)pszBuffer,
&dwBytes) ;
if (dwRetVal == ERROR_SUCCESS)
{
// Ищем значение индекса для PROCESS.
pszTemp = pszBuffer;
while (i != (int)dwBytes)
{
while (*(pszTemp+i) != '\0')
{
szIndex[j] = *(pszTemp+i);
i++;
j++;
}
szIndex[j] = '\0';
i++;
j = 0;
while (*(pszTemp+i) != '\0')
{
szObject[j] = *(pszTemp+i);
i++;
j++;
}
szObject[j] = '\0';
i++;
j = 0;
if (*(pszTemp+i) == '\0')
i++;
if (strcmp(szObject, pszCounter) == 0)
break;
}
// Освобождаем память
HeapFree (GetProcessHeap(), 0, (LPVOID)pszBuffer);
}
else
{
//Тут мы сообщаем об ошибке
}
// Закрываем ключ.
RegCloseKey (hKeyIndex);
}
else
{
//Тут мы сообщаем об ошибке
}
return dwRetVal;
}