Thoughts on DLL problems encountered during development and Solutions

Source: Internet
Author: User

Recently I wrote a shell program in the company and called the DLL plug-in to embed the form into a panel in the exe. Many problems have been encountered, most of which have been solved, and several solutions have not been found yet, to be studied, I also hope that rich people who know the solution can share the research results.

The problems listed below and their solutions are only for programs I have written (DLL plug-ins embed form into a panel in exe) and their own solutions.

From the problems encountered, we can see that Delphi encapsulates too many things, and sometimes using APIs directly will have unexpected results.
Experience: All messages should be used for communication between DLL and exe.
First problem: the tab key and enter key are invalid in the form of DLL.
Original program:
// Frmdll is the form in DLL, and frmexe is the main form of EXE, the same below
// Why does the following code directly reference the form in EXE and reference the form in DLL? To facilitate reading, you only need to pass a handle.
// Panworkspace is a tpanel in EXE, And the form in dll must be embedded in it.
Frmdll. windowstate: = wsmaximized;
Frmdll. borderstyle: = bsnone;
Windows. setparent (frmdll. Handle, frmexe. panworkspace. Handle );

The tab and enter keys are invalid in the embedded form. Remove them.
Frmdll. borderstyle: = bsnone;
After normal, but I do not need the title, use the API to solve the problem
Frmdll. windowstate: = wsmaximized;
Setwindowlong (frmdll. Handle, gwl_style, getwindowlong (frmdll. Handle, gwl_style) and not (ws_caption or ws_thickframe ));
Windows. setparent (frmdll. Handle, frmexe. panworkspace. Handle );
Ws_caption and ws_thickframe indicate the title bar and border respectively, and the problem is solved.

Second problem: resize of DLL form
When the main form of EXE changes the size, the panel in the form will also change (panel. Align is set to alclient), but the embedded DLL form will not change. solution:
// The EXE window receives messages and changes the size of the child form.
// The fchildwindowlist is tlist, and the structure information list of child forms
Type
// Struct of some information in the subform
Pforminfo = ^ tforminfo;
Tforminfo = record
Handle: hwnd;
Parent: hwnd;
Style: hwnd;
End;

Tfrmexe = Class (tform)
Private
Procedure wmsize (VAR message: twmsize); message wm_size;
End;

Procedure tfrmexe. wmsize (VAR message: twmsize );
// Resize message
VaR
I: integer;
RC: trect;
Begin
Inherited;
If getwindowrect (panworkspace. Handle, RC) then
If assigned (fchildwindowlist) then
For I: = 0 to fchildwindowlist. Count-1 do
Setwindowpos (pforminfo (fchildwindowlist [I]). Handle, 0,
0, 0, RC. Right-RC. Left, RC. Bottom-RC. Top,
Swp_noactivate );
End;

Third problem: when the focus is on the form in the DLL, switch to another application and click the Application Object button on the taskbar.
When the focus is on the form in the DLL, switch to another application, and click the Application Object button on the taskbar. The main form of the EXE cannot be switched over. Switch to other programs, directly click the embedded DLL form and obtain the focus of the DLL form. It is found that the button of the Application object on the taskbar is pressed, but the EXE form is not mentioned at the beginning, when the DLL form gets the focus, the title bar of the EXE form turns gray, which does not meet the usage habits. Although it does not affect the use, I think it should be solved.

1. When the DLL form gets the focus, the title bar of the EXE form turns gray.
DLL form
Tfrmdll = Class (tform)
Private
Procedure wmactivate (VAR message: tmessage); message wm_activate;
End;

Procedure tfrmdll. wmactivate (VAR message: tmessage );
Begin
Inherited;
Sendmessage (frmexe. Handle, wm_ncactivate, INTEGER (true), 0 );
End;

2. Solution to the Focal Point Problem
Add the following unit to the Project
// ================================================ ==========================================================
// Unit name: apphandler
// Author: ysai
// Date: 2003-06-05
// Purpose: handle the focus issue
// History:
// ================================================ ==========================================================

Unit apphandler;

Interface

Uses
Windows, messages, sysutils, forms;

Implementation

VaR
Oldwproc: tfnwndproc;

