-1

I have a problem after upgrading Delphi.

I have this code:

function EnumerateWindows(hWnd: HWND; lparam:LPARAM):Bool;
var
  ClassName, TheText : Array [0..255] of char;
  sName : string;
begin
  Application.ProcessMessages;
  GetClassNAme(hWnd,Classname, 255);
  if GetWindowText(hWnd, TheText, 255) > 0 then
  begin
    sName := StrPas(TheText);
    if pos('NOTEPAD',UpperCase(sName)) > 0 then
      postMessage(FindWindow(ClassName, TheText), WM_CLOSE, 0, 0);
  end;

procedure TForm1.Button1Click(Sender: TObject);
begin
  EnumWindows(@EnumerateWindows,0);
end;

In Delphi 7 the code above is working perfectly anytime there is NOTEPAD title and the program will kill its process but when I tried to use Selphi 10.3 the code above is not working. When i open Notepad it does not kill the process (there is no error in compiler). Is there any way to make the code work in Delphi 10.3?

Olivier
  • 13,283
  • 1
  • 8
  • 24
  • Please edit your question so that the code is at least compile without error. – fpiette Apr 11 '21 at 09:16
  • 3
    Your function EnumerateWindows MUST return a value. – fpiette Apr 11 '21 at 09:18
  • So if this is working some time in Delphi 7, that's just (bad!) luck. – Andreas Rejbrand Apr 11 '21 at 09:26
  • 3
    Every time you use a function in the Windows API you should read its [documentation](https://learn.microsoft.com/en-us/windows/win32/api/winuser/nf-winuser-enumwindows) carefully. In this case, the documentation says "EnumWindows continues until the last top-level window is enumerated or the callback function returns FALSE" and, for the [callback function](https://learn.microsoft.com/en-us/previous-versions/windows/desktop/legacy/ms633498(v=vs.85)), "To continue enumeration, the callback function must return TRUE; to stop enumeration, it must return FALSE." – Andreas Rejbrand Apr 11 '21 at 09:26
  • 3
    Also, you MUST use the `stdcall` calling convention on your callback. And you SHOULD not use `ProcessMessages` in the callback. – Andreas Rejbrand Apr 11 '21 at 09:27
  • And retrieving the class name is useless. – Olivier Apr 11 '21 at 09:29
  • 5
    This is literally the exact same code as in [this question](https://stackoverflow.com/questions/67025618/) posted yesterday under a different user account. – Remy Lebeau Apr 11 '21 at 09:41
  • I have another question. About the code above so if the program already sended a signal to close the process but the process isn't close (still running) is there anyway to make if condition for it ? I tried " if not postMessage(FindWindow(ClassName, TheText), WM_CLOSE, 0, 0) Then " But it isn't work – Mirana chan Apr 13 '21 at 05:25
  • @Miranachan For your new question, please do NOT use comment here but ask a new question. When you'll ask your question, saying "it doesn't work" is not enough. Say what happens and if nothing happens, say that. – fpiette Apr 13 '21 at 05:27
  • I am sorry i just think it still relate that's why but if i supposed to.. i Will – Mirana chan Apr 13 '21 at 05:28

2 Answers2

0

You have to either use

  • the types AnsiChar and AnsiString or
  • the functions GetClassNameW(), GetWindowTextW(), StrPasW() and FindWindowW()

...because Delphi 7 uses by default ANSI and Delphi 10 by default WIDE. You could also use Unicode in Delphi 7 right away by using all the WIDE functions and the types WideChar and WideString. Edit: the previous text is wrong as per Remy's comment.

Furthermore no process is killed: WM_CLOSE merely requests a window to be closed - there is neither a guarantee that the process really closes that window (i.e. for Notepad it can still result in a question dialog if you want to save your edits or not), nor that the process would end after closing that window - processes can run without windows. To kill a process you have to use TerminateProcess().

AmigoJack
  • 5,234
  • 1
  • 15
  • 31
  • 2
    The code is using the TCHAR version of the Win32 API functions, so they map to the ANSI `A` functions in Delphi 7, and to the Unicode `W` functions in Delphi 10. And the code is using the general `Char` type, which maps to `AnsiChar` in Delphi 7, and to `WideChar` in Delphi 10. So, this issue is not a problem with character type mismatches. – Remy Lebeau Apr 11 '21 at 09:41
0

i finally managed to fix it... when i added this

Result := True;

after if condition the code is working.