Library tutorials & articles
Hosting Control Panel Applets using C#/C++
Wrapping Up
Time to go download the code, and perhaps toss me a vote so I know how to improve for the next article
Well it's time that you downloaded the source and demo projects if you haven't done so already. Nothing feels quite as good as running a project and seeing some results. So go have fun playing with the project and stepping around through some interesting coding ideas. I hope this helps some of you overcome some similar hurdles. I had a lot of fun writing the code and almost as much fun trying to explain it in this article. This is my official first posting online, probably will have many more, just gotta find the time. I've held back for sooooo long on posting from lack of time, not lack of ideas or knowledge. Look for more posts in the future.
Also, this being my first article, if you don't mind, give me some feedback, and possibly a vote. Have some kindness on my writing abilities as an author of articles, because as you may know I write code, not books. So chances are high that the article reads poorly, but hopefully the code is solid! :)
A quick peak at the Applet Viewer Window displaying the applets in large icon mode.
Now viewing in details view. Notice the name and description displayed for each applet.
And finally notice an applet that has just been launched by double clicking its icon. This demonstrates the applets are really being hosted by the applet engine.
What we learned
Let's review a few interesting concepts that we've covered:
- Calling unmanaged function pointers
- Dynamically loading unmanaged libraries at runtime
- Acquiring function pointers to unmanaged functions
- Translating C/C++ structures and data types to CLR compliant code
- Finding alternatives to unsafe code for the purposes of using sizeof
- Allocating/deallocating memory on the stack
- Understanding how applets can be manipulated programmatically
- Extracting strings and icons from embedded resources located in external unmanaged libraries
Things left, and known issues
- Thread calls to Open and Close, or make Asynchronous wrappers
- Figure out why certain applets return false after they close
- Find out where in the heck the Admin Tools Applets are located or how they are inserted into the control panel namespace (I think it's a Shell Extension, just haven't found it yet)
- Figure out how to work Marshal.GetUnmanagedThunkForManagedMethodPtr
- Figure out how to convert MAKEINTRESOURCE to C#
Related articles
Related discussion
-
Calling C++ DLL from C#
by Thushan Fernando (1 replies)
-
flash & axwebbrowser
by vik12 (0 replies)
-
Random number generation
by adib4u2000 (1 replies)
-
convert to dayofweek
by John F (0 replies)
-
(C# and ADO.NET) ExecuteNonQuery() problem
by gicio (0 replies)
Events coming up
-
Dec
6
Developing AJAX Web Applications with Castle Monorail
London, United Kingdom
Monorail is the model-view-controller engine of the Castle Project, bringing many of the best ideas of Ruby on Rails to the .NET world. In this talk, David De Florinier and Gojko Adzic show how Monorail makes it easy to develop .NET based AJAX applications, and how to use the Castle Project to build Web 2.0 applications effectively. Come to this session if you are a .NET web developer. Everyone is welcome!
Hi,
have also tried to convert the ambigous #define MAKEINTRESOURCEW(i) (LPWSTR)((ULONGPTR)((WORD)(i))) in C++ into C# but with no luck.
So I compiled a C++ program using MAKEINTRESOURCE and traced it to see what TYPE is really passed to UpdateResource(..) or similar resource accessing functions. What I hav efound that it actaully passes the interger value (Resource ID). For example if you have a Resource with "MYRES_ID" with ID 129
the compiled code actaully just passes the 129 as a WORD data.
So in C# while doing DllImport, I just chaged the Data Type for the Resource Id parameter which uses MAKEINTRESOURCE.
Here is what I did with UpdateResource
[DllImport("kernel32.dll")]
static extern bool UpdateResource(IntPtr hUpdate, string lpType, int lpName, ushort wLanguage, IntPtr lpData, uint cbData);
Notice the Third param which has been chaged from String to int. And It works!!! Now you will just pass (using my example as mentioned above) 129 instead of MYRESID, or directly MYRESID if it is defined somewhere to reprent 129.
Rezaul Kabir
shuvro@yahoo.com
Sorry, I had a comment, but it was a mis-understanding of the original post.
This article is very useful to understand how to call unmanaged function from C#.net. I have to do the same thing for my project but it seems little complex as it is passing user defined data type as an argument to the calling function. I will appreciate help with this.
Unmanaged C++ function which I am trying to call from C#.net app. is as below: (from the header file)
static void LibAction(const libString& actionXML, libString& returnXML, libError& libError);
libSting is a reference to the container class - wraps Standard Teplate Library String type. declared in the header file as below:
class LIBCLASSEXPORT LibString : public std::string
{
typedef std::string STL_STRING;
public:
// --- Constructors/Destructor ---
LibString() { ; }
LibString(const LibString& S);
LibString(const char* s);
LibString(char s);
LibString(istream&);
LibString(const STLSTRING & S) : STLSTRING(S) { ; }
virtual ~LibString();
libError is a reference to the container class which is used for the error handling.
How do I call this function from C# windows application.
Below is how I am trying to declare above function in my C# app.
[DllImport(@"C:\Test\dlls\Lib.dll", EntryPoint="LibAction")]
public static extern void LibAction(string actionXML, string returnXML, string libError);
Instead of string I should be passing ref to the libString. I am not sure how do I do that in C#.
Please help.