Create a third plug-in series for source insight-Build a custom code framework for plug-in Software

Source: Internet
Author: User


The previous article introduced how "tabsiplus" injects code. This article describes how to build the most important part of a plug-in software, that is, the custom code for its extended functions. As mentioned above, due to Windows Process Management restrictions, extended code must be mounted to the process space of the program in the form of a dynamic link library, using the method described in the previous article, you can start a thread by creating a remote thread to load our custom dynamic link library. Now let's take a look at how this dynamic link library is implemented.

First, this is a dynamic link library. Considering that there are a large number of interface operations in the extended functions, we chose to support MFC and also provide an export function named "initfunc, it is called by a remote thread started in the program to initialize the plug-in Dynamic Link Library. The prototype of this export function is as follows:
Typedef DWORD (winapi * PFn )();
No parameter, but a return value indicates whether the initialization is successful. Now, you can use the wizard of Visual C ++ to generate a framework that supports the dynamic link library of MFC, and manually add an export function named "initfunc". If you do not know how to do this, you can stop reading this article because it may be useless to you.

In the generated code, MFC encapsulates dllmain, so there is a cxxxapp class. XXX is the same as the name of your dynamic link library. tabsiplus uses ctabsiplusapp, there are three important points to note: one is ctabsiplusapp: initinstance (), the other is ctabsiplusapp: exitinstance (), and the other is our export function "initfunc ". When loadlibrary () in the remote thread calls our custom dynamic link library, ctabsiplusapp: initinstance () is called. When freelibrary () is called, ctabsiplusapp: exitinstance () there are also two function calls, of course, that is, the constructor and destructor of the ctabsiplusapp class. Some initialization code can also be completed in the constructor, however, this is not recommended because if loadlibrary () fails because of a constructor trigger exception, the subsequent destructor will not be called because the constructor has not completed object construction, at the same time, because loadlibrary () fails, the call Branch of freelibrary () is not executed, so the ctabsiplusapp: exitinstance () is not called, which causes an exception in resource release.

Obviously, the call of ctabsiplusapp: initinstance () occurs before the call of the initfunc function. Therefore, you must control the sequence before the initialization code. Ctabsiplusapp: Specifies the code for Resource Initialization in initinstance (). For example, if you create a file tag bar window and hook the message in the "source insight" window, the code for managing these messages can be arranged in the initfunc function. Note that our plug-in code is attached to the "source insight" process in the form of a dynamic link library, so it does not have a message loop and the UI system of all windows cannot work normally, there are two solutions: one is to manually add a message loop after the initfunc function creates a window. for how to implement this, refer to the Windows SDK programming method; the other method is not to put the main work in initfunc, but to create a local thread in the initfunc function and put the troublesome things of window UI in this thread for processing, in this way, we can use the message loop of this thread to make the window UI system work. Another advantage is that the initfunc function can return immediately, the Host Program that loads the plug-in can also get the loading information of the plug-in time to arrange the next loading action (that is, calling createremotethread () according to the situation ()), at the same time, the memory allocated in the program to be hung can be released in a timely manner. Tabsiplus is the second method. The following is the initfunc function implementation of tabsiplus. Of course, some code is saved, and the main core is a line:

DWORD winapi initfunc ()
{
// Other initialization operations
G_ptabwnduithread = (ctabwnduithread *) afxbeginthread (runtime_class (ctabwnduithread), thread_priority_normal, 0, 0, null );
// Other operations

Return (g_ptabwnduithread! = NULL );
}

Create a tag bar window in the initinstance () function of the ctabwnduithread class and hook the messages in the related window in "Source insight:

Bool ctabwnduithread: initinstance ()
{
Afx_manage_state (afxgetstaticmodulestate ());

G_psiframewnd = new csiframewnd (); // cwnd: fromhandle (hdevstudiownd );
G_psiframewnd-> attach (hwndsiframe); // hook Si Main Window

Hwnd hmdiwnd = g_psiframewnd-> getmdiclientwnd ();

// Uint uthressid = getcurrentthreadid ();
// Create the tabs window
M_ptabbarwnd = new ctabbarswnd ();
M_ptabbarwnd-> Create (cwnd: fromhandle (g_psiframewnd-> getsafehwnd ()),
Rbs_bandborders | rbs_autosize | rbs_fixedorder | rbs_dblclktoggle,
Ws_child | ws_visible | ws_clipchildren | ws_clipsiblings | cbrs_top | cbrs_size_fixed, afx_idw_rebar );

M_pmainwnd = m_ptabbarwnd; // This is very important, otherwise this thread cannot exit
G_psiframewnd-> settabbarwnd (m_ptabbarwnd-> getsafehwnd ());
G_mdichildmng.settabbarwnd (m_ptabbarwnd-> getsafehwnd ());

M_ptabbarwnd-> setwindowpos (cwnd: fromhandle (hmdiwnd)-> getwindow (gw_hwndprev), 0, 0, 0, 0, swp_nomove | swp_nosize );

G_psimdiclientwnd = new csimdiwnd ();
G_psimdiclientwnd-> settabbarwnd (m_ptabbarwnd-> getsafehwnd ());
Debugtracing (gndbglevelnormaldebug, _ T ("MDI client attach ..."));
G_psimdiclientwnd-> attach (hmdiwnd );
Debugtracing (gndbglevelnormaldebug, _ T ("MDI client Enum ..."));
G_psimdiclientwnd-> enummdichildwnd (g_mdichildmng, true );
Debugtracing (gndbglevelnormaldebug, _ T ("MDI client Enum end (% d)"), g_mdichildmng.getchildcount ());
Pglobalactivesiwindow = g_mdichildmng.lookupmdichild (g_psimdiclientwnd-> mdigetactive (null ));
G_psimdiclientwnd-> setmanaging (true );

Return true;
}

Is it like the cxxxapp: initinstance () function in the MFC program of the Standard Single-document structure? Especially for m_pmainwnd? Assigning values to m_pmainwnd is actually very important. Otherwise, the thread will exit directly. Another benefit to assigning values to m_pmainwnd is that closing the m_ptabbarwnd window will abort the ctabwnduithread thread, this is the same as the result in the MFC program of the standard single document structure.

Ctabwnduithread: Many of the initinstance () functions hook the internal windows of "Source insight". How does tabsiplus get the handles of these windows, how to associate messages between them? See article 4: plug-in series 4 for source insight-Analysis of "Source insight"

Source insignt file tag plug-in: tabsiplus:
Http://blog.csdn.net/orbit/

Related Article

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.