delphi에서 다른 창을 제어하는 컨트롤

8450 단어 Delphi

먼저 말씀드리자면 저는 풋내기입니다. 저는 단지 제가 오랫동안 갇혀 있던 문제의 해결 방안을 발표하여 나중에 제가 또 잊어버리지 않도록 하고 싶을 뿐입니다. 그리고 이런 작은 지식을 아직 모르는 동료들에게 도움을 주고 싶습니다.여러분 저의 천박함을 비웃지 마세요.동시에 저의 저급함을 나타내기 위해 저는 기본적인 것을 수다스럽게 말할 것입니다. 이것은 모두 제 이해이고 정확하지 않습니다.다른 프로그램 창의 창 컨트롤을 제어하려면 리셋 함수가 무엇인지 알아야 합니다.나의 이해는 다음과 같다. 리셋 함수는 자신의 프로그램이 호출하는 것이 아니라 오히려 다른 것을 호출하게 한다. 예를 들어 윈도우즈 운영체제, 예를 들어 다른 프로그램 등이다.근데 언제 호출됐는지 모르겠어요.리셋 함수는 일반적으로 호출자의 요구에 따라 매개 변수와 리셋 값의 유형을 정의한다. 호출자에게 리셋 함수의 입구 주소를 제공한 다음에 호출자가 어떤 사건이 발생할 때 언제든지 당신이 제공한 주소에 따라 이 함수를 호출하여 알려 주고 미리 정해진 형식에 따라 매개 변수를 전달할 수 있다.그래서 많은 사람들이 예를 들어 리셋 함수는 정말 당신이 가지고 있는 BP기와 비슷하다고 말한다. 다른 사람에게 번호를 알려주면 일이 있을 때 콜!그래서 리셋 함수를 쓴 후에 반드시 등록된 동작이 있다. 바로 호출자에게 내가 쓴 함수를 어떻게 찾았는지 알려주는 것이다.일부 Windows API 함수는 SetTimer, LineDDA, EnumObjects, 그리고 우리가 다음에 사용할 EnumWindows와 같은 리셋 함수 주소를 매개 변수 중 하나로 요구할 것이다.Delphi에서 콜백 함수를 선언하는 형식은 다음과 같습니다.
function EnumWindowsProc(AhWnd:LongInt;lParam:LongInt):boolean;stdcall;


우선 함수 명칭은 마음대로 찾을 수 있지만 함수 매개 변수의 유형은 일반적으로 함부로 해서는 안 된다. 그 순서, 데이터 유형 등은 모두 규정되어 있다. 왜냐하면 이것들은 모두 다른 프로그램이 호출하도록 하는 것이기 때문에 그들은 이미 규정되어 있지만 매개 변수의 명칭은 마음대로 불러도 된다.다음에 반드시'stdcall'을 가져가야 합니다. stdcall은 표준 호출입니다. 즉, 표준 윈도우즈 매개 변수 전달 방식으로 함수를 호출합니다.함수체를 작성하는 것은 매우 간단하다. 전달된 매개 변수를 이용하면 된다. 이 매개 변수는 다른 사람이 너에게 준 것임을 기억하고 이 매개 변수가 무슨 뜻을 대표하는지 알기만 하면 된다.호출자에게 리셋 함수 입구 주소를 등록하는 함수를 다시 보십시오.
function EnumWindows(lpEnumFunc: TFNWndEnumProc; lParam: LPARAM): BOOL; stdcall;


TFNWndEnumProc는 포인터 유형입니다.그중의 lpEnumFunc는 리셋 함수의 입구 주소입니다.다음은 EnumWindows를 호출하는 형식입니다.
EnumWindows(@EnumWindowsProc,0);


시스템에 리셋 함수의 입구 주소를 등록함으로써 시스템은 필요할 때 리셋 함수를 호출하여 매개 변수를 전달할 수 있다. 아마도 이런 매개 변수가 우리가 원하는 것일 것이다.EnumWindows 함수의 기능은 화면에 있는 모든 프로그램의 맨 윗부분 창을 열거하여 창 핸들을 매개 변수로 리셋 함수에 전달하는 것이다.창을 찾으면 리셋 함수를 한 번 호출합니다.매거 종료의 조건은 모든 창을 매거하거나, 함수를 되돌려주면false입니다.lParam: LPARAM 매개 변수는 프로그램이 정의한 값입니다. 이 값은 리셋 함수에 전달됩니다.EnumWindowsProc를 다시 한 번 살펴보십시오.
function EnumWindowsProc(AhWnd:LongInt;lParam:LongInt):boolean;stdcall;


