Programming Visual Basic 2008 phần 8 ppsx

79 288 0
Programming Visual Basic 2008 phần 8 ppsx

Đang tải... (xem toàn văn)

Tài liệu hạn chế xem trước, để xem đầy đủ mời bạn chọn Tải xuống

Thông tin tài liệu

532 | Chapter 19: Localization and Globalization ' Draw the text. e.Graphics.DrawString(TextBox1.Text, TextBox1.Font, _ SystemBrushes.WindowText, 1, 4) ' Put everything back. e.Graphics.Restore(saveState) End Sub When you run the program, it creates a mirror image of whatever you type in the TextBox control using GDI+ features. Figure 19-4 shows me playing with the pro- gram instead of meeting this chapter’s submission deadline. As interesting as this program may be, it is neither fully globalized nor localized. It’s almost globalized. All we need to do to fully globalize it is to “throw the switch” on the form that enables later localization. We do this through the form’s Localizable property. Change this property from False to True. Ta-da! Your form is globalized! Now for part 2: localization. Here are the steps to localize the form: 1. Determine which language or language-culture combination you want to localize. 2. Select that language or language-culture from the form’s Language property. When you open this property list, it includes languages alone, such as “French,” and languages combined with a culture or country, as with “French (Canada).” The language-alone entries are known as “neutral language” entries. You can use either type for localization. If you select, for instance, “French,” users of your application in either France or French-speaking Canada will use the French resources. If you localize using “French (Canada),” French Canadian users will access the localized resources, but not French-language users in France. 3. Modify any of the properties of the form or its controls. That’s it. Whenever the form’s Language property is changed to something other than (Default), Visual Studio starts recording all form and control changes into a sepa- rate form-specific and language- or language-culture-specific resource file. You can localize the form with multiple languages. Each time you change the Language property to another language or language-culture selection, the changes to the form or controls apply only to that selection. Whatever you change gets saved in a separate resource file. Figure 19-4. Look Ma, I’m upside down Localizing Forms Within Visual Studio | 533 Let’s try it with the sample mirror program. I’m going to choose Japanese for the localization language. First, I set the form’s Language property to “Japanese.” The form momentarily blinks, but there is no other noticeable change. It looks just as it did in Figure 19-3. Next, I change the Text properties of the form and of each label control to their Japa- nese language equivalents (see Figure 19-5). Do you notice how the shorter Japanese language labels are farther away from the text and mirror display fields? Does it bother you as much as it bothers me? To get it out of my mind, I will resize the two fields a little larger by stretching them to the left, as I’ve done in Figure 19-6. The amazing part is that if you set the form’s Language property back to (Default), not only will the labels return to English, but the resized text and mirror fields will return to their “natural” sizes. Although I haven’t checked out every property, the localization feature seems to impact all display elements of each control. The program is now fully localized for English (the default language) and Japanese. Normally, the Japanese resource would be used only on a system running the Japanese version of Microsoft Windows. But we can force the program to use Japanese by chang- ing its “user interface culture.” In the application’s startup code (the MyApplication_ Startup routine in the ApplicationEvents.vb file), I add the following code: Private Sub MyApplication_Startup(ByVal sender As Object, _ ByVal e As Microsoft.VisualBasic.ApplicationServices. _ StartupEventArgs) Handles Me.Startup If (MsgBox("Switch from English to Japanese?", _ MsgBoxStyle.Question Or MsgBoxStyle.YesNo) = _ MsgBoxResult.Yes) Then Figure 19-5. The name-mirror program in Japanese Figure 19-6. The Japanese version with adjusted fields 534 | Chapter 19: Localization and Globalization My.Application.ChangeUICulture("ja-JP") End If End Sub And sure enough, running the program and saying “Yes” to the “Switch to Japa- nese” prompt presents a form in Japanese, as shown in Figure 19-7. (If you answer “No” to the question, the default language, English, appears.) Let’s look at the files created in this project. (Look in the installation directory of this book’s code for the Foreign Names subdirectory. I’ve placed a copy of this mirror- text project there for you.) The source code directory includes a Form1.resx file, added by default to all new Windows Forms applications. But there is also a Form1. ja.resx file, the Form1 resource file for the Japanese language. Visual Studio will com- pile this file into a language-specific resource when it builds the project. At that time, the code’s bin\Release subdirectory will contain a further ja subdirectory with a file named ForeignNames.resources.dll. This is the satellite assembly that contains all of the Japanese language resources. If the application had included multiple forms, all of the Japanese resources for all forms would appear in that single DLL file. Adding Resources Outside Visual Studio Visual Studio makes localization quite easy. But it’s rare that the developer of a major application would also be fluent in multiple target languages. And you cer- tainly don’t want non-programmers gaining access to your forms and code in Visual Studio, where they can do who-knows-what to its logic. To keep foreign-language eyes and fingers where they belong, Microsoft wrote the Windows Resource Localization Editor, and included it with the Software Develop- ment Kit supplied with .NET. (On my system, it’s located at Start ➝ [All] Programs ➝ Microsoft Windows SDK v6.0A ➝ Tools ➝ Windows Resource Localization Editor. Its command-line name is winres.exe.) When you are ready to have a translator con- vert a form to a specific language, you only need to provide them with this program, and the form’s .resx file (such as Form1.resx). The program simulates the display of the form as it appears in Visual Studio, and lets the translator modify any relevant form or control properties for a specific language. Figure 19-8 shows ForeignNames’s Form1 in the Localization Editor. Figure 19-7. Look Ma, I’m Japanese Manually Compiling Resources | 535 The program prompts for the target language or language-culture when you try to save changes. It outputs a language-specific .resx file (such as Form1.ja.resx for Japa- nese) that can be used in your application. Once you get the foreign resource files back from the translators, store them (the files, not the translators) in the project’s source directory, and rebuild the project to generate the correct satellite assemblies. Manually Compiling Resources It’s possible to generate the satellite assemblies manually from the source .resx files without rebuilding the entire project in Visual Studio. You will have to use the Win- dows command line (cmd.exe), and you will need access to the main assembly’s EXE or DLL file. It’s not for the faint of heart, and a single mistyped character could cost American taxpayers millions. Figure 19-1 summarized the steps needed to move a .resx file into a satellite assembly. The “generate” and “compile” steps can be done using two command-line utilities: resgen.exe and al.exe. Doesn’t that sound like great fun? As with other .NET command-line tools, these tools need the command-line envi- ronment to be set up just so, or they will have a snit and refuse to run. To ensure that you have the correct environment, you need to open the special .NET version of the command line. The .NET SDK was installed when you installed the framework, so you should be able to find a Start-menu entry for it at Start ➝ [All] Programs ➝ Microsoft Visual Studio 2008 ➝ Visual Studio Tools ➝ Visual Studio 2008 Com- mand Prompt. Figure 19-8. An amazing likeness of Form1, ready for translation 536 | Chapter 19: Localization and Globalization Resource File Generation Once you have a .resx file available, either by creating it manually or by using the Win- dows Resource Localization Editor, you generate a .resources file using resgen.exe, the Resource Generator command-line utility, part of the SDK toolset. It accepts an input and an output filename as its arguments. resgen.exe Form1.ja.resx Form1.ja.resources If you omit the output filename, resgen will simply replace the .resx extension with .resources. If you have multiple foreign-language assemblies (for multiple forms, for instance), generate resource files for all of them. Then you will be ready to compile the satellite assembly. Compiling Satellite Assemblies .NET uses al.exe, the Assembly Linker program, to compile all of your .NET applica- tions to their final assembly files. We’ll use this same program to generate the satel- lite assemblies. Its command-line arguments were designed by a secret society, so getting them just right will take some work. Let’s look at the command first, and then I’ll explain it. al.exe /target:lib /embed:Form1.ja.resources,ForeignNames.Form1.ja.resources /culture:ja /out:ForeignNames.resources.dll /template:bin\Release\ForeignNames.exe You should enter these lines as one long line. I had to wrap them in the book because the publisher didn’t want to do one of those fold-out pages that you see in some children’s books. They didn’t like my interactive “pop-up” Visual Studio envi- ronment idea, either (something about keeping the book at less than $100 per copy). The options provided to al.exe work all of the magic: /target:lib The lib part says, “Output a DLL-style file.” /embed This option indicates which source files you want to include in the output assembly. The first comma-delimited part indicates the source filename. The sec- ond part indicates the name by which this resource will be known in the applica- tion. The name must be in the format basename.cultureName.resources, where basename is the application name (for application-wide resources) or the class name (qualified with its namespace) for a specific class, such as Form1. Since my application and its default top-level namespace are both “ForeignNames,” I’ve included that in the name component. You can add as many /embed options as you have resource files to include. Other Localization Features | 537 /culture Although you will eventually put the satellite assembly in a folder named for the target culture, Visual Basic doesn’t trust you. Instead, it wants a record of the culture embedded in the assembly itself. You do that through this command-line option. /out This option specifies the output name of the satellite file. You really need to use the name application.resources.dll for the file, where application is the same as your application’s name before the .exe part. If you don’t do this, it won’t work. Well, you could still get it to work by adjusting the application’s app.config file, but that file is just plain scary, so you don’t want to go there. /template This is the option that says, “I’m making a satellite assembly, and the related pri- mary assembly is x.” To use the satellite assembly, locate the directory that contains the main EXE assembly. Create a new subdirectory right there, giving it the name of the language or language-culture key used to create the assembly (“ja” in my case; “ja-JP” would have been an option if I created the assembly using “Japanese (Japan)”). Then put the new satellite assembly in that subdirectory. Other Localization Features Localization is more than just words on a screen. There are also issues of how you display times, dates, and monetary values to the user. The good news is that these features will work automatically if you globalize your program properly. Just as each .NET program maintains a “user interface culture” (which we played with in the sample program previously), it also has a “general culture” used for string manipula- tion of times, dates, financial values, and other similar culture-dependent things. If you use core methods such as CDate to extract date values, instead of scanning through a user-entered date string by hand, you get culture-specific date processing for free. Also for output, if you use the predefined formats for the Format method (and other similar string output methods), you get correct culture-specific format- ting for no additional effort on your part. Let’s try a quick sample that displays money using the local currency. I’m creating a new Windows Forms application. I’ll add the following code to the ApplicationEvents.vb file: Private Sub MyApplication_Startup(ByVal sender As Object, _ ByVal e As Microsoft.VisualBasic.ApplicationServices. _ StartupEventArgs) Handles Me.Startup If (MsgBox("Switch from English to Japanese?", _ MsgBoxStyle.Question Or MsgBoxStyle.YesNo) = _ MsgBoxResult.Yes) Then 538 | Chapter 19: Localization and Globalization My.Application.ChangeCulture("ja-JP") End If End Sub This code block is almost identical to the one we used in the previous sample, but I’m calling My.Application.ChangeCulture instead of My.Application.ChangeUICulture (the UI part is missing). This changes the string-manipulation culture instead of the user interface culture. Now I’ll add the following code to Form1’s class: Private Sub Form1_Load(ByVal sender As System.Object, _ ByVal e As System.EventArgs) Handles MyBase.Load MsgBox(Format("500", "Currency")) End Sub Figure 19-9 shows the results of this code when run in both English and Japanese modes. The Framework Class Libraries (FCLs) include even more culture management fea- tures in the System.Globalization namespace. The classes in this namespace let you manually adjust the output of culture-sensitive strings to meet your needs. Most of them are pretty esoteric and are intended for specific culture groups, so I won’t be discussing them here. Summary It’s a small world, after all. And the culture-specific features in .NET have helped to make it that way, at least for your software. I’m still amazed that I’m able to use Jap- anese on my English version of Microsoft Windows. (I first had to enable support for East Asian languages in the Control Panel’s Regional and Language Options applet.) And now it’s not just Windows or Microsoft Office that can automatically shift with the current culture. Politicians can do it, too. Oops, I mean that your own applica- tions can do it, too. By taking advantage of culture-specific resources and the auto- matic and manual formatting features included with .NET, you’ll soon be selling your snazzy business application in six of the seven continents. Figure 19-9. Spending money in two places at once Project | 539 Project I know you’re expecting me to localize all of the forms in the Library Project into Greek, and it is a tempting idea. But in the interest of brevity (and my sanity), I’ll leave that as an exercise for the reader. (Muffled laughter.) What we will do in this chapter’s project code is to enable the remaining patron- specific tracking and management features. Those features include the management of fines for naughty patrons who don’t return their library books on time. We’ll use the generic currency formatting features discussed in this chapter to make the appli- cation as globally accessible as possible. PROJECT ACCESS Load the Chapter 19 (Before) Code project, either through the New Project tem- plates or by accessing the project directly from the installation directory. To see the code in its final form, load Chapter 19 (After) Code instead. Tracking Patron Payments Let’s create a class that exposes the important features of each set of payments applied to a specific checked-in item. Of course, they’ll all be stored in the Library database. But keeping a summary of payments temporarily cached in memory simpli- fies some processing. Add a new class item to the Library Project, giving it the name PaymentItem.vb. Define it using the following code. INSERT SNIPPET Insert Chapter 19, Snippet Item 1. Public Class PaymentItem ' Used to track and print payment tickets. Public ItemTitle As String Public PatronCopyID As Integer Public FeesPaid As Decimal Public BalanceDue As Decimal End Class Each instance of this class identifies the collected fines and payments for a specific library item ( ItemTitle) and for the patron who turned in the item late ( PatronCopyID). 540 | Chapter 19: Localization and Globalization Calculating Patron Fines We also need to know the total fines owed by a patron for all items, even when we’re not showing the details. Add the CalculatePatronFines function to the General.vb module. INSERT SNIPPET Insert Chapter 19, Snippet Item 2. Public Function CalculatePatronFines( _ ByVal patronID As Integer) As Decimal ' Given a patron ID, calculate the fines due. Dim sqlText As String On Error GoTo ErrorHandler ' Retrieve the fine records for the patron. sqlText = "SELECT SUM(Fine - Paid) FROM PatronCopy " & _ "WHERE Patron = " & patronID Return DBGetDecimal(ExecuteSQLReturn(sqlText)) ErrorHandler: GeneralError("CalculatePatronFines", Err.GetException( )) Return 0@ End Function It’s pretty basic code, actually, since the database does all of the work of adding up the values. I checked the database documentation and confirmed that Fine and Paid are required fields, and will never be NULL. This keeps the SQL code terse. Patron Record Access Before reviewing a patron’s record, the user must identify the patron. This is done through a Patron Record Access form, sort of a login form for patrons. Each patron is assigned a password, which must be supplied before the patron can access his or her record. Administrators can access a patron’s record without providing the password. I’ve already added the PatronAccess.vb form to your project; it appears in Figure 19-10. This form’s code is a lot like that found in the ChangeUser.vb form, a form that pro- vides administrative access to the program, and that we added back in Chapter 11. The Patron Access form behaves a little differently for administrators and regular patrons. • Regular patrons must either provide their bar code, or supply their name (full last name, optional wildcards on the first name) and their password. If they use a partial name instead of a bar code, and a search of that name results in multiple matches, they will have to provide a more correct entry of their name. (If two patrons have the same name, they will have to depend on bar codes; but this program is for a small library, so name conflicts should be rare.) Project | 541 • Administrators enter the patron’s name or bar code, but no password is needed. If there are multiple name matches, the form presents all matching names in a list, and the administrator can select the correct entry from the list. This gives an administrator full access to all patron records. It’s obviously important for an administrator to log out when finished using a workstation that is available to patrons. The PatronAccess form’s SelectPatron method provides the interface to the form for both administrators and ordinary patrons. The function returns the ID of the selected patron, or –1 if the user didn’t successfully access a patron record. Patron Password Modification Although administrators can change the password of each patron through the Patron.vb form, we don’t want to give ordinary patrons access to that form and all of its raw, unadulterated power. But we still want the patrons to be able to change their own passwords, because it’s the nice and secure thing to do. I’ve added the PatronPassword.vb form to your project to fulfill this purpose (see Figure 19-11). Figure 19-10. The Patron Access form, PatronAccess.vb Figure 19-11. The Patron Password form, PatronPassword.vb [...]... the output You may also need to know about available features of the printer, such as whether it supports color If you used to be a Visual Basic 6.0 developer, you were accustomed to the convenient Printers collection The absence of that collection in Visual Basic 20 08 means that we must use more indirect means to access the printers * You can find the article referenced on my web site, http://www.timaki.com,... on the Print button this time, the Print Range section of the dialog has enabled the Pages field, and it’s already filled in with the minimum and maximum pages in the range “1–5” (see Figure 20 -8) Figure 20 -8 Support for page ranges If the user adjusts this field to “1–6,” an error occurs stating that the valid range is somewhere within “1–5” only But whether the user selects All Pages or 1–5 or 1–4... later chapter) it will be used elsewhere in the Library Project Create a new class named PatronDetailItem.vb, and use the following code for its content INSERT SNIPPET Insert Chapter 19, Snippet Item 8 Private Class PatronDetailItem Public DetailID As Integer Public TitleText As String Public DueDate As Date Public FineAmount As Decimal Public PaidAmount As Decimal Public BalanceDue As Decimal End... Locate the comment that reads, “Show the total balance,” and add the following code just after it INSERT SNIPPET Insert Chapter 19, Snippet Item 10 BalanceDue.Text = Format(totalBalance, "Currency") 5 48 | Chapter 19: Localization and Globalization The Fines list, an owner draw ListBox implementation, also displays currency values This is another list that forgoes the standard ListItemData class, using... chapter, a printer is now treated like any other NET drawing surface The statements you use to draw on a form or control can be copied and pasted directly into your printing code As I mentioned in Chapter 18, Windows Presentation Foundation (WPF) includes features that let you generate XPS files, designed for eventual WYSIWYG printing I will not be discussing that technology in this chapter since the XPS... in Windows Printers are a lot like people Oh, I don’t mean that they are cantankerous, or that they quickly run out of ink Like the people of the world, printers speak many different languages At the basic end of the language scale, some printers simply output the characters they receive Others add “escape sequences,” special combinations of characters that enable enhanced features such as font selection... Printing in Windows | 553 Printing in NET Having both screen and printer output generated through identical GDI+ commands means that I can make this a really short chapter, referring you back to Chapter 18 for details But it also means that there needs to be a canvas—a System.Drawing.Graphics object—where the printer-specific GDI+ commands target their output The System.Drawing.Printing.PrintDocument class... Figure 20-4 shows the Print Preview dialog, although with no page-specific content 554 | Chapter 20: Printing Figure 20-2 The Page Setup dialog PrintPreviewControl The PrintPreviewDialog control includes basic preview management features (such as the zoom feature) that meet the needs of most applications Unfortunately, that control is a sealed black box, and you cannot easily add your own custom features...The form is basically a dramatically reduced subset of the full Patron.vb form Since it needs to deal with only active patrons, it doesn’t have a lot of the Patron.vb code that differentiates between new and existing... strings to the PrinterSettings’ PrinterName member, making the specific printer available within the application The following code chunk lets the user select from the list of printers, and displays some basic information about the selected printer: Private Sub Form1_Load(ByVal sender As System.Object, _ ByVal e As System.EventArgs) Handles MyBase.Load ' - Display the list of printers Dim scanPrinter . entry for it at Start ➝ [All] Programs ➝ Microsoft Visual Studio 20 08 ➝ Visual Studio Tools ➝ Visual Studio 20 08 Com- mand Prompt. Figure 19 -8. An amazing likeness of Form1, ready for translation 536 | Chapter. Japanese resources for all forms would appear in that single DLL file. Adding Resources Outside Visual Studio Visual Studio makes localization quite easy. But it’s rare that the developer of a major. display of the form as it appears in Visual Studio, and lets the translator modify any relevant form or control properties for a specific language. Figure 19 -8 shows ForeignNames’s Form1 in the

Ngày đăng: 13/08/2014, 08:20

Tài liệu cùng người dùng

Tài liệu liên quan