Watch, Follow, &
Connect with Us
Public Report
Report From: Delphi-BCB/VCL/Core VCL Classes/TApplication    [ Add a report in this area ]  
Report #:  85705   Status: Open
THintWindow descendent, HintMouseThread and DLL
Project:  Delphi Build #:  14.0.3593.25826
Version:    14.0 Submitted By:   Soeren Muehlbauer
Report Type:  Basic functionality failure Date Reported:  6/25/2010 7:02:02 AM
Severity:    Commonly encountered problem Last Updated: 3/20/2012 2:24:39 AM
Platform:    All platforms Internal Tracking #:   277683
Resolution: None (Resolution Comments) Resolved in Build: : None
Duplicate of:  None
Voting and Rating
Overall Rating: No Ratings Yet
0.00 out of 5
Total Votes: None
Description
An exception is raised when unloading a dll which contains a form and showed a hint.
Steps to Reproduce:
1. Create a dll which contains a form
2. Derive a custom hint window from THintWindow
3. Override the ActivateHint method
4. When the given Rect is empty call Application.CancelHint (this is important)

5. Load this dll dynamically
6. Execute the form
7. Unload the dll


The created MouseHintThread is sometimes active on unloading the dll. This causes a exception.

Workarounds
In procedure TApplication.ActivateHint(CursorPos: TPoint)

after the call to FHintWindow.ActivateHintData place the follwing code:

if FHintControl = nil
then begin
  UnhookHintHooks;
  Exit;
end;

In procedure Forms.HookHintHooks

change

  if not Application.FRunning then

to

  if not (Application.FRunning and Assigned(Application.FHintControl))  then
Attachment
EMBTTest.zip
Comments

Tomohiro Takahashi at 6/26/2010 8:04:01 AM -
Could you please attach sample projects(.dll and .exe) to reproduce your issue?

Soeren Muehlbauer at 6/28/2010 2:06:24 AM -
Its a very simple setup. Please find the attached files. When using the exe and dll open a parallel task manager. Add the threads column. When using Delphi itself open the thread watch window.

Press the button and move the mouse over the listview. Move the mouse out of the window. Do this so long as the thread count is 2. Then close the window (with thread count = 2). You will get a AV immediately.

Tomohiro Takahashi at 6/28/2010 6:41:14 PM -
When I run your application and click Button1 on my PC, MainForm's icon and Form1's icon are on Taskbar.
In addition, the Form1's icon is invalid(empty icon).
Is it your expected behavior?

Soeren Muehlbauer at 6/28/2010 9:18:57 PM -
Thats expected behavior when creating forms from a dll. It knows nothing about the (main) application object in the exe. By modifying TShowFormProc to

type
  TShowFormProc = procedure(const aAppHandle: THandle); stdcall;

and the dll source to

procedure ShowTheForm(const aAppHandle: THandle); stdcall;
var
  Hdl: HWND;
begin
  Hdl := Application.Handle;
  Application.Handle := aAppHandle;
  try
    with TForm1.Create(nil) do
    begin
      ShowModal;
      Free;
    end;
  finally
    Application.Handle := Hdl;
  end;
end;

In the exe you would call:

    @ShowFormProc := GetProcAddress(DllHandle, 'ShowTheForm');
    if Assigned(ShowFormProc)
    then ShowFormProc(Application.Handle);

In this case you will not get the second taskbar item.

Server Response from: ETNACODE01