是否可以从本机代码操作.net控件?特别是,我想从一些本机代码中设置TextBox
的文本。我希望它以这种方式完成,以保持业务逻辑与用户界面分离,但正是本机代码只知道如何正确格式化数据(协议中接收的一些字节)。
我知道我可以通过Handle
属性获取窗口句柄,但是在那里,我将如何调用所需的方法?
字符串处理是我唯一的选择吗?本机代码是否应构建要在控件上显示的消息?
答案 0 :(得分:1)
在文本框中设置文本的“原生”方式是向文本框发送WM_SETTEXT
消息:
// handle is initialized from TextBox::Handle
PostMessage(handle, WM_SETTEXT, 0, _T("Some text"));
同时阅读PostMessage
和SendMessage
。根据您分配和构建文本的方式,您可能需要使用SendMessage
以避免过早解除分配。
答案 1 :(得分:1)
如果您希望将业务逻辑与用户界面分开,并且某些业务逻辑采用本机代码,那么从而不是更改任何GUI内容将是一个非常好的主意直接使用本机代码,因为它与您想要实现的完全相反。最好尝试在C ++ / CLI中编写某种包装器方法,从那里调用本机数据格式例程,使其可用于您的GUI代码。
如果您真的想要从本机代码调用托管代码,可以在C ++ / CLI中声明一个调用托管方法的(native!)静态方法。您可以将指向此类方法的函数指针传递给程序的较低层(例如,您的本机C ++层),可以从那里调用它。
有些事情:
// the native code layer:
// "Callbacks.h"
void (*_myNativeCallback)();
void InitCallback(void (*myNativeCallback)())
{
_myNativeCallback=myNativeCallback;
}
// now you can use _myNativeCallback within your native code
// the C++/CLI layer:
#include "Callbacks.h"
//...
static void MyNativeCallback()
{
ManagedClass::StaticMethod();
}
InitCallback(MyNativeCallback);
在ManagedClass::StaticMethod
中,您可以访问.NET代码,操作TextBox
任何可以从那里获得的表单都不会有任何问题。如果您必须将原生字符串转换为System::String
,您可能会发现此代码段有用:
inline System::String StdToSysString(const std::string &s)
{
return gcnew System::String(s.c_str());
}
反之亦然(假设Ansi代码页):
inline std::string SystemToStdString(System::String ss)
{
using namespace System::Runtime::InteropServices;
const char* chars =
(const char*)(Marshal::StringToHGlobalAnsi(ss)).ToPointer();
std::string s = chars;
Marshal::FreeHGlobal(System::IntPtr((void*)chars));
return s;
}