Я тут уже создавал тему об этом. Тогда этот вопрос решил. Пытаюсь теперь тот код переписать под VS2005 (он был под 2003). Не выходит. В 2003 было так:
Код | [StructLayout(LayoutKind::Sequential)] public __gc struct Message { IntPtr hWnd; UInt32 msg; IntPtr wParam; IntPtr lParam; UInt32 time; System::Drawing::Point p; };
[System::Security::SuppressUnmanagedCodeSecurity] // We won't use this maliciously [DllImport(S"User32.dll", CharSet=CharSet::Auto)] extern "C" bool PeekMessage(engine_tester::Message __gc *msg, IntPtr hWnd, UInt32 messageFilterMin, UInt32 messageFilterMax, UInt32 flags);
public __gc class Form1 : public System::Windows::Forms::Form { public: . . . Form1(void) { InitializeComponent(); msg = new Message(); . . . } public: System::Void OnApplicationIdle(System::Object *sender, System::EventArgs *e) { while (AppStillIdle()) { // Render a frame during idle time (no messages are waiting) //UpdateEnvironment(); //Render3DEnvironment(); engine->Render(); } }
private: Message *msg; bool AppStillIdle(System::Void) { return !PeekMessage(msg, IntPtr::Zero, 0, 0, 0); } . . . }
|
Теперь в 2005ой студии я столкнулся с проблемой, что дизайнер форм не работает, если перед классом формы есть какие-либо определения/описания. Поэтому было решено вынести их в отдельный класс:
Код | namespace MyInterop { using namespace System; using namespace System::Runtime::InteropServices; // using namespace Loader; [StructLayout(LayoutKind::Sequential)] public ref struct Message { IntPtr hWnd; UInt32 msg; IntPtr wParam; IntPtr lParam; UInt32 time; System::Drawing::Point p; };
static public ref class MyInteropClass { public: static Message^ msg;
[System::Security::SuppressUnmanagedCodeSecurity] // We won't use this maliciously [DllImport("User32.dll", CharSet=CharSet::Auto)] static bool PeekMessage(Message^ msg, IntPtr hWnd, UInt32 messageFilterMin, UInt32 messageFilterMax, UInt32 flags);
private: static MyInteropClass() {msg = gcnew Message();} //~MyInteropClass() {delete msg;} };
|
Потом использовал этот класс в форме:
Код | #include "InteropFuncForForm.h"
public ref class Form1 : public System::Windows::Forms::Form { . . . public: System::Void OnApplicationIdle(System::Object^ sender, System::EventArgs^ e) { // pin_ptr<MyInterop::Message^> ppmsg = &MyInteropClass::msg; // System::Windows::Forms::NativeMethods::MSG *mssg; while(!MyInteropClass::PeekMessage(MyInteropClass::msg, IntPtr::Zero, 0, 0, 0)) { // Выполняем здесь всю необходимую работу } }
|
И тут вылазят ошибки на место вызова PeekMessage: Error 2 error C2039: 'PeekMessageW' : is not a member of 'MyInterop::MyInteropClass' Error 3 error C2664: 'PeekMessageW' : cannot convert parameter 1 from 'MyInterop::Message ^' to 'LPMSG'
Пытался со второй бороться, определяя Message структуру как value struct, либо просто struct (т.е. unmaganed) (отсюда кстати и закомменченные строки кода), однако Error 3 всё равно оставалась только уже говорила, что не может конвертнуть либо interior_ptr, либо MyInterop::Message* соответсвенно в LPMSG. Также пытался использовать MSG из NativeMethods, но тут на строчке System::Windows::Forms::NativeMethods::MSG *mssg; вылетала ошибка: Error 3 error C2039: 'MSG' : is not a member of 'System::Windows::Forms' не смотря на то, что я вводил эти данные не вручную (выбирал из выпадающих списков) и всплывающая подсказка говорит, что это value class ... sealed |