通過指點操作獲得視窗控制代碼

來源:互聯網
上載者:User

通過指點操作獲得視窗控制代碼

趙砥:
    我用VB的sendkeys編寫了一個向其他程式類比鍵盤發送字元的工具,因VB編的程式體積太大,
    我想用Delphi重寫,使用SendMessage等API函數,但我想找到一個用滑鼠點一下其他進程的
    視窗便可獲得該視窗的線程id和視窗控制代碼的方法,請指點一下。(使用findwindow獲得視窗
    控制代碼要輸入視窗標題,不好。)
回答:
    首先需要說明要在Delphi 實現Sendkeys功能,應該使用Journal Playback鉤子(hook)函數,
    而不是使用SendMessage函數。下面我們來介紹如何利用滑鼠移動讓使用者選擇視窗,而程式
    進一步得到視窗的控制代碼。Windows API中有一個函數WindowFromPoint,只要知道滑鼠的位置
    (螢幕座標),就可以得到該位置所屬的視窗的控制代碼,有了控制代碼,就可以利用其他的函數得到
    更多的資訊。如果滑鼠在程式的視窗中移動,可以得到MouseMove事件。要想滑鼠在視窗外部
    移動時,仍能得到滑鼠事件,必須使用SetCapture函數。下面這個例子就是利用這兩個函數
    來實現你所要求的功能。
    
    type
     TForm1 = class(TForm)
     …………
    public
     procedure InvertTracker(hwndDest : Integer);
     end;
     …………
    var
     Form1: TForm1;
     mlngHwndCaptured: Integer;
     hWndLast: Integer;
     …………
    procedure TForm1.FormMouseMove(Sender: TObject; Shift: TShiftState; X,
     Y: Integer);
    var pt : TPoint;
    begin
     if GetCapture() <> 0 then // 處於捕捉狀態
     begin
     pt.X := X;
     pt.Y := Y;
     ClientToScreen(pt); // 獲得滑鼠的螢幕位置
     // 獲得視窗控制代碼
     mlngHwndCaptured := WindowFromPoint(pt);
    
     if hWndLast <> mlngHwndCaptured then
     begin
     if hWndLast <> 0 then // 使視窗邊框加粗
     InvertTracker(hWndLast);
     InvertTracker(mlngHwndCaptured);
     hWndLast := mlngHwndCaptured;
     end
     end;
     // 顯示座標和視窗控制代碼
     Caption := 'X: ' + IntToStr(x) + ', Y: ' + IntToStr(y)
     + ', hWnd: ' + IntToStr(mlngHwndCaptured);
    end;
    
    procedure TForm1.FormMouseDown(Sender: TObject; Button: TMouseButton;
     Shift: TShiftState; X, Y: Integer);
    begin
     if SetCapture(handle) <> 0 then // 開始捕捉
     Cursor := crUpArrow;
    end;
    
    procedure TForm1.FormMouseUp(Sender: TObject; Button: TMouseButton;
     Shift: TShiftState; X, Y: Integer);
    var strCaption: PChar;
    begin
     If mlngHwndCaptured <> 0 Then
     begin // 獲得視窗標題
     strCaption := StrAlloc(1000);
     GetWindowText(mlngHwndCaptured, strCaption, 1000);
     Caption := StrPas(strCaption);
     InvalidateRect(0, PRect(0), True);
     mlngHwndCaptured := 0;
     Cursor := crDefault;
     ReleaseCapture;
     StrDispose(strCaption);
     hWndLast := 0;
     end
    end;
    // 使視窗邊框變粗
    procedure TForm1.InvertTracker(hwndDest: Integer);
    var
     hdcDest, hPen, hOldPen, hOldBrush : Integer;
     cxBorder, cxFrame, cyFrame, cxScreen, cyScreen, cr : Integer;
     rc : TRect;
    Const NULL_BRUSH = 5;
    Const R2_NOT = 6;
    Const PS_INSIDEFRAME = 6;
    begin
     cxScreen := GetSystemMetrics(0);
     cyScreen := GetSystemMetrics(1);
     cxBorder := GetSystemMetrics(5);
     cxFrame := GetSystemMetrics(32);
     cyFrame := GetSystemMetrics(33);
     GetWindowRect(hwndDest, rc);
    
     hdcDest := GetWindowDC(hwndDest);
    
     SetROP2(hdcDest, R2_NOT);
     cr := clBlack;
     hPen := CreatePen(PS_INSIDEFRAME, 3 * cxBorder, cr);
    
     hOldPen := SelectObject(hdcDest, hPen);
     hOldBrush := SelectObject(hdcDest, GetStockObject(NULL_BRUSH));
     Rectangle(hdcDest, 0, 0, rc.Right - rc.Left, rc.Bottom - rc.Top);
     SelectObject(hdcDest, hOldBrush);
     SelectObject(hdcDest, hOldPen);
    
     ReleaseDC(hwndDest, hdcDest);
     DeleteObject(hPen);
    end;
    // 將視窗移動到左上方,並減少視窗高度,便於操作
    procedure TForm1.FormCreate(Sender: TObject);
    begin
     Left := 0;
     Top :=0;
     ClientHeight := 76;
    end;
    
    運行該程式時,先在程式視窗內點一下,然後按住滑鼠左鍵不放,移動滑鼠,這時你會
    看到程式視窗的標題位置不斷顯示滑鼠的當前位置(視窗座標)和滑鼠所在位置的視窗控制代碼。
    同時,被選中的視窗邊框加粗,一旦放開左鍵,則程式視窗的標題就改為所選中視窗的標題。
    相信許多人對這種操作方式都會感到熟悉,因為象Spy++(Visual C++)、Magic Mouse、
    Capture Professional等很多軟體都是採用類似的操作來選擇視窗的。

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.