Unmanaged DLL (exporting Dialog) + Class Library (DLL) + no Windows Style/Themes - c#

I have a managed application TestApplication.exe in C# and Application.EnableVisualStyles() is allready called.
I have a Class Library MySharedCode.dll also in C# which uses [DLLImport()] to import some External dialogs out of an unmanaged dll.
Well, now I am using (add reference) MySharedCode.dll in my TestApplication.exe and call a function MyTestConfigDlg() out of it. TestClass.MyTestConfigDlg();
OK, everything works fine and I get my dialog, but the dialog has NO XP style/themes?
I just wanted to see if it's general problem with managed/unmanged modules, so I used the [DLLImport()] to call the same MyTestConfigDlg() dialog but this time directly in my TestApplication.exe! WOW! Worked as I expected. The Dialog was in XP Style/Themes!
so, anybody here who can help me out?
FYI: I also tried (just for test) to call MessageBoxA() API call in my Class Library Dll which later called by my TestApplication.exe and the MessageBoxA() had also no Style/Themes!
Thanks in advance!

Usage of the Application.EnableVisualStyles() applies to certain windows controls such as ListBox, ListView, Menu, Buttons, to make it in line with the XP themes control from the start, if it was running on Vista and later, it would conform the controls to that style also. In short I do not know how do you mean the dialog has no XP/Themes support when invoked directly via the References, yet when you used DllImport keyword to import the function it worked, that is unusual. Usually the usage of DllImport is for unmanaged code API, but somehow it picked it up...I do recall that there was a bug with the .NET 1.1 framework in that if you called Application.EnableVisualStyles(), it failed to work, unless a call to Application.DoEvents() was invoked between enabling the Visual styles and instantiating a winforms, maybe in your case, when instantiating a dialog, perhaps that could solve it by calling Application.DoEvents(), other than that, I am out of ideas...
Hope this helps,
Best regards,
Tom.

Related

Locating a ToolStripStatusLabel in a third party WinForms process

I've been asked to create a little tool to help automate a basic 3rd party WinForms application.
So far I've managed to overcome many hurdles but this one is by far one of the most frustrating of them all (And spending 8 hours researching only to find out LVM_GETITEMTEXT was returning an LVITEM struct with 64-bit pointers was very frustrating) - I can't seem to find any way at all to get any kind of reference to a ToolStrupStatusLabel in the third party application's StatusStrip.
The only indication I have that the application has finished it's assigned task is when the StatusStrip is updated to show it has been finished. I can't reliably automate it's operation if I can't find out when it finishes one job and proceeds to another.
Is there any message I can SendMessage() to the application? Any function I can call? Anything that will help me locate the text on this label so I can gain some insight into the application's status?
The automation tool is programmed in C#/Winforms with pInvoke for various Windows functions. I've also created my own DLL in C++ to assist with obtaining data from the LVITEM struct, so C++ workarounds are possible too.
This isn't going to work. The ToolStripItem derived classes are special, they do not derive from Control. They don't have their own window handle, they use the window of their host to draw themselves. Where the host is a Control, like ToolStrip or StatusStrip in your case.
This makes them unusable from traditional UI automation tools that require a window handle. The only way to commandeer them is by injecting a DLL that uses reflection to get a ToolStripItem reference. This exists, the Managed Spy++ tool uses this technique. Source code is provided so you can put your own together, you'll want to leverage the ManagedSpyLib which does the heavy lifting.

Why console application is taking more time than forms application in c#

I have created a Class Library (called as GNGEngine.dll) which performs some image processing stuff. This dll contains a function ProcessBitmap() as the main function to do searching for specific pattern. I have tested the engine by creating anothers forms application and taking the reference of the dll. I am calling the ProcessBitmap() method of dll by clicking on the button. The forms application takes 8secs to process the image completely.
Now as per clients requirement i have created an exe (console application) file GNGEngineRunner.exe which takes the image filename as the argument. I have created the object of dll class and called the method ProcessBitmap() and passed the file for its processing. The same image now takes almost a minute to its processing.
Is there any specific reason, why it is taking too much time?
Thanks for sharing your valuable time.
First of all you should attach a profiler to see what is happening. If you don't have one you can use the trial version at http://www.red-gate.com/products/dotnet-development/ants-performance-profiler/
Visual Studio has a performance profiler built in, but depending on your VS version it could be anything from nonexistant, crappy or good.
Second, there should be no reason for this. I would guess that the problem is that you have exceptions being thrown because of reference to a non-existing form/GUI-object or similar. Execution-wise Console or WinForm is 100% the same and you can even mix them in one app. The only difference is some references and the fact that you create a console window instead of a form.
Feel free to add more details and possibly some code.
You haven't told us what you're doing or how you're doing it, which makes it near impossible to answer really... but your first step should be to get some appropriate traces of what's going on. Insert a judicious amount of logging (including a timestamp) and then it should be reasonably clear where in your process the time is going. Run it in both the console version and the Windows Forms version. Then concentrate on the bottleneck - possibly asking another SO question with more details.

Intercepting and hiding a window before it appears

