Q&A

  • - class name...
1. EnumWindowsProc에서 실행되어 있는 윈도우들의 핸들을 구하고

2. GetClassName에서 Class이름을 구하려고 하는데요...



showmesage(GetClassName(Handle))하면

Exploer - 'IEFram', 메모장 - 'Notepad'식으로 제가 원하는 값이지만.

일반 응용프로그램(델파이나 다른 비쥬얼 툴로 작성한 것)들은 폼이름을 MainForm으로

해도 TApplication이 출력됩니다..

제가 원하는 것은 TApplication이 아니라 TMainForm과 같은 값이 출력되는 겁니다.



spy에서 보면 잘 나오는데..GetClassName에서는 TApplication만 출력이 되는군요...



제 소스는 다음과 같습니다......

-----------------------------------------------------------------------------

function EnumWindowsProc(Wnd: HWND; lb: TListbox): BOOL; stdcall;

var

caption: Array [0..128] of Char;

begin

Result := True;

if //skip invisible windows

IsWindowVisible(Wnd) and

//only process truly top-level windows. GetWindowLong must be used, not GetParent

((GetWindowLong(Wnd, GWL_HWNDPARENT) = 0) or

(HWND(GetWindowLong(Wnd, GWL_HWNDPARENT)) = GetDesktopWindow)) and

//skip WS_EX_TOOLWINDOW windows

((GetWindowLong(Wnd, GWL_EXSTYLE) and WS_EX_TOOLWINDOW) = 0) then

begin

SendMessage(Wnd, WM_GETTEXT, Sizeof(caption), integer(@caption));

lb.Items.AddObject(caption, TObject(Wnd));

end;

end;



function GetClassName(Wnd: HWnd): string;

var

Buf : array[0..128] of Char;

begin

if ((IsWindow(Wnd)) and (Windows.GetClassNameA(Wnd, Buf, SizeOf(Buf)) > 0)) then

Result := Buf

else

Result := '';

end;





Procedure TMainForm.FormCreate(Sender: TObject);

var

WinHandle : THandle;

fRect : TRect;

i : Integer;

begin

ListBox1.Clear;

EnumWindows(@EnumWindowsProc, Integer(ListBox1));



for i := 0 to ListBox1.Items.Count-1 do

begin

WinHandle := HWND(ListBox1.Items.Objects[i]);



ShowMessage(GetClassName(WinHandle));



// WinHandle := FindWindow('CabsinetWClass',nil);

// if WinHandle <= 0 then

// WinHandle := FindWindow('IEFrame',nil);



end; // end for

end;



