2012-03-01 4 views
6

Win7 64 비트에서 Delphi XE2 업데이트 3 또는 업데이트 4를 사용하십시오. 이 델파이에서 델파이 6Delphi XE2 EnumWindows가 제대로 작동하지 않습니다.

에 콜백 함수가 False를 반환 할 때까지 창을 처리 6 enumwindows를 작동하는 데 사용처럼

호출 enumwindows이 작동하지 않습니다. 설명서에서 수행해야하는 작업은 다음과 같습니다.

"열거를 계속하려면 콜백 함수가 TRUE를 반환하고 열거를 중지하려면 FALSE를 반환해야합니다." 다음과 같이

enumwindows에 전화 걸기 : 그것은 그래서 콜백 기능이 buttonclick 이벤트 전에 코드에 정의되어

function FindMyWindow(hWnd: HWND; lParam: LPARAM): boolean; stdcall; 
var TheText : array[0..150] of char; 
str : string; 
begin 
Result := True; 
GLBWindowHandle := 0; 
if (GetWindowText(hWnd, TheText, 150) <> 0) then 
    begin 
    str := TheText; 
    if str = 'Form1' then 
     begin 
     GLBWindowHandle := hWnd; 
     Result := False; 
     end 
    else 
     result := True; 
    end; 
end; 

그냥 명확하게하기 : 여기
procedure TForm1.Button1Click(Sender: TObject); 
begin 
    EnumWindows(@FindMyWindow,0); 
    if GLBWindowHandle <> 0 then begin 
    ShowMessage('found'); 
    end; 
end; 

가 콜백 함수입니다 인터페이스 섹션에서 정의 할 필요없이 컴파일러에서 찾을 수 있습니다. 거짓 결과가 반환되고 잘못된 결과가 반환되고 GLBWindowHandle이 후이 열거가 계속 델파이 XE2를 사용하여 실행하는 경우 GLBWindowHandle 제로

하지되면

이 델파이 6 창을 열거하여 실행하는 경우는 중지 항상 0입니다.

WTF? 누구나 열거 형이 문서 상태와 같이 멈추지 않고 델파이 6에서 사용되는 이유를 알 수있는 아이디어가 있습니까?

건배!

+0

'GLBWindowHandle'이 설정되고 재설정 된 것을 확인 했습니까? 아니면 설정되지 않았을 가능성이 있습니까? – hvd

+0

예, 설정되고 다시 설정됩니다. –

+0

32 비트 및 64 비트 용으로 컴파일하면 동일한 문제가 발생합니까? –

답변

12

이 선언은 올바르지 않습니다

function FindMyWindow(hWnd: HWND; lParam: LPARAM): boolean; stdcall; 

그것은해야한다 :

function FindMyWindow(hWnd: HWND; lParam: LPARAM): BOOL; stdcall; 

당신은 그들이 같은 일을하지 않기 때문에 BooleanBOOL을 섞어 조심하지해야합니다. 전자는 1 바이트이고 후자는 4 바이트입니다. EnumWindows이 기대하는 것과 콜백 기능이 전달하는 것 사이의 불일치로 인해 사용자는 관찰하는 동작을 유발할 수 있습니다.

The compiler can help find this error if you get out of the habit of using the @ operator before the function name when you call EnumWindows . If the function signature is compatible, the compiler will let you use it without @ . Using @ turns it into a generic pointer, and that's compatible with everything, so the error is masked by unnecessary syntax. In short, using @ to create function pointers should be considered a code smell.


토론

불행하게도 Windows.pas 헤더 번역과 같이 가장 도움이되지 않는 방식으로 EnumWindows를 정의 또한


은 롭 케네디는이 우수한 의견을 기여 :

function EnumWindows(lpEnumFunc: TFNWndEnumProc; lParam: LPARAM): BOOL; stdcall; 

이제 문제는 TFNWndEnumProc의 정의에 있습니다.

TFarProc = Pointer; 
TFNWndEnumProc = TFarProc; 

이 함수는 일반 포인터를 필요 때문에, 일반적인 포인터를 만들기 위해 @ 연산자를 사용하는이 것을 의미한다 : 그것은 정의됩니다. TFNWndEnumProc는 다음과 같이 선언 된 경우 :

TFNWndEnumProc = function(hWnd: HWND; lParam: LPARAM): BOOL; stdcall; 

다음 컴파일러 오류를 발견 할 수 있었을 것이다.

[DCC Error] Unit1.pas(38): E2010 Incompatible types: 'LongBool' and 'Boolean'

나는이 문제를 QC 및 TFarProc 사용을 중지하는 엠 바카 데로을 설득 내 운을 시험해 생각 :

type 
    TFNWndEnumProc = function(hWnd: HWND; lParam: LPARAM): BOOL; stdcall; 

function EnumWindows(lpEnumFunc: TFNWndEnumProc; 
    lParam: LPARAM): BOOL; stdcall; external 'user32'; 

function FindMyWindow(hWnd: HWND; lParam: LPARAM): Boolean; stdcall; 
begin 
    Result := False; 
end; 

.... 
EnumWindows(FindMyWindow, 0); 

컴파일러는 다음과 같은 오류와 EnumWindows에 대한 호출을 거부합니다.

+0

DOH! 데이빗 감사합니다. 이상하게도 Delphi 6에서 작동합니다. –

+0

D6에서 운이 좋았을 것입니다. 나는 행동이 바뀌는 정확한 이유를 찾기 위해 노력하는 한 멀리까지 가지 못했습니다. –

+0

컴파일러의 내부에는 이러한 겉보기에 이상한 효과가있는 여러 해가 걸렸습니다. 내 자신의 질문에 대한 내 자신의 대답을 참조하십시오. (저에게 거의 저 년 동안 곤란을 겪었습니다.) (http://stackoverflow.com/questions/1482699/zeroconf-bonjour-code-that-works-in-delphi-7-not- Working-in-2009) – Deltics