Using hook functions dynamic Chinese foreign language menu

zhaozj2021-02-16  53

Using hook functions dynamic Chinese foreign language menu

Yangshan River

Introduction Current, English version of the application, generally has a Chinese version on the Chinese platform. This has a localized version of the Chinese language, and there are also third-party suppliers in China or foreign suppliers in China to launch Chinese versions for market needs. The way the latter is divided into kernel and plug-in. Due to the series of problems such as copyright, the source code design is not necessarily compatible with Chinese, so few people are used. Therefore, in today's China, all the ways from Chinese Star to Quartet Cubes will use plug-in Chinese. The plug-in Hanhua can also use a variety of ways, and depending on the language of the operating system platform (Simplified Chinese, Traditional Chinese, English, etc.), the degree of Chinese is also different. The author has a slightly well-appreciated, through research, and presents a method of hanging Chinese in the Chinese operating system platform and is discussed by colleagues in interested.

Prior to this, we must clear a few related concepts.

two. "Hook" of Windows

Unlike the old qualification operating system DOS on the PC, the programming of Windows must comply with Microsoft to give you the "Game Rules": establish a window, establish a message loop for the window, and complete a variety of work in window functions In short: Must listen to Microsoft's arrangements, otherwise your app is not compatible, it is difficult to guarantee compatibility. In fact, Microsoft left a lot of "back door", "hook function" is one of the means.

The so-called "hook function", that is, a means of reserving the application in the message processing mechanism, the application can use it to install a subroutine for a specific message, so that we can monitor before reaching the destination in some messages. Or modify them. Windows provides 7 hook functions, 13 of Windows 95. In view of the development trend of the operating system, it is not discussed by Windows3.x. He will refer to Windows 95 (referred to as Win95) when Windows is mentioned. Methods for installing and removing these hook functions are the same, Win95 uses the following API:

HHOOK SETWINDOWSHOKEX (// Installation

INT IDHOOK, / / ​​Type to install the hook

HookProc lpfn, // hook function address (callback function)

Hinstance HMOD, // The example handle of the program where the hook function is located

DWORD DWTHREADID / / The ID of the thread to install the hook

);

A hook function chain is formed when some applications install the same class hook. The installation function returns the filter function instance handle that specifies the hook type. .

Bool unhookwindowshookex (// Remove

HHOOK HHK / / Handle of the hook function to be removed

);

The hook type under Win95 is:

Wh_callwndproc // Window Process Hook

Wh_callwndprocret // message has been processed in the window process

// After receiving the hook function of these messages

WH_CBT / / computer-based training hook

Wh_debug // Check the wrong hook

Wh_ForeGroundIdle // Front desk free window hook

Wh_getMessage // Receive the hook of delivery message

Wh_journalplayback // Playback Previous Enter Message Hook

WH_JOURNALRECORD / / Record Enter Message Hook

Wh_keyboard // Keyboard hook

Wh_mouse // mouse hook

Message hooks such as WH_MSGFILTER / / dialog

WH_SYSMSGFILTER / / System Message Hook

WH_SHELL / / hook hook

The hook function is typically placed in the DLL such that it can be accessed by each process within the system, so the third parameter in the mounting hook API should be the handle of the DLL module.

In these types of hooks, the hooks of the Wh_getMessage type can access the information of our access window. The hook intercepts all messages obtained from the application queue through the standard message loop acquisition function. These messages contain a lot of valuable data, such as window handles, etc. Under normal circumstances, the hook function will be called regardless of whether the associated process is active, it will reduce the performance of the system, and even the system is stable. Therefore, the use of hook functions should be cautious, and it should be removed immediately. Win95 is a multi-threaded system that requires the scope of the hook function used by the user. The following is an explanation of the scope of action:

Hook role range

WH_CallWndProc thread or system

WH_CBT thread or system

WH_Debug thread or system

WH_GetMessage thread or system

Wh_journalplayback is only available

Wh_journalrecord only system

WH_KEYBOARD thread or system

WH_MOUSE thread or system

WH_MSGFilter thread or system

WH_SHELL thread or system

Wh_sysmsgfilter only

