Reading Resources at Runtime


At this point, you've created a resource file, created the custom build step to create the binary resource file, and set up the project to link in that file to your built assembly. The final step this hour is to use those resources from managed C++ code.

Included within the .NET Framework is a class named ResourceManager that's specifically designed to work with application resources. In addition to being able to read resources at runtime, ResourceManager is also culture aware. By you specifying a language and sublanguage (collectively known as a culture) when using the ResourceManager class, it has the ability to select the proper resource based on that culture. If one is not found, it returns the default resource instead. One clear advantage that this brings is the ability to easily change the language for a user interface. In this hour, however, we are just going to focus on using the ResourceManger class to retrieve the default resource.

The two main functions within the ResourceManager class that you will be using are the GetString function and the GetObject function. The GetString function, as its name implies, retrieves the value of a string resource given its string ID. The GetObject function, on the other hand, retrieves other types of data within the resource file, such as images, cursors, icons, and so on. Because the GetObject function is generic and can retrieve differing types of data, you have to cast it to the specific data type you want when assigning it to a variable. This is done by using the dynamic_cast C++ operator, which is used to change data from one type to another.

The first step, before we can start using the resources, is to create a WinForm with two controls: a Label control and a PictureBox control. Next, using the same methodology as previous lessons, create an InitForm function to handle the initialization of the form. Your header file should look similar to Listing 8.1.

Listing 8.1 The Header File for a Basic WinForm That Uses Resources
 1: #pragma once  2:  3: #using <mscorlib.dll>  4: using namespace System;  5:  6: // required dlls for WinForms  7: #using "System.dll"  8: #using "System.Windows.Forms.dll"  9: #using "System.Drawing.dll" 10: 11: // required namespaces for WinForms 12: using namespace System::ComponentModel; 13: using namespace System::Windows::Forms; 14: using namespace System::Drawing; 15: 16: __gc class WinForm: public Form 17: { 18: public: 19:    WinForm(); 20:    ~WinForm(); 21:    void InitForm(); 22: 23: protected: 24:    System::ComponentModel::Container* m_Components; 25:    Label* m_Label; 26:    PictureBox* m_Picture; 27: }; 

In the InitForm function, create the Label control, the PictureBox control, and the control container. Set the properties as shown in Listing 8.2. However, you'll need to set the PictureBox control's size based on the bitmap size you created when you made your resource file. You can do this either by opening the image in the Microsoft Windows Paint program and selecting Image, Attributes from the main menu to get the width and height or by opening your .resx file in the ResEditor utility and expanding the image resource to display information about the image.

Listing 8.2 Creating the Label and PictureBox Controls
 1: #include "StdAfx.h"  2: #include "winform.h"  3: #using <mscorlib.dll>  4:  5: WinForm::WinForm(void)  6: {  7:     InitForm();  8: }  9: 10: WinForm::~WinForm(void) 11: { 12:     Form::Dispose(); 13: } 14: 15: void WinForm::InitForm() 16: { 17:     SuspendLayout(); 18: 19:    // create component container 20:    m_Components = new System::ComponentModel::Container(); 21: 22:    // create the label control 23:    m_Label = new Label(); 24:    m_Label->Location = Point(10, 30 ); 25:    m_Label->TabIndex = 1; 26:    m_Label->TabStop = false; 27:    m_Label->Size = System::Drawing::Size(200, 16); 28: 29:    // create the PictureBox Control 30:    m_Picture = new PictureBox(); 31:    m_Picture->Location = Point( 10, 50 ); 32:    m_Picture->TabIndex = 2; 33:    m_Picture->TabStop = false; 34:    m_Picture->Size = System::Drawing::Size(183, 102); 35: 36:    // add the controls to the container 37:    Controls->Add( m_Label ); 38:    Controls->Add( m_Picture ); 39: 40:    // form properties 41:    ClientSize = System::Drawing::Size(205, 200); 42:    FormBorderStyle = System::Windows::Forms::FormBorderStyle::FixedDialog; 43: 44:    Name = S"Hour 8"; 45:    Text = S"Hour 8"; 46: 47:    ResumeLayout(); 48: } 

Now that you have a basic WinForm set up that contains a Label and a PictureBox control, it's time to use the resources you created earlier to set the controls' data. In order to use the ResourceManager class discussed earlier, you must first create an instance of the class using parameters to the constructor to tell it which resource you wish to use. The resource name is the name of the output file without the .resources extension that is created when your .resx file is compiled. For this hour's lesson, the name of the .resources file is NETResources. The second parameter to the constructor is the location of this resource. As you'll recall from earlier in the lesson, the resource is linked to the assembly as an embedded managed resource file. Therefore, the location is not an actual path but an assembly class pointer that is found by calling the GetExecutingAssembly function.

Immediately following the SuspendLayout function call within the InitForm function of your WinForm class, insert the following code:

 // create resource manager    Resources::ResourceManager * pResources =    new Resources::ResourceManager    (S"NETResource", Reflection::Assembly::GetExecutingAssembly()); 

Now that you've created an instance of the ResourceManager class, you can use it to retrieve the string and image resources. The property for the Label control that you want to change is the Text property. Use the GetString function provided by the ResourceManager class to set this property, as shown here:

 // get label text from resource m_Label->Text = pResources->GetString(S"IDS_HELLO"); 

Setting the Image property for the PictureBox control, however, isn't as straightforward. As mentioned earlier, the only other function available to retrieve resources using the ResourceManager class is the GetObject function. Because this function returns an Object* value, you will need to cast that return value to an Image object. This is done using the dynamic_cast operator, as the following code demonstrates:

     // get image data for PictureBox from resource m_Picture->Image = dynamic_cast<Image*>    (pResources->GetObject(S"IDB_PICTURE")); 

The last thing to do to finish the project is to make sure you launch your WinForm from the application's main function, as shown in Listing 8.3.

Listing 8.3 Launching the WinForm
 1: #include "stdafx.h"  2: #include "WinForm.h"  3: #using <mscorlib.dll>  4: #include <tchar.h>  5:  6: using namespace System;  7:  8: // This is the entry point for this application  9: int _tmain(void) 10: { 11:    Application::Run(new WinForm()); 12:    return 0; 13: } 


Sams Teach Yourself Visual C++. NET in 24 Hours
Sams Teach Yourself Visual C++.NET in 24 Hours
ISBN: 0672323230
EAN: 2147483647
Year: 2002
Pages: 237

Similar book on Amazon © 2008-2017.
If you may any questions please contact us: