Clean and complete Delphi multi-language-Design Mode

Source: Internet
Author: User

With the increasing degree of globalization, software has become more and more like dandelion, scattered and rooted everywhere. This solves the problem of display in different languages. We certainly hope that a set of programs can support different languages without modifying the Code, rather than maintaining many versions.

The first problem to be discussed is garbled characters. Since Unicode is not supported in versions Win32 to 11. X of Delphi, ANSI code is generally used. In such cases, garbled characters are displayed:

  1. The language and text used are different from the current language set by the system. For example, in the simplified version of QQ, in the traditional operating system (or in the simplified operating system, the "non-Unicode program language" is set to "traditional) it is garbled. Even if you change font. charset, some components may still be garbled, such as statusbar. Therefore, windows in the Vietnamese version displays Vietnamese, windows in the Iranian version displays Iranian, windows in the Vietnamese version does not display Iranian, and windows in the Iranian version displays Vietnamese, in this way, we can ensure that there is no garbled problem. Fortunately, such misplacement is rarely used.
  2. The system does not have a Language Pack for the language you want to display;

If you want to ensure that there are no garbled characters at all, you must consider using Unicode codes and use a complete set of Unicode-supported components, such as TNT, but it is relatively simple in Ui monetization, you cannot use other components.

Let's get down to the truth. First, let's see where Strings need to be implemented in multiple languages and see the advantages and disadvantages of various implementation methods.
1. components on the interface, such as tbutton Caption;
2. Actively pop-up messages, such as showmessage ('Are you sure? '), Raise exception. Create ('error! ');
3. Exception error report information, such as exception caused by F/0;
4. The above strings in the 3rd RMB package;

There are many ways to implement multiple languages:
1. resource generation tool provided by Delphi
This tool lists all strings in the DFM file of the project and the strings defined as resourcestring in PAS, and compiles the strings into different resources in different languages. Select the language before project compilation, each language is compiled into an EXE.

This tool is inconvenient to use. It is not a complete solution. It is the same as Borland's Midas demo (tclientdataset connects to remotedatamodule's tdatasetprovider through providername. during actual ERP system development, who will put 100 tdatasetprovider to connect 100 tdataset ?), It is just a demonstration of the principle.

First, because DFM is a part of the resource file, "update resource DLLs... ", for example, if you forget to change" button1 "to" button2 ", the" resource button1 error cannot be found "will be reported during the running. The Dictionary Editing screen provided contains a string, there are also left/top and other materials; dictionaries cannot be reused. In a module, translation is performed, and in 2nd modules, the same words must be translated.

Secondly, each language is an EXE/BPL. If your system is package cutting, BPL is also one for each language. Be careful not to combine BPL in different languages, at that time, a screen will display Chinese characters, and a display of German (one may be garbled) will be miserable.

Once again, if the BPL assembly system does not provide a multi-language solution for 3rd RMB, You need to modify the 3rd RMB, But we generally do not do this, because the RMB 3rd million will be updated at any time, do you need to update others every time they are updated.

Therefore, no one generally uses the solution provided by Delphi (except for demo ).

2. Resource DLL Method

Use a separate resourcedll and loadresstring function to obtain the translation string, but you need to write this function everywhere to replace it one by one, especially the string on the form. Oh, it will be exhausted. Dictionary can be reused.
3. Many INI file methods are discussed online.
This method is to write a replacement engine, and read the language string from the INI file at runtime to replace the display text of the image element. This method is much more advanced than the first one. If you do not need to compile an EXE in each language, you only need to provide different INI files. If the INI is not synchronously updated during screen modification, no fatal errors will occur, at most, a text is not converted. The engine also provides a String Conversion Function, so it can also process the pop-up messages. This method has three different implementations in the file format:
(1), [number] = [String]
Each string is numbered from 1, 1, 2, 3, 4..., which is very troublesome. The code must be modified. Of course, it is okay to switch the language during runtime.
(2) [component. Attribute] = [String]
In this implementation, the component instance is matched one by one, and the attribute is determined by rtti. The replacement is precise, and the language can be switched during runtime. The disadvantage is that it is a little dull and multiple strings with the same components will be listed multiple times; there is no scalability, it is difficult to represent complicated components such as columns of tlistview.
(3), [old string] = [New String]
Regardless of the instance of the component, INI is a pure language table or dictionary. The language to be switched during expansion and runtime may be in the engine. The disadvantage is that it cannot be used to process multiple meanings of a word.