I am developing a (in-process) plug-in to application and as part of my plug-in I want to replace the application's tool-tips with my own. However, there is no API available for me to do so, so I've decided to go low-level.
I know the window class of the tool tip, but the question is, how do I detect it being created and how do I close it afterward?
Here's what I thought to do so far:
Create a system-wide hook on WM_CREATE
When caught, check the class and the process of the WM_CREATE target
Verify it is indeed the window I care about:
If the process is the one my plug-in is sitting in
And if the class is of the correct type
And if the correct application is in focus (in case of multiple applications)
Send a WM_DESTROY to the created window and create my own window at its position instead
How does it sound? Assuming there is indeed no API to handle the tooltips, is there a simpler way for what I need?
Thanks!
P.S Tagged as C++/C# as I intend to write it in these 2 languages (C++ for system-wide hook, C# for everything else)
If you know the type of the window you want to block, you can simply subclass it and handle the destruction in your own WndProc. Use GetClassLongPtr() with GCL_WNDPROC on the tooltip class, use SetClassLongPtr() with GCL_WNDPROC to set your own WndProc and have it call DestroyWindow() on WM_CREATE and call the old WndProc for the rest..
This won't work. Consider the view of the application that you're replacing the tooltips of and assuming that you could tell it to destroy windows. What will happen when the app decides that it needs to close the tooltip? It doesn't have the handle of your new window, it has the handle of the old window, which you've destroyed. Time for things to go wrong.
Your plugin system needs to explicitly support replacing the tooltips if you want this to work smoothly. Perhaps an optional part of the plugin framework could be a RequestTooltip function. If it doesn't exist, or returns null, or whatever then the default tooltips are used, otherwise your plugin provided ones are used.

How to eliminate Unhandled Exception dialog produced by 3rd party application

I'm working with a 3rd party executable that I can't recompile (vendor is no longer available). It was originally written under .Net 1.1 but seems to work fine under later versions as well. I launch it using Process.Start from my own application (I've tried p/invoke CreateProcess as well with the same results so that's not relevant)
Unfortunately this 3rd party app now throws an unhandled exception as it exits. The Microsoft dialog box has a title like "Exception thrown from v2.0 ... Broadcast Window" with the version number relating to the version of .Net it's running under (I can use a .exe.config file to target different .Net versions, doesn't help).
The unhandled exception dialog box on exit doesn't cause any real problems, but is troubling to my users who have to click OK to dismiss it every time. Is there any way (a config file option perhaps) to disable this dialog from showing for an app I don't have the source code to? I've considered loading it in a new AppDomain which would give me access to the UnhandledException event but there's no indication I could change the appearence of the dialog. Maybe someone knows what causes the exception and I can fix this some other way?
You could write a wrapper application that calls the 3rd party application directly and launch your application using Process.Start.
Then in your wrapper application trap the exception so the users won't see the error message.
If it hasn't been obfuscated you may be able to decompile it? This is of course illegal etc. but if the company has actually gone bankrupt then no one is there to pursue it. It is reasonable for you to support the code if you have no other choice.
Reflector might give you a clue as to why the code crashes as well, perhaps you need to do something or call it with a parameter to stop it from doing so?
Next time don't try to use something without source code :)
A workaround is to follow Chris' suggestion. A wrapper application can make use of such code,
http://blog.jtbworld.com/2007/06/windows-live-writer-spell-checking.html
Find the old application executable.
Execute it in an AppDomain object created in the wrapper application.
Bind your application unhandled exception handler to this AppDomain object's UnhandledException event.
http://msdn.microsoft.com/en-us/library/system.appdomain.unhandledexception.aspx

Communicate between a COM DLL and C#

I asked a question the other day regarding overlay icons. With help, I figured out how to get that working.
Here's how an icon overlay works (as far as I understand): Before the shell draws an icon it contacts all the icon overlay handlers in the system to determine whether it should draw an overlay on the that particular icon.
My setup:
I have a registered Shell Extension (Icon Overlay Handler) that I want to use to display icon overlays. Also, I have a .NET application (C#) that will write to a database (SQLite, most likely) with the names, etc. of all the files and folders I want to display an overlay on.
My problem is:
How do I get the Shell Extension (I think its basically a COM DLL) to call back into my .NET application? Or is that overkill and should I just have the Shell Extension read from the database directly?
Possible solutions?
Have the Shell Extension (icon overlay handler) read the database and determine whether to show overlay.
Have the Shell Extension call back into a .NET application to determine whether to show the overlay.
I hope this makes sense, if not, I'll try to elaborate.
A COM DLL cannot talk to .NET assembly directly. You might need to expose your .NET assembly as COM object and talk to this COM object instead. But this might in fact be an overkill in your scenario. Another option would be to expose the functionality that talks to the database in your .NET assembly as some interoperable service (WCF?) that might be called from the shell etension.
Yes, if you mark your assembly as COM visible and run regasm, then your COM dll can import the generated type library and call CoCreateInstance to get a reference to your .NET classes.
HOWEVER, it is a little scary to pull the .NET framework into a shell extension. So you might want to make sure that the .NET code is invoked out-of-process... ie CLSCTX_LOCAL _SERVER to CoCreateInstance.

Categories

Resources