Using the hook function to achieve Chinese If we know the handle of a window, we can get the getMenu function.

The menu handle of the window. After that, we can get the external string of each menu item by the following menu function, and the corresponding Chinese string can be obtained by check the dictionary, and finally the Chinese string is replaced with the Chinese string. Note that Chinese display This program does not solve, so it is necessary to execute on the Chinese operating system. The above process here can be expressed as:

HWnd (window handle)

GetMenu (hwnd)

HMENU (menu handle)

GetSubmenu (Hmenu, Flag, Position)

HSUBMENU (submenu handle)

GetMenuItemString (Hsubmenu, Position, LPString, Len, Flag)

LPSZText (menu items)

FindChinese (LPSTRING, LPCHINESE, LEN)

LPSZCHINESE (Chinese string)

ModifyMenu (Hsubmenu, Position, Flag, ID, LPCHINESE)

Menu 项

So, how do you get another program's window handle from a program? This must know the window of the window. Because the window class name is a global atom, it is impossible to be the same as the same class name, and can be used as a unique identifier. Through the class name, FindWindowEx can get the window handle of its currently running application instance.

Through the above analysis, we can make such a solution:

Run a specific application that completes two tasks:

Search for the class name of our foreign language program, get the window handle of the program current instance, the ID of the main thread, install a hook function of the wh_getMessage type. Use the window handle to get the main menu handle, add a custom menu item after the menu. This menu item is primarily used to send messages to the window process so that the hook function of the wh_getMessage type can be activated, and

The handle of the main menu of the program makes the above-described Chinese process.

2.

The hook function is mainly working in Chinese. The hook function should exist in a DLL. Mainly used to intercept custom menu messages, in this menu message processing, get the main menu handle, find the dictionary in the DLL, replace the foreign menu item.

Program Description Since Win95 is a multi-threaded environment, the thread ID must be specified when the hook function is hooked. This parameter is usually set to NULL in a Windows 3.x environment. When the hook installer is looking for a window class, if you can't find it, you should use the WINEXEC function to start according to the path to the external program, and then look for so that you can install the hook function smoothly. The hook installer can also perform menu Hanhua by getting a window handle. However, considering that many applications often modify the menu during operation, the main process of Chinese is placed in the hook function. Because the front hook is not effective, dynamic Chinese can be easily performed by the selection of custom menu items. The hook installer and the foreign language we want Chinese are two different processes, and there are two different application spaces in Win95. To implement a dictionary of a dynamic connection library for foreign programs, because the hook function is mounted, the same process is the same process space, and DLL is a hook installer, so you must use the dictionary and some hook functions. Variables are set to memory sharing and need to be used to use the #pragma Date_SEG instruction. See the program code. This is very important, otherwise it will have an annoying protection. For simplicity, the number of dictionary entries in the dynamic connection library is limited. In fact, Win95 can be greater than 64K. In addition, the pattern used in the example is extremely simple, and everyone can improve the subsection. The menu often contains a lot of keyboard operational simplekekes, so the Chinese string must inherit the relevant content in the foreign language, and all the operations of the original program must not be changed. . After replacing the menu item, you must immediately perform the refresh of the menu bar, otherwise the display of the menu is extremely confusing. The DrawMenubar function should be called immediately after replacement. To define the .def file, export to the function, the introduction must be accurate, otherwise it will cause compilation to fail. The program passes in the PWIN95, BC5.0, and PMMX166 environments. Some dynamically connected public libraries of BC may be required, pay attention to when commissioning. 10 In order to demonstrate the purpose, reduce the space, hereby commenting the part of the program. Hook function installer:

#define strict

#include

#include

#include "mate.h"

BOOL WINAPI _IMPORT InstallmsgfilterHook (HWND HWND);

Int Pascal Winmain (Hinstance Hinstance, Hinstance Hpre, LPSTR LPCMDLINE, INT NCMDSHOW)