4  COMMENTS
  • Profile
    최용일 2001.09.08 01:10
    안녕하세요. 최용일입니다.



    TApplication으로 나오는 것이 정상입니다. 델파이 프로젝트를 만들때 메인 윈도우는



    TApplication이고 이것의 서브윈도우로 메인폼을 비롯한 여러가지 폼들이 들어가게



    됩니다. 이건 스파이프로그램으로 보셨다면 아실텐데요... TApplication의 핸들을



    찾으셨다면 GetWindowEx를 이용해서 메인폼의 핸들을 찾으실 수 있습니다.



    ^^ 항상 즐코하세요...



    나그네... wrote:

    > 1. EnumWindowsProc에서 실행되어 있는 윈도우들의 핸들을 구하고

    > 2. GetClassName에서 Class이름을 구하려고 하는데요...

    >

    > showmesage(GetClassName(Handle))하면

    > Exploer - 'IEFram', 메모장 - 'Notepad'식으로 제가 원하는 값이지만.

    > 일반 응용프로그램(델파이나 다른 비쥬얼 툴로 작성한 것)들은 폼이름을 MainForm으로

    > 해도 TApplication이 출력됩니다..

    > 제가 원하는 것은 TApplication이 아니라 TMainForm과 같은 값이 출력되는 겁니다.

    >

    > spy에서 보면 잘 나오는데..GetClassName에서는 TApplication만 출력이 되는군요...

    >

    > 제 소스는 다음과 같습니다......

    > -----------------------------------------------------------------------------

    > function EnumWindowsProc(Wnd: HWND; lb: TListbox): BOOL; stdcall;

    > var

    > caption: Array [0..128] of Char;

    > begin

    > Result := True;

    > if //skip invisible windows

    > IsWindowVisible(Wnd) and

    > //only process truly top-level windows. GetWindowLong must be used, not GetParent

    > ((GetWindowLong(Wnd, GWL_HWNDPARENT) = 0) or

    > (HWND(GetWindowLong(Wnd, GWL_HWNDPARENT)) = GetDesktopWindow)) and

    > //skip WS_EX_TOOLWINDOW windows

    > ((GetWindowLong(Wnd, GWL_EXSTYLE) and WS_EX_TOOLWINDOW) = 0) then

    > begin

    > SendMessage(Wnd, WM_GETTEXT, Sizeof(caption), integer(@caption));

    > lb.Items.AddObject(caption, TObject(Wnd));

    > end;

    > end;

    >

    > function GetClassName(Wnd: HWnd): string;

    > var

    > Buf : array[0..128] of Char;

    > begin

    > if ((IsWindow(Wnd)) and (Windows.GetClassNameA(Wnd, Buf, SizeOf(Buf)) > 0)) then

    > Result := Buf

    > else

    > Result := '';

    > end;

    >

    >

    > Procedure TMainForm.FormCreate(Sender: TObject);

    > var

    > WinHandle : THandle;

    > fRect : TRect;

    > i : Integer;

    > begin

    > ListBox1.Clear;

    > EnumWindows(@EnumWindowsProc, Integer(ListBox1));

    >

    > for i := 0 to ListBox1.Items.Count-1 do

    > begin

    > WinHandle := HWND(ListBox1.Items.Objects[i]);

    >

    > ShowMessage(GetClassName(WinHandle));

    >

    > // WinHandle := FindWindow('CabsinetWClass',nil);

    > // if WinHandle <= 0 then

    > // WinHandle := FindWindow('IEFrame',nil);

    >

    > end; // end for

    > end;

    >

  • Profile
    나그네... 2001.09.08 02:28
    최용일님 답변 감사합니다...



    근데 GetWindowEx란 API가 있나요??



    혹시 FindWindowEx아닌가요??



    만약 그렇다면 아래 소스에서는 FindWindow를 쓰지 않고 ClassName를 구했는데..



    FindWindowEx를 쓰려면 어떻게 해야 하는지요??



    부탁만 드리니 참 죄송합니다......





    최용일 wrote:

    > 안녕하세요. 최용일입니다.

    >

    > TApplication으로 나오는 것이 정상입니다. 델파이 프로젝트를 만들때 메인 윈도우는

    >

    > TApplication이고 이것의 서브윈도우로 메인폼을 비롯한 여러가지 폼들이 들어가게

    >

    > 됩니다. 이건 스파이프로그램으로 보셨다면 아실텐데요... TApplication의 핸들을

    >

    > 찾으셨다면 GetWindowEx를 이용해서 메인폼의 핸들을 찾으실 수 있습니다.

    >

    > ^^ 항상 즐코하세요...

    >

    > 나그네... wrote:

    > > 1. EnumWindowsProc에서 실행되어 있는 윈도우들의 핸들을 구하고

    > > 2. GetClassName에서 Class이름을 구하려고 하는데요...

    > >

    > > showmesage(GetClassName(Handle))하면

    > > Exploer - 'IEFram', 메모장 - 'Notepad'식으로 제가 원하는 값이지만.

    > > 일반 응용프로그램(델파이나 다른 비쥬얼 툴로 작성한 것)들은 폼이름을 MainForm으로

    > > 해도 TApplication이 출력됩니다..

    > > 제가 원하는 것은 TApplication이 아니라 TMainForm과 같은 값이 출력되는 겁니다.

    > >

    > > spy에서 보면 잘 나오는데..GetClassName에서는 TApplication만 출력이 되는군요...

    > >

    > > 제 소스는 다음과 같습니다......

    > > -----------------------------------------------------------------------------

    > > function EnumWindowsProc(Wnd: HWND; lb: TListbox): BOOL; stdcall;

    > > var

    > > caption: Array [0..128] of Char;

    > > begin

    > > Result := True;

    > > if //skip invisible windows

    > > IsWindowVisible(Wnd) and

    > > //only process truly top-level windows. GetWindowLong must be used, not GetParent

    > > ((GetWindowLong(Wnd, GWL_HWNDPARENT) = 0) or

    > > (HWND(GetWindowLong(Wnd, GWL_HWNDPARENT)) = GetDesktopWindow)) and

    > > //skip WS_EX_TOOLWINDOW windows

    > > ((GetWindowLong(Wnd, GWL_EXSTYLE) and WS_EX_TOOLWINDOW) = 0) then

    > > begin

    > > SendMessage(Wnd, WM_GETTEXT, Sizeof(caption), integer(@caption));

    > > lb.Items.AddObject(caption, TObject(Wnd));

    > > end;

    > > end;

    > >

    > > function GetClassName(Wnd: HWnd): string;

    > > var

    > > Buf : array[0..128] of Char;

    > > begin

    > > if ((IsWindow(Wnd)) and (Windows.GetClassNameA(Wnd, Buf, SizeOf(Buf)) > 0)) then

    > > Result := Buf

    > > else

    > > Result := '';

    > > end;

    > >

    > >

    > > Procedure TMainForm.FormCreate(Sender: TObject);

    > > var

    > > WinHandle : THandle;

    > > fRect : TRect;

    > > i : Integer;

    > > begin

    > > ListBox1.Clear;

    > > EnumWindows(@EnumWindowsProc, Integer(ListBox1));

    > >

    > > for i := 0 to ListBox1.Items.Count-1 do

    > > begin

    > > WinHandle := HWND(ListBox1.Items.Objects[i]);

    > >

    > > ShowMessage(GetClassName(WinHandle));

    > >

    > > // WinHandle := FindWindow('CabsinetWClass',nil);

    > > // if WinHandle <= 0 then

    > > // WinHandle := FindWindow('IEFrame',nil);

    > >

    > > end; // end for

    > > end;

    > >

  • Profile
    최용일 2001.09.08 11:46
    GetWindowEx가 아니라 FindWindowEx가 맞구요...



    폼들이 TApplication의 하위윈도우로 들어간다고 했는데 제가 잘못알고 말했군요...



    TApplication과 메인폼은 같은 레벨이네요... 죄송합니다...



    콜백함수를 보니까 콜백함수에서 리스트박스에 저장하는 윈도우들은 작업표시줄에 들어



    갈 수 있는 윈도우들인거 같습니다. 델파이 프로그램은 TApplication만 작업표시줄에



    들어갑니다. 메인폼은 님이 작성하신 콜백함수의 조건에 맞지 않기 때문에 리스트박스에



    들어가지 않네요... 참고로 스파이프로그램에서는 조건을 정하지 않고 모든 윈도우들을



    다 보여줍니다...



    ^^ 항상 즐코하세요...



    나그네... wrote:

    > 최용일님 답변 감사합니다...

    >

    > 근데 GetWindowEx란 API가 있나요??

    >

    > 혹시 FindWindowEx아닌가요??

    >

    > 만약 그렇다면 아래 소스에서는 FindWindow를 쓰지 않고 ClassName를 구했는데..

    >

    > FindWindowEx를 쓰려면 어떻게 해야 하는지요??

    >

    > 부탁만 드리니 참 죄송합니다......

    >

    >

    > 최용일 wrote:

    > > 안녕하세요. 최용일입니다.

    > >

    > > TApplication으로 나오는 것이 정상입니다. 델파이 프로젝트를 만들때 메인 윈도우는

    > >

    > > TApplication이고 이것의 서브윈도우로 메인폼을 비롯한 여러가지 폼들이 들어가게

    > >

    > > 됩니다. 이건 스파이프로그램으로 보셨다면 아실텐데요... TApplication의 핸들을

    > >

    > > 찾으셨다면 GetWindowEx를 이용해서 메인폼의 핸들을 찾으실 수 있습니다.

    > >

    > > ^^ 항상 즐코하세요...

    > >

    > > 나그네... wrote:

    > > > 1. EnumWindowsProc에서 실행되어 있는 윈도우들의 핸들을 구하고

    > > > 2. GetClassName에서 Class이름을 구하려고 하는데요...

    > > >

    > > > showmesage(GetClassName(Handle))하면

    > > > Exploer - 'IEFram', 메모장 - 'Notepad'식으로 제가 원하는 값이지만.

    > > > 일반 응용프로그램(델파이나 다른 비쥬얼 툴로 작성한 것)들은 폼이름을 MainForm으로

    > > > 해도 TApplication이 출력됩니다..

    > > > 제가 원하는 것은 TApplication이 아니라 TMainForm과 같은 값이 출력되는 겁니다.

    > > >

    > > > spy에서 보면 잘 나오는데..GetClassName에서는 TApplication만 출력이 되는군요...

    > > >

    > > > 제 소스는 다음과 같습니다......

    > > > -----------------------------------------------------------------------------

    > > > function EnumWindowsProc(Wnd: HWND; lb: TListbox): BOOL; stdcall;

    > > > var

    > > > caption: Array [0..128] of Char;

    > > > begin

    > > > Result := True;

    > > > if //skip invisible windows

    > > > IsWindowVisible(Wnd) and

    > > > //only process truly top-level windows. GetWindowLong must be used, not GetParent

    > > > ((GetWindowLong(Wnd, GWL_HWNDPARENT) = 0) or

    > > > (HWND(GetWindowLong(Wnd, GWL_HWNDPARENT)) = GetDesktopWindow)) and

    > > > //skip WS_EX_TOOLWINDOW windows

    > > > ((GetWindowLong(Wnd, GWL_EXSTYLE) and WS_EX_TOOLWINDOW) = 0) then

    > > > begin

    > > > SendMessage(Wnd, WM_GETTEXT, Sizeof(caption), integer(@caption));

    > > > lb.Items.AddObject(caption, TObject(Wnd));

    > > > end;

    > > > end;

    > > >

    > > > function GetClassName(Wnd: HWnd): string;

    > > > var

    > > > Buf : array[0..128] of Char;

    > > > begin

    > > > if ((IsWindow(Wnd)) and (Windows.GetClassNameA(Wnd, Buf, SizeOf(Buf)) > 0)) then

    > > > Result := Buf

    > > > else

    > > > Result := '';

    > > > end;

    > > >

    > > >

    > > > Procedure TMainForm.FormCreate(Sender: TObject);

    > > > var

    > > > WinHandle : THandle;

    > > > fRect : TRect;

    > > > i : Integer;

    > > > begin

    > > > ListBox1.Clear;

    > > > EnumWindows(@EnumWindowsProc, Integer(ListBox1));

    > > >

    > > > for i := 0 to ListBox1.Items.Count-1 do

    > > > begin

    > > > WinHandle := HWND(ListBox1.Items.Objects[i]);

    > > >

    > > > ShowMessage(GetClassName(WinHandle));

    > > >

    > > > // WinHandle := FindWindow('CabsinetWClass',nil);

    > > > // if WinHandle <= 0 then

    > > > // WinHandle := FindWindow('IEFrame',nil);

    > > >

    > > > end; // end for

    > > > end;

    > > >

  • Profile
    Ziker 2001.09.08 01:06
    안녕하세요...



    Application.Components[i].ClassType



    으로 한번 찾아 보세욤...



    그럼..





    나그네... wrote:

    > 1. EnumWindowsProc에서 실행되어 있는 윈도우들의 핸들을 구하고

    > 2. GetClassName에서 Class이름을 구하려고 하는데요...

    >

    > showmesage(GetClassName(Handle))하면

    > Exploer - 'IEFram', 메모장 - 'Notepad'식으로 제가 원하는 값이지만.

    > 일반 응용프로그램(델파이나 다른 비쥬얼 툴로 작성한 것)들은 폼이름을 MainForm으로

    > 해도 TApplication이 출력됩니다..

    > 제가 원하는 것은 TApplication이 아니라 TMainForm과 같은 값이 출력되는 겁니다.

    >

    > spy에서 보면 잘 나오는데..GetClassName에서는 TApplication만 출력이 되는군요...

    >

    > 제 소스는 다음과 같습니다......

    > -----------------------------------------------------------------------------

    > function EnumWindowsProc(Wnd: HWND; lb: TListbox): BOOL; stdcall;

    > var

    > caption: Array [0..128] of Char;

    > begin

    > Result := True;

    > if //skip invisible windows

    > IsWindowVisible(Wnd) and

    > //only process truly top-level windows. GetWindowLong must be used, not GetParent

    > ((GetWindowLong(Wnd, GWL_HWNDPARENT) = 0) or

    > (HWND(GetWindowLong(Wnd, GWL_HWNDPARENT)) = GetDesktopWindow)) and

    > //skip WS_EX_TOOLWINDOW windows

    > ((GetWindowLong(Wnd, GWL_EXSTYLE) and WS_EX_TOOLWINDOW) = 0) then

    > begin

    > SendMessage(Wnd, WM_GETTEXT, Sizeof(caption), integer(@caption));

    > lb.Items.AddObject(caption, TObject(Wnd));

    > end;

    > end;

    >

    > function GetClassName(Wnd: HWnd): string;

    > var

    > Buf : array[0..128] of Char;

    > begin

    > if ((IsWindow(Wnd)) and (Windows.GetClassNameA(Wnd, Buf, SizeOf(Buf)) > 0)) then

    > Result := Buf

    > else

    > Result := '';

    > end;

    >

    >

    > Procedure TMainForm.FormCreate(Sender: TObject);

    > var

    > WinHandle : THandle;

    > fRect : TRect;

    > i : Integer;

    > begin

    > ListBox1.Clear;

    > EnumWindows(@EnumWindowsProc, Integer(ListBox1));

    >

    > for i := 0 to ListBox1.Items.Count-1 do

    > begin

    > WinHandle := HWND(ListBox1.Items.Objects[i]);

    >

    > ShowMessage(GetClassName(WinHandle));

    >

    > // WinHandle := FindWindow('CabsinetWClass',nil);

    > // if WinHandle <= 0 then

    > // WinHandle := FindWindow('IEFrame',nil);

    >

    > end; // end for

    > end;

    >