|
You need to handle it however is appropriate to your application.
Moving a file that's in use could break the application that has the
file open - that's why it's not allowed.
Mark
Mark Salsbery
Microsoft MVP - Visual C++
|
|
|
|
|
I have a C++ application that I would like to use the managed DateTime class. However, I would like to add an extension method to the class, call it Foo(), that returns a double. I know that in C#, you can write the class as follows:
using System;
namespace ManagedCode {
public static class DateTimeExtension {
public static double Foo(this DateTime dt) {
return 83.5;
}
}
} The problem is that I cannot figure out how to call the extension method defined above from C++. I have attempted the following, but get the error "error C2039: 'Foo' : is not a member of 'System::DateTime'":
#using "ManagedCode.dll"
#using <mscorlib.dll>
#using <system.dll>
using namespace ManagedCode;
using ManagedCode::DateTimeExtension;
using System::DateTime;
public int main(void) {
DateTime foo;
double temp = foo.Foo();
return 0;
} I also know the way I would have done this in C++ 8 years ago would be as follows:
#using <mscorlib.dll>
#using <system.dll>
class DateTime : public System::DateTime {
public:
DateTime();
double Foo();
}; But here, I get the error that I cannot create an unmanaged class that inherits from a managed class. OK, fine. Next I tried the following:
#using <mscorlib.dll>
#using <system.dll>
ref class DateTime : public System::DateTime {
protected:
~DateTime();
public:
DateTime();
!DateTime();
double Foo();
}; But here, I get the error that I cannot inherit from a sealed class. Does anyone know how I can accomplish the goal of getting a DateTime class into C++ that exports an additional method, Foo()? Thanks in advance,
Sounds like somebody's got a case of the Mondays
-Jeff
|
|
|
|
|
You could wrap a System::DateTime in another class.
Here's an example of a ref class wrapper:
public ref class MyDateTime
{
System::DateTime dateTime;
public:
static operator System::DateTime(MyDateTime ^val)
{
return val->dateTime;
}
MyDateTime()
{
dateTime = System::DateTime::UtcNow;
}
MyDateTime(System::DateTime datetime)
{
dateTime = datetime;
}
void Foo()
{
}
};
Mark Salsbery
Microsoft MVP - Visual C++
|
|
|
|
|
I considered that, but decided that it was no different than just adding a classless function unassociated with DateTime. Another solution would be to re-implement the entirety of the DateTime class, where I publicly expose the underlying DateTime object's methods and properties with the same signatures, but my DateTime return type. This is a lot of work that should be able to be done in about 10 lines of code using inheritance or extension methods. Is there some way to incorporate the class from C# AFTER I add the extension method "Foo"? Or, is there some way to define an extension method in C++? Thanks for the reply,
Sounds like somebody's got a case of the Mondays
-Jeff
|
|
|
|
|
Whatever works for you
If I come up with an elegant solution I'll let you know - right now, I've got nothing.
Mark
Mark Salsbery
Microsoft MVP - Visual C++
|
|
|
|
|
Hi Jeff,
I am afraid it can't be done. I quote:
"Extension methods are a really nice syntactic sugar. They're not really added to the class, as we can see, but the compiler makes it feel like they are."
from here.[^]
So it is a new C# thingy, nothing C++/CLI currently is capable of.
|
|
|
|
|
I have three forms A,B and C. C has a webbrowser contorl
Upon a certain event form A opens a url in webbrowser of C.Upon some other event FormB should open a url in same webbrowser of C.. How do I achieve the desired behaviour.
Perhaps, by creating a global instance of form C. If so, where should I declare the global instance, in form A,B or C?
My project is a CLR winForms project.
Any pointers would be appreciated.
|
|
|
|
|
I want to write a windows service (myService) by using C++/CLI (Visual Studio 2005). This myService can use MFC function for OLE Automation.
Just for a first try, I did the following project configuration and coding:
• Creating a Windows Service under C++/CRL
• Adding ServiceInstaller with start type automatic and sereviceprocessInstaller with Account Local System
• Setting MFC in a Shared DLL
• Setting Common Language Runtime Support (/clr)
• Setting Multithreaded-Debug-DLL (/MDd)
• Adding #include <afxdisp.h> in stdafx.h
Compile is always successful. But when I use myServie.exe –Install to install my windows service in Visual Studio 2005 Command Prompt, I always get the following exceptions
When debugging:
Unhandled exception at 0x78374588 (mfc80ud.dll) in myService.exe: 0xC0000005: Access Violation reading location 0x00000000.
In Visual Studio 2005 Command Prompt:
Unhandled exception: System.AccessViolationException
Attempted to read or write protected memory.
This is often an indication that other memory is corrupt.
at _wWinMainCRTStartup()
Does anyone know the reason? Where am I wrong?
Many thanks for any help!
|
|
|
|
|
Try adding the following lines to your _tmain before the call to ServiceBase::Run()...
AfxInitialize();
AfxWinInit(::GetModuleHandle(NULL), NULL, ::GetCommandLine(), 0);
Beyond that, there's no guarantee the MFC classes you want to use are going
to work in your service. Some, like the database classes, do work. Most don't -
like anything involving windows (CWnds).
Mark
Mark Salsbery
Microsoft MVP - Visual C++
|
|
|
|
|
Hi Mark!
Thank you for you reply!
I added such code like that you said.
AfxInitialize();
AfxWinInit(::GetModuleHandle(NULL), NULL, ::GetCommandLine(), 0);
ServiceBase::Run(gcnew ccs_clientWinService());
But the result is same as without that.
Anyway thank you so much! hope you still have futher ideas for me.
|
|
|
|
|
I'd need to see the call stack at the time of the exception...
Without it I could only guess.
Mark
Mark Salsbery
Microsoft MVP - Visual C++
|
|
|
|
|
How can I record the call stack at the time of the exception?
|
|
|
|
|
When debugging I saw the program stops at winmain.cpp below and the line if (!pThread->InitInstance())
// This is a part of the Microsoft Foundation Classes C++ library.
// Copyright (C) Microsoft Corporation
// All rights reserved.
//
// This source code is only intended as a supplement to the
// Microsoft Foundation Classes Reference and related
// electronic documentation provided with the library.
// See these sources for detailed information regarding the
// Microsoft Foundation Classes product.
#include "stdafx.h"
#include "sal.h"
/////////////////////////////////////////////////////////////////////////////
// Standard WinMain implementation
// Can be replaced as long as 'AfxWinInit' is called first
int AFXAPI AfxWinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance,
__in LPTSTR lpCmdLine, int nCmdShow)
{
ASSERT(hPrevInstance == NULL);
int nReturnCode = -1;
CWinThread* pThread = AfxGetThread();
CWinApp* pApp = AfxGetApp();
// AFX internal initialization
if (!AfxWinInit(hInstance, hPrevInstance, lpCmdLine, nCmdShow))
goto InitFailure;
// App global initializations (rare)
if (pApp != NULL && !pApp->InitApplication())
goto InitFailure;
// Perform specific initializations
if (!pThread->InitInstance())
{
if (pThread->m_pMainWnd != NULL)
{
TRACE(traceAppMsg, 0, "Warning: Destroying non-NULL m_pMainWnd\n");
pThread->m_pMainWnd->DestroyWindow();
}
nReturnCode = pThread->ExitInstance();
goto InitFailure;
}
nReturnCode = pThread->Run();
InitFailure:
#ifdef _DEBUG
// Check for missing AfxLockTempMap calls
if (AfxGetModuleThreadState()->m_nTempMapLock != 0)
{
TRACE(traceAppMsg, 0, "Warning: Temp map lock count non-zero (%ld).\n",
AfxGetModuleThreadState()->m_nTempMapLock);
}
AfxLockTempMaps();
AfxUnlockTempMaps(-1);
#endif
AfxWinTerm();
return nReturnCode;
}
/////////////////////////////////////////////////////////////////////////////
|
|
|
|
|
|
Is the code you are using in your service tested? The actual operations of the service should be developed and tested in an environment external to the Service process before ever attempting to integrate and execute it in a Service process.
led mike
|
|
|
|
|
Yes, I want my Windows Service to use a dll created in Visual C++ 6.0.
This dll uses MFC to implement OLE Automation (reading data from a server application).
As I learned from It just works (using unmanaged C++ in C++/CLI), I copied dll and lib files to the windows service project, included header files and added lib file to additional dependence. When compiling I got error message, MFC should be set to MFC in a Shared DLL. After I did that I got error messages described at http://www.gregcons.com/KateBlog/DontCompileMFCAppsWithClrpure.aspx[^] when compiling. After I changed the setting to Common Language Runtime Support (/clr), the compile got successful, but as said I got problem to install this windows service.
I located the problem as I wrote in my first post. It seems to me if I set MFC in a Shared DLL
and Common Language Runtime Support (/clr), and include one MFC header file (without dll, lib and ohter header files), I will get this problem when intalling.
What do you think?
Thank You!
|
|
|
|
|
xuesyuan wrote: What do you think?
Well the first thing I think is that it does not sound like you tested as I asked you. If this was my project I would create a Win32 Console Project in VS2005 and attempt to use the Visual C++ 6 DLL from that project before I ever tried to create and run a Service.
Secondly
xuesyuan wrote: When debugging:
Unhandled exception at 0x78374588 (mfc80ud.dll) in myService.exe: 0xC0000005: Access Violation reading location 0x00000000.
xuesyuan wrote: Yes, I want my Windows Service to use a dll created in Visual C++ 6.0.
You used MFC version 8 to link to a DLL linked to MFC version 6. First off I wouldn't do that. However it may in fact work anyway if you have the old MFC DLLs installed on the machine you are trying to execute the DLL on. Do you? If not you should try that first. If the problem persists you should search MSDN (using Google) for information on using a MFC 6 DLL from a VS2005 application.
led mike
|
|
|
|
|
Thanks for your ideas and suggestion!
|
|
|
|
|
xuesyuan wrote: I want my Windows Service to use a dll created in Visual C++ 6.0.
As led mike mentioned, that's not going to work, except under
extremely controlled circumstances.
You'll have two MFC libraries and two CRT libraries running at the same
time. You won't be able to share objects between them without knowing exactly
what you're doing.
MFC is NOT supported in services, so it's up to you to study the source
code for all MFC classes you use and make sure they work in a service.
That means only simple wrapper classes, like CDatabase/CRecordset are.
If you can't upgrade the DLL to your current MFC version, your best bet
is to implement the service using Win32 APIs instead of C++/CLI, using VC6.
Mark Salsbery
Microsoft MVP - Visual C++
|
|
|
|
|
I have 3 columns in my listview. i have tied the cloumn widths to change appropriately whenever the listview resizes.
However, when I resize the columns, an additional column appears on the right. How do I stop the additonal column from appearing, and be able to resize the 3 columns only.
|
|
|
|
|
I believe you can make the rightmost column automagically resize to
fill the remaining space by setting its width to -2. Then you'd
only need to resize the first two columns - the third will follow.
Mark
Mark Salsbery
Microsoft MVP - Visual C++
|
|
|
|
|
Hi All
Actually am C# developer.now i want to write the code in C++ for "writing XL sheet from C++".Using introp dll we can use in c#.it may be same in c++.but i dont know perfectly....please give me any link related this or code....its ver urgent...
Thanx in Advance
Mohan.T
Mohan t working for N.I.C
|
|
|
|
|
Microsoft::Office::Interop::Excel::Application^ exl = gcnew Microsoft::Office::Interop::Excel::ApplicationClass();
FileInfo^ file = gcnew FileInfo("c:\\leonigah.xls");
Workbook^ wb = exl->Workbooks->Open("c:\\leonigah.xls", 0, false, 5,"", "", true, Microsoft::Office::Interop::Excel::XlPlatform::xlWindows, "\t", false, false,0, true, true, 0);
Worksheet^ ws = static_cast<Worksheet^> (exl->ActiveSheet);
Range^ rn = (Range^)ws->Cells[2, 4];//2=row;4=column
rn->Value2 = "leonigah";
Nigah M Manzoor
modified on Wednesday, July 23, 2008 8:13 AM
|
|
|
|
|
Hi, I'm using Visual Studio 2005 C++/CLI. This should be an easy one. I have a textBox that has some number in it. When I press the (+) or (-) key on the far right keypad I can use ::Keys::Add and Keys::Subtract to recognize that those keys had been pressed and I can increment and decrement the number, and then put number.ToString() back in the textBox but the "+" or "-" character gets added to the textBox (and I don't want that). How do I restrict the characters that can be added to a textBox->Text String^?
Thanks,
Buck
|
|
|
|
|