{

Char szprogramclass [30] = "shi"; // The class name of the foreign language is here, this demonstration // program class name

Char szprogrampath [30] = "E: //ysh/shi//shi.exe"; // Foreign program path, this

// The program path to be used by the reader can be set as the reader

MSG msg;

HWND _HWND; / / 要 外 程序 程序 程序 程序

HMENU HMENU; // Main menu handle

INT NTOPLVEL; / / Top popup menu item

_hWnd = findwindow (szprogramclass, null);

IF (_hWnd = = null) // Not found

{

IF (Winexec (SZPROGRAMPATH, SW_SHOW) == ERROR_FILE_NOT_FOUND) // Didn't find the specified program

{

MessageBox (Null, "File Not Found!", "Chinese Mallace", MB_OK;

Return (False);

}

_hWnd = findwindow (szprogramclass, null); // Looking for IF again (_hWnd == null)

{

MessageBox (NULL, "Find Window Faild!", "Chinese Mallace", MB_OK;

Return (False);

}

}

LoadLibrary ("mate.dll"); // loaded into the library

HMENU = GetMenu (_hwnd); // Get menu

Appendmenu (HMENU, MF_BITMAP | MF_ENABED, CM_MYMENUITEM, "Chinese && English"); // Add your own menu item

Drawmenubar (_hwnd); // Heavy paintings, otherwise the menu shows chaos

IF (! installmsgfilterhook (_hwnd)) // Install the hook

{

Messagebox (NULL, "Hook Function Failed!", "Chinese Mallace", MB_OK;

Return (False);

}

}

Return (TRUE);

}

The main code of the dynamic connection library:

#define CommonNum 100

#include

#include

#include

#include "mate.h"

#pragma data_seg ("tweny") / / must be explained in .def as a shared section

Static hHOOK MSGFILTERHOK = null; // Receive delivery message hook handle

Static hinstance hinstance = null;

Static HWnd ShihWnd = NULL; // Foreign Program Window Handle

Static bool flag = true;

Static HMenu HWndMenu = NULL; // Menu Handle

Commondict Word [CommonnUM] = // Dictionary, the structure is defined in the head

//

{

{"& File", "file & f"},

{"& New", "New & n"},

{"& Open", "Open & O"},

{"& Savior", "save & s"},

{"Save & AS", "Save As & A"},

{"P & Rinter Setup", "Printer Settings & R"},

{"Page SET & UP", "Page Settings & U"},

{"& Print", "Print & P"},

{"E & XIT", "Exit & X"},

{"& Edit", "Edit & E"},

{"& Undo", "revoke & u"},

{"& Redo", "red do & r"},

{"Cu & T", "Cut & T"},

{"& Copy", "copy & c"},

{"& Paste", "Paste & P"},

{"& Window", "Window & W"},

{"& Windows", "Window & W"}, {"& Tile", "Cascade & T"}

{"& Cascade", "laminated & c"},

{"& Hide", "Hide & H"},

{"& Hidden", "Hide & H"},

{"& View", "show & v"},

{"& All", "all & a"},

{"& Hidden Document List", "Hide all text windows & h"},

{"& Help", "Help & H"},

{"Help Topics", "Help Topic & W"},

{"& What's this?", "What is this & w"},

{"& About", "About & A"},

}

#pragma data_seg () // shared segment declaration end

Bool WinApi_export installmsgfilterhook (hwnd hwnd);

LResult Callback_export msgfilter (int ncode, wparam wparam, lparam lparam); // hook type declaration

Bool WinApi SearchDict1 (Char * English, Char * Chinese); // Tatting Dictionary

Bool WinApi DllenTryPoint (Hinstance Hinthis, DWord FDWREASON, LPVOID LPVRESVERED)

{

Hinstance = Hinthis;

Switch (FDWREASON)

{...} // See related documents

Return (TRUE);

}

Bool WinAPI_Export Installmsgfilterhook (HWND HWND)

{// Install the hook function

DWORD PID; // Thread ID

ShihWnd = hwnd; // Mapped program window

HWndMenu = GetMenu (ShihWnd); // Get menu handle

IF (! hwndmenu) MessageBox (Null, "Get Menu Faild",

"Install", MB_OK;

Return (msgfilterhook = setwindowshookex (WH_GetMessage, (HookProc) msgfilter, hinstance, getwindowthreadprocessid (hwnd, & pid))! = null); / / Install the hook function of the specified thread

}

LResult Callback_export Msgfilter (int Ncode, WPARAM WPARAM, LPARAM LPARAM)

{// message filter function

HMENU HPOPUP; // Main menu handle

Char lpmenustr [30]; // menu item string

INT I, Count;

IF (ncode> = 0) // less than zero remaining to system processing

{

Switch (ncode)

{

Msg * msg;

HMENU HSUBMENU, HSUB2MENU; // Two-layer menu

HWND HWNDTHIS;

Char BUF [100], Chinese [100]; // Character buffer

INT TOPNUM, SUBNUM, SUB2NUM; // is the top-level menu item, respectively,

// Pop up menu item, the secondary submenu number

INT i = 0, j = 0, k = 0; uint itemid; // menu item ID, modify the command ID of the menu when modifying the menu item

Menuiteminfo MenuItem;

Case HC_Action:

MSG = (msg *) lparam;

Switch (msg-> message)

{

Case WM_COMMAND:

IF (msg-> wparam == cm_mymenuitem) / / Is it a custom menu item?

{

HWNDTHIS = msg-> hwnd; // Get window handle

HWndMenu = GetMenu (hwndthis); // Get the main menu handle

TopNum = getMenuItemcount (hwndMenu); // Get the top-level menu item

For (i = 0; i

{

IF (Getmenustring (HWndMenu, I, BUF, 100, MF_BYPOSITION))

/ / Get the string of the specified location menu item

{

IF (SearchDict1 (BUF, Chinese)) // If you find it from the dictionary

{

Itemid = getMenuItemID (HWndMenu, i); // get menu ID

ModifyMenu (HWndMenu, I, MF_String | MF_BYPOSITION, ITEMID, Chinese); // Modify the menu

Drawmenubar (hwndthis); // Update Now

}

Else

{

}

}

}

IF (HWndMenu)

{

For (i = 0; i

{// Chinese pop-up menu item

Hsubmenu = GetSubmenu (HWndMenu, i);

Subnum = getMenuItemcount (Hsubmenu);

For (j = 0; j <= Subnum; J )

{

{

IF (Getmenustring (HSubmenu, J, BUF, 100, MF_BYPOSITION))

// Pop-up menu item content is character?

{

IF (SearchDict1 (BUF, Chinese) // Tatches Dictionary

{

Itemid = getMenuItemID (HSubmenu, J);

IF (itemid == 0xfffffffff) // Is there any submenu?

{// Chinese

HSUB2MENU = GetSubmenu (HsubMenu, J);

Sub2Num = getMenuItemcount (HSUB2MENU);

For (k = 0; k

{

IF (Getmenustring (HSUB2MENU, K, BUF, 100, MF_BYPOSITION))

{

IF (SearchDict1 (BUF, Chinese))

{

ItemID = GetMenuItemID (HSUB2MENU, K);

Modifymenu (HSUB2MENU, K, MF_STRING | MF_BYPOSITION, ITEMID, Chinese);

}

}

}

}

ModifyMenu (Hsubmenu, J, MF_String | MF_BYPOSITION, ITEMID, Chinese);

Drawmenubar (hwndthis); // Update Now

}

}

}

}

}

}

Else

MessageBox (NULL, "HWndMenu Is Null", "My Hook", MB_OK;

} // Unaffected the main menu handle

Break;

DEFAULT:

Break;

}

Break;

}

}

Return (CallNexthooKex (Msgfilterhook, Ncode, WPARAM, LPARAM);

}

Bool WinApi SearchDict1 (Char * English) {

Char in [100], OUT [100];

INT I;

Bool flag; // Find a sign

LSTRCPY (IN, ENGLISH);

For (i = 0; i <60 / * number * /; i ) // Level the length of the dictionary

{

LSTRCPY (OUT, WORD [I] .english);

Flag = LSTRCMP (IN, OUT);

IF (! flag) //

{

LSTRCPY (Chinese, Word [i] .chinese; // Copy Chinese characters

Break;

}

Else

{// Add to check the code for the second dictionary here

}

}

Return (! flag); // Return to find results

}

==

Written in 1998

转载请注明原文地址:https://www.9cbs.com/read-20907.html

New Post(0)