In general, this method has made great progress, but in order to use INI files, we have to work hard to crack the 64 K limit. A more professional way is to use custom file formats.
In terms of simplicity, it is undoubtedly a custom conversion engine. The [old string] = [New String] file format is convenient. With the help of dictionary management tools, dictionary files can be used repeatedly, it can also be provided to professional translation companies. So the rest of the questions are about how convenient the engine is. It is best for users not to write a line of code, how to expand and support any third-party components, and how to make the same picture have texts in multiple languages, the same word can be converted into different meanings ......

4. inherit a subclass for each component class and convert the text in the loaded method of the subclass. Because all the components to be processed are leaf-level components (although tlabel and tpanel are from tcustomcontrol, tcustomcontrol cannot be handled only), the workload is heavy. There is nothing to do with the old programs except for component replacement.

5. Register a conversion function for each component class. The engine traverses the container to find the nearest Conversion Function of the blood source for each component and calls this function to convert the text of the component. In this way, you do not have to deal with leaf nodes. You only need to register functions on the appropriate component layer; you do not have to change the old program. When designing a form, you only need to place one component on the form. After loaded, this component starts to parse the component on the form, starting from for I: = 0 to ComponentCount-1 or from for I: = 0 to ControlCount-1, find a component and look for the latest serial number of blood, then, use this function to replace the text. Because the number of sending letters is added, it cannot be used as a replacement. It can be used for any element, in addition, you do not need to modify the replacement of RMB 3rd.

I think the 5th methods are elegant and look clean. It is set by the gof design pattern, which belongs to the Mediator Pattern ). Many years ago, we used a component called txpmenu to obtain an XP-style interface. We also felt that it was very clean and everything was done with one component. Instead of replacing tlabel with tflatlabel, change tbutton to tflatbutton ...... I remember there was an article in programmer who specifically praised this component. However, the component does not use the intermediary mode and cannot be well expanded to support 3rd RMB.

Finally, let's think about how to fully support multiple languages in Delphi if I am Borland. Delphi provides a block-defined keyword "resourcestring". The compiler will compile the String constant defined in this block in the resource area of the EXE file, during runtime, the Windows API loadstringa is used for reading. Therefore, some external conversion tools can directly read these resource strings from the EXE file and then write the converted strings; the embedded conversion engine can also intercept this API function to convert text. However, if the strings in the EXE are not completely recycled, there is nothing to do with it. This is just the DFM file from Delphi. Delphi places the DFM file as a resource in the exe, the string on it cannot decide whether to use don't Resource (many constant strings in Delphi source code have this prompt.

In addition to the data types such as string, widestring, and ansistring, Delphi adds a data type multistring and modifies the definition of the VCL component (please solve Borland together with Unicode), such as tlabel. caption is defined as multistring, which has a special processing method for the multistring type. For example, if resourcestring is processed using loadstring API, it is converted once every read, but it should be more than this content, for example, to transfer the instance, and then provide a global applicationmulti component, similar to applicationevent, so that it can be captured outside. As for the dictionary, it can only be provided by external users (of course, a standard format can be developed so that all Delphi users can share and exchange it ).

This method seems feasible, but there is another efficiency issue to consider. (1) Each read is converted, which is less efficient for frequently draw items. (2) for example, a toolbar has many toolbuttons, beginupdate/endupdate is usually used for batch update. How can VCL tell future generations to improve this efficiency. (Note: The efficiency does not seem to be a problem. Frequent draw is caused by multiple string changes. In fact, the component itself will already be processed using beginupdate/endupdate, which is not externally involved)

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.