程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
 程式師世界 >> 編程語言 >> C語言 >> 關於C語言 >> 如何獲得另一個應用程序窗口中的文本

如何獲得另一個應用程序窗口中的文本

編輯:關於C語言

要想獲得另一個進程窗口的文本,只需直接發送WM_GETTEXT。

CWnd* pWnd = GetOtherAppWindow();
TCHAR buf[512];
pWnd->SendMessage(WM_GETTEXT,
    sizeof(buf)/sizeof(TCHAR),
    (LPARAM)(void*)buf);
    如果您在用C編程,自然用HWND代替CWnd。有人肯定會問:嘿,等一下——如果這樣做可以的話,為什麼GetWindowText不起作用呢?WM_GETTEXT不就是GetWindowText發送的嗎?錯也,GetWindowText只在窗口屬於當前進程時才發送WM_GETTEXT,否則它干別的事情。這一點文檔中說得很清楚:
如果目標窗口屬於另一個進程,並且有窗口標題,則GetWindowText獲得窗口標題文本。如果沒有窗口標題,則GetWindowText返回空串。這是設計行為,也就是說,在設計時就是這麼處理的。
換句話說,你可以獲得另一個進程主窗口的標題,但得不到窗口中象編輯框、組合框或者按鈕這樣的子窗口的文本。
    為什麼會這樣呢?為什麼這是“設計行為”呢?因為文檔又解釋道:
       “它允許目標窗口所在進程掛起的情況下,應用程序無需掛起而調用GetWindowText,”真是妙哉,不是嗎?GetWindowText提供了禁地(never-never land)調用保護。當然老道的程序員可能會想:那有什麼好的?GetWindowText得不到文本,如果想要得到文本必須用SendMessage發送WM_GETTEXT,它可能掛起。那何以保護呢?即便不使用SendMessage!你還能用SendMessageTimeout,即使是調用進入一個死鎖進程, 它肯定能返回。在多任務世界中,要考慮的繁瑣事情真是太多了。
    真正的問題是:為什麼微軟公司的那幫家伙不讓GetWindowText函數做它該做的事情?也就是說,如果窗口在當前進程中,為什麼GetWindowText 不做一次SendMessage(WM_GETTEXT),而窗口在另一個進程時,做一次SendMessageTimeout呢?很好的問題。只有Window 向導(Wizard)知道。我懷疑在從偽多任務到真正的多任務過渡的過程中,微軟公司的那幫家伙在處理以前遺留下來的應用時有難言之隱...... 按照慣例,我寫了一個小程序GWTTest作示范。GWTTest顯示從GetWindowText 和 SendMessageTimeout(WM_GETTEXT) 獲得的頂層窗口及其編輯框控制的文本。如圖一所示: 圖一GetWindowText 與 WM_GETTEXT的比較     GWTTest程序本身沒有什麼用處,它只是用來示范GetWindowText 和 WM_GETTEXT之間的差別。從程序的運行結果可以看出,兩種操作都能返回頂層窗口的標題,但只有WM_GETTEXT才能對其它進程中的編輯框控制起作用。GWTTest是一個簡單的CListView應用程序;獲取文本的函數是CMyView::AddWindowInfo,代碼如下:
//AddWindowInfo.cpp源代碼
//////////////////
// 添加窗口信息, 頂層或者編輯框控制
void CMyView::AddWindowInfo(int iItem, HWND hwnd)
{
   CListCtrl& lc = GetListCtrl();
   CWnd* pWnd = CWnd::FromHandle(hwnd);
   int iSubitem = 1;

   // 添加類名
   CString s;
   ::GetClassName(hwnd, s.GetBuffer(STRINGLEN), STRINGLEN);
   lc.SetItemText(iItem,iSubitem++,s);

   // 用GetWindowText添加窗口文本
   pWnd->GetWindowText(s);
   lc.SetItemText(iItem,iSubitem++,s);
   // 用WM_GETTEXT添加窗口文本
   DWORD result;
   SendMessageTimeout(hwnd,
      WM_GETTEXT,
      STRINGLEN,
      (LPARAM)s.GetBuffer(STRINGLEN),
      0,
      1000,
      &result);
   lc.SetItemText(iItem,iSubitem++,s);
   s.ReleaseBuffer();
}

  1. 上一頁:
  2. 下一頁:
Copyright © 程式師世界 All Rights Reserved