시스템이 창을 찾은 후 이 리셋 함수를 호출하여 창의 핸들을 첫 번째 매개 변수로 전달하고, EnumWindows에서 lParam: LPARAM이라는 프로그램이 정의한 값을 두 번째 매개 변수로 전달합니다.그래서 우리는 EnumWindowsProc 함수에서 전달된 두 개의 매개 변수를 이용하여 어떤 처리를 할 수 있다.
다음은 시스템에 있는 모든 프로그램의 맨 윗부분 창을 열거하는 프로그램입니다. 창의 제목을 얻고, 창 클래스의 이름을 얻으려고 합니다.창 제목 지정:
function GetWindowText(hWnd: HWND; lpString: PChar; nMaxCount: Integer): Integer; stdcall;


이 함수 기능은 창 핸들이 hWnd인 창의 제목을 버퍼 lpString에 복사합니다.nMaxCount는 버퍼에 복사된 최대 문자 수입니다.창 제목을 얻으려면 메시지를 보낼 수도 있습니다: WMGETTEXT, 사실 GetWindowText는 WM을 보내는 것이다GETTEXT 메시지의창 클래스 이름을 사용하려면:
function GetClassName(hWnd: HWND; lpClassName: PChar; nMaxCount: Integer): Integer; stdcall;


그 매개 변수의 의미는 위의 함수와 차이가 많지 않다.자세히 설명 안 할게요.먼저 EnumWindowsProc의 콜백 함수를 작성합니다.이제 우리는 이미 두 개의 매개 변수의 값이 있다고 자신에게 말해라.이 두 파라미터는 시스템이 우리에게 준 것이다.창 제목과 클래스 이름을 표시하기 위해 TMemo 컨트롤을 사용합니다.먼저interface 부분에서 함수를 설명합니다.
function EnumWindowsProc(AhWnd:LongInt;AForm:TForm1):boolean;stdcall;


내가 두 번째 파라미터를 바꾸었으니, 괜찮아. 그때 호출할 때 주의해서 봐.그런 다음 implementation 섹션에서 함수를 정의합니다.
function EnumWindowsProc(AhWnd:LongInt;AForm:TForm1):boolean;

var

lpszClassName,lpszWindowText:array[0..254] of char; //       。

begin

GetWindowText(AhWnd,lpszWindowText,254);//      

GetClassName(AhWnd,lpszClassName,254);//      。

Aform.memo1.lines.add(StrPas(lpszWindowText));

Aform.memo1.lines.add(StrPas(lpszClassName));

Aform.memo1.lines.add('--------------------');

Result:=True;

end;


이어서 해야 할 일은 Enum Windows 함수를 호출하고 리셋 함수 입구 주소를 등록하여 시스템에서 리셋 함수를 호출하도록 하는 것이다. 창을 열거했다.그래서 TButton: btn 을 하나 더 추가합니다.listwindow
procedure TForm1.btn_listwindowClick(Sender: TObject);

begin

EnumWindows(@EnumWindowsProc,LongInt(self));

end;


프로그램 목록은 다음과 같습니다.
unit Unit1;

interface

uses

Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,

Dialogs, StdCtrls;

type

TForm1 = class(TForm)

Memo1: TMemo;

btn_listwindow: TButton;

procedure btn_listwindowClick(Sender: TObject);

private

{ Private declarations }

public

{ Public declarations }

end;

var

Form1: TForm1;

function EnumWindowsProc(AhWnd:LongInt;AForm:TForm1):boolean;stdcall;

implementation

{$R *.dfm}

function EnumWindowsProc(AhWnd:LongInt;AForm:TForm1):boolean;

var

lpszClassName,lpszWindowText:array[0..254] of char;

begin

GetWindowText(AhWnd,lpszWindowText,254);

GetClassName(AhWnd,lpszClassName,254);

Aform.memo1.lines.add(StrPas(lpszWindowText));

Aform.memo1.lines.add(StrPas(lpszClassName));

Aform.memo1.lines.add('--------------------');

Result:=True;

end;

procedure TForm1.btn_listwindowClick(Sender: TObject);

begin

EnumWindows(@EnumWindowsProc,LongInt(self));

end;

end.


F9, 실행, 결과를 봅시다.가장 좋은 것은 F7 단일 단계 추적 디버깅을 해서 리셋 함수가 어떻게 호출되는지 보는 것이다.
리셋 함수의 개념과 위의 예가 있으면 우리는 계속할 수 있다.제목이 알려진 창 핸들을 찾으려면 API 함수를 사용하면 됩니다:FindWindow.그 함수 원형은: function Find Window (lpClassName, lpWindow Name: PChar): HWND;stdcall;lpClassName: 창 클래스 이름.제목만 알면 비어 있을 수 있습니다.창 클래스 이름은 많은 공구.로 얻을 수 있습니다.예를 들어 winsignt32.lpWindowName:창 제목.호출 방법은 다음과 같습니다.
var wndhwnd:HWND;