Function newwndproc (
Handle: hwnd;
MSG: integer;
Wparam: longint;
Lparam: longint
): Longint; stdcall;
Begin
Result: = 0;
Case MSG
Wm_activateapp: // The Window embedded in the DLL in the main window will not focus on the program in advance
Begin
Case wparam
0: // The application loses focus
Begin
If assigned (application. mainform)
And (getwindowlong (application. Handle, gwl_exstyle)
And ws_ex_toolwindow = 0) then
Sendmessage (
Application. mainform. handle,
Wm_ncactivate,
INTEGER (false ),
0); // The title bar is dimmed when the focus is lost.
End;
1: // The application gets the focus
Begin
If assigned (application. mainform)
And (getwindowlong (application. Handle, gwl_exstyle)
And ws_ex_toolwindow = 0) then
Sendmessage (
Application. mainform. handle,
Wm_activate,
Wa_active,
1); // Note: set this parameter to 1, which will be used later.
End; // case wparam
End;
Result: = callwindowproc (oldwproc, handle, MSG, wparam, lparam );
End; // MSG: wm_activateapp
Else
Result: = callwindowproc (oldwproc, handle, MSG, wparam, lparam );
End; // case msg
End;

Initialization
// Replace application Message Processing
Oldwproc: = tfnwndproc (setwindowlong (application. Handle, gwl_wndproc,
Longint (@ newwndproc )));

Finalization
// Restore the Message Processing Process
If oldwproc <> nil then
Setwindowlong (application. Handle, gwl_wndproc, longint (oldwproc ));

End.
// The unit ends.

// Main Window of the EXE program
Tfrmexe = Class (tform)
Private
Procedure wmactivate (VAR message: tmessage); message wm_activate;
End;

Procedure tfrmexe. wmactivate (VAR message: tmessage );
// Exciting message. Message. lparam = 1 is sent from the oaapphandler unit, and the activation subwindow
VaR
Hwindow: hwnd;
Begin
Inherited;
If message. lparam = 1 then // if the message is sent by apphander, set the focus to the active subform.
Begin
Hwindow: = getactivechildwindowhandle; // This function obtains the activity subform.
// If there is a subwindow and there is no modal display form, move the focus to the subform.
If (hwindow> 0) and isw.wenabled (application. Handle) then
Windows. setforegroundwindow (hwindow );
End;
End;

Fourth problem: SpeedButton does not restore the plane when the mouse leaves in the DLL (it does not appear when showmodal is used) (unsolved)
When SpeedButton. Flat is set to true, the mouse in the DLL will not return to the flat state, but will not appear in the showmodal state. I don't know the reason, it should be because the message is not processed well, and I don't know if anyone has solved the problem.

Another focus issue: when the focus is on the DLL form, press Alt + TAB. No exe program exists in the program displayed in the dialog box!
The focus is on the EXE form. when the focus is on the DLL form, the icon of the EXE application will not appear with ALT + TAB. After switching to other tasks, you cannot switch back with ALT + TAB! This is a big bug and the cause is not found yet.
After reading it with spy ++, press the Alt + Tab key and the form receives a wm_cancelmode message. I think, since the focus is on the EXE form, you can see the icon, but I cannot see it on the DLL, so I can set the focus to the EXE when I receive this message?
The Code is as follows:
Tdllform = Class (tform)
Private
Procedure wmcancelmode (VAR message: tmessage); message wm_cancelmode;
End;

Procedure tdllform. wmcancelmode (VAR message: tmessage );
// Handle the problem of no application icon in the pop-up dialog box of ALT + Tab
Begin
Setforegroundwindow (exeform. Handle); // set the EXE form to the current focused form
End;

Now, no matter whether the focus is on the EXE form or the DLL form, there are application icons in the dialog box that appears by pressing Alt + TAB, but the difference is that, press Alt + TAB when the focus is on the EXE form. The next application is activated by default, while press Alt + TAB when the focus is on the DLL form. The first application is activated by default, that is, the application itself actually activates the EXE form.
Although I still don't get used to it very much, I finally got it out, and I will post it in the future with a good solution.

Hint problem (unsolved)
When the focus is on the form in DLL, moving the mouse over the control does not display the control's hint, and the application. the onhint event does not occur either. However, when you focus on the EXE form, you can move the cursor over the control in the DLL form to display the hint. cause not found :(

Alt + TAB solved, but there is still a problem with the keyboard and mouse operations.
When the focus is in the DLL, click other applications with the mouse, lose the focus, and press Alt + TAB, the damn application icon is gone, anxious ....

Thoughts on DLL problems encountered during development and Solutions

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.