2013-07-30 60 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

它也是NoneOfMyBusiness爲什麼你使用ANSI字符串而不是Unicode字符串?這是2013年,所有的Windows程序都應該完全是Unicode。用'wchar_t'和'SendMessageW'替換'char'和'SendMessageA'。確保爲您的項目定義了「UNICODE」符號。 –

+0

由於最終結果必須以char形式存在,因爲它被導出爲不理解wchar_t的古老腳本語言。 – DeleteMe

回答

1

下面的代碼適用於類似的問題。在我的情況下,我正在尋找一個應用程序的窗口句柄,以便我可以父母的DLL。我通過它的標題來識別應用程序。它的C++ Builder代碼對某些部分可能並不熟悉。我會評論我發現的差異。主要的是使用Application,我不確定非Embarcadero的等價物是什麼,但是每個運行的代碼實例都有一個管理消息循環等的Application實例。我將我的dll的Application-> Handle設置爲調用應用程序hWnd,以使其不在任務欄中等等。此代碼適用於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

看來,(WPARAM)的sizeof(CHAR)/的sizeof(MAX_PATH)將返回你爲零,因爲的sizeof(char)的將是defenetly越小則最大路徑,所以你說WINAPI,你的可變長度爲零這就是爲什麼它返回空字符串給你。 改爲指定MAX_PATH值。