|
delegate int BrowseCallBackProcDelegate(
unsigned/*HWND*/ hwnd, unsigned int/*UINT*/ uMsg
, unsigned/*LPARAM*/ lParam, unsigned/*LPARAM*/ lpData);
[STAThreadAttribute]
int main(array<system::string ^=""> ^args)
{
Form1^ pForm1=gcnew Form1();
// Enabling Windows XP visual effects before any controls are created
Application::EnableVisualStyles();
BrowseCallBackProcDelegate^ BCBD =
gcnew BrowseCallBackProcDelegate(Form1::BrowseForFileCallBackProc);
pin_ptr<browsecallbackprocdelegate^> pBCBD= &BCBD;
IntPtr delegatePointer =
Marshal::GetFunctionPointerForDelegate(BCBD);
pForm1->m_pbi->lpfn=static_cast<bffcallback>(delegatePointer.ToPointer());
// Create the main window and run it
Application::Run();
return 0;
}
http://blog.joycode.com/jiangsheng
http://blog.csdn.net/jiangsheng
Command what is yours
Conquer what is not
---Kane
|
|
|
|
|
Thank you for trying but my application is written in C#.
Only the hook Dll is written in C++/CLI because it's simply not possible to write a global hook entirely in managed code.
|
|
|
|
|
Thanks to Tomas Restrepo the problem is solved.
He wrote:
Florian,
> thank you for your reply but I'm afraid it doesn't work. The Dll project
> compiles fine but as soon as I run my C# test app I get an
> ArgumentException ("Object contains non-primitive or non-blittable
> data."). Seems like GCHandle::Alloc() has a problem with my delegate ...
> Any suggestions?
Ahh, true, you are completely correct.
Thinking more closely to what you want to do, I realize you might not need
to actually pin the delegate at all; just keep a reference to it alive so
that it is not garbage collected (it actually does *not* matter that it
moves around in memory, as that won't affect the call to it from unmanaged
code in this particular case).
I looked around to verify this, and found what I was looking for:
http://blogs.msdn.com/cbrumme/archive/2003/05/06/51385.aspx
Here, Chris Brumme explains in detail:
"Along the same lines, managed Delegates can be marshaled to unmanaged code,
where they are exposed as unmanaged function pointers. Calls on those
pointers will perform an unmanaged to managed transition; a change in
calling convention; entry into the correct AppDomain; and any necessary
argument marshaling. Clearly the unmanaged function pointer must refer to a
fixed address. It would be a disaster if the GC were relocating that! This
leads many applications to create a pinning handle for the delegate. This
is completely unnecessary. The unmanaged function pointer actually refers
to a native code stub that we dynamically generate to perform the transition
& marshaling. This stub exists in fixed memory outside of the GC heap.
However, the application is responsible for somehow extending the lifetime
of the delegate until no more calls will occur from unmanaged code. The
lifetime of the native code stub is directly related to the lifetime of the
delegate. Once the delegate is collected, subsequent calls via the
unmanaged function pointer will crash or otherwise corrupt the process. In
our recent release, we added a Customer Debug Probe which allows you to
cleanly detect this - all too common - bug in your code. If you haven't
started using Customer Debug Probes during development, please take a look!"
Hope this helps!
--
Tomas Restrepo
tomasr@mvps.org
http://www.winterdom.com/
My response:
Hi Tomas!
> Hope this helps!
Problem solved! :-) Thank you!
It had nothing to do with the delegate at all. The problem was the return
value in my unmanaged callback. The hook worked till the app window lost
focus. After reactivating the window my delegate didn't receive any
keystroke messages. I assumed that this was because the delegte has been
relocated on the heap. Actually at this point it should have been clear that
I'm wrong. My application didn't crash which most likely would have happend
if my function pointer was pointing "somewhere" in the memory.
I have a few more problems now but I think I can figure them out on my own.
Thanks again!
Regards,
Florian
|
|
|
|
|
How can i stop program from loading if another instance of that program exist.
|
|
|
|
|
|
Search this site - or pretty much any code site - for the word singleton.
Cheers,
Tom Archer - Visual C++ MVP
Archer Consulting Group
"So look up ahead at times to come, despair is not for us. We have a world and more to see, while this remains behind." - James N. Rowe
|
|
|
|
|
I am creating an aplication, that requires .NET Framework 1.1. I know how to check if framework is installed. I don't want to create a large instaler. My application only has about 120KB. I have use unmanaged command to detect if is installed. Then i have tried on another commputer with Windows 2000 without .NET Framework. And i got an error, that it wants to have mscorelib.dll. You can check a sample below to know what i think.
I hope you understand what i want to know.
#include "stdafx.h"
#include "Form1.h"
#include <windows.h>
using namespace CDDvdOrganizer;
bool IsDotNetInstalled()
{
HKEY key;
bool bRunInstall = true;
if (ERROR_SUCCESS == ::RegOpenKeyEx(HKEY_LOCAL_MACHINE, "SOFTWARE\\Microsoft\\.NETFramework\\policy\\v1.1", 0, KEY_READ, &key))
{
bRunInstall = false;
BYTE val[10];
DWORD len = 10;
if (ERROR_SUCCESS == ::RegQueryValueEx(key, "4322", NULL, NULL, &val[0], &len))
{
char *pVal = (char *)&val[0];
if (0 == ::strcmp(pVal, "3706-4322"))
{
bRunInstall = true;
}
::RegCloseKey(key);
}
if (bRunInstall == false)
{
::MessageBox(NULL, "You must instal .NET Framework 1.1", "Error", MB_OK | MB_ICONERROR);
}
}
return bRunInstall;
}
int APIENTRY _tWinMain(HINSTANCE hInstance,
HINSTANCE hPrevInstance,
LPTSTR lpCmdLine,
int nCmdShow)
{
if (IsDotNetInstalled() == false)
{
PostQuitMessage(0);
}
System::Threading::Thread::CurrentThread->ApartmentState = System::Threading::ApartmentState::STA;
Application::Run(new Form1());
return 0;
}
ps: Sorry for my poor english.
|
|
|
|
|
Saksida Bojan wrote:
System::Threading::Thread::CurrentThread->ApartmentState = System::Threading::ApartmentState::STA; Application::Run(new Form1());
This is managed C++ code. You need to create an unmanaged project in order for it to not require the .NET framework. Your code is fine, these lines are not, and your project is therefore not either, it's a MC++ app.
I assume you know this, as you're asking the MC++ board. MC++, by definition, requires the .NET framework.
Christian Graus - Microsoft MVP - C++
|
|
|
|
|
So i must create Win32 or MFC Application detect, and if is installed run my app. I Know dis is MC++ forum, but how can i use to run other exe with some command line in Win32 syntax, Please.
ps: I Don't like programing in MFC and Win32.
|
|
|
|
|
Saksida Bojan wrote:
So i must create Win32 or MFC Application detect, and if is installed run my app
But of course. MC++ needs the exact same libraries as C#. How else did you think it worked ?
Saksida Bojan wrote:
but how can i use to run other exe with some command line in Win32 syntax, Please.
::ShellExecute.
Saksida Bojan wrote:
ps: I Don't like programing in MFC and Win32.
Sorry, but you're stuck with it for this. The funny thing is, you say that, but as far as I could see, nearly all your code WAS perfectly fine Win32, you were calling Win32 APIs for registry access, that's for sure.
Christian Graus - Microsoft MVP - C++
|
|
|
|
|
Thanks For the help. I didn't fully write this code. Someone posted on .NET Framework forum and i changed a bit.
|
|
|
|
|
|
Using SetEnvironmentVariable and other related API calls I am able to set only the "Environment Variables" specific to the process. How do I make these settings Global?
Thanks in Advance
|
|
|
|
|
Hi,
I want to monitor the file system operations done by the user,
namely
1. File/Folder Open,
2. File/Folder Copy,
3. File/Folder Rename,
4. File/Folder Delete,
5. File Save and
6. File/Folder Move operations.
I tried ICopyHook interface but it gave the information on folder Delete, Rename and Copy Operations alone.
It was not monitoring folder Open and Move operations. It also did not monitor any file based operations. Please suggest me the way to monitor the file/folder operations.
Thanks in Advance.
|
|
|
|
|
System::String *table;<br />
<br />
switch(table)<br />
{<br />
case 'CD':<br />
strTempSelectCommand = S"SELECT ID FROM CD WHERE ID=";<br />
break;<br />
case 'DVD':<br />
strTempSelectCommand = S"SELECT ID FROM DVD WHERE ID=";<br />
break;<br />
<br />
default:<br />
break;<br />
}
I got
c:\Projecti\CDDvdOrganizer\Core\CDDvdCore.h(155): error C2450: switch expression of type 'System::String __gc *' is illegal
Can anybody help me? Thanks in advance
|
|
|
|
|
you cannot use 'CD' , 'DVD' case statements.
single quotes are for single characters. if you want to use strings, it should be double quotes "" instead
but unfortunaltey, switch dont work with string. you must change it to an if - else if - else statement...
TOXCCT >>> GEII power [toxcct][VisualCalc]
|
|
|
|
|
To bad. I was hopping to use switch statment. Thank you for your reply.
|
|
|
|
|
read again the switch sintax and u will learn that switch will not make a "strcmp" for ya' ... that is you need an ordinal type for switch arg (i.e. numbers) and constants for case "labels". Perhaps u could #define cd 1, ... dvd 2, etc ... and try using switch that way
|
|
|
|
|
My program isn't desing in that way, I need to use String format, but switch doesn't recognize it, because it is managed type. I think strcmp is MFC or win32 type.
|
|
|
|
|
hello all,
1 - is it posiblle to pass ADO Recordset as a parameter from C++ managed code (.Net MC++) to a C++ unmanaged code (the old existing code) function??
how can i do it using the P-Invoce mechanism?
if it's not posibble - how can i call an exisiting C++ unmanaged function that expect me to pass a Recordset parameter???
2- the same question but i need to pass the unmanaged function an
IUnknown* parameter(hold the connection to the DB).
if u can show me an example it will be great
thank's
|
|
|
|
|
Hi, i would like to find out what are the ways to call unmanaged c++ dll's and lib's into c# using visual studio 2005 beta. I have tried many ways like using p-invoke and adding through reference but none of these methods seemed to do it for me. Are there any easier ways to perform this operation using Visual Studio 2005 Beta? I would like to create an application that uses certain dll's and lib's from the ogg vorbis library and implement them into my windows application whereby the GUI would be done using C#. The url for the ogg vorbis codes are as follows. www.vorbis.com. I would really appreciate your kind feedback. Thank you.
|
|
|
|
|
Hi,
I have to use a MFC C++ DLL (unmanaged of course) in a C++ .Net project.
I have problems to do that. I've created a C++ .Net project and includes the MFC DLL.
My problems comes as soon as I call a method (ctor, dtor or method) from the MFC DLL.
I've got this kind of error :
<br />
error LNK2001: unresolved external symbol "public: __thiscall toto::toto(void)" (??0toto@@$$FQAE@XZ)<br />
fatal error LNK1120: 2 unresolved externals<br />
toto is the unmanaged class from the MFC DLL.
I call it in the C++ .Net class like this :
<br />
toto *p;<br />
p = new toto();<br />
(the first line compile but not the second)
Thanks,
Denis (denissohet AT hotmail DOT com
|
|
|
|
|
|
DllImport must be use to import an unmanaged function but I have to import into my C++ .Net code, classes from unmanaged code... And I don't know how to do. I want to do a wrapper but I can't call my unmanaged classes un .Net code. That's my problem in fact.
I've try the DllImport, but I can't call a constructor :s Is it possible to do this ?
Thks
|
|
|
|
|
Sorry for not replying.
I'm not a big fan of MFC, but, I've read that using MFC classes in a .NET CLR project can be problematic. As I recall there is a conflict with a compiler switch that enables runtime type checks in MFC, and this conflicts with the operation of the Common Language Runtime.
Sorry for my previous post, it could just be making things more difficult for you.
There is an article on MSDN Magazine about this problem. I suggest that you search there.
|
|
|
|