wndhwnd:=FindWindow(nil,'     ');

if wndhwnd<>0 then file://       .

begin

xxxxx

end

else begin

MessageBox(self.handle,'        ','  ',0);

end;


이 창 핸들이 있으면 우리의 초기 목적에서 멀지 않습니다. 다른 창의 창 컨트롤을 제어합니다.마찬가지로, 우선 다른 창에 있는 창 컨트롤의 핸들을 가져와야 합니다.우리는 이 API 함수를 사용한다:EnumChildWindows.함수 원형은 다음과 같습니다.
function EnumChildWindows(hWndParent: HWND; lpEnumFunc: TFNWndEnumProc;lParam: LPARAM): BOOL; stdcall;


이 함수와 EnumWindow 함수는 매우 상상적이다.그 작용도 비슷하다.그것의 기능은 창 핸들이 hWndParent인 창의 모든 창 컨트롤을 열거하는 핸들입니다.마찬가지로 리셋 함수 매개 변수의 형식으로 제시된 것이다.
우리는 다시 하나의 실제 예를 들어 이 함수의 용법을 설명한다.프로그램의 기능은 사용자가 창 제목을 입력한 다음FindWindow 함수를 호출해서 이 창 핸들을 찾을 수 있도록 하는 것입니다.이 핸들을 통해 우리는 메모에 이 창의 모든 창 컨트롤을 표시합니다. 마찬가지로 리셋 함수를 먼저 작성합니다.
function EnumChildWndProc(AhWnd:LongInt;

AlParam:lParam):boolean;stdcall;

var

WndClassName: array[0..254] of Char;

WndCaption: array[0..254] of Char;

begin

GetClassName(AhWnd,wndClassName,254);

GetWindowText(aHwnd,WndCaption,254);

with form1.memo1 do

begin

lines.add( string(wndClassName));

lines.add( string(wndCaption));

lines.add('-------');

end;

result:=true;

end;


그런 다음 EnumChild Windows 함수를 호출합니다.
procedure TForm1.Button1Click(Sender: TObject);

var

hWnd:LongInt;

begin

memo1.Lines.Clear;

Memo1.Lines.Add(Edit1.Text+'         ');

hWnd:=FindWindow(nil,pchar(Edit1.Text));

if hWnd<>0 then

begin

EnumChildWindows(hWnd,@EnumChildWndProc,0);

end

else MessageBox(self.handle,'        ','  ',0);

end;


프로그램 목록은 다음과 같습니다.
unit Unit1;

interface

uses

Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,

Dialogs, StdCtrls;

type

TForm1 = class(TForm)

Memo1: TMemo; file://         

Label1: TLabel; 

Edit1: TEdit;  file://    .

Button1: TButton; 

procedure Button1Click(Sender: TObject);

private

{ Private declarations }

public

{ Public declarations }

end;

var

Form1: TForm1;

function EnumChildWndProc(AhWnd:LongInt;

AlParam:lParam):boolean;stdcall;

implementation

{$R *.dfm}

function EnumChildWndProc(AhWnd:LongInt;

AlParam:lParam):boolean;stdcall;

var

WndClassName: array[0..254] of Char;

WndCaption: array[0..254] of Char;

begin

GetClassName(AhWnd,wndClassName,254);

GetWindowText(aHwnd,WndCaption,254);

with form1.memo1 do

begin

lines.add( string(wndClassName));

lines.add( string(wndCaption));

lines.add('-------');

end;

result:=true;

end;

procedure TForm1.Button1Click(Sender: TObject);

var

hWnd:LongInt;

begin

memo1.Lines.Clear;

Memo1.Lines.Add(Edit1.Text+'         ');

hWnd:=FindWindow(nil,pchar(Edit1.Text));

if hWnd<>0 then

begin

EnumChildWindows(hWnd,@EnumChildWndProc,0);

end

else MessageBox(self.handle,'        ','  ',0);

end;

end.


컨트롤 손잡이가 있으면 우리는 당연히 마음대로 할 수 있다.예를 들어 SendMessage(hWnd, WM SETTEXT, 0, LongInt('하하!'))).컨트롤에 텍스트를 보낼 수 있습니다.다른 것은 다른 소식을 보낼 수도 있고 많은 일을 할 수도 있다.마지막으로 요약하자면 마지막 예제에서 창 컨트롤의 코드가 바뀌지 않았습니다. 메시지를 보낼 수 있습니다. 여기에서 함수를 호출하는 뒤에 코드를 추가할 수 있습니다. 예를 들어 위의 메시지는 핸들이 hWnd인 컨트롤의 TEXT를 하하!

좋은 웹페이지 즐겨찾기