C++ Windows Forms application icon exception - visual-studio

I want to set an icon for my Windows Form application. My actions step by step:
I created an 'icon.ico' (256x256) and put it into my project folder
In my 'Form1.h [Design]' I chose this file using Properties
This code appeared in 'Form1.h'
void InitializeComponent(void)
{ ...
this->Icon = (cli::safe_cast<System::Drawing::Icon^>(resources->GetObject(L"$this.Icon")));
... }
The object '$this.Icon' appeared in 'Form1.resx'
I rebuilt the whole project -> no errors
During execution the line 'this->Icon = ...' causes an exception: System.Resources.MissingManifestResourceException: 'Could not find any resources appropriate for the specified culture or the neutral culture. Make sure "WinForm.Form1.resources" was correctly embedded or linked into assembly "MyProject" at compile time, or that all the satellite assemblies required are loadable and fully signed.'
Here I found numerous advices, such as remove/add icon or set some custom properties for 'Form1.resx', but none of them works for me

Just like above, change line to:
this->Icon = gcnew System::Drawing::Icon(L"ICON_NAME.ico");
You might get error/exception while opening form creator but you shouldn't lose any data.
Been there, done that :)

Place the Icon you want to connect to your Form in the project directory.
Then replace the line above with the following:
this->Icon = gcnew System::Drawing::Icon(L"app.ico");
This should neutralize the bug that Microsoft has not fixed.

If you are using visual studio 2019 , you need to change the name of namespace in Form1 the same as your project name, i did it and it works
and make sure you change it in main :
[STAThread]
int main() {
Application::EnableVisualStyles();
Application::SetCompatibleTextRenderingDefault(false);
Application::Run(gcnew your_namespace_name::Form1());
return 0;
}

Related

Why can't I use STAThread attribute in C++/CLI?

I wan to use the STAThread attribute on my the main thread of my program. However, Visual Studio says it cannot find it. I have tried references necessary assemblies and using proper namespace, but it just can't find it.
Edit:
I have been able to get to work successfully after manually creating a thread with the
ApartmentState to STA. I think this is the equivalent to setting the thread, be it the main thread, but not exactly because i'm creating another thread. Anyone have another way to do this.
Here is the code:
void threadStart ()
{
Application::Run (gcnew GraphicsForm());
}
[System::STAThread] // This will not work!
int main(array<System::String ^> ^args)
{
Thread ^t = gcnew Thread(gcnew ThreadStart (threadStart));
t->ApartmentState = ApartmentState::STA;
t->Start();
return 0;
}
When I create a new C++/CLI project in Visual Studio 2012 with only a single main() function and then add [System::STAThread] in front of main(), it compiles and runs without a problem. To me, this means that it is most likely a settings difference between projects.
My recommendation is to do the same thing. Create a new C++/CLI project, add [System::STAThread] and see if it has any issues. If not, then you're at the point of checking the differences between the two projects to determine why one works properly and the other is giving you an error.

Getting started with Watin

