Forum > Win32/64

Program doesn't close. PeekMessage always has WM_QUIT

<< < (2/3) > >>

440bx:

--- Quote from: wk on July 07, 2021, 05:04:24 pm ---Thanks for the hint.

Is this a bug in the LCL?

--- End quote ---
You're welcome and, as far as that being a bug, since I know nothing about the LCL, I am unable to answer that question.

engkin:
 A little more from the source code:

--- Code: Pascal  [+][-]window.onload = function(){var x1 = document.getElementById("main_content_section"); if (x1) { var x = document.getElementsByClassName("geshi");for (var i = 0; i < x.length; i++) { x[i].style.maxHeight='none'; x[i].style.height = Math.min(x[i].clientHeight+15,306)+'px'; x[i].style.resize = "vertical";}};} ---      while PeekMessage(AMessage, HWnd(nil), 0, 0, PM_REMOVE) do      begin        if AMessage.message = WM_QUIT then        begin          PostQuitMessage(AMessage.wParam);          break;        end;        TranslateMessage(@AMessage);        DispatchMessageW(@AMessage);      end;
Notice PM_REMOVE in the marked line. This code is part of AppProcessMessages which is called when you call ProcessMessages. So this is not the main loop, and exiting this procedure will not end the application.

I suspected something else is wrong in your code.

Here is the main loop:

--- Code: Pascal  [+][-]window.onload = function(){var x1 = document.getElementById("main_content_section"); if (x1) { var x = document.getElementsByClassName("geshi");for (var i = 0; i < x.length; i++) { x[i].style.maxHeight='none'; x[i].style.height = Math.min(x[i].clientHeight+15,306)+'px'; x[i].style.resize = "vertical";}};} ---procedure TApplication.RunLoop;begin  repeat    if CaptureExceptions then      try // run with try..except        HandleMessage;      except        HandleException(Self);      end    else      HandleMessage; // run without try..except  until Terminated;end;
The only way to exit is to have Terminated = True.

As in:

--- Code: Pascal  [+][-]window.onload = function(){var x1 = document.getElementById("main_content_section"); if (x1) { var x = document.getElementsByClassName("geshi");for (var i = 0; i < x.length; i++) { x[i].style.maxHeight='none'; x[i].style.height = Math.min(x[i].clientHeight+15,306)+'px'; x[i].style.resize = "vertical";}};} ---procedure TCustomForm.Close;..    if CloseQuery then..      case CloseAction of..        caFree:          begin            // if form is MainForm, then terminate the application..            if IsMainForm then              Application.Terminate..
Otherwise, RunLoop --> HandleMessage --> AppProcessMessages, repeat :)

440bx:

--- Quote from: engkin on July 08, 2021, 04:51:00 am --- A little more from the source code:

--- Code: Pascal  [+][-]window.onload = function(){var x1 = document.getElementById("main_content_section"); if (x1) { var x = document.getElementsByClassName("geshi");for (var i = 0; i < x.length; i++) { x[i].style.maxHeight='none'; x[i].style.height = Math.min(x[i].clientHeight+15,306)+'px'; x[i].style.resize = "vertical";}};} ---      while PeekMessage(AMessage, HWnd(nil), 0, 0, PM_REMOVE) do      begin        etc...      end;
Notice PM_REMOVE in the marked line.

--- End quote ---
Now, that makes sense (finally!)

engkin:

--- Quote from: 440bx on July 08, 2021, 05:05:43 am ---Now, that makes sense (finally!)

--- End quote ---

The code is more complicated than I showed, but I hope it is a bit more clear now.

wk:
I think we need to look at the complete code (line numbers are from the source):

--- Code: Pascal  [+][-]window.onload = function(){var x1 = document.getElementById("main_content_section"); if (x1) { var x = document.getElementsByClassName("geshi");for (var i = 0; i < x.length; i++) { x[i].style.maxHeight='none'; x[i].style.height = Math.min(x[i].clientHeight+15,306)+'px'; x[i].style.resize = "vertical";}};} ---362 procedure TWin32WidgetSet.AppProcessMessages;363     var364       AMessage: TMsg;365       retVal, index: dword;366       pHandles: Windows.LPHANDLE;367     368         procedure CallWaitHandler;369         begin370           FWaitHandlers[index].OnEvent(FWaitHandlers[index].UserData, 0);371         end;372     373     begin374       repeat375         if FPendingWaitHandlerIndex >= 0 then376         begin377           index := FPendingWaitHandlerIndex;378           FPendingWaitHandlerIndex := -1;379           CallWaitHandler;380         end;381     {$ifdef DEBUG_ASYNCEVENTS}382         if Length(FWaitHandles) > 0 then383           DebugLn('[ProcessMessages] WaitHandleCount=', IntToStr(FWaitHandleCount),384             ', WaitHandle[0]=', IntToHex(FWaitHandles[0], 8));385     {$endif}386         if FWaitHandleCount > 0 then387           pHandles := @FWaitHandles[0]388         else389           pHandles := nil;390         retVal := Windows.MsgWaitForMultipleObjects(FWaitHandleCount,391           pHandles, False, 0, QS_ALLINPUT);392         if (retVal < WAIT_OBJECT_0 + FWaitHandleCount) then393         begin394           index := retVal-WAIT_OBJECT_0;395           CallWaitHandler;396         end else397         if retVal = WAIT_OBJECT_0 + FWaitHandleCount then398         begin399           while PeekMessage(AMessage, HWnd(nil), 0, 0, PM_REMOVE) do400           begin401             if AMessage.message = WM_QUIT then402             begin403               PostQuitMessage(AMessage.wParam);404               break;405             end;406             // Handle MDI form accelerators407             if Assigned(Application) and408                Assigned(Application.MainForm) and409                (Application.MainForm.FormStyle=fsMDIForm) and410                TranslateMDISysAccel(Win32WidgetSet.MDIClientHandle, @AMessage)411             then begin412               // handled by TranslateMDISysAccel413             end else begin414               TranslateMessage(@AMessage);415               DispatchMessageW(@AMessage);416             end;417           end;418         end else419         if retVal = WAIT_TIMEOUT then420         begin421           // check for pending to-be synchronized methods422           CheckSynchronize;423           CheckPipeEvents;424           break;425         end else426         if retVal = $FFFFFFFF then427         begin428           DebugLn('[TWin32WidgetSet.AppProcessMessages] MsgWaitForMultipleObjects returned: ', IntToStr(GetLastError));429           break;430         end;431       until false;432     end; 
When the program closes, debugger gets to line 404. The 'break' jumps out of 'while PeekMessage' (line 399) to the outer 'repeat until false' to line 375. This repeats forever. I hope the highlights in the code help.

Can I maybe catch the 'PostQuitMessage' in the main form or somewhere else?

Navigation

[0] Message Index

[#] Next page

[*] Previous page

Go to full version