In order to help I need answers to the following questions (which when asked may also lead you on your own to the solution):
1. Are ControlA.ascx and ControlB.ascx being loaded into Main.ascx using LoadControl or are they part of the delcarative markup (html, etc.) code for Main.ascx?
2. Are you localizing the controls (such as label) of ControlA and ControlB using a ResourceKey in the markup or are you calling one of the forms of Localization.GetString in the code behind?
3. If you are calling Localization.GetString are you using the overloaded method which includes the parameter for the LocalResourceFile, that is:
MyLocalizedValue = GetString("MyKey", LocalResourceFile)
4. If so, have you set a break point in the debugger to check the value being returned for LocalResourceFile. It should be of the form of:
. . . /DesktopModules/MyModuleFolderName/App_LocalResources/ControlA
5. If the value for LocalResourceFile does not include ControlA or ControlB at its end, you will need to have set the ID of the child control loaded with LoadControl to the name of the control or, set the value of ControlA and ControlB's LocalResourceFile property explicitely each time the control is loaded. You could also set the child controls's LocalResourceFile property to that of the Main.ascx control. In that case, localization values for each child control would be pulled from Main.ascx.resx rather than from separate ControlA.ascx.resx and ControlB.ascx.resx resource files.
6. Although not directly related to this problem, you'll also find it helpful to have set the ModuleConfiguration property of each child control to that of the main control immediately after the child control has been loaded.