I am trying to do the quick start example, I bring in the ref's using NuGet in VS2010, I scrape the sample code on the webpage, I see my NUnit Session window, I click the green arrow, but the browser doesn't get invoked (doesn't start). What am I missing?
using System;
using NUnit.Framework;
using WatiN.Core;
namespace FirstWatinProject
{
[TestFixture]
public class Class1
{
[Test]
[STAThread]
public void SearchForWatiNOnGoogle()
{
using (var browser = new IE("http://www.google.com"))
{
browser.TextField(Find.ByName("q")).TypeText("WatiN");
browser.Button(Find.ByName("btnK")).Click();
Assert.IsTrue(browser.ContainsText("WatiN"));
}
}
}
}
I am getting the following error in NUnit Sessions window;
SearchForWaitOnGoogle Failed: System.IO.FileNotFoundException: Could
not load file or assembly 'Interop.SHDocVw, Version=1.1.0.0,
Culture=neutral etc...
Okay, solved the error, it is as the following other overflow thread concludes;
WatiN System.IO.FileNotFoundException Interop.SHDocVw
BUT, a key action in the sequence is to build the class library project AFTER setting the Interop.SHDocVw dlls' 'Embed Interop Types' property to 'False';
Then you can hit the green arrow in NUNIT Sessions window and you will see the IE browser startup after a second or two. Simply click it and you will see whatever actions you have programmed.
God is in the details!
Setting the Interop.SHDocVw, Microsoft.mshtml dlls' 'Embed Interop Types' property to 'False';
Of course Visual Studio would give you warnings on how to amend.
The Use of Nugget Package Manager
Check for the availability of Interop.SHDocVw.dll,
Make sure that your project has a reference to Interop.SHDocVw.dll and the dll is present in the Bin/Release Folder depending upon how you are running..
Just select Build from the main menu...then select Configuration Manager. In the list select you project and change its Plateform 'Any CPU' etc to x86.
If you have only Only CPU option, you can use ... option when chosing platform and create new setting, that is for X86 platform and then choose it.
ref:
Change target to x86 in VS2010
I already had a reference to Interop.SHDocVw. The easiest fix for me was simply changing .NET from 4.5 to 3.5 in Visual Studio settings. After making the change, it worked fine.

How Can I Add an "ATL Simple Object" to Old ATL DLL Project Upgraded to VS 2010?

We have a DLL project which has existed for a long time (maybe as far back as Visual Studio 6) which has been updated for each new version of VS. The project contains a number COM classes implemented using ATL.
After upgrade to VS 2010, the project still builds fine. However, if I try to right-click the project and choose Add -> Class... -> ATL Simple Object, I get an error box that says this:
ATL classes can only be added to MFC EXE and MFC Regular DLL projects or projects with full ATL support.
This worked in VS 2008.
When I look at the project properties, Use of MFC was set to Use Standard Windows Libraries and Use of ATL was set to Not Using ATL. I changed these to Use MFC in a Shared DLL and Dynamic Link to ATL respectively, but still get the same error.
I know how to add new ATL objects without using the wizard, and I could try to recreate the project from scratch using VS 2010 to make it happy. But does anyone know of any easy way to get VS to allow me to use the ATL Simple Object wizard with a project that it doesn't recognize as a project "with full ATL support"?
Check this thread out.
It seems that adding this fragment info your ATL C++ code make it work. You don't need to actually build the project, just remove this stuff away after you are done with the wizard (provided that solution works for you).
// Added fake code begins here
class CAppModule :
public CComModule
{
};
// Added fake code ends here, below is regular ATL project stuff
CAppModule _Module;
This is where it all comes from, in $(VisualStudio)\VC\VCWizards\1033\common.js:
/******************************************************************************
Description: Returns a boolean indicating whether project is ATL-based.
oProj: Project object
******************************************************************************/
function IsATLProject(oProj)
{
try
{
var oCM = oProj.CodeModel;
oCM.Synchronize();
// look for global variable derived from CAtlModuleT
var oVariables = oCM.Variables;
for (var nCntr = 1; nCntr <= oVariables.Count; nCntr++)
{
var oVariable = oVariables(nCntr);
var strTypeString = oVariable.TypeString;
if (strTypeString == "ATL::CComModule" || strTypeString == "ATL::CAutoThreadModule")
{
return true;
}
Same problem here, but the project source already had CComModule _Module;
Fixed it, based on the IsATLProject script shown above, by changing it to
**ATL::**CComModule _Module;

Embedded Resource missing in Visual Studio 2010 when name ends with "No.xxx"

I've come across a strange behaviour in Visual Studio 2010.
When using embedded resources (files which are added to my C# project and for which the Build Action property is set to Embedded Resource), the files are included in the output assembly as binary data. Listing the resources is straightforward:
class Program
{
static void Main(string[] args)
{
string[] names = typeof (Program).Assembly.GetManifestResourceNames ();
foreach (var name in names)
{
System.Console.Out.WriteLine (name);
}
}
}
However, if the embedded resource file name ends with No.xxx (the extension is irrelevant), the file does not show up in the list. I cannot figure out any reason why Visual Studio 2010 would not include such a file. What did I miss?
Note: if I rename the embedded resource file in the solution explorer to something else, then everything works as expected.
Dan from the Microsoft Connect team has finally provided a valid explanation for this behaviour:
Hello, thanks for the report, this is actually working normally. The reason is that any resx files whose names match the pattern .VALIDCULTURE.resx are assumed to be specific to that culture. (This is how it has worked since VS2002, for better or worse)
In your case "no" is a valid culture (Norwegian, I guess) so the build process builds it into a satellite assembly. Here's what I got when I tried this. Note the "no" subfolder. If in your app you change your current culture to Norwegian, the resource load will load this set of resources.
So the problem has nothing to do with the word No itself, but rather with the fact that it is a valid, two-letter, culture name (in my case Norwegian). I checked, and indeed, there was a sub-folder in bin\Debug named No, containing a satellite assembly named Project.resources.dll in it.
Renaming the resource to end with .EN.xxx or .FR.xxx does, of course, exhibit the same behaviour.
As of MSBuild 16.9 you can include files like these by setting the WithCulture property to "false", as pointed out by #reduckted :-)
<EmbeddedResource Include="Resources.en.xml" WithCulture="false" />

"Run Custom Tool" for resx files in MVC2 project (from an external application/script)

I am trying to get the localization for my MVC project working with our existing infrastructure for editing string resources. We store all our resource string in database tables and have a front end web UI to edit them with, and an export application which generated the .resx files. This all works great, but I am having a little difficulty with a new project using MVC2 and VS2010.
I have asked another question on this, the answer to which almost got me there, but not quite.
I have now changed the resources to be in a Resources folder (instead of App_GlobalResources), as recommended by a number of people. And have the following settings against my .resx files ...
Build Action = Embedded Resource
Copy to Output Directory = Do not copy
Custom Tool = PublicResXFileCodeGenerator
Custom Tool Namespace = Resources
File Name = MyApp.resx
I have changed my export application to run the resgen.exe tool with the following parameters ...
string args = string.Format("/publicClass \"{0}\" /str:cs,Resources,{1},\"{2}\"", resourceFile, Path.GetFileNameWithoutExtension(resourceFile), csFilename);
... which generates an almost identical .designer.cs file as I get when I add the .resx file to my project initially. The only difference is the
The generated .designer.cs file differs slightly from the file I get when I run the resgen.exe tool from within my export application.
This is the code generated by VS2010 when I first add the .resx file to my Resources folder ...
public static global::System.Resources.ResourceManager ResourceManager {
get {
if (object.ReferenceEquals(resourceMan, null)) {
global::System.Resources.ResourceManager temp = new global::System.Resources.ResourceManager("Resources.MyApp", typeof(MyApp).Assembly);
resourceMan = temp;
}
return resourceMan;
}
}
... the difference when I run the resgen.exe tool is that is prefixs MyCompany.MyApp to the namespace in the constructor to ResourceManager
new global::System.Resources.ResourceManager("MyCompany.MyApp.Resources.MyApp", typeof(MyApp).Assembly);
Now, this to me seems to be a bug in the resgen.exe tool, because I've told it that the Namespace for my resources is Resources, not MyCompany.MyApp.Resources.
So, is there a fix/work-around for this problem?
The only thing I can think to do at the moment is to post-process the generated .designer.cs file with powershell and fix it!
Finally, I have solved the problem.
I decided to simplify things a bit by breaking my resources out in to a new assembly called Resources. I then added my resx files and set the properties for them as below ...
Build Action = Embedded Resource
Copy to Output Directory = Do not copy
Custom Tool = PublicResXFileCodeGenerator
Custom Tool Namespace = Resources
File Name = MyApp.resx
I then changed my export application to run ...
resgen MyApp.resx /str:c#,Resources,MyApp,MyApp.designer.cs /publicClass
... and to delete *.resources from the folder (created by the resgen.exe utility, but not needed)
This got rid of the prefix on the constructor to ResourceManager, and then i just added a reference to my new Resources assembly to my web application.
I've run a few tests to make sure all is good, including going in to the .designer.cs file and deleting one of the properties to cause a compiler error. Then re-ran my export app, and everything worked again.
So, I am a happy bunny!

Resources