> > On Sep 16, 2:06 am, "Jochen Kalmbach [MVP]" <nospam-
> > Jochen.Kalmb...@holzma.de> wrote:
[quoted text clipped - 46 lines]
>
> - Show quoted text -
Afters hours of trying to make the callback function as described I
restart from scratch with a working example found at :
http://www.codeproject.com/managedcpp/cbwijw.asp The only problem is
that this example use /oldSyntax and I manage to convert it to the new
syntax. I'm still trying to figure out how to solve 2 errors and 1
warning.
Original /old syntax source : http://www.codeproject.com/managedcpp/cbwijw.asp
Here is the converted example :
======================
<Code>
#include "stdafx.h"
#using <mscorlib.dll>
#using <System.dll>
#using <System.Drawing.dll>
#using <System.Windows.Forms.dll>
#include <tchar.h>
#include <windows.h>
using namespace System;
using namespace System::ComponentModel;
using namespace System::Drawing;
using namespace System::Windows::Forms;
ref class CEnumWindows
{
private:
__nogc class _CEnumWindows // **** Error C4980: '__nogc' : use of
this keyword requires /clr:oldSyntax ***
{
private:
static BOOL EnumWindowsProc(HWND hwnd, LPARAM)
{
CEnumWindows^ pew = CEnumWindows::GetClass();
pew->m_EnumProc->Invoke(hwnd, NULL); //*** Error C2664:
'CEnumWindows::EnumProc::Invoke' : cannot convert parameter 1 from
'HWND' to 'System::IntPtr'
return TRUE;
}
public:
void StartFinding()
{
EnumWindows((WNDENUMPROC)_CEnumWindows::EnumWindowsProc,NULL);
}
};
private:
_CEnumWindows* m_ew;
public:
delegate bool EnumProc(IntPtr hwnd, IntPtr lParam);
static CEnumWindows^ GetClass()
{
return m_pclass;
}
static CEnumWindows^ m_pclass=NULL;
CEnumWindows()
{
m_pclass = this;
m_ew = new _CEnumWindows();
}
~CEnumWindows()
{
delete m_ew;
}
void StartFinding()
{
m_ew->StartFinding();
}
EnumProc^ m_EnumProc;
};
public ref class NForm : public Form
{
public:
bool EWHandler(IntPtr hwnd, IntPtr lParam)
{
char buff[512];
if(GetWindowText((HWND)hwnd.ToInt32(),buff,511))
{
String^ s = String::Format("{0}{1}",
hwnd.ToInt32().ToString("X8"),Convert::ToString(buff)); // ***
Warning warning C4800: 'char *' : forcing value to bool 'true' or
'false' (performance warning) ***
lbox->Items->Add(s);
}
return false;
}
NForm()
{
StartPosition = FormStartPosition::CenterScreen;
Text = "Callbacks with IJW - Nish for CodeProject - Avoid
DllImport";
Size = Drawing::Size(750,550);
FormBorderStyle =
System::Windows::Forms::FormBorderStyle::FixedDialog;
MaximizeBox = false;
lbox = gcnew ListBox();
lbox->Location=Point(5,5);
lbox->Size=Drawing::Size(730,500);
lbox->Sorted = true;
Controls->Add(lbox);
CEnumWindows^ p = gcnew CEnumWindows();
p->m_EnumProc = gcnew
CEnumWindows::EnumProc(this,&NForm::EWHandler);
p->StartFinding();
}
ListBox^ lbox;
};
int WinMain(HINSTANCE,HINSTANCE,LPSTR,int)
{
Application::Run(gcnew NForm());
return 0;
}
</Code>
Here is the ***errors*** :
==================
Error C4980: '__nogc' : use of this keyword requires /clr:oldSyntax
-> What is the new syntax for _nogc ? cant find much details on
google...
Error C2664: 'CEnumWindows::EnumProc::Invoke' : cannot convert
parameter 1 from 'HWND' to 'System::IntPtr'
-> ???? no idea :(
Warning warning C4800: 'char *' : forcing value to bool 'true' or
'false' (performance warning)
-> ???? no idea :(
If i can find solution these errors I will be ble to integrate this
"example" in my C++ form project.
Thanks again for any clues on this issues...
Ben Voigt [C++ MVP] - 18 Sep 2007 14:14 GMT
>> > On Sep 16, 2:06 am, "Jochen Kalmbach [MVP]" <nospam-
>> > Jochen.Kalmb...@holzma.de> wrote:
[quoted text clipped - 59 lines]
> Original /old syntax source :
> http://www.codeproject.com/managedcpp/cbwijw.asp
I don't know that C++/CLI will even allow you to nest an unmanaged class
inside a ref class, in any case the new syntax for __nogc class is simply
"class", no "ref" or "value" prefix.
You could do what David suggested and pass the handle to your form through
the extra parameter provided for your use. To do that, you will need your
original code and GCHandle::Alloc, GCHandle::Target, and GCHandle::Free.
The problem with passing a pointer through unmanaged code is that the
garbage collector might move your form around while running your callback,
then it will adjust the pointer that you received, but the next time the
callback is invoked, it will get the original pointer location which is no
longer valid. GCHandle solves this problem.
SQACPP - 21 Sep 2007 21:57 GMT
> >> "SQACPP" <lsdiscip...@hotmail.com> wrote in message
>
[quoted text clipped - 78 lines]
>
> - Show quoted text -
Thanks for your help!
I'm still trying to make the enumwindows works and being able to
display the results of enumWindows in my form (this->listBox2->Items-
>Add(...)
using namespace System::Runtime::InteropServices;
BOOL CALLBACK MyEnumWindowsProc(HWND hwnd, LPARAM lparam)
{
//GCHandle MyThis = GCHandle::FromIntPtr(lparam); //** not
working since LPARAM is not a IntPtr
//Form MyForm= gcnew System::Windows::Forms::; // ** Dont know
how to define a new "this" instance (my form)
// GCHandle gch = GCHandle.FromIntPtr(param);
// TextWriter tw = (TextWriter)gch.Target;
// tw.WriteLine(handle);
return (TRUE);
}
// ....
GCHandle gch = GCHandle::Alloc(this);
// *** NOT WORKING :
EnumWindows(MyEnumWindowsProc,GCHandle::ToIntPtr(gch)); //** not
working since LPARAM is not a IntPtr
EnumWindows(MyEnumWindowsProc,0);
// ....
I need help to understand how to change the lparam param to a IntPtr
without having compiling errors like :
[error C4439: 'AutomationWinForm::MyEnumWindowsProc' : function
definition with a managed type in the signature must have a __clrcall
calling convention]
when i change my the last param of my callback like this : BOOL
CALLBACK MyEnumWindowsProc(HWND hwnd, IntPtr lparam)
and
[error C2664: 'EnumWindows' : cannot convert parameter 1 from 'BOOL
(__stdcall *)(HWND,System::IntPtr)' to 'WNDENUMPROC' ]
when I change the call to enumWindows like this
EnumWindows(MyEnumWindowsProc,GCHandle::ToIntPtr(gch));
Also it still not clear how to define a new instance of my form
(this) :
Really need help!...thanks!
SQACPP - 23 Sep 2007 08:14 GMT
> > "SQACPP" <lsdiscip...@hotmail.com> wrote in message
>
[quoted text clipped - 138 lines]
>
> - Show quoted text -
Any idea?
Ben Voigt [C++ MVP] - 25 Sep 2007 19:47 GMT
> I'm still trying to make the enumwindows works and being able to
> display the results of enumWindows in my form (this->listBox2->Items-
[quoted text clipped - 5 lines]
> //GCHandle MyThis = GCHandle::FromIntPtr(lparam); //** not
> working since LPARAM is not a IntPtr
There's a converting constructor, try GCHandle::FromIntPtr(IntPtr(lparam))
or else GCHandle::FromIntPtr(IntPtr((void*)lparam))
> //Form MyForm= gcnew System::Windows::Forms::; // ** Dont know
> how to define a new "this" instance (my form)
[quoted text clipped - 11 lines]
> EnumWindows(MyEnumWindowsProc,GCHandle::ToIntPtr(gch)); //** not
> working since LPARAM is not a IntPtr
use GCHandle::ToIntPtr(gch).ToPointer()
> EnumWindows(MyEnumWindowsProc,0);
> // ....
[quoted text clipped - 21 lines]
>
> Really need help!...thanks!
SQACPP - 30 Sep 2007 09:06 GMT
> > I'm still trying to make the enumwindows works and being able to
> > display the results of enumWindows in my form (this->listBox2->Items-
[quoted text clipped - 54 lines]
>
> - Show quoted text -
Thanks for still trying to help me!....
BOOL CALLBACK MyEnumWindowsProc(HWND hwnd, LPARAM lparam)
{
GCHandle MyThis = GCHandle::FromIntPtr(IntPtr(lparam)) ;
// ** missing code here to be able to access to my form **//
MyThis->Label1->Text="blabla";
return (TRUE);
}
// ....
GCHandle gch = GCHandle::Alloc(this);
EnumWindows(MyEnumWindowsProc,GCHandle::ToIntPtr(gch).ToPointer()); //
** Error **//
This code return the error Error C2664: 'EnumWindows' : cannot convert
parameter 2 from 'void *' to 'LPARAM'
instead of printing "blabla" in the label1 of my form each time the
callback proc is called for each windows.
I have no clues about how to recreate a usable form "instance" in my
callback procedure... The following code in the proc is to output to
the console but how to work with a form instead ???
GCHandle gch = GCHandle.FromIntPtr(lparam);
TextWriter tw = (TextWriter)gch.Target;
tw.WriteLine(handle);
Thanks...