|
Hi,
IMO you should not attempt to call an event handler explicitly; one reason is you would have to provide fake parameters, sender wouldn't be a problem, the particular EventArgs may prove more difficult to fake. Unless of course you're absolutely sure the handler doesn't (and never will) use its parameters.
There are two alternatives I would recommend:
1. some events can be triggered by calling an appropriate method, e.g. Button.PerformClick().
2. when the functionality of an event handler is also useful outside the normel event handling, refactor it into a separate method, call that from the event handler, and from anywhere else you'd like to call it.
|
|
|
|
|
Thanks for the reply! My problem I have with you're second suggestion is that some of the windows contain third party controls, and are basically black boxes, so I cannot move that functionality into a seperate method. You're first suggestion seems promising, is there a way to do something like that, but with key stokes instead of Button.PerformClick()? Thanks!
|
|
|
|
|
yes, you can send key strokes and mouse actions to any window you like, whether in your own app or another one. However may be tricky, and error prone; the user (assuming there is one) may well interfere with your automation (or vice versa), so I do not recommend it in general.
If you must, there is the SendKeys class; its SendWait() method is useful. What I have been doing for mouse automation mostly is based on Win32 functions such as SetCursorPos() and SendInput(), both in user32.dll
WARNING: localization changes the shortcut letters that can be used to steer menu's and buttons.
|
|
|
|
|
We have been bringing our old C++ code that uses MFC into the .NET world by compiling it into a mixed-mode assembly. We have found that when this assembly is loaded in an AppDomain e.g. by NUnit or by ASP .NET, the dll is not unloaded when the AppDomain is unloaded. The host application can load the dll many times, and may eventually run out of memory.
I have found that this is due to static data. If I make a simple mixed mode assembly with no static data, or with a static object with a default constructor, the dll is unloaded correctly. If the object has a non-trivial constructor, then the dll is not unloaded.
Even the simplest MFC dll has a static CWinApp derived object, so I don't think it would be possible to remove this kind of static data from our mixed-mode dll without a removing its dependency on MFC (a task that is too big to contemplate at the moment). Is there any other way to force the mixed-mode dll to be freed when the AppDomain is unloaded?
|
|
|
|
|
Hi,
I am able to call the funtion successfully, when linked the dll implicitly.
But when I am linking explicitly using LoadLibrary and GetProcAddress, GetProcAddress returning NULL value.
what mightbe the problem, I am using the same function name as I have used while implicit linking.
regards,
Charan
|
|
|
|
|
Are you saying it works when you link statically? Have you exported the functions that are eligible to call?
Best wishes,
Navaneeth
|
|
|
|
|
I'm quite new to programming C++ and I ran into a problem. I'm working on a program in which some objects are being used by different functions, in separate files. I created the objects in a header file and can access them from a source file. However, I would like to have an instance of the object available for access from all of my functions. How can I create such objects / instances?
Any help is highly appreciated.
|
|
|
|
|
I'm not sure I fully understand your question, but the usual way of doing this is to pass a reference to the object to each function that requires it. Making objects globally visible is generally less safe. For example:
int main()
{
CType* object = new CType();
BOOL result = MyFunc(object);
}
BOOL MyFunc(CType* anObject)
{
int rc = OtherStuff(anObject);
}
txtspeak is the realm of 9 year old children, not developers. Christian Graus
|
|
|
|
|
Thanks for the quick answer Richard!
I tried to do this, but the problem I ran into is the following:
I have a sourcefile "program.cpp" with header "program.h" in which my classes are defined. I want to pass an object from "program.cpp" to "function1.cpp", by:
double^ function1result = function1(CType^ object)
In function1 I should now write the function as:
double^ function1(CType^ object){}
When I do that, I get an "undeclared identifyer" error. When I include the "program.h" header where the class is defined I get a "type redefinition" error. So my question is how to pass these objects in a way that such errors are avoided.
|
|
|
|
|
Arjen Tjallema wrote: When I include the "program.h" header where the class is defined I get a "type redefinition" error.
This means you are defining the type (presumably CType ) in more than one place in your source code. Without seeing more of your header and source file it's difficult to be more explicit.
txtspeak is the realm of 9 year old children, not developers. Christian Graus
|
|
|
|
|
Thanks again! I'll put some bits of my code here to clarify my question.
The "program.h" header contains a class clGlobals:
public ref class clGlobals
{
public:
double^ airDensity;
double^ waterDensity;
double^ gravitation;
};
In my "program.cpp" source I create an instance, put some values in it and (try to) call function1:
clGlobals^ globals = gcnew clGlobals();
globals->airDensity = Convert::ToDouble(1.025);
globals->waterDensity = Convert::ToDouble(1025);
globals->gravitation = Convert::ToDouble(9.81);
double^ load = function1();
The "function1.h" header contains a declaration of the function:
double^ load(clGlobals^ global);
And the "function1.cpp" source contains the actual function:
double^ load(clGlobals^ global)
{
return load;
}
I hope this clarifies my question.
|
|
|
|
|
I don't quite get some of this syntax. What does function1() do and where is it defined? Why does function load() not return a double, or does it?
txtspeak is the realm of 9 year old children, not developers. Christian Graus
|
|
|
|
|
O, excuse me, I made a mistake in my previous post.
The "function1.h" header code should be:
double^ function1(clGlobals^ global);
And the "function1.cpp" source code should be:
double^ function1(clGlobals^ global)
{
double^ load;
return load;
}
I hope it is understandable now.
|
|
|
|
|
Arjen Tjallema wrote: I hope it is understandable now.
Yes, and after correcting this line from:
double^ load = function1();
to:
double^ load = function1(globals);
it compiles and runs fine. If you still have a problem then it is not within this code.
txtspeak is the realm of 9 year old children, not developers. Christian Graus
|
|
|
|
|
That's strange, I get the following error when trying to compile:
function1.h(1) : error C2065: 'clGlobals' : undeclared identifier
I have put the four files in a new project to isolate it from the rest of my code, but still I get this error message. Do yo have any clue where to look for the problem?
|
|
|
|
|
The best way to resolve this is to add the following lines:
#include "program.h"
#pragma once
at the beginning of function.h . And add:
#pragma once
at the beginning of program.h .
This should ensure that the class definition for clGlobals is found in any file that includes function.h . Also the #pragma once statements ensure that the header files are processed once only per compilation unit, even if they are found in #include statements more than once.
txtspeak is the realm of 9 year old children, not developers. Christian Graus
|
|
|
|
|
That indeed solves the problem.
Thanks a lot for your help!
|
|
|
|
|
Arjen Tjallema wrote: Thanks a lot for your help!
You're welcome; it's good to find the solution occasionally!
txtspeak is the realm of 9 year old children, not developers. Christian Graus
|
|
|
|
|
Hi,
I have developed a small application. But it gives the above error
It is declared in another class named "CPassword"
SqlConnection ^connect = gcnew SqlConnection();
connect->ConnectionString = ConfigurationManager::ConnectionStrings["SQLConnection"]->ConnectionString;;
SqlCommand ^cmd = gcnew SqlCommand();
cmd->CommandType = CommandType::StoredProcedure;
cmd->CommandText = "GetUserPassword";
DataSet ^dtSet = gcnew DataSet();
try
{
connect->Open();
SqlDataAdapter ^adp = gcnew SqlDataAdapter();
adp->SelectCommand = cmd;
cmd->Parameters->Add(gcnew SqlParameter("@user_id",SqlDbType::VarChar));
cmd->Parameters["@user_id"]->Value = userID;
adp->Fill(dtSet, "Password");
return dtSet;
}
And I am calling this function from another class
CPassword ^objPassword = gcnew CPassword();
DataSet ^dtSet = gcnew DataSet();
dtSet = objPassword->fn_ReturnPassword(txtUserId->Text);
Plese help....
Thanks to all
|
|
|
|
|
Can you post the entire CPassword function and the DataSet class...it would help to understand your problem
the problem can be in the try catch.....how do you implement the catch (not reported in the forum)
|
|
|
|
|
Thank u for ur reply.
Actually I solved my problem by not returning 'DataSet' object, it pass as a reference in function parameter.
|
|
|
|
|
Ok, so first off, I'm really new to C++ so please let me know if this is in the wrong forum. I'm trying to finish a small project using Visual Studio 2008 Professional and I'm running into an error:
"The application has failed to start because its side-by-side configuration is incorrect. Please see the application event log for more detail".
So this is roughly what I'm doing:
1. Create a new Windows Forms Application project
2. Add some Labels (one of them is dynamic and displays the current time), some bitmap pictures, and a clickable hyperlink
3. Create a version.rc file to display version info on the compiled .EXE file.
4. After making sure it runs in Debug mode, I compile it in Release mode
The compiled .EXE file works just fine on my 64-bit Windows 7 box I'm developing on, and it works fine on several 32-bit Windows 7 machines I've tested. It also worked on an XP box I got my hands on. However, when I had some others here at work test it, they got the above error on a Windows Vista machine and on a Windows XP machine.
So what gives? How can I create a simple little app that we can launch on all the various newer (XP on up) operating systems without having to rely on a prerequisite add-on being installed? I'm just looking to create some basic user notification windows. Nothing too fancy.
Is there something I need to change to get this thing to work consistently on all the OSes? Or do I need to do something other than a Windows Forms Application?
Thanks!
|
|
|
|
|
|
I think I've got it working now. I ended up copying the files located in "C:\Program Files (x86)\Microsoft Visual Studio 9.0\VC\redist\x86\Microsoft.VC90.CRT" into the same folder as my .EXE and it now seems to be working on all the machines I've tested.
|
|
|
|
|
Instead of manually copuing the required CRT files, you might want to look into using a Setup and Deployment project. Right-click on the project and select Add Merge Module, and select the module corresponding to the CRT file you listed above. If there are any components your app depends on, you can add those to the project as well. When the user runs the generated setup.exe file, it will autoamtically install the prerequisites (including the merge module), and then install your app.
Regarding the prerequistes, there's a handy utility here[^] that allows you to build custom prerequisite packages for VS.
Dybs
The shout of progress is not "Eureka!" it's "Strange... that's not what i expected". - peterchen
|
|
|
|