2013-07-30 2 views
3

프로세스의 창 제목을 얻을 수있는 프로그램을 작성하려고합니다. 내가 문제를 설명하기 전에, 여기에 코드입니다 : 나는 윈도우의 실제 제목을 취득 할 때까지이 프로그램은 지금까지 작동프로세스 이름에서 창 제목 얻기

#include <Windows.h> 
#include <string> 
#include <Psapi.h> 
#include <algorithm> 

std::string window_title; 
std::string search_for;  

BOOL CALLBACK EnumWindowCallback(HWND hWindow, LPARAM param) 
{ 
    if (IsWindow(hWindow) == TRUE) 
    { 
     DWORD pid = 0; 

     if (GetWindowThreadProcessId(hWindow, &pid) != 0) 
     { 
      HANDLE hProcess; 
      hProcess = OpenProcess(PROCESS_ALL_ACCESS, FALSE, pid); 
      if (hProcess != 0) 
      { 
       std::string path; 
       CHAR name[MAX_PATH]; 
       GetModuleFileNameExA(hProcess, NULL, name, sizeof(name)/sizeof(CHAR)); 
       path = name; 
       unsigned int slash = path.find_last_of('\\'); 
       if (slash != std::string::npos){ 
        std::string proc_name = path.substr(slash + 1, path.length()); 
        std::transform(proc_name.begin(), proc_name.end(), proc_name.begin(), ::tolower); 
        if (proc_name == search_for) 
        { 
         CHAR finalTitle[MAX_PATH]; 
         ZeroMemory(finalTitle, sizeof(finalTitle)); 
         SendMessageA(hWindow, WM_GETTEXT, (WPARAM)sizeof(CHAR)/sizeof(MAX_PATH), (LPARAM)finalTitle); 
         window_title = finalTitle; 
         return FALSE; 
        } 
       } 
      } 
     } 
    } 
    return TRUE; 
}; 

const char* __stdcall GetWinTitleByProcessName(const char* title) 
{ 
    search_for = title; 
    std::transform(search_for.begin(), search_for.end(), search_for.begin(), ::tolower); 
    if (EnumWindows((WNDENUMPROC)EnumWindowCallback, 0) == FALSE) 
    { 
     return window_title.c_str(); 
    } 

    return "NOTFOUND"; 
} 

int WINAPI WinMain(HINSTANCE, HINSTANCE, LPSTR, int) 
{ 
    MessageBoxA(NULL, GetWinTitleByProcessName("chrome.exe"), "Test", MB_OK); 
} 

. 여기에 표시된대로 GetWindowText 및 SendMessage를 시도했습니다. 두 메서드 모두 빈 문자열을 반환합니다.

어떻게 창 제목을 얻을 수 있습니까?

+0

이 질문에 방문한 : http://stackoverflow.com/questions/7063316/getwindowtext-returning-empty-string-and-strange-error하지만 내 질문에 맞는 솔루션이 실제로 포함되어 있지 않습니다. – DeleteMe

+0

유니 코드 문자열 대신 ANSI 문자열을 사용하는 이유는 무엇입니까? 2013 년, 모든 Windows 프로그램은 완전히 유니 코드 여야합니다. 'char'와'SendMessageA'를'wchar_t'와'SendMessageW'로 대체하십시오. 프로젝트에'UNICODE' 심볼이 정의되어 있는지 확인하십시오. –

+0

최종 결과는 wchar_t를 인식하지 못하는 고대 스크립팅 언어로 내보내지기 때문에 char에 있어야하기 때문에. – DeleteMe

답변

1

다음 코드는 비슷한 문제를 해결합니다. 제 경우에는 응용 프로그램의 윈도우 핸들을 찾고 있으므로 DLL을 부모로 사용할 수 있습니다. 나는 그 자막으로 응용 프로그램을 식별합니다. C++ 빌더 코드 때문에 익숙하지 않은 부분이있을 수 있습니다. 나는 그 차이점을 언급 할 것이다. 주요한 것은 Application을 사용하는 것입니다. Embarcadero가 아닌 것은 무엇인지는 모르겠지만, 실행중인 각 코드 인스턴스는 메시지 루프를 관리하는 Application 인스턴스를 가지고 있습니다. 나는 dll의 Application-> Handle을 호출하는 응용 프로그램에 설정하여 다른 것들 중에서 작업 표시 줄에서 그것을 지우도록했다. 이 코드는 xp, vista 32 및 win7 64에서 작동합니다.

void HideDLL() { 
     if (Application->Handle == 0) { 
     SearchObject *so = new SearchObject(); 
     so->Caption = L"MyCallingApp"; 
     so->Handle = 0; 
     EnumWindows((WNDENUMPROC)EnumWindowsProc, (long)so); 
     Application->Handle = so->Handle; 

     delete so; 
     } 

    } 
    BOOL CALLBACK EnumWindowsProc(HWND hWnd, LPARAM lparam) { 

     bool result; 
     SearchObject *so = (SearchObject*)lparam; 
     wchar_t *caption = new wchar_t[STR_DEFAULT]; 

     GetWindowTextW(hWnd, caption, STR_DEFAULT); 
     // String is an Embarcadero type representing UnicodeString 
     String Caption = caption; 
     // Pos is a wrapper around strstr I think 
     // the actual caption in my case is decorated with some other stuff 
     // I only know that it will start with the name of the app 
     if (Caption.Pos(so->Caption) > 0) { 
     so->Handle = hWnd; 
     result = false; 
     } else { 
     result = true; 
     } 
     delete caption; 
     return result; 
    } 

희망이 있습니다.

1

sizeof (char)가 최대 경로보다 작기 때문에 (WPARAM) sizeof (CHAR)/sizeof (MAX_PATH)는 0을 반환하는 것으로 보이므로 WinAPI에 변수의 길이가 0이라고 말해야합니다 그래서 빈 문자열이 반환됩니다. 대신 MAX_PATH 값을 지정하십시오.